Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/wolfcrypt/src/ecc.c
Line
Count
Source
1
/* ecc.c
2
 *
3
 * Copyright (C) 2006-2026 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
#define WC_FIPS_LL_CRYPTO
23
#define _WC_BUILDING_ECC_C
24
25
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
26
27
#ifdef WOLFSSL_ECC_NO_SMALL_STACK
28
#undef WOLFSSL_SMALL_STACK
29
#undef WOLFSSL_SMALL_STACK_CACHE
30
#endif
31
32
/*
33
Possible ECC enable options:
34
 * HAVE_ECC:            Overall control of ECC                  default: on
35
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
36
 * HAVE_ECC_SIGN:       ECC sign                                default: on
37
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
38
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
39
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
40
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
41
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
42
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
43
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
44
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
45
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
46
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
47
 *                        Includes the curve "a" variable in calculation
48
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
49
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
50
 *                                                              default: off
51
 * FP_ECC:              ECC Fixed Point Cache                   default: off
52
 *                      FP cache is not supported for SECP160R1, SECP160R2,
53
 *                      SECP160K1 and SECP224K1. These do not work with scalars
54
 *                      that are the length of the order when the order is
55
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
56
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
57
 *                      For the ECC curve parameters `ecc_set_type` use fixed
58
 *                      array for hex string
59
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify/keygen/secret.
60
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
61
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
62
 *                      normal blocking API's
63
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
64
 *                      signing. If the value is invalid, a new random 'k' is
65
 *                      generated in the loop. (For testing)
66
 *                                                              default: off
67
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
68
 *                      Enables the setting of the 'k' value to use during ECDSA
69
 *                      signing. If the value is invalid then an error is
70
 *                      returned rather than generating a new 'k'. (For testing)
71
 *                                                              default: off
72
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
73
 *                      deterministic ECC signatures. The following function
74
 *                      can be used to set the deterministic signing flag in the
75
 *                      ecc key structure.
76
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
77
 *                                                              default: off
78
 *
79
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
80
 *                      hash directly instead of doing bits2octets(H(m)), when
81
 *                      the variant macro is used the bits2octets operation on
82
 *                      the hash is removed.
83
 *                                                              default: off
84
 *
85
 * WC_PROTECT_ENCRYPTED_MEM:
86
 *                      Enables implementations that protect data that is in
87
 *                      encrypted memory.
88
 *                                                              default: off
89
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
90
 *                      Enables generation of scalar (private key and ECDSA
91
 *                      nonce) to be performed using reject sampling algorithm.
92
 *                      Use this when CPU state can be closely observed by
93
 *                      attacker.
94
 *                                                              default: off
95
 * WOLFSSL_ECC_BLIND_K
96
 *                      Blind the private key k by using a random mask.
97
 *                      The private key is never stored unprotected but an
98
 *                      unmasked copy is computed and stored each time it is
99
 *                      needed.
100
 *                                                              default: off
101
 * WOLFSSL_CHECK_VER_FAULTS
102
 *                      Sanity check on verification steps in case of faults.
103
 *                                                              default: off
104
 * ECC_TIMING_RESISTANT: Enables constant-time ECC operations   default: on
105
 *                      to prevent timing side-channel attacks.
106
 *                      Auto-enabled for FIPS and some embedded builds.
107
 * WC_NO_CACHE_RESISTANT: Disables cache-resistant operations   default: off
108
 *                      (conditional swaps) in ECC scalar multiply to
109
 *                      reduce overhead. Not recommended for secure use.
110
 * ALT_ECC_SIZE:        Uses alternate smaller fixed-size arrays default: off
111
 *                      for ECC points instead of full mp_int arrays,
112
 *                      reducing memory. Requires USE_FAST_MATH.
113
 * WOLFSSL_ECC_NO_SMALL_STACK: Disables WOLFSSL_SMALL_STACK     default: off
114
 *                      optimizations for ECC, using stack instead of heap.
115
 * HAVE_ECC_CHECK_PUBKEY_ORDER: Validates ECC public key order  default: on
116
 *                      during import. Auto-enabled unless
117
 *                      NO_ECC_CHECK_PUBKEY_ORDER is defined.
118
 * NO_ECC_CHECK_PUBKEY_ORDER: Disables public key order check   default: off
119
 *                      during ECC key import. Not recommended.
120
 * HAVE_ECC_MAKE_PUB:   Enables computing public key from       default: on
121
 *                      private key via wc_ecc_make_pub.
122
 * HAVE_ECC_VERIFY_HELPER: Enables ECC verify helper functions  default: on
123
 *                      Auto-enabled unless using hardware accelerators.
124
 * WOLFSSL_PUBLIC_ECC_ADD_DBL: Makes ecc_projective_add_point   default: off
125
 *                      and ecc_projective_dbl_point public APIs.
126
 * SQRTMOD_USE_MOD_EXP: Computes square root mod prime using    default: off
127
 *                      modular exponentiation instead of Jacobi method
128
 *                      for compressed key decompression.
129
 *
130
 * ECIES options:
131
 * WOLFSSL_ECIES_OLD:   Uses original wolfSSL ECIES format      default: off
132
 *                      (public key not in shared secret material).
133
 * WOLFSSL_ECIES_ISO18033: Uses ISO 18033 ECIES standard        default: off
134
 *                      (includes public key in shared secret).
135
 * WOLFSSL_ECIES_GEN_IV: Generates random IV for ECIES          default: off
136
 *                      encryption instead of deriving from KDF.
137
 * WOLFSSL_ECIES_STATIC_GCM_NONCE:                              default: off
138
 *                      Allows the AES-GCM DEM in the default IV mode, where the
139
 *                      GCM nonce is a fixed all-zero value that is not sent.
140
 *                      This is ONLY safe because ECIES derives a fresh key from
141
 *                      a fresh ephemeral key each message, so the (key, nonce)
142
 *                      pair never repeats.  Reusing the ephemeral key would
143
 *                      reuse both the key and the nonce - catastrophic for GCM.
144
 *                      Off by default: without this define, the GCM DEM returns
145
 *                      NOT_COMPILED_IN in the default IV mode so the fixed nonce
146
 *                      cannot be selected by accident.  Not needed with
147
 *                      WOLFSSL_ECIES_GEN_IV (random nonce) or WOLFSSL_ECIES_OLD
148
 *                      (KDF-derived nonce).
149
 *
150
 * Fixed Point Cache options (requires FP_ECC):
151
 * FP_ENTRIES:          Number of FP cache entries               default: 15
152
 * FP_LUT:              FP lookup table bit size (2-12). Larger  default: 8
153
 *                      values use more memory but faster verify.
154
 * FP_ECC_CONTROL:      Auto-selects cached FP ECC verify with  default: on
155
 *                      SP when WOLFSSL_HAVE_SP_ECC is available.
156
 *
157
 * SP Math ECC options:
158
 * WOLFSSL_HAVE_SP_ECC: Enables SP math optimizations for ECC   default: on
159
 *                      Provides significant performance improvement.
160
 * WOLFSSL_SP_NO_256:   Disables SP P-256 support               default: off
161
 * WOLFSSL_SP_384:      Enables SP P-384 support                default: off
162
 * WOLFSSL_SP_521:      Enables SP P-521 support                default: off
163
 * WOLFSSL_SP_1024:     Enables SP 1024-bit support for SAKKE   default: off
164
 * WOLFSSL_SP_SM2:      Enables SP SM2 curve support            default: off
165
 *                      Auto-enabled with WOLFSSL_SM2.
166
 *
167
 * Hardware/Offload options:
168
 * WOLFSSL_KCAPI_ECC:   Offload ECC to Linux Kernel Crypto API  default: off
169
 * WC_ASYNC_ENABLE_ECC: Enables async ECC with crypto callbacks default: off
170
 *                      Requires WOLFSSL_ASYNC_CRYPT.
171
 * WC_ASYNC_ENABLE_ECC_KEYGEN: Enables async ECC key gen        default: off
172
 * PLUTON_CRYPTO_ECC:   Uses ARM Pluton TEE for ECC operations  default: off
173
 * WOLFSSL_CAAM_BLACK_KEY_SM: Uses NXP CAAM secure memory for   default: off
174
 *                      encrypted black key storage.
175
 */
176
177
/*
178
ECC Curve Types:
179
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
180
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
181
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
182
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
183
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
184
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
185
 */
186
187
/*
188
ECC Curve Sizes:
189
 * ECC_USER_CURVES: Allows custom combination of key sizes below
190
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
191
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
192
 * HAVE_ECC112: 112 bit key
193
 * HAVE_ECC128: 128 bit key
194
 * HAVE_ECC160: 160 bit key
195
 * HAVE_ECC192: 192 bit key
196
 * HAVE_ECC224: 224 bit key
197
 * HAVE_ECC239: 239 bit key
198
 * NO_ECC256: Disables 256 bit key (on by default)
199
 * HAVE_ECC320: 320 bit key
200
 * HAVE_ECC384: 384 bit key
201
 * HAVE_ECC512: 512 bit key
202
 * HAVE_ECC521: 521 bit key
203
 */
204
205
206
#ifdef HAVE_ECC
207
208
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
209
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
210
    !defined(WOLFSSL_CUSTOM_CURVES)
211
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
212
#endif
213
214
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
215
    #ifdef USE_WINDOWS_API
216
        #pragma code_seg(".fipsA$f")
217
        #pragma const_seg(".fipsB$f")
218
    #endif
219
#endif
220
221
/* public ASN interface */
222
#include <wolfssl/wolfcrypt/asn_public.h>
223
224
#include <wolfssl/wolfcrypt/ecc.h>
225
#include <wolfssl/wolfcrypt/asn.h>
226
#include <wolfssl/wolfcrypt/hash.h>
227
228
#ifdef WOLFSSL_HAVE_SP_ECC
229
#include <wolfssl/wolfcrypt/sp.h>
230
#endif
231
232
#ifdef HAVE_ECC_ENCRYPT
233
    #include <wolfssl/wolfcrypt/kdf.h>
234
235
    /* For wc_AesGcmEncrypt() wrapper, if needed. */
236
    #include <wolfssl/wolfcrypt/wc_compat.h>
237
238
    #include <wolfssl/wolfcrypt/aes.h>
239
#endif
240
241
#ifdef WOLF_CRYPTO_CB
242
    #include <wolfssl/wolfcrypt/cryptocb.h>
243
#endif
244
245
#ifdef NO_INLINE
246
    #include <wolfssl/wolfcrypt/misc.h>
247
#else
248
    #define WOLFSSL_MISC_INCLUDED
249
    #include <wolfcrypt/src/misc.c>
250
#endif
251
252
#if FIPS_VERSION3_GE(6,0,0)
253
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
254
                                                     { 0x1a2b3c4d, 0x00000005 };
255
    int wolfCrypt_FIPS_ECC_sanity(void)
256
    {
257
        return 0;
258
    }
259
#endif
260
261
#if defined(FREESCALE_LTC_ECC)
262
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
263
#endif
264
265
#if defined(WOLFSSL_STM32_PKA) || defined(WOLFSSL_STM32_CCB) || \
266
    defined(WOLFSSL_DHUK)
267
    /* CCB without PKA still needs stm32.h so its consistency #errors (e.g. CCB
268
     * requires DHUK + BARE/CUBEMX) are visible to this translation unit, and
269
     * the DHUK case needs WC_STM32_HAS_DHUK visible so the
270
     * wc_ecc_import_wrapped_private definition below is gated the same way as
271
     * its prototype in ecc.h. */
272
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
273
#endif
274
275
#if defined(WOLFSSL_PSOC6_CRYPTO)
276
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
277
#endif
278
279
#if defined(WOLFSSL_CAAM)
280
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
281
#endif
282
283
#if defined(WOLFSSL_KCAPI_ECC)
284
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
285
#endif
286
287
#ifdef WOLFSSL_SE050
288
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
289
#endif
290
291
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
292
    #include <xsecure_ellipticclient.h>
293
#endif
294
295
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
296
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
297
    #include <wolfssl/wolfcrypt/hmac.h>
298
#endif
299
300
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
301
    !defined(WOLFSSL_MICROCHIP_TA100) && \
302
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
303
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
304
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && \
305
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
306
    !defined(WOLFSSL_PSOC6_CRYPTO)
307
    /* STM32 sign-only (e.g. C5): the HW PKA cannot run the integrated ECDSA
308
     * verify (mode 0x26) correctly, so use the SW verify helper rather than the
309
     * HW-accelerator sigRS path. Note the helper's scalar multiplications still
310
     * run on the HW PKA generic-mul (stm32.c provides wc_ecc_mulmod_ex under
311
     * !WC_STM32_PKA_VERIFY_ONLY) -- the C5 issue is specifically the verify-mode
312
     * wrapper, not the point math, which is exercised and correct (the lead for
313
     * a future real HW verify). */
314
    #undef  HAVE_ECC_VERIFY_HELPER
315
    #define HAVE_ECC_VERIFY_HELPER
316
#endif
317
/* Compile in the software verify helper whenever SE050 hardware ECDSA verify is
318
 * bypassed:
319
 *  - WOLFSSL_SE050_NO_ECDSA_VERIFY disables SE050 ECDSA verify outright.
320
 *  - WOLFSSL_SE050_ONLY_KEY_ID verifies software keys (keyIdSet == 0) in
321
 *    wolfCrypt; the SE050 is used at runtime only for keys resident in HW. */
322
#if (defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) || \
323
     (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID))) && \
324
    defined(HAVE_ECC_VERIFY)
325
    #define HAVE_ECC_VERIFY_HELPER
326
#endif
327
328
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
329
        !defined(WOLFSSL_MICROCHIP_TA100) && \
330
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
331
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB)
332
    #undef  HAVE_ECC_MAKE_PUB
333
    #define HAVE_ECC_MAKE_PUB
334
#endif
335
336
337
/* macro guard for ecc_check_pubkey_order functionality */
338
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
339
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
340
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
341
     !defined(WOLFSSL_MICROCHIP_TA100) && \
342
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
343
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
344
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
345
346
    /* CAAM builds use public key validation as a means to check if an
347
     * imported private key is an encrypted black key or not */
348
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
349
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
350
#endif
351
352
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
353
#define MAX_ECC_BITS_USE    SP_INT_BITS
354
#else
355
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
356
#endif
357
358
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
359
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
360
361
#define ECC_KEY_MAX_BITS(key)                                       \
362
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
363
        ((unsigned)((key)->dp->size * 8)))
364
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
365
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
366
        ((unsigned)((key)->dp->size * 8)))
367
368
#else
369
370
/* Add one bit for cases when order is a bit greater than prime. */
371
#define ECC_KEY_MAX_BITS(key)                                       \
372
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
373
        ((unsigned)((key)->dp->size * 8 + 1)))
374
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
375
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
376
        ((unsigned)((key)->dp->size * 8 + 1)))
377
378
#endif
379
380
#ifdef WOLFSSL_ECC_BLIND_K
381
mp_int* ecc_get_k(ecc_key* key)
382
{
383
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
384
    return key->ku;
385
}
386
void ecc_blind_k(ecc_key* key, mp_int* b)
387
{
388
    mp_xor_ct(key->k, b, key->dp->size, key->k);
389
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
390
}
391
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
392
{
393
    int ret = 0;
394
    WC_RNG local_rng;
395
396
#ifdef ECC_TIMING_RESISTANT
397
    if (rng == NULL) {
398
        rng = key->rng;
399
    }
400
#endif
401
    if (rng == NULL) {
402
        ret = wc_InitRng(&local_rng);
403
        if (ret == 0) {
404
            rng = &local_rng;
405
        }
406
    }
407
    if (ret == 0) {
408
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
409
            sizeof(mp_digit), rng);
410
        if (ret == 0) {
411
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
412
        }
413
    }
414
415
    if (rng == &local_rng) {
416
        wc_FreeRng(&local_rng);
417
    }
418
    return ret;
419
}
420
421
mp_int* wc_ecc_key_get_priv(ecc_key* key)
422
{
423
    return ecc_get_k(key);
424
}
425
#endif
426
427
/* forward declarations */
428
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
429
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
430
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
431
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
432
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
433
#endif
434
435
/* internal ECC states */
436
enum {
437
    ECC_STATE_NONE = 0,
438
439
    ECC_STATE_SHARED_SEC_GEN,
440
    ECC_STATE_SHARED_SEC_RES,
441
442
    ECC_STATE_SIGN_DO,
443
    ECC_STATE_SIGN_ENCODE,
444
445
    ECC_STATE_VERIFY_DECODE,
446
    ECC_STATE_VERIFY_DO,
447
    ECC_STATE_VERIFY_RES
448
};
449
450
451
/* map
452
   ptmul -> mulmod
453
*/
454
455
/* 256-bit curve on by default whether user curves or not */
456
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
457
    #define ECC112
458
#endif
459
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
460
    #define ECC128
461
#endif
462
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
463
    #define ECC160
464
#endif
465
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
466
    #define ECC192
467
#endif
468
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
469
    #define ECC224
470
#endif
471
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
472
    #define ECC239
473
#endif
474
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
475
    #define ECC256
476
#endif
477
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
478
    #define ECC320
479
#endif
480
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
481
    #define ECC384
482
#endif
483
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
484
    #define ECC512
485
#endif
486
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
487
    #define ECC521
488
#endif
489
490
/* The encoded OID's for ECC curves */
491
#ifdef ECC112
492
    #ifndef NO_ECC_SECP
493
        #ifdef HAVE_OID_ENCODING
494
            #define CODED_SECP112R1    {1,3,132,0,6}
495
            #define CODED_SECP112R1_SZ 5
496
        #else
497
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
498
            #define CODED_SECP112R1_SZ 5
499
        #endif
500
        #ifndef WOLFSSL_ECC_CURVE_STATIC
501
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
502
        #else
503
            #define ecc_oid_secp112r1 CODED_SECP112R1
504
        #endif
505
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
506
    #endif /* !NO_ECC_SECP */
507
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
508
        #ifdef HAVE_OID_ENCODING
509
            #define CODED_SECP112R2    {1,3,132,0,7}
510
            #define CODED_SECP112R2_SZ 5
511
        #else
512
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
513
            #define CODED_SECP112R2_SZ 5
514
        #endif
515
        #ifndef WOLFSSL_ECC_CURVE_STATIC
516
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
517
        #else
518
            #define ecc_oid_secp112r2 CODED_SECP112R2
519
        #endif
520
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
521
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
522
#endif /* ECC112 */
523
#ifdef ECC128
524
    #ifndef NO_ECC_SECP
525
        #ifdef HAVE_OID_ENCODING
526
            #define CODED_SECP128R1    {1,3,132,0,28}
527
            #define CODED_SECP128R1_SZ 5
528
        #else
529
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
530
            #define CODED_SECP128R1_SZ 5
531
        #endif
532
        #ifndef WOLFSSL_ECC_CURVE_STATIC
533
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
534
        #else
535
            #define ecc_oid_secp128r1 CODED_SECP128R1
536
        #endif
537
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
538
    #endif /* !NO_ECC_SECP */
539
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
540
        #ifdef HAVE_OID_ENCODING
541
            #define CODED_SECP128R2    {1,3,132,0,29}
542
            #define CODED_SECP128R2_SZ 5
543
        #else
544
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
545
            #define CODED_SECP128R2_SZ 5
546
        #endif
547
        #ifndef WOLFSSL_ECC_CURVE_STATIC
548
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
549
        #else
550
            #define ecc_oid_secp128r2 CODED_SECP128R2
551
        #endif
552
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
553
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
554
#endif /* ECC128 */
555
#ifdef ECC160
556
#ifndef FP_ECC
557
    #ifndef NO_ECC_SECP
558
        #ifdef HAVE_OID_ENCODING
559
            #define CODED_SECP160R1    {1,3,132,0,8}
560
            #define CODED_SECP160R1_SZ 5
561
        #else
562
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
563
            #define CODED_SECP160R1_SZ 5
564
        #endif
565
        #ifndef WOLFSSL_ECC_CURVE_STATIC
566
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
567
        #else
568
            #define ecc_oid_secp160r1 CODED_SECP160R1
569
        #endif
570
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
571
    #endif /* !NO_ECC_SECP */
572
    #ifdef HAVE_ECC_SECPR2
573
        #ifdef HAVE_OID_ENCODING
574
            #define CODED_SECP160R2    {1,3,132,0,30}
575
            #define CODED_SECP160R2_SZ 5
576
        #else
577
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
578
            #define CODED_SECP160R2_SZ 5
579
        #endif
580
        #ifndef WOLFSSL_ECC_CURVE_STATIC
581
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
582
        #else
583
            #define ecc_oid_secp160r2 CODED_SECP160R2
584
        #endif
585
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
586
    #endif /* HAVE_ECC_SECPR2 */
587
    #ifdef HAVE_ECC_KOBLITZ
588
        #ifdef HAVE_OID_ENCODING
589
            #define CODED_SECP160K1    {1,3,132,0,9}
590
            #define CODED_SECP160K1_SZ 5
591
        #else
592
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
593
            #define CODED_SECP160K1_SZ 5
594
        #endif
595
        #ifndef WOLFSSL_ECC_CURVE_STATIC
596
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
597
        #else
598
            #define ecc_oid_secp160k1 CODED_SECP160K1
599
        #endif
600
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
601
    #endif /* HAVE_ECC_KOBLITZ */
602
#endif /* !FP_ECC */
603
    #ifdef HAVE_ECC_BRAINPOOL
604
        #ifdef HAVE_OID_ENCODING
605
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
606
            #define CODED_BRAINPOOLP160R1_SZ 10
607
        #else
608
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
609
            #define CODED_BRAINPOOLP160R1_SZ 9
610
        #endif
611
        #ifndef WOLFSSL_ECC_CURVE_STATIC
612
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
613
        #else
614
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
615
        #endif
616
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
617
    #endif /* HAVE_ECC_BRAINPOOL */
618
#endif /* ECC160 */
619
#ifdef ECC192
620
    #ifndef NO_ECC_SECP
621
        #ifdef HAVE_OID_ENCODING
622
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
623
            #define CODED_SECP192R1_SZ 7
624
        #else
625
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
626
            #define CODED_SECP192R1_SZ 8
627
        #endif
628
        #ifndef WOLFSSL_ECC_CURVE_STATIC
629
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
630
        #else
631
            #define ecc_oid_secp192r1 CODED_SECP192R1
632
        #endif
633
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
634
    #endif /* !NO_ECC_SECP */
635
    #ifdef HAVE_ECC_SECPR2
636
        #ifdef HAVE_OID_ENCODING
637
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
638
            #define CODED_PRIME192V2_SZ 7
639
        #else
640
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
641
            #define CODED_PRIME192V2_SZ 8
642
        #endif
643
        #ifndef WOLFSSL_ECC_CURVE_STATIC
644
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
645
        #else
646
            #define ecc_oid_prime192v2 CODED_PRIME192V2
647
        #endif
648
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
649
    #endif /* HAVE_ECC_SECPR2 */
650
    #ifdef HAVE_ECC_SECPR3
651
        #ifdef HAVE_OID_ENCODING
652
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
653
            #define CODED_PRIME192V3_SZ 7
654
        #else
655
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
656
            #define CODED_PRIME192V3_SZ 8
657
        #endif
658
        #ifndef WOLFSSL_ECC_CURVE_STATIC
659
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
660
        #else
661
            #define ecc_oid_prime192v3 CODED_PRIME192V3
662
        #endif
663
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
664
    #endif /* HAVE_ECC_SECPR3 */
665
    #ifdef HAVE_ECC_KOBLITZ
666
        #ifdef HAVE_OID_ENCODING
667
            #define CODED_SECP192K1    {1,3,132,0,31}
668
            #define CODED_SECP192K1_SZ 5
669
        #else
670
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
671
            #define CODED_SECP192K1_SZ 5
672
        #endif
673
        #ifndef WOLFSSL_ECC_CURVE_STATIC
674
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
675
        #else
676
            #define ecc_oid_secp192k1 CODED_SECP192K1
677
        #endif
678
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
679
    #endif /* HAVE_ECC_KOBLITZ */
680
    #ifdef HAVE_ECC_BRAINPOOL
681
        #ifdef HAVE_OID_ENCODING
682
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
683
            #define CODED_BRAINPOOLP192R1_SZ 10
684
        #else
685
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
686
            #define CODED_BRAINPOOLP192R1_SZ 9
687
        #endif
688
        #ifndef WOLFSSL_ECC_CURVE_STATIC
689
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
690
        #else
691
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
692
        #endif
693
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
694
    #endif /* HAVE_ECC_BRAINPOOL */
695
#endif /* ECC192 */
696
#ifdef ECC224
697
    #ifndef NO_ECC_SECP
698
        #ifdef HAVE_OID_ENCODING
699
            #define CODED_SECP224R1    {1,3,132,0,33}
700
            #define CODED_SECP224R1_SZ 5
701
        #else
702
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
703
            #define CODED_SECP224R1_SZ 5
704
        #endif
705
        #ifndef WOLFSSL_ECC_CURVE_STATIC
706
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
707
        #else
708
            #define ecc_oid_secp224r1 CODED_SECP224R1
709
        #endif
710
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
711
    #endif /* !NO_ECC_SECP */
712
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
713
        #ifdef HAVE_OID_ENCODING
714
            #define CODED_SECP224K1    {1,3,132,0,32}
715
            #define CODED_SECP224K1_SZ 5
716
        #else
717
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
718
            #define CODED_SECP224K1_SZ 5
719
        #endif
720
        #ifndef WOLFSSL_ECC_CURVE_STATIC
721
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
722
        #else
723
            #define ecc_oid_secp224k1 CODED_SECP224K1
724
        #endif
725
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
726
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
727
    #ifdef HAVE_ECC_BRAINPOOL
728
        #ifdef HAVE_OID_ENCODING
729
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
730
            #define CODED_BRAINPOOLP224R1_SZ 10
731
        #else
732
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
733
            #define CODED_BRAINPOOLP224R1_SZ 9
734
        #endif
735
        #ifndef WOLFSSL_ECC_CURVE_STATIC
736
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
737
        #else
738
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
739
        #endif
740
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
741
    #endif /* HAVE_ECC_BRAINPOOL */
742
#endif /* ECC224 */
743
#ifdef ECC239
744
    #ifndef NO_ECC_SECP
745
        #ifdef HAVE_OID_ENCODING
746
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
747
            #define CODED_PRIME239V1_SZ 7
748
        #else
749
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
750
            #define CODED_PRIME239V1_SZ 8
751
        #endif
752
        #ifndef WOLFSSL_ECC_CURVE_STATIC
753
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
754
        #else
755
            #define ecc_oid_prime239v1 CODED_PRIME239V1
756
        #endif
757
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
758
    #endif /* !NO_ECC_SECP */
759
    #ifdef HAVE_ECC_SECPR2
760
        #ifdef HAVE_OID_ENCODING
761
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
762
            #define CODED_PRIME239V2_SZ 7
763
        #else
764
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
765
            #define CODED_PRIME239V2_SZ 8
766
        #endif
767
        #ifndef WOLFSSL_ECC_CURVE_STATIC
768
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
769
        #else
770
            #define ecc_oid_prime239v2 CODED_PRIME239V2
771
        #endif
772
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
773
    #endif /* HAVE_ECC_SECPR2 */
774
    #ifdef HAVE_ECC_SECPR3
775
        #ifdef HAVE_OID_ENCODING
776
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
777
            #define CODED_PRIME239V3_SZ 7
778
        #else
779
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
780
            #define CODED_PRIME239V3_SZ 8
781
        #endif
782
        #ifndef WOLFSSL_ECC_CURVE_STATIC
783
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
784
        #else
785
            #define ecc_oid_prime239v3 CODED_PRIME239V3
786
        #endif
787
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
788
    #endif /* HAVE_ECC_SECPR3 */
789
#endif /* ECC239 */
790
#ifdef ECC256
791
    #ifndef NO_ECC_SECP
792
        #ifdef HAVE_OID_ENCODING
793
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
794
            #define CODED_SECP256R1_SZ 7
795
        #else
796
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
797
            #define CODED_SECP256R1_SZ 8
798
        #endif
799
        #ifndef WOLFSSL_ECC_CURVE_STATIC
800
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
801
        #else
802
            #define ecc_oid_secp256r1 CODED_SECP256R1
803
        #endif
804
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
805
    #endif /* !NO_ECC_SECP */
806
    #ifdef HAVE_ECC_KOBLITZ
807
        #ifdef HAVE_OID_ENCODING
808
            #define CODED_SECP256K1    {1,3,132,0,10}
809
            #define CODED_SECP256K1_SZ 5
810
        #else
811
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
812
            #define CODED_SECP256K1_SZ 5
813
        #endif
814
        #ifndef WOLFSSL_ECC_CURVE_STATIC
815
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
816
        #else
817
            #define ecc_oid_secp256k1 CODED_SECP256K1
818
        #endif
819
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
820
    #endif /* HAVE_ECC_KOBLITZ */
821
    #ifdef HAVE_ECC_BRAINPOOL
822
        #ifdef HAVE_OID_ENCODING
823
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
824
            #define CODED_BRAINPOOLP256R1_SZ 10
825
        #else
826
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
827
            #define CODED_BRAINPOOLP256R1_SZ 9
828
        #endif
829
        #ifndef WOLFSSL_ECC_CURVE_STATIC
830
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
831
        #else
832
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
833
        #endif
834
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
835
    #endif /* HAVE_ECC_BRAINPOOL */
836
#endif /* ECC256 */
837
    #if defined(WOLFSSL_SM2)
838
        #ifdef HAVE_OID_ENCODING
839
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
840
            #define CODED_SM2P256V1_SZ 6
841
        #else
842
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
843
            #define CODED_SM2P256V1_SZ 8
844
        #endif
845
        #ifndef WOLFSSL_ECC_CURVE_STATIC
846
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
847
        #else
848
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
849
        #endif
850
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
851
    #endif /* WOLFSSL_SM2 */
852
#ifdef ECC320
853
    #ifdef HAVE_ECC_BRAINPOOL
854
        #ifdef HAVE_OID_ENCODING
855
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
856
            #define CODED_BRAINPOOLP320R1_SZ 10
857
        #else
858
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
859
            #define CODED_BRAINPOOLP320R1_SZ 9
860
        #endif
861
        #ifndef WOLFSSL_ECC_CURVE_STATIC
862
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
863
        #else
864
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
865
        #endif
866
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
867
    #endif /* HAVE_ECC_BRAINPOOL */
868
#endif /* ECC320 */
869
#ifdef ECC384
870
    #ifndef NO_ECC_SECP
871
        #ifdef HAVE_OID_ENCODING
872
            #define CODED_SECP384R1    {1,3,132,0,34}
873
            #define CODED_SECP384R1_SZ 5
874
        #else
875
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
876
            #define CODED_SECP384R1_SZ 5
877
        #endif
878
        #ifndef WOLFSSL_ECC_CURVE_STATIC
879
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
880
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
881
        #else
882
            #define ecc_oid_secp384r1 CODED_SECP384R1
883
        #endif
884
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
885
    #endif /* !NO_ECC_SECP */
886
    #ifdef HAVE_ECC_BRAINPOOL
887
        #ifdef HAVE_OID_ENCODING
888
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
889
            #define CODED_BRAINPOOLP384R1_SZ 10
890
        #else
891
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
892
            #define CODED_BRAINPOOLP384R1_SZ 9
893
        #endif
894
        #ifndef WOLFSSL_ECC_CURVE_STATIC
895
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
896
        #else
897
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
898
        #endif
899
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
900
    #endif /* HAVE_ECC_BRAINPOOL */
901
#endif /* ECC384 */
902
#ifdef ECC512
903
    #ifdef HAVE_ECC_BRAINPOOL
904
        #ifdef HAVE_OID_ENCODING
905
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
906
            #define CODED_BRAINPOOLP512R1_SZ 10
907
        #else
908
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
909
            #define CODED_BRAINPOOLP512R1_SZ 9
910
        #endif
911
        #ifndef WOLFSSL_ECC_CURVE_STATIC
912
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
913
        #else
914
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
915
        #endif
916
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
917
    #endif /* HAVE_ECC_BRAINPOOL */
918
#endif /* ECC512 */
919
#ifdef ECC521
920
    #ifndef NO_ECC_SECP
921
        #ifdef HAVE_OID_ENCODING
922
            #define CODED_SECP521R1     {1,3,132,0,35}
923
            #define CODED_SECP521R1_SZ 5
924
        #else
925
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
926
            #define CODED_SECP521R1_SZ 5
927
        #endif
928
        #ifndef WOLFSSL_ECC_CURVE_STATIC
929
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
930
        #else
931
            #define ecc_oid_secp521r1 CODED_SECP521R1
932
        #endif
933
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
934
    #endif /* !NO_ECC_SECP */
935
#endif /* ECC521 */
936
937
938
/* This holds the key settings.
939
   ***MUST*** be organized by size from smallest to largest. */
940
941
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
942
    #undef ecc_sets
943
    #undef ecc_sets_count
944
#endif
945
946
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
947
static
948
#endif
949
const ecc_set_type ecc_sets[] = {
950
#ifdef ECC112
951
    #ifndef NO_ECC_SECP
952
    {
953
        14,                             /* size/bytes */
954
        ECC_SECP112R1,                  /* ID         */
955
        "SECP112R1",                    /* curve name */
956
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
957
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
958
        "659EF8BA043916EEDE8911702B22", /* B          */
959
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
960
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
961
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
962
        ecc_oid_secp112r1,              /* oid/oidSz  */
963
        ecc_oid_secp112r1_sz,
964
        ECC_SECP112R1_OID,              /* oid sum    */
965
        1,                              /* cofactor   */
966
    },
967
    #endif /* !NO_ECC_SECP */
968
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
969
    {
970
        14,                             /* size/bytes */
971
        ECC_SECP112R2,                  /* ID         */
972
        "SECP112R2",                    /* curve name */
973
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
974
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
975
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
976
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
977
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
978
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
979
        ecc_oid_secp112r2,              /* oid/oidSz  */
980
        ecc_oid_secp112r2_sz,
981
        ECC_SECP112R2_OID,              /* oid sum    */
982
        4,                              /* cofactor   */
983
    },
984
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
985
#endif /* ECC112 */
986
#ifdef ECC128
987
    #ifndef NO_ECC_SECP
988
    {
989
        16,                                 /* size/bytes */
990
        ECC_SECP128R1,                      /* ID         */
991
        "SECP128R1",                        /* curve name */
992
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
993
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
994
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
995
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
996
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
997
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
998
        ecc_oid_secp128r1,                  /* oid/oidSz  */
999
        ecc_oid_secp128r1_sz,
1000
        ECC_SECP128R1_OID,                  /* oid sum    */
1001
        1,                                  /* cofactor   */
1002
    },
1003
    #endif /* !NO_ECC_SECP */
1004
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
1005
    {
1006
        16,                                 /* size/bytes */
1007
        ECC_SECP128R2,                      /* ID         */
1008
        "SECP128R2",                        /* curve name */
1009
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1010
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
1011
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
1012
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
1013
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
1014
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
1015
        ecc_oid_secp128r2,                  /* oid/oidSz  */
1016
        ecc_oid_secp128r2_sz,
1017
        ECC_SECP128R2_OID,                  /* oid sum    */
1018
        4,                                  /* cofactor   */
1019
    },
1020
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
1021
#endif /* ECC128 */
1022
#ifdef ECC160
1023
#ifndef FP_ECC
1024
    #ifndef NO_ECC_SECP
1025
    {
1026
        20,                                         /* size/bytes */
1027
        ECC_SECP160R1,                              /* ID         */
1028
        "SECP160R1",                                /* curve name */
1029
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
1030
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
1031
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
1032
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
1033
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
1034
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
1035
        ecc_oid_secp160r1,                          /* oid/oidSz  */
1036
        ecc_oid_secp160r1_sz,
1037
        ECC_SECP160R1_OID,                          /* oid sum    */
1038
        1,                                          /* cofactor   */
1039
    },
1040
    #endif /* !NO_ECC_SECP */
1041
    #ifdef HAVE_ECC_SECPR2
1042
    {
1043
        20,                                         /* size/bytes */
1044
        ECC_SECP160R2,                              /* ID         */
1045
        "SECP160R2",                                /* curve name */
1046
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1047
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
1048
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
1049
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
1050
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
1051
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
1052
        ecc_oid_secp160r2,                          /* oid/oidSz  */
1053
        ecc_oid_secp160r2_sz,
1054
        ECC_SECP160R2_OID,                          /* oid sum    */
1055
        1,                                          /* cofactor   */
1056
    },
1057
    #endif /* HAVE_ECC_SECPR2 */
1058
    #ifdef HAVE_ECC_KOBLITZ
1059
    {
1060
        20,                                         /* size/bytes */
1061
        ECC_SECP160K1,                              /* ID         */
1062
        "SECP160K1",                                /* curve name */
1063
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1064
        "0000000000000000000000000000000000000000", /* A          */
1065
        "0000000000000000000000000000000000000007", /* B          */
1066
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
1067
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
1068
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
1069
        ecc_oid_secp160k1,                          /* oid/oidSz  */
1070
        ecc_oid_secp160k1_sz,
1071
        ECC_SECP160K1_OID,                          /* oid sum    */
1072
        1,                                          /* cofactor   */
1073
    },
1074
    #endif /* HAVE_ECC_KOBLITZ */
1075
#endif /* !FP_ECC */
1076
    #ifdef HAVE_ECC_BRAINPOOL
1077
    {
1078
        20,                                         /* size/bytes */
1079
        ECC_BRAINPOOLP160R1,                        /* ID         */
1080
        "BRAINPOOLP160R1",                          /* curve name */
1081
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
1082
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
1083
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
1084
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
1085
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
1086
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
1087
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1088
        ecc_oid_brainpoolp160r1_sz,
1089
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1090
        1,                                          /* cofactor   */
1091
    },
1092
    #endif /* HAVE_ECC_BRAINPOOL */
1093
#endif /* ECC160 */
1094
#ifdef ECC192
1095
    #ifndef NO_ECC_SECP
1096
    {
1097
        24,                                                 /* size/bytes */
1098
        ECC_SECP192R1,                                      /* ID         */
1099
        "SECP192R1",                                        /* curve name */
1100
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1101
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1102
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1103
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1104
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1105
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1106
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1107
        ecc_oid_secp192r1_sz,
1108
        ECC_SECP192R1_OID,                                  /* oid sum    */
1109
        1,                                                  /* cofactor   */
1110
    },
1111
    #endif /* !NO_ECC_SECP */
1112
    #ifdef HAVE_ECC_SECPR2
1113
    {
1114
        24,                                                 /* size/bytes */
1115
        ECC_PRIME192V2,                                     /* ID         */
1116
        "PRIME192V2",                                       /* curve name */
1117
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1118
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1119
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1120
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1121
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1122
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1123
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1124
        ecc_oid_prime192v2_sz,
1125
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1126
        1,                                                  /* cofactor   */
1127
    },
1128
    #endif /* HAVE_ECC_SECPR2 */
1129
    #ifdef HAVE_ECC_SECPR3
1130
    {
1131
        24,                                                 /* size/bytes */
1132
        ECC_PRIME192V3,                                     /* ID         */
1133
        "PRIME192V3",                                       /* curve name */
1134
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1135
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1136
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1137
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1138
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1139
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1140
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1141
        ecc_oid_prime192v3_sz,
1142
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1143
        1,                                                  /* cofactor   */
1144
    },
1145
    #endif /* HAVE_ECC_SECPR3 */
1146
    #ifdef HAVE_ECC_KOBLITZ
1147
    {
1148
        24,                                                 /* size/bytes */
1149
        ECC_SECP192K1,                                      /* ID         */
1150
        "SECP192K1",                                        /* curve name */
1151
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1152
        "000000000000000000000000000000000000000000000000", /* A          */
1153
        "000000000000000000000000000000000000000000000003", /* B          */
1154
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1155
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1156
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1157
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1158
        ecc_oid_secp192k1_sz,
1159
        ECC_SECP192K1_OID,                                  /* oid sum    */
1160
        1,                                                  /* cofactor   */
1161
    },
1162
    #endif /* HAVE_ECC_KOBLITZ */
1163
    #ifdef HAVE_ECC_BRAINPOOL
1164
    {
1165
        24,                                                 /* size/bytes */
1166
        ECC_BRAINPOOLP192R1,                                /* ID         */
1167
        "BRAINPOOLP192R1",                                  /* curve name */
1168
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1169
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1170
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1171
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1172
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1173
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1174
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1175
        ecc_oid_brainpoolp192r1_sz,
1176
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1177
        1,                                                  /* cofactor   */
1178
    },
1179
    #endif /* HAVE_ECC_BRAINPOOL */
1180
#endif /* ECC192 */
1181
#ifdef ECC224
1182
    #ifndef NO_ECC_SECP
1183
    {
1184
        28,                                                         /* size/bytes */
1185
        ECC_SECP224R1,                                              /* ID         */
1186
        "SECP224R1",                                                /* curve name */
1187
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1188
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1189
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1190
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1191
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1192
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1193
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1194
        ecc_oid_secp224r1_sz,
1195
        ECC_SECP224R1_OID,                                          /* oid sum    */
1196
        1,                                                          /* cofactor   */
1197
    },
1198
    #endif /* !NO_ECC_SECP */
1199
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1200
    {
1201
        28,                                                         /* size/bytes */
1202
        ECC_SECP224K1,                                              /* ID         */
1203
        "SECP224K1",                                                /* curve name */
1204
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1205
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1206
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1207
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1208
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1209
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1210
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1211
        ecc_oid_secp224k1_sz,
1212
        ECC_SECP224K1_OID,                                          /* oid sum    */
1213
        1,                                                          /* cofactor   */
1214
    },
1215
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1216
    #ifdef HAVE_ECC_BRAINPOOL
1217
    {
1218
        28,                                                         /* size/bytes */
1219
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1220
        "BRAINPOOLP224R1",                                          /* curve name */
1221
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1222
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1223
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1224
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1225
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1226
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1227
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1228
        ecc_oid_brainpoolp224r1_sz,
1229
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1230
        1,                                                          /* cofactor   */
1231
    },
1232
    #endif /* HAVE_ECC_BRAINPOOL */
1233
#endif /* ECC224 */
1234
#ifdef ECC239
1235
    #ifndef NO_ECC_SECP
1236
    {
1237
        30,                                                             /* size/bytes */
1238
        ECC_PRIME239V1,                                                 /* ID         */
1239
        "PRIME239V1",                                                   /* curve name */
1240
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1241
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1242
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1243
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1244
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1245
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1246
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1247
        ecc_oid_prime239v1_sz,
1248
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1249
        1,                                                              /* cofactor   */
1250
    },
1251
    #endif /* !NO_ECC_SECP */
1252
    #ifdef HAVE_ECC_SECPR2
1253
    {
1254
        30,                                                             /* size/bytes */
1255
        ECC_PRIME239V2,                                                 /* ID         */
1256
        "PRIME239V2",                                                   /* curve name */
1257
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1258
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1259
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1260
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1261
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1262
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1263
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1264
        ecc_oid_prime239v2_sz,
1265
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1266
        1,                                                              /* cofactor   */
1267
    },
1268
    #endif /* HAVE_ECC_SECPR2 */
1269
    #ifdef HAVE_ECC_SECPR3
1270
    {
1271
        30,                                                             /* size/bytes */
1272
        ECC_PRIME239V3,                                                 /* ID         */
1273
        "PRIME239V3",                                                   /* curve name */
1274
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1275
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1276
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1277
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1278
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1279
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1280
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1281
        ecc_oid_prime239v3_sz,
1282
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1283
        1,                                                              /* cofactor   */
1284
    },
1285
    #endif /* HAVE_ECC_SECPR3 */
1286
#endif /* ECC239 */
1287
#ifdef ECC256
1288
    #ifndef NO_ECC_SECP
1289
    {
1290
        32,                                                                 /* size/bytes */
1291
        ECC_SECP256R1,                                                      /* ID         */
1292
        "SECP256R1",                                                        /* curve name */
1293
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1294
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1295
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1296
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1297
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1298
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1299
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1300
        ecc_oid_secp256r1_sz,
1301
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1302
        1,                                                                  /* cofactor   */
1303
    },
1304
    #endif /* !NO_ECC_SECP */
1305
    #ifdef HAVE_ECC_KOBLITZ
1306
    {
1307
        32,                                                                 /* size/bytes */
1308
        ECC_SECP256K1,                                                      /* ID         */
1309
        "SECP256K1",                                                        /* curve name */
1310
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1311
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1312
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1313
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1314
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1315
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1316
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1317
        ecc_oid_secp256k1_sz,
1318
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1319
        1,                                                                  /* cofactor   */
1320
    },
1321
    #endif /* HAVE_ECC_KOBLITZ */
1322
    #ifdef HAVE_ECC_BRAINPOOL
1323
    {
1324
        32,                                                                 /* size/bytes */
1325
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1326
        "BRAINPOOLP256R1",                                                  /* curve name */
1327
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1328
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1329
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1330
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1331
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1332
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1333
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1334
        ecc_oid_brainpoolp256r1_sz,
1335
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1336
        1,                                                                  /* cofactor   */
1337
    },
1338
    #endif /* HAVE_ECC_BRAINPOOL */
1339
#endif /* ECC256 */
1340
    #if defined(WOLFSSL_SM2)
1341
    {
1342
        32,                                                     /* size/bytes */
1343
        ECC_SM2P256V1,                                          /* ID         */
1344
        "SM2P256V1",                                            /* curve name */
1345
1346
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1347
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1348
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1349
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1350
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1351
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1352
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1353
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1354
        ecc_oid_sm2p256v1_sz,
1355
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1356
        1,                                                      /* cofactor   */
1357
    },
1358
    #endif /* WOLFSSL_SM2 */
1359
#ifdef ECC320
1360
    #ifdef HAVE_ECC_BRAINPOOL
1361
    {
1362
        40,                                                                                 /* size/bytes */
1363
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1364
        "BRAINPOOLP320R1",                                                                  /* curve name */
1365
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1366
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1367
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1368
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1369
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1370
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1371
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1372
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1373
        1,                                                                                  /* cofactor   */
1374
    },
1375
    #endif /* HAVE_ECC_BRAINPOOL */
1376
#endif /* ECC320 */
1377
#ifdef ECC384
1378
    #ifndef NO_ECC_SECP
1379
    {
1380
        48,                                                                                                 /* size/bytes */
1381
        ECC_SECP384R1,                                                                                      /* ID         */
1382
        "SECP384R1",                                                                                        /* curve name */
1383
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1384
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1385
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1386
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1387
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1388
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1389
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1390
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1391
        1,                                                                                                  /* cofactor   */
1392
    },
1393
    #endif /* !NO_ECC_SECP */
1394
    #ifdef HAVE_ECC_BRAINPOOL
1395
    {
1396
        48,                                                                                                 /* size/bytes */
1397
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1398
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1399
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1400
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1401
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1402
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1403
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1404
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1405
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1406
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1407
        1,                                                                                                  /* cofactor   */
1408
    },
1409
    #endif /* HAVE_ECC_BRAINPOOL */
1410
#endif /* ECC384 */
1411
#ifdef ECC512
1412
    #ifdef HAVE_ECC_BRAINPOOL
1413
    {
1414
        64,                                                                                                                                 /* size/bytes */
1415
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1416
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1417
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1418
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1419
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1420
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1421
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1422
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1423
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1424
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1425
        1,                                                                                                                                  /* cofactor   */
1426
    },
1427
    #endif /* HAVE_ECC_BRAINPOOL */
1428
#endif /* ECC512 */
1429
#ifdef ECC521
1430
    #ifndef NO_ECC_SECP
1431
    {
1432
        66,                                                                                                                                    /* size/bytes */
1433
        ECC_SECP521R1,                                                                                                                         /* ID         */
1434
        "SECP521R1",                                                                                                                           /* curve name */
1435
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1436
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1437
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1438
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1439
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1440
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1441
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1442
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1443
        1,                                                                                                                                     /* cofactor   */
1444
    },
1445
    #endif /* !NO_ECC_SECP */
1446
#endif /* ECC521 */
1447
#ifdef WOLFCRYPT_HAVE_SAKKE
1448
    {
1449
        128,
1450
        ECC_SAKKE_1,
1451
        "SAKKE1",
1452
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1453
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1454
        "0",
1455
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1456
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1457
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1458
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1459
            NULL, 0,
1460
        #else
1461
            {0}, 0,
1462
        #endif
1463
        0,
1464
        4,
1465
    },
1466
#endif
1467
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1468
    /* place holder for custom curve index for cache */
1469
    {
1470
        1, /* non-zero */
1471
        ECC_CURVE_CUSTOM,
1472
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1473
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1474
        #else
1475
            {0},{0},{0},{0},{0},{0},{0},{0},
1476
        #endif
1477
        0, 0, 0
1478
    },
1479
#endif
1480
    {
1481
        0,
1482
        ECC_CURVE_INVALID,
1483
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1484
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1485
        #else
1486
            {0},{0},{0},{0},{0},{0},{0},{0},
1487
        #endif
1488
        0, 0, 0
1489
    }
1490
};
1491
55.5k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1492
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1493
static
1494
#endif
1495
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1496
1497
60.0k
const ecc_set_type *wc_ecc_get_sets(void) {
1498
60.0k
    return ecc_sets;
1499
60.0k
}
1500
0
size_t wc_ecc_get_sets_count(void) {
1501
0
    return ecc_sets_count;
1502
0
}
1503
1504
#ifdef HAVE_OID_ENCODING
1505
    /* encoded OID cache */
1506
    typedef struct {
1507
        word32 oidSz;
1508
        byte oid[ECC_MAX_OID_LEN];
1509
    } oid_cache_t;
1510
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1511
1512
    static wolfSSL_Mutex ecc_oid_cache_lock
1513
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1514
#ifndef WOLFSSL_MUTEX_INITIALIZER
1515
    static volatile int eccOidLockInit = 0;
1516
#endif
1517
#endif /* HAVE_OID_ENCODING */
1518
1519
/* Forward declarations */
1520
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1521
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1522
#endif
1523
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1524
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1525
    mp_int* prime, mp_int* order);
1526
#endif
1527
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1528
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1529
    !defined(WOLFSSL_KCAPI_ECC)
1530
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1531
#endif
1532
1533
1534
#ifdef HAVE_COMP_KEY
1535
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1536
    !defined(WOLFSSL_CRYPTOCELL)
1537
1538
#ifndef WOLFSSL_SP_MATH
1539
#if !defined(SQRTMOD_USE_MOD_EXP)
1540
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1541
#endif
1542
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1543
#endif
1544
#endif
1545
#endif
1546
1547
1548
/* Curve Specs */
1549
typedef struct ecc_curve_spec {
1550
    const ecc_set_type* dp;
1551
1552
    mp_int* prime;
1553
    mp_int* Af;
1554
    mp_int* Bf;
1555
    mp_int* order;
1556
    mp_int* Gx;
1557
    mp_int* Gy;
1558
1559
#ifdef ECC_CACHE_CURVE
1560
    mp_int prime_lcl;
1561
    mp_int Af_lcl;
1562
    mp_int Bf_lcl;
1563
    mp_int order_lcl;
1564
    mp_int Gx_lcl;
1565
    mp_int Gy_lcl;
1566
#else
1567
#ifdef WOLFSSL_SP_MATH_ALL
1568
    unsigned char* spec_ints;
1569
#else
1570
    mp_int* spec_ints;
1571
#endif
1572
    word32 spec_count;
1573
    word32 spec_use;
1574
#endif
1575
1576
    byte load_mask;
1577
} ecc_curve_spec;
1578
1579
    #define ECC_CURVE_FIELD_NONE    0x00
1580
181k
    #define ECC_CURVE_FIELD_PRIME   0x01
1581
181k
    #define ECC_CURVE_FIELD_AF      0x02
1582
179k
    #define ECC_CURVE_FIELD_BF      0x04
1583
161k
    #define ECC_CURVE_FIELD_ORDER   0x08
1584
133k
    #define ECC_CURVE_FIELD_GX      0x10
1585
133k
    #define ECC_CURVE_FIELD_GY      0x20
1586
12.8k
    #define ECC_CURVE_FIELD_ALL     0x3F
1587
    #define ECC_CURVE_FIELD_COUNT   6
1588
1589
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1590
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1591
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1592
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1593
};
1594
1595
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1596
{
1597
    word32 up, down;
1598
    up = 0;
1599
    down = len - 1;
1600
    while (up < len)
1601
        outbuf[up++] = inbuf[down--];
1602
}
1603
1604
static int xil_mpi_import(mp_int *mpi,
1605
                          const byte *inbuf,
1606
                          word32 len,
1607
                          void* heap)
1608
{
1609
    int err;
1610
#ifdef WOLFSSL_SMALL_STACK
1611
    byte* buf = NULL;
1612
#else
1613
    byte buf[MAX_ECC_BYTES];
1614
1615
    if (len > MAX_ECC_BYTES)
1616
        return BUFFER_E;
1617
#endif
1618
1619
    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
1620
        return MEMORY_E);
1621
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1622
    /* Register the stack buffer before it is filled so any future exit before
1623
     * the ForceZero is checked. XMEMSET makes it defined for registration. */
1624
    XMEMSET(buf, 0, len);
1625
    wc_MemZero_Add("xil_mpi_import buf", buf, len);
1626
#endif
1627
    buf_reverse(buf, inbuf, len);
1628
1629
    err = mp_read_unsigned_bin(mpi, buf, len);
1630
    ForceZero(buf, len);
1631
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1632
    wc_MemZero_Check(buf, len);
1633
#endif
1634
    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1635
    return err;
1636
}
1637
#endif
1638
1639
#ifdef ECC_CACHE_CURVE
1640
    /* cache (mp_int) of the curve parameters */
1641
    #ifdef WOLFSSL_NO_MALLOC
1642
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1643
    #else
1644
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1645
    #endif
1646
    #ifndef SINGLE_THREADED
1647
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1648
    #endif
1649
1650
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1651
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1652
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1653
#elif defined(WOLFSSL_SMALL_STACK)
1654
#ifdef WOLFSSL_SP_MATH_ALL
1655
    #define DECLARE_CURVE_SPECS(intcount)                               \
1656
23.5k
        unsigned char* spec_ints = NULL;                                \
1657
23.5k
        ecc_curve_spec curve_lcl;                                       \
1658
23.5k
        ecc_curve_spec* curve = &curve_lcl;                             \
1659
23.5k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1660
23.5k
        curve->spec_count = intcount
1661
1662
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1663
23.4k
    do {                                                                \
1664
23.4k
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1665
23.4k
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1666
23.4k
            DYNAMIC_TYPE_ECC);                                          \
1667
23.4k
        if (spec_ints == NULL)                                          \
1668
23.4k
            (err) = MEMORY_E;                                           \
1669
23.4k
        else {                                                          \
1670
23.0k
            curve->spec_ints = spec_ints;                               \
1671
23.0k
            (err) = MP_OKAY;                                            \
1672
23.0k
        }                                                               \
1673
23.4k
    } while (0)
1674
#else
1675
    #define DECLARE_CURVE_SPECS(intcount)                               \
1676
        mp_int* spec_ints = NULL;                                       \
1677
        ecc_curve_spec curve_lcl;                                       \
1678
        ecc_curve_spec* curve = &curve_lcl;                             \
1679
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1680
        curve->spec_count = intcount
1681
1682
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1683
    do {                                                                \
1684
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1685
                            DYNAMIC_TYPE_ECC);                          \
1686
        if (spec_ints == NULL)                                          \
1687
            (err) = MEMORY_E;                                           \
1688
        else {                                                          \
1689
            curve->spec_ints = spec_ints;                               \
1690
            (err) = MP_OKAY;                                            \
1691
        }                                                               \
1692
    } while (0)
1693
#endif
1694
    #define FREE_CURVE_SPECS()                                          \
1695
23.4k
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1696
#else
1697
#ifdef WOLFSSL_SP_MATH_ALL
1698
    #define DECLARE_CURVE_SPECS(intcount)                               \
1699
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1700
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1701
        ecc_curve_spec curve_lcl;                                       \
1702
        ecc_curve_spec* curve = &curve_lcl;                             \
1703
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1704
        curve->spec_ints = spec_ints;                                   \
1705
        curve->spec_count = (intcount)
1706
#else
1707
    #define DECLARE_CURVE_SPECS(intcount)                               \
1708
        mp_int spec_ints[(intcount)];                                   \
1709
        ecc_curve_spec curve_lcl;                                       \
1710
        ecc_curve_spec* curve = &curve_lcl;                             \
1711
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1712
        curve->spec_ints = spec_ints;                                   \
1713
        curve->spec_count = (intcount)
1714
#endif
1715
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1716
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1717
#endif /* ECC_CACHE_CURVE */
1718
1719
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1720
    byte mask)
1721
190k
{
1722
190k
    if (item) {
1723
    #ifdef HAVE_WOLF_BIGINT
1724
        wc_bigint_free(&item->raw);
1725
    #endif
1726
190k
        mp_clear(item);
1727
190k
    }
1728
190k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1729
190k
}
1730
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1731
47.3k
{
1732
47.3k
    if (curve == NULL) {
1733
0
        return;
1734
0
    }
1735
1736
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1737
39.7k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1738
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1739
39.7k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1740
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1741
39.0k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1742
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1743
32.0k
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1744
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1745
19.9k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1746
47.3k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1747
19.9k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1748
1749
47.3k
    curve->load_mask = 0;
1750
47.3k
}
1751
1752
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1753
47.3k
{
1754
47.3k
    if (curve) {
1755
    #ifdef ECC_CACHE_CURVE
1756
        #ifdef WOLFSSL_CUSTOM_CURVES
1757
        /* only free custom curves (rest are globally cached) */
1758
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1759
            wc_ecc_curve_cache_free_spec(curve);
1760
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1761
        }
1762
        #endif
1763
    #else
1764
47.3k
        wc_ecc_curve_cache_free_spec(curve);
1765
47.3k
    #endif
1766
47.3k
    }
1767
47.3k
}
1768
1769
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1770
    mp_int** dst, byte mask)
1771
127k
{
1772
127k
    int err;
1773
1774
127k
#ifndef ECC_CACHE_CURVE
1775
    /* get mp_int from temp */
1776
127k
    if (curve->spec_use >= curve->spec_count) {
1777
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1778
0
        return ECC_BAD_ARG_E;
1779
0
    }
1780
127k
#ifdef WOLFSSL_SP_MATH_ALL
1781
127k
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1782
127k
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1783
#else
1784
    *dst = &curve->spec_ints[curve->spec_use++];
1785
#endif
1786
127k
#endif
1787
1788
127k
#ifdef WOLFSSL_SP_MATH_ALL
1789
127k
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1790
#else
1791
    err = mp_init(*dst);
1792
#endif
1793
127k
    if (err == MP_OKAY) {
1794
127k
        curve->load_mask |= mask;
1795
1796
127k
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1797
1798
    #ifdef HAVE_WOLF_BIGINT
1799
        if (err == MP_OKAY)
1800
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1801
    #endif
1802
127k
    }
1803
127k
    return err;
1804
127k
}
1805
1806
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1807
    byte load_mask)
1808
46.1k
{
1809
46.1k
    int ret = 0;
1810
46.1k
    ecc_curve_spec* curve;
1811
46.1k
    byte load_items = 0; /* mask of items to load */
1812
#ifdef ECC_CACHE_CURVE
1813
    int x;
1814
#endif
1815
1816
46.1k
    if (dp == NULL || pCurve == NULL)
1817
0
        return BAD_FUNC_ARG;
1818
1819
#ifdef ECC_CACHE_CURVE
1820
    x = wc_ecc_get_curve_idx(dp->id);
1821
    if (x == ECC_CURVE_INVALID)
1822
        return ECC_BAD_ARG_E;
1823
1824
#if !defined(SINGLE_THREADED)
1825
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1826
    if (ret != 0) {
1827
        return ret;
1828
    }
1829
#endif
1830
1831
#ifdef WOLFSSL_NO_MALLOC
1832
    curve = &ecc_curve_spec_cache[x];
1833
#else
1834
    /* make sure cache has been allocated */
1835
    if (ecc_curve_spec_cache[x] == NULL
1836
    #ifdef WOLFSSL_CUSTOM_CURVES
1837
        || dp->id == ECC_CURVE_CUSTOM
1838
    #endif
1839
    ) {
1840
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1841
        if (curve == NULL) {
1842
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1843
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1844
        #endif
1845
            return MEMORY_E;
1846
        }
1847
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1848
1849
        /* set curve pointer to cache */
1850
    #ifdef WOLFSSL_CUSTOM_CURVES
1851
        if (dp->id != ECC_CURVE_CUSTOM)
1852
    #endif
1853
        {
1854
            ecc_curve_spec_cache[x] = curve;
1855
        }
1856
    }
1857
    else {
1858
        curve = ecc_curve_spec_cache[x];
1859
    }
1860
#endif /* WOLFSSL_NO_MALLOC */
1861
1862
    /* return new or cached curve */
1863
    *pCurve = curve;
1864
#else
1865
46.1k
    curve = *pCurve;
1866
46.1k
#endif /* ECC_CACHE_CURVE */
1867
1868
    /* make sure the curve is initialized */
1869
46.1k
    if (curve->dp != dp) {
1870
46.1k
        curve->load_mask = 0;
1871
1872
    #ifdef ECC_CACHE_CURVE
1873
        curve->prime = &curve->prime_lcl;
1874
        curve->Af = &curve->Af_lcl;
1875
        curve->Bf = &curve->Bf_lcl;
1876
        curve->order = &curve->order_lcl;
1877
        curve->Gx = &curve->Gx_lcl;
1878
        curve->Gy = &curve->Gy_lcl;
1879
    #endif
1880
46.1k
    }
1881
46.1k
    curve->dp = dp; /* set dp info */
1882
1883
    /* determine items to load */
1884
46.1k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1885
46.1k
    curve->load_mask |= load_items;
1886
1887
    /* load items */
1888
46.1k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1889
39.7k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1890
39.7k
            ECC_CURVE_FIELD_PRIME);
1891
46.1k
    if (load_items & ECC_CURVE_FIELD_AF)
1892
39.7k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1893
39.7k
            ECC_CURVE_FIELD_AF);
1894
46.1k
    if (load_items & ECC_CURVE_FIELD_BF)
1895
39.0k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1896
39.0k
            ECC_CURVE_FIELD_BF);
1897
46.1k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1898
32.0k
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1899
32.0k
            ECC_CURVE_FIELD_ORDER);
1900
46.1k
    if (load_items & ECC_CURVE_FIELD_GX)
1901
19.9k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1902
19.9k
            ECC_CURVE_FIELD_GX);
1903
46.1k
    if (load_items & ECC_CURVE_FIELD_GY)
1904
19.9k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1905
19.9k
            ECC_CURVE_FIELD_GY);
1906
1907
    /* check for error */
1908
46.1k
    if (ret != 0) {
1909
0
        wc_ecc_curve_free(curve);
1910
0
        ret = MP_READ_E;
1911
0
    }
1912
1913
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1914
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1915
#endif
1916
1917
46.1k
    return ret;
1918
46.1k
}
1919
1920
#ifdef ECC_CACHE_CURVE
1921
int wc_ecc_curve_cache_init(void)
1922
{
1923
    int ret = 0;
1924
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1925
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1926
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1927
#endif
1928
    return ret;
1929
}
1930
1931
void wc_ecc_curve_cache_free(void)
1932
{
1933
    int x;
1934
    /* free all ECC curve caches */
1935
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1936
    #ifdef WOLFSSL_NO_MALLOC
1937
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1938
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1939
    #else
1940
        if (ecc_curve_spec_cache[x]) {
1941
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1942
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1943
            ecc_curve_spec_cache[x] = NULL;
1944
        }
1945
    #endif /* WOLFSSL_NO_MALLOC */
1946
    }
1947
1948
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1949
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1950
    wc_FreeMutex(&ecc_curve_cache_mutex);
1951
#endif
1952
}
1953
#endif /* ECC_CACHE_CURVE */
1954
1955
1956
/* Retrieve the curve name for the ECC curve id.
1957
 *
1958
 * curve_id  The id of the curve.
1959
 * returns the name stored from the curve if available, otherwise NULL.
1960
 */
1961
const char* wc_ecc_get_name(int curve_id)
1962
9.18k
{
1963
9.18k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1964
9.18k
    if (curve_idx == ECC_CURVE_INVALID)
1965
34
        return NULL;
1966
9.14k
    return ecc_sets[curve_idx].name;
1967
9.18k
}
1968
1969
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1970
39.7k
{
1971
39.7k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1972
0
        return BAD_FUNC_ARG;
1973
0
    }
1974
1975
39.7k
    if (keysize > ECC_MAXSIZE) {
1976
551
        return ECC_BAD_ARG_E;
1977
551
    }
1978
1979
    /* handle custom case */
1980
39.1k
    if (key->idx != ECC_CUSTOM_IDX) {
1981
38.7k
        int x;
1982
1983
        /* default values */
1984
38.7k
        key->idx = 0;
1985
38.7k
        key->dp = NULL;
1986
1987
        /* find ecc_set based on curve_id or key size */
1988
498k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1989
498k
            if (curve_id > ECC_CURVE_DEF) {
1990
390k
                if (curve_id == ecc_sets[x].id)
1991
33.1k
                  break;
1992
390k
            }
1993
108k
            else if (keysize <= ecc_sets[x].size) {
1994
5.42k
                break;
1995
5.42k
            }
1996
498k
        }
1997
38.7k
        if (ecc_sets[x].size == 0) {
1998
151
            WOLFSSL_MSG("ECC Curve not found");
1999
151
            return ECC_CURVE_OID_E;
2000
151
        }
2001
2002
38.6k
        key->idx = x;
2003
38.6k
        key->dp  = &ecc_sets[x];
2004
38.6k
    }
2005
2006
39.0k
    return 0;
2007
39.1k
}
2008
2009
2010
#ifdef ALT_ECC_SIZE
2011
static void alt_fp_init(mp_int* a)
2012
{
2013
    a->size = FP_SIZE_ECC;
2014
    mp_zero(a);
2015
}
2016
#endif /* ALT_ECC_SIZE */
2017
2018
2019
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
2020
    !defined(WOLFSSL_CRYPTOCELL) && \
2021
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
2022
      defined(WOLFSSL_IMXRT1170_CAAM))
2023
2024
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
2025
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2026
                                     mp_int* modulus, mp_digit mp);
2027
2028
/**
2029
   Add two ECC points
2030
   P        The point to add
2031
   Q        The point to add
2032
   R        [out] The destination of the double
2033
   a        ECC curve parameter a
2034
   modulus  The modulus of the field the ECC curve is in
2035
   mp       The "b" value from montgomery_setup()
2036
   return   MP_OKAY on success
2037
*/
2038
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2039
                                     mp_int* a, mp_int* modulus, mp_digit mp)
2040
3.67M
{
2041
3.67M
#if !defined(WOLFSSL_SP_MATH)
2042
3.67M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2043
3.67M
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2044
#ifdef ALT_ECC_SIZE
2045
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2046
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2047
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2048
#endif
2049
3.67M
   mp_int  *x, *y, *z;
2050
3.67M
   int     err;
2051
2052
3.67M
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2053
0
       return WC_KEY_SIZE_E;
2054
0
   }
2055
2056
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
2057
3.67M
   if (Q == R) {
2058
0
      ecc_point* tPt  = P;
2059
0
      P = Q;
2060
0
      Q = tPt;
2061
0
   }
2062
2063
3.67M
#ifdef WOLFSSL_SMALL_STACK
2064
#ifdef WOLFSSL_SMALL_STACK_CACHE
2065
   if (R->key != NULL) {
2066
       t1 = R->key->t1;
2067
       t2 = R->key->t2;
2068
#ifdef ALT_ECC_SIZE
2069
       rx = R->key->x;
2070
       ry = R->key->y;
2071
       rz = R->key->z;
2072
#endif
2073
   }
2074
   else
2075
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2076
3.67M
#endif /* WOLFSSL_SMALL_STACK */
2077
3.67M
   {
2078
3.67M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2079
3.67M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2080
3.67M
   #ifdef MP_INT_SIZE_CHECK_NULL
2081
3.67M
      if (t1 == NULL || t2 == NULL) {
2082
139
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2083
139
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2084
139
         return MEMORY_E;
2085
139
      }
2086
3.67M
   #endif
2087
#ifdef ALT_ECC_SIZE
2088
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2089
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2090
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2091
   #ifdef MP_INT_SIZE_CHECK_NULL
2092
      if (rx == NULL || ry == NULL || rz == NULL) {
2093
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2094
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2095
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2096
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2097
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2098
         return MEMORY_E;
2099
      }
2100
   #endif
2101
#endif
2102
3.67M
   }
2103
2104
3.67M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2105
3.67M
   if (err == MP_OKAY) {
2106
3.67M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2107
3.67M
   }
2108
3.67M
   if (err != MP_OKAY) {
2109
0
#ifdef WOLFSSL_SMALL_STACK
2110
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2111
      if (R->key == NULL)
2112
   #endif
2113
0
#endif
2114
0
      {
2115
      #ifdef ALT_ECC_SIZE
2116
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2117
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2118
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2119
      #endif
2120
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2121
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2122
0
      }
2123
0
      return err;
2124
0
   }
2125
2126
   /* should we dbl instead? */
2127
3.67M
   if (err == MP_OKAY) {
2128
3.67M
#ifdef ECC_TIMING_RESISTANT
2129
3.67M
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2130
#else
2131
      err = mp_sub(modulus, Q->y, t1);
2132
#endif
2133
3.67M
   }
2134
3.67M
   if (err == MP_OKAY) {
2135
3.67M
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2136
4.74k
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2137
180
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2138
146
          mp_clear(t1);
2139
146
          mp_clear(t2);
2140
146
   #ifdef WOLFSSL_SMALL_STACK
2141
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2142
         if (R->key == NULL)
2143
      #endif
2144
146
   #endif
2145
146
         {
2146
         #ifdef ALT_ECC_SIZE
2147
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2148
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2149
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2150
         #endif
2151
146
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2152
146
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2153
146
         }
2154
146
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2155
146
      }
2156
3.67M
   }
2157
2158
3.67M
   if (err != MP_OKAY) {
2159
0
      goto done;
2160
0
   }
2161
2162
/* If use ALT_ECC_SIZE we need to use local stack variable since
2163
   ecc_point x,y,z is reduced size */
2164
#ifdef ALT_ECC_SIZE
2165
   /* Use local stack variable */
2166
   x = rx;
2167
   y = ry;
2168
   z = rz;
2169
2170
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2171
   if (err == MP_OKAY) {
2172
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2173
   }
2174
   if (err == MP_OKAY) {
2175
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2176
   }
2177
   if (err != MP_OKAY) {
2178
      goto done;
2179
   }
2180
#else
2181
   /* Use destination directly */
2182
3.67M
   x = R->x;
2183
3.67M
   y = R->y;
2184
3.67M
   z = R->z;
2185
3.67M
#endif
2186
2187
3.67M
   if (err == MP_OKAY)
2188
3.67M
       err = mp_copy(P->x, x);
2189
3.67M
   if (err == MP_OKAY)
2190
3.67M
       err = mp_copy(P->y, y);
2191
3.67M
   if (err == MP_OKAY)
2192
3.67M
       err = mp_copy(P->z, z);
2193
2194
   /* if Z is one then these are no-operations */
2195
3.67M
   if (err == MP_OKAY) {
2196
3.67M
       if (!mp_iszero(Q->z)) {
2197
           /* T1 = Z' * Z' */
2198
3.67M
           err = mp_sqr(Q->z, t1);
2199
3.67M
           if (err == MP_OKAY)
2200
3.67M
               err = mp_montgomery_reduce(t1, modulus, mp);
2201
2202
           /* X = X * T1 */
2203
3.67M
           if (err == MP_OKAY)
2204
3.67M
               err = mp_mul(t1, x, x);
2205
3.67M
           if (err == MP_OKAY)
2206
3.67M
               err = mp_montgomery_reduce(x, modulus, mp);
2207
2208
           /* T1 = Z' * T1 */
2209
3.67M
           if (err == MP_OKAY)
2210
3.67M
               err = mp_mul(Q->z, t1, t1);
2211
3.67M
           if (err == MP_OKAY)
2212
3.67M
               err = mp_montgomery_reduce(t1, modulus, mp);
2213
2214
           /* Y = Y * T1 */
2215
3.67M
           if (err == MP_OKAY)
2216
3.67M
               err = mp_mul(t1, y, y);
2217
3.67M
           if (err == MP_OKAY)
2218
3.67M
               err = mp_montgomery_reduce(y, modulus, mp);
2219
3.67M
       }
2220
3.67M
   }
2221
2222
   /* T1 = Z*Z */
2223
3.67M
   if (err == MP_OKAY)
2224
3.67M
       err = mp_sqr(z, t1);
2225
3.67M
   if (err == MP_OKAY)
2226
3.67M
       err = mp_montgomery_reduce(t1, modulus, mp);
2227
2228
   /* T2 = X' * T1 */
2229
3.67M
   if (err == MP_OKAY)
2230
3.67M
       err = mp_mul(Q->x, t1, t2);
2231
3.67M
   if (err == MP_OKAY)
2232
3.67M
       err = mp_montgomery_reduce(t2, modulus, mp);
2233
2234
   /* T1 = Z * T1 */
2235
3.67M
   if (err == MP_OKAY)
2236
3.67M
       err = mp_mul(z, t1, t1);
2237
3.67M
   if (err == MP_OKAY)
2238
3.67M
       err = mp_montgomery_reduce(t1, modulus, mp);
2239
2240
   /* T1 = Y' * T1 */
2241
3.67M
   if (err == MP_OKAY)
2242
3.67M
       err = mp_mul(Q->y, t1, t1);
2243
3.67M
   if (err == MP_OKAY)
2244
3.66M
       err = mp_montgomery_reduce(t1, modulus, mp);
2245
2246
   /* Y = Y - T1 */
2247
3.67M
   if (err == MP_OKAY)
2248
3.66M
       err = mp_submod_ct(y, t1, modulus, y);
2249
   /* T1 = 2T1 */
2250
3.67M
   if (err == MP_OKAY)
2251
3.66M
       err = mp_addmod_ct(t1, t1, modulus, t1);
2252
   /* T1 = Y + T1 */
2253
3.67M
   if (err == MP_OKAY)
2254
3.66M
       err = mp_addmod_ct(t1, y, modulus, t1);
2255
   /* X = X - T2 */
2256
3.67M
   if (err == MP_OKAY)
2257
3.66M
       err = mp_submod_ct(x, t2, modulus, x);
2258
   /* T2 = 2T2 */
2259
3.67M
   if (err == MP_OKAY)
2260
3.66M
       err = mp_addmod_ct(t2, t2, modulus, t2);
2261
   /* T2 = X + T2 */
2262
3.67M
   if (err == MP_OKAY)
2263
3.66M
       err = mp_addmod_ct(t2, x, modulus, t2);
2264
2265
3.67M
   if (err == MP_OKAY) {
2266
3.66M
       if (!mp_iszero(Q->z)) {
2267
           /* Z = Z * Z' */
2268
3.66M
           err = mp_mul(z, Q->z, z);
2269
3.66M
           if (err == MP_OKAY)
2270
3.66M
               err = mp_montgomery_reduce(z, modulus, mp);
2271
3.66M
       }
2272
3.66M
   }
2273
2274
   /* Z = Z * X */
2275
3.67M
   if (err == MP_OKAY)
2276
3.66M
       err = mp_mul(z, x, z);
2277
3.67M
   if (err == MP_OKAY)
2278
3.66M
       err = mp_montgomery_reduce(z, modulus, mp);
2279
2280
   /* T1 = T1 * X  */
2281
3.67M
   if (err == MP_OKAY)
2282
3.66M
       err = mp_mul(t1, x, t1);
2283
3.67M
   if (err == MP_OKAY)
2284
3.66M
       err = mp_montgomery_reduce(t1, modulus, mp);
2285
2286
   /* X = X * X */
2287
3.67M
   if (err == MP_OKAY)
2288
3.66M
       err = mp_sqr(x, x);
2289
3.67M
   if (err == MP_OKAY)
2290
3.66M
       err = mp_montgomery_reduce(x, modulus, mp);
2291
2292
   /* T2 = T2 * x */
2293
3.67M
   if (err == MP_OKAY)
2294
3.66M
       err = mp_mul(t2, x, t2);
2295
3.67M
   if (err == MP_OKAY)
2296
3.66M
       err = mp_montgomery_reduce(t2, modulus, mp);
2297
2298
   /* T1 = T1 * X  */
2299
3.67M
   if (err == MP_OKAY)
2300
3.66M
       err = mp_mul(t1, x, t1);
2301
3.67M
   if (err == MP_OKAY)
2302
3.66M
       err = mp_montgomery_reduce(t1, modulus, mp);
2303
2304
   /* X = Y*Y */
2305
3.67M
   if (err == MP_OKAY)
2306
3.66M
       err = mp_sqr(y, x);
2307
3.67M
   if (err == MP_OKAY)
2308
3.66M
       err = mp_montgomery_reduce(x, modulus, mp);
2309
2310
   /* X = X - T2 */
2311
3.67M
   if (err == MP_OKAY)
2312
3.66M
       err = mp_submod_ct(x, t2, modulus, x);
2313
   /* T2 = T2 - X */
2314
3.67M
   if (err == MP_OKAY)
2315
3.66M
       err = mp_submod_ct(t2, x, modulus, t2);
2316
   /* T2 = T2 - X */
2317
3.67M
   if (err == MP_OKAY)
2318
3.66M
       err = mp_submod_ct(t2, x, modulus, t2);
2319
   /* T2 = T2 * Y */
2320
3.67M
   if (err == MP_OKAY)
2321
3.66M
       err = mp_mul(t2, y, t2);
2322
3.67M
   if (err == MP_OKAY)
2323
3.66M
       err = mp_montgomery_reduce(t2, modulus, mp);
2324
2325
   /* Y = T2 - T1 */
2326
3.67M
   if (err == MP_OKAY)
2327
3.66M
       err = mp_submod_ct(t2, t1, modulus, y);
2328
   /* Y = Y/2 */
2329
3.67M
   if (err == MP_OKAY)
2330
3.66M
       err = mp_div_2_mod_ct(y, modulus, y);
2331
2332
#ifdef ALT_ECC_SIZE
2333
   if (err == MP_OKAY)
2334
       err = mp_copy(x, R->x);
2335
   if (err == MP_OKAY)
2336
       err = mp_copy(y, R->y);
2337
   if (err == MP_OKAY)
2338
       err = mp_copy(z, R->z);
2339
#endif
2340
2341
3.67M
done:
2342
2343
   /* clean up */
2344
3.67M
   mp_clear(t1);
2345
3.67M
   mp_clear(t2);
2346
3.67M
#ifdef WOLFSSL_SMALL_STACK
2347
#ifdef WOLFSSL_SMALL_STACK_CACHE
2348
   if (R->key == NULL)
2349
#endif
2350
3.67M
#endif
2351
3.67M
   {
2352
   #ifdef ALT_ECC_SIZE
2353
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2354
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2355
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2356
   #endif
2357
3.67M
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2358
3.67M
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2359
3.67M
   }
2360
2361
3.67M
   return err;
2362
#else
2363
    int modBits = mp_count_bits(modulus);
2364
2365
    (void)a;
2366
    (void)mp;
2367
2368
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2369
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2370
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2371
                                            R->x, R->y, R->z);
2372
    }
2373
#endif
2374
#ifndef WOLFSSL_SP_NO_256
2375
    if (modBits == 256) {
2376
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2377
                                         R->x, R->y, R->z);
2378
    }
2379
#endif
2380
#ifdef WOLFSSL_SP_384
2381
    if (modBits == 384) {
2382
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2383
                                         R->x, R->y, R->z);
2384
    }
2385
#endif
2386
#ifdef WOLFSSL_SP_521
2387
    if (modBits == 521) {
2388
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2389
                                         R->x, R->y, R->z);
2390
    }
2391
#endif
2392
    return ECC_BAD_ARG_E;
2393
#endif
2394
3.67M
}
2395
2396
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2397
                             mp_int* a, mp_int* modulus, mp_digit mp)
2398
2.27k
{
2399
2.27k
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2400
0
        return ECC_BAD_ARG_E;
2401
0
    }
2402
2403
2.27k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2404
2.24k
        mp_cmp(P->y, modulus) != MP_LT ||
2405
2.21k
        mp_cmp(P->z, modulus) != MP_LT ||
2406
2.21k
        mp_cmp(Q->x, modulus) != MP_LT ||
2407
2.18k
        mp_cmp(Q->y, modulus) != MP_LT ||
2408
2.14k
        mp_cmp(Q->z, modulus) != MP_LT) {
2409
128
        return ECC_OUT_OF_RANGE_E;
2410
128
    }
2411
2412
2.14k
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2413
2.27k
}
2414
2415
/* ### Point doubling in Jacobian coordinate system ###
2416
 *
2417
 * let us have a curve:                 y^2 = x^3 + a*x + b
2418
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2419
 *
2420
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2421
 * Xr = M^2 - 2*S
2422
 * Yr = M * (S - Xr) - 8*T
2423
 * Zr = 2 * Yp * Zp
2424
 *
2425
 * M = 3 * Xp^2 + a*Zp^4
2426
 * T = Yp^4
2427
 * S = 4 * Xp * Yp^2
2428
 *
2429
 * SPECIAL CASE: when a == 3 we can compute M as
2430
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2431
 */
2432
2433
/**
2434
   Double an ECC point
2435
   P   The point to double
2436
   R   [out] The destination of the double
2437
   a   ECC curve parameter a
2438
   modulus  The modulus of the field the ECC curve is in
2439
   mp       The "b" value from montgomery_setup()
2440
   return   MP_OKAY on success
2441
*/
2442
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2443
                                     mp_int* modulus, mp_digit mp)
2444
3.81M
{
2445
3.81M
#if !defined(WOLFSSL_SP_MATH)
2446
3.81M
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2447
3.81M
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2448
#ifdef ALT_ECC_SIZE
2449
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2450
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2451
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2452
#endif
2453
3.81M
   mp_int *x, *y, *z;
2454
3.81M
   int    err;
2455
2456
3.81M
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2457
0
       return WC_KEY_SIZE_E;
2458
0
   }
2459
2460
3.81M
#ifdef WOLFSSL_SMALL_STACK
2461
#ifdef WOLFSSL_SMALL_STACK_CACHE
2462
   if (R->key != NULL) {
2463
       t1 = R->key->t1;
2464
       t2 = R->key->t2;
2465
   #ifdef ALT_ECC_SIZE
2466
       rx = R->key->x;
2467
       ry = R->key->y;
2468
       rz = R->key->z;
2469
   #endif
2470
   }
2471
   else
2472
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2473
3.81M
#endif
2474
3.81M
   {
2475
3.81M
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2476
3.81M
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2477
3.81M
   #ifdef MP_INT_SIZE_CHECK_NULL
2478
3.81M
      if (t1 == NULL || t2 == NULL) {
2479
157
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2480
157
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2481
157
         return MEMORY_E;
2482
157
      }
2483
3.81M
   #endif
2484
   #ifdef ALT_ECC_SIZE
2485
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2486
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2487
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2488
   #ifdef MP_INT_SIZE_CHECK_NULL
2489
      if (rx == NULL || ry == NULL || rz == NULL) {
2490
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2491
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2492
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2493
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2494
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2495
          return MEMORY_E;
2496
      }
2497
   #endif
2498
   #endif
2499
3.81M
   }
2500
2501
3.81M
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2502
3.81M
   if (err == MP_OKAY) {
2503
3.81M
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2504
3.81M
   }
2505
3.81M
   if (err != MP_OKAY) {
2506
0
#ifdef WOLFSSL_SMALL_STACK
2507
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2508
      if (R->key == NULL)
2509
   #endif
2510
0
#endif
2511
0
      {
2512
      #ifdef ALT_ECC_SIZE
2513
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2514
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2515
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2516
      #endif
2517
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2518
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2519
0
      }
2520
0
      return err;
2521
0
   }
2522
2523
/* If use ALT_ECC_SIZE we need to use local stack variable since
2524
   ecc_point x,y,z is reduced size */
2525
#ifdef ALT_ECC_SIZE
2526
   /* Use local stack variable */
2527
   x = rx;
2528
   y = ry;
2529
   z = rz;
2530
2531
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2532
   if (err == MP_OKAY) {
2533
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2534
   }
2535
   if (err == MP_OKAY) {
2536
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2537
   }
2538
   if (err != MP_OKAY) {
2539
#ifdef WOLFSSL_SMALL_STACK
2540
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2541
      if (R->key == NULL)
2542
   #endif
2543
#endif
2544
      {
2545
      #ifdef ALT_ECC_SIZE
2546
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2547
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2548
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2549
      #endif
2550
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2551
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2552
      }
2553
      return err;
2554
   }
2555
#else
2556
   /* Use destination directly */
2557
3.81M
   x = R->x;
2558
3.81M
   y = R->y;
2559
3.81M
   z = R->z;
2560
3.81M
#endif
2561
2562
3.81M
   if (err == MP_OKAY)
2563
3.81M
       err = mp_copy(P->x, x);
2564
3.81M
   if (err == MP_OKAY)
2565
3.81M
       err = mp_copy(P->y, y);
2566
3.81M
   if (err == MP_OKAY)
2567
3.81M
       err = mp_copy(P->z, z);
2568
2569
   /* T1 = Z * Z */
2570
3.81M
   if (err == MP_OKAY)
2571
3.81M
       err = mp_sqr(z, t1);
2572
3.81M
   if (err == MP_OKAY)
2573
3.81M
       err = mp_montgomery_reduce(t1, modulus, mp);
2574
2575
   /* Z = Y * Z */
2576
3.81M
   if (err == MP_OKAY)
2577
3.81M
       err = mp_mul(z, y, z);
2578
3.81M
   if (err == MP_OKAY)
2579
3.81M
       err = mp_montgomery_reduce(z, modulus, mp);
2580
2581
   /* Z = 2Z */
2582
3.81M
   if (err == MP_OKAY)
2583
3.81M
       err = mp_addmod_ct(z, z, modulus, z);
2584
2585
   /* Determine if curve "a" should be used in calc */
2586
3.81M
#ifdef WOLFSSL_CUSTOM_CURVES
2587
3.81M
   if (err == MP_OKAY) {
2588
      /* Use a and prime to determine if a == 3 */
2589
3.81M
      err = mp_submod(modulus, a, modulus, t2);
2590
3.81M
   }
2591
3.81M
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2592
      /* T2 = X * X */
2593
521k
      err = mp_sqr(x, t2);
2594
521k
      if (err == MP_OKAY)
2595
521k
          err = mp_montgomery_reduce(t2, modulus, mp);
2596
      /* T1 = T2 + T1 */
2597
521k
      if (err == MP_OKAY)
2598
521k
          err = mp_addmod_ct(t2, t2, modulus, t1);
2599
      /* T1 = T2 + T1 */
2600
521k
      if (err == MP_OKAY)
2601
521k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2602
521k
   }
2603
3.29M
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2604
      /* use "a" in calc */
2605
2606
      /* T2 = T1 * T1 */
2607
660k
      err = mp_sqr(t1, t2);
2608
660k
      if (err == MP_OKAY)
2609
660k
          err = mp_montgomery_reduce(t2, modulus, mp);
2610
      /* T1 = T2 * a */
2611
660k
      if (err == MP_OKAY)
2612
660k
          err = mp_mulmod(t2, a, modulus, t1);
2613
      /* T2 = X * X */
2614
660k
      if (err == MP_OKAY)
2615
660k
          err = mp_sqr(x, t2);
2616
660k
      if (err == MP_OKAY)
2617
660k
          err = mp_montgomery_reduce(t2, modulus, mp);
2618
      /* T1 = T2 + T1 */
2619
660k
      if (err == MP_OKAY)
2620
660k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2621
      /* T1 = T2 + T1 */
2622
660k
      if (err == MP_OKAY)
2623
660k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2624
      /* T1 = T2 + T1 */
2625
660k
      if (err == MP_OKAY)
2626
660k
          err = mp_addmod_ct(t1, t2, modulus, t1);
2627
660k
   }
2628
2.63M
   else
2629
2.63M
#endif /* WOLFSSL_CUSTOM_CURVES */
2630
2.63M
   {
2631
      /* assumes "a" == 3 */
2632
2.63M
      (void)a;
2633
2634
      /* T2 = X - T1 */
2635
2.63M
      if (err == MP_OKAY)
2636
2.63M
          err = mp_submod_ct(x, t1, modulus, t2);
2637
      /* T1 = X + T1 */
2638
2.63M
      if (err == MP_OKAY)
2639
2.63M
          err = mp_addmod_ct(t1, x, modulus, t1);
2640
      /* T2 = T1 * T2 */
2641
2.63M
      if (err == MP_OKAY)
2642
2.63M
          err = mp_mul(t1, t2, t2);
2643
2.63M
      if (err == MP_OKAY)
2644
2.63M
          err = mp_montgomery_reduce(t2, modulus, mp);
2645
2646
      /* T1 = 2T2 */
2647
2.63M
      if (err == MP_OKAY)
2648
2.63M
          err = mp_addmod_ct(t2, t2, modulus, t1);
2649
      /* T1 = T1 + T2 */
2650
2.63M
      if (err == MP_OKAY)
2651
2.63M
          err = mp_addmod_ct(t1, t2, modulus, t1);
2652
2.63M
   }
2653
2654
   /* Y = 2Y */
2655
3.81M
   if (err == MP_OKAY)
2656
3.81M
       err = mp_addmod_ct(y, y, modulus, y);
2657
   /* Y = Y * Y */
2658
3.81M
   if (err == MP_OKAY)
2659
3.81M
       err = mp_sqr(y, y);
2660
3.81M
   if (err == MP_OKAY)
2661
3.81M
       err = mp_montgomery_reduce(y, modulus, mp);
2662
2663
   /* T2 = Y * Y */
2664
3.81M
   if (err == MP_OKAY)
2665
3.81M
       err = mp_sqr(y, t2);
2666
3.81M
   if (err == MP_OKAY)
2667
3.81M
       err = mp_montgomery_reduce(t2, modulus, mp);
2668
2669
   /* T2 = T2/2 */
2670
3.81M
   if (err == MP_OKAY)
2671
3.81M
       err = mp_div_2_mod_ct(t2, modulus, t2);
2672
2673
   /* Y = Y * X */
2674
3.81M
   if (err == MP_OKAY)
2675
3.81M
       err = mp_mul(y, x, y);
2676
3.81M
   if (err == MP_OKAY)
2677
3.81M
       err = mp_montgomery_reduce(y, modulus, mp);
2678
2679
   /* X = T1 * T1 */
2680
3.81M
   if (err == MP_OKAY)
2681
3.81M
       err = mp_sqr(t1, x);
2682
3.81M
   if (err == MP_OKAY)
2683
3.81M
       err = mp_montgomery_reduce(x, modulus, mp);
2684
2685
   /* X = X - Y */
2686
3.81M
   if (err == MP_OKAY)
2687
3.81M
       err = mp_submod_ct(x, y, modulus, x);
2688
   /* X = X - Y */
2689
3.81M
   if (err == MP_OKAY)
2690
3.81M
       err = mp_submod_ct(x, y, modulus, x);
2691
2692
   /* Y = Y - X */
2693
3.81M
   if (err == MP_OKAY)
2694
3.81M
       err = mp_submod_ct(y, x, modulus, y);
2695
   /* Y = Y * T1 */
2696
3.81M
   if (err == MP_OKAY)
2697
3.81M
       err = mp_mul(y, t1, y);
2698
3.81M
   if (err == MP_OKAY)
2699
3.81M
       err = mp_montgomery_reduce(y, modulus, mp);
2700
2701
   /* Y = Y - T2 */
2702
3.81M
   if (err == MP_OKAY)
2703
3.81M
       err = mp_submod_ct(y, t2, modulus, y);
2704
2705
#ifdef ALT_ECC_SIZE
2706
   if (err == MP_OKAY)
2707
       err = mp_copy(x, R->x);
2708
   if (err == MP_OKAY)
2709
       err = mp_copy(y, R->y);
2710
   if (err == MP_OKAY)
2711
       err = mp_copy(z, R->z);
2712
#endif
2713
2714
   /* clean up */
2715
3.81M
   mp_clear(t1);
2716
3.81M
   mp_clear(t2);
2717
2718
3.81M
#ifdef WOLFSSL_SMALL_STACK
2719
#ifdef WOLFSSL_SMALL_STACK_CACHE
2720
   if (R->key == NULL)
2721
#endif
2722
3.81M
#endif
2723
3.81M
   {
2724
    #ifdef ALT_ECC_SIZE
2725
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2726
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2727
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2728
    #endif
2729
3.81M
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2730
3.81M
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2731
3.81M
    }
2732
2733
3.81M
   return err;
2734
#else
2735
    int modBits = mp_count_bits(modulus);
2736
2737
    (void)a;
2738
    (void)mp;
2739
2740
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2741
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2742
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2743
    }
2744
#endif
2745
#ifndef WOLFSSL_SP_NO_256
2746
    if (modBits == 256) {
2747
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2748
    }
2749
#endif
2750
#ifdef WOLFSSL_SP_384
2751
    if (modBits == 384) {
2752
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2753
    }
2754
#endif
2755
#ifdef WOLFSSL_SP_521
2756
    if (modBits == 521) {
2757
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2758
    }
2759
#endif
2760
    return ECC_BAD_ARG_E;
2761
#endif
2762
3.81M
}
2763
2764
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2765
                             mp_int* modulus, mp_digit mp)
2766
3.03k
{
2767
3.03k
    if (P == NULL || R == NULL || modulus == NULL)
2768
0
        return ECC_BAD_ARG_E;
2769
2770
3.03k
    if (mp_cmp(P->x, modulus) != MP_LT ||
2771
3.00k
        mp_cmp(P->y, modulus) != MP_LT ||
2772
2.97k
        mp_cmp(P->z, modulus) != MP_LT) {
2773
55
        return ECC_OUT_OF_RANGE_E;
2774
55
    }
2775
2776
2.97k
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2777
3.03k
}
2778
2779
#if !defined(FREESCALE_LTC_ECC) && \
2780
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY)) && \
2781
    !defined(WOLFSSL_CRYPTOCELL)
2782
2783
2784
/**
2785
  Map a projective Jacobian point back to affine space
2786
  P        [in/out] The point to map
2787
  modulus  The modulus of the field the ECC curve is in
2788
  mp       The "b" value from montgomery_setup()
2789
  ct       Operation should be constant time.
2790
  return   MP_OKAY on success
2791
*/
2792
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2793
16.3k
{
2794
16.3k
    int err = MP_OKAY;
2795
16.3k
    (void)ct;
2796
2797
16.3k
    if (P == NULL || modulus == NULL){
2798
0
        return ECC_BAD_ARG_E;
2799
0
    }
2800
16.3k
    {
2801
16.3k
        #if !defined(WOLFSSL_SP_MATH)
2802
16.3k
        DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2803
16.3k
        DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2804
        #ifdef ALT_ECC_SIZE
2805
        DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2806
        DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2807
        DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2808
        #endif
2809
16.3k
        mp_int *x, *y, *z;
2810
2811
16.3k
        if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2812
0
            return WC_KEY_SIZE_E;
2813
0
        }
2814
2815
        /* special case for point at infinity */
2816
16.3k
        if (mp_cmp_d(P->z, 0) == MP_EQ) {
2817
450
            err = mp_set(P->x, 0);
2818
450
            if (err == MP_OKAY)
2819
450
                err = mp_set(P->y, 0);
2820
450
            if (err == MP_OKAY)
2821
450
                err = mp_set(P->z, 1);
2822
450
            return err;
2823
450
        }
2824
2825
15.9k
        #ifdef WOLFSSL_SMALL_STACK
2826
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2827
        if (P->key != NULL) {
2828
            t1 = P->key->t1;
2829
            t2 = P->key->t2;
2830
        #ifdef ALT_ECC_SIZE
2831
            rx = P->key->x;
2832
            ry = P->key->y;
2833
            rz = P->key->z;
2834
        #endif
2835
        }
2836
        else
2837
        #endif /* WOLFSSL_SMALL_STACK_CACHE */
2838
15.9k
        #endif
2839
15.9k
        {
2840
15.9k
            NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2841
15.9k
            NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2842
15.9k
        #ifdef MP_INT_SIZE_CHECK_NULL
2843
15.9k
            if (t1 == NULL || t2 == NULL) {
2844
40
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2845
40
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2846
40
                return MEMORY_E;
2847
40
            }
2848
15.9k
        #endif
2849
        #ifdef ALT_ECC_SIZE
2850
            NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2851
            NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2852
            NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2853
        #ifdef MP_INT_SIZE_CHECK_NULL
2854
            if (rx == NULL || ry == NULL || rz == NULL) {
2855
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2856
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2857
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2858
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2859
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2860
                return MEMORY_E;
2861
            }
2862
        #endif
2863
        #endif
2864
15.9k
        }
2865
2866
15.9k
        err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2867
15.9k
        if (err == MP_OKAY) {
2868
15.9k
            err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2869
15.9k
        }
2870
15.9k
        if (err != MP_OKAY) {
2871
0
        #ifdef WOLFSSL_SMALL_STACK
2872
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2873
            if (P->key == NULL)
2874
        #endif
2875
0
        #endif
2876
0
            {
2877
            #ifdef ALT_ECC_SIZE
2878
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2879
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2880
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2881
            #endif
2882
0
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2883
0
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2884
0
            }
2885
0
            return MEMORY_E;
2886
0
        }
2887
2888
        #ifdef ALT_ECC_SIZE
2889
        /* Use local stack variable */
2890
        x = rx;
2891
        y = ry;
2892
        z = rz;
2893
2894
        err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2895
        if (err == MP_OKAY) {
2896
            err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2897
        }
2898
        if (err == MP_OKAY) {
2899
            err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2900
        }
2901
        if (err != MP_OKAY) {
2902
            goto done;
2903
        }
2904
2905
        if (err == MP_OKAY)
2906
            err = mp_copy(P->x, x);
2907
        if (err == MP_OKAY)
2908
            err = mp_copy(P->y, y);
2909
        if (err == MP_OKAY)
2910
            err = mp_copy(P->z, z);
2911
2912
        if (err != MP_OKAY) {
2913
            goto done;
2914
        }
2915
        #else
2916
        /* Use destination directly */
2917
15.9k
        x = P->x;
2918
15.9k
        y = P->y;
2919
15.9k
        z = P->z;
2920
15.9k
        #endif
2921
2922
        /* get 1/z */
2923
15.9k
        if (err == MP_OKAY) {
2924
15.9k
        #if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2925
15.9k
                        defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2926
15.9k
            if (ct) {
2927
10.0k
                err = mp_invmod_mont_ct(z, modulus, t1, mp);
2928
10.0k
                if (err == MP_OKAY)
2929
9.79k
                    err = mp_montgomery_reduce(t1, modulus, mp);
2930
10.0k
            }
2931
5.85k
            else
2932
5.85k
        #endif
2933
5.85k
            {
2934
                /* first map z back to normal */
2935
5.85k
                err = mp_montgomery_reduce(z, modulus, mp);
2936
5.85k
                if (err == MP_OKAY)
2937
5.85k
                    err = mp_invmod(z, modulus, t1);
2938
5.85k
            }
2939
15.9k
        }
2940
2941
        /* get 1/z^2 and 1/z^3 */
2942
15.9k
        if (err == MP_OKAY)
2943
15.6k
            err = mp_sqr(t1, t2);
2944
15.9k
        if (err == MP_OKAY)
2945
15.6k
            err = mp_mod(t2, modulus, t2);
2946
15.9k
        if (err == MP_OKAY)
2947
15.6k
            err = mp_mul(t1, t2, t1);
2948
15.9k
        if (err == MP_OKAY)
2949
15.6k
            err = mp_mod(t1, modulus, t1);
2950
2951
        /* multiply against x/y */
2952
15.9k
        if (err == MP_OKAY)
2953
15.6k
            err = mp_mul(x, t2, x);
2954
15.9k
        if (err == MP_OKAY)
2955
15.6k
            err = mp_montgomery_reduce(x, modulus, mp);
2956
15.9k
        if (err == MP_OKAY)
2957
15.6k
            err = mp_mul(y, t1, y);
2958
15.9k
        if (err == MP_OKAY)
2959
15.6k
            err = mp_montgomery_reduce(y, modulus, mp);
2960
2961
15.9k
        if (err == MP_OKAY)
2962
15.6k
            err = mp_set(z, 1);
2963
2964
        #ifdef ALT_ECC_SIZE
2965
        /* return result */
2966
        if (err == MP_OKAY)
2967
            err = mp_copy(x, P->x);
2968
        if (err == MP_OKAY)
2969
            err = mp_copy(y, P->y);
2970
        if (err == MP_OKAY)
2971
            err = mp_copy(z, P->z);
2972
2973
        done:
2974
        #endif
2975
2976
        /* clean up */
2977
15.9k
        mp_clear(t1);
2978
15.9k
        mp_clear(t2);
2979
2980
15.9k
        #ifdef WOLFSSL_SMALL_STACK
2981
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2982
        if (P->key == NULL)
2983
        #endif
2984
15.9k
        #endif
2985
15.9k
        {
2986
        #ifdef ALT_ECC_SIZE
2987
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2988
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2989
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2990
        #endif
2991
15.9k
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2992
15.9k
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2993
15.9k
        }
2994
2995
15.9k
        return err;
2996
        /* end !defined(WOLFSSL_SP_MATH) */
2997
2998
        #else
2999
        /* begin defined(WOLFSSL_SP_MATH) */
3000
        if (P == NULL || modulus == NULL)
3001
            return ECC_BAD_ARG_E;
3002
3003
        (void)mp;
3004
        (void)ct;
3005
3006
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3007
        if ((mp_count_bits(modulus) == 256) &&
3008
            (!mp_is_bit_set(modulus, 224))) {
3009
            err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
3010
        }
3011
        #elif !defined(WOLFSSL_SP_NO_256)
3012
        if (mp_count_bits(modulus) == 256) {
3013
            err = sp_ecc_map_256(P->x, P->y, P->z);
3014
        }
3015
        #elif defined(WOLFSSL_SP_384)
3016
        if (mp_count_bits(modulus) == 384) {
3017
            err = sp_ecc_map_384(P->x, P->y, P->z);
3018
        }
3019
        #elif defined(WOLFSSL_SP_521)
3020
        if (mp_count_bits(modulus) == 521) {
3021
            err = sp_ecc_map_521(P->x, P->y, P->z);
3022
        }
3023
        #else
3024
        err = ECC_BAD_ARG_E;
3025
        #endif
3026
3027
        WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
3028
    return err;
3029
#endif /* WOLFSSL_SP_MATH */
3030
15.9k
    }
3031
15.9k
}
3032
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
3033
3034
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
3035
11.3k
{
3036
11.3k
    return ecc_map_ex(P, modulus, mp, 0);
3037
11.3k
}
3038
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
3039
3040
#if !defined(FREESCALE_LTC_ECC) && \
3041
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY)) && \
3042
    !defined(WOLFSSL_CRYPTOCELL)
3043
#if !defined(WOLFSSL_SP_MATH)
3044
3045
#ifndef ECC_TIMING_RESISTANT
3046
3047
/* size of sliding window, don't change this! */
3048
#define WINSIZE  4
3049
#define M_POINTS 8
3050
3051
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
3052
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3053
{
3054
   int      err = MP_OKAY;
3055
   int      i;
3056
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
3057
   int      bitcnt = 0, mode = 0, digidx = 0;
3058
   mp_digit buf;
3059
   int      infinity;
3060
3061
   (void)rng;
3062
3063
   /* calc the M tab, which holds kG for k==8..15 */
3064
   /* M[0] == 8G */
3065
   if (err == MP_OKAY)
3066
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
3067
   if (err == MP_OKAY)
3068
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3069
   if (err == MP_OKAY)
3070
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3071
3072
   /* now find (8+k)G for k=1..7 */
3073
   if (err == MP_OKAY)
3074
       for (j = 9; j < 16; j++) {
3075
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
3076
                                                        modulus, mp, &infinity);
3077
           if (err != MP_OKAY) break;
3078
       }
3079
3080
   /* setup sliding window */
3081
   if (err == MP_OKAY) {
3082
       mode   = 0;
3083
       bitcnt = 1;
3084
       buf    = 0;
3085
       digidx = mp_get_digit_count(k) - 1;
3086
       bitcpy = bitbuf = 0;
3087
       first  = 1;
3088
3089
       /* perform ops */
3090
       for (;;) {
3091
           /* grab next digit as required */
3092
           if (--bitcnt == 0) {
3093
               if (digidx == -1) {
3094
                   break;
3095
               }
3096
               buf    = mp_get_digit(k, digidx);
3097
               bitcnt = (int) DIGIT_BIT;
3098
               --digidx;
3099
           }
3100
3101
           /* grab the next msb from the ltiplicand */
3102
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3103
           buf <<= 1;
3104
3105
           /* skip leading zero bits */
3106
           if (mode == 0 && i == 0)
3107
               continue;
3108
3109
           /* if the bit is zero and mode == 1 then we double */
3110
           if (mode == 1 && i == 0) {
3111
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3112
               if (err != MP_OKAY) break;
3113
               continue;
3114
           }
3115
3116
           /* else we add it to the window */
3117
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3118
           mode = 2;
3119
3120
           if (bitcpy == WINSIZE) {
3121
               /* if this is the first window we do a simple copy */
3122
               if (first == 1) {
3123
                   /* R = kG [k = first window] */
3124
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3125
                   if (err != MP_OKAY) break;
3126
3127
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3128
                   if (err != MP_OKAY) break;
3129
3130
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3131
                   first = 0;
3132
               } else {
3133
                   /* normal window */
3134
                   /* ok window is filled so double as required and add  */
3135
                   /* double first */
3136
                   for (j = 0; j < WINSIZE; j++) {
3137
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3138
                                                                            mp);
3139
                       if (err != MP_OKAY) break;
3140
                   }
3141
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3142
3143
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3144
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3145
                                                     a, modulus, mp, &infinity);
3146
               }
3147
               if (err != MP_OKAY) break;
3148
               /* empty window and reset */
3149
               bitcpy = bitbuf = 0;
3150
               mode = 1;
3151
           }
3152
       }
3153
   }
3154
3155
   /* if bits remain then double/add */
3156
   if (err == MP_OKAY) {
3157
       if (mode == 2 && bitcpy > 0) {
3158
           /* double then add */
3159
           for (j = 0; j < bitcpy; j++) {
3160
               /* only double if we have had at least one add first */
3161
               if (first == 0) {
3162
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3163
                   if (err != MP_OKAY) break;
3164
               }
3165
3166
               bitbuf <<= 1;
3167
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3168
                   if (first == 1) {
3169
                       /* first add, so copy */
3170
                       err = mp_copy(tG->x, R->x);
3171
                       if (err != MP_OKAY) break;
3172
3173
                       err = mp_copy(tG->y, R->y);
3174
                       if (err != MP_OKAY) break;
3175
3176
                       err = mp_copy(tG->z, R->z);
3177
                       if (err != MP_OKAY) break;
3178
                       first = 0;
3179
                   } else {
3180
                       /* then add */
3181
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3182
                                                                 mp, &infinity);
3183
                       if (err != MP_OKAY) break;
3184
                   }
3185
               }
3186
           }
3187
       }
3188
   }
3189
3190
   #undef WINSIZE
3191
3192
   return err;
3193
}
3194
3195
#else
3196
3197
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3198
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3199
22.2k
{
3200
22.2k
    int err = MP_OKAY;
3201
3202
22.2k
    err = mp_montgomery_calc_normalization(mu, modulus);
3203
    /* Generate random value to multiply into p->z. */
3204
22.2k
    if (err == MP_OKAY)
3205
22.2k
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3206
    /* Convert to montogmery form. */
3207
22.2k
    if (err == MP_OKAY)
3208
22.1k
        err = mp_mulmod(ty, mu, modulus, ty);
3209
    /* Multiply random value into p->z. */
3210
22.2k
    if (err == MP_OKAY)
3211
22.0k
        err = mp_mul(p->z, ty, p->z);
3212
22.2k
    if (err == MP_OKAY)
3213
22.0k
        err = mp_montgomery_reduce(p->z, modulus, mp);
3214
    /* Square random value for X (X' = X / Z^2). */
3215
22.2k
    if (err == MP_OKAY)
3216
22.0k
        err = mp_sqr(ty, tx);
3217
22.2k
    if (err == MP_OKAY)
3218
22.0k
        err = mp_montgomery_reduce(tx, modulus, mp);
3219
    /* Multiply square of random by random value for Y. */
3220
22.2k
    if (err == MP_OKAY)
3221
22.0k
        err = mp_mul(ty, tx, ty);
3222
22.2k
    if (err == MP_OKAY)
3223
21.9k
        err = mp_montgomery_reduce(ty, modulus, mp);
3224
    /* Multiply square into X. */
3225
22.2k
    if (err == MP_OKAY)
3226
21.9k
        err = mp_mul(p->x, tx, p->x);
3227
22.2k
    if (err == MP_OKAY)
3228
21.9k
        err = mp_montgomery_reduce(p->x, modulus, mp);
3229
    /* Multiply cube into Y (Y' = Y / Z^3). */
3230
22.2k
    if (err == MP_OKAY)
3231
21.9k
        err = mp_mul(p->y, ty, p->y);
3232
22.2k
    if (err == MP_OKAY)
3233
21.9k
        err = mp_montgomery_reduce(p->y, modulus, mp);
3234
3235
22.2k
    return err;
3236
22.2k
}
3237
3238
#ifndef WC_PROTECT_ENCRYPTED_MEM
3239
88.9k
#define M_POINTS 3
3240
3241
/* Joye double-add ladder.
3242
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3243
 * by Marc Joye (2007)
3244
 *
3245
 * Algorithm 1':
3246
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3247
 *   Output: Q = kP
3248
 *   1: R[0] = P; R[1] = P
3249
 *   2: for j = 1 to t-1 do
3250
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3251
 *   4: end for
3252
 *   5: b = k[0]; R[b] = R[b] - P
3253
 *   6: return R[0]
3254
 *
3255
 * Assumes: k < order.
3256
 */
3257
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3258
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3259
18.1k
{
3260
18.1k
    int      err = MP_OKAY;
3261
18.1k
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3262
18.1k
    int      i;
3263
18.1k
    int      j = 1;
3264
18.1k
    int      cnt = DIGIT_BIT;
3265
18.1k
    int      t = 0;
3266
18.1k
    mp_digit b;
3267
18.1k
    mp_digit v = 0;
3268
18.1k
    mp_int*  kt = R[2]->x;
3269
18.1k
#ifndef WC_NO_CACHE_RESISTANT
3270
    /* First bit always 1 (fix at end) and swap equals first bit */
3271
18.1k
    int      swap = 1;
3272
18.1k
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3273
18.1k
#endif
3274
18.1k
    int      infinity;
3275
3276
18.1k
#ifndef WC_NO_CACHE_RESISTANT
3277
18.1k
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3278
18.1k
    if (err == MP_OKAY)
3279
18.1k
        err = mp_init(tmp);
3280
18.1k
#endif
3281
3282
    /* Step 1: R[0] = P; R[1] = P */
3283
    /* R[0] = P */
3284
18.1k
    if (err == MP_OKAY)
3285
18.1k
        err = mp_copy(P->x, R[0]->x);
3286
18.1k
    if (err == MP_OKAY)
3287
18.1k
        err = mp_copy(P->y, R[0]->y);
3288
18.1k
    if (err == MP_OKAY)
3289
18.1k
        err = mp_copy(P->z, R[0]->z);
3290
3291
    /* R[1] = P */
3292
18.1k
    if (err == MP_OKAY)
3293
18.1k
        err = mp_copy(P->x, R[1]->x);
3294
18.1k
    if (err == MP_OKAY)
3295
18.1k
        err = mp_copy(P->y, R[1]->y);
3296
18.1k
    if (err == MP_OKAY)
3297
18.1k
        err = mp_copy(P->z, R[1]->z);
3298
3299
    /* Randomize z ordinates to obfuscate timing. */
3300
18.1k
    if ((err == MP_OKAY) && (rng != NULL))
3301
10.4k
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3302
18.1k
    if ((err == MP_OKAY) && (rng != NULL))
3303
10.2k
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3304
3305
18.1k
    if (err == MP_OKAY) {
3306
        /* Order could be one greater than the size of the modulus. */
3307
17.7k
        t = mp_count_bits(modulus) + 1;
3308
17.7k
        v = k->dp[0] >> 1;
3309
17.7k
        if (cnt > t) {
3310
0
            cnt = t;
3311
0
        }
3312
17.7k
        err = mp_copy(k, kt);
3313
17.7k
    }
3314
18.1k
    if (err == MP_OKAY) {
3315
17.7k
        err = mp_grow(kt, (int)modulus->used + 1);
3316
17.7k
    }
3317
    /* Step 2: for j = 1 to t-1 do */
3318
4.35M
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3319
4.34M
        if (--cnt == 0) {
3320
133k
            v = kt->dp[j++];
3321
133k
            cnt = DIGIT_BIT;
3322
133k
        }
3323
3324
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3325
4.34M
        b = v & 1;
3326
4.34M
        v >>= 1;
3327
#ifdef WC_NO_CACHE_RESISTANT
3328
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3329
        if (err == MP_OKAY) {
3330
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3331
                                                        modulus, mp, &infinity);
3332
        }
3333
#else
3334
        /* Swap R[0] and R[1] if other index is needed. */
3335
4.34M
        swap ^= (int)b;
3336
4.34M
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3337
4.34M
            tmp);
3338
4.34M
        if (err == MP_OKAY) {
3339
4.34M
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3340
4.34M
                tmp);
3341
4.34M
        }
3342
4.34M
        if (err == MP_OKAY) {
3343
4.34M
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3344
4.34M
                tmp);
3345
4.34M
        }
3346
4.34M
        swap = (int)b;
3347
3348
4.34M
        if (err == MP_OKAY)
3349
4.34M
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3350
4.34M
        if (err == MP_OKAY) {
3351
4.34M
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3352
4.34M
                                                                 mp, &infinity);
3353
4.34M
        }
3354
4.34M
#endif /* WC_NO_CACHE_RESISTANT */
3355
4.34M
    }
3356
    /* Step 4: end for */
3357
18.1k
#ifndef WC_NO_CACHE_RESISTANT
3358
    /* Swap back if last bit is 0. */
3359
18.1k
    swap ^= 1;
3360
18.1k
    if (err == MP_OKAY) {
3361
16.2k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3362
16.2k
            tmp);
3363
16.2k
    }
3364
18.1k
    if (err == MP_OKAY) {
3365
16.2k
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3366
16.2k
            tmp);
3367
16.2k
    }
3368
18.1k
    if (err == MP_OKAY) {
3369
16.2k
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3370
16.2k
            tmp);
3371
16.2k
    }
3372
18.1k
#endif
3373
3374
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3375
    /* R[2] = -P */
3376
18.1k
    if (err == MP_OKAY)
3377
16.2k
        err = mp_copy(P->x, R[2]->x);
3378
18.1k
    if (err == MP_OKAY)
3379
16.2k
        err = mp_sub(modulus, P->y, R[2]->y);
3380
18.1k
    if (err == MP_OKAY)
3381
16.2k
        err = mp_copy(P->z, R[2]->z);
3382
    /* Subtract point by adding negative. */
3383
18.1k
    if (err == MP_OKAY) {
3384
16.2k
        b = k->dp[0] & 1;
3385
#ifdef WC_NO_CACHE_RESISTANT
3386
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3387
                                                                     &infinity);
3388
#else
3389
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3390
16.2k
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3391
16.2k
            tmp);
3392
16.2k
        if (err == MP_OKAY) {
3393
16.2k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3394
16.2k
                (int)b, tmp);
3395
16.2k
        }
3396
16.2k
        if (err == MP_OKAY) {
3397
16.2k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3398
16.2k
                (int)b, tmp);
3399
16.2k
        }
3400
16.2k
        if (err == MP_OKAY)
3401
16.2k
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3402
16.2k
                                                                 mp, &infinity);
3403
        /* Swap back if necessary. */
3404
16.2k
        if (err == MP_OKAY) {
3405
16.2k
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3406
16.2k
                (int)b, tmp);
3407
16.2k
        }
3408
16.2k
        if (err == MP_OKAY) {
3409
16.2k
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3410
16.2k
                (int)b, tmp);
3411
16.2k
        }
3412
16.2k
        if (err == MP_OKAY) {
3413
16.2k
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3414
16.2k
                (int)b, tmp);
3415
16.2k
        }
3416
16.2k
#endif
3417
16.2k
    }
3418
3419
    /* Step 6: return R[0] */
3420
18.1k
    if (err == MP_OKAY)
3421
16.2k
        err = mp_copy(R[0]->x, Q->x);
3422
18.1k
    if (err == MP_OKAY)
3423
16.2k
        err = mp_copy(R[0]->y, Q->y);
3424
18.1k
    if (err == MP_OKAY)
3425
16.2k
        err = mp_copy(R[0]->z, Q->z);
3426
3427
18.1k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3428
18.1k
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3429
18.1k
#endif
3430
3431
18.1k
    return err;
3432
18.1k
}
3433
3434
#else
3435
/* Number of points to allocate for use during scalar multiplication. */
3436
#define M_POINTS        5
3437
/* Last of the points is used as a temporary during calculations. */
3438
#define TMP_IDX         M_POINTS - 1
3439
3440
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3441
    int digits, int m)
3442
{
3443
    int i;
3444
3445
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3446
    /* Only using positive numbers in ECC operations. */
3447
    ra->sign = 0;
3448
    rb->sign = 0;
3449
#endif
3450
    /* Don't store 0 when mask is 0, it will be in a register. */
3451
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3452
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3453
    for (i = 0; i < digits; i++) {
3454
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3455
                    a->dp[i];
3456
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3457
                    b->dp[i];
3458
    }
3459
}
3460
3461
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3462
    ecc_point* b, int digits, int m)
3463
{
3464
    /* Conditionally swap each ordinate. */
3465
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3466
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3467
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3468
}
3469
3470
/* Joye double-add ladder.
3471
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3472
 * by Marc Joye (2007)
3473
 *
3474
 * Algorithm 1':
3475
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3476
 *   Output: Q = kP
3477
 *   1: R[0] = P; R[1] = P
3478
 *   2: for j = 1 to t-1 do
3479
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3480
 *   4: end for
3481
 *   5: b = k[0]; R[b] = R[b] - P
3482
 *   6: return R[0]
3483
 *
3484
 * Assumes: k < order.
3485
 */
3486
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3487
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3488
{
3489
    int          err = MP_OKAY;
3490
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3491
    int          i;
3492
    int          j = 1;
3493
    int          cnt;
3494
    int          t = 0;
3495
    mp_int*      kt = R[TMP_IDX]->x;
3496
    /* First bit always 1 (fix at end) and swap equals first bit */
3497
    register int swap = 1;
3498
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3499
    int          set = 0;
3500
    int          infinity;
3501
3502
    /* Step 1: R[0] = P; R[1] = P */
3503
    /* R[0] = P */
3504
    if (err == MP_OKAY)
3505
        err = mp_copy(P->x, R[0]->x);
3506
    if (err == MP_OKAY)
3507
        err = mp_copy(P->y, R[0]->y);
3508
    if (err == MP_OKAY)
3509
        err = mp_copy(P->z, R[0]->z);
3510
3511
    /* R[1] = P */
3512
    if (err == MP_OKAY)
3513
        err = mp_copy(P->x, R[1]->x);
3514
    if (err == MP_OKAY)
3515
        err = mp_copy(P->y, R[1]->y);
3516
    if (err == MP_OKAY)
3517
        err = mp_copy(P->z, R[1]->z);
3518
3519
    /* Randomize z ordinates to obfuscate timing. */
3520
    if ((err == MP_OKAY) && (rng != NULL))
3521
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3522
                           R[TMP_IDX]->y, kt);
3523
    if ((err == MP_OKAY) && (rng != NULL))
3524
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3525
                           R[TMP_IDX]->y, kt);
3526
3527
    if (err == MP_OKAY) {
3528
        /* Order could be one greater than the size of the modulus. */
3529
        t = mp_count_bits(modulus) + 1;
3530
        err = mp_copy(k, kt);
3531
    }
3532
    if (err == MP_OKAY) {
3533
        err = mp_grow(kt, modulus->used + 1);
3534
    }
3535
    /* Step 2: for j = 1 to t-1 do */
3536
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3537
        if (++cnt == DIGIT_BIT) {
3538
            j++;
3539
            cnt = 0;
3540
        }
3541
3542
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3543
        /* Swap R[0] and R[1] if other index is needed. */
3544
        /* Ensure 'swap' changes when shifted word is 0. */
3545
        swap += (kt->dp[j] >> cnt) + 2;
3546
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3547
                              R[set + 0], R[set + 1], modulus->used, swap);
3548
        /* Change to operate on set copied into. */
3549
        set = 2 - set;
3550
        /* Ensure 'swap' changes to a previously unseen value. */
3551
        swap += (kt->dp[j] >> cnt) + swap;
3552
3553
        /* R[0] = 2*R[0] */
3554
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3555
                                            mp);
3556
        if (err == MP_OKAY) {
3557
            /* R[0] = R[1] + R[0] */
3558
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3559
                                         R[set + 0], a, modulus, mp, &infinity);
3560
        }
3561
        /*  R[1]->z * 2 - same point. */
3562
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3563
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3564
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3565
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3566
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3567
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3568
    }
3569
    /* Step 4: end for */
3570
    /* Swap back if last bit is 0. */
3571
    /* Ensure 'swap' changes. */
3572
    swap += 1;
3573
    if (err == MP_OKAY) {
3574
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3575
                              R[set + 0], R[set + 1], modulus->used, swap);
3576
        set = 2 - set;
3577
    }
3578
3579
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3580
    /* R[TMP_IDX] = -P */
3581
    if (err == MP_OKAY)
3582
        err = mp_copy(P->x, R[TMP_IDX]->x);
3583
    if (err == MP_OKAY)
3584
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3585
    if (err == MP_OKAY)
3586
        err = mp_copy(P->z, R[TMP_IDX]->z);
3587
    /* Subtract point by adding negative. */
3588
    if (err == MP_OKAY) {
3589
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3590
         * Last bit of k->dp[0] is being used to make decision to swap.
3591
         */
3592
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3593
                              R[set + 0], R[set + 1], modulus->used,
3594
                              (int)k->dp[0]);
3595
        set = 2 - set;
3596
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3597
                                            a, modulus, mp, &infinity);
3598
        /* Swap back if necessary. */
3599
        if (err == MP_OKAY) {
3600
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3601
                                  R[set + 0], R[set + 1], modulus->used,
3602
                                  (int)k->dp[0]);
3603
            set = 2 - set;
3604
        }
3605
    }
3606
3607
    /* Step 6: return R[0] */
3608
    if (err == MP_OKAY)
3609
        err = mp_copy(R[set + 0]->x, Q->x);
3610
    if (err == MP_OKAY)
3611
        err = mp_copy(R[set + 0]->y, Q->y);
3612
    if (err == MP_OKAY)
3613
        err = mp_copy(R[set + 0]->z, Q->z);
3614
3615
    return err;
3616
}
3617
3618
#endif
3619
3620
#endif
3621
3622
/* Convert the point to montgomery form.
3623
 *
3624
 * @param  [in]   p        Point to convert.
3625
 * @param  [out]  r        Point in montgomery form.
3626
 * @param  [in]   modulus  Modulus of ordinates.
3627
 * @return  0 on success.
3628
 * @return  -ve on failure.
3629
 */
3630
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3631
                             void* heap)
3632
15.2k
{
3633
15.2k
   int err = MP_OKAY;
3634
3635
15.2k
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3636
3637
15.2k
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
3638
0
       return WC_KEY_SIZE_E;
3639
0
   }
3640
3641
15.2k
   (void)heap;
3642
3643
15.2k
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3644
15.2k
#ifdef MP_INT_SIZE_CHECK_NULL
3645
15.2k
   if (mu == NULL)
3646
33
       err = MEMORY_E;
3647
15.2k
#endif
3648
15.2k
   if (err == MP_OKAY)
3649
15.1k
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3650
15.2k
   if (err == MP_OKAY) {
3651
15.1k
       err = mp_montgomery_calc_normalization(mu, modulus);
3652
3653
15.1k
       if (err == MP_OKAY) {
3654
15.1k
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3655
1.43k
               err = mp_copy(p->x, r->x);
3656
1.43k
               if (err == MP_OKAY)
3657
1.43k
                   err = mp_copy(p->y, r->y);
3658
1.43k
               if (err == MP_OKAY)
3659
1.43k
                   err = mp_copy(p->z, r->z);
3660
1.43k
           }
3661
13.7k
           else {
3662
13.7k
               err = mp_mulmod(p->x, mu, modulus, r->x);
3663
13.7k
               if (err == MP_OKAY)
3664
13.7k
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3665
13.7k
               if (err == MP_OKAY)
3666
13.6k
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3667
13.7k
           }
3668
15.1k
       }
3669
3670
15.1k
       mp_clear(mu);
3671
15.1k
   }
3672
3673
15.2k
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3674
15.2k
   return err;
3675
15.2k
}
3676
3677
#ifdef WOLFSSL_SMALL_STACK_CACHE
3678
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3679
{
3680
   int err = MP_OKAY;
3681
3682
   (void)heap;
3683
3684
   if (key == NULL) {
3685
       return ECC_BAD_ARG_E;
3686
   }
3687
3688
   XMEMSET(key, 0, sizeof(*key));
3689
3690
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3691
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3692
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3693
#ifdef ALT_ECC_SIZE
3694
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3695
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3696
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3697
#endif
3698
   if (key->t1 == NULL || key->t2 == NULL
3699
#ifdef ALT_ECC_SIZE
3700
      || key->x == NULL || key->y == NULL || key->z == NULL
3701
#endif
3702
   ) {
3703
       err = MEMORY_E;
3704
   }
3705
   if (err == 0) {
3706
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3707
   }
3708
   if (err == 0) {
3709
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3710
   }
3711
#ifdef ALT_ECC_SIZE
3712
   if (err == 0) {
3713
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3714
   }
3715
   if (err == 0) {
3716
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3717
   }
3718
   if (err == 0) {
3719
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3720
   }
3721
#endif
3722
#else
3723
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3724
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3725
#ifdef ALT_ECC_SIZE
3726
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3727
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3728
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3729
#endif
3730
   if (key->t1 == NULL || key->t2 == NULL
3731
#ifdef ALT_ECC_SIZE
3732
      || key->x == NULL || key->y == NULL || key->z == NULL
3733
#endif
3734
   ) {
3735
       err = MEMORY_E;
3736
   }
3737
#endif
3738
3739
   return err;
3740
}
3741
3742
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3743
{
3744
    (void)heap;
3745
3746
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3747
#ifdef ALT_ECC_SIZE
3748
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3749
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3750
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3751
#endif
3752
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3753
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3754
#else
3755
#ifdef ALT_ECC_SIZE
3756
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3757
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3758
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3759
#endif
3760
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3761
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3762
#endif
3763
}
3764
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3765
#endif /* !WOLFSSL_SP_MATH */
3766
3767
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3768
/**
3769
   Perform a point multiplication
3770
   k    The scalar to multiply by
3771
   G    The base point
3772
   R    [out] Destination for kG
3773
   a    ECC curve parameter a
3774
   modulus  The modulus of the field the ECC curve is in
3775
   map      Boolean whether to map back to affine or not
3776
                (1==map, 0 == leave in projective)
3777
   return MP_OKAY on success
3778
*/
3779
#ifdef FP_ECC
3780
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3781
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3782
                             void* heap)
3783
#else
3784
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3785
                     mp_int* modulus, int map, void* heap)
3786
#endif
3787
#if !defined(WOLFSSL_SP_MATH)
3788
5.28k
{
3789
5.28k
   ecc_point     *tG, *M[M_POINTS];
3790
#ifdef WOLFSSL_NO_MALLOC
3791
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3792
#endif
3793
5.28k
   int           i, err;
3794
#ifdef WOLFSSL_SMALL_STACK_CACHE
3795
   ecc_key       *key = NULL;
3796
#endif
3797
5.28k
   mp_digit      mp;
3798
3799
   /* init variables */
3800
5.28k
   tG = NULL;
3801
5.28k
   XMEMSET(M, 0, sizeof(M));
3802
3803
5.28k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3804
0
       err = ECC_BAD_ARG_E;
3805
0
       goto exit;
3806
0
   }
3807
3808
   /* k can't have more bits than modulus count plus 1 */
3809
5.28k
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3810
148
       err = ECC_OUT_OF_RANGE_E;
3811
148
       goto exit;
3812
148
   }
3813
3814
#ifdef WOLFSSL_SMALL_STACK_CACHE
3815
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3816
   if (key == NULL) {
3817
       err = MP_MEM;
3818
       goto exit;
3819
   }
3820
   err = ecc_key_tmp_init(key, heap);
3821
   if (err != MP_OKAY)
3822
      goto exit;
3823
   R->key = key;
3824
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3825
3826
  /* alloc ram for window temps */
3827
20.4k
  for (i = 0; i < M_POINTS; i++) {
3828
  #ifdef WOLFSSL_NO_MALLOC
3829
      M[i] = &lcl_M[i];
3830
  #endif
3831
15.3k
      err = wc_ecc_new_point_ex(&M[i], heap);
3832
15.3k
      if (err != MP_OKAY) {
3833
50
         goto exit;
3834
50
      }
3835
#ifdef WOLFSSL_SMALL_STACK_CACHE
3836
      M[i]->key = key;
3837
#endif
3838
15.3k
  }
3839
3840
   /* make a copy of G in case R==G */
3841
#ifdef WOLFSSL_NO_MALLOC
3842
   tG = &lcl_tG;
3843
#endif
3844
5.09k
   err = wc_ecc_new_point_ex(&tG, heap);
3845
5.09k
   if (err != MP_OKAY) {
3846
23
       goto exit;
3847
23
   }
3848
5.06k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3849
45
       goto exit;
3850
45
   }
3851
3852
   /* init montgomery reduction */
3853
5.02k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3854
0
       goto exit;
3855
0
   }
3856
3857
#ifdef FP_ECC
3858
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3859
#else
3860
5.02k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3861
5.02k
#endif
3862
   /* map R back from projective space */
3863
5.02k
   if (err == MP_OKAY && map)
3864
4.75k
       err = ecc_map(R, modulus, mp);
3865
3866
5.28k
exit:
3867
3868
   /* done */
3869
5.28k
   wc_ecc_del_point_ex(tG, heap);
3870
21.1k
   for (i = 0; i < M_POINTS; i++) {
3871
15.8k
       wc_ecc_del_point_ex(M[i], heap);
3872
15.8k
   }
3873
3874
#ifdef WOLFSSL_SMALL_STACK_CACHE
3875
   if (key) {
3876
       if (R)
3877
           R->key = NULL;
3878
       ecc_key_tmp_final(key, heap);
3879
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3880
   }
3881
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3882
3883
5.28k
   return err;
3884
5.02k
}
3885
#else
3886
{
3887
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3888
       return ECC_BAD_ARG_E;
3889
   }
3890
3891
   (void)a;
3892
3893
   /* For supported curves the order is the same length in bits as the modulus.
3894
    * Can't have more than order bits for the scalar.
3895
    */
3896
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3897
       return ECC_OUT_OF_RANGE_E;
3898
   }
3899
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3900
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3901
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3902
       return IS_POINT_E;
3903
   }
3904
3905
#ifdef WOLFSSL_HAVE_SP_ECC
3906
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3907
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3908
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3909
   }
3910
#endif
3911
#ifndef WOLFSSL_SP_NO_256
3912
   if (mp_count_bits(modulus) == 256) {
3913
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3914
   }
3915
#endif
3916
#ifdef WOLFSSL_SP_384
3917
   if (mp_count_bits(modulus) == 384) {
3918
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3919
   }
3920
#endif
3921
#ifdef WOLFSSL_SP_521
3922
   if (mp_count_bits(modulus) == 521) {
3923
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3924
   }
3925
#endif
3926
#else
3927
   (void)map;
3928
   (void)map;
3929
   (void)heap;
3930
#endif
3931
   return ECC_BAD_ARG_E;
3932
}
3933
#endif
3934
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3935
3936
#ifndef FP_ECC
3937
#if !defined(WOLFSSL_SP_MATH)
3938
#ifdef ECC_TIMING_RESISTANT
3939
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3940
   mp_int* modulus, mp_int* order)
3941
10.0k
{
3942
10.0k
    int err;
3943
10.0k
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3944
3945
10.0k
    if (MP_BITS_OVER_MAX(mp_bitsused(order), MAX_ECC_BITS_USE) ||
3946
10.0k
            MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
3947
0
        return WC_KEY_SIZE_E;
3948
0
    }
3949
3950
10.0k
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3951
10.0k
#ifdef MP_INT_SIZE_CHECK_NULL
3952
10.0k
    if (t == NULL) {
3953
9
        err = MEMORY_E;
3954
9
    }
3955
10.0k
    else
3956
10.0k
#endif
3957
10.0k
    {
3958
10.0k
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3959
10.0k
    }
3960
10.0k
    if (err == MP_OKAY) {
3961
        /* Check for k == order - 1. Result will be 0 point which is not correct
3962
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3963
         * (with constant time implementation)
3964
         */
3965
10.0k
        err = mp_sub_d(order, 1, t);
3966
10.0k
        if (err == MP_OKAY) {
3967
10.0k
            int kIsMinusOne = (mp_cmp((const mp_int*)k, t) == MP_EQ);
3968
10.0k
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3969
10.0k
            if (err == MP_OKAY) {
3970
10.0k
                err = mp_sub(modulus, tG->y, t);
3971
10.0k
            }
3972
10.0k
            if (err == MP_OKAY) {
3973
10.0k
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3974
10.0k
            }
3975
10.0k
            if (err == MP_OKAY) {
3976
10.0k
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3977
10.0k
            }
3978
10.0k
        }
3979
3980
10.0k
        mp_free(t);
3981
10.0k
    }
3982
3983
10.0k
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3984
10.0k
    return err;
3985
10.0k
}
3986
#endif /* ECC_TIMING_RESISTANT */
3987
#endif
3988
3989
/**
3990
   Perform a point multiplication
3991
   k    The scalar to multiply by
3992
   G    The base point
3993
   R    [out] Destination for kG
3994
   a    ECC curve parameter a
3995
   modulus  The modulus of the field the ECC curve is in
3996
   map      Boolean whether to map back to affine or not
3997
                (1==map, 0 == leave in projective)
3998
   return MP_OKAY on success
3999
*/
4000
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
4001
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
4002
                      void* heap)
4003
#if !defined(WOLFSSL_SP_MATH)
4004
5.96k
{
4005
5.96k
   ecc_point     *tG, *M[M_POINTS];
4006
#ifdef WOLFSSL_NO_MALLOC
4007
   ecc_point     lcl_tG, lcl_M[M_POINTS];
4008
#endif
4009
5.96k
   int           i, err;
4010
#ifdef WOLFSSL_SMALL_STACK_CACHE
4011
   ecc_key       *key = NULL;
4012
#endif
4013
5.96k
   mp_digit      mp;
4014
4015
5.96k
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4016
0
      return ECC_BAD_ARG_E;
4017
0
   }
4018
4019
#ifdef HAVE_ECC_CDH
4020
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
4021
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
4022
          return ECC_OUT_OF_RANGE_E;
4023
      }
4024
   }
4025
   else
4026
#endif
4027
   /* k can't have more bits than order */
4028
5.96k
   if (mp_count_bits(k) > mp_count_bits(order)) {
4029
18
      WOLFSSL_MSG("Private key length is greater than order in bits.");
4030
18
      return ECC_OUT_OF_RANGE_E;
4031
18
   }
4032
4033
   /* init variables */
4034
5.94k
   tG = NULL;
4035
5.94k
   XMEMSET(M, 0, sizeof(M));
4036
4037
#ifdef WOLFSSL_SMALL_STACK_CACHE
4038
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
4039
   if (key == NULL)
4040
       return MEMORY_E;
4041
   err = ecc_key_tmp_init(key, heap);
4042
   if (err != MP_OKAY)
4043
      goto exit;
4044
   R->key = key;
4045
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4046
4047
   /* alloc ram for window temps */
4048
23.5k
   for (i = 0; i < M_POINTS; i++) {
4049
   #ifdef WOLFSSL_NO_MALLOC
4050
      M[i] = &lcl_M[i];
4051
   #endif
4052
17.7k
      err = wc_ecc_new_point_ex(&M[i], heap);
4053
17.7k
      if (err != MP_OKAY) {
4054
91
         goto exit;
4055
91
      }
4056
#ifdef WOLFSSL_SMALL_STACK_CACHE
4057
      M[i]->key = key;
4058
#endif
4059
17.7k
  }
4060
4061
   /* make a copy of G in case R==G */
4062
#ifdef WOLFSSL_NO_MALLOC
4063
   tG = &lcl_tG;
4064
#endif
4065
5.85k
   err = wc_ecc_new_point_ex(&tG, heap);
4066
5.85k
   if (err != MP_OKAY) {
4067
15
       goto exit;
4068
15
   }
4069
5.84k
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
4070
54
       goto exit;
4071
54
   }
4072
4073
   /* init montgomery reduction */
4074
5.78k
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
4075
0
      goto exit;
4076
0
   }
4077
4078
5.78k
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
4079
5.78k
#ifdef ECC_TIMING_RESISTANT
4080
5.78k
   if (err == MP_OKAY) {
4081
5.58k
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
4082
5.58k
   }
4083
#else
4084
   (void)order;
4085
#endif
4086
   /* map R back from projective space */
4087
5.78k
   if (err == MP_OKAY && map)
4088
0
      err = ecc_map(R, modulus, mp);
4089
4090
5.94k
exit:
4091
4092
   /* done */
4093
5.94k
   wc_ecc_del_point_ex(tG, heap);
4094
23.7k
   for (i = 0; i < M_POINTS; i++) {
4095
17.8k
      wc_ecc_del_point_ex(M[i], heap);
4096
17.8k
   }
4097
#ifdef WOLFSSL_SMALL_STACK_CACHE
4098
   R->key = NULL;
4099
   ecc_key_tmp_final(key, heap);
4100
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
4101
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4102
4103
5.94k
   return err;
4104
5.78k
}
4105
#else
4106
{
4107
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4108
       return ECC_BAD_ARG_E;
4109
   }
4110
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4111
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4112
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4113
       return IS_POINT_E;
4114
   }
4115
4116
   (void)a;
4117
   (void)order;
4118
   (void)rng;
4119
4120
#ifdef WOLFSSL_HAVE_SP_ECC
4121
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4122
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4123
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4124
   }
4125
#endif
4126
#ifndef WOLFSSL_SP_NO_256
4127
   if (mp_count_bits(modulus) == 256) {
4128
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4129
   }
4130
#endif
4131
#ifdef WOLFSSL_SP_384
4132
   if (mp_count_bits(modulus) == 384) {
4133
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4134
   }
4135
#endif
4136
#ifdef WOLFSSL_SP_521
4137
   if (mp_count_bits(modulus) == 521) {
4138
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4139
   }
4140
#endif
4141
#else
4142
   (void)map;
4143
   (void)heap;
4144
#endif
4145
   return ECC_BAD_ARG_E;
4146
}
4147
#endif /* !WOLFSSL_SP_MATH */
4148
#endif /* !FP_ECC */
4149
4150
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4151
4152
/** ECC Fixed Point mulmod global
4153
    k        The multiplicand
4154
    G        Base point to multiply
4155
    R        [out] Destination of product
4156
    a        ECC curve parameter a
4157
    modulus  The modulus for the curve
4158
    map      [boolean] If non-zero maps the point back to affine coordinates,
4159
             otherwise it's left in jacobian-montgomery form
4160
    return MP_OKAY if successful
4161
*/
4162
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4163
                  mp_int* modulus, int map)
4164
351
{
4165
351
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4166
0
        mp_zero(R->x);
4167
0
        mp_zero(R->y);
4168
0
        mp_set(R->z, 1);
4169
0
        return MP_OKAY;
4170
0
    }
4171
351
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4172
351
}
4173
4174
#endif
4175
4176
/**
4177
 * Allocate a new ECC point (if one not provided)
4178
 * use a heap hint when creating new ecc_point
4179
 * @return 0 on success
4180
 * @return BAD_FUNC_ARG for invalid arguments
4181
 * @return MEMORY_E on failure to allocate memory
4182
*/
4183
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4184
161k
{
4185
161k
   int err = MP_OKAY;
4186
161k
   ecc_point* p;
4187
4188
161k
   if (point == NULL) {
4189
0
       return BAD_FUNC_ARG;
4190
0
   }
4191
4192
161k
   p = *point;
4193
161k
   if (p == NULL) {
4194
161k
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4195
161k
   }
4196
161k
   if (p == NULL) {
4197
1.35k
      return MEMORY_E;
4198
1.35k
   }
4199
160k
   XMEMSET(p, 0, sizeof(ecc_point));
4200
4201
160k
   if (*point == NULL)
4202
160k
       p->isAllocated = 1;
4203
4204
160k
#ifndef ALT_ECC_SIZE
4205
160k
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4206
160k
   if (err != MP_OKAY) {
4207
0
      WOLFSSL_MSG("mp_init_multi failed.");
4208
0
      if (p->isAllocated)
4209
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4210
0
      p = NULL;
4211
0
   }
4212
#else
4213
   p->x = (mp_int*)&p->xyz[0];
4214
   p->y = (mp_int*)&p->xyz[1];
4215
   p->z = (mp_int*)&p->xyz[2];
4216
   alt_fp_init(p->x);
4217
   alt_fp_init(p->y);
4218
   alt_fp_init(p->z);
4219
#endif
4220
4221
160k
   *point = p;
4222
160k
   (void)heap;
4223
160k
   return err;
4224
161k
} /* wc_ecc_new_point_ex */
4225
4226
ecc_point* wc_ecc_new_point_h(void* heap)
4227
32.3k
{
4228
32.3k
    ecc_point* p = NULL;
4229
32.3k
    (void)wc_ecc_new_point_ex(&p, heap);
4230
32.3k
    return p;
4231
32.3k
}
4232
4233
ecc_point* wc_ecc_new_point(void)
4234
3.26k
{
4235
3.26k
   ecc_point* p = NULL;
4236
3.26k
   (void)wc_ecc_new_point_ex(&p, NULL);
4237
3.26k
   return p;
4238
3.26k
}
4239
4240
/** Free an ECC point from memory
4241
  p   The point to free
4242
*/
4243
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4244
202k
{
4245
202k
   if (p != NULL) {
4246
160k
      mp_clear(p->x);
4247
160k
      mp_clear(p->y);
4248
160k
      mp_clear(p->z);
4249
160k
      if (p->isAllocated)
4250
160k
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4251
160k
   }
4252
202k
   (void)heap;
4253
202k
}
4254
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4255
230
{
4256
230
   wc_ecc_del_point_ex(p, heap);
4257
230
}
4258
void wc_ecc_del_point(ecc_point* p)
4259
75.1k
{
4260
75.1k
    wc_ecc_del_point_ex(p, NULL);
4261
75.1k
}
4262
4263
void wc_ecc_forcezero_point(ecc_point* p)
4264
0
{
4265
0
    if (p != NULL) {
4266
0
        mp_forcezero(p->x);
4267
0
        mp_forcezero(p->y);
4268
0
        mp_forcezero(p->z);
4269
0
    }
4270
0
}
4271
4272
4273
/** Copy the value of a point to an other one
4274
  p    The point to copy
4275
  r    The created point
4276
*/
4277
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4278
384k
{
4279
384k
    int ret;
4280
4281
    /* prevents null arguments */
4282
384k
    if (p == NULL || r == NULL)
4283
0
        return ECC_BAD_ARG_E;
4284
4285
384k
    ret = mp_copy(p->x, r->x);
4286
384k
    if (ret != MP_OKAY)
4287
0
        return ret;
4288
384k
    ret = mp_copy(p->y, r->y);
4289
384k
    if (ret != MP_OKAY)
4290
0
        return ret;
4291
384k
    ret = mp_copy(p->z, r->z);
4292
384k
    if (ret != MP_OKAY)
4293
0
        return ret;
4294
4295
384k
    return MP_OKAY;
4296
384k
}
4297
4298
/** Compare the value of a point with an other one
4299
 a    The point to compare
4300
 b    The other point to compare
4301
4302
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4303
 */
4304
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4305
2.30k
{
4306
2.30k
    int ret;
4307
4308
    /* prevents null arguments */
4309
2.30k
    if (a == NULL || b == NULL)
4310
0
        return BAD_FUNC_ARG;
4311
4312
2.30k
    ret = mp_cmp(a->x, b->x);
4313
2.30k
    if (ret != MP_EQ)
4314
1.73k
        return ret;
4315
571
    ret = mp_cmp(a->y, b->y);
4316
571
    if (ret != MP_EQ)
4317
328
        return ret;
4318
243
    ret = mp_cmp(a->z, b->z);
4319
243
    if (ret != MP_EQ)
4320
17
        return ret;
4321
4322
226
    return MP_EQ;
4323
243
}
4324
4325
4326
/** Returns whether an ECC idx is valid or not
4327
  n      The idx number to check
4328
  return 1 if valid, 0 if not
4329
*/
4330
int wc_ecc_is_valid_idx(int n)
4331
34.4k
{
4332
34.4k
   int x;
4333
4334
34.4k
   if (n >= (int)ECC_SET_COUNT)
4335
0
       return 0;
4336
4337
731k
   for (x = 0; ecc_sets[x].size != 0; x++)
4338
696k
       ;
4339
   /* -1 is a valid index --- indicating that the domain params
4340
      were supplied by the user */
4341
34.4k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4342
34.4k
      return 1;
4343
34.4k
   }
4344
4345
0
   return 0;
4346
34.4k
}
4347
4348
int wc_ecc_get_curve_idx(int curve_id)
4349
30.2k
{
4350
30.2k
    int curve_idx;
4351
336k
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4352
336k
        if (curve_id == ecc_sets[curve_idx].id)
4353
30.1k
            break;
4354
336k
    }
4355
30.2k
    if (ecc_sets[curve_idx].size == 0) {
4356
87
        return ECC_CURVE_INVALID;
4357
87
    }
4358
30.1k
    return curve_idx;
4359
30.2k
}
4360
4361
int wc_ecc_get_curve_id(int curve_idx)
4362
1.53k
{
4363
1.53k
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4364
1.53k
        return ecc_sets[curve_idx].id;
4365
1.53k
    }
4366
0
    return ECC_CURVE_INVALID;
4367
1.53k
}
4368
4369
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4370
 *
4371
 * id      curve id, from ecc_curve_id enum in ecc.h
4372
 * return  curve size, from ecc_sets[] on success, negative on error
4373
 */
4374
int wc_ecc_get_curve_size_from_id(int curve_id)
4375
1.71k
{
4376
1.71k
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4377
1.71k
    if (curve_idx == ECC_CURVE_INVALID)
4378
0
        return ECC_BAD_ARG_E;
4379
1.71k
    return ecc_sets[curve_idx].size;
4380
1.71k
}
4381
4382
/* Returns the curve index that corresponds to a given curve name in
4383
 * ecc_sets[] of ecc.c
4384
 *
4385
 * name    curve name, from ecc_sets[].name in ecc.c
4386
 * return  curve index in ecc_sets[] on success, negative on error
4387
 */
4388
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4389
0
{
4390
0
    int curve_idx;
4391
4392
0
    if (curveName == NULL)
4393
0
        return BAD_FUNC_ARG;
4394
4395
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4396
0
        if (
4397
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4398
0
            ecc_sets[curve_idx].name &&
4399
0
        #endif
4400
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4401
0
            break;
4402
0
        }
4403
0
    }
4404
0
    if (ecc_sets[curve_idx].size == 0) {
4405
0
        WOLFSSL_MSG("ecc_set curve name not found");
4406
0
        return ECC_CURVE_INVALID;
4407
0
    }
4408
0
    return curve_idx;
4409
0
}
4410
4411
/* Returns the curve size that corresponds to a given curve name,
4412
 * as listed in ecc_sets[] of ecc.c.
4413
 *
4414
 * name    curve name, from ecc_sets[].name in ecc.c
4415
 * return  curve size, from ecc_sets[] on success, negative on error
4416
 */
4417
int wc_ecc_get_curve_size_from_name(const char* curveName)
4418
0
{
4419
0
    int curve_idx;
4420
4421
0
    if (curveName == NULL)
4422
0
        return BAD_FUNC_ARG;
4423
4424
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4425
0
    if (curve_idx < 0)
4426
0
        return curve_idx;
4427
4428
0
    return ecc_sets[curve_idx].size;
4429
0
}
4430
4431
/* Returns the curve id that corresponds to a given curve name,
4432
 * as listed in ecc_sets[] of ecc.c.
4433
 *
4434
 * name   curve name, from ecc_sets[].name in ecc.c
4435
 * return curve id, from ecc_sets[] on success, negative on error
4436
 */
4437
int wc_ecc_get_curve_id_from_name(const char* curveName)
4438
0
{
4439
0
    int curve_idx;
4440
4441
0
    if (curveName == NULL)
4442
0
        return BAD_FUNC_ARG;
4443
4444
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4445
0
    if (curve_idx < 0)
4446
0
        return curve_idx;
4447
4448
0
    return ecc_sets[curve_idx].id;
4449
0
}
4450
4451
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4452
 * parameter for equality.
4453
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4454
 * Returns MP_EQ on success, negative on error */
4455
static int wc_ecc_cmp_param(const char* curveParam,
4456
                            const byte* param, word32 paramSz, int encType)
4457
0
{
4458
0
    int err = MP_OKAY;
4459
0
#ifdef WOLFSSL_SMALL_STACK
4460
0
    mp_int* a = NULL;
4461
0
    mp_int* b = NULL;
4462
#else
4463
    mp_int  a[1], b[1];
4464
#endif
4465
4466
0
    if (param == NULL || curveParam == NULL)
4467
0
        return BAD_FUNC_ARG;
4468
4469
0
    if (encType == WC_TYPE_HEX_STR) {
4470
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4471
0
            return -1;
4472
0
        return (XSTRNCMP(curveParam, (const char*) param, paramSz) == 0)
4473
0
            ? 0 : -1;
4474
0
    }
4475
4476
0
#ifdef WOLFSSL_SMALL_STACK
4477
0
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4478
0
    if (a == NULL)
4479
0
        return MEMORY_E;
4480
0
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4481
0
    if (b == NULL) {
4482
0
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4483
0
        return MEMORY_E;
4484
0
    }
4485
0
#endif
4486
4487
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4488
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4489
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4490
0
        return err;
4491
0
    }
4492
4493
0
    if (err == MP_OKAY) {
4494
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4495
0
    }
4496
0
    if (err == MP_OKAY)
4497
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4498
4499
0
    if (err == MP_OKAY) {
4500
0
        if (mp_cmp(a, b) != MP_EQ) {
4501
0
            err = -1;
4502
0
        } else {
4503
0
            err = MP_EQ;
4504
0
        }
4505
0
    }
4506
4507
0
    mp_clear(a);
4508
0
    mp_clear(b);
4509
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4510
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4511
4512
0
    return err;
4513
0
}
4514
4515
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4516
 * curve parameters.
4517
 *
4518
 * fieldSize  the field size in bits
4519
 * prime      prime of the finite field
4520
 * primeSz    size of prime in octets
4521
 * Af         first coefficient a of the curve
4522
 * AfSz       size of Af in octets
4523
 * Bf         second coefficient b of the curve
4524
 * BfSz       size of Bf in octets
4525
 * order      curve order
4526
 * orderSz    size of curve in octets
4527
 * Gx         affine x coordinate of base point
4528
 * GxSz       size of Gx in octets
4529
 * Gy         affine y coordinate of base point
4530
 * GySz       size of Gy in octets
4531
 * cofactor   curve cofactor
4532
 *
4533
 * return curve id, from ecc_sets[] on success, negative on error
4534
 */
4535
int wc_ecc_get_curve_id_from_params(int fieldSize,
4536
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4537
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4538
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4539
0
{
4540
0
    int idx;
4541
0
    int curveSz;
4542
4543
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4544
0
        Gx == NULL || Gy == NULL)
4545
0
        return BAD_FUNC_ARG;
4546
4547
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4548
4549
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4550
0
        if (curveSz == ecc_sets[idx].size) {
4551
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4552
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4553
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4554
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4555
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4556
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4557
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4558
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4559
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4560
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4561
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4562
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4563
0
                (cofactor == ecc_sets[idx].cofactor)) {
4564
0
                    break;
4565
0
            }
4566
0
        }
4567
0
    }
4568
4569
0
    if (ecc_sets[idx].size == 0)
4570
0
        return ECC_CURVE_INVALID;
4571
4572
0
    return ecc_sets[idx].id;
4573
0
}
4574
4575
/* Returns the curve id in ecc_sets[] that corresponds
4576
 * to a given domain parameters pointer.
4577
 *
4578
 * dp   domain parameters pointer
4579
 *
4580
 * return curve id, from ecc_sets[] on success, negative on error
4581
 */
4582
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4583
0
{
4584
0
    int idx;
4585
4586
0
    if (dp == NULL
4587
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4588
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4589
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4590
0
    #endif
4591
0
    ) {
4592
0
        return BAD_FUNC_ARG;
4593
0
    }
4594
4595
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4596
0
        if (dp->size == ecc_sets[idx].size) {
4597
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4598
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4599
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4600
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4601
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4602
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4603
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4604
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4605
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4606
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4607
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4608
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4609
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4610
0
                    break;
4611
0
            }
4612
0
        }
4613
0
    }
4614
4615
0
    if (ecc_sets[idx].size == 0)
4616
0
        return ECC_CURVE_INVALID;
4617
4618
0
    return ecc_sets[idx].id;
4619
0
}
4620
4621
/* Returns the curve id that corresponds to a given OID,
4622
 * as listed in ecc_sets[] of ecc.c.
4623
 *
4624
 * oid   OID, from ecc_sets[].name in ecc.c
4625
 * len   OID len, from ecc_sets[].name in ecc.c
4626
 * return curve id, from ecc_sets[] on success, negative on error
4627
 */
4628
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4629
0
{
4630
0
    int curve_idx;
4631
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4632
    int ret;
4633
    #ifdef HAVE_OID_DECODING
4634
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4635
    #else
4636
    byte  decOid[MAX_OID_SZ];
4637
    #endif
4638
    word32 decOidSz;
4639
#endif
4640
4641
0
    if (oid == NULL)
4642
0
        return BAD_FUNC_ARG;
4643
4644
#ifdef HAVE_OID_DECODING
4645
    decOidSz = (word32)sizeof(decOid);
4646
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4647
    if (ret != 0) {
4648
        return ret;
4649
    }
4650
#endif
4651
4652
0
    if (len == 0) {
4653
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4654
0
        WOLFSSL_MSG("zero oidSz");
4655
0
        return ECC_CURVE_INVALID;
4656
0
    }
4657
4658
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4659
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4660
        decOidSz = (word32)sizeof(decOid);
4661
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4662
            decOid, &decOidSz);
4663
        if (ret != 0) {
4664
            continue;
4665
        }
4666
    #endif
4667
4668
0
        if (
4669
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4670
0
            ecc_sets[curve_idx].oid &&
4671
0
        #endif
4672
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4673
            decOidSz == len &&
4674
                XMEMCMP(decOid, oid, len) == 0
4675
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4676
            /* We double because decOidSz is a count of word16 elements. */
4677
            ecc_sets[curve_idx].oidSz == decOidSz &&
4678
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4679
        #else
4680
0
            ecc_sets[curve_idx].oidSz == len &&
4681
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4682
0
        #endif
4683
0
        ) {
4684
0
            break;
4685
0
        }
4686
0
    }
4687
0
    if (ecc_sets[curve_idx].size == 0) {
4688
0
        WOLFSSL_MSG("ecc_set curve name not found");
4689
0
        return ECC_CURVE_INVALID;
4690
0
    }
4691
4692
0
    return ecc_sets[curve_idx].id;
4693
0
}
4694
4695
/* Get curve parameters using curve index */
4696
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4697
21.1k
{
4698
21.1k
    const ecc_set_type* ecc_set = NULL;
4699
4700
21.1k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4701
21.1k
        ecc_set = &ecc_sets[curve_idx];
4702
21.1k
    }
4703
21.1k
    return ecc_set;
4704
21.1k
}
4705
4706
4707
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4708
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4709
{
4710
   if (key == NULL || mp == NULL)
4711
      return BAD_FUNC_ARG;
4712
   if (*mp == NULL) {
4713
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4714
      if (*mp == NULL) {
4715
         return MEMORY_E;
4716
      }
4717
      XMEMSET(*mp, 0, sizeof(mp_int));
4718
   }
4719
   return 0;
4720
}
4721
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4722
{
4723
   if (key && mp && *mp) {
4724
      mp_clear(*mp);
4725
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4726
      *mp = NULL;
4727
   }
4728
}
4729
4730
static int wc_ecc_alloc_async(ecc_key* key)
4731
{
4732
    int err = wc_ecc_alloc_mpint(key, &key->r);
4733
    if (err == 0)
4734
        err = wc_ecc_alloc_mpint(key, &key->s);
4735
    return err;
4736
}
4737
4738
static void wc_ecc_free_async(ecc_key* key)
4739
{
4740
    wc_ecc_free_mpint(key, &key->r);
4741
    wc_ecc_free_mpint(key, &key->s);
4742
#ifdef HAVE_CAVIUM_V
4743
    wc_ecc_free_mpint(key, &key->e);
4744
    wc_ecc_free_mpint(key, &key->signK);
4745
#endif /* HAVE_CAVIUM_V */
4746
}
4747
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4748
4749
4750
#ifdef HAVE_ECC_DHE
4751
/**
4752
  Create an ECC shared secret between two keys
4753
  private_key      The private ECC key (heap hint based off of private key)
4754
  public_key       The public key
4755
  out              [out] Destination of the shared secret
4756
                         Conforms to EC-DH from ANSI X9.63
4757
  outlen           [in/out] The max size and resulting size of the shared secret
4758
  return           MP_OKAY if successful
4759
*/
4760
WOLFSSL_ABI
4761
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4762
                      word32* outlen)
4763
859
{
4764
859
   int err = 0;
4765
859
   int privateKeyOk = 0;
4766
4767
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4768
   !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
4769
   CRYS_ECDH_TempData_t tempBuff;
4770
#endif
4771
4772
859
   (void)err;
4773
859
   (void)privateKeyOk;
4774
4775
859
   if (private_key == NULL || public_key == NULL || out == NULL ||
4776
859
                                                            outlen == NULL) {
4777
0
       return BAD_FUNC_ARG;
4778
0
   }
4779
4780
859
#ifdef WOLF_CRYPTO_CB
4781
859
    #ifndef WOLF_CRYPTO_CB_FIND
4782
859
    if (private_key->devId != INVALID_DEVID)
4783
0
    #endif
4784
0
    {
4785
0
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4786
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4787
0
            return err;
4788
        /* fall-through when unavailable */
4789
0
    }
4790
859
#endif
4791
4792
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4793
    return NO_VALID_DEVID;
4794
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4795
   /* type valid? */
4796
859
   privateKeyOk = private_key->type == ECC_PRIVATEKEY ||
4797
230
                  private_key->type == ECC_PRIVATEKEY_ONLY;
4798
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
4799
      defined(WOLFSSL_SE050_ONLY_KEY_ID)
4800
   /* A SE050 key-id handle can represent a private key even though
4801
    * wc_ecc_use_key_id() only loads the public point into the ecc_key. */
4802
   if (private_key->keyIdSet)
4803
      privateKeyOk = 1;
4804
#endif
4805
859
   if (!privateKeyOk) {
4806
0
      return ECC_BAD_ARG_E;
4807
0
   }
4808
4809
   /* Verify domain params supplied */
4810
859
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4811
859
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4812
0
      return ECC_BAD_ARG_E;
4813
0
   }
4814
4815
   /* Verify curve id matches */
4816
859
   if (private_key->dp->id != public_key->dp->id) {
4817
0
      return ECC_BAD_ARG_E;
4818
0
   }
4819
4820
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
4821
    defined(WOLFSSL_MICROCHIP_TA100)
4822
   /* For SECP256R1 use hardware */
4823
   if (private_key->dp->id == ECC_SECP256R1 &&
4824
       private_key->slot != ATECC_INVALID_SLOT) {
4825
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4826
       *outlen = private_key->dp->size;
4827
   }
4828
   else {
4829
      err = NOT_COMPILED_IN;
4830
   }
4831
#elif defined(WOLFSSL_CRYPTOCELL)
4832
4833
    /* generate a secret*/
4834
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4835
                            &private_key->ctx.privKey,
4836
                            out,
4837
                            (uint32_t*)outlen,
4838
                            &tempBuff);
4839
4840
    if (err != SA_SILIB_RET_OK){
4841
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4842
        return err;
4843
    }
4844
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4845
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4846
#elif defined(WOLFSSL_KCAPI_ECC)
4847
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4848
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
4849
      defined(WOLFSSL_SE050_ONLY_KEY_ID)
4850
   /* SE050-resident private key uses hardware ECDH; a software private key
4851
    * (keyIdSet == 0) uses the wolfCrypt software implementation. */
4852
   if (private_key->keyIdSet)
4853
       err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4854
   else
4855
       err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out,
4856
                                     outlen);
4857
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE)
4858
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4859
#else
4860
859
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4861
859
#endif /* WOLFSSL_ATECC508A */
4862
859
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4863
4864
859
   return err;
4865
859
}
4866
4867
4868
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4869
    !defined(WOLFSSL_MICROCHIP_TA100) && \
4870
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4871
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4872
4873
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4874
                               byte* out, word32* outlen)
4875
195
{
4876
195
    int err = MP_OKAY;
4877
195
    mp_int* k = ecc_get_k(private_key);
4878
#ifdef WOLFSSL_SE050
4879
    /* A key-id handle holds no software private scalar - ECDH for such a key
4880
     * runs on the SE050 - so the identity this function computes from the
4881
     * all-zero scalar is not a shared secret and must not be rejected here. */
4882
    int checkInf = !private_key->keyIdSet;
4883
#else
4884
195
    int checkInf = 1;
4885
195
#endif
4886
#ifdef HAVE_ECC_CDH
4887
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
4888
#endif
4889
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4890
    defined(WC_ECC_NONBLOCK_ONLY)
4891
    ecc_nb_ctx_t nb_ctx;
4892
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4893
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4894
4895
#ifdef HAVE_ECC_CDH
4896
    /* if cofactor flag has been set */
4897
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4898
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4899
        /* only perform cofactor calc if not equal to 1 */
4900
        if (cofactor != 1) {
4901
#ifdef WOLFSSL_SMALL_STACK
4902
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4903
                return MEMORY_E;
4904
#endif
4905
            k = k_lcl;
4906
            if (mp_init(k) != MP_OKAY) {
4907
                err = MEMORY_E;
4908
                goto errout;
4909
            }
4910
            /* multiply cofactor times private key "k" */
4911
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4912
            if (err != MP_OKAY)
4913
                goto errout;
4914
        }
4915
    }
4916
#endif
4917
4918
#ifdef WOLFSSL_HAVE_SP_ECC
4919
4920
#ifndef WOLFSSL_SP_NO_256
4921
    if (private_key->idx != ECC_CUSTOM_IDX &&
4922
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4923
    #ifndef WC_ECC_NONBLOCK
4924
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4925
    #else
4926
        if (private_key->nb_ctx) {
4927
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4928
                                           point, out, outlen,
4929
                                           private_key->heap);
4930
        }
4931
        else {
4932
        #ifdef WC_ECC_NONBLOCK_ONLY
4933
            do { /* perform blocking call to non-blocking function */
4934
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4935
                                               outlen, private_key->heap);
4936
            } while (err == FP_WOULDBLOCK);
4937
        #else
4938
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4939
                                        private_key->heap);
4940
        #endif /* WC_ECC_NONBLOCK_ONLY */
4941
        }
4942
    #endif /* !WC_ECC_NONBLOCK */
4943
    }
4944
    else
4945
#endif /* ! WOLFSSL_SP_NO_256 */
4946
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4947
    if (private_key->idx != ECC_CUSTOM_IDX &&
4948
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4949
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4950
                                                             private_key->heap);
4951
    }
4952
    else
4953
#endif
4954
#ifdef WOLFSSL_SP_384
4955
    if (private_key->idx != ECC_CUSTOM_IDX &&
4956
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4957
    #ifndef WC_ECC_NONBLOCK
4958
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4959
    #else
4960
        if (private_key->nb_ctx) {
4961
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4962
                                           point, out, outlen,
4963
                                           private_key->heap);
4964
        }
4965
        else {
4966
        #ifdef WC_ECC_NONBLOCK_ONLY
4967
            do { /* perform blocking call to non-blocking function */
4968
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4969
                                               outlen, private_key->heap);
4970
            } while (err == FP_WOULDBLOCK);
4971
        #else
4972
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4973
                                        private_key->heap);
4974
        #endif /* WC_ECC_NONBLOCK_ONLY */
4975
        }
4976
    #endif /* !WC_ECC_NONBLOCK */
4977
    }
4978
    else
4979
#endif /* WOLFSSL_SP_384 */
4980
#ifdef WOLFSSL_SP_521
4981
    if (private_key->idx != ECC_CUSTOM_IDX &&
4982
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4983
    #ifndef WC_ECC_NONBLOCK
4984
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4985
    #else
4986
        if (private_key->nb_ctx) {
4987
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4988
                                           point, out, outlen,
4989
                                           private_key->heap);
4990
        }
4991
        else {
4992
        #ifdef WC_ECC_NONBLOCK_ONLY
4993
            do { /* perform blocking call to non-blocking function */
4994
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4995
                                               outlen, private_key->heap);
4996
            } while (err == FP_WOULDBLOCK);
4997
        #else
4998
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4999
                                        private_key->heap);
5000
        #endif /* WC_ECC_NONBLOCK_ONLY */
5001
        }
5002
    #endif /* !WC_ECC_NONBLOCK */
5003
    }
5004
    else
5005
#endif /* WOLFSSL_SP_521 */
5006
#else
5007
195
    (void)point;
5008
195
    (void)out;
5009
195
    (void)outlen;
5010
195
    (void)k;
5011
195
#endif
5012
#if defined(WOLFSSL_SP_MATH)
5013
    {
5014
        (void)checkInf;
5015
        err = WC_KEY_SIZE_E;
5016
        goto errout;
5017
    }
5018
#else
5019
195
    {
5020
195
        ecc_point* result = NULL;
5021
        #ifdef WOLFSSL_NO_MALLOC
5022
        ecc_point  lcl_result;
5023
        #endif
5024
195
        int x = 0;
5025
195
        mp_digit mp = 0;
5026
195
        DECLARE_CURVE_SPECS(3);
5027
5028
        /* load curve info */
5029
195
        ALLOC_CURVE_SPECS(3, err);
5030
195
        if (err == MP_OKAY) {
5031
195
            err = wc_ecc_curve_load(private_key->dp, &curve,
5032
195
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5033
195
                 ECC_CURVE_FIELD_ORDER));
5034
195
        }
5035
5036
195
        if (err != MP_OKAY) {
5037
0
            FREE_CURVE_SPECS();
5038
0
            goto errout;
5039
0
        }
5040
5041
        /* make new point */
5042
    #ifdef WOLFSSL_NO_MALLOC
5043
        result = &lcl_result;
5044
    #endif
5045
195
        err = wc_ecc_new_point_ex(&result, private_key->heap);
5046
195
        if (err != MP_OKAY) {
5047
0
            wc_ecc_curve_free(curve);
5048
0
            FREE_CURVE_SPECS();
5049
0
            goto errout;
5050
0
        }
5051
5052
195
#ifdef ECC_TIMING_RESISTANT
5053
195
        if (private_key->rng == NULL) {
5054
0
            err = MISSING_RNG_E;
5055
0
        }
5056
195
#endif
5057
5058
195
        if (err == MP_OKAY) {
5059
            /* Map in a separate call as this should be constant time */
5060
195
#ifdef ECC_TIMING_RESISTANT
5061
195
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5062
195
                                              curve->order, private_key->rng, 0,
5063
195
                                              private_key->heap);
5064
#else
5065
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5066
                                      curve->order, NULL, 0, private_key->heap);
5067
#endif
5068
195
        }
5069
195
        if (err == MP_OKAY) {
5070
        #ifdef WOLFSSL_CHECK_MEM_ZERO
5071
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
5072
                result->x);
5073
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
5074
                result->y);
5075
        #endif
5076
174
            err = mp_montgomery_setup(curve->prime, &mp);
5077
174
        }
5078
195
        if (err == MP_OKAY) {
5079
            /* Use constant time map if compiled in */
5080
174
            err = ecc_map_ex(result, curve->prime, mp, 1);
5081
174
        }
5082
195
        if (err == MP_OKAY) {
5083
            /* SP 800-56Ar3 5.7.1.2: the shared secret must not be the point at
5084
             * infinity. ecc_map_ex reports that case as x, y of zero with a
5085
             * success code, so check the point explicitly. */
5086
174
            if (checkInf && wc_ecc_point_is_at_infinity(result)) {
5087
12
                err = ECC_INF_E;
5088
12
            }
5089
174
        }
5090
195
        if (err == MP_OKAY) {
5091
162
            x = mp_unsigned_bin_size(curve->prime);
5092
162
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
5093
0
                err = BUFFER_E;
5094
0
            }
5095
162
        }
5096
5097
195
        if (err == MP_OKAY) {
5098
162
            XMEMSET(out, 0, (size_t)x);
5099
162
            err = mp_to_unsigned_bin(result->x, out +
5100
162
                                     (x - mp_unsigned_bin_size(result->x)));
5101
162
        }
5102
195
        *outlen = (word32)x;
5103
5104
195
        mp_forcezero(result->x);
5105
195
        mp_forcezero(result->y);
5106
195
        wc_ecc_del_point_ex(result, private_key->heap);
5107
5108
195
        wc_ecc_curve_free(curve);
5109
195
        FREE_CURVE_SPECS();
5110
195
    }
5111
0
#endif
5112
5113
#ifdef WOLFSSL_HAVE_SP_ECC
5114
    if ((err == MP_OKAY) && checkInf) {
5115
        /* The single precision implementations above serialize the point at
5116
         * infinity as an all-zero x-coordinate and report success, so the
5117
         * identity has to be recognized from the output. SP 800-56Ar3 5.7.1.2
5118
         * requires an error and stop in that case. Accumulate over the whole
5119
         * buffer so the scan does not branch on the secret. */
5120
        word32 i;
5121
        byte   acc = 0;
5122
5123
        for (i = 0; i < *outlen; i++) {
5124
            acc |= out[i];
5125
        }
5126
        if (acc == 0) {
5127
            err = ECC_INF_E;
5128
        }
5129
    }
5130
#endif
5131
5132
195
  errout:
5133
5134
#ifdef HAVE_ECC_CDH
5135
    if (k == k_lcl)
5136
        mp_forcezero(k);
5137
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
5138
#endif
5139
5140
195
    return err;
5141
195
}
5142
5143
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5144
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
5145
            ecc_point* point, byte* out, word32 *outlen)
5146
{
5147
    int err = 0;
5148
5149
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5150
    DECLARE_CURVE_SPECS(3);
5151
5152
    /* load curve info */
5153
    ALLOC_CURVE_SPECS(3, err);
5154
    if (err == MP_OKAY) {
5155
        err = wc_ecc_curve_load(private_key->dp, &curve,
5156
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5157
             ECC_CURVE_FIELD_ORDER));
5158
    }
5159
5160
    if (err != MP_OKAY) {
5161
        FREE_CURVE_SPECS();
5162
        return err;
5163
    }
5164
5165
    if (private_key->dp
5166
    #ifdef WOLFSSL_CUSTOM_CURVES
5167
        && private_key->dp->id != ECC_CURVE_CUSTOM
5168
    #endif
5169
    #ifdef HAVE_CAVIUM_V
5170
        /* verify the curve is supported by hardware */
5171
        && NitroxEccIsCurveSupported(private_key)
5172
    #endif
5173
    ) {
5174
        word32 keySz = private_key->dp->size;
5175
5176
        /* sync public key x/y */
5177
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5178
            &ecc_get_k(private_key)->raw, keySz);
5179
        if (err == MP_OKAY)
5180
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5181
        if (err == MP_OKAY)
5182
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5183
    #ifdef HAVE_CAVIUM_V
5184
        /* allocate buffer for output */
5185
        if (err == MP_OKAY)
5186
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5187
        if (err == MP_OKAY)
5188
            err = wc_bigint_alloc(&private_key->e->raw,
5189
                NitroxEccGetSize(private_key)*2);
5190
        if (err == MP_OKAY)
5191
            err = NitroxEcdh(private_key,
5192
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5193
                private_key->e->raw.buf, &private_key->e->raw.len,
5194
                &curve->prime->raw);
5195
    #else
5196
        if (err == MP_OKAY)
5197
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5198
        if (err == MP_OKAY)
5199
            err = IntelQaEcdh(&private_key->asyncDev,
5200
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5201
                out, outlen,
5202
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5203
                private_key->dp->cofactor);
5204
    #endif
5205
    }
5206
    else
5207
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5208
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5209
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5210
        sw->eccSharedSec.private_key = private_key;
5211
        sw->eccSharedSec.public_point = point;
5212
        sw->eccSharedSec.out = out;
5213
        sw->eccSharedSec.outLen = outlen;
5214
        err = WC_PENDING_E;
5215
    }
5216
    else
5217
#endif
5218
    {
5219
        /* use sync in other cases */
5220
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5221
    }
5222
5223
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5224
        private_key->state++;
5225
    }
5226
5227
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5228
    wc_ecc_curve_free(curve);
5229
    FREE_CURVE_SPECS();
5230
#endif
5231
5232
    return err;
5233
}
5234
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5235
5236
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5237
/**
5238
 Create an ECC shared secret between private key and public point
5239
 private_key      The private ECC key (heap hint based on private key)
5240
 point            The point to use (public key)
5241
 out              [out] Destination of the shared secret
5242
                        Conforms to EC-DH from ANSI X9.63
5243
 outlen           [in/out] The max size and resulting size of the shared secret
5244
 return           MP_OKAY if successful
5245
*/
5246
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5247
                            byte* out, word32 *outlen)
5248
859
{
5249
859
    int err;
5250
5251
859
    if (private_key == NULL || point == NULL || out == NULL ||
5252
859
                                                            outlen == NULL) {
5253
0
        return BAD_FUNC_ARG;
5254
0
    }
5255
5256
    /* type valid? */
5257
859
    if (private_key->type != ECC_PRIVATEKEY &&
5258
230
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5259
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5260
0
        return ECC_BAD_ARG_E;
5261
0
    }
5262
5263
    /* Verify domain params supplied */
5264
859
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5265
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5266
0
        return ECC_BAD_ARG_E;
5267
0
    }
5268
5269
859
    switch (private_key->state) {
5270
859
        case ECC_STATE_NONE:
5271
859
        case ECC_STATE_SHARED_SEC_GEN:
5272
859
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5273
5274
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5275
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5276
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5277
                    out, outlen);
5278
            }
5279
            else
5280
        #endif
5281
859
            {
5282
859
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5283
859
                    out, outlen);
5284
859
            }
5285
859
            if (err < 0) {
5286
63
                break;
5287
63
            }
5288
796
            FALL_THROUGH;
5289
5290
796
        case ECC_STATE_SHARED_SEC_RES:
5291
796
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5292
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5293
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5294
            #ifdef HAVE_CAVIUM_V
5295
                /* verify the curve is supported by hardware */
5296
                if (NitroxEccIsCurveSupported(private_key)) {
5297
                    /* copy output */
5298
                    *outlen = private_key->dp->size;
5299
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5300
                }
5301
            #endif /* HAVE_CAVIUM_V */
5302
            }
5303
        #endif /* WOLFSSL_ASYNC_CRYPT */
5304
796
            err = 0;
5305
796
            break;
5306
5307
0
        default:
5308
0
            err = BAD_STATE_E;
5309
859
    } /* switch */
5310
5311
    /* if async pending then return and skip done cleanup below */
5312
859
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5313
0
        return err;
5314
0
    }
5315
5316
    /* cleanup */
5317
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5318
    wc_ecc_free_async(private_key);
5319
#endif
5320
859
    private_key->state = ECC_STATE_NONE;
5321
5322
859
    return err;
5323
859
}
5324
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5325
#elif defined(WOLFSSL_KCAPI_ECC)
5326
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5327
                            byte* out, word32 *outlen)
5328
{
5329
    int err;
5330
    WC_DECLARE_VAR(public_key, ecc_key, 1,
5331
                   private_key ? private_key->heap : NULL);
5332
5333
    WC_ALLOC_VAR_EX(public_key, ecc_key, 1, private_key->heap, DYNAMIC_TYPE_ECC,
5334
                    return MEMORY_E);
5335
5336
    err = wc_ecc_init_ex(public_key, private_key->heap, INVALID_DEVID);
5337
    if (err == MP_OKAY) {
5338
        #if FIPS_VERSION3_GE(6,0,0)
5339
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5340
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5341
         * keysize here when relying on default selection */
5342
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5343
            if (private_key->dp->size == 0 &&
5344
                (private_key->dp->id == ECC_SECP256R1 ||
5345
                private_key->dp->id == ECC_SECP224R1 ||
5346
                private_key->dp->id == ECC_SECP384R1 ||
5347
                private_key->dp->id == ECC_SECP521R1)) {
5348
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5349
                err = 0;
5350
            } else {
5351
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5352
                err = ECC_CURVE_OID_E;
5353
            }
5354
        }
5355
        if (err == 0) { /* FIPS specific check */
5356
        #endif
5357
        err = wc_ecc_set_curve(public_key, private_key->dp->size,
5358
                               private_key->dp->id);
5359
        if (err == MP_OKAY) {
5360
            err = mp_copy(point->x, public_key->pubkey.x);
5361
        }
5362
        #if FIPS_VERSION3_GE(6,0,0)
5363
        } /* end FIPS specific check */
5364
        #endif
5365
        if (err == MP_OKAY) {
5366
            err = mp_copy(point->y, public_key->pubkey.y);
5367
        }
5368
        if (err == MP_OKAY) {
5369
            err = wc_ecc_shared_secret(private_key, public_key, out, outlen);
5370
        }
5371
5372
        wc_ecc_free(public_key);
5373
    }
5374
5375
    WC_FREE_VAR_EX(public_key, private_key->heap, DYNAMIC_TYPE_ECC);
5376
    return err;
5377
}
5378
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5379
#endif /* HAVE_ECC_DHE */
5380
5381
/* Checks if a point p lies on the curve with index curve_idx */
5382
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5383
6.08k
{
5384
6.08k
    int err = MP_OKAY;
5385
6.08k
    DECLARE_CURVE_SPECS(3);
5386
5387
6.08k
    if (p == NULL)
5388
0
        return BAD_FUNC_ARG;
5389
5390
    /* is the IDX valid ?  */
5391
6.08k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5392
0
       return ECC_BAD_ARG_E;
5393
0
    }
5394
5395
6.08k
    ALLOC_CURVE_SPECS(3, err);
5396
6.08k
    if (err == MP_OKAY) {
5397
5.88k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5398
5.88k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5399
5.88k
                                ECC_CURVE_FIELD_BF);
5400
5.88k
    }
5401
5402
6.08k
    if (err == MP_OKAY) {
5403
5.88k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5404
5.88k
    }
5405
5406
6.08k
    wc_ecc_curve_free(curve);
5407
6.08k
    FREE_CURVE_SPECS();
5408
5409
6.08k
    return err;
5410
6.08k
}
5411
5412
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5413
    !defined(WOLFSSL_CRYPTOCELL) && \
5414
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5415
      defined(WOLFSSL_IMXRT1170_CAAM))
5416
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5417
int wc_ecc_point_is_at_infinity(ecc_point* p)
5418
9.81k
{
5419
9.81k
    if (p == NULL)
5420
0
        return BAD_FUNC_ARG;
5421
9.81k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5422
2.22k
        return 1;
5423
5424
7.58k
    return 0;
5425
9.81k
}
5426
#endif
5427
5428
/* generate random and ensure its greater than 0 and less than order */
5429
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5430
32.0k
{
5431
32.0k
#ifndef WC_NO_RNG
5432
32.0k
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5433
32.0k
    int err;
5434
32.0k
    byte buf[ECC_MAXSIZE_GEN];
5435
5436
32.0k
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5437
32.0k
                                                                order == NULL) {
5438
0
        return BAD_FUNC_ARG;
5439
0
    }
5440
5441
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5442
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5443
32.0k
    size += 8;
5444
5445
    /* make up random string */
5446
32.0k
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5447
#ifdef WOLFSSL_CHECK_MEM_ZERO
5448
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5449
#endif
5450
5451
    /* load random buffer data into k */
5452
32.0k
    if (err == 0)
5453
31.7k
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5454
5455
    /* the key should be smaller than the order of base point */
5456
32.0k
    if (err == MP_OKAY) {
5457
31.7k
        if (mp_cmp(k, order) != MP_LT) {
5458
31.5k
            err = mp_mod(k, order, k);
5459
31.5k
        }
5460
31.7k
    }
5461
5462
    /* quick sanity check to make sure we're not dealing with a 0 key */
5463
32.0k
    if (err == MP_OKAY) {
5464
31.6k
        if (mp_iszero(k) == MP_YES)
5465
133
          err = MP_ZERO_E;
5466
31.6k
    }
5467
5468
32.0k
    ForceZero(buf, ECC_MAXSIZE_GEN);
5469
#ifdef WOLFSSL_CHECK_MEM_ZERO
5470
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5471
#endif
5472
5473
32.0k
    return err;
5474
#else
5475
    int err;
5476
    byte buf[ECC_MAXSIZE_GEN];
5477
    int bits;
5478
5479
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5480
            (k == NULL) || (order == NULL)) {
5481
        return BAD_FUNC_ARG;
5482
    }
5483
5484
    /* Get actual bit count of order. */
5485
    bits = mp_count_bits(order);
5486
    size = (bits + 7) >> 3;
5487
5488
    /* generate number in range of order through rejection sampling. */
5489
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5490
    do {
5491
        /* A.2.2 step 3: make up random string */
5492
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5493
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5494
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5495
    #endif
5496
        /* Generated multiple of 8 bits but now make it size of order. */
5497
        if ((bits & 0x7) > 0) {
5498
            buf[0] &= (1 << (bits & 0x7)) - 1;
5499
        }
5500
5501
        /* A.2.2 step 4: convert to integer. */
5502
        /* A.4.2 step 3: Convert the bit string to integer x. */
5503
        if (err == 0) {
5504
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5505
        }
5506
5507
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5508
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5509
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5510
            break;
5511
        }
5512
    }
5513
    while (err == MP_OKAY);
5514
5515
    ForceZero(buf, ECC_MAXSIZE_GEN);
5516
#ifdef WOLFSSL_CHECK_MEM_ZERO
5517
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5518
#endif
5519
5520
    return err;
5521
#endif
5522
#else
5523
    (void)rng;
5524
    (void)size;
5525
    (void)k;
5526
    (void)order;
5527
    return NOT_COMPILED_IN;
5528
#endif /* !WC_NO_RNG */
5529
32.0k
}
5530
5531
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5532
36.9k
{
5533
    /* make sure required key variables are reset */
5534
36.9k
    key->state = ECC_STATE_NONE;
5535
36.9k
}
5536
5537
5538
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
5539
/* compute the public key Q = d*G in software.
5540
 *
5541
 * key    private key holding the scalar d, must be present and in range
5542
 * curve  [in]curve for key, cannot be NULL
5543
 * pub    [out]initialized ecc_point receiving the public key
5544
 * rng    optional RNG for a timing-resistant point multiply, may be NULL
5545
 *
5546
 * returns MP_OKAY on success
5547
 */
5548
static int ecc_make_pub_sw(ecc_key* key, ecc_curve_spec* curve,
5549
        ecc_point* pub, WC_RNG* rng)
5550
9.48k
{
5551
9.48k
    int err = MP_OKAY;
5552
5553
9.48k
    (void)rng;
5554
5555
    /* The private scalar must be in range for the base-point multiply
5556
     * below. */
5557
9.48k
    if (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
5558
9.48k
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT)) {
5559
41
        err = ECC_PRIV_KEY_E;
5560
41
    }
5561
5562
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5563
    defined(HAVE_INTEL_QA)
5564
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5565
        word32 keySz = key->dp->size;
5566
        /* sync private key to raw */
5567
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5568
        if (err == MP_OKAY) {
5569
            err = IntelQaEccPointMul(&key->asyncDev,
5570
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5571
                &curve->Gx->raw, &curve->Gy->raw,
5572
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5573
                key->dp->cofactor);
5574
        }
5575
    }
5576
    else
5577
#endif
5578
9.48k
    { /* BEGIN: Software Crypto */
5579
#ifdef WOLFSSL_HAVE_SP_ECC
5580
    /* Single-Precision Math (optimized for specific curves) */
5581
    if (err != MP_OKAY) {
5582
    }
5583
    else
5584
#ifndef WOLFSSL_SP_NO_256
5585
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5586
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5587
    }
5588
    else
5589
#endif /* WOLFSSL_SP_NO_256 */
5590
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5591
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5592
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5593
    }
5594
    else
5595
#endif
5596
#ifdef WOLFSSL_SP_384
5597
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5598
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5599
    }
5600
    else
5601
#endif
5602
#ifdef WOLFSSL_SP_521
5603
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5604
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5605
    }
5606
    else
5607
#endif
5608
#endif /* WOLFSSL_HAVE_SP_ECC */
5609
5610
#if defined(WOLFSSL_SP_MATH)
5611
        err = WC_KEY_SIZE_E;
5612
#else
5613
9.48k
    if (err == MP_OKAY) {
5614
        /* Multi-Precision Math: compute public curve */
5615
9.44k
        mp_digit mp = 0;
5616
9.44k
        ecc_point* base = NULL;
5617
    #ifdef WOLFSSL_NO_MALLOC
5618
        ecc_point  lcl_base;
5619
        base = &lcl_base;
5620
    #endif
5621
9.44k
        err = wc_ecc_new_point_ex(&base, key->heap);
5622
5623
        /* read in the x/y for this key */
5624
9.44k
        if (err == MP_OKAY)
5625
9.39k
            err = mp_copy(curve->Gx, base->x);
5626
9.44k
        if (err == MP_OKAY)
5627
9.39k
            err = mp_copy(curve->Gy, base->y);
5628
9.44k
        if (err == MP_OKAY)
5629
9.39k
            err = mp_montgomery_setup(curve->prime, &mp);
5630
9.44k
        if (err == MP_OKAY)
5631
9.39k
            err = mp_set(base->z, 1);
5632
5633
        /* make the public key */
5634
9.44k
        if (err == MP_OKAY) {
5635
            /* Map in a separate call as this should be constant time */
5636
9.39k
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5637
9.39k
                                 curve->prime, curve->order, rng, 0, key->heap);
5638
9.39k
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5639
1.24k
               err = MEMORY_E;
5640
1.24k
            }
5641
9.39k
        }
5642
9.44k
        if (err == MP_OKAY) {
5643
            /* Use constant time map if compiled in */
5644
7.66k
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5645
7.66k
        }
5646
5647
9.44k
        wc_ecc_del_point_ex(base, key->heap);
5648
9.44k
    }
5649
9.48k
#endif /* WOLFSSL_SP_MATH */
5650
9.48k
    } /* END: Software Crypto */
5651
5652
9.48k
    return err;
5653
9.48k
}
5654
#endif /* HAVE_ECC_MAKE_PUB && !WOLF_CRYPTO_CB_ONLY_ECC */
5655
5656
/* create the public ECC key from a private key
5657
 *
5658
 * key     an initialized private key to generate public part from
5659
 * curve   [in]curve for key, cannot be NULL
5660
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5661
 *         is cached in key instead.
5662
 *
5663
 * Note this function is local to the file because of the argument type
5664
 *      ecc_curve_spec. Having this argument allows for not having to load the
5665
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5666
 * For async the results are placed directly into pubOut, so this function
5667
 *      does not need to be called again
5668
 *
5669
 * returns MP_OKAY on success
5670
 */
5671
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5672
        ecc_point* pubOut, WC_RNG* rng)
5673
16.9k
{
5674
16.9k
    int err = MP_OKAY;
5675
16.9k
#ifdef HAVE_ECC_MAKE_PUB
5676
16.9k
    ecc_point* pub;
5677
16.9k
    int doneInCb = 0;
5678
16.9k
#endif /* HAVE_ECC_MAKE_PUB */
5679
5680
16.9k
    (void)rng;
5681
5682
16.9k
    if (key == NULL) {
5683
0
        return BAD_FUNC_ARG;
5684
0
    }
5685
5686
16.9k
#ifdef HAVE_ECC_MAKE_PUB
5687
    /* if ecc_point passed in then use it as output for public key point */
5688
16.9k
    if (pubOut != NULL) {
5689
4.41k
        pub = pubOut;
5690
4.41k
    }
5691
12.5k
    else {
5692
        /* caching public key making it a ECC_PRIVATEKEY instead of
5693
           ECC_PRIVATEKEY_ONLY */
5694
12.5k
        pub = &key->pubkey;
5695
12.5k
        key->type = ECC_PRIVATEKEY_ONLY;
5696
12.5k
    }
5697
5698
16.9k
    if (err == MP_OKAY) {
5699
16.9k
    #ifndef ALT_ECC_SIZE
5700
16.9k
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5701
    #else
5702
        pub->x = (mp_int*)&pub->xyz[0];
5703
        pub->y = (mp_int*)&pub->xyz[1];
5704
        pub->z = (mp_int*)&pub->xyz[2];
5705
        alt_fp_init(pub->x);
5706
        alt_fp_init(pub->y);
5707
        alt_fp_init(pub->z);
5708
    #endif
5709
16.9k
    }
5710
5711
16.9k
#ifdef WOLF_CRYPTO_CB
5712
    /* offload Q = d*G to the device; fall through to software only when the
5713
     * device reports the operation unavailable.
5714
     *
5715
     * Under WOLF_CRYPTO_CB_FIND the devId gate is dropped so a find callback
5716
     * can route a key initialized with INVALID_DEVID. This helper is also
5717
     * shared by internal callers that compute a point from a transient scalar
5718
     * in key->k - the ECDSA software-sign nonce R = k*G (ecc_sign_hash_sw),
5719
     * keygen public-part derivation, and verify-time public-key recovery.
5720
     * Reaching the software signer means the device already declined to sign
5721
     * (the whole-sign offload wc_CryptoCb_EccSign ran first), so a find
5722
     * callback that hands this make-pub to a device notwithstanding the
5723
     * INVALID_DEVID is expected to likewise decline it. If it does not decline
5724
     * *and* the device ignores key->k (e.g. relying on an internal key
5725
     * representation), it returns d*G instead of the requested k*G and the
5726
     * resulting signature is wrong - but such a scenario is very unlikely. */
5727
16.9k
    #ifndef WOLF_CRYPTO_CB_FIND
5728
16.9k
    if ((err == MP_OKAY) && (key->devId != INVALID_DEVID))
5729
    #else
5730
    if (err == MP_OKAY)
5731
    #endif
5732
0
    {
5733
0
        err = wc_CryptoCb_EccMakePub(key, pub);
5734
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5735
0
            doneInCb = 1;
5736
0
        else
5737
0
            err = MP_OKAY; /* device declined the offload; fall back */
5738
0
    }
5739
16.9k
#endif
5740
5741
16.9k
    if ((err == MP_OKAY) && !doneInCb) {
5742
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5743
        /* software derivation is stripped and no device handled the op;
5744
         * fail closed */
5745
        (void)curve;
5746
        err = NO_VALID_DEVID;
5747
#else
5748
16.9k
        err = ecc_make_pub_sw(key, curve, pub, rng);
5749
16.9k
#endif
5750
16.9k
    }
5751
5752
16.9k
    if (err != MP_OKAY
5753
    #ifdef WOLFSSL_ASYNC_CRYPT
5754
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5755
    #endif
5756
16.9k
    ) {
5757
        /* clean up if failed */
5758
2.55k
    #ifndef ALT_ECC_SIZE
5759
2.55k
        mp_clear(pub->x);
5760
2.55k
        mp_clear(pub->y);
5761
2.55k
        mp_clear(pub->z);
5762
2.55k
    #endif
5763
2.55k
    }
5764
5765
#else
5766
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5767
    (void)curve;
5768
    err = NOT_COMPILED_IN;
5769
#endif /* HAVE_ECC_MAKE_PUB */
5770
5771
    /* change key state if public part is cached */
5772
16.9k
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5773
12.5k
        key->type = ECC_PRIVATEKEY;
5774
12.5k
    }
5775
5776
16.9k
    return err;
5777
16.9k
}
5778
5779
5780
/* create the public ECC key from a private key
5781
 *
5782
 * key     an initialized private key to generate public part from
5783
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5784
 *         is cached in key instead.
5785
 *
5786
 *
5787
 * returns MP_OKAY on success
5788
 */
5789
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5790
4.44k
{
5791
4.44k
    WOLFSSL_ENTER("wc_ecc_make_pub");
5792
5793
4.44k
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5794
4.44k
}
5795
5796
/* create the public ECC key from a private key - mask timing use random z
5797
 *
5798
 * key     an initialized private key to generate public part from
5799
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5800
 *         is cached in key instead.
5801
 *
5802
 *
5803
 * returns MP_OKAY on success
5804
 */
5805
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5806
1.49k
{
5807
1.49k
    int err = MP_OKAY;
5808
1.49k
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5809
5810
1.49k
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5811
5812
1.49k
    if (key == NULL) {
5813
0
        return BAD_FUNC_ARG;
5814
0
    }
5815
5816
    /* load curve info */
5817
1.49k
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5818
1.49k
    if (err == MP_OKAY) {
5819
1.48k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5820
1.48k
    }
5821
1.49k
    if (err == MP_OKAY) {
5822
1.48k
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5823
1.48k
    }
5824
5825
1.49k
    wc_ecc_curve_free(curve);
5826
1.49k
    FREE_CURVE_SPECS();
5827
5828
1.49k
    return err;
5829
1.49k
}
5830
5831
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5832
    defined(WOLFSSL_MICROCHIP_TA100)
5833
/* Resolve the curve id to pass to the Microchip backend. Keep the curve
5834
 * distinction by id (not size): SECP256R1, SECP256K1 and BRAINPOOLP256R1 are
5835
 * all 32 bytes and must NOT be collapsed onto SECP256R1. */
5836
static WC_INLINE int microchip_curve_id_for_key(const ecc_key* key)
5837
{
5838
    if (key != NULL && key->dp != NULL) {
5839
        return key->dp->id;
5840
    }
5841
    return ECC_CURVE_DEF;
5842
}
5843
#endif
5844
5845
5846
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5847
        int curve_id, int flags)
5848
9.29k
{
5849
9.29k
    int err = 0;
5850
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5851
    !defined(WOLFSSL_MICROCHIP_TA100) && \
5852
    !defined(WOLFSSL_ATECC608A)
5853
    const CRYS_ECPKI_Domain_t*  pDomain;
5854
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5855
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5856
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5857
    word32 raw_size = 0;
5858
#endif
5859
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5860
    defined(WC_ECC_NONBLOCK_ONLY)
5861
    ecc_nb_ctx_t nb_ctx;
5862
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5863
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5864
5865
9.29k
    if (key == NULL || rng == NULL) {
5866
0
        return BAD_FUNC_ARG;
5867
0
    }
5868
5869
    /* make sure required variables are reset */
5870
9.29k
    wc_ecc_reset(key);
5871
5872
    #if FIPS_VERSION3_GE(6,0,0)
5873
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5874
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5875
     * keysize here when relying on default selection */
5876
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5877
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5878
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5879
             curve_id == ECC_SECP521R1)) {
5880
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5881
            err = 0;
5882
        } else {
5883
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5884
            err = ECC_CURVE_OID_E;
5885
        }
5886
    }
5887
    if (err == 0) { /* FIPS specific check */
5888
    #endif
5889
9.29k
    err = wc_ecc_set_curve(key, keysize, curve_id);
5890
9.29k
    if (err != 0) {
5891
0
        return err;
5892
0
    }
5893
    #if FIPS_VERSION3_GE(6,0,0)
5894
    } /* end FIPS specific check */
5895
    #endif
5896
9.29k
    key->flags = (byte)flags;
5897
5898
9.29k
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5899
9.29k
    #ifndef WOLF_CRYPTO_CB_FIND
5900
9.29k
    if (key->devId != INVALID_DEVID)
5901
0
    #endif
5902
0
    {
5903
0
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5904
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5905
0
            return err;
5906
        /* fall-through when unavailable */
5907
0
    }
5908
9.29k
#endif
5909
5910
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5911
    return NO_VALID_DEVID;
5912
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5913
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5914
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5915
    #ifdef HAVE_CAVIUM
5916
        /* TODO: Not implemented */
5917
    #elif defined(HAVE_INTEL_QA)
5918
        /* Implemented in ecc_make_pub_ex for the pub calc */
5919
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5920
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5921
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5922
            sw->eccMake.rng = rng;
5923
            sw->eccMake.key = key;
5924
            sw->eccMake.size = keysize;
5925
            sw->eccMake.curve_id = curve_id;
5926
            return WC_PENDING_E;
5927
        }
5928
    #endif
5929
    }
5930
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5931
5932
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5933
    defined(WOLFSSL_MICROCHIP_TA100)
5934
#if defined(WOLFSSL_MICROCHIP_TA100)
5935
    /* TA100 supports multiple curves natively. */
5936
    if (key->dp->id == ECC_SECP256R1 ||
5937
        key->dp->id == ECC_SECP224R1 ||
5938
        key->dp->id == ECC_SECP384R1 ||
5939
        key->dp->id == ECC_SECP256K1 ||
5940
        key->dp->id == ECC_BRAINPOOLP256R1) {
5941
#else
5942
    /* ATECC508A/608A hardware only supports SECP256R1. */
5943
    if (key->dp->id == ECC_SECP256R1) {
5944
#endif
5945
       key->type = ECC_PRIVATEKEY;
5946
       if (key->slot == ATECC_INVALID_SLOT)
5947
           key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5948
       err = atmel_ecc_create_key(key->slot, microchip_curve_id_for_key(key),
5949
           key->pubkey_raw);
5950
5951
       /* populate key->pubkey */
5952
       if (err == 0
5953
       #ifdef ALT_ECC_SIZE
5954
          && key->pubkey.x
5955
       #endif
5956
       ) {
5957
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5958
                                      (word32)key->dp->size);
5959
       }
5960
       if (err == 0
5961
       #ifdef ALT_ECC_SIZE
5962
          && key->pubkey.y
5963
       #endif
5964
       ) {
5965
           err = mp_read_unsigned_bin(key->pubkey.y,
5966
                                      key->pubkey_raw + key->dp->size,
5967
                                      (word32)key->dp->size);
5968
       }
5969
   }
5970
   else {
5971
      err = NOT_COMPILED_IN;
5972
   }
5973
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
5974
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
5975
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5976
    key->type = ECC_PRIVATEKEY;
5977
#elif defined(WOLFSSL_CRYPTOCELL)
5978
5979
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5980
    raw_size = (word32)(key->dp->size)*2 + 1;
5981
5982
    /* generate first key pair */
5983
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5984
                                wc_rndGenVectFunc,
5985
                                pDomain,
5986
                                &key->ctx.privKey,
5987
                                &key->ctx.pubKey,
5988
                                &tempBuff,
5989
                                &fipsCtx);
5990
5991
    if (err != SA_SILIB_RET_OK){
5992
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5993
        return err;
5994
    }
5995
    key->type = ECC_PRIVATEKEY;
5996
5997
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5998
                                   CRYS_EC_PointUncompressed,
5999
                                   &ucompressed_key[0],
6000
                                   (uint32_t*)&raw_size);
6001
6002
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
6003
        err = mp_read_unsigned_bin(key->pubkey.x,
6004
                                   &ucompressed_key[1], key->dp->size);
6005
        if (err == MP_OKAY) {
6006
            err = mp_read_unsigned_bin(key->pubkey.y,
6007
                            &ucompressed_key[1+key->dp->size],key->dp->size);
6008
        }
6009
    }
6010
    raw_size = key->dp->size;
6011
    if (err == MP_OKAY) {
6012
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
6013
                                       ucompressed_key,
6014
                                       (uint32_t*)&raw_size);
6015
    }
6016
6017
    if (err == SA_SILIB_RET_OK) {
6018
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
6019
#ifdef WOLFSSL_ECC_BLIND_K
6020
        if (err == MP_OKAY) {
6021
            err = ecc_blind_k_rng(key, rng);
6022
        }
6023
#endif
6024
    }
6025
6026
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6027
    return silabs_ecc_make_key(key, keysize);
6028
#elif defined(WOLFSSL_KCAPI_ECC)
6029
6030
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
6031
    (void)rng;
6032
6033
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6034
    if (xil_curve_type[key->dp->id] == 0)
6035
        return ECC_CURVE_OID_E;
6036
6037
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
6038
    if (err)
6039
        return err;
6040
    /* Make sure that private key is max. 521 bits */
6041
    if (key->dp->size == 66)
6042
        key->privKey[65] &= 0x1U;
6043
6044
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
6045
6046
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6047
                                        2 * key->dp->size);
6048
6049
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
6050
                                      xil_curve_type[key->dp->id],
6051
                                      XIL_CAST_U64(key->privKey),
6052
                                      XIL_CAST_U64(key->keyRaw));
6053
    if (err != XST_SUCCESS) {
6054
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
6055
        err = WC_HW_E;
6056
    }
6057
6058
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6059
                                        2 * key->dp->size);
6060
6061
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
6062
    if (err == 0)
6063
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
6064
                                          xil_curve_type[key->dp->id],
6065
                                          XIL_CAST_U64(key->keyRaw));
6066
#endif
6067
6068
    if (err == 0)
6069
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
6070
                             key->heap);
6071
    if (err == 0)
6072
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
6073
                             key->dp->size, key->heap);
6074
    if (err == 0)
6075
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
6076
                             key->heap);
6077
#ifdef WOLFSSL_ECC_BLIND_K
6078
    if (err == 0)
6079
        err = ecc_blind_k_rng(key, rng);
6080
#endif
6081
    if (err == 0)
6082
        err = mp_set(key->pubkey.z, 1);
6083
    if (err) {
6084
        key->privKey = NULL;
6085
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
6086
        return err;
6087
    }
6088
6089
    key->type = ECC_PRIVATEKEY;
6090
6091
#else
6092
6093
#ifdef WOLFSSL_HAVE_SP_ECC
6094
6095
#ifndef WOLFSSL_SP_NO_256
6096
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
6097
    #ifndef WC_ECC_NONBLOCK
6098
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6099
    #else
6100
        if (key->nb_ctx) {
6101
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6102
                                         &key->pubkey, key->heap);
6103
        }
6104
        else {
6105
        #ifdef WC_ECC_NONBLOCK_ONLY
6106
            do { /* perform blocking call to non-blocking function */
6107
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
6108
                                             &key->pubkey, key->heap);
6109
            } while (err == FP_WOULDBLOCK);
6110
        #else
6111
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6112
        #endif /* WC_ECC_NONBLOCK_ONLY */
6113
        }
6114
    #endif /* !WC_ECC_NONBLOCK */
6115
6116
        if (err == MP_OKAY) {
6117
            key->type = ECC_PRIVATEKEY;
6118
        }
6119
    }
6120
    else
6121
#endif /* !WOLFSSL_SP_NO_256 */
6122
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
6123
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
6124
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
6125
        if (err == MP_OKAY) {
6126
            key->type = ECC_PRIVATEKEY;
6127
        }
6128
    }
6129
    else
6130
#endif
6131
#ifdef WOLFSSL_SP_384
6132
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
6133
    #ifndef WC_ECC_NONBLOCK
6134
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6135
    #else
6136
        if (key->nb_ctx) {
6137
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6138
                                         &key->pubkey, key->heap);
6139
        }
6140
        else {
6141
        #ifdef WC_ECC_NONBLOCK_ONLY
6142
            do { /* perform blocking call to non-blocking function */
6143
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
6144
                                             &key->pubkey, key->heap);
6145
            } while (err == FP_WOULDBLOCK);
6146
        #else
6147
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6148
        #endif /* WC_ECC_NONBLOCK_ONLY */
6149
        }
6150
    #endif /* !WC_ECC_NONBLOCK */
6151
6152
        if (err == MP_OKAY) {
6153
            key->type = ECC_PRIVATEKEY;
6154
        }
6155
    }
6156
    else
6157
#endif /* WOLFSSL_SP_384 */
6158
#ifdef WOLFSSL_SP_521
6159
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
6160
    #ifndef WC_ECC_NONBLOCK
6161
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6162
    #else
6163
        if (key->nb_ctx) {
6164
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6165
                                         &key->pubkey, key->heap);
6166
        }
6167
        else {
6168
        #ifdef WC_ECC_NONBLOCK_ONLY
6169
            do { /* perform blocking call to non-blocking function */
6170
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
6171
                                             &key->pubkey, key->heap);
6172
            } while (err == FP_WOULDBLOCK);
6173
        #else
6174
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6175
        #endif /* WC_ECC_NONBLOCK_ONLY */
6176
        }
6177
    #endif /* !WC_ECC_NONBLOCK */
6178
6179
        if (err == MP_OKAY) {
6180
            key->type = ECC_PRIVATEKEY;
6181
        }
6182
    }
6183
    else
6184
#endif /* WOLFSSL_SP_521 */
6185
#endif /* WOLFSSL_HAVE_SP_ECC */
6186
6187
9.29k
   { /* software key gen */
6188
#if defined(WOLFSSL_SP_MATH)
6189
        err = WC_KEY_SIZE_E;
6190
#else
6191
9.29k
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6192
6193
        /* setup the key variables */
6194
9.29k
#ifndef ALT_ECC_SIZE
6195
9.29k
        err = mp_init(key->k);
6196
#else
6197
        err = 0;
6198
        key->k = (mp_int*)key->ka;
6199
        alt_fp_init(key->k);
6200
#endif
6201
6202
        /* load curve info */
6203
9.29k
        if (err == MP_OKAY) {
6204
9.29k
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6205
9.29k
            if (err != MP_OKAY) {
6206
57
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6207
57
            }
6208
9.29k
        }
6209
6210
9.29k
        if (err == MP_OKAY) {
6211
9.23k
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6212
9.23k
            if (err != MP_OKAY) {
6213
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
6214
0
            }
6215
9.23k
        }
6216
6217
        /* generate k */
6218
9.29k
        if (err == MP_OKAY) {
6219
9.23k
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
6220
9.23k
            if (err != MP_OKAY) {
6221
174
                WOLFSSL_MSG("wc_ecc_gen_k failed");
6222
174
            }
6223
9.23k
        }
6224
6225
        /* generate public key from k */
6226
9.29k
        if (err == MP_OKAY) {
6227
9.06k
            err = ecc_make_pub_ex(key, curve, NULL, rng);
6228
9.06k
            if (err != MP_OKAY) {
6229
2.14k
                WOLFSSL_MSG("ecc_make_pub_ex failed");
6230
2.14k
            }
6231
9.06k
        }
6232
6233
9.29k
        if (err == MP_OKAY
6234
        #ifdef WOLFSSL_ASYNC_CRYPT
6235
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
6236
        #endif
6237
9.29k
        ) {
6238
6.91k
            key->type = ECC_PRIVATEKEY;
6239
6.91k
        }
6240
2.38k
        else {
6241
            /* cleanup these on failure case only */
6242
2.38k
            mp_forcezero(key->k);
6243
2.38k
        }
6244
6245
        /* cleanup allocations */
6246
9.29k
        wc_ecc_curve_free(curve);
6247
9.29k
        FREE_CURVE_SPECS();
6248
9.29k
#endif /* WOLFSSL_SP_MATH */
6249
9.29k
    }
6250
6251
#ifdef HAVE_WOLF_BIGINT
6252
    if (err == MP_OKAY)
6253
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6254
    if (err == MP_OKAY)
6255
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6256
    if (err == MP_OKAY)
6257
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6258
    if (err == MP_OKAY)
6259
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6260
#endif
6261
6262
#ifdef WOLFSSL_ECC_BLIND_K
6263
    if (err == MP_OKAY)
6264
        err = ecc_blind_k_rng(key, rng);
6265
#endif
6266
6267
9.29k
#endif /* HAVE_ECC_MAKE_PUB */
6268
6269
9.29k
    return err;
6270
9.29k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6271
9.29k
}
6272
6273
6274
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6275
                        int flags)
6276
11.8k
{
6277
11.8k
    int err;
6278
6279
11.8k
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6280
6281
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6282
    !defined(WOLFSSL_KCAPI_ECC)
6283
    if (err == MP_OKAY) {
6284
        err = _ecc_validate_public_key(key, 0, 0);
6285
    }
6286
    if (err == MP_OKAY
6287
#if defined(WOLF_CRYPTO_CB)
6288
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6289
        && key->devId == INVALID_DEVID
6290
#endif
6291
        ) {
6292
        err = _ecc_pairwise_consistency_test(key, rng);
6293
    }
6294
    /* FIPS 140-3 IG 10.3.A (TE10.35.02): a key pair that fails post-
6295
     * generation validation or PCT must be rendered unusable so a caller
6296
     * that ignores the return value cannot use it. */
6297
    if (err != MP_OKAY) {
6298
        wc_ecc_free(key);
6299
    }
6300
#endif
6301
6302
11.8k
    return err;
6303
11.8k
}
6304
6305
WOLFSSL_ABI
6306
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6307
11.8k
{
6308
11.8k
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6309
11.8k
}
6310
6311
#ifdef ECC_DUMP_OID
6312
/* Optional dump of encoded OID for adding new curves */
6313
static int mOidDumpDone;
6314
static void wc_ecc_dump_oids(void)
6315
{
6316
    int x;
6317
6318
    if (mOidDumpDone) {
6319
        return;
6320
    }
6321
6322
    /* find matching OID sum (based on encoded value) */
6323
    for (x = 0; ecc_sets[x].size != 0; x++) {
6324
        int i;
6325
        byte* oid;
6326
        word32 oidSz, sum = 0;
6327
6328
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6329
6330
    #ifdef HAVE_OID_ENCODING
6331
        byte oidEnc[ECC_MAX_OID_LEN];
6332
6333
        oid = oidEnc;
6334
        oidSz = ECC_MAX_OID_LEN;
6335
6336
        printf("OID: ");
6337
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6338
            printf("%d.", ecc_sets[x].oid[i]);
6339
        }
6340
        printf("\n");
6341
6342
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6343
    #else
6344
        oid = (byte*)ecc_sets[x].oid;
6345
        oidSz = ecc_sets[x].oidSz;
6346
    #endif
6347
6348
        printf("OID Encoded: ");
6349
        for (i = 0; i < (int)oidSz; i++) {
6350
            printf("0x%02X,", oid[i]);
6351
        }
6352
        printf("\n");
6353
6354
        for (i = 0; i < (int)oidSz; i++) {
6355
            sum += oid[i];
6356
        }
6357
        printf("Sum: %u\n", sum);
6358
6359
        /* validate sum */
6360
        if (ecc_sets[x].oidSum != sum) {
6361
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6362
        }
6363
    }
6364
    mOidDumpDone = 1;
6365
}
6366
#endif /* ECC_DUMP_OID */
6367
6368
6369
WOLFSSL_ABI
6370
ecc_key* wc_ecc_key_new(void* heap)
6371
29.2k
{
6372
29.2k
    int devId = INVALID_DEVID;
6373
29.2k
    ecc_key* key;
6374
6375
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6376
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6377
    devId = WOLFSSL_CAAM_DEVID;
6378
#endif
6379
29.2k
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6380
29.2k
    if (key) {
6381
26.1k
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6382
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6383
0
            key = NULL;
6384
0
        }
6385
26.1k
    }
6386
6387
29.2k
    return key;
6388
29.2k
}
6389
6390
6391
WOLFSSL_ABI
6392
void wc_ecc_key_free(ecc_key* key)
6393
78.8k
{
6394
78.8k
    if (key) {
6395
26.1k
        void* heap = key->heap;
6396
6397
26.1k
        wc_ecc_free(key);
6398
26.1k
        ForceZero(key, sizeof(ecc_key));
6399
26.1k
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6400
26.1k
        (void)heap;
6401
26.1k
    }
6402
78.8k
}
6403
6404
6405
/**
6406
 Make a new ECC key
6407
 rng          An active RNG state
6408
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6409
 key          [out] Destination of the newly created key
6410
 return       MP_OKAY if successful,
6411
 upon error all allocated memory will be freed
6412
 */
6413
WOLFSSL_ABI
6414
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6415
0
{
6416
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6417
0
}
6418
6419
/* Setup dynamic pointers if using normal math for proper freeing */
6420
WOLFSSL_ABI
6421
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6422
40.9k
{
6423
40.9k
    int ret      = 0;
6424
6425
40.9k
    if (key == NULL) {
6426
0
        return BAD_FUNC_ARG;
6427
0
    }
6428
6429
#ifdef ECC_DUMP_OID
6430
    wc_ecc_dump_oids();
6431
#endif
6432
6433
40.9k
    XMEMSET(key, 0, sizeof(ecc_key));
6434
40.9k
    key->state = ECC_STATE_NONE;
6435
6436
40.9k
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6437
40.9k
    key->devId = devId;
6438
#else
6439
    (void)devId;
6440
#endif
6441
6442
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6443
    defined(WOLFSSL_MICROCHIP_TA100)
6444
    key->slot = ATECC_INVALID_SLOT;
6445
#ifdef WOLFSSL_MICROCHIP_TA100
6446
    /* TA100 needs pubkey initialized to populate after genkey. With
6447
     * ALT_ECC_SIZE the x/y/z pointers must first be aimed at the inline
6448
     * xyz[] storage; mp_init_multi otherwise dereferences NULL. */
6449
#ifdef ALT_ECC_SIZE
6450
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6451
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6452
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6453
    alt_fp_init(key->pubkey.x);
6454
    alt_fp_init(key->pubkey.y);
6455
    alt_fp_init(key->pubkey.z);
6456
#else
6457
    ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
6458
                        NULL, NULL, NULL);
6459
    if (ret != MP_OKAY) {
6460
        return MEMORY_E;
6461
    }
6462
#endif
6463
#endif
6464
#else
6465
#if defined(WOLFSSL_KCAPI_ECC)
6466
    key->handle = NULL;
6467
#endif
6468
#ifdef ALT_ECC_SIZE
6469
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6470
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6471
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6472
    alt_fp_init(key->pubkey.x);
6473
    alt_fp_init(key->pubkey.y);
6474
    alt_fp_init(key->pubkey.z);
6475
    key->k = (mp_int*)key->ka;
6476
    alt_fp_init(key->k);
6477
#ifdef WOLFSSL_ECC_BLIND_K
6478
    key->kb = (mp_int*)key->kba;
6479
    key->ku = (mp_int*)key->kia;
6480
    alt_fp_init(key->kb);
6481
    alt_fp_init(key->ku);
6482
#endif
6483
#else
6484
40.9k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6485
40.9k
#ifndef WOLFSSL_ECC_BLIND_K
6486
40.9k
                                                                      NULL, NULL
6487
#else
6488
                                                                key->kb, key->ku
6489
#endif
6490
40.9k
                        );
6491
40.9k
    if (ret != MP_OKAY) {
6492
0
        return MEMORY_E;
6493
0
    }
6494
40.9k
#endif /* ALT_ECC_SIZE */
6495
#ifdef WOLFSSL_ECC_BLIND_K
6496
    mp_forcezero(key->kb);
6497
#endif
6498
40.9k
#endif /* WOLFSSL_ATECC508A */
6499
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6500
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6501
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6502
     defined(WOLFSSL_NO_MALLOC)
6503
    ret = mp_init(key->sign_k);
6504
    if (ret != MP_OKAY) {
6505
        return MEMORY_E;
6506
    }
6507
#endif
6508
6509
#ifdef WOLFSSL_HEAP_TEST
6510
    (void)heap;
6511
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6512
#else
6513
40.9k
    key->heap = heap;
6514
40.9k
#endif
6515
6516
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6517
    #ifdef WOLF_CRYPTO_CB
6518
    /* prefer crypto callback */
6519
    if (key->devId != INVALID_DEVID)
6520
    #endif
6521
    {
6522
        /* handle as async */
6523
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6524
                                                        key->heap, devId);
6525
    }
6526
    if (ret != 0)
6527
        return ret;
6528
#endif
6529
6530
#if defined(WOLFSSL_DSP)
6531
    key->handle = -1;
6532
#endif
6533
6534
#ifdef WOLFSSL_SE050
6535
    key->keyId = 0;
6536
    key->keyIdSet = 0;
6537
#endif
6538
6539
#ifdef WOLFSSL_CHECK_MEM_ZERO
6540
    mp_memzero_add("ECC k", key->k);
6541
#ifdef WOLFSSL_ECC_BLIND_K
6542
    mp_memzero_add("ECC kb", key->kb);
6543
    mp_memzero_add("ECC ku", key->ku);
6544
#endif
6545
#endif
6546
6547
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6548
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6549
6550
    if (wc_InitXsecure(&(key->xSec))) {
6551
        WOLFSSL_MSG("Can't initialize Xsecure");
6552
        return WC_HW_E;
6553
    }
6554
#endif
6555
6556
40.9k
    return ret;
6557
40.9k
}
6558
6559
WOLFSSL_ABI
6560
int wc_ecc_init(ecc_key* key)
6561
1.77k
{
6562
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6563
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6564
#else
6565
1.77k
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6566
1.77k
#endif
6567
1.77k
}
6568
6569
#ifdef WOLF_PRIVATE_KEY_ID
6570
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6571
                   int devId)
6572
0
{
6573
0
    int ret = 0;
6574
#ifdef WOLFSSL_SE050
6575
    /* SE050 TLS users store a word32 at id, need to read it back */
6576
    word32 keyId = 0;
6577
#endif
6578
6579
0
    if (key == NULL)
6580
0
        ret = BAD_FUNC_ARG;
6581
0
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6582
0
        ret = BUFFER_E;
6583
0
    if (ret == 0)
6584
0
        ret = wc_ecc_init_ex(key, heap, devId);
6585
0
    if (ret == 0 && id != NULL && len != 0) {
6586
0
        XMEMCPY(key->id, id, (size_t)len);
6587
0
        key->idLen = len;
6588
    #ifdef WOLFSSL_SE050
6589
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6590
        if (len == (int)sizeof(word32)) {
6591
            keyId = readUnalignedWord32(key->id);
6592
            ret = wc_ecc_use_key_id(key, keyId, 0);
6593
        }
6594
    #endif
6595
0
    }
6596
6597
0
    return ret;
6598
0
}
6599
6600
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6601
0
{
6602
0
    int ret = 0;
6603
0
    int labelLen = 0;
6604
6605
0
    if (key == NULL || label == NULL)
6606
0
        ret = BAD_FUNC_ARG;
6607
0
    if (ret == 0) {
6608
0
        labelLen = (int)XSTRLEN(label);
6609
0
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6610
0
            ret = BUFFER_E;
6611
0
    }
6612
0
    if (ret == 0)
6613
0
        ret = wc_ecc_init_ex(key, heap, devId);
6614
0
    if (ret == 0) {
6615
0
        XMEMCPY(key->label, label, (size_t)labelLen);
6616
0
        key->labelLen = labelLen;
6617
0
    }
6618
6619
0
    return ret;
6620
0
}
6621
#endif /* WOLF_PRIVATE_KEY_ID */
6622
6623
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6624
439
{
6625
439
    if (key == NULL) {
6626
0
        return BAD_FUNC_ARG;
6627
0
    }
6628
439
    key->flags |= flags;
6629
439
    return 0;
6630
439
}
6631
6632
6633
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6634
0
{
6635
0
    int err = MP_OKAY;
6636
0
    int orderBits;
6637
0
    DECLARE_CURVE_SPECS(1);
6638
6639
0
    ALLOC_CURVE_SPECS(1, err);
6640
0
    if (err == MP_OKAY) {
6641
0
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6642
0
    }
6643
6644
0
    if (err != 0) {
6645
0
       FREE_CURVE_SPECS();
6646
0
       return err;
6647
0
    }
6648
0
    orderBits = mp_count_bits(curve->order);
6649
6650
0
    wc_ecc_curve_free(curve);
6651
0
    FREE_CURVE_SPECS();
6652
0
    return orderBits;
6653
0
}
6654
6655
#ifdef HAVE_ECC_SIGN
6656
6657
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6658
    defined(WOLFSSL_MICROCHIP_TA100) || \
6659
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6660
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6661
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6662
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6663
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6664
    ecc_key* key)
6665
{
6666
    int err;
6667
#ifdef PLUTON_CRYPTO_ECC
6668
    if (key->devId != INVALID_DEVID) /* use hardware */
6669
#endif
6670
    {
6671
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6672
        !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
6673
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6674
        word32 raw_sig_size = *outlen;
6675
        word32 msgLenInBytes = inlen;
6676
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6677
    #endif
6678
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6679
#ifdef WOLFSSL_SMALL_STACK
6680
        byte* K = NULL;
6681
        byte* incopy = NULL;
6682
#else
6683
        byte K[MAX_ECC_BYTES] = {0};
6684
        byte incopy[MAX_ECC_BYTES] = {0};
6685
#endif
6686
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6687
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6688
        word32 Ksize;
6689
#endif
6690
#endif
6691
        word32 keysize = (word32)key->dp->size;
6692
    #ifdef PLUTON_CRYPTO_ECC
6693
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6694
    #endif
6695
6696
    #ifndef WOLFSSL_KCAPI_ECC
6697
        /* Check args */
6698
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6699
            return ECC_BAD_ARG_E;
6700
        }
6701
    #endif
6702
6703
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6704
         defined(WOLFSSL_MICROCHIP_TA100)
6705
#if defined(WOLFSSL_MICROCHIP_TA100)
6706
        if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
6707
            (void)inlen;
6708
            /* Sign: Result is 32-bytes of R then 32-bytes of S */
6709
            err = atmel_ecc_sign(key->slot, in, out);
6710
        }
6711
        else {
6712
            /* Sign: Result is raw R||S */
6713
            err = atmel_ecc_sign_ex(key->slot, microchip_curve_id_for_key(key),
6714
                in, inlen, out);
6715
        }
6716
#else
6717
        (void)inlen;
6718
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6719
        err = atmel_ecc_sign(key->slot, in, out);
6720
#endif
6721
6722
        if (err != 0) {
6723
           return err;
6724
        }
6725
    #elif defined(PLUTON_CRYPTO_ECC)
6726
        {
6727
            /* if the input is larger than curve order, we must truncate */
6728
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6729
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6730
            }
6731
6732
            /* perform ECC sign */
6733
            word32 raw_sig_size = *outlen;
6734
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6735
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6736
               return BAD_COND_E;
6737
            }
6738
        }
6739
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6740
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6741
        if (err != 0) {
6742
               return WC_HW_E;
6743
        }
6744
    #elif defined(WOLFSSL_CRYPTOCELL)
6745
        /* truncate if hash is longer than key size */
6746
        if (msgLenInBytes > keysize) {
6747
            msgLenInBytes = keysize;
6748
        }
6749
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6750
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6751
            (void)cc310_hashModeECC(keysize);
6752
            /* Ignoring returned value */
6753
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6754
6755
        }
6756
6757
        /* create signature from an input buffer using a private key*/
6758
        err = CRYS_ECDSA_Sign(&wc_rndState,
6759
                               wc_rndGenVectFunc,
6760
                               &sigCtxTemp,
6761
                               &key->ctx.privKey,
6762
                               hash_mode,
6763
                               (byte*)in,
6764
                               msgLenInBytes,
6765
                               out,
6766
                               (uint32_t*)&raw_sig_size);
6767
6768
        if (err != SA_SILIB_RET_OK){
6769
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6770
            return err;
6771
        }
6772
    #elif defined(WOLFSSL_KCAPI_ECC)
6773
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6774
        if (err != MP_OKAY) {
6775
            return err;
6776
        }
6777
        (void)rng;
6778
    #elif defined(WOLFSSL_SE050)
6779
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6780
        if (err != MP_OKAY) {
6781
            return err;
6782
        }
6783
        (void)rng;
6784
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6785
6786
#ifdef WOLFSSL_SMALL_STACK
6787
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6788
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6789
        if (K == NULL || incopy == NULL) {
6790
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6791
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6792
            return MEMORY_E;
6793
        }
6794
#else
6795
        if (inlen > sizeof(incopy))
6796
            return ECC_BAD_ARG_E;
6797
#endif
6798
6799
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6800
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6801
        err = deterministic_sign_helper(in, inlen, key);
6802
        if (err)
6803
            return err;
6804
        Ksize = mp_unsigned_bin_size(key->sign_k);
6805
        if (Ksize > keysize) {
6806
            err = BUFFER_E;
6807
            goto error_out;
6808
        }
6809
        err = mp_to_unsigned_bin(key->sign_k, K);
6810
        if (err)
6811
            goto error_out;
6812
        mp_reverse(K, Ksize);
6813
#else
6814
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6815
        if (err)
6816
            goto error_out;
6817
        /* Make sure that K is max. 521 bits */
6818
        if (keysize == 66)
6819
            K[65] &= 0x1;
6820
#endif
6821
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6822
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6823
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6824
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6825
6826
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6827
6828
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6829
                                           xil_curve_type[key->dp->id],
6830
                                           XIL_CAST_U64(incopy), keysize,
6831
                                           XIL_CAST_U64(key->privKey),
6832
                                           XIL_CAST_U64(K),
6833
                                           XIL_CAST_U64(out));
6834
        if (err) {
6835
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6836
            err = WC_HW_E;
6837
        }
6838
6839
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6840
        mp_reverse(&out[0], keysize);
6841
        mp_reverse(&out[keysize], keysize);
6842
6843
error_out:
6844
        ForceZero(K, MAX_ECC_BYTES);
6845
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6846
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6847
        if (err) {
6848
            ForceZero(out, keysize * 2);
6849
            return err;
6850
        }
6851
    #endif /* HW-specific #if-#elif chain */
6852
6853
    #ifndef WOLFSSL_SE050
6854
        /* Load R and S, SE050 does this in port layer */
6855
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6856
        if (err != MP_OKAY) {
6857
            return err;
6858
        }
6859
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6860
        if (err != MP_OKAY) {
6861
            return err;
6862
        }
6863
    #endif
6864
6865
        /* Check for zeros */
6866
        if (mp_iszero(r) || mp_iszero(s)) {
6867
            return MP_ZERO_E;
6868
        }
6869
    }
6870
#ifdef PLUTON_CRYPTO_ECC
6871
    else {
6872
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6873
    }
6874
#endif
6875
    (void)rng;
6876
6877
    return err;
6878
}
6879
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6880
6881
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6882
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6883
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6884
{
6885
    int err;
6886
    mp_int *r = NULL, *s = NULL;
6887
6888
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6889
                                                                rng == NULL) {
6890
        return ECC_BAD_ARG_E;
6891
    }
6892
6893
    err = wc_ecc_alloc_async(key);
6894
    if (err != 0) {
6895
        return err;
6896
    }
6897
    r = key->r;
6898
    s = key->s;
6899
6900
    switch (key->state) {
6901
        case ECC_STATE_NONE:
6902
        case ECC_STATE_SIGN_DO:
6903
            key->state = ECC_STATE_SIGN_DO;
6904
6905
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6906
                break;
6907
            }
6908
6909
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6910
            if (err < 0) {
6911
                break;
6912
            }
6913
6914
            FALL_THROUGH;
6915
6916
        case ECC_STATE_SIGN_ENCODE:
6917
            key->state = ECC_STATE_SIGN_ENCODE;
6918
6919
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6920
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6921
                    DECLARE_CURVE_SPECS(1);
6922
                    ALLOC_CURVE_SPECS(1, err);
6923
                    if (err != MP_OKAY) {
6924
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6925
                        break;
6926
                    }
6927
6928
                    /* get curve order */
6929
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6930
                #endif
6931
6932
                #ifdef HAVE_CAVIUM_V
6933
                    /* Nitrox requires r and s in sep buffer, so split it */
6934
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6935
                #endif
6936
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6937
                    /* only do this if not software, since it overwrites result */
6938
                    wc_bigint_to_mp(&r->raw, r);
6939
                    wc_bigint_to_mp(&s->raw, s);
6940
6941
                /* if using a curve with cofactor != 1 then reduce by mod order */
6942
                #ifdef HAVE_ECC_CDH
6943
                    /* if r is not less than order than reduce */
6944
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6945
                        err = mp_mod(r, curve->order, r);
6946
                    }
6947
                    wc_ecc_curve_free(curve);
6948
                    FREE_CURVE_SPECS();
6949
                #endif
6950
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6951
            }
6952
6953
            /* encoded with DSA header */
6954
            if (err == 0) {
6955
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6956
            }
6957
6958
            /* done with R/S */
6959
            mp_clear(r);
6960
            mp_clear(s);
6961
            break;
6962
6963
        default:
6964
            err = BAD_STATE_E;
6965
            break;
6966
    }
6967
6968
    /* if async pending then return and skip done cleanup below */
6969
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6970
        key->state++;
6971
        return err;
6972
    }
6973
6974
    /* cleanup */
6975
    wc_ecc_free_async(key);
6976
    key->state = ECC_STATE_NONE;
6977
6978
    return err;
6979
}
6980
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6981
6982
/**
6983
 Sign a message digest
6984
 in        The message digest to sign
6985
 inlen     The length of the digest
6986
 out       [out] The destination for the signature
6987
 outlen    [in/out] The max size and resulting size of the signature
6988
 key       A private ECC key
6989
 return    MP_OKAY if successful
6990
 */
6991
WOLFSSL_ABI
6992
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6993
                     WC_RNG* rng, ecc_key* key)
6994
3.10k
{
6995
3.10k
    int err;
6996
3.10k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6997
3.10k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6998
3.10k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6999
3.10k
#endif
7000
#ifdef NO_ASN
7001
    word32 keySz;
7002
#endif
7003
7004
3.10k
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7005
6
        return WC_KEY_SIZE_E;
7006
6
    }
7007
7008
3.10k
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
7009
178
        return ECC_BAD_ARG_E;
7010
178
    }
7011
2.92k
    if ((inlen > WC_MAX_DIGEST_SIZE) ||
7012
2.83k
        (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7013
379
    {
7014
379
        return BAD_LENGTH_E;
7015
379
    }
7016
7017
2.54k
#ifdef WOLF_CRYPTO_CB
7018
2.54k
    #ifndef WOLF_CRYPTO_CB_FIND
7019
2.54k
    if (key->devId != INVALID_DEVID)
7020
0
    #endif
7021
0
    {
7022
0
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
7023
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7024
0
            return err;
7025
        /* fall-through when unavailable */
7026
0
    }
7027
2.54k
#endif
7028
7029
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
7030
    (void)rng;
7031
    (void)inlen;
7032
    (void)s;
7033
    (void)r;
7034
    (void)err;
7035
    return NO_VALID_DEVID;
7036
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
7037
2.54k
    if (rng == NULL) {
7038
0
        WOLFSSL_MSG("ECC sign RNG missing");
7039
0
        return ECC_BAD_ARG_E;
7040
0
    }
7041
7042
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7043
    /* handle async cases */
7044
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
7045
#else
7046
7047
2.54k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7048
2.54k
    #ifdef MP_INT_SIZE_CHECK_NULL
7049
2.54k
    if (r == NULL)
7050
2
        return MEMORY_E;
7051
2.54k
    #endif
7052
2.54k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7053
2.54k
    #ifdef MP_INT_SIZE_CHECK_NULL
7054
2.54k
    if (s == NULL) {
7055
2
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7056
2
        return MEMORY_E;
7057
2
    }
7058
2.54k
    #endif
7059
7060
2.54k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7061
2.54k
    if (err != 0) {
7062
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7063
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7064
0
        return err;
7065
0
    }
7066
2.54k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7067
2.54k
    if (err != 0) {
7068
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7069
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7070
0
        return err;
7071
0
    }
7072
7073
/* hardware crypto */
7074
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID)
7075
    /* Route by key location: SE050-resident keys sign in hardware, software
7076
     * keys (keyIdSet == 0) sign with the wolfCrypt software implementation. */
7077
    if (key->keyIdSet)
7078
        err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7079
    else
7080
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7081
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
7082
    defined(WOLFSSL_MICROCHIP_TA100) || \
7083
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
7084
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
7085
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7086
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7087
#else
7088
2.54k
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7089
2.54k
#endif
7090
2.54k
    if (err < 0) {
7091
128
        mp_clear(r);
7092
128
        mp_clear(s);
7093
128
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7094
128
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7095
128
        return err;
7096
128
    }
7097
7098
2.41k
#ifndef NO_ASN
7099
    /* encoded with DSA header */
7100
2.41k
    err = StoreECC_DSA_Sig(out, outlen, r, s);
7101
#else
7102
    /* No support for DSA ASN.1 header.
7103
     * Signature will be r+s directly. */
7104
    keySz = 0;
7105
    if (key->dp != NULL) {
7106
        keySz = (word32)key->dp->size;
7107
    }
7108
    if (keySz <= 0) {
7109
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
7110
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
7111
    }
7112
    *outlen = keySz * 2;
7113
7114
    /* Export signature into r,s */
7115
    mp_to_unsigned_bin_len(r, out, keySz);
7116
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
7117
#endif /* !NO_ASN */
7118
7119
    /* cleanup */
7120
2.41k
    mp_clear(r);
7121
2.41k
    mp_clear(s);
7122
7123
2.41k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7124
2.41k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7125
2.41k
#endif /* WOLFSSL_ASYNC_CRYPT */
7126
2.41k
    return err;
7127
2.54k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
7128
2.54k
}
7129
7130
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7131
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7132
/* returns MP_OKAY on success */
7133
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
7134
{
7135
    int err = MP_OKAY;
7136
    DECLARE_CURVE_SPECS(1);
7137
    ALLOC_CURVE_SPECS(1, err);
7138
7139
    /* get curve order */
7140
    if (err == MP_OKAY) {
7141
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7142
    }
7143
7144
    if (err == MP_OKAY) {
7145
    #ifndef WOLFSSL_NO_MALLOC
7146
        /* if key->sign_k is NULL then create a buffer for the mp_int
7147
         * if not NULL then assume the user correctly set deterministic flag and
7148
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
7149
        if (key->sign_k == NULL) {
7150
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7151
                                                            DYNAMIC_TYPE_ECC);
7152
            if (key->sign_k != NULL) {
7153
                err = mp_init(key->sign_k);
7154
                if (err != MP_OKAY) {
7155
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7156
                    key->sign_k = NULL;
7157
                }
7158
            }
7159
        }
7160
        if (key->sign_k != NULL) {
7161
            if (wc_ecc_gen_deterministic_k(in, inlen,
7162
                        key->hashType, ecc_get_k(key), key->sign_k,
7163
                        curve->order, key->heap) != 0) {
7164
                mp_free(key->sign_k);
7165
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7166
                key->sign_k = NULL;
7167
                err = ECC_PRIV_KEY_E;
7168
            }
7169
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7170
            else {
7171
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
7172
            }
7173
        #endif
7174
        }
7175
        else {
7176
            err = MEMORY_E;
7177
        }
7178
    #else
7179
        key->sign_k_set = 0;
7180
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
7181
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
7182
            err = ECC_PRIV_KEY_E;
7183
        }
7184
        else {
7185
            key->sign_k_set = 1;
7186
        }
7187
    #endif
7188
    }
7189
7190
    wc_ecc_curve_free(curve);
7191
    FREE_CURVE_SPECS();
7192
    return err;
7193
}
7194
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
7195
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
7196
7197
/* WOLFSSL_STM32_PKA routes HW ECDSA sign/verify through the STM32 PKA
7198
 * (HAL_PKA_ECDSASign / Verify). Works under both the CubeMX-HAL path
7199
 * and the bare-metal direct-register path (WOLFSSL_STM32_BARE) -- the
7200
 * bare-metal driver implements the same HAL_PKA_ECDSA* surface.
7201
 *
7202
 * The non-FIPS input-validation checks (length range, all-zero digest
7203
 * rejection) live inside the SW body of wc_ecc_sign_hash_ex below.
7204
 * Since the STM32_PKA branch returns early without reaching them,
7205
 * mirror those checks here so HW + SW paths share the same input
7206
 * contract. Without this, an all-zero digest reaches the PKA IP and
7207
 * succeeds at the HW layer -- the wolfcrypt_test ECC sweep then fails
7208
 * at the post-call assertion that expected ECC_BAD_ARG_E for a zero
7209
 * digest. */
7210
/* The STM32H563 "light" PKA can verify but not sign (per ST: H563
7211
 * verify-only, H573 full). WC_STM32_PKA_VERIFY_ONLY routes sign to the
7212
 * software path (the #elif branch below) while verify stays on the HW PKA. */
7213
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_VERIFY_ONLY)
7214
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7215
                     ecc_key* key, mp_int *r, mp_int *s)
7216
{
7217
#ifndef WC_ALLOW_ECC_ZERO_HASH
7218
    byte hashIsZero = 0;
7219
    word32 zIdx;
7220
#endif
7221
7222
    if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7223
        return ECC_BAD_ARG_E;
7224
    }
7225
    if ((inlen > WC_MAX_DIGEST_SIZE) || (inlen < WC_MIN_DIGEST_SIZE)) {
7226
        return BAD_LENGTH_E;
7227
    }
7228
#ifndef WC_ALLOW_ECC_ZERO_HASH
7229
    /* reject all 0's hash */
7230
    for (zIdx = 0; zIdx < inlen; zIdx++)
7231
        hashIsZero |= in[zIdx];
7232
    if (hashIsZero == 0)
7233
        return ECC_BAD_ARG_E;
7234
#endif
7235
7236
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7237
}
7238
7239
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7240
      !defined(WOLFSSL_MICROCHIP_TA100) && \
7241
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
7242
#ifndef WOLFSSL_SP_MATH
7243
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
7244
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
7245
                            mp_int* s)
7246
785
{
7247
785
    int err = MP_OKAY;
7248
785
    int loop_check = 0;
7249
7250
785
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
7251
7252
785
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
7253
0
        return WC_KEY_SIZE_E;
7254
0
    }
7255
7256
785
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7257
785
#ifdef MP_INT_SIZE_CHECK_NULL
7258
785
    if (b == NULL)
7259
1
        err = MEMORY_E;
7260
785
#endif
7261
7262
785
    if (err == MP_OKAY) {
7263
784
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7264
784
    }
7265
7266
785
#ifdef WOLFSSL_CUSTOM_CURVES
7267
    /* if custom curve, apply params to pubkey */
7268
785
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
7269
0
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
7270
0
    }
7271
785
#endif
7272
7273
785
    if (err == MP_OKAY) {
7274
        /* Generate blinding value - non-zero value. */
7275
895
        do {
7276
895
            if (++loop_check > 64) {
7277
1
                 err = RNG_FAILURE_E;
7278
1
                 break;
7279
1
            }
7280
7281
894
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
7282
894
        }
7283
894
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
7284
784
        loop_check = 0;
7285
784
    }
7286
#ifdef WOLFSSL_CHECK_MEM_ZERO
7287
    if (err == MP_OKAY) {
7288
        mp_memzero_add("ecc_sign_hash_sw b", b);
7289
    }
7290
#endif
7291
7292
796
    for (; err == MP_OKAY;) {
7293
793
        if (++loop_check > 64) {
7294
11
             err = RNG_FAILURE_E;
7295
11
             break;
7296
11
        }
7297
782
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7298
782
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7299
782
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7300
782
#ifndef WOLFSSL_NO_MALLOC
7301
782
        if (key->sign_k != NULL)
7302
#else
7303
        if (key->sign_k_set)
7304
#endif
7305
369
        {
7306
369
            if (loop_check > 1) {
7307
0
               err = RNG_FAILURE_E;
7308
0
               break;
7309
0
            }
7310
7311
            /* use provided sign_k */
7312
369
            err = mp_copy(key->sign_k, pubkey->k);
7313
369
            if (err != MP_OKAY) break;
7314
7315
            /* free sign_k, so only used once */
7316
369
            mp_forcezero(key->sign_k);
7317
369
#ifndef WOLFSSL_NO_MALLOC
7318
369
            mp_free(key->sign_k);
7319
369
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7320
369
            key->sign_k = NULL;
7321
#else
7322
            key->sign_k_set = 0;
7323
#endif
7324
369
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
7325
369
            loop_check = 64;
7326
369
    #endif
7327
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7328
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7329
            if (key->deterministic == 1) {
7330
                /* sign_k generated earlier in function for SP calls.
7331
                 * Only go through the loop once and fail if error */
7332
                loop_check = 64;
7333
            }
7334
    #endif
7335
7336
            /* compute public key based on provided "k" */
7337
369
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
7338
369
        }
7339
413
        else
7340
413
#endif
7341
413
        {
7342
413
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
7343
413
                    WC_ECC_FLAG_NONE);
7344
413
        }
7345
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7346
        if (err == MP_OKAY) {
7347
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7348
        }
7349
    #endif
7350
    #ifdef WOLFSSL_ASYNC_CRYPT
7351
        /* for async do blocking wait here */
7352
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7353
    #endif
7354
782
        if (err != MP_OKAY) break;
7355
7356
        /* find r = x1 mod n */
7357
775
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7358
775
        if (err != MP_OKAY) break;
7359
7360
775
        if (mp_iszero(r) == MP_NO) {
7361
775
            mp_int* kp = ecc_get_k(pubkey);
7362
775
            mp_int* ep = kp;
7363
775
            mp_int* x  = ecc_get_k(key);
7364
7365
            /* Blind after getting. */
7366
775
            ecc_blind_k(key, b);
7367
7368
            /* find s = (e + xr)/k
7369
                      = b.(e/k.b + x.r/k.b) */
7370
7371
            /* k' = k.b */
7372
775
            err = mp_mulmod(kp, b, curve->order, kp);
7373
775
            if (err != MP_OKAY) break;
7374
7375
            /* k' = 1/k.b
7376
                  = 1/k' */
7377
775
            err = mp_invmod(kp, curve->order, kp);
7378
775
            if (err != MP_OKAY) break;
7379
7380
            /* s = x.r */
7381
775
            err = mp_mulmod(x, r, curve->order, s);
7382
775
            if (err != MP_OKAY) break;
7383
7384
            /* s = x.r/k.b
7385
                 = k'.s */
7386
775
            err = mp_mulmod(kp, s, curve->order, s);
7387
775
            if (err != MP_OKAY) break;
7388
7389
            /* e' = e/k.b
7390
                  = e.k' */
7391
775
            err = mp_mulmod(kp, e, curve->order, ep);
7392
775
            if (err != MP_OKAY) break;
7393
7394
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7395
                 = e' + s */
7396
775
            err = mp_addmod_ct(ep, s, curve->order, s);
7397
775
            if (err != MP_OKAY) break;
7398
7399
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7400
                 = b.s */
7401
775
            err = mp_mulmod(s, b, curve->order, s);
7402
775
            if (err != MP_OKAY) break;
7403
7404
775
            if (mp_iszero(s) == MP_NO) {
7405
                /* sign successful */
7406
764
                break;
7407
764
            }
7408
775
         }
7409
11
     #ifndef ALT_ECC_SIZE
7410
11
         mp_clear(pubkey->pubkey.x);
7411
11
         mp_clear(pubkey->pubkey.y);
7412
11
         mp_clear(pubkey->pubkey.z);
7413
11
     #endif
7414
11
         mp_forcezero(pubkey->k);
7415
7416
11
         err = WC_CHECK_FOR_INTR_SIGNALS();
7417
11
         if (err != 0)
7418
0
             break;
7419
11
         WC_RELAX_LONG_LOOP();
7420
11
    }
7421
785
    mp_forcezero(b);
7422
785
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7423
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7424
    mp_memzero_check(b);
7425
#endif
7426
7427
785
    return err;
7428
785
}
7429
#endif
7430
7431
#ifdef WOLFSSL_HAVE_SP_ECC
7432
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7433
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7434
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7435
/* SP only resets the logical length of k, leaving its digits in the backing
7436
 * store. Clear it the way the software path does. */
7437
static void ecc_sign_k_forcezero(ecc_key* key)
7438
{
7439
#ifndef WOLFSSL_NO_MALLOC
7440
    if (key->sign_k != NULL) {
7441
        mp_forcezero(key->sign_k);
7442
        mp_free(key->sign_k);
7443
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7444
        key->sign_k = NULL;
7445
    }
7446
#else
7447
    if (key->sign_k_set) {
7448
        mp_forcezero(key->sign_k);
7449
        key->sign_k_set = 0;
7450
    }
7451
#endif
7452
}
7453
#endif
7454
7455
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7456
    ecc_key* key, mp_int *r, mp_int *s)
7457
{
7458
    if (key->idx != ECC_CUSTOM_IDX) {
7459
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7460
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7461
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7462
        mp_int* sign_k = key->sign_k;
7463
    #else
7464
        mp_int* sign_k = NULL;
7465
    #endif
7466
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7467
        /* perform blocking call to non-blocking function */
7468
        ecc_nb_ctx_t nb_ctx;
7469
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7470
    #endif
7471
    #ifndef WOLFSSL_SP_NO_256
7472
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7473
        #ifdef WC_ECC_NONBLOCK
7474
            #ifdef WC_ECC_NONBLOCK_ONLY
7475
            int err;
7476
            #endif
7477
            if (key->nb_ctx) {
7478
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7479
                    ecc_get_k(key), r, s, sign_k, key->heap);
7480
            }
7481
            #ifdef WC_ECC_NONBLOCK_ONLY
7482
            do { /* perform blocking call to non-blocking function */
7483
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7484
                    ecc_get_k(key), r, s, sign_k, key->heap);
7485
            } while (err == FP_WOULDBLOCK);
7486
            return err;
7487
            #endif
7488
        #endif /* WC_ECC_NONBLOCK */
7489
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7490
            {
7491
                int ret;
7492
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7493
                                      sign_k, key->heap);
7494
                return ret;
7495
            }
7496
        #endif
7497
        }
7498
    #endif
7499
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7500
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7501
            int ret;
7502
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7503
                                      sign_k, key->heap);
7504
            return ret;
7505
        }
7506
    #endif
7507
    #ifdef WOLFSSL_SP_384
7508
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7509
        #ifdef WC_ECC_NONBLOCK
7510
            #ifdef WC_ECC_NONBLOCK_ONLY
7511
            int err;
7512
            #endif
7513
            if (key->nb_ctx) {
7514
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7515
                    ecc_get_k(key), r, s, sign_k, key->heap);
7516
            }
7517
            #ifdef WC_ECC_NONBLOCK_ONLY
7518
            do { /* perform blocking call to non-blocking function */
7519
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7520
                    ecc_get_k(key), r, s, sign_k, key->heap);
7521
            } while (err == FP_WOULDBLOCK);
7522
            return err;
7523
            #endif
7524
        #endif /* WC_ECC_NONBLOCK */
7525
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7526
            {
7527
                int ret;
7528
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7529
                                      sign_k, key->heap);
7530
                return ret;
7531
            }
7532
        #endif
7533
        }
7534
    #endif
7535
    #ifdef WOLFSSL_SP_521
7536
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7537
        #ifdef WC_ECC_NONBLOCK
7538
            #ifdef WC_ECC_NONBLOCK_ONLY
7539
            int err;
7540
            #endif
7541
            if (key->nb_ctx) {
7542
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7543
                    ecc_get_k(key), r, s, sign_k, key->heap);
7544
            }
7545
            #ifdef WC_ECC_NONBLOCK_ONLY
7546
            do { /* perform blocking call to non-blocking function */
7547
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7548
                    ecc_get_k(key), r, s, sign_k, key->heap);
7549
            } while (err == FP_WOULDBLOCK);
7550
            return err;
7551
            #endif
7552
        #endif /* WC_ECC_NONBLOCK */
7553
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7554
            {
7555
                int ret;
7556
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7557
                                      sign_k, key->heap);
7558
                return ret;
7559
            }
7560
        #endif
7561
        }
7562
    #endif
7563
        (void)sign_k;
7564
    }
7565
7566
    /* SP doesn't support curve. */
7567
    return WC_KEY_SIZE_E;
7568
}
7569
#endif
7570
7571
/**
7572
  Sign a message digest
7573
  in        The message digest to sign
7574
  inlen     The length of the digest
7575
  key       A private ECC key
7576
  r         [out] The destination for r component of the signature
7577
  s         [out] The destination for s component of the signature
7578
  return    MP_OKAY if successful
7579
*/
7580
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7581
                     ecc_key* key, mp_int *r, mp_int *s)
7582
801
{
7583
801
   int    err = 0;
7584
801
#ifndef WC_ALLOW_ECC_ZERO_HASH
7585
801
   byte hashIsZero = 0;
7586
801
   word32 zIdx;
7587
801
#endif
7588
801
#if !defined(WOLFSSL_SP_MATH)
7589
801
   mp_int* e;
7590
801
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7591
801
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7592
801
#endif
7593
7594
801
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7595
801
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7596
801
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7597
801
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7598
801
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7599
801
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7600
#else
7601
   DECLARE_CURVE_SPECS(1);
7602
#endif
7603
801
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7604
0
       return WC_KEY_SIZE_E;
7605
0
   }
7606
801
#endif /* !WOLFSSL_SP_MATH */
7607
7608
801
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7609
0
       return ECC_BAD_ARG_E;
7610
0
   }
7611
801
   if ((inlen > WC_MAX_DIGEST_SIZE) ||
7612
801
       (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7613
0
   {
7614
0
       return BAD_LENGTH_E;
7615
0
   }
7616
7617
801
#ifndef WC_ALLOW_ECC_ZERO_HASH
7618
   /* reject all 0's hash */
7619
24.1k
   for (zIdx = 0; zIdx < inlen; zIdx++)
7620
23.3k
       hashIsZero |= in[zIdx];
7621
801
   if (hashIsZero == 0)
7622
13
       return ECC_BAD_ARG_E;
7623
788
#endif
7624
7625
   /* is this a private key? */
7626
788
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7627
0
      return ECC_BAD_ARG_E;
7628
0
   }
7629
7630
   /* is the IDX valid ?  */
7631
788
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7632
0
      return ECC_BAD_ARG_E;
7633
0
   }
7634
7635
#if defined(WOLFSSL_SP_MATH)
7636
    if (key->idx == ECC_CUSTOM_IDX || (1
7637
    #ifndef WOLFSSL_SP_NO_256
7638
         && ecc_sets[key->idx].id != ECC_SECP256R1
7639
    #endif
7640
    #ifdef WOLFSSL_SP_SM2
7641
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7642
    #endif
7643
    #ifdef WOLFSSL_SP_384
7644
         && ecc_sets[key->idx].id != ECC_SECP384R1
7645
    #endif
7646
    #ifdef WOLFSSL_SP_521
7647
         && ecc_sets[key->idx].id != ECC_SECP521R1
7648
    #endif
7649
        )) {
7650
        return WC_KEY_SIZE_E;
7651
    }
7652
#endif
7653
7654
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7655
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7656
    /* generate deterministic 'k' value to be used either with SP or normal */
7657
    if (key->deterministic == 1) {
7658
        if (deterministic_sign_helper(in, inlen, key)) {
7659
            WOLFSSL_MSG("Error generating deterministic k to sign");
7660
            return ECC_PRIV_KEY_E;
7661
        }
7662
    }
7663
#endif
7664
7665
7666
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7667
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7668
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7669
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7670
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7671
            sw->eccSign.in = in;
7672
            sw->eccSign.inSz = inlen;
7673
            sw->eccSign.rng = rng;
7674
            sw->eccSign.key = key;
7675
            sw->eccSign.r = r;
7676
            sw->eccSign.s = s;
7677
            return WC_PENDING_E;
7678
        }
7679
    }
7680
#endif
7681
7682
#if defined(WOLFSSL_HAVE_SP_ECC)
7683
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7684
   /* WC_KEY_SIZE_E only means SP left this curve to the software path below,
7685
    * which needs k and clears it itself. Every other result consumed k. */
7686
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7687
   #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7688
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7689
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7690
       #ifdef WC_ECC_NONBLOCK
7691
       /* An incomplete operation still needs k. */
7692
       if (err != FP_WOULDBLOCK)
7693
       #endif
7694
       {
7695
           ecc_sign_k_forcezero(key);
7696
       }
7697
   #endif
7698
       return err;
7699
   }
7700
#else
7701
788
   (void)inlen;
7702
788
#endif
7703
7704
788
#if !defined(WOLFSSL_SP_MATH)
7705
7706
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7707
   err = wc_ecc_alloc_mpint(key, &key->e);
7708
   if (err != 0) {
7709
      return err;
7710
   }
7711
   e = key->e;
7712
#else
7713
788
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7714
788
#ifdef MP_INT_SIZE_CHECK_NULL
7715
788
   if (e_lcl == NULL) {
7716
1
      return MEMORY_E;
7717
1
   }
7718
787
#endif
7719
787
   e = e_lcl;
7720
787
#endif
7721
7722
   /* get the hash and load it as a bignum into 'e' */
7723
   /* init the bignums */
7724
787
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7725
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7726
0
      return err;
7727
0
   }
7728
7729
   /* load curve info */
7730
787
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7731
787
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7732
787
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7733
787
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7734
787
    if (err == MP_OKAY)
7735
786
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7736
#else
7737
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7738
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7739
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7740
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7741
        if (err == MP_OKAY)
7742
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7743
    }
7744
    else
7745
    #endif
7746
    {
7747
        ALLOC_CURVE_SPECS(1, err);
7748
        if (err == MP_OKAY)
7749
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7750
    }
7751
#endif
7752
7753
   /* load digest into e */
7754
787
   if (err == MP_OKAY) {
7755
       /* we may need to truncate if hash is longer than key size */
7756
786
       word32 orderBits = (word32)mp_count_bits(curve->order);
7757
7758
       /* truncate down to byte size, may be all that's needed */
7759
786
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7760
191
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7761
786
       err = mp_read_unsigned_bin(e, in, inlen);
7762
7763
       /* may still need bit truncation too */
7764
786
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7765
156
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7766
786
   }
7767
7768
   /* make up a key and export the public copy */
7769
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7770
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7771
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7772
   #ifdef HAVE_CAVIUM_V
7773
       if (NitroxEccIsCurveSupported(key))
7774
   #endif
7775
       {
7776
           word32 keySz = key->dp->size;
7777
           mp_int* k;
7778
       #ifdef HAVE_CAVIUM_V
7779
           err = wc_ecc_alloc_mpint(key, &key->signK);
7780
           if (err != 0)
7781
              return err;
7782
           k = key->signK;
7783
       #else
7784
           mp_int k_lcl;
7785
           k = &k_lcl;
7786
       #endif
7787
7788
           err = mp_init(k);
7789
7790
            /* make sure r and s are allocated */
7791
       #ifdef HAVE_CAVIUM_V
7792
           /* Nitrox V needs single buffer for R and S */
7793
           if (err == MP_OKAY)
7794
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7795
           /* Nitrox V only needs Prime and Order */
7796
           if (err == MP_OKAY)
7797
               err = wc_ecc_curve_load(key->dp, &curve,
7798
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7799
       #else
7800
           if (err == MP_OKAY)
7801
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7802
           if (err == MP_OKAY)
7803
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7804
       #endif
7805
           if (err == MP_OKAY)
7806
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7807
7808
           /* load e and k */
7809
           if (err == MP_OKAY)
7810
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7811
           if (err == MP_OKAY)
7812
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7813
                  keySz);
7814
           if (err == MP_OKAY)
7815
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7816
           if (err == MP_OKAY)
7817
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7818
7819
       #ifdef HAVE_CAVIUM_V
7820
           if (err == MP_OKAY)
7821
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7822
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7823
                  &curve->order->raw);
7824
       #else
7825
           if (err == MP_OKAY)
7826
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7827
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7828
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7829
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7830
       #endif
7831
7832
       #ifndef HAVE_CAVIUM_V
7833
           mp_clear(e);
7834
           mp_forcezero(k);
7835
       #endif
7836
           wc_ecc_curve_free(curve);
7837
           FREE_CURVE_SPECS();
7838
7839
           return err;
7840
       }
7841
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7842
   }
7843
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7844
7845
787
   if (err == MP_OKAY) {
7846
786
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7847
7848
786
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7849
786
           err=MEMORY_E);
7850
786
       if (WC_VAR_OK(pubkey))
7851
785
       {
7852
       /* don't use async for key, since we don't support async return here */
7853
785
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7854
785
           if (err == MP_OKAY) {
7855
785
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7856
785
              wc_ecc_free(pubkey);
7857
785
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7858
785
           }
7859
785
       }
7860
786
   }
7861
7862
787
   mp_clear(e);
7863
787
   wc_ecc_curve_free(curve);
7864
787
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7865
787
   FREE_CURVE_SPECS();
7866
787
#endif /* !WOLFSSL_SP_MATH */
7867
7868
787
   return err;
7869
787
}
7870
7871
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7872
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7873
/* helper function to do HMAC operations
7874
 * returns 0 on success and updates "out" buffer
7875
 */
7876
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7877
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7878
        byte* out, enum wc_HashType hashType, void* heap)
7879
{
7880
    WC_DECLARE_VAR(hmac, Hmac, 1, heap);
7881
    int  ret, init;
7882
7883
    WC_ALLOC_VAR_EX(hmac, Hmac, 1, heap, DYNAMIC_TYPE_HMAC,
7884
                    return MEMORY_E);
7885
7886
    ret = init = wc_HmacInit(hmac, heap, INVALID_DEVID);
7887
    if (ret == 0)
7888
        ret = wc_HmacSetKey(hmac, (int)hashType, K, KSz);
7889
7890
    if (ret == 0)
7891
        ret = wc_HmacUpdate(hmac, V, VSz);
7892
7893
    if (ret == 0 && oct != NULL)
7894
        ret = wc_HmacUpdate(hmac, oct, 1);
7895
7896
    if (ret == 0)
7897
        ret = wc_HmacUpdate(hmac, x, xSz);
7898
7899
    if (ret == 0)
7900
        ret = wc_HmacUpdate(hmac, h1, h1Sz);
7901
7902
    if (ret == 0)
7903
        ret = wc_HmacFinal(hmac, out);
7904
7905
    if (init == 0)
7906
        wc_HmacFree(hmac);
7907
7908
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
7909
    return ret;
7910
}
7911
7912
7913
/* Generates a deterministic key based of the message using RFC6979
7914
 * @param  [in]   hash     Hash value to sign
7915
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7916
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7917
 *                WC_HASH_TYPE_SHA256
7918
 * @param  [in]   priv     Current ECC private key set
7919
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7920
 * @param  [in]   order    ECC order parameter to use with generation
7921
 * @return  0 on success.
7922
 */
7923
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7924
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7925
        void* heap)
7926
{
7927
    int ret = 0;
7928
#ifndef WOLFSSL_SMALL_STACK
7929
    byte h1[MAX_ECC_BYTES];
7930
    byte V[WC_MAX_DIGEST_SIZE];
7931
    byte K[WC_MAX_DIGEST_SIZE];
7932
    byte x[MAX_ECC_BYTES];
7933
    mp_int z1[1];
7934
#else
7935
    byte *h1 = NULL;
7936
    byte *V  = NULL;
7937
    byte *K  = NULL;
7938
    byte *x  = NULL;
7939
    mp_int *z1 = NULL;
7940
#endif
7941
    word32 xSz, VSz, KSz, h1len, qLen;
7942
    byte intOct;
7943
    int qbits = 0;
7944
7945
    if (hash == NULL || k == NULL || order == NULL) {
7946
        return BAD_FUNC_ARG;
7947
    }
7948
7949
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7950
        WOLFSSL_MSG("hash size was too large!");
7951
        return BAD_FUNC_ARG;
7952
    }
7953
7954
    /* if none is provided then detect has type based on hash size */
7955
    if (hashType == WC_HASH_TYPE_NONE) {
7956
        if (hashSz == 64) {
7957
            hashType = WC_HASH_TYPE_SHA512;
7958
        }
7959
        else if (hashSz == 48) {
7960
            hashType = WC_HASH_TYPE_SHA384;
7961
        }
7962
        else if (hashSz == 32) {
7963
            hashType = WC_HASH_TYPE_SHA256;
7964
        }
7965
        else {
7966
            return BAD_FUNC_ARG;
7967
        }
7968
    }
7969
7970
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
7971
        WOLFSSL_MSG("private key larger than max expected!");
7972
        return BAD_FUNC_ARG;
7973
    }
7974
7975
#ifdef WOLFSSL_SMALL_STACK
7976
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
7977
    if (h1 == NULL) {
7978
        ret = MEMORY_E;
7979
    }
7980
7981
    if (ret == 0) {
7982
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7983
        if (V == NULL)
7984
            ret = MEMORY_E;
7985
    }
7986
7987
    if (ret == 0) {
7988
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
7989
        if (K == NULL)
7990
            ret = MEMORY_E;
7991
    }
7992
7993
    if (ret == 0) {
7994
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
7995
        if (x == NULL)
7996
            ret = MEMORY_E;
7997
    }
7998
7999
    if (ret == 0) {
8000
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
8001
        if (z1 == NULL)
8002
            ret = MEMORY_E;
8003
    }
8004
8005
    /* bail out if any error has been hit at this point */
8006
    if (ret != 0) {
8007
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8008
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8009
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8010
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8011
        return ret;
8012
    }
8013
#endif
8014
8015
    VSz = KSz = hashSz;
8016
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
8017
8018
    /* 3.2 b. Set V = 0x01 0x01 ... */
8019
    XMEMSET(V, 0x01, VSz);
8020
8021
    /* 3.2 c. Set K = 0x00 0x00 ... */
8022
    XMEMSET(K, 0x00, KSz);
8023
8024
#ifdef WOLFSSL_CHECK_MEM_ZERO
8025
    wc_MemZero_Add("wc_ecc_gen_deterministic_k K", K, KSz);
8026
    wc_MemZero_Add("wc_ecc_gen_deterministic_k V", V, VSz);
8027
#endif
8028
8029
    if (ret == 0) {
8030
        ret = mp_init(z1); /* always init z1 and free z1 */
8031
    }
8032
    if (ret == 0) {
8033
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
8034
    }
8035
    if (ret == 0) {
8036
    #ifdef WOLFSSL_CHECK_MEM_ZERO
8037
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
8038
    #endif
8039
        qbits = mp_count_bits(order);
8040
        if (qbits < 0)
8041
            ret = MP_VAL;
8042
    }
8043
8044
    if (ret == 0) {
8045
         /* hash truncate if too long */
8046
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
8047
            /* calculate truncated hash size using bits rounded up byte */
8048
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
8049
        }
8050
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
8051
    }
8052
8053
    /* bits2octets on h1 */
8054
    if (ret == 0) {
8055
        XMEMSET(h1, 0, MAX_ECC_BYTES);
8056
8057
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8058
        /* mod reduce by order using conditional subtract
8059
         * RFC6979 lists a variant that uses the hash directly instead of
8060
         * doing bits2octets(H(m)), when variant macro is used avoid this
8061
         * bits2octets operation */
8062
        if (mp_cmp(z1, order) == MP_GT) {
8063
            int z1Sz;
8064
8065
            mp_sub(z1, order, z1);
8066
            z1Sz = mp_unsigned_bin_size(z1);
8067
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
8068
                ret = BUFFER_E;
8069
            }
8070
            else {
8071
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8072
            }
8073
        }
8074
        else
8075
    #endif
8076
        {
8077
            /* use original hash and keep leading 0's */
8078
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8079
        }
8080
    }
8081
    mp_free(z1);
8082
8083
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
8084
    if (ret == 0) {
8085
        intOct = 0x00;
8086
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
8087
                hashType, heap);
8088
    }
8089
8090
    /* 3.2 step e. V = HMAC_K(V) */
8091
    if (ret == 0) {
8092
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8093
                heap);
8094
    }
8095
8096
8097
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
8098
    if (ret == 0) {
8099
        intOct = 0x01;
8100
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
8101
                heap);
8102
    }
8103
8104
    /* 3.2 step g. V = HMAC_K(V) */
8105
    if (ret == 0) {
8106
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8107
                heap);
8108
    }
8109
8110
    /* 3.2 step h. loop through the next steps until a valid value is found */
8111
    if (ret == 0 ) {
8112
        int err;
8113
8114
        intOct = 0x00;
8115
        do {
8116
            xSz = 0; /* used as tLen */
8117
            err = 0; /* start as good until generated k is tested */
8118
8119
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
8120
            while (xSz < qLen) {
8121
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8122
                        hashType, heap);
8123
                if (ret == 0) {
8124
                    int sz;
8125
8126
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
8127
                    XMEMCPY(x + xSz, V, (size_t)sz);
8128
                    xSz += (word32)sz;
8129
                }
8130
                else {
8131
                    break; /* error case */
8132
                }
8133
            }
8134
8135
            if (ret == 0) {
8136
                mp_clear(k); /* 3.2 step h.1 clear T */
8137
                ret = mp_read_unsigned_bin(k, x, xSz);
8138
            }
8139
8140
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
8141
                /* handle odd case where shift of 'k' is needed with RFC 6979
8142
                 *  k = bits2int(T) in section 3.2 h.3 */
8143
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
8144
            }
8145
8146
            /* 3.2 step h.3 the key should be smaller than the order of base
8147
             * point */
8148
            if (ret == 0) {
8149
                if (mp_cmp(k, order) != MP_LT) {
8150
                    err = MP_VAL;
8151
                } else if (mp_iszero(k) == MP_YES) {
8152
                    /* no 0 key's */
8153
                    err = MP_ZERO_E;
8154
                }
8155
            }
8156
8157
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
8158
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
8159
            if (ret == 0 && err != 0) {
8160
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
8161
                    hashType, heap);
8162
                if (ret == 0) {
8163
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8164
                    hashType, heap);
8165
                }
8166
            }
8167
        } while (ret == 0 && err != 0);
8168
    }
8169
8170
    ForceZero(x, MAX_ECC_BYTES);
8171
    ForceZero(K, WC_MAX_DIGEST_SIZE);
8172
    ForceZero(V, WC_MAX_DIGEST_SIZE);
8173
#ifdef WOLFSSL_SMALL_STACK
8174
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
8175
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8176
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8177
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8178
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8179
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8180
    wc_MemZero_Check(x, MAX_ECC_BYTES);
8181
    wc_MemZero_Check(K, WC_MAX_DIGEST_SIZE);
8182
    wc_MemZero_Check(V, WC_MAX_DIGEST_SIZE);
8183
#endif
8184
8185
    return ret;
8186
}
8187
8188
8189
/* Sets the deterministic flag for 'k' generation with sign.
8190
 * returns 0 on success
8191
 */
8192
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
8193
                                enum wc_HashType hashType)
8194
{
8195
    if (key == NULL) {
8196
        return BAD_FUNC_ARG;
8197
    }
8198
8199
    key->deterministic = flag ? 1 : 0;
8200
    key->hashType = hashType;
8201
    return 0;
8202
}
8203
8204
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
8205
{
8206
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
8207
}
8208
8209
#endif /* end sign_ex and deterministic sign */
8210
8211
8212
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
8213
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
8214
512
{
8215
512
    int ret = MP_OKAY;
8216
512
    DECLARE_CURVE_SPECS(1);
8217
8218
512
    if (k == NULL || klen == 0 || key == NULL) {
8219
0
        return BAD_FUNC_ARG;
8220
0
    }
8221
8222
512
    ALLOC_CURVE_SPECS(1, ret);
8223
512
    if (ret == MP_OKAY) {
8224
503
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8225
503
    }
8226
8227
512
    if (ret != 0) {
8228
9
        FREE_CURVE_SPECS();
8229
9
        return ret;
8230
9
    }
8231
8232
503
#ifndef WOLFSSL_NO_MALLOC
8233
503
    if (key->sign_k == NULL) {
8234
503
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
8235
503
                                                            DYNAMIC_TYPE_ECC);
8236
503
        if (key->sign_k) {
8237
494
            ret = mp_init(key->sign_k);
8238
494
        }
8239
9
        else {
8240
9
            ret = MEMORY_E;
8241
9
        }
8242
503
    }
8243
503
#endif
8244
8245
503
    if (ret == 0) {
8246
494
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
8247
494
    }
8248
503
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
8249
26
        ret = MP_VAL;
8250
26
    }
8251
#ifdef WOLFSSL_NO_MALLOC
8252
    if (ret == 0) {
8253
        key->sign_k_set = 1;
8254
    }
8255
#endif
8256
8257
503
    wc_ecc_curve_free(curve);
8258
503
    FREE_CURVE_SPECS();
8259
503
    return ret;
8260
512
}
8261
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
8262
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
8263
8264
#if defined(WOLFSSL_DHUK) && defined(WC_STM32_HAS_DHUK) && \
8265
    (defined(WOLFSSL_STM32_BARE) || defined(WOLFSSL_STM32_CUBEMX))
8266
/* Import a hardware-wrapped ECC private scalar + its derivation seed onto the
8267
 * ecc_key for the DHUK crypto-callback sign path. The scalar is AES-encrypted
8268
 * (offline or on-chip) with the device key that the SAES derives from the seed;
8269
 * at sign time it is decrypted into a short-lived buffer. The devId is NOT set
8270
 * here -- enable the device by setting devId at init
8271
 * (wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID)). See ecc.h for the contract. */
8272
int wc_ecc_import_wrapped_private(ecc_key* key, const byte* seed, word32 seedSz,
8273
                                  const byte* wrapped, word32 wrappedLen,
8274
                                  word32 plainLen)
8275
{
8276
    if (key == NULL || seed == NULL || wrapped == NULL) {
8277
        return BAD_FUNC_ARG;
8278
    }
8279
    /* Seed is the 256-bit DHUK derivation secret. */
8280
    if (seedSz != sizeof(key->dhuk_seed)) {
8281
        return BAD_FUNC_ARG;
8282
    }
8283
    /* Wrapped scalar blob must be a non-zero multiple of one AES block. */
8284
    if (wrappedLen == 0u || (wrappedLen % 16u) != 0u) {
8285
        return BAD_FUNC_ARG;
8286
    }
8287
    if (wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
8288
        return BAD_FUNC_ARG;
8289
    }
8290
    /* Plain length must fit inside the wrapped blob and be non-zero. */
8291
    if (plainLen == 0u || plainLen > wrappedLen) {
8292
        return BAD_FUNC_ARG;
8293
    }
8294
    /* Wrapped blob must be no larger than the plaintext padded up to a full
8295
     * AES block; a larger blob is malformed and would overrun the fixed-size
8296
     * unwrap buffer used during signing. */
8297
    if (wrappedLen > ((plainLen + 15u) & ~15u)) {
8298
        return BAD_FUNC_ARG;
8299
    }
8300
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
8301
    XMEMCPY(key->dhuk_seed, seed, seedSz);
8302
    key->dhuk_wrapped_priv_len = wrappedLen;
8303
    key->dhuk_plain_priv_len   = plainLen;
8304
    key->dhuk_seed_sz          = seedSz;
8305
#ifdef WOLFSSL_STM32_CCB
8306
    /* This is a DHUK seed-wrapped (non-CCB) scalar; clear any CCB blob
8307
     * routing left from a prior import so signing uses the DHUK path. */
8308
    key->dhuk_is_ccb = 0;
8309
#endif
8310
    return 0;
8311
}
8312
#endif /* WOLFSSL_DHUK && WC_STM32_HAS_DHUK && (BARE || CUBEMX) */
8313
8314
/* Guard must match the ecc.h prototype and the ccb_ / dhuk_ ecc_key struct
8315
 * members (both WOLFSSL_DHUK && WOLFSSL_STM32_CCB) -- the implementation must
8316
 * not be broader than the members it dereferences. */
8317
#if defined(WOLFSSL_DHUK) && defined(WOLFSSL_STM32_CCB)
8318
/* Load a previously provisioned device-protected ECDSA blob (wrapped scalar +
8319
 * AES-GCM iv/tag) and its public key onto the ecc_key. Sets the curve so the
8320
 * sign path can derive the parameters, and marks the key for the device
8321
 * crypto-callback. The caller enables the device with
8322
 * wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID). Generic name -- the wrapping is
8323
 * the STM32 CCB, but the surface is not CCB-specific. */
8324
int wc_ecc_import_wrapped_private_ex(ecc_key* key, int curve_id,
8325
                           const byte* wrapped, word32 wrappedLen,
8326
                           const byte* iv, word32 ivLen,
8327
                           const byte* tag, word32 tagLen,
8328
                           const byte* pub, word32 pubLen)
8329
{
8330
    int modSz;
8331
    int ret;
8332
8333
    if (key == NULL || wrapped == NULL || iv == NULL || tag == NULL ||
8334
        pub == NULL) {
8335
        return BAD_FUNC_ARG;
8336
    }
8337
    /* Fixed 16-byte AES-GCM iv/tag -- validate explicitly (no over-read). */
8338
    if (ivLen != sizeof(key->ccb_iv) || tagLen != sizeof(key->ccb_tag)) {
8339
        return BAD_FUNC_ARG;
8340
    }
8341
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8342
    if (modSz <= 0) {
8343
        return BAD_FUNC_ARG;
8344
    }
8345
    if (wrappedLen == 0u || wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
8346
        return BAD_FUNC_ARG;
8347
    }
8348
    if (pubLen != (word32)(2 * modSz)) {
8349
        return BAD_FUNC_ARG;
8350
    }
8351
    /* Import public key (qx||qy) + set the curve (key->dp). */
8352
    ret = wc_ecc_import_unsigned(key, pub, pub + modSz, NULL, curve_id);
8353
    if (ret != 0) {
8354
        return ret;
8355
    }
8356
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
8357
    key->dhuk_wrapped_priv_len = wrappedLen;
8358
    XMEMCPY(key->ccb_iv,  iv,  sizeof(key->ccb_iv));
8359
    XMEMCPY(key->ccb_tag, tag, sizeof(key->ccb_tag));
8360
    key->dhuk_is_ccb = 1;
8361
    /* Clear any DHUK seed-import state left from a prior import; the CCB
8362
     * path keys off the wrapped blob + iv/tag, not the seed. */
8363
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8364
    key->dhuk_seed_sz        = 0;
8365
    key->dhuk_plain_priv_len = 0;
8366
    return 0;
8367
}
8368
8369
/* Crypto-callback keygen handler (WC_PK_TYPE_EC_KEYGEN). Provisions a fresh
8370
 * device-protected key: generate a scalar, have the CCB wrap it into a
8371
 * device-bound blob and derive its public key, and store both on the ecc_key
8372
 * (the scalar is zeroized and never leaves this call / the hardware). The
8373
 * scalar is generated in software with the supplied rng on a throwaway key with
8374
 * no devId (so no callback recursion). Returns CRYPTOCB_UNAVAILABLE for curves
8375
 * the CCB cannot wrap so keygen falls back to software. Not a public entry
8376
 * point -- reached via wc_ecc_make_key() on a WC_DHUK_DEVID key. */
8377
int wc_ecc_dev_make_key(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
8378
{
8379
#ifdef WOLFSSL_SMALL_STACK
8380
    ecc_key* tmp = NULL;             /* ecc_key is ~1-2KB -- heap it on the
8381
                                      * small-stack embedded targets this port
8382
                                      * runs on (repo convention). */
8383
#else
8384
    ecc_key  tmp[1];
8385
#endif
8386
#ifdef WOLFSSL_SMALL_STACK
8387
    /* d || pub || wrapped in one heap scratch buffer (~326 B) -- keep the
8388
     * fixed byte buffers off the stack too, like tmp above. */
8389
    byte*   scratch = NULL;
8390
    byte*   d;
8391
    byte*   pub;       /* qx || qy, contiguous */
8392
    byte*   wrapped;
8393
#else
8394
    byte    d[MAX_ECC_BYTES];
8395
    byte    pub[2 * MAX_ECC_BYTES];   /* qx || qy, contiguous */
8396
    byte    wrapped[96];
8397
#endif
8398
    byte    iv[16];
8399
    byte    tag[16];
8400
    word32  dLen;
8401
    word32  wrappedSz = 0;
8402
    int     modSz;
8403
    int     ret;
8404
    int     tmpInit = 0;
8405
8406
    (void)keysize;
8407
    if (rng == NULL || key == NULL) {
8408
        return BAD_FUNC_ARG;
8409
    }
8410
    /* wc_ecc_set_curve() ran before the callback, so key->dp is resolved even
8411
     * when curve_id came in as the default. */
8412
    if (curve_id <= 0 && key->dp != NULL) {
8413
        curve_id = key->dp->id;
8414
    }
8415
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8416
    if (modSz <= 0 || (word32)modSz > MAX_ECC_BYTES) {
8417
        return CRYPTOCB_UNAVAILABLE;   /* unsupported -> software keygen */
8418
    }
8419
8420
#ifdef WOLFSSL_SMALL_STACK
8421
    tmp = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
8422
    if (tmp == NULL) {
8423
        return MEMORY_E;
8424
    }
8425
    scratch = (byte*)XMALLOC((3 * MAX_ECC_BYTES) + 96, key->heap,
8426
                             DYNAMIC_TYPE_TMP_BUFFER);
8427
    if (scratch == NULL) {
8428
        XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8429
        return MEMORY_E;
8430
    }
8431
    d       = scratch;
8432
    pub     = scratch + MAX_ECC_BYTES;
8433
    wrapped = scratch + (3 * MAX_ECC_BYTES);
8434
#endif
8435
8436
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8437
    /* Register the stack private-key buffer before keygen/export so any exit
8438
     * before the ForceZero is checked. XMEMSET makes it defined. */
8439
    XMEMSET(d, 0, MAX_ECC_BYTES);
8440
    wc_MemZero_Add("wc_ecc_dev_make_key d", d, MAX_ECC_BYTES);
8441
#endif
8442
    ret = wc_ecc_init_ex(tmp, key->heap, INVALID_DEVID);
8443
    if (ret == 0) {
8444
        tmpInit = 1;
8445
        ret = wc_ecc_make_key_ex(rng, modSz, tmp, curve_id);
8446
    }
8447
    if (ret == 0) {
8448
        dLen = (word32)modSz;
8449
        ret = wc_ecc_export_private_only(tmp, d, &dLen);
8450
    }
8451
    if (ret == 0) {
8452
        ret = wc_Stm32_Ccb_EccMakeBlob(curve_id, d, dLen, iv, tag, wrapped,
8453
                                       &wrappedSz, pub, pub + modSz);
8454
        if (ret != 0) {
8455
            ret = CRYPTOCB_UNAVAILABLE;   /* curve not CCB-wrappable -> SW */
8456
        }
8457
    }
8458
    if (ret == 0) {
8459
        ret = wc_ecc_import_wrapped_private_ex(key, curve_id, wrapped, wrappedSz,
8460
                                     iv, (word32)sizeof(iv), tag,
8461
                                     (word32)sizeof(tag), pub,
8462
                                     (word32)(2 * modSz));
8463
    }
8464
8465
    ForceZero(d, MAX_ECC_BYTES);
8466
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8467
    wc_MemZero_Check(d, MAX_ECC_BYTES);
8468
#endif
8469
    if (tmpInit) {
8470
        wc_ecc_free(tmp);
8471
    }
8472
#ifdef WOLFSSL_SMALL_STACK
8473
    XFREE(scratch, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8474
    XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8475
#endif
8476
    return ret;
8477
}
8478
#endif /* WOLFSSL_DHUK && WOLFSSL_STM32_CCB */
8479
8480
#endif /* !HAVE_ECC_SIGN */
8481
8482
#ifdef WOLFSSL_CUSTOM_CURVES
8483
void wc_ecc_free_curve(ecc_set_type* curve, void* heap)
8484
706
{
8485
706
#ifndef WOLFSSL_ECC_CURVE_STATIC
8486
706
    if (curve->prime != NULL)
8487
507
        XFREE((void*)(wc_ptr_t)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
8488
706
    if (curve->Af != NULL)
8489
474
        XFREE((void*)(wc_ptr_t)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
8490
706
    if (curve->Bf != NULL)
8491
469
        XFREE((void*)(wc_ptr_t)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
8492
706
    if (curve->order != NULL)
8493
442
        XFREE((void*)(wc_ptr_t)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
8494
706
    if (curve->Gx != NULL)
8495
448
        XFREE((void*)(wc_ptr_t)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
8496
706
    if (curve->Gy != NULL)
8497
448
        XFREE((void*)(wc_ptr_t)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
8498
706
#endif
8499
8500
706
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
8501
8502
706
    (void)heap;
8503
706
}
8504
#endif /* WOLFSSL_CUSTOM_CURVES */
8505
8506
/**
8507
  Free an ECC key from memory
8508
  key   The key you wish to free
8509
*/
8510
WOLFSSL_ABI
8511
int wc_ecc_free(ecc_key* key)
8512
17.1k
{
8513
17.1k
    if (key == NULL) {
8514
0
        return 0;
8515
0
    }
8516
8517
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
8518
    if (key->devId != INVALID_DEVID) {
8519
        /* Best-effort HSM resource release; errors are intentionally discarded
8520
         * so that software cleanup always runs and wc_ecc_free() retains its
8521
         * ABI guarantee of returning 0 on success. */
8522
        (void)wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
8523
                         WC_PK_TYPE_EC_KEYGEN, 0, key);
8524
        /* always continue to software cleanup */
8525
    }
8526
#endif
8527
8528
17.1k
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
8529
17.1k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
8530
17.1k
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8531
17.1k
#ifndef WOLFSSL_NO_MALLOC
8532
17.1k
    if (key->sign_k != NULL)
8533
180
#endif
8534
180
    {
8535
180
        mp_forcezero(key->sign_k);
8536
180
        mp_free(key->sign_k);
8537
180
#ifndef WOLFSSL_NO_MALLOC
8538
180
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
8539
180
        key->sign_k = NULL;
8540
180
#endif
8541
180
    }
8542
17.1k
#endif
8543
8544
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8545
    #ifdef WC_ASYNC_ENABLE_ECC
8546
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
8547
    #endif
8548
    wc_ecc_free_async(key);
8549
#endif
8550
8551
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
8552
    /* free secure memory */
8553
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
8554
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
8555
       caamFreePart(key->partNum);
8556
    }
8557
#endif
8558
8559
#ifdef WOLFSSL_SE050
8560
#ifdef WOLFSSL_SE050_AUTO_ERASE
8561
    wc_se050_erase_object(key->keyId);
8562
#endif
8563
    se050_ecc_free_key(key);
8564
#endif
8565
8566
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
8567
    defined(WOLFSSL_MICROCHIP_TA100)
8568
    atmel_ecc_free(key->slot);
8569
    key->slot = ATECC_INVALID_SLOT;
8570
#endif /* WOLFSSL_ATECC508A */
8571
8572
#ifdef WOLFSSL_KCAPI_ECC
8573
    KcapiEcc_Free(key);
8574
#endif
8575
8576
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
8577
    key->privKey = NULL;
8578
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
8579
    ForceZero(&key->xSec, sizeof(key->xSec));
8580
#endif
8581
8582
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
8583
    wc_MAXQ10XX_EccFree(key);
8584
#endif
8585
8586
#ifdef WOLFSSL_DHUK
8587
    /* Scrub the DHUK derivation seed and wrapped scalar (both secret). */
8588
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8589
    ForceZero(key->dhuk_wrapped_priv, sizeof(key->dhuk_wrapped_priv));
8590
    key->dhuk_seed_sz = 0;
8591
    key->dhuk_wrapped_priv_len = 0;
8592
    key->dhuk_plain_priv_len = 0;
8593
#endif
8594
8595
17.1k
    mp_clear(key->pubkey.x);
8596
17.1k
    mp_clear(key->pubkey.y);
8597
17.1k
    mp_clear(key->pubkey.z);
8598
8599
#ifdef ALT_ECC_SIZE
8600
    if (key->k)
8601
#endif
8602
17.1k
        mp_forcezero(key->k);
8603
#ifdef WOLFSSL_ECC_BLIND_K
8604
#ifdef ALT_ECC_SIZE
8605
    if (key->kb)
8606
#endif
8607
        mp_forcezero(key->kb);
8608
#ifdef ALT_ECC_SIZE
8609
    if (key->ku)
8610
#endif
8611
        mp_forcezero(key->ku);
8612
#endif
8613
8614
17.1k
#ifdef WOLFSSL_CUSTOM_CURVES
8615
17.1k
    if (key->deallocSet && key->dp != NULL) {
8616
0
        wc_ecc_free_curve((ecc_set_type *)(wc_ptr_t)key->dp, key->heap);
8617
0
        key->dp = NULL;
8618
0
    }
8619
17.1k
#endif
8620
8621
#ifdef WOLFSSL_CHECK_MEM_ZERO
8622
    wc_MemZero_Check(key, sizeof(ecc_key));
8623
#endif
8624
8625
17.1k
    return 0;
8626
17.1k
}
8627
8628
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
8629
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
8630
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
8631
      defined(WOLFSSL_IMXRT1170_CAAM))
8632
/* Handles add failure cases:
8633
 *
8634
 * Before add:
8635
 *   Case 1: A is infinity
8636
 *        -> Copy B into result.
8637
 *   Case 2: B is infinity
8638
 *        -> Copy A into result.
8639
 *   Case 3: x and z are the same in A and B (same x value in affine)
8640
 *     Case 3a: y values the same - same point
8641
 *           -> Double instead of add.
8642
 *     Case 3b: y values different - negative of the other when points on curve
8643
 *           -> Need to set result to infinity.
8644
 *
8645
 * After add:
8646
 *   Case 1: A and B are the same point (maybe different z)
8647
 *           (Result was: x == y == z == 0)
8648
 *        -> Need to double instead.
8649
 *
8650
 *   Case 2: A + B = <infinity> = 0.
8651
 *           (Result was: z == 0, x and/or y not 0)
8652
 *        -> Need to set result to infinity.
8653
 */
8654
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8655
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8656
4.08M
{
8657
4.08M
    int err;
8658
8659
4.08M
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8660
        /* A is infinity. */
8661
132k
        err = wc_ecc_copy_point(B, R);
8662
132k
    }
8663
3.95M
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8664
        /* B is infinity. */
8665
11.7k
        err = wc_ecc_copy_point(A, R);
8666
11.7k
    }
8667
3.94M
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8668
        /* x ordinattes the same. */
8669
847
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8670
            /* A = B */
8671
210
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8672
210
        }
8673
637
        else {
8674
            /* A = -B */
8675
637
            err = mp_set(R->x, 0);
8676
637
            if (err == MP_OKAY)
8677
637
                err = mp_set(R->y, 0);
8678
637
            if (err == MP_OKAY)
8679
637
                err = mp_set(R->z, 1);
8680
637
            if ((err == MP_OKAY) && (infinity != NULL))
8681
163
                *infinity = 1;
8682
637
        }
8683
847
    }
8684
3.94M
    else {
8685
3.94M
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8686
3.94M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8687
            /* When all zero then should have done a double */
8688
10.2k
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8689
77
                if (mp_iszero(B->z)) {
8690
0
                    err = wc_ecc_copy_point(B, R);
8691
0
                    if (err == MP_OKAY) {
8692
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8693
0
                    }
8694
0
                    if (err == MP_OKAY) {
8695
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8696
0
                    }
8697
0
                }
8698
77
                else {
8699
77
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8700
77
                }
8701
77
            }
8702
            /* When only Z zero then result is infinity */
8703
10.1k
            else {
8704
10.1k
                err = mp_set(R->x, 0);
8705
10.1k
                if (err == MP_OKAY)
8706
10.1k
                    err = mp_set(R->y, 0);
8707
10.1k
                if (err == MP_OKAY)
8708
10.1k
                    err = mp_set(R->z, 1);
8709
10.1k
                if ((err == MP_OKAY) && (infinity != NULL))
8710
9.17k
                    *infinity = 1;
8711
10.1k
            }
8712
10.2k
        }
8713
3.94M
    }
8714
8715
4.08M
    return err;
8716
4.08M
}
8717
8718
/* Handles when P is the infinity point.
8719
 *
8720
 * Double infinity -> infinity.
8721
 * Otherwise do normal double - which can't lead to infinity as odd order.
8722
 */
8723
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8724
                                  mp_int* modulus, mp_digit mp)
8725
4.24M
{
8726
4.24M
    int err;
8727
8728
4.24M
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8729
        /* P is infinity. */
8730
156k
        err = wc_ecc_copy_point(P, R);
8731
156k
    }
8732
4.08M
    else {
8733
4.08M
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8734
4.08M
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8735
25.2k
           err = mp_set(R->x, 0);
8736
25.2k
           if (err == MP_OKAY)
8737
25.2k
               err = mp_set(R->y, 0);
8738
25.2k
           if (err == MP_OKAY)
8739
25.2k
               err = mp_set(R->z, 1);
8740
25.2k
        }
8741
4.08M
    }
8742
8743
4.24M
    return err;
8744
4.24M
}
8745
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8746
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8747
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8748
            (WOLFSSL_IMXRT1170_CAAM))
8749
        */
8750
8751
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8752
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
8753
    !defined(WOLFSSL_CRYPTOCELL) && \
8754
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8755
#ifdef ECC_SHAMIR
8756
8757
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8758
    ecc_point* Bm, mp_int* modulus, void* heap)
8759
1.33k
{
8760
1.33k
    int err = MP_OKAY;
8761
8762
1.33k
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8763
8764
1.33k
    if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
8765
0
        return WC_KEY_SIZE_E;
8766
0
    }
8767
8768
1.33k
    (void)heap;
8769
8770
1.33k
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8771
1.33k
#ifdef MP_INT_SIZE_CHECK_NULL
8772
1.33k
    if (mu == NULL)
8773
1
       err = MEMORY_E;
8774
1.33k
#endif
8775
1.33k
    if (err == MP_OKAY) {
8776
1.33k
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8777
1.33k
    }
8778
1.33k
    if (err == MP_OKAY) {
8779
1.33k
        err = mp_montgomery_calc_normalization(mu, modulus);
8780
8781
1.33k
        if (err == MP_OKAY) {
8782
            /* copy ones ... */
8783
1.33k
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8784
1.33k
        }
8785
8786
1.33k
        if (err == MP_OKAY)
8787
1.32k
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8788
1.33k
        if (err == MP_OKAY)
8789
1.32k
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8790
8791
1.33k
        if (err == MP_OKAY)
8792
1.32k
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8793
1.33k
        if (err == MP_OKAY)
8794
1.32k
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8795
1.33k
        if (err == MP_OKAY)
8796
1.32k
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8797
8798
        /* done with mu */
8799
1.33k
        mp_clear(mu);
8800
1.33k
    }
8801
8802
1.33k
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8803
8804
1.33k
    return err;
8805
1.33k
}
8806
8807
/** Computes kA*A + kB*B = C using Shamir's Trick
8808
  A        First point to multiply
8809
  kA       What to multiple A by
8810
  B        Second point to multiply
8811
  kB       What to multiple B by
8812
  C        [out] Destination point (can overlap with A or B)
8813
  a        ECC curve parameter a
8814
  modulus  Modulus for curve
8815
  return MP_OKAY on success
8816
*/
8817
#ifdef FP_ECC
8818
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8819
                             ecc_point* B, mp_int* kB,
8820
                             ecc_point* C, mp_int* a, mp_int* modulus,
8821
                             void* heap)
8822
#else
8823
int ecc_mul2add(ecc_point* A, mp_int* kA,
8824
                    ecc_point* B, mp_int* kB,
8825
                    ecc_point* C, mp_int* a, mp_int* modulus,
8826
                    void* heap)
8827
#endif
8828
1.72k
{
8829
#ifdef WOLFSSL_SMALL_STACK_CACHE
8830
  ecc_key        *key = NULL;
8831
#endif
8832
1.72k
#ifdef WOLFSSL_SMALL_STACK
8833
1.72k
  ecc_point**    precomp = NULL;
8834
#else
8835
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8836
  #ifdef WOLFSSL_NO_MALLOC
8837
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8838
  #endif
8839
#endif
8840
1.72k
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8841
#ifdef WOLFSSL_NO_MALLOC
8842
  unsigned char tA[ECC_BUFSIZE];
8843
  unsigned char tB[ECC_BUFSIZE];
8844
#else
8845
1.72k
  unsigned char* tA = NULL;
8846
1.72k
  unsigned char* tB = NULL;
8847
1.72k
#endif
8848
1.72k
  int            err = MP_OKAY, first, x, y;
8849
1.72k
  mp_digit       mp = 0;
8850
8851
  /* argchks */
8852
1.72k
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8853
1.72k
                                                         modulus == NULL) {
8854
0
     return ECC_BAD_ARG_E;
8855
0
  }
8856
8857
1.72k
#ifndef WOLFSSL_NO_MALLOC
8858
  /* allocate memory */
8859
1.72k
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8860
1.72k
  if (tA == NULL) {
8861
1
     return MP_MEM;
8862
1
  }
8863
1.72k
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8864
1.72k
  if (tB == NULL) {
8865
1
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8866
1
     return MP_MEM;
8867
1
  }
8868
1.71k
#endif
8869
8870
#ifdef WOLFSSL_SMALL_STACK_CACHE
8871
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8872
  if (key == NULL) {
8873
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8874
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8875
     return MP_MEM;
8876
  }
8877
#endif
8878
1.71k
#ifdef WOLFSSL_SMALL_STACK
8879
1.71k
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8880
1.71k
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8881
1.71k
  if (precomp == NULL) {
8882
1
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8883
1
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8884
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8885
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8886
  #endif
8887
1
     return MP_MEM;
8888
1
  }
8889
1.71k
#endif
8890
#ifdef WOLFSSL_SMALL_STACK_CACHE
8891
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8892
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8893
#ifdef ALT_ECC_SIZE
8894
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8895
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8896
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8897
#endif
8898
8899
  if (key->t1 == NULL || key->t2 == NULL
8900
#ifdef ALT_ECC_SIZE
8901
     || key->x == NULL || key->y == NULL || key->z == NULL
8902
#endif
8903
  ) {
8904
#ifdef ALT_ECC_SIZE
8905
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8906
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8907
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8908
#endif
8909
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8910
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8911
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8912
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8913
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8914
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8915
      return MEMORY_E;
8916
  }
8917
  C->key = key;
8918
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8919
8920
  /* init variables */
8921
1.71k
  XMEMSET(tA, 0, ECC_BUFSIZE);
8922
1.71k
  XMEMSET(tB, 0, ECC_BUFSIZE);
8923
#ifndef WOLFSSL_SMALL_STACK
8924
  XMEMSET(precomp, 0, sizeof(precomp));
8925
#else
8926
1.71k
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8927
1.71k
#endif
8928
#ifdef WOLFSSL_CHECK_MEM_ZERO
8929
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8930
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8931
#endif
8932
8933
  /* get sizes */
8934
1.71k
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8935
1.71k
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8936
1.71k
  len  = MAX(lenA, lenB);
8937
8938
  /* sanity check */
8939
1.71k
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8940
0
    err = BAD_FUNC_ARG;
8941
0
  }
8942
8943
1.71k
  if (err == MP_OKAY) {
8944
    /* extract and justify kA */
8945
1.71k
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8946
8947
    /* extract and justify kB */
8948
1.71k
    if (err == MP_OKAY)
8949
1.71k
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8950
8951
    /* allocate the table */
8952
1.71k
    if (err == MP_OKAY) {
8953
29.0k
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8954
        #ifdef WOLFSSL_NO_MALLOC
8955
            precomp[x] = &lcl_precomp[x];
8956
        #endif
8957
27.3k
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8958
27.3k
            if (err != MP_OKAY)
8959
12
                break;
8960
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8961
            precomp[x]->key = key;
8962
        #endif
8963
27.3k
        }
8964
1.71k
    }
8965
1.71k
  }
8966
8967
1.71k
  if (err == MP_OKAY)
8968
    /* init montgomery reduction */
8969
1.70k
    err = mp_montgomery_setup(modulus, &mp);
8970
8971
1.71k
  if (err == MP_OKAY) {
8972
1.70k
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8973
1.70k
  }
8974
8975
1.71k
  if (err == MP_OKAY) {
8976
    /* precomp [i,0](A + B) table */
8977
1.69k
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8978
1.69k
  }
8979
1.71k
  if (err == MP_OKAY) {
8980
1.69k
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8981
1.69k
                                                          a, modulus, mp, NULL);
8982
1.69k
  }
8983
8984
1.71k
  if (err == MP_OKAY) {
8985
    /* precomp [0,i](A + B) table */
8986
1.69k
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8987
1.69k
  }
8988
1.71k
  if (err == MP_OKAY) {
8989
1.69k
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8990
1.69k
                                                             modulus, mp, NULL);
8991
1.69k
  }
8992
8993
1.71k
  if (err == MP_OKAY) {
8994
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8995
6.79k
    for (x = 1; x < 4; x++) {
8996
20.3k
      for (y = 1; y < 4; y++) {
8997
15.2k
        if (err == MP_OKAY) {
8998
15.2k
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8999
15.2k
                                                  precomp[x+(y<<2)], a, modulus,
9000
15.2k
                                                  mp, NULL);
9001
15.2k
        }
9002
15.2k
      }
9003
5.09k
    }
9004
1.69k
  }
9005
9006
1.71k
  if (err == MP_OKAY) {
9007
1.68k
    nibble  = 3;
9008
1.68k
    first   = 1;
9009
1.68k
    bitbufA = tA[0];
9010
1.68k
    bitbufB = tB[0];
9011
9012
    /* for every byte of the multiplicands */
9013
205k
    for (x = 0; x < (int)len || nibble != 3; ) {
9014
        /* grab a nibble */
9015
203k
        if (++nibble == 4) {
9016
50.8k
            if (x == (int)len) break;
9017
50.8k
            bitbufA = tA[x];
9018
50.8k
            bitbufB = tB[x];
9019
50.8k
            nibble  = 0;
9020
50.8k
            x++;
9021
50.8k
        }
9022
9023
        /* extract two bits from both, shift/update */
9024
203k
        nA = (bitbufA >> 6) & 0x03;
9025
203k
        nB = (bitbufB >> 6) & 0x03;
9026
203k
        bitbufA = (bitbufA << 2) & 0xFF;
9027
203k
        bitbufB = (bitbufB << 2) & 0xFF;
9028
9029
        /* if both zero, if first, continue */
9030
203k
        if ((nA == 0) && (nB == 0) && (first == 1)) {
9031
933
            continue;
9032
933
        }
9033
9034
        /* double twice, only if this isn't the first */
9035
202k
        if (first == 0) {
9036
            /* double twice */
9037
200k
            if (err == MP_OKAY)
9038
200k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9039
200k
            if (err == MP_OKAY)
9040
200k
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9041
17
            else
9042
17
                break;
9043
200k
        }
9044
9045
        /* if not both zero */
9046
202k
        if ((nA != 0) || (nB != 0)) {
9047
180k
            unsigned int i = nA + (nB<<2);
9048
180k
            if (first == 1) {
9049
                /* if first, copy from table */
9050
2.37k
                first = 0;
9051
2.37k
                if (err == MP_OKAY)
9052
2.37k
                    err = mp_copy(precomp[i]->x, C->x);
9053
9054
2.37k
                if (err == MP_OKAY)
9055
2.37k
                    err = mp_copy(precomp[i]->y, C->y);
9056
9057
2.37k
                if (err == MP_OKAY)
9058
2.37k
                    err = mp_copy(precomp[i]->z, C->z);
9059
0
                else
9060
0
                    break;
9061
177k
            } else {
9062
                /* if not first, add from table */
9063
177k
                if (err == MP_OKAY)
9064
177k
                    err = ecc_projective_add_point_safe(C, precomp[i],
9065
177k
                                                        C, a, modulus, mp,
9066
177k
                                                        &first);
9067
177k
                if (err != MP_OKAY)
9068
21
                    break;
9069
177k
            }
9070
180k
        }
9071
202k
    }
9072
1.68k
  }
9073
9074
  /* reduce to affine */
9075
1.71k
  if (err == MP_OKAY)
9076
1.64k
    err = ecc_map(C, modulus, mp);
9077
9078
  /* clean up */
9079
29.2k
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
9080
27.4k
     wc_ecc_del_point_ex(precomp[x], heap);
9081
27.4k
  }
9082
9083
1.71k
  ForceZero(tA, ECC_BUFSIZE);
9084
1.71k
  ForceZero(tB, ECC_BUFSIZE);
9085
#ifdef WOLFSSL_SMALL_STACK_CACHE
9086
#ifdef ALT_ECC_SIZE
9087
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
9088
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
9089
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
9090
#endif
9091
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
9092
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
9093
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
9094
  C->key = NULL;
9095
#endif
9096
1.71k
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
9097
1.71k
#ifndef WOLFSSL_NO_MALLOC
9098
1.71k
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9099
1.71k
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9100
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
9101
  wc_MemZero_Check(tB, ECC_BUFSIZE);
9102
  wc_MemZero_Check(tA, ECC_BUFSIZE);
9103
#endif
9104
1.71k
  return err;
9105
1.71k
}
9106
9107
#endif /* ECC_SHAMIR */
9108
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
9109
        * !WOLFSSL_CRYPTOCEL */
9110
9111
9112
#ifdef HAVE_ECC_VERIFY
9113
/* verify
9114
 *
9115
 * w  = s^-1 mod n
9116
 * u1 = xw
9117
 * u2 = rw
9118
 * X = u1*G + u2*Q
9119
 * v = X_x1 mod n
9120
 * accept if v == r
9121
 */
9122
9123
/**
9124
 Verify an ECC signature
9125
 sig         The signature to verify
9126
 siglen      The length of the signature (octets)
9127
 hash        The hash (message digest) that was signed
9128
 hashlen     The length of the hash (octets)
9129
 res         Result of signature, 1==valid, 0==invalid
9130
 key         The corresponding public ECC key
9131
 return      MP_OKAY if successful (even if the signature is not valid)
9132
             Caller should check the *res value to determine if the signature
9133
             is valid or invalid. Other negative values are returned on error.
9134
 */
9135
WOLFSSL_ABI
9136
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
9137
                       word32 hashlen, int* res, ecc_key* key)
9138
4.50k
{
9139
4.50k
    int err;
9140
9141
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9142
    mp_int *r = NULL, *s = NULL;
9143
#else
9144
4.50k
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9145
4.50k
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9146
4.50k
#endif
9147
#ifdef WOLFSSL_ASYNC_CRYPT
9148
    int isPrivateKeyOnly = 0;
9149
#endif
9150
#ifdef NO_ASN
9151
    word32 keySz;
9152
#endif
9153
9154
4.50k
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
9155
6
        return WC_KEY_SIZE_E;
9156
6
    }
9157
9158
4.49k
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
9159
37
        return ECC_BAD_ARG_E;
9160
37
    }
9161
9162
    /* Check hash length */
9163
4.46k
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
9164
4.42k
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
9165
141
        return BAD_LENGTH_E;
9166
141
    }
9167
9168
4.31k
#ifdef WOLF_CRYPTO_CB
9169
4.31k
    #ifndef WOLF_CRYPTO_CB_FIND
9170
4.31k
    if (key->devId != INVALID_DEVID)
9171
0
    #endif
9172
0
    {
9173
0
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
9174
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9175
0
            return err;
9176
        /* fall-through when unavailable */
9177
0
    }
9178
4.31k
#endif
9179
9180
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
9181
    (void)siglen;
9182
    (void)hashlen;
9183
    (void)s;
9184
    (void)r;
9185
    (void)err;
9186
    return NO_VALID_DEVID;
9187
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
9188
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9189
    err = wc_ecc_alloc_async(key);
9190
    if (err != 0)
9191
        return err;
9192
    r = key->r;
9193
    s = key->s;
9194
#else
9195
4.31k
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9196
4.31k
        DYNAMIC_TYPE_ECC);
9197
4.31k
    #ifdef MP_INT_SIZE_CHECK_NULL
9198
4.31k
    if (r == NULL)
9199
10
        return MEMORY_E;
9200
4.30k
    #endif
9201
4.30k
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9202
4.30k
        DYNAMIC_TYPE_ECC);
9203
4.30k
    #ifdef MP_INT_SIZE_CHECK_NULL
9204
4.30k
    if (s == NULL) {
9205
4
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9206
4
        return MEMORY_E;
9207
4
    }
9208
4.30k
    #endif
9209
4.30k
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9210
4.30k
    if (err != 0) {
9211
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9212
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9213
0
        return err;
9214
0
    }
9215
4.30k
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9216
4.30k
    if (err != 0) {
9217
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9218
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9219
0
        return err;
9220
0
    }
9221
4.30k
#endif /* WOLFSSL_ASYNC_CRYPT */
9222
9223
4.30k
    switch (key->state) {
9224
4.30k
        case ECC_STATE_NONE:
9225
4.30k
        case ECC_STATE_VERIFY_DECODE:
9226
4.30k
            key->state = ECC_STATE_VERIFY_DECODE;
9227
9228
            /* default to invalid signature */
9229
4.30k
            *res = 0;
9230
9231
4.30k
    #ifndef NO_ASN
9232
            /* Decode ASN.1 ECDSA signature. */
9233
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9234
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
9235
             * If either of those don't allocate correctly, none of
9236
             * the rest of this function will execute, and everything
9237
             * gets cleaned up at the end. */
9238
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
9239
        #else
9240
            /* r and s are initialized. */
9241
4.30k
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
9242
4.30k
        #endif
9243
4.30k
            if (err < 0) {
9244
30
                break;
9245
30
            }
9246
    #else
9247
            /* No support for DSA ASN.1 header.
9248
             * Signature must be r+s directly. */
9249
            keySz = 0;
9250
            if (key->dp != NULL) {
9251
                keySz = (word32)key->dp->size;
9252
            }
9253
            if (siglen != keySz * 2) {
9254
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
9255
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
9256
            }
9257
9258
            /* Import signature into r,s */
9259
            mp_init(r);
9260
            mp_init(s);
9261
            mp_read_unsigned_bin(r, sig, keySz);
9262
            mp_read_unsigned_bin(s, sig + keySz, keySz);
9263
    #endif /* !NO_ASN */
9264
4.27k
            FALL_THROUGH;
9265
9266
4.27k
        case ECC_STATE_VERIFY_DO:
9267
4.27k
            key->state = ECC_STATE_VERIFY_DO;
9268
        #ifdef WOLFSSL_ASYNC_CRYPT
9269
            if (key->type == ECC_PRIVATEKEY_ONLY) {
9270
                isPrivateKeyOnly = 1;
9271
            }
9272
        #endif
9273
4.27k
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9274
9275
4.27k
        #ifndef WOLFSSL_ASYNC_CRYPT
9276
            /* done with R/S */
9277
4.27k
            mp_clear(r);
9278
4.27k
            mp_clear(s);
9279
4.27k
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9280
4.27k
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9281
4.27k
        #ifdef MP_INT_SIZE_CHECK_NULL
9282
4.27k
            r = NULL;
9283
4.27k
            s = NULL;
9284
4.27k
        #endif
9285
4.27k
        #endif
9286
9287
4.27k
            if (err < 0) {
9288
117
                break;
9289
117
            }
9290
4.15k
            FALL_THROUGH;
9291
9292
4.15k
        case ECC_STATE_VERIFY_RES:
9293
4.15k
            key->state = ECC_STATE_VERIFY_RES;
9294
4.15k
            err = 0;
9295
4.15k
            break;
9296
9297
0
        default:
9298
0
            err = BAD_STATE_E;
9299
4.30k
    }
9300
9301
#ifdef WOLFSSL_ASYNC_CRYPT
9302
    /* if async pending then return and skip done cleanup below */
9303
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
9304
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
9305
            key->state++;
9306
        return err;
9307
    }
9308
#endif
9309
9310
    /* cleanup */
9311
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9312
    wc_ecc_free_async(key);
9313
#else
9314
4.30k
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9315
4.30k
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9316
4.30k
#endif
9317
9318
    /* make sure required variables are reset */
9319
4.30k
    wc_ecc_reset(key);
9320
4.30k
    return err;
9321
4.30k
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
9322
4.30k
}
9323
9324
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
9325
9326
#if (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
9327
    !defined(WOLFSSL_PSOC6_CRYPTO) && \
9328
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9329
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
9330
1.40k
{
9331
1.40k
    int err = MP_OKAY;
9332
1.40k
    DECLARE_CURVE_SPECS(1);
9333
9334
1.40k
    ALLOC_CURVE_SPECS(1, err);
9335
1.40k
    if (err == MP_OKAY) {
9336
1.40k
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
9337
1.40k
    }
9338
1.40k
    if (err != 0) {
9339
1
        FREE_CURVE_SPECS();
9340
1
        return err;
9341
1
    }
9342
9343
1.40k
    if (mp_iszero(r) || mp_iszero(s)) {
9344
14
        err = MP_ZERO_E;
9345
14
    }
9346
1.40k
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
9347
23
        err = MP_VAL;
9348
23
    }
9349
1.40k
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
9350
18
        err = MP_VAL;
9351
18
    }
9352
9353
1.40k
    wc_ecc_curve_free(curve);
9354
1.40k
    FREE_CURVE_SPECS();
9355
1.40k
    return err;
9356
1.40k
}
9357
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
9358
9359
#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP)
9360
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
9361
    word32 hashlen, int* res, ecc_key* key)
9362
1.74k
{
9363
1.74k
    (void)r;
9364
1.74k
    (void)s;
9365
1.74k
    (void)hash;
9366
1.74k
    (void)hashlen;
9367
1.74k
    (void)res;
9368
1.74k
    (void)key;
9369
9370
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
9371
  if (key->handle != -1) {
9372
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
9373
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9374
  }
9375
  if (wolfSSL_GetHandleCbSet() == 1) {
9376
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
9377
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9378
  }
9379
#endif
9380
9381
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
9382
    if (key->idx == ECC_CUSTOM_IDX || (1
9383
    #ifndef WOLFSSL_SP_NO_256
9384
         && ecc_sets[key->idx].id != ECC_SECP256R1
9385
    #endif
9386
    #ifdef WOLFSSL_SP_SM2
9387
         && ecc_sets[key->idx].id != ECC_SM2P256V1
9388
    #endif
9389
    #ifdef WOLFSSL_SP_384
9390
         && ecc_sets[key->idx].id != ECC_SECP384R1
9391
    #endif
9392
    #ifdef WOLFSSL_SP_521
9393
         && ecc_sets[key->idx].id != ECC_SECP521R1
9394
    #endif
9395
        )) {
9396
        return WC_KEY_SIZE_E;
9397
    }
9398
#endif
9399
9400
#if defined(WOLFSSL_HAVE_SP_ECC)
9401
    if (key->idx != ECC_CUSTOM_IDX) {
9402
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
9403
        /* perform blocking call to non-blocking function */
9404
        ecc_nb_ctx_t nb_ctx;
9405
        int err;
9406
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
9407
        err = NOT_COMPILED_IN; /* set default error */
9408
    #endif
9409
    #ifndef WOLFSSL_SP_NO_256
9410
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
9411
        #ifdef WC_ECC_NONBLOCK
9412
            if (key->nb_ctx) {
9413
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9414
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9415
                    key->heap);
9416
            }
9417
            #ifdef WC_ECC_NONBLOCK_ONLY
9418
            do { /* perform blocking call to non-blocking function */
9419
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
9420
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9421
                    key->heap);
9422
            } while (err == FP_WOULDBLOCK);
9423
            return err;
9424
            #endif
9425
        #endif /* WC_ECC_NONBLOCK */
9426
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9427
            {
9428
                int ret;
9429
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
9430
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9431
                return ret;
9432
            }
9433
        #endif
9434
        }
9435
    #endif
9436
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9437
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
9438
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
9439
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
9440
                key->pubkey.y, key->pubkey.z, r, s, res,
9441
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
9442
                                          key->fpIdx, key->fpBuild, key->heap),
9443
                key->heap);
9444
            #endif
9445
            #if !defined(FP_ECC_CONTROL)
9446
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
9447
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9448
            #endif
9449
        }
9450
    #endif
9451
    #ifdef WOLFSSL_SP_384
9452
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
9453
        #ifdef WC_ECC_NONBLOCK
9454
            if (key->nb_ctx) {
9455
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9456
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9457
                    key->heap);
9458
            }
9459
            #ifdef WC_ECC_NONBLOCK_ONLY
9460
            do { /* perform blocking call to non-blocking function */
9461
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
9462
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9463
                    key->heap);
9464
            } while (err == FP_WOULDBLOCK);
9465
            return err;
9466
            #endif
9467
        #endif /* WC_ECC_NONBLOCK */
9468
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9469
            {
9470
                int ret;
9471
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
9472
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9473
                return ret;
9474
            }
9475
        #endif
9476
        }
9477
    #endif
9478
    #ifdef WOLFSSL_SP_521
9479
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
9480
        #ifdef WC_ECC_NONBLOCK
9481
            if (key->nb_ctx) {
9482
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9483
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9484
                    key->heap);
9485
            }
9486
            #ifdef WC_ECC_NONBLOCK_ONLY
9487
            do { /* perform blocking call to non-blocking function */
9488
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
9489
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9490
                    key->heap);
9491
            } while (err == FP_WOULDBLOCK);
9492
            return err;
9493
            #endif
9494
        #endif /* WC_ECC_NONBLOCK */
9495
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9496
            {
9497
                int ret;
9498
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
9499
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9500
                return ret;
9501
            }
9502
        #endif
9503
        }
9504
    #endif
9505
    }
9506
#endif
9507
9508
1.74k
    return NOT_COMPILED_IN;
9509
1.74k
}
9510
9511
#if !defined(WOLFSSL_MICROCHIP) && \
9512
    (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC))
9513
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
9514
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
9515
1.35k
{
9516
1.35k
   int        err;
9517
1.35k
   ecc_point* mG = NULL;
9518
1.35k
   ecc_point* mQ = NULL;
9519
#ifdef WOLFSSL_NO_MALLOC
9520
   ecc_point  lcl_mG;
9521
   ecc_point  lcl_mQ;
9522
#endif
9523
9524
1.35k
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9525
1.35k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9526
1.35k
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9527
1.35k
#endif
9528
1.35k
   mp_int*    e;
9529
1.35k
   mp_int*    v = NULL;      /* Will be w. */
9530
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
9531
   mp_int     u1tmp[1];
9532
   mp_int     u2tmp[1];
9533
#endif
9534
1.35k
   mp_int*    u1 = NULL;     /* Will be e. */
9535
1.35k
   mp_int*    u2 = NULL;     /* Will be w. */
9536
9537
1.35k
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
9538
0
       return WC_KEY_SIZE_E;
9539
0
   }
9540
9541
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
9542
   err = wc_ecc_alloc_mpint(key, &key->e);
9543
   if (err != 0) {
9544
      return err;
9545
   }
9546
   e = key->e;
9547
9548
   err = mp_init(e);
9549
#else
9550
1.35k
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
9551
1.35k
#ifdef MP_INT_SIZE_CHECK_NULL
9552
1.35k
   if (e_lcl == NULL) {
9553
0
       return MEMORY_E;
9554
0
   }
9555
1.35k
#endif
9556
1.35k
   e = e_lcl;
9557
9558
1.35k
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9559
1.35k
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
9560
1.35k
   if (err != MP_OKAY) {
9561
0
#ifdef WOLFSSL_SMALL_STACK
9562
0
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9563
0
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9564
0
   #endif
9565
0
#endif
9566
0
      return MEMORY_E;
9567
0
   }
9568
9569
   /* read hash */
9570
1.35k
   if (err == MP_OKAY) {
9571
       /* we may need to truncate if hash is longer than key size */
9572
1.35k
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
9573
9574
       /* truncate down to byte size, may be all that's needed */
9575
1.35k
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9576
355
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
9577
1.35k
       err = mp_read_unsigned_bin(e, hash, hashlen);
9578
9579
       /* may still need bit truncation too */
9580
1.35k
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9581
260
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
9582
1.35k
   }
9583
9584
   /* check for async hardware acceleration */
9585
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9586
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9587
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
9588
   #ifdef HAVE_CAVIUM_V
9589
      if (NitroxEccIsCurveSupported(key))
9590
   #endif
9591
      {
9592
          word32 keySz = (word32)key->dp->size;
9593
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
9594
          if (err == MP_OKAY)
9595
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
9596
          if (err == MP_OKAY)
9597
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
9598
          if (err == MP_OKAY)
9599
          #ifdef HAVE_CAVIUM_V
9600
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
9601
                    &key->pubkey.y->raw, &r->raw, &s->raw,
9602
                    &curve->prime->raw, &curve->order->raw, res);
9603
          #else
9604
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
9605
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
9606
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
9607
                    &curve->Gx->raw, &curve->Gy->raw, res);
9608
          #endif
9609
9610
      #ifndef HAVE_CAVIUM_V
9611
          mp_clear(e);
9612
      #endif
9613
9614
          return err;
9615
      }
9616
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
9617
   }
9618
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
9619
9620
1.35k
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
9621
1.35k
#ifdef MP_INT_SIZE_CHECK_NULL
9622
1.35k
   if (w == NULL) {
9623
0
       err = MEMORY_E;
9624
0
   }
9625
1.35k
#endif
9626
9627
1.35k
   if (err == MP_OKAY) {
9628
#ifdef WOLFSSL_CHECK_VER_FAULTS
9629
    #ifndef WOLFSSL_NO_MALLOC
9630
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9631
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9632
       if (u1 == NULL || u2 == NULL)
9633
            err = MEMORY_E;
9634
    #else
9635
        u1 = u1tmp;
9636
        u2 = u2tmp;
9637
    #endif
9638
       /* zeroed so the cleanup below no-ops if the init is skipped */
9639
       if (u1 != NULL)
9640
           XMEMSET(u1, 0, sizeof(mp_int));
9641
       if (u2 != NULL)
9642
           XMEMSET(u2, 0, sizeof(mp_int));
9643
#else
9644
1.35k
       u1 = e;
9645
1.35k
       u2 = w;
9646
1.35k
#endif
9647
1.35k
       v = w;
9648
1.35k
   }
9649
1.35k
   if (err == MP_OKAY) {
9650
1.35k
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9651
1.35k
   }
9652
#ifdef WOLFSSL_CHECK_VER_FAULTS
9653
   if (err == MP_OKAY) {
9654
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9655
   }
9656
   if (err == MP_OKAY) {
9657
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9658
   }
9659
#endif
9660
9661
   /* allocate points */
9662
1.35k
   if (err == MP_OKAY) {
9663
   #ifdef WOLFSSL_NO_MALLOC
9664
       mG = &lcl_mG;
9665
   #endif
9666
1.35k
       err = wc_ecc_new_point_ex(&mG, key->heap);
9667
1.35k
   }
9668
1.35k
   if (err == MP_OKAY) {
9669
   #ifdef WOLFSSL_NO_MALLOC
9670
       mQ = &lcl_mQ;
9671
   #endif
9672
1.35k
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9673
1.35k
   }
9674
9675
   /*  w  = s^-1 mod n */
9676
1.35k
   if (err == MP_OKAY)
9677
1.35k
       err = mp_invmod(s, curve->order, w);
9678
9679
   /* u1 = ew */
9680
1.35k
   if (err == MP_OKAY)
9681
1.34k
       err = mp_mulmod(e, w, curve->order, u1);
9682
9683
#ifdef WOLFSSL_CHECK_VER_FAULTS
9684
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9685
        err = BAD_STATE_E;
9686
    }
9687
#endif
9688
9689
   /* u2 = rw */
9690
1.35k
   if (err == MP_OKAY)
9691
1.34k
       err = mp_mulmod(r, w, curve->order, u2);
9692
9693
#ifdef WOLFSSL_CHECK_VER_FAULTS
9694
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9695
        err = BAD_STATE_E;
9696
    }
9697
#endif
9698
9699
   /* find mG and mQ */
9700
1.35k
   if (err == MP_OKAY)
9701
1.33k
       err = mp_copy(curve->Gx, mG->x);
9702
1.35k
   if (err == MP_OKAY)
9703
1.33k
       err = mp_copy(curve->Gy, mG->y);
9704
1.35k
   if (err == MP_OKAY)
9705
1.33k
       err = mp_set(mG->z, 1);
9706
9707
1.35k
   if (err == MP_OKAY)
9708
1.33k
       err = mp_copy(key->pubkey.x, mQ->x);
9709
1.35k
   if (err == MP_OKAY)
9710
1.33k
       err = mp_copy(key->pubkey.y, mQ->y);
9711
1.35k
   if (err == MP_OKAY)
9712
1.33k
       err = mp_copy(key->pubkey.z, mQ->z);
9713
9714
#if defined(FREESCALE_LTC_ECC)
9715
   /* use PKHA to compute u1*mG + u2*mQ */
9716
   if (err == MP_OKAY)
9717
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9718
   if (err == MP_OKAY)
9719
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9720
   if (err == MP_OKAY)
9721
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9722
#else
9723
#ifndef ECC_SHAMIR
9724
    if (err == MP_OKAY)
9725
    {
9726
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9727
        ecc_point mG1, mQ1;
9728
        wc_ecc_copy_point(mQ, &mQ1);
9729
        wc_ecc_copy_point(mG, &mG1);
9730
     #endif
9731
9732
        mp_digit mp = 0;
9733
9734
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9735
            /* compute u1*mG + u2*mQ = mG */
9736
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9737
                                                                     key->heap);
9738
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9739
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9740
                err = BAD_STATE_E;
9741
            }
9742
9743
            /* store new value for comparing with after add operation */
9744
           wc_ecc_copy_point(mG, &mG1);
9745
        #endif
9746
            if (err == MP_OKAY) {
9747
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9748
                                                                     key->heap);
9749
            }
9750
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9751
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9752
                err = BAD_STATE_E;
9753
            }
9754
        #endif
9755
9756
            /* find the montgomery mp */
9757
            if (err == MP_OKAY)
9758
                err = mp_montgomery_setup(curve->prime, &mp);
9759
9760
            /* add them - pass mG as A (first) not B (second): the safe-add
9761
             * recovery for a missed-double doubles B into R, which requires
9762
             * B and R to be different points. */
9763
            if (err == MP_OKAY)
9764
                err = ecc_projective_add_point_safe(mG, mQ, mG, curve->Af,
9765
                                                        curve->prime, mp, NULL);
9766
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9767
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9768
                err = BAD_STATE_E;
9769
            }
9770
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9771
                err = BAD_STATE_E;
9772
            }
9773
        #endif
9774
        }
9775
        else {
9776
            /* compute 0*mG + u2*mQ = mG */
9777
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9778
                                                                     key->heap);
9779
            /* find the montgomery mp */
9780
            if (err == MP_OKAY)
9781
                err = mp_montgomery_setup(curve->prime, &mp);
9782
        }
9783
9784
        /* reduce */
9785
        if (err == MP_OKAY)
9786
            err = ecc_map(mG, curve->prime, mp);
9787
    }
9788
#else
9789
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9790
1.35k
    if (err == MP_OKAY) {
9791
1.33k
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9792
1.33k
                                                                     key->heap);
9793
1.33k
    }
9794
1.35k
#endif /* ECC_SHAMIR */
9795
1.35k
#endif /* FREESCALE_LTC_ECC */
9796
9797
   /* v = X_x1 mod n */
9798
1.35k
   if (err == MP_OKAY)
9799
1.31k
       err = mp_mod(mG->x, curve->order, v);
9800
9801
   /* does v == r */
9802
1.35k
   if (err == MP_OKAY) {
9803
1.31k
       if (mp_cmp(v, r) == MP_EQ)
9804
1.20k
           *res = 1;
9805
#ifdef WOLFSSL_CHECK_VER_FAULTS
9806
       /* redundant comparison as sanity check that first one happened */
9807
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9808
           *res = 0;
9809
#endif
9810
1.31k
   }
9811
9812
   /* cleanup */
9813
1.35k
   wc_ecc_del_point_ex(mG, key->heap);
9814
1.35k
   wc_ecc_del_point_ex(mQ, key->heap);
9815
9816
1.35k
   mp_clear(e);
9817
1.35k
   mp_clear(w);
9818
1.35k
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9819
#ifdef WOLFSSL_CHECK_VER_FAULTS
9820
   mp_clear(u1);
9821
   mp_clear(u2);
9822
#ifndef WOLFSSL_NO_MALLOC
9823
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9824
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9825
#endif
9826
#endif
9827
1.35k
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9828
1.35k
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9829
1.35k
#endif
9830
9831
1.35k
   return err;
9832
1.35k
}
9833
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9834
#endif /* HAVE_ECC_VERIFY_HELPER */
9835
9836
/**
9837
   Verify an ECC signature
9838
   r           The signature R component to verify
9839
   s           The signature S component to verify
9840
   hash        The hash (message digest) that was signed
9841
   hashlen     The length of the hash (octets)
9842
   res         Result of signature, 1==valid, 0==invalid
9843
   key         The corresponding public ECC key
9844
   return      MP_OKAY if successful (even if the signature is not valid)
9845
               Caller should check the *res value to determine if the signature
9846
               is valid or invalid. Other negative values are returned on error.
9847
*/
9848
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9849
                    word32 hashlen, int* res, ecc_key* key)
9850
1.41k
{
9851
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_SIGN_ONLY)
9852
    /* HW ECDSA verify via STM32 PKA. Works under both the CubeMX-HAL
9853
     * and the bare-metal direct-register paths. (Under WC_STM32_PKA_SIGN_ONLY
9854
     * -- e.g. STM32C5 -- verify falls through to the software body below.)
9855
     * Mirror the non-FIPS
9856
     * input-validation from the SW body below (length range, all-zero
9857
     * digest rejection) so HW + SW share the same input contract. */
9858
#ifndef WC_ALLOW_ECC_ZERO_HASH
9859
    byte hashIsZero = 0;
9860
    word32 zIdx;
9861
#endif
9862
9863
    if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) {
9864
        return ECC_BAD_ARG_E;
9865
    }
9866
    if ((hashlen > WC_MAX_DIGEST_SIZE) || (hashlen < WC_MIN_DIGEST_SIZE)) {
9867
        return BAD_LENGTH_E;
9868
    }
9869
#ifndef WC_ALLOW_ECC_ZERO_HASH
9870
    /* reject all 0's hash */
9871
    for (zIdx = 0; zIdx < hashlen; zIdx++)
9872
        hashIsZero |= hash[zIdx];
9873
    if (hashIsZero == 0)
9874
        return ECC_BAD_ARG_E;
9875
#endif
9876
9877
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9878
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9879
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9880
#else
9881
1.41k
   int           err;
9882
1.41k
   word32        keySz = 0;
9883
1.41k
#ifndef WC_ALLOW_ECC_ZERO_HASH
9884
1.41k
   byte hashIsZero = 0;
9885
1.41k
   word32 zIdx;
9886
1.41k
#endif
9887
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9888
   byte sigRS[ATECC_KEY_SIZE*2];
9889
#elif defined(WOLFSSL_MICROCHIP_TA100)
9890
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9891
#elif defined(WOLFSSL_CRYPTOCELL)
9892
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9893
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9894
   word32 msgLenInBytes = hashlen;
9895
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9896
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9897
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9898
#elif defined(WOLFSSL_KCAPI_ECC)
9899
   byte sigRS[MAX_ECC_BYTES*2];
9900
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9901
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9902
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9903
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) && \
9904
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
9905
#else
9906
   /* Software verify helper (also used for SE050 software keys under
9907
    * WOLFSSL_SE050_ONLY_KEY_ID) needs the curve specs. */
9908
1.41k
   int curveLoaded = 0;
9909
1.41k
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9910
1.41k
#endif
9911
9912
1.41k
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9913
0
       return ECC_BAD_ARG_E;
9914
9915
    /* Check hash length */
9916
1.41k
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
9917
1.41k
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
9918
0
        return BAD_LENGTH_E;
9919
0
    }
9920
9921
1.41k
#ifndef WC_ALLOW_ECC_ZERO_HASH
9922
    /* reject all 0's hash */
9923
43.8k
    for (zIdx = 0; zIdx < hashlen; zIdx++)
9924
42.4k
        hashIsZero |= hash[zIdx];
9925
1.41k
    if (hashIsZero == 0)
9926
10
        return ECC_BAD_ARG_E;
9927
1.40k
#endif
9928
9929
   /* default to invalid signature */
9930
1.40k
   *res = 0;
9931
9932
   /* is the IDX valid ?  */
9933
1.40k
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9934
0
      return ECC_BAD_ARG_E;
9935
0
   }
9936
9937
1.40k
   err = wc_ecc_check_r_s_range(key, r, s);
9938
1.40k
   if (err != MP_OKAY) {
9939
56
      return err;
9940
56
   }
9941
9942
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID) && \
9943
    !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY)
9944
   /* Key resident in the SE050: verify in hardware. Software keys fall through
9945
    * to the wolfCrypt verify helper below. */
9946
   if (key->keyIdSet) {
9947
       return se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9948
   }
9949
#endif
9950
9951
1.35k
   keySz = (word32)key->dp->size;
9952
9953
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9954
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9955
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9956
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9957
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9958
            sw->eccVerify.r = r;
9959
            sw->eccVerify.s = s;
9960
            sw->eccVerify.hash = hash;
9961
            sw->eccVerify.hashlen = hashlen;
9962
            sw->eccVerify.stat = res;
9963
            sw->eccVerify.key = key;
9964
            return WC_PENDING_E;
9965
        }
9966
    }
9967
#endif
9968
9969
#ifndef HAVE_ECC_VERIFY_HELPER
9970
9971
#ifndef WOLFSSL_SE050
9972
    /* Extract R and S with front zero padding (if required),
9973
     * SE050 does this in port layer  */
9974
    XMEMSET(sigRS, 0, sizeof(sigRS));
9975
    err = mp_to_unsigned_bin(r, sigRS +
9976
                                (keySz - mp_unsigned_bin_size(r)));
9977
    if (err != MP_OKAY) {
9978
        return err;
9979
    }
9980
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9981
                                (keySz - mp_unsigned_bin_size(s)));
9982
    if (err != MP_OKAY) {
9983
        return err;
9984
    }
9985
#endif /* WOLFSSL_SE050 */
9986
9987
#if defined(WOLFSSL_MICROCHIP_TA100)
9988
    if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
9989
        err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9990
        if (err != 0) {
9991
            return err;
9992
        }
9993
        (void)hashlen;
9994
    }
9995
    else {
9996
        err = atmel_ecc_verify_ex(hash, hashlen, sigRS, key->pubkey_raw,
9997
            keySz * 2, microchip_curve_id_for_key(key), res);
9998
        if (err != 0) {
9999
           return err;
10000
        }
10001
    }
10002
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10003
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
10004
    if (err != 0) {
10005
       return err;
10006
    }
10007
    (void)hashlen;
10008
#elif defined(WOLFSSL_CRYPTOCELL)
10009
10010
   /* truncate if hash is longer than key size */
10011
   if (msgLenInBytes > keySz) {
10012
       msgLenInBytes = keySz;
10013
   }
10014
   hash_mode = cc310_hashModeECC(msgLenInBytes);
10015
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
10016
       /* hash_mode = */ cc310_hashModeECC(keySz);
10017
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
10018
   }
10019
10020
   /* verify the signature using the public key */
10021
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
10022
                           &key->ctx.pubKey,
10023
                           hash_mode,
10024
                           &sigRS[0],
10025
                           keySz*2,
10026
                           (byte*)hash,
10027
                           msgLenInBytes);
10028
10029
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
10030
       /* signature verification reported invalid signature. */
10031
       *res = 0; /* Redundant, added for code clarity */
10032
       err = MP_OKAY;
10033
   }
10034
   else if (err != SA_SILIB_RET_OK) {
10035
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
10036
       return err;
10037
   }
10038
   else {
10039
       /* valid signature. */
10040
       *res = 1;
10041
       err = MP_OKAY;
10042
   }
10043
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10044
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
10045
                                hash, hashlen,
10046
                                res, key);
10047
#elif defined(WOLFSSL_KCAPI_ECC)
10048
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
10049
    if (err == 0) {
10050
        *res = 1;
10051
    }
10052
#elif defined(WOLFSSL_SE050)
10053
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
10054
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10055
    if (hashlen > sizeof(hashcopy))
10056
        return ECC_BAD_ARG_E;
10057
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
10058
    mp_reverse(sigRS, keySz);
10059
    mp_reverse(sigRS + keySz, keySz);
10060
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
10061
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
10062
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
10063
10064
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
10065
                                     xil_curve_type[key->dp->id],
10066
                                     XIL_CAST_U64(hashcopy), keySz,
10067
                                     XIL_CAST_U64(key->keyRaw),
10068
                                     XIL_CAST_U64(sigRS));
10069
10070
    if (err != XST_SUCCESS) {
10071
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
10072
        err = WC_HW_E;
10073
    } else {
10074
        *res = 1;
10075
    }
10076
#endif
10077
10078
#else
10079
  /* checking if private key with no public part */
10080
1.35k
  if (key->type == ECC_PRIVATEKEY_ONLY) {
10081
506
      WOLFSSL_MSG("Verify called with private key, generating public part");
10082
506
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10083
506
      if (err != MP_OKAY) {
10084
0
          return err;
10085
0
      }
10086
506
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10087
506
      if (err != MP_OKAY) {
10088
0
          FREE_CURVE_SPECS();
10089
0
          return err;
10090
0
      }
10091
506
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
10092
506
      if (err != MP_OKAY) {
10093
0
           WOLFSSL_MSG("Unable to extract public key");
10094
0
           wc_ecc_curve_free(curve);
10095
0
           FREE_CURVE_SPECS();
10096
0
           return err;
10097
0
      }
10098
506
      curveLoaded = 1;
10099
506
  }
10100
10101
1.35k
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
10102
1.35k
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
10103
0
      if (curveLoaded) {
10104
0
           wc_ecc_curve_free(curve);
10105
0
           FREE_CURVE_SPECS();
10106
0
      }
10107
0
      return err;
10108
0
  }
10109
10110
1.35k
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
10111
1.35k
   if (!curveLoaded) {
10112
846
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10113
846
       if (err != 0) {
10114
1
          return err;
10115
1
       }
10116
       /* read in the specs for this curve */
10117
845
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10118
845
       if (err != 0) {
10119
0
          FREE_CURVE_SPECS();
10120
0
          return err;
10121
0
       }
10122
845
   }
10123
10124
1.35k
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
10125
1.35k
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
10126
10127
1.35k
   (void)curveLoaded;
10128
1.35k
   wc_ecc_curve_free(curve);
10129
1.35k
   FREE_CURVE_SPECS();
10130
1.35k
#endif /* HAVE_ECC_VERIFY_HELPER */
10131
10132
1.35k
   (void)keySz;
10133
1.35k
   (void)hashlen;
10134
10135
1.35k
   return err;
10136
1.35k
#endif /* WOLFSSL_STM32_PKA */
10137
1.35k
}
10138
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
10139
#endif /* HAVE_ECC_VERIFY */
10140
10141
#ifdef HAVE_ECC_KEY_IMPORT
10142
/* import point from der
10143
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
10144
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
10145
                               const int curve_idx, ecc_point* point,
10146
                               int shortKeySize)
10147
82
{
10148
82
    int err = 0;
10149
82
#ifdef HAVE_COMP_KEY
10150
82
    int compressed = 0;
10151
82
#endif
10152
82
    int keysize;
10153
82
    byte pointType;
10154
10155
#ifndef HAVE_COMP_KEY
10156
    (void)shortKeySize;
10157
#endif
10158
10159
82
    if (in == NULL || point == NULL || (curve_idx < 0) ||
10160
82
        (wc_ecc_is_valid_idx(curve_idx) == 0))
10161
0
        return ECC_BAD_ARG_E;
10162
10163
    /* must be odd */
10164
82
    if ((inLen & 1) == 0) {
10165
0
        return ECC_BAD_ARG_E;
10166
0
    }
10167
10168
    /* validate point format byte before any memory operations */
10169
82
    pointType = in[0];
10170
82
    if (pointType != ECC_POINT_UNCOMP &&
10171
0
            pointType != ECC_POINT_COMP_EVEN &&
10172
0
            pointType != ECC_POINT_COMP_ODD) {
10173
0
        return ASN_PARSE_E;
10174
0
    }
10175
10176
    /* clear if previously allocated */
10177
82
    mp_clear(point->x);
10178
82
    mp_clear(point->y);
10179
82
    mp_clear(point->z);
10180
10181
    /* init point */
10182
#ifdef ALT_ECC_SIZE
10183
    point->x = (mp_int*)&point->xyz[0];
10184
    point->y = (mp_int*)&point->xyz[1];
10185
    point->z = (mp_int*)&point->xyz[2];
10186
    alt_fp_init(point->x);
10187
    alt_fp_init(point->y);
10188
    alt_fp_init(point->z);
10189
#else
10190
82
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
10191
10192
82
    if (err != MP_OKAY)
10193
0
        return MEMORY_E;
10194
82
#endif
10195
10196
    /* pointType already validated above; check for compressed format */
10197
82
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10198
0
#ifdef HAVE_COMP_KEY
10199
0
        compressed = 1;
10200
#else
10201
        err = NOT_COMPILED_IN;
10202
#endif
10203
0
    }
10204
10205
    /* adjust to skip first byte */
10206
82
    inLen -= 1;
10207
82
    in += 1;
10208
10209
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
10210
     * is true */
10211
82
#ifdef HAVE_COMP_KEY
10212
82
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
10213
#else
10214
    keysize = (int)(inLen>>1);
10215
#endif
10216
10217
    /* sanity check that x coordinate is expected size */
10218
82
    if (err == MP_OKAY) {
10219
82
        if (keysize != ecc_sets[curve_idx].size) {
10220
0
            err = ECC_BAD_ARG_E;
10221
0
        }
10222
82
    }
10223
10224
    /* read data */
10225
82
    if (err == MP_OKAY)
10226
82
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
10227
10228
82
#ifdef HAVE_COMP_KEY
10229
82
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10230
    #if defined(WOLFSSL_HAVE_SP_ECC)
10231
        #ifndef WOLFSSL_SP_NO_256
10232
        if (curve_idx != ECC_CUSTOM_IDX &&
10233
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
10234
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
10235
        }
10236
        else
10237
        #endif
10238
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10239
        if (curve_idx != ECC_CUSTOM_IDX &&
10240
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
10241
            err = sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
10242
        }
10243
        else
10244
        #endif
10245
        #ifdef WOLFSSL_SP_384
10246
        if (curve_idx != ECC_CUSTOM_IDX &&
10247
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
10248
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
10249
        }
10250
        else
10251
        #endif
10252
        #ifdef WOLFSSL_SP_521
10253
        if (curve_idx != ECC_CUSTOM_IDX &&
10254
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
10255
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
10256
        }
10257
        else
10258
        #endif
10259
    #endif
10260
0
    #if !defined(WOLFSSL_SP_MATH)
10261
0
        {
10262
0
            int did_init = 0;
10263
0
        #ifdef WOLFSSL_SMALL_STACK
10264
0
            mp_int* t1 = NULL;
10265
0
            mp_int* t2 = NULL;
10266
        #else
10267
            mp_int t1[1], t2[1];
10268
        #endif
10269
0
            DECLARE_CURVE_SPECS(3);
10270
10271
0
            ALLOC_CURVE_SPECS(3, err);
10272
10273
0
        #ifdef WOLFSSL_SMALL_STACK
10274
0
            if (err == MP_OKAY) {
10275
0
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10276
0
                                      DYNAMIC_TYPE_BIGINT);
10277
0
                if (t1 == NULL) {
10278
0
                    err = MEMORY_E;
10279
0
                }
10280
0
            }
10281
0
            if (err == MP_OKAY) {
10282
0
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10283
0
                                      DYNAMIC_TYPE_BIGINT);
10284
0
                if (t2 == NULL) {
10285
0
                    err = MEMORY_E;
10286
0
                }
10287
0
            }
10288
0
        #endif
10289
10290
0
            if (err == MP_OKAY) {
10291
0
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10292
0
                    err = MEMORY_E;
10293
0
                else
10294
0
                    did_init = 1;
10295
0
            }
10296
10297
            /* load curve info */
10298
0
            if (err == MP_OKAY)
10299
0
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10300
0
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10301
0
                        ECC_CURVE_FIELD_BF));
10302
10303
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
10304
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10305
            /* validate prime is prime for custom curves */
10306
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
10307
                int isPrime = MP_NO;
10308
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10309
                if (err == MP_OKAY && isPrime == MP_NO)
10310
                    err = MP_VAL;
10311
            }
10312
        #endif
10313
10314
            /* compute x^3 */
10315
0
            if (err == MP_OKAY)
10316
0
                err = mp_sqr(point->x, t1);
10317
0
            if (err == MP_OKAY)
10318
0
                err = mp_mulmod(t1, point->x, curve->prime, t1);
10319
10320
            /* compute x^3 + a*x */
10321
0
            if (err == MP_OKAY)
10322
0
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
10323
0
            if (err == MP_OKAY)
10324
0
                err = mp_add(t1, t2, t1);
10325
10326
            /* compute x^3 + a*x + b */
10327
0
            if (err == MP_OKAY)
10328
0
                err = mp_add(t1, curve->Bf, t1);
10329
10330
            /* compute sqrt(x^3 + a*x + b) */
10331
0
            if (err == MP_OKAY)
10332
0
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
10333
10334
            /* adjust y */
10335
0
            if (err == MP_OKAY) {
10336
0
                if ((mp_isodd(t2) == MP_YES &&
10337
0
                                            pointType == ECC_POINT_COMP_ODD) ||
10338
0
                    (mp_isodd(t2) == MP_NO &&
10339
0
                                            pointType == ECC_POINT_COMP_EVEN)) {
10340
0
                    err = mp_mod(t2, curve->prime, point->y);
10341
0
                }
10342
0
                else {
10343
0
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
10344
0
                }
10345
0
            }
10346
10347
0
            if (did_init) {
10348
0
                mp_clear(t2);
10349
0
                mp_clear(t1);
10350
0
            }
10351
10352
0
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10353
0
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10354
10355
0
            wc_ecc_curve_free(curve);
10356
0
            FREE_CURVE_SPECS();
10357
0
        }
10358
    #else
10359
        {
10360
            err = WC_KEY_SIZE_E;
10361
        }
10362
    #endif
10363
0
    }
10364
82
#endif
10365
10366
82
    if (err == MP_OKAY) {
10367
82
#ifdef HAVE_COMP_KEY
10368
82
        if (compressed == 0)
10369
82
#endif
10370
82
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
10371
82
    }
10372
82
    if (err == MP_OKAY)
10373
82
        err = mp_set(point->z, 1);
10374
10375
82
    if (err != MP_OKAY) {
10376
0
        mp_clear(point->x);
10377
0
        mp_clear(point->y);
10378
0
        mp_clear(point->z);
10379
0
    }
10380
10381
82
    return err;
10382
82
}
10383
10384
/* function for backwards compatibility with previous implementations */
10385
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
10386
                            ecc_point* point)
10387
155
{
10388
155
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
10389
155
}
10390
#endif /* HAVE_ECC_KEY_IMPORT */
10391
10392
#ifdef HAVE_ECC_KEY_EXPORT
10393
/* export point to der */
10394
10395
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
10396
                               word32* outLen, int compressed)
10397
0
{
10398
0
    if (compressed == 0)
10399
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
10400
0
#ifdef HAVE_COMP_KEY
10401
0
    else
10402
0
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
10403
#else
10404
    return NOT_COMPILED_IN;
10405
#endif
10406
0
}
10407
10408
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
10409
                            word32* outLen)
10410
336
{
10411
336
    int    ret = MP_OKAY;
10412
336
    word32 numlen;
10413
336
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10414
10415
336
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10416
0
        return ECC_BAD_ARG_E;
10417
10418
336
    numlen = (word32)ecc_sets[curve_idx].size;
10419
10420
    /* return length needed only */
10421
336
    if (point != NULL && out == NULL && outLen != NULL) {
10422
25
        *outLen = 1 + 2*numlen;
10423
25
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10424
25
    }
10425
10426
311
    if (point == NULL || out == NULL || outLen == NULL)
10427
0
        return ECC_BAD_ARG_E;
10428
10429
311
    if (*outLen < (1 + 2*numlen)) {
10430
20
        *outLen = 1 + 2*numlen;
10431
20
        return BUFFER_E;
10432
20
    }
10433
10434
    /* Sanity check the ordinates' sizes. */
10435
291
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
10436
268
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
10437
45
        return ECC_BAD_ARG_E;
10438
45
    }
10439
10440
    /* store byte point type */
10441
246
    out[0] = ECC_POINT_UNCOMP;
10442
10443
246
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10444
246
        return MEMORY_E);
10445
10446
    /* pad and store x */
10447
173
    XMEMSET(buf, 0, ECC_BUFSIZE);
10448
173
    ret = mp_to_unsigned_bin(point->x, buf +
10449
173
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
10450
173
    if (ret != MP_OKAY)
10451
7
        goto done;
10452
166
    XMEMCPY(out+1, buf, numlen);
10453
10454
    /* pad and store y */
10455
166
    XMEMSET(buf, 0, ECC_BUFSIZE);
10456
166
    ret = mp_to_unsigned_bin(point->y, buf +
10457
166
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
10458
166
    if (ret != MP_OKAY)
10459
11
        goto done;
10460
155
    XMEMCPY(out+1+numlen, buf, numlen);
10461
10462
155
    *outLen = 1 + 2*numlen;
10463
10464
173
done:
10465
173
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10466
10467
173
    return ret;
10468
155
}
10469
10470
10471
/* export point to der */
10472
#ifdef HAVE_COMP_KEY
10473
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
10474
                                       byte* out, word32* outLen)
10475
0
{
10476
0
    int    ret = MP_OKAY;
10477
0
    word32 numlen;
10478
0
    word32 output_len;
10479
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10480
10481
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10482
0
        return ECC_BAD_ARG_E;
10483
10484
0
    numlen = (word32)ecc_sets[curve_idx].size;
10485
0
    output_len = 1 + numlen; /* y point type + x */
10486
10487
    /* return length needed only */
10488
0
    if (point != NULL && out == NULL && outLen != NULL) {
10489
0
        *outLen = output_len;
10490
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10491
0
    }
10492
10493
0
    if (point == NULL || out == NULL || outLen == NULL)
10494
0
        return ECC_BAD_ARG_E;
10495
10496
10497
0
    if (*outLen < output_len) {
10498
0
        *outLen = output_len;
10499
0
        return BUFFER_E;
10500
0
    }
10501
10502
    /* Sanity check the ordinate's size. */
10503
0
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
10504
0
        return ECC_BAD_ARG_E;
10505
0
    }
10506
10507
    /* store byte point type */
10508
0
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
10509
0
                                            ECC_POINT_COMP_EVEN;
10510
10511
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10512
0
        return MEMORY_E);
10513
10514
    /* pad and store x */
10515
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
10516
0
    ret = mp_to_unsigned_bin(point->x, buf +
10517
0
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
10518
0
    if (ret != MP_OKAY)
10519
0
        goto done;
10520
0
    XMEMCPY(out+1, buf, numlen);
10521
10522
0
    *outLen = output_len;
10523
10524
0
done:
10525
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10526
10527
0
    return ret;
10528
0
}
10529
#endif /* HAVE_COMP_KEY */
10530
10531
/* Software-only export of public ECC key in ANSI X9.63 format.
10532
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
10533
static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10534
7.59k
{
10535
7.59k
   int    ret = MP_OKAY;
10536
7.59k
   word32 numlen;
10537
7.59k
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10538
7.59k
   word32 pubxlen, pubylen;
10539
10540
   /* return length needed only */
10541
7.59k
   if (key != NULL && out == NULL && outLen != NULL) {
10542
      /* if key hasn't been setup assume max bytes for size estimation */
10543
0
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10544
      /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10545
0
      *outLen = 1 + 2 * numlen;
10546
0
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10547
0
   }
10548
10549
7.59k
   if (key == NULL || out == NULL || outLen == NULL) {
10550
0
      return ECC_BAD_ARG_E;
10551
0
   }
10552
10553
7.59k
   if (key->type == ECC_PRIVATEKEY_ONLY) {
10554
0
       return ECC_PRIVATEONLY_E;
10555
0
   }
10556
10557
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10558
    /* check if public key in secure memory */
10559
    if (key->securePubKey > 0) {
10560
        int keySz = wc_ecc_size(key);
10561
10562
        /* store byte point type */
10563
        out[0] = ECC_POINT_UNCOMP;
10564
10565
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
10566
            return WC_HW_E;
10567
10568
        *outLen = 1 + 2*keySz;
10569
        return MP_OKAY;
10570
    }
10571
#endif
10572
10573
7.59k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
10574
1.17k
       return ECC_BAD_ARG_E;
10575
1.17k
   }
10576
10577
6.42k
   numlen = (word32)key->dp->size;
10578
10579
    /* verify room in out buffer */
10580
6.42k
   if (*outLen < (1 + 2*numlen)) {
10581
0
      *outLen = 1 + 2*numlen;
10582
0
      return BUFFER_E;
10583
0
   }
10584
10585
   /* verify public key length is less than key size */
10586
6.42k
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
10587
6.42k
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
10588
6.42k
   if ((pubxlen > numlen) || (pubylen > numlen)) {
10589
0
      WOLFSSL_MSG("Public key x/y invalid!");
10590
0
      return BUFFER_E;
10591
0
   }
10592
10593
   /* store byte point type */
10594
6.42k
   out[0] = ECC_POINT_UNCOMP;
10595
10596
6.42k
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10597
6.42k
       return MEMORY_E);
10598
10599
   /* pad and store x */
10600
6.33k
   XMEMSET(buf, 0, ECC_BUFSIZE);
10601
6.33k
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
10602
6.33k
   if (ret != MP_OKAY)
10603
3
      goto done;
10604
6.33k
   XMEMCPY(out+1, buf, numlen);
10605
10606
   /* pad and store y */
10607
6.33k
   XMEMSET(buf, 0, ECC_BUFSIZE);
10608
6.33k
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
10609
6.33k
   if (ret != MP_OKAY)
10610
4
      goto done;
10611
6.32k
   XMEMCPY(out+1+numlen, buf, numlen);
10612
10613
6.32k
   *outLen = 1 + 2*numlen;
10614
10615
6.33k
done:
10616
6.33k
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10617
10618
6.33k
   return ret;
10619
6.32k
}
10620
10621
10622
/* export public ECC key in ANSI X9.63 format */
10623
WOLFSSL_ABI
10624
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10625
10.0k
{
10626
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10627
    int ret;
10628
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
10629
#endif
10630
10631
10.0k
    if (key == NULL || outLen == NULL) {
10632
0
        return ECC_BAD_ARG_E;
10633
0
    }
10634
10635
    /* return length needed only */
10636
10.0k
    if (out == NULL) {
10637
1.63k
        word32 numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10638
        /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10639
1.63k
        *outLen = 1 + 2 * numlen;
10640
1.63k
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10641
1.63k
    }
10642
10643
8.39k
    if (key->type == ECC_PRIVATEKEY_ONLY) {
10644
122
        return ECC_PRIVATEONLY_E;
10645
122
    }
10646
10647
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10648
    #ifndef WOLF_CRYPTO_CB_FIND
10649
    if (key->devId != INVALID_DEVID)
10650
    #endif
10651
    {
10652
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
10653
        if (!WC_VAR_OK(tmpKey)) {
10654
            return MEMORY_E;
10655
        }
10656
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
10657
10658
        ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
10659
        if (ret != 0) {
10660
            WC_FREE_VAR(tmpKey, key->heap);
10661
            return ret;
10662
        }
10663
10664
        ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
10665
                                     key, tmpKey);
10666
        if (ret == 0) {
10667
            /* Call software helper (no callback recursion) */
10668
            ret = _ecc_export_x963(tmpKey, out, outLen);
10669
        }
10670
10671
        wc_ecc_free(tmpKey);
10672
        WC_FREE_VAR(tmpKey, key->heap);
10673
10674
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
10675
            return ret;
10676
        }
10677
    }
10678
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
10679
10680
8.27k
    return _ecc_export_x963(key, out, outLen);
10681
8.39k
}
10682
10683
/* export public ECC key in ANSI X9.63 format, extended with
10684
 * compression option */
10685
WOLFSSL_ABI
10686
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
10687
                          int compressed)
10688
6.45k
{
10689
6.45k
    if (compressed == 0) {
10690
3.45k
        return wc_ecc_export_x963(key, out, outLen);
10691
3.45k
    }
10692
3.00k
#ifdef HAVE_COMP_KEY
10693
3.00k
    else
10694
3.00k
        return wc_ecc_export_x963_compressed(key, out, outLen);
10695
#else
10696
    return NOT_COMPILED_IN;
10697
#endif
10698
6.45k
}
10699
#endif /* HAVE_ECC_KEY_EXPORT */
10700
10701
10702
/* is ecc point on curve described by dp ? */
10703
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10704
4.38k
{
10705
4.38k
#if !defined(WOLFSSL_SP_MATH)
10706
4.38k
   int err;
10707
4.38k
#ifdef WOLFSSL_SMALL_STACK
10708
4.38k
   mp_int* t1;
10709
4.38k
   mp_int* t2;
10710
#else
10711
   mp_int  t1[1], t2[1];
10712
#endif
10713
10714
4.38k
#ifdef WOLFSSL_SMALL_STACK
10715
4.38k
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10716
4.38k
   if (t1 == NULL)
10717
79
       return MEMORY_E;
10718
4.30k
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10719
4.30k
   if (t2 == NULL) {
10720
48
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
10721
48
       return MEMORY_E;
10722
48
   }
10723
4.25k
#endif
10724
10725
4.25k
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
10726
0
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10727
0
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10728
0
      return err;
10729
0
   }
10730
10731
   /* compute y^2 */
10732
4.25k
   if (err == MP_OKAY)
10733
4.25k
       err = mp_sqr(ecp->y, t1);
10734
10735
   /* compute x^3 */
10736
4.25k
   if (err == MP_OKAY)
10737
4.23k
       err = mp_sqr(ecp->x, t2);
10738
4.25k
   if (err == MP_OKAY)
10739
4.21k
       err = mp_mod(t2, prime, t2);
10740
4.25k
   if (err == MP_OKAY)
10741
4.20k
       err = mp_mul(ecp->x, t2, t2);
10742
10743
   /* compute y^2 - x^3 */
10744
4.25k
   if (err == MP_OKAY)
10745
4.19k
       err = mp_submod(t1, t2, prime, t1);
10746
10747
   /* Determine if curve "a" should be used in calc */
10748
4.25k
#ifdef WOLFSSL_CUSTOM_CURVES
10749
4.25k
   if (err == MP_OKAY) {
10750
      /* Use a and prime to determine if a == 3 */
10751
4.18k
      err = mp_set(t2, 0);
10752
4.18k
      if (err == MP_OKAY)
10753
4.18k
          err = mp_submod(prime, a, prime, t2);
10754
4.18k
   }
10755
4.25k
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
10756
      /* compute y^2 - x^3 + a*x */
10757
1.91k
      if (err == MP_OKAY)
10758
1.91k
          err = mp_mulmod(t2, ecp->x, prime, t2);
10759
1.91k
      if (err == MP_OKAY)
10760
1.89k
          err = mp_addmod(t1, t2, prime, t1);
10761
1.91k
   }
10762
2.34k
   else
10763
2.34k
#endif /* WOLFSSL_CUSTOM_CURVES */
10764
2.34k
   {
10765
      /* assumes "a" == 3 */
10766
2.34k
      (void)a;
10767
10768
      /* compute y^2 - x^3 + 3x */
10769
2.34k
      if (err == MP_OKAY)
10770
2.27k
          err = mp_add(t1, ecp->x, t1);
10771
2.34k
      if (err == MP_OKAY)
10772
2.27k
          err = mp_add(t1, ecp->x, t1);
10773
2.34k
      if (err == MP_OKAY)
10774
2.27k
          err = mp_add(t1, ecp->x, t1);
10775
2.34k
      if (err == MP_OKAY)
10776
2.27k
          err = mp_mod(t1, prime, t1);
10777
2.34k
  }
10778
10779
   /* adjust range (0, prime) */
10780
4.25k
   while (err == MP_OKAY && mp_isneg(t1)) {
10781
0
      err = mp_add(t1, prime, t1);
10782
0
   }
10783
4.25k
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
10784
0
      err = mp_sub(t1, prime, t1);
10785
0
   }
10786
10787
   /* compare to b */
10788
4.25k
   if (err == MP_OKAY) {
10789
4.16k
       if (mp_cmp(t1, b) != MP_EQ) {
10790
1.34k
          err = IS_POINT_E;
10791
2.81k
       } else {
10792
2.81k
          err = MP_OKAY;
10793
2.81k
       }
10794
4.16k
   }
10795
10796
4.25k
   mp_clear(t1);
10797
4.25k
   mp_clear(t2);
10798
10799
4.25k
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10800
4.25k
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10801
10802
4.25k
   return err;
10803
#else
10804
   (void)a;
10805
   (void)b;
10806
10807
#ifdef WOLFSSL_HAVE_SP_ECC
10808
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10809
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10810
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10811
   }
10812
#endif
10813
#ifndef WOLFSSL_SP_NO_256
10814
   if (mp_count_bits(prime) == 256) {
10815
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10816
   }
10817
#endif
10818
#ifdef WOLFSSL_SP_384
10819
   if (mp_count_bits(prime) == 384) {
10820
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10821
   }
10822
#endif
10823
#ifdef WOLFSSL_SP_521
10824
   if (mp_count_bits(prime) == 521) {
10825
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10826
   }
10827
#endif
10828
#else
10829
   (void)ecp;
10830
   (void)prime;
10831
#endif
10832
   return WC_KEY_SIZE_E;
10833
#endif
10834
4.25k
}
10835
10836
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10837
3.78k
{
10838
3.78k
    int err = MP_OKAY;
10839
10840
    /* Validate parameters. */
10841
3.78k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10842
0
        err = BAD_FUNC_ARG;
10843
0
    }
10844
10845
3.78k
    if (err == MP_OKAY) {
10846
        /* x must be in the range [0, p-1] */
10847
3.78k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10848
505
            err = ECC_OUT_OF_RANGE_E;
10849
505
        }
10850
3.78k
    }
10851
10852
3.78k
    if (err == MP_OKAY) {
10853
        /* y must be in the range [0, p-1] */
10854
3.28k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10855
143
            err = ECC_OUT_OF_RANGE_E;
10856
143
        }
10857
3.28k
    }
10858
10859
3.78k
    if (err == MP_OKAY) {
10860
        /* z must be one, that is point must be in affine form. */
10861
3.14k
        if (!mp_isone(ecp->z)) {
10862
276
            err = ECC_BAD_ARG_E;
10863
276
        }
10864
3.14k
    }
10865
10866
3.78k
    if (err == MP_OKAY) {
10867
        /* Check x and y are valid for curve equation. */
10868
2.86k
        err = _ecc_is_point(ecp, a, b, prime);
10869
2.86k
    }
10870
10871
3.78k
    return err;
10872
3.78k
}
10873
10874
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
10875
10876
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10877
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10878
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10879
/* validate privkey * generator == pubkey, 0 on success */
10880
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10881
{
10882
    int        err;
10883
    ecc_point* base = NULL;
10884
    ecc_point* res  = NULL;
10885
#ifdef WOLFSSL_NO_MALLOC
10886
    ecc_point lcl_base;
10887
    ecc_point lcl_res;
10888
#endif
10889
    DECLARE_CURVE_SPECS(3);
10890
10891
    if (key == NULL)
10892
        return BAD_FUNC_ARG;
10893
10894
    ALLOC_CURVE_SPECS(3, err);
10895
    if (err != MP_OKAY) {
10896
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10897
        return err;
10898
    }
10899
10900
#ifdef WOLFSSL_NO_MALLOC
10901
    res = &lcl_res;
10902
#endif
10903
    err = wc_ecc_new_point_ex(&res, key->heap);
10904
10905
#ifdef WOLFSSL_HAVE_SP_ECC
10906
#ifndef WOLFSSL_SP_NO_256
10907
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10908
        if (err == MP_OKAY) {
10909
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10910
        }
10911
    }
10912
    else
10913
#endif
10914
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10915
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10916
        if (err == MP_OKAY) {
10917
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10918
        }
10919
    }
10920
    else
10921
#endif
10922
#ifdef WOLFSSL_SP_384
10923
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10924
        if (err == MP_OKAY) {
10925
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10926
        }
10927
    }
10928
    else
10929
#endif
10930
#ifdef WOLFSSL_SP_521
10931
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10932
        if (err == MP_OKAY) {
10933
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10934
        }
10935
    }
10936
    else
10937
#endif
10938
#endif
10939
    {
10940
        if (err == MP_OKAY) {
10941
        #ifdef WOLFSSL_NO_MALLOC
10942
            base = &lcl_base;
10943
        #endif
10944
            err = wc_ecc_new_point_ex(&base, key->heap);
10945
        }
10946
10947
        if (err == MP_OKAY) {
10948
            /* load curve info */
10949
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10950
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10951
        }
10952
10953
        /* set up base generator */
10954
        if (err == MP_OKAY)
10955
            err = mp_copy(curve->Gx, base->x);
10956
        if (err == MP_OKAY)
10957
            err = mp_copy(curve->Gy, base->y);
10958
        if (err == MP_OKAY)
10959
            err = mp_set(base->z, 1);
10960
10961
#ifdef WOLFSSL_KCAPI_ECC
10962
        if (err == MP_OKAY) {
10963
            word32 pubkey_sz = (word32)key->dp->size*2;
10964
            if (key->handle == NULL) {
10965
                /* if handle loaded, then pubkey_raw already populated */
10966
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10967
            }
10968
            if (err == 0) {
10969
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10970
                                           pubkey_sz/2);
10971
            }
10972
            if (err == MP_OKAY) {
10973
                err = mp_read_unsigned_bin(res->y,
10974
                                           key->pubkey_raw + pubkey_sz/2,
10975
                                           pubkey_sz/2);
10976
            }
10977
            if (err == MP_OKAY) {
10978
                err = mp_set(res->z, 1);
10979
            }
10980
        }
10981
        (void)a;
10982
        (void)prime;
10983
#else
10984
#ifdef ECC_TIMING_RESISTANT
10985
        if (err == MP_OKAY)
10986
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10987
                                          curve->order, key->rng, 1, key->heap);
10988
#else
10989
        if (err == MP_OKAY)
10990
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10991
                                              curve->order, NULL, 1, key->heap);
10992
#endif
10993
#endif /* WOLFSSL_KCAPI_ECC */
10994
    }
10995
10996
    if (err == MP_OKAY) {
10997
        /* compare result to public key */
10998
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10999
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
11000
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
11001
            /* didn't match */
11002
            err = ECC_PRIV_KEY_E;
11003
        }
11004
    }
11005
11006
    wc_ecc_curve_free(curve);
11007
    wc_ecc_del_point_ex(res, key->heap);
11008
    wc_ecc_del_point_ex(base, key->heap);
11009
    FREE_CURVE_SPECS();
11010
11011
    return err;
11012
}
11013
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
11014
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
11015
11016
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
11017
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
11018
11019
/* check privkey generator helper, creates prime needed */
11020
static int ecc_check_privkey_gen_helper(ecc_key* key)
11021
{
11022
    int    err;
11023
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11024
    !defined(WOLFSSL_MICROCHIP_TA100)
11025
    DECLARE_CURVE_SPECS(2);
11026
#endif
11027
11028
    if (key == NULL)
11029
        return BAD_FUNC_ARG;
11030
11031
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11032
    defined(WOLFSSL_MICROCHIP_TA100)
11033
    /* Hardware based private key, so this operation is not supported */
11034
    err = MP_OKAY; /* just report success */
11035
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11036
    /* Hardware based private key, so this operation is not supported */
11037
    err = MP_OKAY; /* just report success */
11038
#elif defined(WOLFSSL_KCAPI_ECC)
11039
    /* Hardware based private key, so this operation is not supported */
11040
    err = MP_OKAY; /* just report success */
11041
#else
11042
    ALLOC_CURVE_SPECS(2, err);
11043
11044
    /* load curve info */
11045
    if (err == MP_OKAY)
11046
        err = wc_ecc_curve_load(key->dp, &curve,
11047
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
11048
11049
    if (err == MP_OKAY)
11050
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11051
11052
    wc_ecc_curve_free(curve);
11053
    FREE_CURVE_SPECS();
11054
11055
#endif /* WOLFSSL_ATECC508A */
11056
11057
    return err;
11058
}
11059
11060
/* Performs a Pairwise Consistency Test on an ECC key pair. */
11061
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
11062
{
11063
    int err = 0;
11064
    word32 flags = key->flags;
11065
11066
    /* If flags not set default to cofactor and dec/sign */
11067
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
11068
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
11069
    }
11070
11071
    if (flags & WC_ECC_FLAG_COFACTOR) {
11072
        err = ecc_check_privkey_gen_helper(key);
11073
    }
11074
11075
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
11076
#ifndef WOLFSSL_SMALL_STACK
11077
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
11078
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
11079
#else
11080
        byte* sig;
11081
#endif
11082
        byte* digest;
11083
        word32 sigLen, digestLen;
11084
        int dynRng = 0, res = 0;
11085
11086
        sigLen = (word32)wc_ecc_sig_size(key);
11087
        digestLen = WC_SHA256_DIGEST_SIZE;
11088
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
11089
            DYNAMIC_TYPE_ECC, return MEMORY_E);
11090
        digest = sig + sigLen;
11091
11092
        if (rng == NULL) {
11093
            dynRng = 1;
11094
            rng = wc_rng_new(NULL, 0, key->heap);
11095
            if (rng == NULL) {
11096
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11097
                return MEMORY_E;
11098
            }
11099
        }
11100
11101
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
11102
11103
        if (!err)
11104
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
11105
                    rng, key);
11106
        if (!err)
11107
            err = wc_ecc_verify_hash(sig, sigLen,
11108
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
11109
11110
        if (res == 0)
11111
            err = ECC_PCT_E;
11112
11113
        if (dynRng) {
11114
            wc_rng_free(rng);
11115
        }
11116
        ForceZero(sig, sigLen + digestLen);
11117
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11118
    }
11119
    (void)rng;
11120
11121
    if (err != 0)
11122
        err = ECC_PCT_E;
11123
11124
    return err;
11125
}
11126
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
11127
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
11128
11129
#ifndef WOLFSSL_SP_MATH
11130
/* validate order * pubkey = point at infinity, 0 on success */
11131
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
11132
        mp_int* prime, mp_int* order)
11133
3.57k
{
11134
3.57k
    ecc_point* inf = NULL;
11135
#ifdef WOLFSSL_NO_MALLOC
11136
    ecc_point  lcl_inf;
11137
#endif
11138
3.57k
    int err;
11139
11140
3.57k
    if (key == NULL)
11141
0
        return BAD_FUNC_ARG;
11142
3.57k
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
11143
3.57k
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
11144
3.57k
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
11145
0
       return IS_POINT_E;
11146
0
   }
11147
11148
#ifdef WOLFSSL_NO_MALLOC
11149
    inf = &lcl_inf;
11150
#endif
11151
3.57k
    err = wc_ecc_new_point_ex(&inf, key->heap);
11152
3.57k
    if (err == MP_OKAY) {
11153
#ifdef WOLFSSL_HAVE_SP_ECC
11154
#ifndef WOLFSSL_SP_NO_256
11155
        if (key->idx != ECC_CUSTOM_IDX &&
11156
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
11157
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
11158
        }
11159
        else
11160
#endif
11161
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11162
        if (key->idx != ECC_CUSTOM_IDX &&
11163
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
11164
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
11165
        }
11166
        else
11167
#endif
11168
#ifdef WOLFSSL_SP_384
11169
        if (key->idx != ECC_CUSTOM_IDX &&
11170
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
11171
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
11172
        }
11173
        else
11174
#endif
11175
#ifdef WOLFSSL_SP_521
11176
        if (key->idx != ECC_CUSTOM_IDX &&
11177
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
11178
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
11179
        }
11180
        else
11181
#endif
11182
#endif
11183
3.56k
#if !defined(WOLFSSL_SP_MATH)
11184
3.56k
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
11185
3.56k
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
11186
19
            err = ECC_INF_E;
11187
#else
11188
        {
11189
            (void)a;
11190
            (void)prime;
11191
11192
            err = WC_KEY_SIZE_E;
11193
        }
11194
#endif
11195
3.56k
    }
11196
11197
3.57k
    wc_ecc_del_point_ex(inf, key->heap);
11198
11199
3.57k
    return err;
11200
3.57k
}
11201
#endif /* !WOLFSSL_SP_MATH */
11202
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11203
11204
11205
#ifdef OPENSSL_EXTRA
11206
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
11207
{
11208
    int err = MP_OKAY;
11209
    DECLARE_CURVE_SPECS(2);
11210
11211
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
11212
        return BAD_FUNC_ARG;
11213
11214
    ALLOC_CURVE_SPECS(2, err);
11215
11216
    if (err == MP_OKAY)
11217
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
11218
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
11219
    if (err == MP_OKAY)
11220
        err = mp_copy(curve->Gx, ecp->x);
11221
    if (err == MP_OKAY)
11222
        err = mp_copy(curve->Gy, ecp->y);
11223
    if (err == MP_OKAY)
11224
        err = mp_set(ecp->z, 1);
11225
11226
    wc_ecc_curve_free(curve);
11227
    FREE_CURVE_SPECS();
11228
11229
    return err;
11230
}
11231
#endif /* OPENSSL_EXTRA */
11232
11233
11234
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
11235
 * ECC Full Public Key Validation Routine. If the parameter
11236
 * partial is set, then it follows section 5.6.2.3.4, the ECC
11237
 * Partial Public Key Validation Routine.
11238
 * If the parameter priv is set, add in a few extra
11239
 * checks on the bounds of the private key. */
11240
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
11241
1.64k
{
11242
1.64k
    int err = MP_OKAY;
11243
1.64k
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
11244
1.64k
    mp_int* b = NULL;
11245
1.64k
    DECLARE_CURVE_SPECS(4);
11246
1.64k
#endif
11247
11248
1.64k
    if (key == NULL)
11249
0
        return BAD_FUNC_ARG;
11250
11251
1.64k
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_CHECK_KEY) && \
11252
1.64k
    !defined(WOLFSSL_CAAM)
11253
    /* Device-first: when a device is configured, let it validate the public
11254
     * key. Fall through to the software/HW path below only when the
11255
     * device reports the operation unavailable.
11256
     * CAAM is excluded: it relies on the software order-check below to detect
11257
     * whether an imported private key is an encrypted black key. */
11258
1.64k
    #ifndef WOLF_CRYPTO_CB_FIND
11259
1.64k
    if (key->devId != INVALID_DEVID)
11260
0
    #endif
11261
0
    {
11262
0
        err = wc_CryptoCb_EccCheckPubKey(key, !partial, priv);
11263
0
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11264
0
            return err;
11265
        /* device declined; fall through. Every software/HW path below
11266
         * re-initializes err before reading it, so no reset is needed here. */
11267
0
    }
11268
1.64k
#endif
11269
11270
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
11271
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
11272
    /* Software validation is stripped; the device-first check above either
11273
     * handled the key or reported the op unavailable, so fail closed rather
11274
     * than accept an unvalidated key. */
11275
    err = NO_VALID_DEVID;
11276
#else
11277
    /* consider key check success on HW crypto
11278
     * ex: ATECC508/608A, CryptoCell and Silabs which validate the key
11279
     * internally
11280
     */
11281
    err = MP_OKAY;
11282
#endif
11283
11284
#else
11285
11286
#ifdef WOLFSSL_HAVE_SP_ECC
11287
#ifndef WOLFSSL_SP_NO_256
11288
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
11289
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
11290
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11291
    }
11292
#endif
11293
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11294
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
11295
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
11296
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11297
    }
11298
#endif
11299
#ifdef WOLFSSL_SP_384
11300
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
11301
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
11302
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11303
    }
11304
#endif
11305
#ifdef WOLFSSL_SP_521
11306
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
11307
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
11308
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11309
    }
11310
#endif
11311
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
11312
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
11313
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
11314
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11315
    }
11316
#endif
11317
#endif
11318
11319
1.64k
#ifndef WOLFSSL_SP_MATH
11320
1.64k
    ALLOC_CURVE_SPECS(4, err);
11321
11322
    #ifdef WOLFSSL_CAAM
11323
    /* keys can be black encrypted ones which can not be checked like plain text
11324
     * keys */
11325
    if (key->blackKey > 0) {
11326
        /* encrypted key was used */
11327
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11328
        FREE_CURVE_SPECS();
11329
        return 0;
11330
    }
11331
    #endif
11332
11333
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
11334
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
11335
    /* pubkey point cannot be at infinity */
11336
1.64k
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11337
0
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11338
0
        FREE_CURVE_SPECS();
11339
0
        return ECC_INF_E;
11340
0
    }
11341
11342
    /* load curve info */
11343
1.64k
    if (err == MP_OKAY)
11344
1.54k
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
11345
1.54k
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER | ECC_CURVE_FIELD_BF));
11346
11347
1.64k
    if (err == MP_OKAY)
11348
1.54k
        b = curve->Bf;
11349
11350
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
11351
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
11352
    /* Qx must be in the range [0, p-1] */
11353
1.64k
    if (err == MP_OKAY) {
11354
1.54k
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
11355
1.52k
                mp_isneg(key->pubkey.x)) {
11356
13
            err = ECC_OUT_OF_RANGE_E;
11357
13
        }
11358
1.54k
    }
11359
11360
    /* Qy must be in the range [0, p-1] */
11361
1.64k
    if (err == MP_OKAY) {
11362
1.52k
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
11363
1.51k
                mp_isneg(key->pubkey.y)) {
11364
11
            err = ECC_OUT_OF_RANGE_E;
11365
11
        }
11366
1.52k
    }
11367
11368
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
11369
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
11370
    /* make sure point is actually on curve */
11371
1.64k
    if (err == MP_OKAY)
11372
1.51k
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
11373
11374
1.64k
    if (!partial) {
11375
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
11376
        /* pubkey * order must be at infinity */
11377
1.64k
        if (err == MP_OKAY)
11378
979
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
11379
979
                    curve->prime, curve->order);
11380
1.64k
    }
11381
11382
1.64k
    if (priv) {
11383
        /* SP 800-56Ar3, section 5.6.2.1.2 */
11384
        /* private keys must be in the range [1, n-1] */
11385
1.64k
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
11386
244
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
11387
244
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
11388
        #ifdef WOLFSSL_KCAPI_ECC
11389
            && key->handle == NULL
11390
        #endif
11391
1.64k
        ) {
11392
0
            err = ECC_PRIV_KEY_E;
11393
0
        }
11394
11395
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
11396
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
11397
        /* private * base generator must equal pubkey */
11398
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
11399
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11400
    #endif
11401
1.64k
    }
11402
11403
1.64k
    wc_ecc_curve_free(curve);
11404
11405
1.64k
    FREE_CURVE_SPECS();
11406
11407
#else
11408
    /* The single precision math curve is not available */
11409
    err = WC_KEY_SIZE_E;
11410
#endif /* !WOLFSSL_SP_MATH */
11411
1.64k
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11412
11413
1.64k
    (void)partial;
11414
1.64k
    (void)priv;
11415
1.64k
    return err;
11416
1.64k
}
11417
11418
11419
/* perform sanity checks on ecc key validity, 0 on success */
11420
WOLFSSL_ABI
11421
int wc_ecc_check_key(ecc_key* key)
11422
11.7k
{
11423
11.7k
    int ret;
11424
    /* _ecc_validate_public_key is the single validation entry point: it is
11425
     * device-first (offloads to the crypto callback when a device is
11426
     * configured) and otherwise runs the software/HW checks, or fails closed
11427
     * under WOLF_CRYPTO_CB_ONLY_ECC. */
11428
11.7k
    ret = _ecc_validate_public_key(key, 0, 1);
11429
11.7k
    return ret;
11430
11.7k
}
11431
11432
11433
#ifdef HAVE_ECC_KEY_IMPORT
11434
/* Software-only import of public ECC key in ANSI X9.63 format.
11435
 * This internal helper avoids recursion when called from the SETKEY path. */
11436
static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11437
                                int curve_id, int untrusted)
11438
804
{
11439
804
    int err = MP_OKAY;
11440
804
#ifdef HAVE_COMP_KEY
11441
804
    int compressed = 0;
11442
804
#endif
11443
804
    int keysize = 0;
11444
804
    byte pointType;
11445
#ifdef WOLFSSL_CRYPTOCELL
11446
    const CRYS_ECPKI_Domain_t* pDomain;
11447
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11448
#endif
11449
11450
804
    if (in == NULL || key == NULL) {
11451
0
        return BAD_FUNC_ARG;
11452
0
    }
11453
11454
    /* must be odd */
11455
804
    if ((inLen & 1) == 0) {
11456
0
        return ECC_BAD_ARG_E;
11457
0
    }
11458
11459
    /* make sure required variables are reset */
11460
804
    wc_ecc_reset(key);
11461
11462
    /* init key */
11463
    #ifdef ALT_ECC_SIZE
11464
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11465
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11466
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11467
        alt_fp_init(key->pubkey.x);
11468
        alt_fp_init(key->pubkey.y);
11469
        alt_fp_init(key->pubkey.z);
11470
        key->k = (mp_int*)key->ka;
11471
        alt_fp_init(key->k);
11472
    #ifdef WOLFSSL_ECC_BLIND_K
11473
        key->kb = (mp_int*)key->kba;
11474
        key->ku = (mp_int*)key->kua;
11475
        alt_fp_init(key->kb);
11476
        alt_fp_init(key->ku);
11477
    #endif
11478
    #else
11479
804
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11480
804
    #ifndef WOLFSSL_ECC_BLIND_K
11481
804
                                                                      NULL, NULL
11482
    #else
11483
                                                                key->kb, key->ku
11484
    #endif
11485
804
                            );
11486
11487
804
        if (err != MP_OKAY)
11488
0
            return MEMORY_E;
11489
804
    #endif
11490
#ifdef WOLFSSL_ECC_BLIND_K
11491
    mp_forcezero(key->kb);
11492
#endif
11493
11494
    /* check for point type (4, 2, or 3) */
11495
804
    pointType = in[0];
11496
804
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
11497
342
                                         pointType != ECC_POINT_COMP_ODD) {
11498
30
        err = ASN_PARSE_E;
11499
30
    }
11500
11501
804
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
11502
687
    #ifdef HAVE_COMP_KEY
11503
687
        compressed = 1;
11504
    #else
11505
        err = NOT_COMPILED_IN;
11506
    #endif
11507
687
    }
11508
11509
    /* adjust to skip first byte */
11510
804
    inLen -= 1;
11511
804
    in += 1;
11512
11513
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11514
    defined(WOLFSSL_MICROCHIP_TA100)
11515
    /* For SECP256R1 only save raw public key for hardware */
11516
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
11517
    #ifdef HAVE_COMP_KEY
11518
        if (!compressed)
11519
    #endif
11520
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11521
    }
11522
#elif defined(WOLFSSL_KCAPI_ECC)
11523
    if (inLen <= (word32)sizeof(key->pubkey_raw))
11524
        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11525
    else
11526
        err = BAD_FUNC_ARG;
11527
#endif
11528
11529
804
    if (err == MP_OKAY) {
11530
774
    #ifdef HAVE_COMP_KEY
11531
        /* adjust inLen if compressed */
11532
774
        if (compressed) {
11533
            /* a compressed coordinate cannot exceed MAX_ECC_BYTES; bound it
11534
             * before doubling so inLen*2 + 1 cannot overflow word32. */
11535
687
            if (inLen > MAX_ECC_BYTES)
11536
0
                err = ECC_BAD_ARG_E;
11537
687
            else
11538
687
                inLen = inLen*2 + 1;  /* used uncompressed len */
11539
687
        }
11540
774
    #endif
11541
11542
        /* determine key size */
11543
774
        if (err == MP_OKAY) {
11544
774
            keysize = (int)(inLen>>1);
11545
            /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys,
11546
             *       only on created keys or signatures */
11547
774
            err = wc_ecc_set_curve(key, keysize, curve_id);
11548
774
            key->type = ECC_PUBLICKEY;
11549
774
        }
11550
774
    }
11551
11552
    /* read data */
11553
804
    if (err == MP_OKAY)
11554
774
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
11555
11556
804
#ifdef HAVE_COMP_KEY
11557
804
    if (err == MP_OKAY && compressed == 1) {   /* build y */
11558
687
#if !defined(WOLFSSL_SP_MATH)
11559
687
    #ifdef WOLFSSL_SMALL_STACK
11560
687
        mp_int* t1 = NULL;
11561
687
        mp_int* t2 = NULL;
11562
    #else
11563
        mp_int t1[1], t2[1];
11564
    #endif
11565
687
        int did_init = 0;
11566
11567
687
        DECLARE_CURVE_SPECS(3);
11568
687
        ALLOC_CURVE_SPECS(3, err);
11569
11570
687
        #ifdef WOLFSSL_SMALL_STACK
11571
687
        if (err == MP_OKAY) {
11572
634
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11573
634
            if (t1 == NULL) {
11574
23
                err = MEMORY_E;
11575
23
            }
11576
634
        }
11577
687
        if (err == MP_OKAY) {
11578
611
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11579
611
            if (t2 == NULL) {
11580
28
                err = MEMORY_E;
11581
28
            }
11582
611
        }
11583
687
        #endif
11584
687
        if (err == MP_OKAY) {
11585
583
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
11586
0
                err = MEMORY_E;
11587
583
            else
11588
583
                did_init = 1;
11589
583
        }
11590
11591
        /* load curve info */
11592
687
        if (err == MP_OKAY)
11593
583
            err = wc_ecc_curve_load(key->dp, &curve,
11594
583
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
11595
583
                 ECC_CURVE_FIELD_BF));
11596
11597
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
11598
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
11599
        /* validate prime is prime for custom curves */
11600
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
11601
            int isPrime = MP_NO;
11602
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
11603
            if (err == MP_OKAY && isPrime == MP_NO)
11604
                err = MP_VAL;
11605
        }
11606
    #endif
11607
11608
        /* compute x^3 */
11609
687
        if (err == MP_OKAY)
11610
583
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
11611
687
        if (err == MP_OKAY)
11612
572
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
11613
11614
        /* compute x^3 + a*x */
11615
687
        if (err == MP_OKAY)
11616
568
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
11617
687
        if (err == MP_OKAY)
11618
558
            err = mp_add(t1, t2, t1);
11619
11620
        /* compute x^3 + a*x + b */
11621
687
        if (err == MP_OKAY)
11622
558
            err = mp_add(t1, curve->Bf, t1);
11623
11624
        /* compute sqrt(x^3 + a*x + b) */
11625
687
        if (err == MP_OKAY)
11626
558
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
11627
11628
        /* adjust y */
11629
687
        if (err == MP_OKAY) {
11630
255
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
11631
203
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
11632
120
                err = mp_mod(t2, curve->prime, t2);
11633
120
            }
11634
135
            else {
11635
135
                err = mp_submod(curve->prime, t2, curve->prime, t2);
11636
135
            }
11637
255
            if (err == MP_OKAY)
11638
254
                err = mp_copy(t2, key->pubkey.y);
11639
255
        }
11640
11641
687
        if (did_init) {
11642
583
            mp_clear(t2);
11643
583
            mp_clear(t1);
11644
583
        }
11645
687
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
11646
687
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
11647
11648
687
        wc_ecc_curve_free(curve);
11649
687
        FREE_CURVE_SPECS();
11650
#else
11651
    #ifndef WOLFSSL_SP_NO_256
11652
        if (key->dp->id == ECC_SECP256R1) {
11653
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
11654
                key->pubkey.y);
11655
        }
11656
        else
11657
    #endif
11658
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11659
        if (key->dp->id == ECC_SM2P256V1) {
11660
            err = sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
11661
        }
11662
        else
11663
    #endif
11664
    #ifdef WOLFSSL_SP_384
11665
        if (key->dp->id == ECC_SECP384R1) {
11666
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
11667
                key->pubkey.y);
11668
        }
11669
        else
11670
    #endif
11671
    #ifdef WOLFSSL_SP_521
11672
        if (key->dp->id == ECC_SECP521R1) {
11673
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
11674
                key->pubkey.y);
11675
        }
11676
        else
11677
    #endif
11678
        {
11679
            err = WC_KEY_SIZE_E;
11680
        }
11681
#endif
11682
687
    }
11683
804
#endif /* HAVE_COMP_KEY */
11684
11685
804
    if (err == MP_OKAY) {
11686
341
    #ifdef HAVE_COMP_KEY
11687
341
        if (compressed == 0)
11688
87
    #endif
11689
87
        {
11690
87
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
11691
87
                (word32)keysize);
11692
87
        }
11693
341
    }
11694
804
    if (err == MP_OKAY)
11695
341
        err = mp_set(key->pubkey.z, 1);
11696
11697
#ifdef WOLFSSL_CRYPTOCELL
11698
    if (err == MP_OKAY) {
11699
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11700
11701
        /* create public key from external key buffer */
11702
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11703
                                               (byte*)in-1, /* re-adjust */
11704
                                               inLen+1,     /* original input */
11705
                                               &key->ctx.pubKey,
11706
                                               &tempBuff);
11707
11708
        if (err != SA_SILIB_RET_OK){
11709
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11710
        }
11711
    }
11712
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11713
    if (err == MP_OKAY)
11714
        err = silabs_ecc_import(key, keysize, 1, 0);
11715
#elif defined(WOLFSSL_SE050)
11716
    if (err == MP_OKAY) {
11717
        /* reset key ID, in case used before */
11718
        key->keyId = 0;
11719
        key->keyIdSet = 0;
11720
    }
11721
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11722
    #ifndef HAVE_COMP_KEY
11723
    if (err == MP_OKAY) {
11724
    #else
11725
    if (err == MP_OKAY && !compressed) {
11726
    #endif
11727
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
11728
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
11729
    }
11730
#endif
11731
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11732
    if (err == MP_OKAY)
11733
        err = wc_ecc_check_key(key);
11734
#endif
11735
804
#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
11736
804
     !defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
11737
804
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11738
804
     !defined(WOLFSSL_CRYPTOCELL) && \
11739
804
     (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
11740
804
       defined(WOLFSSL_IMXRT1170_CAAM))
11741
804
    if ((err == MP_OKAY) && untrusted) {
11742
        /* Reject point at infinity. */
11743
341
        if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11744
0
            err = ECC_INF_E;
11745
0
        }
11746
        /* Verify the point lies on the curve (y^2 = x^3 + ax + b mod p) */
11747
341
        if ((err == MP_OKAY) && (key->idx != ECC_CUSTOM_IDX)) {
11748
    #ifdef WOLFSSL_HAVE_SP_ECC
11749
        #ifndef WOLFSSL_SP_NO_256
11750
            if (ecc_sets[key->idx].id == ECC_SECP256R1) {
11751
                err = sp_ecc_is_point_256(key->pubkey.x, key->pubkey.y);
11752
            #if defined(WOLFSSL_SM2)
11753
                if (err != MP_OKAY && curve_id < 0) {
11754
                    /* Retry with SM2 curve when P-256 returns invalid.
11755
                     * Only when no explicit curve was requested (curve_id < 0).
11756
                     * Needed because SM2 keys can be mis-identified as
11757
                     * SECP256R1 during parsing. */
11758
                #if defined(WOLFSSL_SP_SM2)
11759
                    err = sp_ecc_is_point_sm2_256(key->pubkey.x,
11760
                                                  key->pubkey.y);
11761
                #else
11762
                    int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11763
                    if (sm2_idx != ECC_CURVE_INVALID)
11764
                        err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11765
                #endif
11766
                    if (err == MP_OKAY) {
11767
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11768
                                               ECC_SM2P256V1);
11769
                    }
11770
                }
11771
            #endif
11772
            }
11773
            else
11774
        #endif
11775
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11776
            if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
11777
                err = sp_ecc_is_point_sm2_256(key->pubkey.x, key->pubkey.y);
11778
            }
11779
            else
11780
        #endif
11781
        #ifdef WOLFSSL_SP_384
11782
            if (ecc_sets[key->idx].id == ECC_SECP384R1) {
11783
                err = sp_ecc_is_point_384(key->pubkey.x, key->pubkey.y);
11784
            }
11785
            else
11786
        #endif
11787
        #ifdef WOLFSSL_SP_521
11788
            if (ecc_sets[key->idx].id == ECC_SECP521R1) {
11789
                err = sp_ecc_is_point_521(key->pubkey.x, key->pubkey.y);
11790
            }
11791
            else
11792
        #endif
11793
            {
11794
                err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11795
            }
11796
    #else
11797
341
            err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11798
341
        #if defined(WOLFSSL_SM2)
11799
341
            if (err != MP_OKAY && curve_id < 0) {
11800
                /* Retry with SM2 curve when P-256 returns invalid.
11801
                 * Only when no explicit curve was requested (curve_id < 0).
11802
                 * Needed because SM2 keys can be mis-identified as
11803
                 * SECP256R1 during parsing. */
11804
0
                int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11805
0
                if (sm2_idx != ECC_CURVE_INVALID) {
11806
0
                    err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11807
0
                    if (err == MP_OKAY) {
11808
0
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11809
0
                                               ECC_SM2P256V1);
11810
0
                    }
11811
0
                }
11812
0
            }
11813
341
        #endif
11814
341
    #endif /* WOLFSSL_HAVE_SP_ECC */
11815
341
        }
11816
341
    }
11817
804
#endif
11818
804
    (void)untrusted;
11819
11820
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11821
    if (err == MP_OKAY) {
11822
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
11823
    }
11824
#endif
11825
11826
804
    if (err != MP_OKAY) {
11827
511
        mp_clear(key->pubkey.x);
11828
511
        mp_clear(key->pubkey.y);
11829
511
        mp_clear(key->pubkey.z);
11830
511
        mp_forcezero(key->k);
11831
511
    }
11832
11833
804
    return err;
11834
804
}
11835
11836
/* import public ECC key in ANSI X9.63 format */
11837
int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11838
                           int curve_id, int untrusted)
11839
4.43k
{
11840
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11841
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
11842
    int err = 0;
11843
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11844
#endif
11845
11846
4.43k
    if (in == NULL || key == NULL) {
11847
0
        return BAD_FUNC_ARG;
11848
0
    }
11849
11850
    /* must be odd */
11851
4.43k
    if ((inLen & 1) == 0) {
11852
125
        return ECC_BAD_ARG_E;
11853
125
    }
11854
11855
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11856
    #ifndef WOLF_CRYPTO_CB_FIND
11857
    if (key->devId != INVALID_DEVID)
11858
    #endif
11859
    {
11860
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11861
        if (!WC_VAR_OK(tmpKey)) {
11862
            return MEMORY_E;
11863
        }
11864
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11865
11866
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11867
        if (err != 0) {
11868
            WC_FREE_VAR(tmpKey, key->heap);
11869
            return err;
11870
        }
11871
11872
    #ifdef WOLFSSL_CUSTOM_CURVES
11873
        if (key->dp != NULL) {
11874
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
11875
            if (err != 0) {
11876
                wc_ecc_free(tmpKey);
11877
                WC_FREE_VAR(tmpKey, key->heap);
11878
                return err;
11879
            }
11880
        }
11881
    #endif
11882
11883
        /* Import into temp via software helper (no callback recursion) */
11884
        err = _ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted);
11885
        if (err == MP_OKAY) {
11886
            cbRet = wc_CryptoCb_SetKey(key->devId,
11887
                WC_SETKEY_ECC_PUB, key, tmpKey,
11888
                wc_ecc_size(tmpKey), NULL, 0, 0);
11889
        }
11890
11891
        wc_ecc_free(tmpKey);
11892
        WC_FREE_VAR(tmpKey, key->heap);
11893
11894
        if (err != MP_OKAY) {
11895
            return err;
11896
        }
11897
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11898
            return cbRet;
11899
        }
11900
    }
11901
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
11902
11903
4.30k
    return _ecc_import_x963_ex2(in, inLen, key, curve_id, untrusted);
11904
4.43k
}
11905
11906
/* import public ECC key in ANSI X9.63 format */
11907
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
11908
                          int curve_id)
11909
3.14k
{
11910
    /* treat as untrusted: validate the point is on the curve */
11911
3.14k
    return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1);
11912
3.14k
}
11913
11914
WOLFSSL_ABI
11915
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
11916
125
{
11917
125
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
11918
125
}
11919
#endif /* HAVE_ECC_KEY_IMPORT */
11920
11921
#ifdef HAVE_ECC_KEY_EXPORT
11922
11923
/* Software-only export of ecc key to component form.
11924
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
11925
static int _ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
11926
                          byte* qy, word32* qyLen, byte* d, word32* dLen,
11927
                          int encType)
11928
0
{
11929
0
    int err = 0;
11930
0
    word32 keySz;
11931
11932
0
    if (key == NULL) {
11933
0
        return BAD_FUNC_ARG;
11934
0
    }
11935
11936
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
11937
0
        return ECC_BAD_ARG_E;
11938
0
    }
11939
0
    keySz = (word32)key->dp->size;
11940
11941
    /* private key, d */
11942
0
    if (d != NULL) {
11943
0
        if (dLen == NULL ||
11944
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
11945
0
            return BAD_FUNC_ARG;
11946
11947
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11948
        defined(WOLFSSL_MICROCHIP_TA100)
11949
        /* Hardware cannot export private portion */
11950
        return NOT_COMPILED_IN;
11951
    #else
11952
    #if defined(WOLFSSL_SECO_CAAM)
11953
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
11954
            /* Hardware cannot export private portion */
11955
            WOLFSSL_MSG("Can not export private key from HSM");
11956
            return NOT_COMPILED_IN;
11957
        }
11958
    #endif
11959
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11960
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11961
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11962
                *dLen = keySz + WC_CAAM_MAC_SZ;
11963
                return BUFFER_E;
11964
            }
11965
11966
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
11967
                encType);
11968
            *dLen = keySz + WC_CAAM_MAC_SZ;
11969
        }
11970
        else if (encType == WC_TYPE_BLACK_KEY &&
11971
                key->blackKey != CAAM_BLACK_KEY_ECB &&
11972
                key->blackKey > 0) {
11973
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11974
                *dLen = keySz + WC_CAAM_MAC_SZ;
11975
                return BUFFER_E;
11976
            }
11977
11978
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11979
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11980
                    return WC_HW_E;
11981
            }
11982
11983
            *dLen = keySz + WC_CAAM_MAC_SZ;
11984
        }
11985
        else
11986
    #endif
11987
0
        {
11988
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11989
0
            if (err != MP_OKAY)
11990
0
                return err;
11991
0
        }
11992
0
    #endif
11993
0
    }
11994
11995
    /* public x component */
11996
0
    if (qx != NULL) {
11997
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11998
0
            return BAD_FUNC_ARG;
11999
12000
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
12001
0
        if (err != MP_OKAY)
12002
0
            return err;
12003
0
    }
12004
12005
    /* public y component */
12006
0
    if (qy != NULL) {
12007
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
12008
0
            return BAD_FUNC_ARG;
12009
12010
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
12011
0
        if (err != MP_OKAY)
12012
0
            return err;
12013
0
    }
12014
12015
0
    return err;
12016
0
}
12017
12018
12019
/* export ecc key to component form, d is optional if only exporting public
12020
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
12021
 * return MP_OKAY on success */
12022
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
12023
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
12024
0
{
12025
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12026
    int err;
12027
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12028
#endif
12029
12030
0
    if (key == NULL) {
12031
0
        return BAD_FUNC_ARG;
12032
0
    }
12033
12034
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12035
    #ifndef WOLF_CRYPTO_CB_FIND
12036
    if (key->devId != INVALID_DEVID)
12037
    #endif
12038
    {
12039
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12040
        if (!WC_VAR_OK(tmpKey)) {
12041
            return MEMORY_E;
12042
        }
12043
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12044
12045
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12046
        if (err != 0) {
12047
            WC_FREE_VAR(tmpKey, key->heap);
12048
            return err;
12049
        }
12050
12051
        err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
12052
                                     key, tmpKey);
12053
        if (err == 0) {
12054
            /* Call software helper (no callback recursion) */
12055
            err = _ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen,
12056
                                  encType);
12057
        }
12058
12059
        wc_ecc_free(tmpKey);
12060
        WC_FREE_VAR(tmpKey, key->heap);
12061
12062
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12063
            return err;
12064
        }
12065
    }
12066
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
12067
12068
0
    return _ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType);
12069
0
}
12070
12071
/* export ecc private key only raw, outLen is in/out size as unsigned bin
12072
   return MP_OKAY on success */
12073
WOLFSSL_ABI
12074
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
12075
0
{
12076
0
    if (out == NULL || outLen == NULL) {
12077
0
        return BAD_FUNC_ARG;
12078
0
    }
12079
12080
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12081
    /* check if black key in secure memory */
12082
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
12083
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
12084
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
12085
            WC_TYPE_BLACK_KEY);
12086
    }
12087
#endif
12088
12089
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
12090
0
        WC_TYPE_UNSIGNED_BIN);
12091
0
}
12092
12093
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
12094
 * return MP_OKAY on success, negative on error */
12095
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
12096
                             byte* qy, word32* qyLen)
12097
0
{
12098
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
12099
0
        return BAD_FUNC_ARG;
12100
0
    }
12101
12102
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
12103
0
        WC_TYPE_UNSIGNED_BIN);
12104
0
}
12105
12106
/* export ecc key to raw elements including public (Qx,Qy) and
12107
 *   private (d) as unsigned bin
12108
 * return MP_OKAY on success, negative on error */
12109
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
12110
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
12111
0
{
12112
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
12113
0
        WC_TYPE_UNSIGNED_BIN);
12114
0
}
12115
12116
#endif /* HAVE_ECC_KEY_EXPORT */
12117
12118
#ifdef HAVE_ECC_KEY_IMPORT
12119
/* Software-only import of private key, public part optional.
12120
 * This internal helper avoids recursion when called from the SETKEY path. */
12121
static int _ecc_import_private_key_ex(const byte* priv, word32 privSz,
12122
                                      const byte* pub, word32 pubSz,
12123
                                      ecc_key* key, int curve_id)
12124
6.39k
{
12125
6.39k
    int ret;
12126
#ifdef WOLFSSL_CRYPTOCELL
12127
    const CRYS_ECPKI_Domain_t* pDomain;
12128
#endif
12129
12130
6.39k
    if (key == NULL || priv == NULL) {
12131
0
        return BAD_FUNC_ARG;
12132
0
    }
12133
12134
    /* public optional, NULL if only importing private */
12135
6.39k
    if (pub != NULL) {
12136
0
    #ifndef NO_ASN
12137
0
        word32 idx = 0;
12138
0
        ret = _ecc_import_x963_ex2(pub, pubSz, key, curve_id, 0);
12139
0
        if (ret < 0)
12140
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
12141
0
        key->type = ECC_PRIVATEKEY;
12142
    #else
12143
        (void)pubSz;
12144
        ret = NOT_COMPILED_IN;
12145
    #endif
12146
0
    }
12147
6.39k
    else {
12148
        /* make sure required variables are reset */
12149
6.39k
        wc_ecc_reset(key);
12150
12151
        /* set key size */
12152
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
12153
         *       on created keys or signatures */
12154
6.39k
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
12155
6.39k
        key->type = ECC_PRIVATEKEY_ONLY;
12156
6.39k
    }
12157
12158
6.39k
    if (ret != 0)
12159
548
        return ret;
12160
12161
#ifdef WOLFSSL_CRYPTOCELL
12162
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
12163
    /* import private key - priv checked for NULL at top */
12164
    if (priv[0] != '\0') {
12165
12166
        /* Create private key from external key buffer*/
12167
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
12168
                                      priv,
12169
                                      privSz,
12170
                                      &key->ctx.privKey);
12171
12172
        if (ret != SA_SILIB_RET_OK) {
12173
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
12174
            return ret;
12175
        }
12176
12177
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12178
    #ifdef WOLFSSL_ECC_BLIND_K
12179
        if (ret == MP_OKAY) {
12180
            err = ecc_blind_k_rng(key, NULL);
12181
        }
12182
    #endif
12183
    }
12184
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12185
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
12186
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
12187
        int part = caamFindUnusedPartition();
12188
        if (part >= 0) {
12189
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
12190
            if (vaddr == 0) {
12191
                WOLFSSL_MSG("Unable to get partition");
12192
                return MEMORY_E;
12193
            }
12194
12195
            key->partNum  = part;
12196
            key->blackKey = (word32)vaddr;
12197
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
12198
                return WC_HW_E;
12199
12200
            if (pub != NULL) {
12201
                /* +1 to account for x963 compressed bit */
12202
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
12203
                    return WC_HW_E;
12204
                key->securePubKey = (word32)vaddr + privSz;
12205
            }
12206
        }
12207
        else {
12208
            WOLFSSL_MSG("Unable to find an unused partition");
12209
            return MEMORY_E;
12210
        }
12211
    #else
12212
        key->blackKey = CAAM_BLACK_KEY_CCM;
12213
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12214
    #ifdef WOLFSSL_ECC_BLIND_K
12215
        if (ret == MP_OKAY) {
12216
            err = ecc_blind_k_rng(key, NULL);
12217
        }
12218
    #endif
12219
    #endif
12220
    }
12221
    else {
12222
        key->blackKey = 0;
12223
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12224
    #ifdef WOLFSSL_ECC_BLIND_K
12225
        if (ret == MP_OKAY) {
12226
            err = ecc_blind_k_rng(key, NULL);
12227
        }
12228
    #endif
12229
12230
        /* If using AES-ECB encrypted black keys check here if key is valid,
12231
         * if not valid than assume is an encrypted key. A public key is needed
12232
         * for testing validity. */
12233
        if (key->devId == WOLFSSL_CAAM_DEVID && (
12234
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
12235
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
12236
            if ((pub != NULL) && (ret == MP_OKAY) &&
12237
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
12238
                key->blackKey = CAAM_BLACK_KEY_ECB;
12239
            }
12240
            else if ((pub == NULL) && (ret == MP_OKAY)) {
12241
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
12242
                key->blackKey = CAAM_BLACK_KEY_ECB;
12243
            }
12244
            else {
12245
                WOLFSSL_MSG("Importing key that is not a black key!");
12246
            }
12247
        }
12248
    }
12249
#else
12250
12251
5.84k
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
12252
#ifdef HAVE_WOLF_BIGINT
12253
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
12254
                                                                 privSz) != 0) {
12255
        mp_clear(key->k);
12256
        ret = ASN_GETINT_E;
12257
    }
12258
#endif /* HAVE_WOLF_BIGINT */
12259
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12260
    if (ret == 0) {
12261
        WC_DECLARE_VAR(order, mp_int, 1, 0);
12262
12263
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
12264
            ret=MEMORY_E);
12265
12266
        if (ret == 0) {
12267
            ret = mp_init(order);
12268
        }
12269
        if (ret == 0) {
12270
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
12271
        }
12272
    #ifdef WOLFSSL_SM2
12273
        /* SM2 curve: private key must be less than order-1. */
12274
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
12275
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
12276
            ret = mp_sub_d(order, 1, order);
12277
        }
12278
    #endif
12279
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
12280
            ret = ECC_PRIV_KEY_E;
12281
        }
12282
12283
        mp_clear(order);
12284
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
12285
    }
12286
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
12287
#ifdef WOLFSSL_ECC_BLIND_K
12288
    if (ret == 0) {
12289
        ret = ecc_blind_k_rng(key, NULL);
12290
    }
12291
#endif
12292
12293
5.84k
#endif /* WOLFSSL_CRYPTOCELL */
12294
12295
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
12296
    if ((pub != NULL) && (ret == MP_OKAY))
12297
        /* public key needed to perform key validation */
12298
        ret = _ecc_validate_public_key(key, 1, 1);
12299
12300
#endif
12301
12302
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12303
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
12304
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12305
    }
12306
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12307
    if (ret == 0) {
12308
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
12309
    }
12310
#endif
12311
12312
5.84k
    return ret;
12313
6.39k
}
12314
12315
/* import private key, public part optional if (pub) passed as NULL */
12316
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
12317
                                 const byte* pub, word32 pubSz, ecc_key* key,
12318
                                 int curve_id)
12319
6.44k
{
12320
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12321
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12322
    int tmpErr = 0;
12323
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12324
#endif
12325
12326
6.44k
    if (key == NULL || priv == NULL) {
12327
48
        return BAD_FUNC_ARG;
12328
48
    }
12329
12330
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12331
    #ifndef WOLF_CRYPTO_CB_FIND
12332
    if (key->devId != INVALID_DEVID)
12333
    #endif
12334
    {
12335
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12336
        if (!WC_VAR_OK(tmpKey)) {
12337
            return MEMORY_E;
12338
        }
12339
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12340
12341
        tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12342
        if (tmpErr != 0) {
12343
            WC_FREE_VAR(tmpKey, key->heap);
12344
            return tmpErr;
12345
        }
12346
12347
    #ifdef WOLFSSL_CUSTOM_CURVES
12348
        if (key->dp != NULL) {
12349
            tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp);
12350
            if (tmpErr != 0) {
12351
                wc_ecc_free(tmpKey);
12352
                WC_FREE_VAR(tmpKey, key->heap);
12353
                return tmpErr;
12354
            }
12355
        }
12356
    #endif
12357
12358
        /* Import into temp via software helper (no callback recursion) */
12359
        tmpErr = _ecc_import_private_key_ex(priv, privSz, pub, pubSz,
12360
            tmpKey, curve_id);
12361
        if (tmpErr == 0) {
12362
            cbRet = wc_CryptoCb_SetKey(key->devId,
12363
                WC_SETKEY_ECC_PRIV, key, tmpKey,
12364
                wc_ecc_size(tmpKey), NULL, 0, 0);
12365
        }
12366
12367
        /* wc_ecc_free calls mp_forcezero on private key components,
12368
         * so no separate ForceZero of the struct is needed here. */
12369
        wc_ecc_free(tmpKey);
12370
        WC_FREE_VAR(tmpKey, key->heap);
12371
12372
        if (tmpErr != 0) {
12373
            return tmpErr;
12374
        }
12375
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12376
            return cbRet;
12377
        }
12378
    }
12379
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12380
12381
6.39k
    return _ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, curve_id);
12382
6.44k
}
12383
12384
/* ecc private key import, public key in ANSI X9.63 format, private raw */
12385
WOLFSSL_ABI
12386
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
12387
                           word32 pubSz, ecc_key* key)
12388
49
{
12389
49
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
12390
49
                                                                ECC_CURVE_DEF);
12391
49
}
12392
#endif /* HAVE_ECC_KEY_IMPORT */
12393
12394
#ifndef NO_ASN
12395
/**
12396
   Convert ECC R,S to signature
12397
   r       R component of signature
12398
   s       S component of signature
12399
   out     DER-encoded ECDSA signature
12400
   outlen  [in/out] output buffer size, output signature size
12401
   return  MP_OKAY on success
12402
*/
12403
WOLFSSL_ABI
12404
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
12405
360
{
12406
360
    int err;
12407
360
#ifdef WOLFSSL_SMALL_STACK
12408
360
    mp_int* rtmp = NULL;
12409
360
    mp_int* stmp = NULL;
12410
#else
12411
    mp_int  rtmp[1];
12412
    mp_int  stmp[1];
12413
#endif
12414
12415
360
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
12416
4
        return ECC_BAD_ARG_E;
12417
12418
356
#ifdef WOLFSSL_SMALL_STACK
12419
356
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12420
356
    if (rtmp == NULL)
12421
0
        return MEMORY_E;
12422
356
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12423
356
    if (stmp == NULL) {
12424
0
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
12425
0
        return MEMORY_E;
12426
0
    }
12427
356
#endif
12428
12429
356
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
12430
356
    if (err != MP_OKAY) {
12431
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12432
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12433
0
        return err;
12434
0
    }
12435
12436
356
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
12437
356
    if (err == MP_OKAY)
12438
353
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
12439
12440
356
    if (err == MP_OKAY) {
12441
350
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
12442
21
            err = MP_ZERO_E;
12443
350
    }
12444
356
    if (err == MP_OKAY) {
12445
329
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
12446
16
            err = MP_READ_E;
12447
16
        }
12448
329
    }
12449
12450
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
12451
356
    if (err == MP_OKAY)
12452
313
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
12453
12454
356
    mp_clear(rtmp);
12455
356
    mp_clear(stmp);
12456
356
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12457
356
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12458
12459
356
    return err;
12460
356
}
12461
12462
/**
12463
   Convert ECC R,S raw unsigned bin to signature
12464
   r       R component of signature
12465
   rSz     R size
12466
   s       S component of signature
12467
   sSz     S size
12468
   out     DER-encoded ECDSA signature
12469
   outlen  [in/out] output buffer size, output signature size
12470
   return  MP_OKAY on success
12471
*/
12472
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
12473
    byte* out, word32* outlen)
12474
0
{
12475
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
12476
0
        return ECC_BAD_ARG_E;
12477
12478
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
12479
0
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
12480
0
}
12481
12482
/**
12483
   Convert ECC signature to R,S
12484
   sig     DER-encoded ECDSA signature
12485
   sigLen  length of signature in octets
12486
   r       R component of signature
12487
   rLen    [in/out] output "r" buffer size, output "r" size
12488
   s       S component of signature
12489
   sLen    [in/out] output "s" buffer size, output "s" size
12490
   return  MP_OKAY on success, negative on error
12491
*/
12492
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
12493
                     byte* s, word32* sLen)
12494
0
{
12495
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
12496
0
        return ECC_BAD_ARG_E;
12497
12498
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
12499
0
}
12500
#endif /* !NO_ASN */
12501
12502
#ifdef HAVE_ECC_KEY_IMPORT
12503
/* Software-only import of raw ECC key material.
12504
 * This internal helper avoids recursion when called from the SETKEY path. */
12505
static int _ecc_import_raw_private(ecc_key* key, const char* qx,
12506
          const char* qy, const char* d, int curve_id, int encType)
12507
1.47k
{
12508
1.47k
    int err = MP_OKAY;
12509
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
12510
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
12511
    const CRYS_ECPKI_Domain_t* pDomain;
12512
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
12513
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
12514
#endif
12515
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12516
    defined(WOLFSSL_MICROCHIP_TA100) || defined(WOLFSSL_CRYPTOCELL)
12517
    word32 keySz = 0;
12518
#endif
12519
12520
    /* if d is NULL, only import as public key using Qx,Qy */
12521
1.47k
    if (key == NULL || qx == NULL || qy == NULL) {
12522
0
        return BAD_FUNC_ARG;
12523
0
    }
12524
12525
    /* make sure required variables are reset */
12526
1.47k
    wc_ecc_reset(key);
12527
12528
    /* set curve type and index */
12529
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
12530
     *       on created keys or signatures */
12531
1.47k
    err = wc_ecc_set_curve(key, 0, curve_id);
12532
1.47k
    if (err != 0) {
12533
0
        return err;
12534
0
    }
12535
12536
    /* init key */
12537
#ifdef ALT_ECC_SIZE
12538
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
12539
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
12540
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
12541
    alt_fp_init(key->pubkey.x);
12542
    alt_fp_init(key->pubkey.y);
12543
    alt_fp_init(key->pubkey.z);
12544
    key->k = (mp_int*)key->ka;
12545
    alt_fp_init(key->k);
12546
#ifdef WOLFSSL_ECC_BLIND_K
12547
    key->kb = (mp_int*)key->kba;
12548
    key->ku = (mp_int*)key->kua;
12549
    alt_fp_init(key->kb);
12550
    alt_fp_init(key->ku);
12551
#endif
12552
#else
12553
1.47k
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
12554
1.47k
#ifndef WOLFSSL_ECC_BLIND_K
12555
1.47k
                                                                      NULL, NULL
12556
#else
12557
                                                                key->kb, key->ku
12558
#endif
12559
1.47k
                        );
12560
12561
1.47k
    if (err != MP_OKAY)
12562
0
        return MEMORY_E;
12563
1.47k
#endif
12564
#ifdef WOLFSSL_ECC_BLIND_K
12565
    mp_forcezero(key->kb);
12566
#endif
12567
12568
    /* read Qx */
12569
1.47k
    if (err == MP_OKAY) {
12570
1.47k
        if (encType == WC_TYPE_HEX_STR)
12571
1.47k
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
12572
0
        else
12573
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
12574
0
                (word32)key->dp->size);
12575
12576
1.47k
        if (mp_isneg(key->pubkey.x)) {
12577
16
            WOLFSSL_MSG("Invalid Qx");
12578
16
            err = BAD_FUNC_ARG;
12579
16
        }
12580
1.47k
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
12581
33
            err = BAD_FUNC_ARG;
12582
33
        }
12583
1.47k
    }
12584
12585
    /* read Qy */
12586
1.47k
    if (err == MP_OKAY) {
12587
1.40k
        if (encType == WC_TYPE_HEX_STR)
12588
1.40k
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
12589
0
        else
12590
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
12591
0
                (word32)key->dp->size);
12592
12593
1.40k
        if (mp_isneg(key->pubkey.y)) {
12594
15
            WOLFSSL_MSG("Invalid Qy");
12595
15
            err = BAD_FUNC_ARG;
12596
15
        }
12597
1.40k
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
12598
28
            err = BAD_FUNC_ARG;
12599
28
        }
12600
1.40k
    }
12601
12602
1.47k
    if (err == MP_OKAY) {
12603
1.34k
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
12604
66
            WOLFSSL_MSG("Invalid Qx and Qy");
12605
66
            err = ECC_INF_E;
12606
66
        }
12607
1.34k
    }
12608
12609
1.47k
    if (err == MP_OKAY)
12610
1.27k
        err = mp_set(key->pubkey.z, 1);
12611
12612
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12613
    defined(WOLFSSL_MICROCHIP_TA100)
12614
    /* For SECP256R1 only save raw public key for hardware */
12615
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
12616
        keySz = key->dp->size;
12617
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12618
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12619
        if (err == MP_OKAY)
12620
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
12621
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12622
    }
12623
#elif defined(WOLFSSL_CRYPTOCELL)
12624
    if (err == MP_OKAY) {
12625
        keyRaw[0] = ECC_POINT_UNCOMP;
12626
        keySz = (word32)key->dp->size;
12627
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
12628
            WC_TYPE_UNSIGNED_BIN);
12629
        if (err == MP_OKAY) {
12630
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
12631
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12632
        }
12633
12634
        if (err == MP_OKAY) {
12635
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
12636
12637
            /* create public key from external key buffer */
12638
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
12639
                                                   keyRaw,
12640
                                                   keySz*2 + 1,
12641
                                                   &key->ctx.pubKey,
12642
                                                   &tempBuff);
12643
        }
12644
12645
        if (err != SA_SILIB_RET_OK){
12646
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
12647
            return err;
12648
        }
12649
    }
12650
#elif defined(WOLFSSL_KCAPI_ECC)
12651
    if (err == MP_OKAY) {
12652
        word32 keySz = key->dp->size;
12653
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12654
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12655
        if (err == MP_OKAY) {
12656
            err = wc_export_int(key->pubkey.y,
12657
                &key->pubkey_raw[keySz], &keySz, keySz,
12658
                WC_TYPE_UNSIGNED_BIN);
12659
        }
12660
    }
12661
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12662
    if (err == MP_OKAY) {
12663
        const word32 keySize = key->dp->size;
12664
        word32 bufSize = sizeof(key->keyRaw);
12665
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
12666
                            WC_TYPE_UNSIGNED_BIN);
12667
        if (err == MP_OKAY) {
12668
            const word32 offset = bufSize;
12669
            bufSize = sizeof(key->keyRaw) - offset;
12670
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
12671
                                keySize, WC_TYPE_UNSIGNED_BIN);
12672
        }
12673
        if (err == MP_OKAY) {
12674
            mp_reverse(key->keyRaw, keySize);
12675
            mp_reverse(&key->keyRaw[keySize], keySize);
12676
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
12677
                                           keySize * 2);
12678
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
12679
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
12680
                                              xil_curve_type[key->dp->id],
12681
                                              XIL_CAST_U64(key->keyRaw));
12682
            if (err) {
12683
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
12684
                err = WC_HW_E;
12685
            }
12686
#endif
12687
        }
12688
    }
12689
#endif
12690
12691
    /* import private key */
12692
1.47k
    if (err == MP_OKAY) {
12693
1.27k
        if (d != NULL) {
12694
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12695
            defined(WOLFSSL_MICROCHIP_TA100)
12696
            /* Hardware doesn't support loading private key */
12697
            err = NOT_COMPILED_IN;
12698
12699
        #elif defined(WOLFSSL_CRYPTOCELL)
12700
            key->type = ECC_PRIVATEKEY;
12701
12702
            if (encType == WC_TYPE_HEX_STR)
12703
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12704
            else
12705
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
12706
                    key->dp->size);
12707
            if (err == MP_OKAY) {
12708
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
12709
                    WC_TYPE_UNSIGNED_BIN);
12710
            }
12711
        #ifdef WOLFSSL_ECC_BLIND_K
12712
            if (err == 0) {
12713
                err = ecc_blind_k_rng(key, NULL);
12714
            }
12715
        #endif
12716
12717
            if (err == MP_OKAY) {
12718
                /* Create private key from external key buffer*/
12719
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
12720
                                              keyRaw,
12721
                                              keySz,
12722
                                              &key->ctx.privKey);
12723
12724
                if (err != SA_SILIB_RET_OK){
12725
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
12726
                    return err;
12727
                }
12728
            }
12729
12730
        #else
12731
0
            key->type = ECC_PRIVATEKEY;
12732
0
            if (encType == WC_TYPE_HEX_STR)
12733
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12734
0
            else {
12735
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12736
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
12737
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12738
                    key->dp->size + WC_CAAM_MAC_SZ);
12739
                }
12740
                else
12741
            #endif /* WOLFSSL_QNX_CAAM */
12742
0
                {
12743
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12744
0
                        (word32)key->dp->size);
12745
0
                }
12746
0
            }
12747
        #ifdef WOLFSSL_ECC_BLIND_K
12748
            if (err == 0) {
12749
                err = ecc_blind_k_rng(key, NULL);
12750
            }
12751
        #endif
12752
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12753
            if (err == MP_OKAY) {
12754
                const word32 key_size = key->dp->size;
12755
                word32 buf_size = key_size;
12756
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
12757
                                    WC_TYPE_UNSIGNED_BIN);
12758
                mp_reverse(key->privKey, key_size);
12759
            }
12760
#endif
12761
12762
0
        #endif /* #else-case of custom HW-specific implementations */
12763
0
            if (err == MP_OKAY) {
12764
0
                if (mp_iszero(key->k) || mp_isneg(key->k)) {
12765
0
                    WOLFSSL_MSG("Invalid private key");
12766
0
                    err = BAD_FUNC_ARG;
12767
0
                }
12768
0
            }
12769
1.27k
        } else {
12770
1.27k
            key->type = ECC_PUBLICKEY;
12771
1.27k
        }
12772
1.27k
    }
12773
12774
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12775
    if (err == MP_OKAY) {
12776
        err = wc_ecc_check_key(key);
12777
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
12778
                                  mp_iszero(key->pubkey.y))) {
12779
            err = BAD_FUNC_ARG;
12780
        }
12781
    }
12782
#endif
12783
12784
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12785
    if (err == MP_OKAY) {
12786
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12787
    }
12788
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12789
    if (err == MP_OKAY) {
12790
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
12791
    }
12792
#endif
12793
12794
1.47k
    if (err != MP_OKAY) {
12795
196
        mp_clear(key->pubkey.x);
12796
196
        mp_clear(key->pubkey.y);
12797
196
        mp_clear(key->pubkey.z);
12798
196
        mp_forcezero(key->k);
12799
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12800
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
12801
#endif
12802
196
    }
12803
12804
1.47k
    return err;
12805
1.47k
}
12806
12807
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
12808
          const char* qy, const char* d, int curve_id, int encType)
12809
9.14k
{
12810
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12811
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12812
    int setKeyType = WC_SETKEY_ECC_PRIV;
12813
    int err;
12814
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12815
#endif
12816
12817
    /* if d is NULL, only import as public key using Qx,Qy */
12818
9.14k
    if (key == NULL || qx == NULL || qy == NULL) {
12819
0
        return BAD_FUNC_ARG;
12820
0
    }
12821
12822
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12823
    #ifndef WOLF_CRYPTO_CB_FIND
12824
    if (key->devId != INVALID_DEVID)
12825
    #endif
12826
    {
12827
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12828
        if (!WC_VAR_OK(tmpKey)) {
12829
            return MEMORY_E;
12830
        }
12831
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12832
12833
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12834
        if (err != 0) {
12835
            WC_FREE_VAR(tmpKey, key->heap);
12836
            return err;
12837
        }
12838
12839
    #ifdef WOLFSSL_CUSTOM_CURVES
12840
        if (key->dp != NULL) {
12841
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
12842
            if (err != 0) {
12843
                wc_ecc_free(tmpKey);
12844
                WC_FREE_VAR(tmpKey, key->heap);
12845
                return err;
12846
            }
12847
        }
12848
    #endif
12849
12850
        /* Import into temp via software helper (no callback recursion) */
12851
        err = _ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType);
12852
        if (err == MP_OKAY) {
12853
            if (d == NULL) {
12854
                setKeyType = WC_SETKEY_ECC_PUB;
12855
            }
12856
            cbRet = wc_CryptoCb_SetKey(key->devId,
12857
                setKeyType, key, tmpKey,
12858
                wc_ecc_size(tmpKey), NULL, 0, 0);
12859
        }
12860
12861
        /* wc_ecc_free calls mp_forcezero on private key components,
12862
         * so no separate ForceZero of the struct is needed here. */
12863
        wc_ecc_free(tmpKey);
12864
        WC_FREE_VAR(tmpKey, key->heap);
12865
12866
        if (err != MP_OKAY) {
12867
            return err;
12868
        }
12869
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12870
            return cbRet;
12871
        }
12872
    }
12873
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12874
12875
9.14k
    return _ecc_import_raw_private(key, qx, qy, d, curve_id, encType);
12876
9.14k
}
12877
12878
/**
12879
   Import raw ECC key
12880
   key       The destination ecc_key structure
12881
   qx        x component of the public key, as ASCII hex string
12882
   qy        y component of the public key, as ASCII hex string
12883
   d         private key, as ASCII hex string, optional if importing public
12884
             key only
12885
   curve_id  The id of the curve.
12886
   @return    MP_OKAY on success
12887
*/
12888
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
12889
                   const char* d, int curve_id)
12890
0
{
12891
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
12892
0
        WC_TYPE_HEX_STR);
12893
0
}
12894
12895
/* Import x, y and optional private (d) as unsigned binary */
12896
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
12897
                   const byte* d, int curve_id)
12898
0
{
12899
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
12900
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
12901
0
}
12902
12903
/**
12904
   Import raw ECC key
12905
   key       The destination ecc_key structure
12906
   qx        x component of the public key, as ASCII hex string
12907
   qy        y component of the public key, as ASCII hex string
12908
   d         private key, as ASCII hex string, optional if importing public
12909
             key only
12910
   curveName ECC curve name, from ecc_sets[]
12911
   return    MP_OKAY on success
12912
*/
12913
WOLFSSL_ABI
12914
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
12915
                   const char* d, const char* curveName)
12916
9.14k
{
12917
9.14k
    int err, x;
12918
12919
    /* if d is NULL, only import as public key using Qx,Qy */
12920
9.14k
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
12921
0
        return BAD_FUNC_ARG;
12922
0
    }
12923
12924
    /* set curve type and index */
12925
89.6k
    for (x = 0; ecc_sets[x].size != 0; x++) {
12926
89.6k
        if (XSTRNCMP(ecc_sets[x].name, curveName,
12927
89.6k
                     XSTRLEN(curveName)) == 0) {
12928
9.14k
            break;
12929
9.14k
        }
12930
89.6k
    }
12931
12932
9.14k
    if (ecc_sets[x].size == 0) {
12933
0
        WOLFSSL_MSG("ecc_set curve name not found");
12934
0
        err = ASN_PARSE_E;
12935
9.14k
    } else {
12936
9.14k
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
12937
9.14k
            WC_TYPE_HEX_STR);
12938
9.14k
    }
12939
12940
0
    return err;
12941
9.14k
}
12942
#endif /* HAVE_ECC_KEY_IMPORT */
12943
12944
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
12945
/* public key size in octets */
12946
static int ecc_public_key_size(ecc_key* key, word32* sz)
12947
317
{
12948
317
    if (key == NULL || key->dp == NULL)
12949
0
        return BAD_FUNC_ARG;
12950
12951
    /* 'Uncompressed' | x | y */
12952
317
    *sz = 1 + 2 * (word32)key->dp->size;
12953
12954
317
    return 0;
12955
317
}
12956
#endif
12957
12958
/* key size in octets */
12959
WOLFSSL_ABI
12960
int wc_ecc_size(ecc_key* key)
12961
262
{
12962
262
    if (key == NULL) {
12963
0
        return 0;
12964
0
    }
12965
12966
#if defined(WOLF_CRYPTO_CB) && \
12967
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
12968
    if (key->devId != INVALID_DEVID) {
12969
        int ret;
12970
        int keySz = 0;
12971
12972
        ret = wc_CryptoCb_EccGetSize(key, &keySz);
12973
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12974
            if (ret != 0) {
12975
                return 0;
12976
            }
12977
            return keySz;
12978
        }
12979
    }
12980
#endif
12981
12982
262
    if (key->dp == NULL) {
12983
0
        return 0;
12984
0
    }
12985
12986
262
    return key->dp->size;
12987
262
}
12988
12989
/* maximum signature size based on key size */
12990
WOLFSSL_ABI
12991
int wc_ecc_sig_size_calc(int sz)
12992
0
{
12993
0
    int maxSigSz = 0;
12994
12995
    /* calculate based on key bits */
12996
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
12997
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
12998
12999
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
13000
0
    if (maxSigSz < (128 + 2)) {
13001
0
        maxSigSz -= 1;
13002
0
    }
13003
13004
0
    return maxSigSz;
13005
0
}
13006
13007
/* maximum signature size based on actual key curve */
13008
WOLFSSL_ABI
13009
int wc_ecc_sig_size(const ecc_key* key)
13010
0
{
13011
0
    int maxSigSz;
13012
0
    int orderBits, keySz;
13013
13014
0
    if (key == NULL) {
13015
0
        return 0;
13016
0
    }
13017
13018
#if defined(WOLF_CRYPTO_CB) && \
13019
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
13020
    if (key->devId != INVALID_DEVID) {
13021
        int ret;
13022
        int cbKeySz = 0;
13023
13024
        ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
13025
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
13026
            if (ret != 0 || cbKeySz == 0) {
13027
                return 0;
13028
            }
13029
            return cbKeySz;
13030
        }
13031
    }
13032
#endif
13033
13034
0
    if (key->dp == NULL) {
13035
0
        return 0;
13036
0
    }
13037
13038
    /* the signature r and s will always be less than order */
13039
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
13040
        extra byte for r and s, so add 2 */
13041
0
    keySz = key->dp->size;
13042
0
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
13043
0
    if (orderBits > keySz * 8) {
13044
0
        keySz = (orderBits + 7) >> 3;
13045
0
    }
13046
    /* maximum possible signature header size is 7 bytes */
13047
0
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
13048
0
    if ((orderBits % 8) == 0) {
13049
        /* MSB can be set, so add 2 */
13050
0
        maxSigSz += ECC_MAX_PAD_SZ;
13051
0
    }
13052
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
13053
0
    if (maxSigSz < (128 + 2)) {
13054
0
        maxSigSz -= 1;
13055
0
    }
13056
13057
0
    return maxSigSz;
13058
0
}
13059
13060
13061
#ifdef FP_ECC
13062
13063
/* fixed point ECC cache */
13064
/* number of entries in the cache */
13065
#ifndef FP_ENTRIES
13066
    #define FP_ENTRIES 15
13067
#endif
13068
13069
/* number of bits in LUT */
13070
#ifndef FP_LUT
13071
    #define FP_LUT     8U
13072
#endif
13073
13074
#ifdef ECC_SHAMIR
13075
    /* Sharmir requires a bigger LUT, TAO */
13076
    #if (FP_LUT > 12) || (FP_LUT < 4)
13077
        #error FP_LUT must be between 4 and 12 inclusively
13078
    #endif
13079
#else
13080
    #if (FP_LUT > 12) || (FP_LUT < 2)
13081
        #error FP_LUT must be between 2 and 12 inclusively
13082
    #endif
13083
#endif
13084
13085
13086
#if !defined(WOLFSSL_SP_MATH)
13087
13088
/** Our FP cache */
13089
typedef struct {
13090
   ecc_point* g;               /* cached COPY of base point */
13091
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
13092
   int        LUT_set;         /* flag to determine if the LUT has been computed */
13093
   mp_int     mu;              /* copy of the montgomery constant */
13094
   int        lru_count;       /* amount of times this entry has been used */
13095
   int        lock;            /* flag to indicate cache eviction */
13096
                               /* permitted (0) or not (1) */
13097
} fp_cache_t;
13098
13099
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
13100
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
13101
13102
#ifndef HAVE_THREAD_LS
13103
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
13104
#ifndef WOLFSSL_MUTEX_INITIALIZER
13105
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
13106
#endif
13107
#endif /* HAVE_THREAD_LS */
13108
13109
/* simple table to help direct the generation of the LUT */
13110
static const struct {
13111
   int ham, terma, termb;
13112
} lut_orders[] = {
13113
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
13114
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
13115
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
13116
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
13117
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
13118
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
13119
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
13120
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
13121
#if FP_LUT > 6
13122
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
13123
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
13124
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
13125
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
13126
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
13127
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
13128
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
13129
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
13130
#if FP_LUT > 7
13131
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
13132
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
13133
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
13134
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
13135
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
13136
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
13137
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
13138
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
13139
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
13140
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
13141
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
13142
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
13143
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
13144
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
13145
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
13146
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
13147
#if FP_LUT > 8
13148
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
13149
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
13150
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
13151
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
13152
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
13153
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
13154
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
13155
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
13156
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
13157
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
13158
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
13159
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
13160
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
13161
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
13162
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
13163
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
13164
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
13165
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
13166
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
13167
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
13168
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
13169
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
13170
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
13171
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
13172
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
13173
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
13174
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
13175
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
13176
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
13177
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
13178
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
13179
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
13180
#if FP_LUT > 9
13181
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
13182
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
13183
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
13184
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
13185
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
13186
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
13187
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
13188
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
13189
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
13190
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
13191
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
13192
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
13193
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
13194
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
13195
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
13196
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
13197
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
13198
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
13199
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
13200
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
13201
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
13202
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
13203
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
13204
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
13205
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
13206
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
13207
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
13208
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
13209
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
13210
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
13211
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
13212
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
13213
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
13214
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
13215
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
13216
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
13217
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
13218
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
13219
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
13220
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
13221
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
13222
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
13223
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
13224
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
13225
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
13226
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
13227
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
13228
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
13229
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
13230
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
13231
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
13232
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
13233
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
13234
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
13235
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
13236
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
13237
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
13238
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
13239
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
13240
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
13241
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
13242
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
13243
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
13244
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
13245
#if FP_LUT > 10
13246
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
13247
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
13248
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
13249
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
13250
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
13251
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
13252
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
13253
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
13254
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
13255
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
13256
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
13257
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
13258
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
13259
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
13260
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
13261
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
13262
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
13263
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
13264
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
13265
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
13266
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
13267
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
13268
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
13269
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
13270
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
13271
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
13272
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
13273
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
13274
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
13275
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
13276
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
13277
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
13278
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
13279
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
13280
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
13281
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
13282
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
13283
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
13284
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
13285
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
13286
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
13287
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
13288
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
13289
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
13290
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
13291
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
13292
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
13293
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
13294
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
13295
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
13296
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
13297
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
13298
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
13299
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
13300
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
13301
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
13302
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
13303
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
13304
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
13305
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
13306
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
13307
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
13308
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
13309
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
13310
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
13311
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
13312
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
13313
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
13314
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
13315
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
13316
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
13317
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
13318
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
13319
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
13320
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
13321
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
13322
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
13323
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
13324
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
13325
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
13326
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
13327
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
13328
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
13329
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
13330
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
13331
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
13332
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
13333
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
13334
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
13335
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
13336
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
13337
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
13338
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
13339
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
13340
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
13341
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
13342
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
13343
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
13344
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
13345
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
13346
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
13347
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
13348
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
13349
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
13350
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
13351
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
13352
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
13353
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
13354
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
13355
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
13356
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
13357
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
13358
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
13359
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
13360
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
13361
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
13362
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
13363
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
13364
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
13365
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
13366
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
13367
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
13368
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
13369
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
13370
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
13371
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
13372
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
13373
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
13374
#if FP_LUT > 11
13375
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
13376
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
13377
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
13378
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
13379
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
13380
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
13381
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
13382
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
13383
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
13384
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
13385
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
13386
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
13387
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
13388
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
13389
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
13390
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
13391
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
13392
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
13393
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
13394
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
13395
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
13396
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
13397
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
13398
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
13399
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
13400
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
13401
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
13402
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
13403
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
13404
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
13405
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
13406
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
13407
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
13408
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
13409
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
13410
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
13411
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
13412
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
13413
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
13414
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
13415
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
13416
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
13417
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
13418
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
13419
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
13420
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
13421
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
13422
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
13423
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
13424
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
13425
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
13426
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
13427
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
13428
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
13429
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
13430
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
13431
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
13432
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
13433
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
13434
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
13435
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
13436
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
13437
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
13438
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
13439
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
13440
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
13441
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
13442
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
13443
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
13444
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
13445
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
13446
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
13447
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
13448
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
13449
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
13450
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
13451
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
13452
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
13453
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
13454
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
13455
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
13456
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
13457
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
13458
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
13459
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
13460
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
13461
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
13462
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
13463
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
13464
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
13465
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
13466
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
13467
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
13468
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
13469
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
13470
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
13471
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
13472
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
13473
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
13474
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
13475
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
13476
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
13477
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
13478
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
13479
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
13480
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
13481
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
13482
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
13483
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
13484
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
13485
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
13486
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
13487
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
13488
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
13489
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
13490
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
13491
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
13492
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
13493
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
13494
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
13495
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
13496
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
13497
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
13498
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
13499
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
13500
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
13501
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
13502
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
13503
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
13504
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
13505
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
13506
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
13507
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
13508
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
13509
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
13510
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
13511
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
13512
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
13513
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
13514
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
13515
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
13516
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
13517
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
13518
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
13519
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
13520
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
13521
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
13522
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
13523
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
13524
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
13525
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
13526
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
13527
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
13528
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
13529
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
13530
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
13531
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
13532
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
13533
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
13534
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
13535
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
13536
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
13537
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
13538
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
13539
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
13540
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
13541
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
13542
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
13543
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
13544
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
13545
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
13546
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
13547
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
13548
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
13549
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
13550
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
13551
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
13552
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
13553
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
13554
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
13555
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
13556
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
13557
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
13558
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
13559
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
13560
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
13561
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
13562
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
13563
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
13564
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
13565
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
13566
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
13567
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
13568
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
13569
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
13570
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
13571
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
13572
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
13573
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
13574
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
13575
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
13576
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
13577
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
13578
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
13579
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
13580
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
13581
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
13582
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
13583
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
13584
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
13585
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
13586
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
13587
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
13588
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
13589
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
13590
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
13591
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
13592
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
13593
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
13594
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
13595
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
13596
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
13597
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
13598
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
13599
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
13600
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
13601
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
13602
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
13603
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
13604
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
13605
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
13606
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
13607
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
13608
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
13609
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
13610
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
13611
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
13612
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
13613
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
13614
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
13615
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
13616
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
13617
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
13618
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
13619
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
13620
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
13621
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
13622
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
13623
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
13624
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
13625
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
13626
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
13627
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
13628
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
13629
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
13630
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
13631
#endif
13632
#endif
13633
#endif
13634
#endif
13635
#endif
13636
#endif
13637
};
13638
13639
13640
/* find a hole and free as required, return -1 if no hole found */
13641
static int find_hole(void)
13642
{
13643
#ifdef WOLFSSL_NO_MALLOC
13644
   return -1;
13645
#else
13646
   int      x, y, z;
13647
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
13648
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
13649
          z = x;
13650
          y = fp_cache[x].lru_count;
13651
       }
13652
   }
13653
13654
   /* decrease all */
13655
   for (x = 0; x < FP_ENTRIES; x++) {
13656
      if (fp_cache[x].lru_count > 3) {
13657
         --(fp_cache[x].lru_count);
13658
      }
13659
   }
13660
13661
   /* free entry z */
13662
   if (z >= 0 && fp_cache[z].g) {
13663
      mp_clear(&fp_cache[z].mu);
13664
      wc_ecc_del_point(fp_cache[z].g);
13665
      fp_cache[z].g  = NULL;
13666
      for (x = 0; x < (1<<FP_LUT); x++) {
13667
         wc_ecc_del_point(fp_cache[z].LUT[x]);
13668
         fp_cache[z].LUT[x] = NULL;
13669
      }
13670
      fp_cache[z].LUT_set = 0;
13671
      fp_cache[z].lru_count = 0;
13672
   }
13673
   return z;
13674
#endif /* !WOLFSSL_NO_MALLOC */
13675
}
13676
13677
/* determine if a base is already in the cache and if so, where */
13678
static int find_base(ecc_point* g)
13679
{
13680
   int x;
13681
   for (x = 0; x < FP_ENTRIES; x++) {
13682
      if (fp_cache[x].g != NULL &&
13683
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
13684
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
13685
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
13686
         break;
13687
      }
13688
   }
13689
   if (x == FP_ENTRIES) {
13690
      x = -1;
13691
   }
13692
   return x;
13693
}
13694
13695
/* add a new base to the cache */
13696
static int add_entry(int idx, ecc_point *g)
13697
{
13698
   unsigned x, y;
13699
13700
   /* allocate base and LUT */
13701
   fp_cache[idx].g = wc_ecc_new_point();
13702
   if (fp_cache[idx].g == NULL) {
13703
      return MP_MEM;
13704
   }
13705
13706
   /* copy x and y */
13707
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
13708
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
13709
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
13710
      wc_ecc_del_point(fp_cache[idx].g);
13711
      fp_cache[idx].g = NULL;
13712
      return MP_MEM;
13713
   }
13714
13715
   for (x = 0; x < (1U<<FP_LUT); x++) {
13716
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
13717
      if (fp_cache[idx].LUT[x] == NULL) {
13718
         for (y = 0; y < x; y++) {
13719
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
13720
            fp_cache[idx].LUT[y] = NULL;
13721
         }
13722
         wc_ecc_del_point(fp_cache[idx].g);
13723
         fp_cache[idx].g         = NULL;
13724
         fp_cache[idx].lru_count = 0;
13725
         return MP_MEM;
13726
      }
13727
   }
13728
13729
   fp_cache[idx].LUT_set   = 0;
13730
   fp_cache[idx].lru_count = 0;
13731
13732
   return MP_OKAY;
13733
}
13734
#endif
13735
13736
#if !defined(WOLFSSL_SP_MATH)
13737
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
13738
 *
13739
 * The algorithm builds patterns in increasing bit order by first making all
13740
 * single bit input patterns, then all two bit input patterns and so on
13741
 */
13742
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
13743
    mp_int* mu)
13744
{
13745
   int err;
13746
   unsigned x, y, bitlen, lut_gap;
13747
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
13748
   int infinity;
13749
13750
#ifdef WOLFSSL_SMALL_STACK
13751
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13752
       return MEMORY_E;
13753
#endif
13754
13755
   err = mp_init(tmp);
13756
   if (err != MP_OKAY) {
13757
       err = MP_MEM;
13758
       goto errout;
13759
   }
13760
13761
   /* sanity check to make sure lut_order table is of correct size,
13762
      should compile out to a NOP if true */
13763
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
13764
       err = BAD_FUNC_ARG;
13765
       goto errout;
13766
   }
13767
13768
   /* get bitlen and round up to next multiple of FP_LUT */
13769
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13770
   x       = bitlen % FP_LUT;
13771
   if (x) {
13772
       bitlen += FP_LUT - x;
13773
   }
13774
   lut_gap = bitlen / FP_LUT;
13775
13776
   /* init the mu */
13777
   err = mp_init_copy(&fp_cache[idx].mu, mu);
13778
   if (err != MP_OKAY)
13779
       goto errout;
13780
13781
   /* copy base */
13782
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
13783
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
13784
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
13785
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
13786
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
13787
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
13788
       err = MP_MULMOD_E;
13789
       goto errout;
13790
   }
13791
13792
   /* make all single bit entries */
13793
   for (x = 1; x < FP_LUT; x++) {
13794
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
13795
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
13796
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
13797
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
13798
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
13799
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
13800
          err = MP_INIT_E;
13801
          goto errout;
13802
      } else {
13803
13804
         /* now double it bitlen/FP_LUT times */
13805
         for (y = 0; y < lut_gap; y++) {
13806
             if ((err = ecc_projective_dbl_point_safe(
13807
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13808
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13809
                                      a, modulus, mp)) != MP_OKAY) {
13810
                 goto errout;
13811
             }
13812
         }
13813
     }
13814
  }
13815
13816
   /* now make all entries in increase order of hamming weight */
13817
   for (x = 2; x <= FP_LUT; x++) {
13818
       if (err != MP_OKAY)
13819
           goto errout;
13820
       for (y = 0; y < (1UL<<FP_LUT); y++) {
13821
           if (lut_orders[y].ham != (int)x) continue;
13822
13823
           /* perform the add */
13824
           if ((err = ecc_projective_add_point_safe(
13825
                           fp_cache[idx].LUT[lut_orders[y].terma],
13826
                           fp_cache[idx].LUT[lut_orders[y].termb],
13827
                           fp_cache[idx].LUT[y], a, modulus, mp,
13828
                           &infinity)) != MP_OKAY) {
13829
               goto errout;
13830
           }
13831
       }
13832
   }
13833
13834
   /* now map all entries back to affine space to make point addition faster */
13835
   for (x = 1; x < (1UL<<FP_LUT); x++) {
13836
       if (err != MP_OKAY)
13837
           break;
13838
13839
       /* convert z to normal from montgomery */
13840
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
13841
13842
       /* invert it */
13843
       if (err == MP_OKAY)
13844
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
13845
                         fp_cache[idx].LUT[x]->z);
13846
13847
       if (err == MP_OKAY)
13848
         /* now square it */
13849
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
13850
13851
       if (err == MP_OKAY)
13852
         /* fix x */
13853
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
13854
                         fp_cache[idx].LUT[x]->x);
13855
13856
       if (err == MP_OKAY)
13857
         /* get 1/z^3 */
13858
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
13859
13860
       if (err == MP_OKAY)
13861
         /* fix y */
13862
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
13863
                         fp_cache[idx].LUT[x]->y);
13864
13865
       if (err == MP_OKAY)
13866
         /* free z */
13867
         mp_clear(fp_cache[idx].LUT[x]->z);
13868
   }
13869
13870
  errout:
13871
13872
   mp_clear(tmp);
13873
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13874
13875
   if (err == MP_OKAY) {
13876
       fp_cache[idx].LUT_set = 1;
13877
       return MP_OKAY;
13878
   }
13879
13880
   /* err cleanup */
13881
   for (y = 0; y < (1U<<FP_LUT); y++) {
13882
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
13883
      fp_cache[idx].LUT[y] = NULL;
13884
   }
13885
   wc_ecc_del_point(fp_cache[idx].g);
13886
   fp_cache[idx].g         = NULL;
13887
   fp_cache[idx].LUT_set   = 0;
13888
   fp_cache[idx].lru_count = 0;
13889
   mp_clear(&fp_cache[idx].mu);
13890
13891
   return err;
13892
}
13893
13894
/* perform a fixed point ECC mulmod */
13895
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
13896
                        mp_int* modulus, mp_digit mp, int map)
13897
{
13898
#ifdef WOLFCRYPT_HAVE_SAKKE
13899
    #define KB_SIZE 256
13900
#else
13901
    #define KB_SIZE 128
13902
#endif
13903
13904
#ifdef WOLFSSL_SMALL_STACK
13905
   unsigned char* kb = NULL;
13906
   mp_int*        tk = NULL;
13907
   mp_int*        order = NULL;
13908
#else
13909
   unsigned char kb[KB_SIZE];
13910
   mp_int        tk[1];
13911
   mp_int        order[1];
13912
#endif
13913
   int      x, err;
13914
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
13915
   int first;
13916
   int tk_zeroize = 0;
13917
13918
#ifdef WOLFSSL_SMALL_STACK
13919
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13920
   if (tk == NULL) {
13921
      err = MEMORY_E; goto done;
13922
   }
13923
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13924
   if (order == NULL) {
13925
      err = MEMORY_E; goto done;
13926
   }
13927
#endif
13928
13929
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
13930
       err = MP_INIT_E; goto done;
13931
   }
13932
13933
   if ((err = mp_copy(k, tk)) != MP_OKAY)
13934
       goto done;
13935
   tk_zeroize = 1;
13936
13937
#ifdef WOLFSSL_CHECK_MEM_ZERO
13938
   mp_memzero_add("accel_fp_mul tk", tk);
13939
#endif
13940
13941
   /* if it's smaller than modulus we fine */
13942
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
13943
      /* find order */
13944
       y = (unsigned)mp_unsigned_bin_size(modulus);
13945
      for (x = 0; ecc_sets[x].size; x++) {
13946
         if (y <= (unsigned)ecc_sets[x].size) break;
13947
      }
13948
13949
      /* back off if we are on the 521 bit curve */
13950
      if (y == 66) --x;
13951
13952
      if ((err = mp_read_radix(order, ecc_sets[x].order,
13953
                                                MP_RADIX_HEX)) != MP_OKAY) {
13954
         goto done;
13955
      }
13956
13957
      /* k must be less than modulus */
13958
      if (mp_cmp(tk, order) != MP_LT) {
13959
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
13960
            goto done;
13961
         }
13962
      }
13963
   }
13964
13965
   /* get bitlen and round up to next multiple of FP_LUT */
13966
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13967
   x       = bitlen % FP_LUT;
13968
   if (x) {
13969
      bitlen += FP_LUT - (unsigned)x;
13970
   }
13971
   lut_gap = bitlen / FP_LUT;
13972
13973
   /* get the k value */
13974
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
13975
      err = BUFFER_E; goto done;
13976
   }
13977
13978
   /* store k */
13979
#ifdef WOLFSSL_SMALL_STACK
13980
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13981
   if (kb == NULL) {
13982
      err = MEMORY_E; goto done;
13983
   }
13984
#endif
13985
13986
   XMEMSET(kb, 0, KB_SIZE);
13987
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
13988
   #ifdef WOLFSSL_CHECK_MEM_ZERO
13989
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
13990
   #endif
13991
      /* let's reverse kb so it's little endian */
13992
      x = 0;
13993
      y = (unsigned)mp_unsigned_bin_size(tk);
13994
      if (y > 0) {
13995
          y -= 1;
13996
      }
13997
13998
      while ((unsigned)x < y) {
13999
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
14000
         ++x; --y;
14001
      }
14002
14003
      /* at this point we can start, yipee */
14004
      first = 1;
14005
      for (x = (int)lut_gap-1; x >= 0; x--) {
14006
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
14007
             by x bits from the start */
14008
          bitpos = (unsigned)x;
14009
          for (y = z = 0; y < FP_LUT; y++) {
14010
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14011
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
14012
                                    the mult in each loop */
14013
          }
14014
14015
          /* double if not first */
14016
          if (!first) {
14017
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14018
                                                              mp)) != MP_OKAY) {
14019
                break;
14020
             }
14021
          }
14022
14023
          /* add if not first, otherwise copy */
14024
          if (!first && z) {
14025
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
14026
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
14027
                break;
14028
             }
14029
          } else if (z) {
14030
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
14031
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
14032
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
14033
                 err = MP_MEM;
14034
                 break;
14035
             }
14036
             first = 0;
14037
          }
14038
      }
14039
   }
14040
14041
   if (err == MP_OKAY) {
14042
      (void) z; /* Acknowledge the unused assignment */
14043
      ForceZero(kb, KB_SIZE);
14044
14045
      /* map R back from projective space */
14046
      if (map) {
14047
         err = ecc_map(R, modulus, mp);
14048
      } else {
14049
         err = MP_OKAY;
14050
      }
14051
   }
14052
14053
done:
14054
   /* cleanup */
14055
   mp_clear(order);
14056
   /* Ensure it was initialized. */
14057
   if (tk_zeroize) {
14058
       mp_forcezero(tk);
14059
   }
14060
14061
#ifdef WOLFSSL_SMALL_STACK
14062
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14063
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14064
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14065
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14066
   wc_MemZero_Check(kb, KB_SIZE);
14067
   mp_memzero_check(tk);
14068
#endif
14069
14070
#undef KB_SIZE
14071
14072
   return err;
14073
}
14074
#endif
14075
14076
#ifdef ECC_SHAMIR
14077
#if !defined(WOLFSSL_SP_MATH)
14078
/* perform a fixed point ECC mulmod */
14079
static int accel_fp_mul2add(int idx1, int idx2,
14080
                            mp_int* kA, mp_int* kB,
14081
                            ecc_point *R, mp_int* a,
14082
                            mp_int* modulus, mp_digit mp)
14083
{
14084
#define KB_SIZE 128
14085
14086
#ifdef WOLFSSL_SMALL_STACK
14087
   unsigned char* kb[2] = {NULL, NULL};
14088
   mp_int*        tka = NULL;
14089
   mp_int*        tkb = NULL;
14090
   mp_int*        order = NULL;
14091
#else
14092
   unsigned char kb[2][KB_SIZE];
14093
   mp_int        tka[1];
14094
   mp_int        tkb[1];
14095
   mp_int        order[1];
14096
#endif
14097
   int      x, err;
14098
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
14099
   int first;
14100
14101
#ifdef WOLFSSL_SMALL_STACK
14102
   /* each is zeroed on acquisition so the cleanup below no-ops if a later
14103
    * allocation fails and the init is skipped */
14104
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14105
   if (tka == NULL) {
14106
      err = MEMORY_E; goto done;
14107
   }
14108
   XMEMSET(tka, 0, sizeof(mp_int));
14109
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14110
   if (tkb == NULL) {
14111
      err = MEMORY_E; goto done;
14112
   }
14113
   XMEMSET(tkb, 0, sizeof(mp_int));
14114
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14115
   if (order == NULL) {
14116
      err = MEMORY_E; goto done;
14117
   }
14118
   XMEMSET(order, 0, sizeof(mp_int));
14119
#endif
14120
14121
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
14122
      err = MP_INIT_E; goto done;
14123
   }
14124
14125
   /* if it's smaller than modulus we fine */
14126
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
14127
      /* find order */
14128
      y = (unsigned)mp_unsigned_bin_size(modulus);
14129
      for (x = 0; ecc_sets[x].size; x++) {
14130
         if (y <= (unsigned)ecc_sets[x].size) break;
14131
      }
14132
14133
      /* back off if we are on the 521 bit curve */
14134
      if (y == 66) --x;
14135
14136
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14137
                                                MP_RADIX_HEX)) != MP_OKAY) {
14138
         goto done;
14139
      }
14140
14141
      /* kA must be less than modulus */
14142
      if (mp_cmp(kA, order) != MP_LT) {
14143
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
14144
            goto done;
14145
         }
14146
      } else {
14147
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14148
            goto done;
14149
         }
14150
      }
14151
   } else {
14152
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14153
         goto done;
14154
      }
14155
   }
14156
#ifdef WOLFSSL_CHECK_MEM_ZERO
14157
   mp_memzero_add("accel_fp_mul2add tka", tka);
14158
#endif
14159
14160
   /* if it's smaller than modulus we fine */
14161
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
14162
      /* find order */
14163
      y = (unsigned)mp_unsigned_bin_size(modulus);
14164
      for (x = 0; ecc_sets[x].size; x++) {
14165
         if (y <= (unsigned)ecc_sets[x].size) break;
14166
      }
14167
14168
      /* back off if we are on the 521 bit curve */
14169
      if (y == 66) --x;
14170
14171
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14172
                                                MP_RADIX_HEX)) != MP_OKAY) {
14173
         goto done;
14174
      }
14175
14176
      /* kB must be less than modulus */
14177
      if (mp_cmp(kB, order) != MP_LT) {
14178
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
14179
            goto done;
14180
         }
14181
      } else {
14182
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14183
            goto done;
14184
         }
14185
      }
14186
   } else {
14187
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14188
         goto done;
14189
      }
14190
   }
14191
#ifdef WOLFSSL_CHECK_MEM_ZERO
14192
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
14193
#endif
14194
14195
   /* get bitlen and round up to next multiple of FP_LUT */
14196
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
14197
   x       = bitlen % FP_LUT;
14198
   if (x) {
14199
      bitlen += FP_LUT - (unsigned)x;
14200
   }
14201
   lut_gap = bitlen / FP_LUT;
14202
14203
   /* get the k value */
14204
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
14205
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
14206
      err = BUFFER_E; goto done;
14207
   }
14208
14209
   /* store k */
14210
#ifdef WOLFSSL_SMALL_STACK
14211
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14212
   if (kb[0] == NULL) {
14213
      err = MEMORY_E; goto done;
14214
   }
14215
#endif
14216
14217
   XMEMSET(kb[0], 0, KB_SIZE);
14218
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
14219
      goto done;
14220
   }
14221
#ifdef WOLFSSL_CHECK_MEM_ZERO
14222
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
14223
#endif
14224
14225
   /* let's reverse kb so it's little endian */
14226
   x = 0;
14227
   y = (unsigned)mp_unsigned_bin_size(tka);
14228
   if (y > 0) {
14229
       y -= 1;
14230
   }
14231
   mp_clear(tka);
14232
   while ((unsigned)x < y) {
14233
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
14234
      ++x; --y;
14235
   }
14236
14237
   /* store b */
14238
#ifdef WOLFSSL_SMALL_STACK
14239
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14240
   if (kb[1] == NULL) {
14241
      err = MEMORY_E; goto done;
14242
   }
14243
#endif
14244
14245
   XMEMSET(kb[1], 0, KB_SIZE);
14246
#ifdef WOLFSSL_CHECK_MEM_ZERO
14247
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
14248
#endif
14249
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
14250
      x = 0;
14251
      y = (unsigned)mp_unsigned_bin_size(tkb);
14252
      if (y > 0) {
14253
          y -= 1;
14254
      }
14255
14256
      while ((unsigned)x < y) {
14257
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
14258
         ++x; --y;
14259
      }
14260
14261
      /* at this point we can start, yipee */
14262
      first = 1;
14263
      for (x = (int)lut_gap-1; x >= 0; x--) {
14264
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
14265
             offset by x bits from the start */
14266
          bitpos = (unsigned)x;
14267
          for (y = zA = zB = 0; y < FP_LUT; y++) {
14268
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14269
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14270
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
14271
                                      the mult in each loop */
14272
          }
14273
14274
          /* double if not first */
14275
          if (!first) {
14276
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14277
                                                              mp)) != MP_OKAY) {
14278
                break;
14279
             }
14280
14281
             /* add if not first, otherwise copy */
14282
             if (zA) {
14283
                if ((err = ecc_projective_add_point_safe(R,
14284
                                             fp_cache[idx1].LUT[zA], R, a,
14285
                                             modulus, mp, &first)) != MP_OKAY) {
14286
                   break;
14287
                }
14288
             }
14289
14290
             if (zB) {
14291
                if ((err = ecc_projective_add_point_safe(R,
14292
                                             fp_cache[idx2].LUT[zB], R, a,
14293
                                             modulus, mp, &first)) != MP_OKAY) {
14294
                   break;
14295
                }
14296
             }
14297
          } else {
14298
             if (zA) {
14299
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
14300
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
14301
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
14302
                     err = MP_MEM;
14303
                     break;
14304
                 }
14305
                    first = 0;
14306
             }
14307
             if (zB && first == 0) {
14308
                if ((err = ecc_projective_add_point_safe(R,
14309
                                        fp_cache[idx2].LUT[zB], R, a,
14310
                                        modulus, mp, &first)) != MP_OKAY){
14311
                   break;
14312
                }
14313
             } else if (zB && first == 1) {
14314
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
14315
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
14316
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
14317
                     err = MP_MEM;
14318
                     break;
14319
                 }
14320
                    first = 0;
14321
             }
14322
          }
14323
      }
14324
   }
14325
14326
done:
14327
   /* cleanup */
14328
   mp_forcezero(tkb);
14329
   mp_forcezero(tka);
14330
   mp_clear(order);
14331
14332
#ifdef WOLFSSL_SMALL_STACK
14333
   if (kb[0])
14334
#endif
14335
      ForceZero(kb[0], KB_SIZE);
14336
#ifdef WOLFSSL_SMALL_STACK
14337
   if (kb[1])
14338
#endif
14339
      ForceZero(kb[1], KB_SIZE);
14340
14341
#ifdef WOLFSSL_SMALL_STACK
14342
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14343
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14344
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14345
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14346
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14347
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14348
   wc_MemZero_Check(kb[1], KB_SIZE);
14349
   wc_MemZero_Check(kb[0], KB_SIZE);
14350
   mp_memzero_check(tkb);
14351
   mp_memzero_check(tka);
14352
#endif
14353
14354
#undef KB_SIZE
14355
14356
    if (err != MP_OKAY)
14357
        return err;
14358
14359
   return ecc_map(R, modulus, mp);
14360
}
14361
14362
14363
/** ECC Fixed Point mulmod global with heap hint used
14364
  Computes kA*A + kB*B = C using Shamir's Trick
14365
  A        First point to multiply
14366
  kA       What to multiple A by
14367
  B        Second point to multiply
14368
  kB       What to multiple B by
14369
  C        [out] Destination point (can overlap with A or B)
14370
  a        ECC curve parameter a
14371
  modulus  Modulus for curve
14372
  return MP_OKAY on success
14373
*/
14374
int ecc_mul2add(ecc_point* A, mp_int* kA,
14375
                ecc_point* B, mp_int* kB,
14376
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
14377
{
14378
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
14379
   mp_digit mp = 0;
14380
#ifdef WOLFSSL_SMALL_STACK
14381
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14382
14383
   if (mu == NULL)
14384
       return MP_MEM;
14385
#else
14386
   mp_int   mu[1];
14387
#endif
14388
14389
   err = mp_init(mu);
14390
   if (err != MP_OKAY) {
14391
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14392
       return err;
14393
   }
14394
14395
#ifndef HAVE_THREAD_LS
14396
#ifndef WOLFSSL_MUTEX_INITIALIZER
14397
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14398
        wc_InitMutex(&ecc_fp_lock);
14399
        initMutex = 1;
14400
   }
14401
#endif
14402
14403
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14404
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14405
      return BAD_MUTEX_E;
14406
   }
14407
#endif /* HAVE_THREAD_LS */
14408
14409
      /* find point */
14410
      idx1 = find_base(A);
14411
14412
      /* no entry? */
14413
      if (idx1 == -1) {
14414
         /* find hole and add it */
14415
         if ((idx1 = find_hole()) >= 0) {
14416
            err = add_entry(idx1, A);
14417
         }
14418
      }
14419
      if (err == MP_OKAY && idx1 != -1 && fp_cache[idx1].lru_count < (INT_MAX-1)) {
14420
         /* increment LRU */
14421
         ++(fp_cache[idx1].lru_count);
14422
      }
14423
14424
      if (err == MP_OKAY) {
14425
        /* find point */
14426
        idx2 = find_base(B);
14427
14428
        /* no entry? */
14429
        if (idx2 == -1) {
14430
           /* find hole and add it */
14431
           if ((idx2 = find_hole()) >= 0)
14432
              err = add_entry(idx2, B);
14433
         }
14434
      }
14435
14436
      if (err == MP_OKAY && idx2 != -1 && fp_cache[idx2].lru_count < (INT_MAX-1)) {
14437
         /* increment LRU */
14438
         ++(fp_cache[idx2].lru_count);
14439
      }
14440
14441
      if (err == MP_OKAY) {
14442
        /* if it's >= 2 AND the LUT is not set build the LUT */
14443
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
14444
           /* compute mp */
14445
           err = mp_montgomery_setup(modulus, &mp);
14446
14447
           if (err == MP_OKAY) {
14448
             mpInit = 1;
14449
             err = mp_montgomery_calc_normalization(mu, modulus);
14450
           }
14451
14452
           if (err == MP_OKAY)
14453
             /* build the LUT */
14454
             err = build_lut(idx1, a, modulus, mp, mu);
14455
        }
14456
      }
14457
14458
      if (err == MP_OKAY) {
14459
        /* if it's >= 2 AND the LUT is not set build the LUT */
14460
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
14461
           if (mpInit == 0) {
14462
                /* compute mp */
14463
                err = mp_montgomery_setup(modulus, &mp);
14464
                if (err == MP_OKAY) {
14465
                    mpInit = 1;
14466
                    err = mp_montgomery_calc_normalization(mu, modulus);
14467
                }
14468
            }
14469
14470
            if (err == MP_OKAY)
14471
              /* build the LUT */
14472
              err = build_lut(idx2, a, modulus, mp, mu);
14473
        }
14474
      }
14475
14476
14477
      if (err == MP_OKAY) {
14478
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
14479
                                     fp_cache[idx2].LUT_set) {
14480
           if (mpInit == 0) {
14481
              /* compute mp */
14482
              err = mp_montgomery_setup(modulus, &mp);
14483
           }
14484
           if (err == MP_OKAY)
14485
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
14486
        } else {
14487
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
14488
        }
14489
      }
14490
14491
#ifndef HAVE_THREAD_LS
14492
    wc_UnLockMutex(&ecc_fp_lock);
14493
#endif /* HAVE_THREAD_LS */
14494
    mp_clear(mu);
14495
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14496
14497
    return err;
14498
}
14499
#endif
14500
#endif /* ECC_SHAMIR */
14501
14502
/** ECC Fixed Point mulmod global
14503
    k        The multiplicand
14504
    G        Base point to multiply
14505
    R        [out] Destination of product
14506
    a        ECC curve parameter a
14507
    modulus  The modulus for the curve
14508
    map      [boolean] If non-zero maps the point back to affine coordinates,
14509
             otherwise it's left in jacobian-montgomery form
14510
    return MP_OKAY if successful
14511
*/
14512
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
14513
    mp_int* modulus, int map, void* heap)
14514
{
14515
#if !defined(WOLFSSL_SP_MATH)
14516
   int   idx, err = MP_OKAY;
14517
   mp_digit mp = 0;
14518
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
14519
   int      mpSetup = 0;
14520
#ifndef HAVE_THREAD_LS
14521
   int got_ecc_fp_lock = 0;
14522
#endif
14523
14524
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
14525
       return ECC_BAD_ARG_E;
14526
   }
14527
14528
   /* k can't have more bits than modulus count plus 1 */
14529
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
14530
      return ECC_OUT_OF_RANGE_E;
14531
   }
14532
14533
#ifdef WOLFSSL_SMALL_STACK
14534
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14535
       return MP_MEM;
14536
#endif
14537
14538
   if (mp_init(mu) != MP_OKAY) {
14539
       err = MP_INIT_E;
14540
       goto out;
14541
   }
14542
14543
#ifndef HAVE_THREAD_LS
14544
#ifndef WOLFSSL_MUTEX_INITIALIZER
14545
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14546
        wc_InitMutex(&ecc_fp_lock);
14547
        initMutex = 1;
14548
   }
14549
#endif
14550
14551
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14552
      err = BAD_MUTEX_E;
14553
      goto out;
14554
   }
14555
   got_ecc_fp_lock = 1;
14556
#endif /* HAVE_THREAD_LS */
14557
14558
      /* find point */
14559
      idx = find_base(G);
14560
14561
      /* no entry? */
14562
      if (idx == -1) {
14563
         /* find hole and add it */
14564
         idx = find_hole();
14565
14566
         if (idx >= 0)
14567
            err = add_entry(idx, G);
14568
      }
14569
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14570
         /* increment LRU */
14571
         ++(fp_cache[idx].lru_count);
14572
      }
14573
14574
14575
      if (err == MP_OKAY) {
14576
        /* if it's 2 build the LUT, if it's higher just use the LUT */
14577
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14578
           /* compute mp */
14579
           err = mp_montgomery_setup(modulus, &mp);
14580
14581
           if (err == MP_OKAY) {
14582
             /* compute mu */
14583
             mpSetup = 1;
14584
             err = mp_montgomery_calc_normalization(mu, modulus);
14585
           }
14586
14587
           if (err == MP_OKAY)
14588
             /* build the LUT */
14589
             err = build_lut(idx, a, modulus, mp, mu);
14590
        }
14591
      }
14592
14593
      if (err == MP_OKAY) {
14594
        if (idx >= 0 && fp_cache[idx].LUT_set) {
14595
           if (mpSetup == 0) {
14596
              /* compute mp */
14597
              err = mp_montgomery_setup(modulus, &mp);
14598
           }
14599
           if (err == MP_OKAY)
14600
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14601
        } else {
14602
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
14603
        }
14604
      }
14605
14606
  out:
14607
14608
#ifndef HAVE_THREAD_LS
14609
    if (got_ecc_fp_lock)
14610
        wc_UnLockMutex(&ecc_fp_lock);
14611
#endif /* HAVE_THREAD_LS */
14612
    mp_clear(mu);
14613
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14614
14615
    return err;
14616
14617
#else /* WOLFSSL_SP_MATH */
14618
14619
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
14620
        return ECC_BAD_ARG_E;
14621
    }
14622
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14623
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14624
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14625
        return IS_POINT_E;
14626
    }
14627
14628
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14629
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14630
        int ret;
14631
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14632
        return ret;
14633
    }
14634
#endif
14635
#ifndef WOLFSSL_SP_NO_256
14636
    if (mp_count_bits(modulus) == 256) {
14637
        int ret;
14638
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14639
        return ret;
14640
    }
14641
#endif
14642
#ifdef WOLFSSL_SP_384
14643
    if (mp_count_bits(modulus) == 384) {
14644
        int ret;
14645
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14646
        return ret;
14647
    }
14648
#endif
14649
#ifdef WOLFSSL_SP_521
14650
    if (mp_count_bits(modulus) == 521) {
14651
        int ret;
14652
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14653
        return ret;
14654
    }
14655
#endif
14656
    return WC_KEY_SIZE_E;
14657
#endif /* WOLFSSL_SP_MATH */
14658
}
14659
14660
/** ECC Fixed Point mulmod global
14661
    k        The multiplicand
14662
    G        Base point to multiply
14663
    R        [out] Destination of product
14664
    a        ECC curve parameter a
14665
    modulus  The modulus for the curve
14666
    map      [boolean] If non-zero maps the point back to affine coordinates,
14667
             otherwise it's left in jacobian-montgomery form
14668
    return MP_OKAY if successful
14669
*/
14670
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
14671
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
14672
{
14673
#if !defined(WOLFSSL_SP_MATH)
14674
   int   idx, err = MP_OKAY;
14675
   mp_digit mp = 0;
14676
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
14677
   int      mpSetup = 0;
14678
#ifndef HAVE_THREAD_LS
14679
   int got_ecc_fp_lock = 0;
14680
#endif
14681
14682
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14683
                                                                order == NULL) {
14684
       return ECC_BAD_ARG_E;
14685
   }
14686
14687
   /* k can't have more bits than order */
14688
   if (mp_count_bits(k) > mp_count_bits(order)) {
14689
      return ECC_OUT_OF_RANGE_E;
14690
   }
14691
14692
#ifdef WOLFSSL_SMALL_STACK
14693
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14694
       return MP_MEM;
14695
#endif
14696
14697
   if (mp_init(mu) != MP_OKAY) {
14698
       err = MP_INIT_E;
14699
       goto out;
14700
   }
14701
14702
#ifndef HAVE_THREAD_LS
14703
#ifndef WOLFSSL_MUTEX_INITIALIZER
14704
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14705
        wc_InitMutex(&ecc_fp_lock);
14706
        initMutex = 1;
14707
   }
14708
#endif
14709
14710
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14711
      err = BAD_MUTEX_E;
14712
      goto out;
14713
   }
14714
   got_ecc_fp_lock = 1;
14715
#endif /* HAVE_THREAD_LS */
14716
14717
      /* find point */
14718
      idx = find_base(G);
14719
14720
      /* no entry? */
14721
      if (idx == -1) {
14722
         /* find hole and add it */
14723
         idx = find_hole();
14724
14725
         if (idx >= 0)
14726
            err = add_entry(idx, G);
14727
      }
14728
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14729
         /* increment LRU */
14730
         ++(fp_cache[idx].lru_count);
14731
      }
14732
14733
14734
      if (err == MP_OKAY) {
14735
        /* if it's 2 build the LUT, if it's higher just use the LUT */
14736
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14737
           /* compute mp */
14738
           err = mp_montgomery_setup(modulus, &mp);
14739
14740
           if (err == MP_OKAY) {
14741
             /* compute mu */
14742
             mpSetup = 1;
14743
             err = mp_montgomery_calc_normalization(mu, modulus);
14744
           }
14745
14746
           if (err == MP_OKAY)
14747
             /* build the LUT */
14748
             err = build_lut(idx, a, modulus, mp, mu);
14749
        }
14750
      }
14751
14752
      if (err == MP_OKAY) {
14753
        if (idx >= 0 && fp_cache[idx].LUT_set) {
14754
           if (mpSetup == 0) {
14755
              /* compute mp */
14756
              err = mp_montgomery_setup(modulus, &mp);
14757
           }
14758
           if (err == MP_OKAY)
14759
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14760
        } else {
14761
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
14762
        }
14763
      }
14764
14765
  out:
14766
14767
#ifndef HAVE_THREAD_LS
14768
    if (got_ecc_fp_lock)
14769
        wc_UnLockMutex(&ecc_fp_lock);
14770
#endif /* HAVE_THREAD_LS */
14771
    mp_clear(mu);
14772
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14773
14774
    return err;
14775
14776
#else /* WOLFSSL_SP_MATH */
14777
14778
    (void)rng;
14779
14780
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14781
                                                                order == NULL) {
14782
        return ECC_BAD_ARG_E;
14783
    }
14784
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14785
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14786
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14787
        return IS_POINT_E;
14788
    }
14789
14790
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14791
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14792
        int ret;
14793
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14794
        return ret;
14795
    }
14796
#endif
14797
#ifndef WOLFSSL_SP_NO_256
14798
    if (mp_count_bits(modulus) == 256) {
14799
        int ret;
14800
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14801
        return ret;
14802
    }
14803
#endif
14804
#ifdef WOLFSSL_SP_384
14805
    if (mp_count_bits(modulus) == 384) {
14806
        int ret;
14807
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14808
        return ret;
14809
    }
14810
#endif
14811
#ifdef WOLFSSL_SP_521
14812
    if (mp_count_bits(modulus) == 521) {
14813
        int ret;
14814
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14815
        return ret;
14816
    }
14817
#endif
14818
    return WC_KEY_SIZE_E;
14819
#endif /* WOLFSSL_SP_MATH */
14820
}
14821
14822
#if !defined(WOLFSSL_SP_MATH)
14823
/* helper function for freeing the cache ...
14824
   must be called with the cache mutex locked */
14825
static void wc_ecc_fp_free_cache(void)
14826
{
14827
   unsigned x, y;
14828
   for (x = 0; x < FP_ENTRIES; x++) {
14829
      if (fp_cache[x].g != NULL) {
14830
         for (y = 0; y < (1U<<FP_LUT); y++) {
14831
            wc_ecc_del_point(fp_cache[x].LUT[y]);
14832
            fp_cache[x].LUT[y] = NULL;
14833
         }
14834
         wc_ecc_del_point(fp_cache[x].g);
14835
         fp_cache[x].g         = NULL;
14836
         mp_clear(&fp_cache[x].mu);
14837
         fp_cache[x].LUT_set   = 0;
14838
         fp_cache[x].lru_count = 0;
14839
         fp_cache[x].lock = 0;
14840
      }
14841
   }
14842
}
14843
#endif
14844
14845
14846
/** Init the Fixed Point cache */
14847
void wc_ecc_fp_init(void)
14848
{
14849
#ifndef WOLFSSL_SP_MATH
14850
#ifndef HAVE_THREAD_LS
14851
#ifndef WOLFSSL_MUTEX_INITIALIZER
14852
   if (initMutex == 0) {
14853
        wc_InitMutex(&ecc_fp_lock);
14854
        initMutex = 1;
14855
   }
14856
#endif
14857
#endif
14858
#endif
14859
}
14860
14861
14862
/** Free the Fixed Point cache */
14863
WOLFSSL_ABI
14864
void wc_ecc_fp_free(void)
14865
{
14866
#if !defined(WOLFSSL_SP_MATH)
14867
#ifndef HAVE_THREAD_LS
14868
#ifndef WOLFSSL_MUTEX_INITIALIZER
14869
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14870
        wc_InitMutex(&ecc_fp_lock);
14871
        initMutex = 1;
14872
   }
14873
#endif
14874
14875
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
14876
#endif /* HAVE_THREAD_LS */
14877
14878
       wc_ecc_fp_free_cache();
14879
14880
#ifndef HAVE_THREAD_LS
14881
       wc_UnLockMutex(&ecc_fp_lock);
14882
#ifndef WOLFSSL_MUTEX_INITIALIZER
14883
       wc_FreeMutex(&ecc_fp_lock);
14884
       initMutex = 0;
14885
#endif
14886
   }
14887
#endif /* HAVE_THREAD_LS */
14888
#endif
14889
}
14890
14891
14892
#endif /* FP_ECC */
14893
14894
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
14895
3.10k
{
14896
3.10k
    int err = 0;
14897
14898
3.10k
#ifdef ECC_TIMING_RESISTANT
14899
3.10k
    if (key == NULL) {
14900
0
        err = BAD_FUNC_ARG;
14901
0
    }
14902
3.10k
    else {
14903
3.10k
        key->rng = rng;
14904
3.10k
    }
14905
#else
14906
    (void)key;
14907
    (void)rng;
14908
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
14909
#endif
14910
14911
3.10k
    return err;
14912
3.10k
}
14913
14914
#ifdef HAVE_ECC_ENCRYPT
14915
14916
14917
enum ecCliState {
14918
    ecCLI_INIT      = 1,
14919
    ecCLI_SALT_GET  = 2,
14920
    ecCLI_SALT_SET  = 3,
14921
    ecCLI_SENT_REQ  = 4,
14922
    ecCLI_RECV_RESP = 5,
14923
    ecCLI_BAD_STATE = 99
14924
};
14925
14926
enum ecSrvState {
14927
    ecSRV_INIT      = 1,
14928
    ecSRV_SALT_GET  = 2,
14929
    ecSRV_SALT_SET  = 3,
14930
    ecSRV_RECV_REQ  = 4,
14931
    ecSRV_SENT_RESP = 5,
14932
    ecSRV_BAD_STATE = 99
14933
};
14934
14935
14936
struct ecEncCtx {
14937
    byte* kdfSalt;         /* optional salt for kdf */
14938
    const byte* kdfInfo;   /* optional info for kdf */
14939
    const byte* macSalt;   /* optional salt for mac */
14940
    word32    kdfSaltSz;   /* size of kdfSalt */
14941
    word32    kdfInfoSz;   /* size of kdfInfo */
14942
    word32    macSaltSz;   /* size of macSalt */
14943
    void*     heap;        /* heap hint for memory used */
14944
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14945
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14946
    byte      encAlgo;     /* which encryption type */
14947
    byte      kdfAlgo;     /* which key derivation function type */
14948
    byte      macAlgo;     /* which mac function type */
14949
    byte      protocol;    /* are we REQ_RESP client or server ? */
14950
    byte      cliSt;       /* protocol state, for sanity checks */
14951
    byte      srvSt;       /* protocol state, for sanity checks */
14952
    WC_RNG*   rng;
14953
};
14954
14955
/* optional set info, can be called before or after set_peer_salt */
14956
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
14957
0
{
14958
0
    if (ctx == NULL)
14959
0
        return BAD_FUNC_ARG;
14960
14961
0
    ctx->encAlgo = encAlgo;
14962
0
    ctx->kdfAlgo = kdfAlgo;
14963
0
    ctx->macAlgo = macAlgo;
14964
14965
0
    return 0;
14966
0
}
14967
14968
#ifdef WOLF_CRYPTO_CB
14969
/* Read back the parameters a caller configured on the context.  Intended for
14970
 * crypto-callback backends (e.g. a hardware ECIES engine) that must reproduce
14971
 * the algorithm, KDF salt and KDF info to run the operation off-device.  Only
14972
 * built when crypto callbacks are enabled, so default builds are unaffected. */
14973
int wc_ecc_ctx_get_algo(ecEncCtx* ctx, byte* encAlgo, byte* kdfAlgo,
14974
                        byte* macAlgo)
14975
0
{
14976
0
    if (ctx == NULL)
14977
0
        return BAD_FUNC_ARG;
14978
14979
0
    if (encAlgo != NULL)
14980
0
        *encAlgo = ctx->encAlgo;
14981
0
    if (kdfAlgo != NULL)
14982
0
        *kdfAlgo = ctx->kdfAlgo;
14983
0
    if (macAlgo != NULL)
14984
0
        *macAlgo = ctx->macAlgo;
14985
14986
0
    return 0;
14987
0
}
14988
14989
int wc_ecc_ctx_get_kdf_salt(ecEncCtx* ctx, const byte** salt, word32* sz)
14990
0
{
14991
0
    if (ctx == NULL || salt == NULL || sz == NULL)
14992
0
        return BAD_FUNC_ARG;
14993
14994
0
    *salt = ctx->kdfSalt;
14995
0
    *sz   = ctx->kdfSaltSz;
14996
14997
0
    return 0;
14998
0
}
14999
15000
int wc_ecc_ctx_get_info(ecEncCtx* ctx, const byte** info, word32* sz)
15001
0
{
15002
0
    if (ctx == NULL || info == NULL || sz == NULL)
15003
0
        return BAD_FUNC_ARG;
15004
15005
0
    *info = ctx->kdfInfo;
15006
0
    *sz   = ctx->kdfInfoSz;
15007
15008
0
    return 0;
15009
0
}
15010
#endif /* WOLF_CRYPTO_CB */
15011
15012
15013
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
15014
0
{
15015
0
    if (ctx == NULL || ctx->protocol == 0)
15016
0
        return NULL;
15017
15018
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
15019
0
        if (ctx->cliSt == ecCLI_INIT) {
15020
0
            ctx->cliSt =  ecCLI_SALT_GET;
15021
0
            return ctx->clientSalt;
15022
0
        }
15023
0
        else {
15024
0
            ctx->cliSt = ecCLI_BAD_STATE;
15025
0
            return NULL;
15026
0
        }
15027
0
    }
15028
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
15029
0
        if (ctx->srvSt == ecSRV_INIT) {
15030
0
            ctx->srvSt =  ecSRV_SALT_GET;
15031
0
            return ctx->serverSalt;
15032
0
        }
15033
0
        else {
15034
0
            ctx->srvSt = ecSRV_BAD_STATE;
15035
0
            return NULL;
15036
0
        }
15037
0
    }
15038
15039
0
    return NULL;
15040
0
}
15041
15042
15043
/* optional set info, can be called before or after set_peer_salt */
15044
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
15045
0
{
15046
0
    if (ctx == NULL || info == 0 || sz < 0)
15047
0
        return BAD_FUNC_ARG;
15048
15049
0
    ctx->kdfInfo   = info;
15050
0
    ctx->kdfInfoSz = (word32)sz;
15051
15052
0
    return 0;
15053
0
}
15054
15055
15056
static const char* exchange_info = "Secure Message Exchange";
15057
15058
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
15059
0
{
15060
0
    byte tmp[EXCHANGE_SALT_SZ/2];
15061
0
    int  halfSz = EXCHANGE_SALT_SZ/2;
15062
15063
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15064
0
        return BAD_FUNC_ARG;
15065
15066
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
15067
0
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
15068
0
        if (ctx->cliSt == ecCLI_SALT_GET)
15069
0
            ctx->cliSt =  ecCLI_SALT_SET;
15070
0
        else {
15071
0
            ctx->cliSt =  ecCLI_BAD_STATE;
15072
0
            return BAD_STATE_E;
15073
0
        }
15074
0
    }
15075
0
    else {
15076
0
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
15077
0
        if (ctx->srvSt == ecSRV_SALT_GET)
15078
0
            ctx->srvSt =  ecSRV_SALT_SET;
15079
0
        else {
15080
0
            ctx->srvSt =  ecSRV_BAD_STATE;
15081
0
            return BAD_STATE_E;
15082
0
        }
15083
0
    }
15084
15085
    /* mix half and half */
15086
    /* tmp stores 2nd half of client before overwrite */
15087
0
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
15088
0
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
15089
0
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
15090
15091
0
    ctx->kdfSalt   = ctx->clientSalt;
15092
0
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
15093
15094
0
    ctx->macSalt   = ctx->serverSalt;
15095
0
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
15096
15097
0
    if (ctx->kdfInfo == NULL) {
15098
        /* default info */
15099
0
        ctx->kdfInfo   = (const byte*)exchange_info;
15100
0
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
15101
0
    }
15102
15103
0
    return 0;
15104
0
}
15105
15106
/* Set the salt pointer into context.
15107
 *
15108
 * @param  [in, out]  ctx   ECIES context object.
15109
 * @param  [in]       salt  Salt to use with KDF.
15110
 * @param  [in]       sz    Length of salt in bytes.
15111
 * @return  0 on success.
15112
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15113
 */
15114
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15115
0
{
15116
0
    if (ctx == NULL || (salt == NULL && sz != 0))
15117
0
        return BAD_FUNC_ARG;
15118
15119
    /* truncate salt if exceeds max */
15120
0
    if (sz > EXCHANGE_SALT_SZ)
15121
0
        sz = EXCHANGE_SALT_SZ;
15122
15123
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
15124
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
15125
0
    if (ctx->protocol == REQ_RESP_CLIENT) {
15126
0
        ctx->cliSt = ecCLI_SALT_SET;
15127
0
        ctx->kdfSalt = ctx->clientSalt;
15128
0
    }
15129
0
    else if (ctx->protocol == REQ_RESP_SERVER) {
15130
0
        ctx->srvSt = ecSRV_SALT_SET;
15131
0
        ctx->kdfSalt = ctx->serverSalt;
15132
0
    }
15133
15134
0
    if (salt != NULL) {
15135
0
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
15136
0
    }
15137
0
    ctx->kdfSaltSz = sz;
15138
15139
0
    return 0;
15140
0
}
15141
15142
/* Set your own salt. By default we generate a random salt for ourselves.
15143
 * This allows overriding that after init or reset.
15144
 *
15145
 * @param  [in, out]  ctx   ECIES context object.
15146
 * @param  [in]       salt  Salt to use for ourselves
15147
 * @param  [in]       sz    Length of salt in bytes.
15148
 * @return  0 on success.
15149
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15150
 */
15151
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15152
0
{
15153
0
    byte* saltBuffer;
15154
15155
0
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15156
0
        return BAD_FUNC_ARG;
15157
15158
0
    if (sz > EXCHANGE_SALT_SZ)
15159
0
        sz = EXCHANGE_SALT_SZ;
15160
0
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
15161
0
        ctx->clientSalt :
15162
0
        ctx->serverSalt;
15163
0
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
15164
0
    XMEMCPY(saltBuffer, salt, sz);
15165
15166
0
    return 0;
15167
0
}
15168
15169
15170
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
15171
0
{
15172
0
    byte* saltBuffer;
15173
15174
0
    if (ctx == NULL || flags == 0)
15175
0
        return BAD_FUNC_ARG;
15176
15177
0
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
15178
15179
0
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
15180
0
}
15181
15182
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
15183
579
{
15184
579
    if (ctx) {
15185
579
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
15186
15187
579
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15188
579
        #ifdef WOLFSSL_AES_128
15189
579
            ctx->encAlgo  = ecAES_128_CBC;
15190
        #else
15191
            ctx->encAlgo  = ecAES_256_CBC;
15192
        #endif
15193
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15194
        #ifdef WOLFSSL_AES_256
15195
            ctx->encAlgo  = ecAES_256_CTR;
15196
        #else
15197
            ctx->encAlgo  = ecAES_128_CTR;
15198
        #endif
15199
    #elif !defined(NO_AES) && defined(HAVE_AESGCM) && \
15200
        (defined(WOLFSSL_ECIES_OLD) || defined(WOLFSSL_ECIES_GEN_IV) || \
15201
         defined(WOLFSSL_ECIES_STATIC_GCM_NONCE))
15202
        /* Only default to GCM when the configured IV mode permits it, so a
15203
         * GCM-only build cannot default to an algorithm that encrypt/decrypt
15204
         * would reject with NOT_COMPILED_IN. */
15205
        #ifdef WOLFSSL_AES_128
15206
            ctx->encAlgo  = ecAES_128_GCM;
15207
        #else
15208
            ctx->encAlgo  = ecAES_256_GCM;
15209
        #endif
15210
    #else
15211
        /* In a GCM-only build using the default IV mode, define
15212
         * WOLFSSL_ECIES_STATIC_GCM_NONCE to opt in to the fixed-nonce DEM. */
15213
        #error "No valid encryption algorithm for ECIES configured."
15214
    #endif
15215
579
        ctx->kdfAlgo  = ecHKDF_SHA256;
15216
579
        ctx->macAlgo  = ecHMAC_SHA256;
15217
579
        ctx->protocol = (byte)flags;
15218
579
        ctx->rng      = rng;
15219
15220
579
        if (flags == REQ_RESP_CLIENT)
15221
0
            ctx->cliSt = ecCLI_INIT;
15222
579
        if (flags == REQ_RESP_SERVER)
15223
0
            ctx->srvSt = ecSRV_INIT;
15224
579
    }
15225
579
}
15226
15227
15228
/* allow ecc context reset so user doesn't have to init/free for reuse */
15229
WOLFSSL_ABI
15230
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
15231
0
{
15232
0
    void* heap;
15233
15234
0
    if (ctx == NULL || rng == NULL)
15235
0
        return BAD_FUNC_ARG;
15236
15237
    /* ecc_ctx_init clears the whole context, so carry the heap hint over it.
15238
     * The context has to be freed to the heap it was allocated from. */
15239
0
    heap = ctx->heap;
15240
0
    ecc_ctx_init(ctx, ctx->protocol, rng);
15241
0
    ctx->heap = heap;
15242
15243
0
    return ecc_ctx_set_salt(ctx, ctx->protocol);
15244
0
}
15245
15246
15247
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
15248
0
{
15249
0
    int       ret = 0;
15250
0
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
15251
0
                                                              DYNAMIC_TYPE_ECC);
15252
15253
0
    if (ctx) {
15254
0
        ctx->protocol = (byte)flags;
15255
0
        ctx->heap     = heap;
15256
0
    }
15257
15258
0
    ret = wc_ecc_ctx_reset(ctx, rng);
15259
0
    if (ret != 0) {
15260
0
        wc_ecc_ctx_free(ctx);
15261
0
        ctx = NULL;
15262
0
    }
15263
15264
0
    return ctx;
15265
0
}
15266
15267
15268
/* alloc/init and set defaults, return new Context  */
15269
WOLFSSL_ABI
15270
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
15271
0
{
15272
0
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
15273
0
}
15274
15275
15276
/* free any resources, clear any keys */
15277
WOLFSSL_ABI
15278
void wc_ecc_ctx_free(ecEncCtx* ctx)
15279
0
{
15280
0
    if (ctx) {
15281
0
        void* heap = ctx->heap;
15282
0
        ForceZero(ctx, sizeof(ecEncCtx));
15283
0
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
15284
0
        (void)heap;
15285
0
    }
15286
0
}
15287
15288
#if !defined(NO_AES) && defined(HAVE_AESGCM)
15289
/* Is the ECIES encryption algorithm an AES-GCM (AEAD) mode?  GCM replaces the
15290
 * AES + HMAC pair with a single authenticated-encryption pass. */
15291
static WC_INLINE int ecc_is_gcm(byte encAlgo)
15292
2.40k
{
15293
2.40k
    return (encAlgo == ecAES_128_GCM || encAlgo == ecAES_256_GCM);
15294
2.40k
}
15295
#else
15296
/* Compile GCM branches out entirely when AES-GCM isn't available. */
15297
#define ecc_is_gcm(encAlgo) (0)
15298
#endif
15299
15300
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
15301
                             int* keysLen, word32* digestSz, word32* blockSz)
15302
579
{
15303
579
    if (ctx) {
15304
579
        switch (ctx->encAlgo) {
15305
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15306
579
            case ecAES_128_CBC:
15307
579
                *encKeySz = KEY_SIZE_128;
15308
579
                *ivSz     = IV_SIZE_128;
15309
579
                *blockSz  = WC_AES_BLOCK_SIZE;
15310
579
                break;
15311
0
            case ecAES_256_CBC:
15312
0
                *encKeySz = KEY_SIZE_256;
15313
0
                *ivSz     = IV_SIZE_128;
15314
0
                *blockSz  = WC_AES_BLOCK_SIZE;
15315
0
                break;
15316
0
        #endif
15317
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15318
0
            case ecAES_128_CTR:
15319
0
                *encKeySz = KEY_SIZE_128;
15320
0
                *ivSz     = 12;
15321
0
                *blockSz  = 1;
15322
0
                break;
15323
0
            case ecAES_256_CTR:
15324
0
                *encKeySz = KEY_SIZE_256;
15325
0
                *ivSz     = 12;
15326
0
                *blockSz  = 1;
15327
0
                break;
15328
0
        #endif
15329
0
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
15330
0
            case ecAES_128_GCM:
15331
0
                *encKeySz = KEY_SIZE_128;
15332
0
                *ivSz     = GCM_NONCE_MID_SZ;
15333
0
                *blockSz  = 1;
15334
0
                break;
15335
0
            case ecAES_256_GCM:
15336
0
                *encKeySz = KEY_SIZE_256;
15337
0
                *ivSz     = GCM_NONCE_MID_SZ;
15338
0
                *blockSz  = 1;
15339
0
                break;
15340
0
        #endif
15341
0
            default:
15342
0
                return BAD_FUNC_ARG;
15343
579
        }
15344
15345
579
        if (ecc_is_gcm(ctx->encAlgo)) {
15346
            /* GCM is AEAD: the full block-sized tag replaces the HMAC digest,
15347
             * and no separate MAC algorithm/key is used. */
15348
0
            *digestSz = WC_AES_BLOCK_SIZE;
15349
0
        }
15350
579
        else {
15351
579
            switch (ctx->macAlgo) {
15352
579
                case ecHMAC_SHA256:
15353
579
                    *digestSz = WC_SHA256_DIGEST_SIZE;
15354
579
                    break;
15355
0
                default:
15356
0
                    return BAD_FUNC_ARG;
15357
579
            }
15358
579
        }
15359
579
    } else
15360
0
        return BAD_FUNC_ARG;
15361
15362
579
    if (ecc_is_gcm(ctx->encAlgo)) {
15363
        /* No MAC key.  The nonce follows the ECIES IV build mode, matching the
15364
         * CBC/CTR DEMs: derived from the KDF (OLD), a fresh random value
15365
         * (GEN_IV), or a fixed zero (default). */
15366
#ifdef WOLFSSL_ECIES_OLD
15367
        *keysLen = *encKeySz + *ivSz;   /* nonce is part of the KDF output */
15368
#else
15369
0
        *keysLen = *encKeySz;
15370
0
#endif
15371
0
    }
15372
579
    else {
15373
#ifdef WOLFSSL_ECIES_OLD
15374
        *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
15375
#else
15376
579
        *keysLen  = *encKeySz + (int)*digestSz;
15377
579
#endif
15378
579
    }
15379
15380
579
    return 0;
15381
579
}
15382
15383
/* Total ECIES output size for msgSz bytes of message: the ephemeral public
15384
 * key (not embedded in the OLD format), the IV/nonce when it is carried in
15385
 * the message (GEN_IV mode only), the ciphertext (same length as the padded
15386
 * plaintext), and the trailing HMAC digest or GCM tag.  Used both to
15387
 * bound-check the caller's output buffer and to report the final output
15388
 * size. */
15389
static word32 ecc_ecies_total_size(word32 pubKeySz, int ivSz, word32 msgSz,
15390
                                   word32 digestSz)
15391
375
{
15392
#ifdef WOLFSSL_ECIES_OLD
15393
    (void)pubKeySz;
15394
    (void)ivSz;
15395
    return msgSz + digestSz;
15396
#elif defined(WOLFSSL_ECIES_GEN_IV)
15397
    return pubKeySz + (word32)ivSz + msgSz + digestSz;
15398
#else
15399
375
    (void)ivSz;
15400
375
    return pubKeySz + msgSz + digestSz;
15401
375
#endif
15402
375
}
15403
15404
/* Validate and advance the single-use REQ/RESP protocol state for an encrypt.
15405
 * A no-op for the default (non REQ/RESP) protocol.  Returns BAD_STATE_E if the
15406
 * ctx is not in the state that permits an encrypt. */
15407
static int ecc_ctx_encrypt_advance(ecEncCtx* ctx)
15408
262
{
15409
262
    if (ctx == NULL)
15410
0
        return 0;
15411
262
    if (ctx->protocol == REQ_RESP_SERVER) {
15412
0
        if (ctx->srvSt != ecSRV_RECV_REQ)
15413
0
            return BAD_STATE_E;
15414
0
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
15415
0
    }
15416
262
    else if (ctx->protocol == REQ_RESP_CLIENT) {
15417
0
        if (ctx->cliSt != ecCLI_SALT_SET)
15418
0
            return BAD_STATE_E;
15419
0
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
15420
0
    }
15421
262
    return 0;
15422
262
}
15423
15424
/* Validate and advance the single-use REQ/RESP protocol state for a decrypt. */
15425
static int ecc_ctx_decrypt_advance(ecEncCtx* ctx)
15426
317
{
15427
317
    if (ctx == NULL)
15428
0
        return 0;
15429
317
    if (ctx->protocol == REQ_RESP_CLIENT) {
15430
0
        if (ctx->cliSt != ecCLI_SENT_REQ)
15431
0
            return BAD_STATE_E;
15432
0
        ctx->cliSt = ecCLI_BAD_STATE; /* we're done no more ops allowed */
15433
0
    }
15434
317
    else if (ctx->protocol == REQ_RESP_SERVER) {
15435
0
        if (ctx->srvSt != ecSRV_SALT_SET)
15436
0
            return BAD_STATE_E;
15437
0
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
15438
0
    }
15439
317
    return 0;
15440
317
}
15441
15442
15443
/* ecc encrypt with shared secret run through kdf
15444
   ctx holds non default algos and inputs
15445
   msgSz should be the right size for encAlgo, i.e., already padded
15446
   return 0 on success */
15447
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15448
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
15449
288
{
15450
288
    int          ret = 0;
15451
288
    word32       blockSz = 0;
15452
288
#ifndef WOLFSSL_ECIES_OLD
15453
288
#ifndef WOLFSSL_ECIES_GEN_IV
15454
288
    byte         iv[ECC_MAX_IV_SIZE];
15455
288
#endif
15456
288
#endif
15457
    /* Not in the output in OLD mode; kept 0 for ecc_ecies_total_size(). */
15458
288
    word32       pubKeySz = 0;
15459
288
    word32       digestSz = 0;
15460
288
    ecEncCtx     localCtx;
15461
288
#ifdef WOLFSSL_SMALL_STACK
15462
288
    byte*        sharedSecret;
15463
288
    byte*        keys;
15464
#else
15465
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15466
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
15467
#else
15468
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
15469
#endif
15470
    byte         keys[ECC_BUFSIZE];         /* max size */
15471
#endif
15472
288
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15473
288
    word32       sharedSz = ECC_MAXSIZE;
15474
#else
15475
    /* 'Uncompressed' byte | public key x | public key y | secret */
15476
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
15477
#endif
15478
288
    int          keysLen = 0;
15479
288
    int          encKeySz = 0;
15480
288
    int          ivSz = 0;
15481
288
    int          offset = 0;         /* keys offset if doing msg exchange */
15482
288
    byte*        encKey = NULL;
15483
288
    byte*        encIv = NULL;
15484
288
    byte*        macKey = NULL;
15485
    /* devId to hand the DEM AES/HMAC primitives; ecc_key only carries a devId
15486
     * field with PLUTON_CRYPTO_ECC or WOLF_CRYPTO_CB, so default to INVALID. */
15487
288
    int          eciesDevId = INVALID_DEVID;
15488
15489
288
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
15490
262
                           outSz  == NULL)
15491
26
        return BAD_FUNC_ARG;
15492
15493
262
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
15494
262
    eciesDevId = privKey->devId;
15495
262
#endif
15496
15497
262
#ifdef WOLF_CRYPTO_CB
15498
262
    #ifndef WOLF_CRYPTO_CB_FIND
15499
262
    if (privKey->devId != INVALID_DEVID)
15500
0
    #endif
15501
0
    {
15502
        /* Snapshot single-use state so we can tell whether the callback handled
15503
         * it purely in hardware (state untouched) versus re-entered software
15504
         * (which advances the state itself, below). */
15505
0
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
15506
0
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
15507
0
        ret = wc_CryptoCb_EciesEncrypt(privKey, pubKey, msg, msgSz, out, outSz,
15508
0
                                       ctx, compressed);
15509
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
15510
            /* Pure-hardware service left the state alone; enforce single-use
15511
             * here so the ctx can't be reused (nonce reuse for static-nonce
15512
             * GCM).  A re-entrant software callback already advanced it. */
15513
0
            if (ret == 0 && ctx != NULL &&
15514
0
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
15515
0
                ret = ecc_ctx_encrypt_advance(ctx);
15516
0
            return ret;
15517
0
        }
15518
        /* fall-through to software (ret is reassigned below) */
15519
0
    }
15520
262
#endif
15521
15522
262
    if (ctx == NULL) {  /* use defaults */
15523
262
        ecc_ctx_init(&localCtx, 0, NULL);
15524
262
        ctx = &localCtx;
15525
262
    }
15526
15527
262
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
15528
262
                            &blockSz);
15529
262
    if (ret != 0)
15530
0
        return ret;
15531
15532
262
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
15533
262
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
15534
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
15535
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
15536
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
15537
262
    if (ecc_is_gcm(ctx->encAlgo))
15538
0
        return NOT_COMPILED_IN;
15539
262
#endif
15540
15541
262
#ifndef WOLFSSL_ECIES_OLD
15542
262
    if (!compressed) {
15543
262
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
15544
262
    }
15545
0
    else {
15546
0
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
15547
0
    }
15548
#else
15549
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
15550
#endif
15551
15552
262
    if (ctx->protocol == REQ_RESP_SERVER) {
15553
0
        offset = keysLen;
15554
0
        keysLen *= 2;
15555
0
    }
15556
15557
    /* Validate and advance the single-use state (also covers a re-entrant
15558
     * software CryptoCb call; the hardware path handles it before dispatch). */
15559
262
    ret = ecc_ctx_encrypt_advance(ctx);
15560
262
    if (ret != 0)
15561
0
        return ret;
15562
15563
262
    if (keysLen > ECC_BUFSIZE) /* keys size */
15564
0
        return BUFFER_E;
15565
15566
262
    if ((msgSz % blockSz) != 0)
15567
46
        return BAD_PADDING_E;
15568
15569
    /* The nonce/IV is embedded in the output only in GEN_IV mode; OLD derives
15570
     * it from the KDF and default uses a fixed nonce (neither is sent). */
15571
216
    if (*outSz < ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz))
15572
4
        return BUFFER_E;
15573
15574
212
#ifdef ECC_TIMING_RESISTANT
15575
212
    if (ctx->rng != NULL && privKey->rng == NULL)
15576
0
        privKey->rng = ctx->rng;
15577
212
#endif
15578
15579
212
#ifndef WOLFSSL_ECIES_OLD
15580
212
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
15581
212
#ifdef ECC_TIMING_RESISTANT
15582
212
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
15583
#else
15584
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
15585
#endif
15586
212
        if (ret != 0)
15587
36
            return ret;
15588
212
    }
15589
176
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
15590
176
    if (ret != 0)
15591
1
        return ret;
15592
175
    out += pubKeySz;
15593
175
#endif
15594
15595
175
#ifdef WOLFSSL_SMALL_STACK
15596
175
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15597
175
    if (sharedSecret == NULL)
15598
1
        return MEMORY_E;
15599
15600
174
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15601
174
    if (keys == NULL) {
15602
1
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15603
1
        return MEMORY_E;
15604
1
    }
15605
173
#endif
15606
15607
#ifdef WOLFSSL_ECIES_ISO18033
15608
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
15609
    sharedSz -= pubKeySz;
15610
#endif
15611
15612
173
    do {
15613
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
15614
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
15615
        if (ret != 0)
15616
            break;
15617
    #endif
15618
173
    #ifndef WOLFSSL_ECIES_ISO18033
15619
173
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
15620
    #else
15621
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
15622
                                                                     &sharedSz);
15623
    #endif
15624
173
    }
15625
173
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
15626
15627
173
    if (ret == 0) {
15628
    #ifdef WOLFSSL_ECIES_ISO18033
15629
        /* KDF data is encoded public key and secret. */
15630
        sharedSz += pubKeySz;
15631
    #endif
15632
167
        switch (ctx->kdfAlgo) {
15633
167
            case ecHKDF_SHA256 :
15634
167
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
15635
167
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15636
167
                           keys, (word32)keysLen);
15637
167
                break;
15638
0
            case ecHKDF_SHA1 :
15639
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
15640
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15641
0
                           keys, (word32)keysLen);
15642
0
                break;
15643
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15644
0
            case ecKDF_X963_SHA1 :
15645
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15646
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15647
0
                break;
15648
0
            case ecKDF_X963_SHA256 :
15649
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15650
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15651
0
                break;
15652
0
            case ecKDF_SHA1 :
15653
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15654
0
                           NULL, 0, keys, (word32)keysLen);
15655
0
                break;
15656
0
            case ecKDF_SHA256 :
15657
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15658
0
                           NULL, 0, keys, (word32)keysLen);
15659
0
                break;
15660
0
#endif
15661
15662
15663
0
            default:
15664
0
                ret = BAD_FUNC_ARG;
15665
0
                break;
15666
167
        }
15667
167
    }
15668
15669
173
    if (ret == 0) {
15670
159
        if (ecc_is_gcm(ctx->encAlgo)) {
15671
            /* GCM nonce follows the ECIES IV build mode, matching CBC/CTR:
15672
             * OLD -> from the KDF output; GEN_IV -> fresh random, embedded;
15673
             * default -> fixed zero.  No MAC key. */
15674
0
            encKey = keys + offset;
15675
0
            macKey = NULL;
15676
#ifdef WOLFSSL_ECIES_OLD
15677
            encIv  = encKey + encKeySz;
15678
#elif defined(WOLFSSL_ECIES_GEN_IV)
15679
            {
15680
                WC_RNG* rng = (privKey->rng != NULL) ? privKey->rng : ctx->rng;
15681
                encIv  = out;
15682
                out   += ivSz;
15683
                if (rng == NULL)
15684
                    ret = MISSING_RNG_E;
15685
                else
15686
                    ret = wc_RNG_GenerateBlock(rng, encIv, (word32)ivSz);
15687
            }
15688
#else
15689
0
            XMEMSET(iv, 0, (size_t)ivSz);
15690
0
            encIv  = iv;
15691
0
#endif
15692
0
        }
15693
159
        else {
15694
    #ifdef WOLFSSL_ECIES_OLD
15695
            encKey = keys + offset;
15696
            encIv  = encKey + encKeySz;
15697
            macKey = encKey + encKeySz + ivSz;
15698
    #elif defined(WOLFSSL_ECIES_GEN_IV)
15699
            encKey = keys + offset;
15700
            encIv  = out;
15701
            out += ivSz;
15702
            macKey = encKey + encKeySz;
15703
            ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
15704
    #else
15705
159
            XMEMSET(iv, 0, (size_t)ivSz);
15706
159
            encKey = keys + offset;
15707
159
            encIv  = iv;
15708
159
            macKey = encKey + encKeySz;
15709
159
    #endif
15710
159
        }
15711
159
    }
15712
15713
173
    if (ret == 0) {
15714
159
       switch (ctx->encAlgo) {
15715
159
            case ecAES_128_CBC:
15716
159
            case ecAES_256_CBC:
15717
159
            {
15718
159
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15719
159
            #ifdef WOLFSSL_SMALL_STACK
15720
159
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15721
159
                                          DYNAMIC_TYPE_AES);
15722
159
                if (aes == NULL) {
15723
0
                    ret = MEMORY_E;
15724
0
                    break;
15725
0
                }
15726
            #else
15727
                Aes aes[1];
15728
            #endif
15729
159
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15730
159
                if (ret == 0) {
15731
159
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
15732
159
                                                                AES_ENCRYPTION);
15733
159
                    if (ret == 0) {
15734
159
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
15735
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15736
                                                    defined(WC_ASYNC_ENABLE_AES)
15737
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15738
                                            WC_ASYNC_FLAG_NONE);
15739
                    #endif
15740
159
                    }
15741
159
                    wc_AesFree(aes);
15742
159
                }
15743
159
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15744
        #else
15745
                ret = NOT_COMPILED_IN;
15746
        #endif
15747
159
                break;
15748
159
            }
15749
0
            case ecAES_128_CTR:
15750
0
            case ecAES_256_CTR:
15751
0
            {
15752
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15753
0
                byte ctr_iv[WC_AES_BLOCK_SIZE];
15754
            #ifndef WOLFSSL_SMALL_STACK
15755
                Aes aes[1];
15756
            #else
15757
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15758
0
                                            DYNAMIC_TYPE_AES);
15759
0
                if (aes == NULL) {
15760
0
                    ret = MEMORY_E;
15761
0
                    break;
15762
0
                }
15763
0
            #endif
15764
15765
                /* Include 4 byte counter starting at all zeros. */
15766
0
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
15767
0
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
15768
0
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
15769
15770
0
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15771
0
                if (ret == 0) {
15772
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
15773
0
                                                                AES_ENCRYPTION);
15774
0
                    if (ret == 0) {
15775
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
15776
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15777
                                                    defined(WC_ASYNC_ENABLE_AES)
15778
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15779
                                            WC_ASYNC_FLAG_NONE);
15780
                    #endif
15781
0
                    }
15782
0
                    wc_AesFree(aes);
15783
0
                }
15784
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15785
        #else
15786
                ret = NOT_COMPILED_IN;
15787
        #endif
15788
0
                break;
15789
0
            }
15790
0
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
15791
0
            case ecAES_128_GCM:
15792
0
            case ecAES_256_GCM:
15793
0
            {
15794
0
            #ifdef WOLFSSL_SMALL_STACK
15795
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15796
0
                                          DYNAMIC_TYPE_AES);
15797
0
                if (aes == NULL) {
15798
0
                    ret = MEMORY_E;
15799
0
                    break;
15800
0
                }
15801
            #else
15802
                Aes aes[1];
15803
            #endif
15804
0
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15805
0
                if (ret == 0) {
15806
0
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
15807
0
                    if (ret == 0) {
15808
                        /* tag is written directly after the ciphertext; the
15809
                         * mac salt (if any) is bound in as AAD, mirroring the
15810
                         * HMAC salt used by the CBC/CTR paths. */
15811
0
                        ret = wc_AesGcmEncrypt(aes, out, msg, msgSz,
15812
0
                                    encIv, (word32)ivSz,
15813
0
                                    out + msgSz, digestSz,
15814
0
                                    ctx->macSalt, ctx->macSaltSz);
15815
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15816
                                                    defined(WC_ASYNC_ENABLE_AES)
15817
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15818
                                            WC_ASYNC_FLAG_NONE);
15819
                    #endif
15820
0
                    }
15821
0
                    wc_AesFree(aes);
15822
0
                }
15823
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15824
0
                break;
15825
0
            }
15826
0
        #endif
15827
0
            default:
15828
0
                ret = BAD_FUNC_ARG;
15829
0
                break;
15830
159
        }
15831
159
    }
15832
15833
173
    if (ret == 0 && !ecc_is_gcm(ctx->encAlgo)) {
15834
159
        switch (ctx->macAlgo) {
15835
159
            case ecHMAC_SHA256:
15836
159
            {
15837
159
            #ifdef WOLFSSL_SMALL_STACK
15838
159
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
15839
159
                                             DYNAMIC_TYPE_HMAC);
15840
159
                if (hmac == NULL) {
15841
0
                    ret = MEMORY_E;
15842
0
                    break;
15843
0
                }
15844
            #else
15845
                Hmac hmac[1];
15846
            #endif
15847
159
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
15848
159
                if (ret == 0) {
15849
159
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
15850
159
                                                         WC_SHA256_DIGEST_SIZE);
15851
159
                    if (ret == 0) {
15852
159
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
15853
159
                        ret = wc_HmacUpdate(hmac, out, msgSz);
15854
                    #else
15855
                        /* IV is before encrypted message. */
15856
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
15857
                    #endif
15858
159
                    }
15859
159
                    if (ret == 0)
15860
159
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
15861
159
                    if (ret == 0)
15862
159
                        ret = wc_HmacFinal(hmac, out+msgSz);
15863
159
                    wc_HmacFree(hmac);
15864
159
                }
15865
159
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
15866
159
                break;
15867
159
            }
15868
15869
0
            default:
15870
0
                ret = BAD_FUNC_ARG;
15871
0
                break;
15872
159
        }
15873
159
    }
15874
15875
173
    if (ret == 0)
15876
159
        *outSz = ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz);
15877
15878
173
    ForceZero(sharedSecret, sharedSz);
15879
173
    ForceZero(keys, (word32)keysLen);
15880
173
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15881
173
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15882
15883
173
    return ret;
15884
173
}
15885
15886
/* ecc encrypt with shared secret run through kdf
15887
   ctx holds non default algos and inputs
15888
   msgSz should be the right size for encAlgo, i.e., already padded
15889
   return 0 on success */
15890
WOLFSSL_ABI
15891
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15892
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15893
288
{
15894
288
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
15895
288
}
15896
15897
/* ecc decrypt with shared secret run through kdf
15898
   ctx holds non default algos and inputs
15899
   return 0 on success */
15900
WOLFSSL_ABI
15901
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15902
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15903
341
{
15904
341
    int          ret = 0;
15905
341
    word32       blockSz = 0;
15906
341
#ifndef WOLFSSL_ECIES_OLD
15907
341
#ifndef WOLFSSL_ECIES_GEN_IV
15908
341
    byte         iv[ECC_MAX_IV_SIZE];
15909
341
#endif
15910
341
    word32       pubKeySz = 0;
15911
341
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
15912
341
#endif
15913
341
    word32       digestSz = 0;
15914
341
    ecEncCtx     localCtx;
15915
341
#ifdef WOLFSSL_SMALL_STACK
15916
341
    byte*        sharedSecret;
15917
341
    byte*        keys;
15918
#else
15919
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15920
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
15921
#else
15922
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
15923
#endif
15924
    byte         keys[ECC_BUFSIZE];         /* max size */
15925
#endif
15926
341
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15927
341
    word32       sharedSz = ECC_MAXSIZE;
15928
#else
15929
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
15930
#endif
15931
341
    int          keysLen = 0;
15932
341
    int          encKeySz = 0;
15933
341
    int          ivSz = 0;
15934
341
    int          offset = 0;       /* in case using msg exchange */
15935
341
    byte*        encKey = NULL;
15936
341
    const byte*  encIv = NULL;
15937
341
    byte*        macKey = NULL;
15938
    /* devId to hand the DEM AES/HMAC primitives; ecc_key only carries a devId
15939
     * field with PLUTON_CRYPTO_ECC or WOLF_CRYPTO_CB, so default to INVALID. */
15940
341
    int          eciesDevId = INVALID_DEVID;
15941
15942
15943
341
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
15944
24
        return BAD_FUNC_ARG;
15945
#ifdef WOLFSSL_ECIES_OLD
15946
    if (pubKey == NULL)
15947
        return BAD_FUNC_ARG;
15948
#endif
15949
15950
317
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
15951
317
    eciesDevId = privKey->devId;
15952
317
#endif
15953
15954
317
#ifdef WOLF_CRYPTO_CB
15955
317
    #ifndef WOLF_CRYPTO_CB_FIND
15956
317
    if (privKey->devId != INVALID_DEVID)
15957
0
    #endif
15958
0
    {
15959
        /* Snapshot single-use state so we can tell whether the callback handled
15960
         * it purely in hardware (state untouched) versus re-entered software
15961
         * (which advances the state itself, below). */
15962
0
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
15963
0
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
15964
0
        ret = wc_CryptoCb_EciesDecrypt(privKey, pubKey, msg, msgSz, out, outSz,
15965
0
                                       ctx);
15966
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
15967
            /* Pure-hardware service left the state alone; enforce single-use
15968
             * here.  A re-entrant software callback already advanced it. */
15969
0
            if (ret == 0 && ctx != NULL &&
15970
0
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
15971
0
                ret = ecc_ctx_decrypt_advance(ctx);
15972
0
            return ret;
15973
0
        }
15974
        /* fall-through to software (ret is reassigned below) */
15975
0
    }
15976
317
#endif
15977
15978
317
    if (ctx == NULL) {  /* use defaults */
15979
317
        ecc_ctx_init(&localCtx, 0, NULL);
15980
317
        ctx = &localCtx;
15981
317
    }
15982
15983
317
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
15984
317
                            &blockSz);
15985
317
    if (ret != 0)
15986
0
        return ret;
15987
15988
317
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
15989
317
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
15990
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
15991
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
15992
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
15993
317
    if (ecc_is_gcm(ctx->encAlgo))
15994
0
        return NOT_COMPILED_IN;
15995
317
#endif
15996
15997
317
#ifndef WOLFSSL_ECIES_OLD
15998
317
    ret = ecc_public_key_size(privKey, &pubKeySz);
15999
317
    if (ret != 0)
16000
0
        return ret;
16001
317
#ifdef HAVE_COMP_KEY
16002
317
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
16003
127
        pubKeySz = (pubKeySz / 2) + 1;
16004
127
    }
16005
317
#endif /* HAVE_COMP_KEY */
16006
317
#endif /* WOLFSSL_ECIES_OLD */
16007
16008
317
    if (ctx->protocol == REQ_RESP_CLIENT) {
16009
0
        offset = keysLen;
16010
0
        keysLen *= 2;
16011
0
    }
16012
16013
    /* Validate and advance the single-use state (also covers a re-entrant
16014
     * software CryptoCb call; the hardware path handles it before dispatch). */
16015
317
    ret = ecc_ctx_decrypt_advance(ctx);
16016
317
    if (ret != 0)
16017
0
        return ret;
16018
16019
317
    if (keysLen > ECC_BUFSIZE) /* keys size */
16020
0
        return BUFFER_E;
16021
16022
317
    if (ecc_is_gcm(ctx->encAlgo)) {
16023
        /* GCM has a trailing tag (digestSz) and no block padding.  The nonce is
16024
         * only present in the input in GEN_IV mode. */
16025
#ifdef WOLFSSL_ECIES_OLD
16026
        if (msgSz < digestSz)
16027
            return BAD_FUNC_ARG;
16028
        if (*outSz < (msgSz - digestSz))
16029
            return BUFFER_E;
16030
#elif defined(WOLFSSL_ECIES_GEN_IV)
16031
        if (msgSz < pubKeySz + (word32)ivSz + digestSz)
16032
            return BAD_FUNC_ARG;
16033
        if (*outSz < (msgSz - (word32)ivSz - digestSz - pubKeySz))
16034
            return BUFFER_E;
16035
#else
16036
0
        if (msgSz < pubKeySz + digestSz)
16037
0
            return BAD_FUNC_ARG;
16038
0
        if (*outSz < (msgSz - digestSz - pubKeySz))
16039
0
            return BUFFER_E;
16040
0
#endif
16041
0
    }
16042
317
    else {
16043
#ifdef WOLFSSL_ECIES_OLD
16044
    if (((msgSz - digestSz) % blockSz) != 0)
16045
        return BAD_PADDING_E;
16046
16047
    if (*outSz < (msgSz - digestSz))
16048
        return BUFFER_E;
16049
#elif defined(WOLFSSL_ECIES_GEN_IV)
16050
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
16051
        return BAD_PADDING_E;
16052
16053
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
16054
        return BAD_FUNC_ARG;
16055
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
16056
        return BUFFER_E;
16057
#else
16058
317
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
16059
126
        return BAD_PADDING_E;
16060
16061
191
    if (msgSz < pubKeySz + blockSz + digestSz)
16062
23
        return BAD_FUNC_ARG;
16063
168
    if (*outSz < (msgSz - digestSz - pubKeySz))
16064
7
        return BUFFER_E;
16065
168
#endif
16066
168
    }
16067
16068
161
#ifdef ECC_TIMING_RESISTANT
16069
161
    if (ctx->rng != NULL && privKey->rng == NULL)
16070
0
        privKey->rng = ctx->rng;
16071
161
#endif
16072
16073
161
#ifdef WOLFSSL_SMALL_STACK
16074
161
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16075
161
    if (sharedSecret == NULL) {
16076
12
    #ifndef WOLFSSL_ECIES_OLD
16077
12
        if (pubKey == peerKey)
16078
0
            wc_ecc_free(peerKey);
16079
12
    #endif
16080
12
        return MEMORY_E;
16081
12
    }
16082
16083
149
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16084
149
    if (keys == NULL) {
16085
21
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16086
21
    #ifndef WOLFSSL_ECIES_OLD
16087
21
        if (pubKey == peerKey)
16088
0
            wc_ecc_free(peerKey);
16089
21
    #endif
16090
21
        return MEMORY_E;
16091
21
    }
16092
128
#endif
16093
16094
128
#ifndef WOLFSSL_ECIES_OLD
16095
128
    if (pubKey == NULL) {
16096
0
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
16097
0
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
16098
0
        pubKey = peerKey;
16099
0
    }
16100
128
    else {
16101
        /* if a public key was passed in we should free it here before init
16102
         * and import */
16103
128
        wc_ecc_free(pubKey);
16104
128
    }
16105
128
    if (ret == 0) {
16106
128
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
16107
128
    }
16108
128
    if (ret == 0) {
16109
128
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
16110
128
    }
16111
128
    if (ret == 0) {
16112
        /* Point is not MACed. */
16113
41
        msg += pubKeySz;
16114
41
        msgSz -= pubKeySz;
16115
41
    }
16116
128
#endif
16117
16118
128
    if (ret == 0) {
16119
    #ifdef WOLFSSL_ECIES_ISO18033
16120
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
16121
        sharedSz -= pubKeySz;
16122
    #endif
16123
16124
41
        do {
16125
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
16126
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
16127
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
16128
            if (ret != 0)
16129
                break;
16130
        #endif
16131
41
        #ifndef WOLFSSL_ECIES_ISO18033
16132
41
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
16133
41
                                                                    &sharedSz);
16134
        #else
16135
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
16136
                                                          pubKeySz, &sharedSz);
16137
        #endif
16138
41
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
16139
41
    }
16140
128
    if (ret == 0) {
16141
    #ifdef WOLFSSL_ECIES_ISO18033
16142
        /* KDF data is encoded public key and secret. */
16143
        sharedSz += pubKeySz;
16144
    #endif
16145
37
        switch (ctx->kdfAlgo) {
16146
37
            case ecHKDF_SHA256 :
16147
37
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
16148
37
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16149
37
                           keys, (word32)keysLen);
16150
37
                break;
16151
0
            case ecHKDF_SHA1 :
16152
0
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
16153
0
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16154
0
                           keys, (word32)keysLen);
16155
0
                break;
16156
0
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
16157
0
            case ecKDF_X963_SHA1 :
16158
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16159
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16160
0
                break;
16161
0
            case ecKDF_X963_SHA256 :
16162
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16163
0
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16164
0
                break;
16165
0
            case ecKDF_SHA1 :
16166
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16167
0
                           NULL, 0, keys, (word32)keysLen);
16168
0
                break;
16169
0
            case ecKDF_SHA256 :
16170
0
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16171
0
                           NULL, 0, keys, (word32)keysLen);
16172
0
                break;
16173
0
#endif
16174
16175
0
            default:
16176
0
                ret = BAD_FUNC_ARG;
16177
0
                break;
16178
37
         }
16179
37
    }
16180
16181
128
    if (ret == 0 && ecc_is_gcm(ctx->encAlgo)) {
16182
        /* GCM nonce follows the ECIES IV build mode (matching CBC/CTR); no MAC
16183
         * key and no separate HMAC verify (GCM authenticates on decrypt). */
16184
0
        encKey = keys + offset;
16185
0
        macKey = NULL;
16186
#ifdef WOLFSSL_ECIES_OLD
16187
        encIv  = encKey + encKeySz;
16188
#elif defined(WOLFSSL_ECIES_GEN_IV)
16189
        encIv  = msg;
16190
        msg   += ivSz;
16191
        msgSz -= (word32)ivSz;
16192
#else
16193
0
        XMEMSET(iv, 0, (size_t)ivSz);
16194
0
        encIv  = iv;
16195
0
#endif
16196
0
    }
16197
128
    else if (ret == 0) {
16198
    #ifdef WOLFSSL_ECIES_OLD
16199
        encKey = keys + offset;
16200
        encIv  = encKey + encKeySz;
16201
        macKey = encKey + encKeySz + ivSz;
16202
    #elif defined(WOLFSSL_ECIES_GEN_IV)
16203
        encKey = keys + offset;
16204
        encIv  = msg;
16205
        msg   += ivSz;
16206
        msgSz -= ivSz;
16207
        macKey = encKey + encKeySz;
16208
    #else
16209
37
        XMEMSET(iv, 0, (size_t)ivSz);
16210
37
        encKey = keys + offset;
16211
37
        encIv  = iv;
16212
37
        macKey = encKey + encKeySz;
16213
37
    #endif
16214
16215
37
        switch (ctx->macAlgo) {
16216
37
            case ecHMAC_SHA256:
16217
37
            {
16218
37
                byte verify[WC_SHA256_DIGEST_SIZE];
16219
37
            #ifdef WOLFSSL_SMALL_STACK
16220
37
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
16221
37
                                             DYNAMIC_TYPE_HMAC);
16222
37
                if (hmac == NULL) {
16223
0
                    ret = MEMORY_E;
16224
0
                    break;
16225
0
                }
16226
            #else
16227
                Hmac hmac[1];
16228
            #endif
16229
37
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
16230
37
                if (ret == 0) {
16231
37
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
16232
37
                                                         WC_SHA256_DIGEST_SIZE);
16233
37
                    if (ret == 0)
16234
37
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
16235
37
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
16236
                    #else
16237
                        /* IV is before encrypted message. */
16238
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
16239
                    #endif
16240
37
                    if (ret == 0)
16241
37
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
16242
16243
37
                    if (ret == 0)
16244
37
                        ret = wc_HmacFinal(hmac, verify);
16245
37
                    if ((ret == 0) && (ConstantCompare(verify, msg + msgSz - digestSz,
16246
37
                                                             (int)digestSz) != 0)) {
16247
20
                        ret = HASH_TYPE_E;
16248
20
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
16249
20
                    }
16250
16251
37
                    wc_HmacFree(hmac);
16252
37
                }
16253
37
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
16254
37
                break;
16255
37
            }
16256
16257
0
            default:
16258
0
                ret = BAD_FUNC_ARG;
16259
0
                break;
16260
37
        }
16261
37
    }
16262
16263
128
    if (ret == 0) {
16264
17
        switch (ctx->encAlgo) {
16265
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
16266
17
            case ecAES_128_CBC:
16267
17
            case ecAES_256_CBC:
16268
17
            {
16269
17
            #ifdef WOLFSSL_SMALL_STACK
16270
17
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16271
17
                                          DYNAMIC_TYPE_AES);
16272
17
                if (aes == NULL) {
16273
0
                    ret = MEMORY_E;
16274
0
                    break;
16275
0
                }
16276
            #else
16277
                Aes aes[1];
16278
            #endif
16279
17
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16280
17
                if (ret == 0) {
16281
17
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
16282
17
                                                                AES_DECRYPTION);
16283
17
                    if (ret == 0) {
16284
17
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
16285
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16286
                                                    defined(WC_ASYNC_ENABLE_AES)
16287
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16288
                                                            WC_ASYNC_FLAG_NONE);
16289
                    #endif
16290
17
                    }
16291
17
                    wc_AesFree(aes);
16292
17
                }
16293
17
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16294
17
                break;
16295
17
            }
16296
0
        #endif
16297
0
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
16298
0
            case ecAES_128_CTR:
16299
0
            case ecAES_256_CTR:
16300
0
            {
16301
0
            #ifdef WOLFSSL_SMALL_STACK
16302
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16303
0
                                          DYNAMIC_TYPE_AES);
16304
0
                if (aes == NULL) {
16305
0
                    ret = MEMORY_E;
16306
0
                    break;
16307
0
                }
16308
             #else
16309
                Aes aes[1];
16310
             #endif
16311
0
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16312
0
                if (ret == 0) {
16313
0
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
16314
                    /* Make a 16 byte IV from the bytes passed in. */
16315
0
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
16316
0
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
16317
0
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
16318
0
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
16319
0
                                                                AES_ENCRYPTION);
16320
0
                    if (ret == 0) {
16321
0
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
16322
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16323
                                                    defined(WC_ASYNC_ENABLE_AES)
16324
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16325
                                                            WC_ASYNC_FLAG_NONE);
16326
                    #endif
16327
0
                    }
16328
0
                    wc_AesFree(aes);
16329
0
                }
16330
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16331
0
                break;
16332
0
            }
16333
0
        #endif
16334
0
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
16335
0
            case ecAES_128_GCM:
16336
0
            case ecAES_256_GCM:
16337
0
            {
16338
0
            #ifdef WOLFSSL_SMALL_STACK
16339
0
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16340
0
                                          DYNAMIC_TYPE_AES);
16341
0
                if (aes == NULL) {
16342
0
                    ret = MEMORY_E;
16343
0
                    break;
16344
0
                }
16345
            #else
16346
                Aes aes[1];
16347
            #endif
16348
0
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16349
0
                if (ret == 0) {
16350
0
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
16351
0
                    if (ret == 0) {
16352
                        /* tag trails the ciphertext; mac salt (if any) is the
16353
                         * AAD.  A tag mismatch returns AES_GCM_AUTH_E. */
16354
0
                        ret = wc_AesGcmDecrypt(aes, out, msg, msgSz - digestSz,
16355
0
                                    encIv, (word32)ivSz,
16356
0
                                    msg + msgSz - digestSz, digestSz,
16357
0
                                    ctx->macSalt, ctx->macSaltSz);
16358
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16359
                                                    defined(WC_ASYNC_ENABLE_AES)
16360
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16361
                                                            WC_ASYNC_FLAG_NONE);
16362
                    #endif
16363
0
                    }
16364
0
                    wc_AesFree(aes);
16365
0
                }
16366
0
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16367
0
                break;
16368
0
            }
16369
0
        #endif
16370
0
            default:
16371
0
                ret = BAD_FUNC_ARG;
16372
0
                break;
16373
17
        }
16374
17
    }
16375
16376
128
    if (ret == 0)
16377
17
       *outSz = msgSz - digestSz;
16378
16379
128
#ifndef WOLFSSL_ECIES_OLD
16380
128
    if (pubKey == peerKey)
16381
0
        wc_ecc_free(peerKey);
16382
128
#endif
16383
128
    ForceZero(sharedSecret, sharedSz);
16384
128
    ForceZero(keys, (word32)keysLen);
16385
128
#ifdef WOLFSSL_SMALL_STACK
16386
128
#ifndef WOLFSSL_ECIES_OLD
16387
128
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16388
128
#endif
16389
128
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16390
128
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16391
128
#endif
16392
16393
128
    return ret;
16394
128
}
16395
16396
16397
#endif /* HAVE_ECC_ENCRYPT */
16398
16399
16400
#ifdef HAVE_COMP_KEY
16401
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
16402
    !defined(WOLFSSL_MICROCHIP_TA100) && \
16403
    !defined(WOLFSSL_CRYPTOCELL)
16404
16405
#ifndef WOLFSSL_SP_MATH
16406
#if !defined(SQRTMOD_USE_MOD_EXP)
16407
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
16408
 */
16409
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
16410
5.97k
{
16411
5.97k
#ifdef WOLFSSL_SMALL_STACK
16412
5.97k
    mp_int*  a1 = NULL;
16413
5.97k
    mp_int*  n1 = NULL;
16414
#else
16415
    mp_int   a1[1], n1[1];
16416
#endif
16417
5.97k
    int      res;
16418
5.97k
    int      s = 1;
16419
5.97k
    int      k;
16420
5.97k
    mp_int*  t[2];
16421
5.97k
    mp_int*  ts;
16422
5.97k
    mp_digit residue;
16423
16424
5.97k
    if (mp_isneg(a) == MP_YES) {
16425
0
        return MP_VAL;
16426
0
    }
16427
5.97k
    if (mp_isneg(n) == MP_YES) {
16428
0
        return MP_VAL;
16429
0
    }
16430
5.97k
    if (mp_iseven(n) == MP_YES) {
16431
4
        return MP_VAL;
16432
4
    }
16433
16434
5.97k
#ifdef WOLFSSL_SMALL_STACK
16435
5.97k
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
16436
5.97k
    if (a1 == NULL) {
16437
1
        return MP_MEM;
16438
1
    }
16439
5.97k
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
16440
5.97k
    if (n1 == NULL) {
16441
7
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
16442
7
        return MP_MEM;
16443
7
    }
16444
5.96k
#endif
16445
16446
5.96k
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
16447
0
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
16448
0
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
16449
0
        return res;
16450
0
    }
16451
16452
5.96k
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
16453
0
        goto done;
16454
0
    }
16455
16456
5.96k
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
16457
0
        goto done;
16458
0
    }
16459
16460
5.96k
    t[0] = a1;
16461
5.96k
    t[1] = n1;
16462
16463
    /* Keep reducing until first number is 0. */
16464
177k
    while (!mp_iszero(t[0])) {
16465
        /* Divide by 2 until odd. */
16466
171k
        k = mp_cnt_lsb(t[0]);
16467
171k
        if (k > 0) {
16468
92.7k
            mp_rshb(t[0], k);
16469
16470
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
16471
             * Odd number of divides results in a negate.
16472
             */
16473
92.7k
            residue = t[1]->dp[0] & 7;
16474
92.7k
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
16475
30.5k
                s = -s;
16476
30.5k
            }
16477
92.7k
        }
16478
16479
        /* Swap t[0] and t[1]. */
16480
171k
        ts   = t[0];
16481
171k
        t[0] = t[1];
16482
171k
        t[1] = ts;
16483
16484
        /* Negate s if both numbers == 3 mod 4. */
16485
171k
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
16486
41.0k
             s = -s;
16487
41.0k
        }
16488
16489
        /* Reduce first number modulo second. */
16490
171k
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
16491
18.8k
            res = mp_sub(t[0], t[1], t[0]);
16492
18.8k
        }
16493
152k
        else {
16494
152k
            res = mp_mod(t[0], t[1], t[0]);
16495
152k
        }
16496
171k
        if (res != MP_OKAY) {
16497
11
            goto done;
16498
11
        }
16499
171k
    }
16500
16501
    /* When the two numbers have divisors in common. */
16502
5.95k
    if (!mp_isone(t[1])) {
16503
263
        s = 0;
16504
263
    }
16505
5.95k
    *c = s;
16506
16507
5.96k
done:
16508
16509
    /* cleanup */
16510
5.96k
    mp_clear(n1);
16511
5.96k
    mp_clear(a1);
16512
16513
5.96k
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
16514
5.96k
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
16515
16516
5.96k
  return res;
16517
5.95k
}
16518
#endif /* !SQRTMOD_USE_MOD_EXP */
16519
16520
16521
/* Solves the modular equation x^2 = n (mod p)
16522
 * where prime number is greater than 2 (odd prime).
16523
 * The result is returned in the third argument x
16524
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
16525
 */
16526
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
16527
2.68k
{
16528
#if defined(SQRTMOD_USE_MOD_EXP)
16529
  int res;
16530
  mp_digit i;
16531
  mp_int e;
16532
16533
  /* first handle the simple cases n = 0 or n = 1 */
16534
  if (mp_cmp_d(n, 0) == MP_EQ) {
16535
      mp_zero(ret);
16536
      return MP_OKAY;
16537
  }
16538
  if (mp_cmp_d(n, 1) == MP_EQ) {
16539
      return mp_set(ret, 1);
16540
  }
16541
16542
  if (mp_iseven(prime)) {
16543
      return MP_VAL;
16544
  }
16545
16546
  res = mp_init(&e);
16547
  if (res == MP_OKAY)
16548
      res = mp_mod_d(prime, 8, &i);
16549
  if (res == MP_OKAY && i == 1) {
16550
      return MP_VAL;
16551
  }
16552
  /* prime mod 8 = 5 */
16553
  else if (res == MP_OKAY && i == 5) {
16554
      res = mp_sub_d(prime, 1, &e);
16555
      if (res == MP_OKAY)
16556
          res = mp_div_2d(&e, 2, &e, NULL);
16557
  }
16558
  /* prime mod 4 = 3 */
16559
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
16560
      res = mp_add_d(prime, 1, &e);
16561
      if (res == MP_OKAY)
16562
          res = mp_div_2d(&e, 2, &e, NULL);
16563
  }
16564
  if (res == MP_OKAY)
16565
      res = mp_exptmod(n, &e, prime, ret);
16566
16567
  mp_clear(&e);
16568
16569
  return res;
16570
#else
16571
2.68k
  int res, legendre, done = 0;
16572
2.68k
  mp_digit i;
16573
2.68k
#ifdef WOLFSSL_SMALL_STACK
16574
2.68k
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16575
2.68k
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16576
2.68k
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16577
2.68k
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16578
2.68k
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16579
2.68k
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16580
2.68k
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16581
2.68k
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16582
2.68k
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16583
2.68k
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16584
#else
16585
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
16586
#endif
16587
16588
2.68k
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
16589
2.68k
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
16590
0
    res = MP_INIT_E;
16591
0
    goto out;
16592
0
  }
16593
16594
2.68k
#ifdef WOLFSSL_SMALL_STACK
16595
2.68k
  if ((t1 == NULL) ||
16596
2.66k
      (C == NULL) ||
16597
2.64k
      (Q == NULL) ||
16598
2.63k
      (S == NULL) ||
16599
2.61k
      (Z == NULL) ||
16600
2.60k
      (M == NULL) ||
16601
2.59k
      (T == NULL) ||
16602
2.58k
      (R == NULL) ||
16603
2.56k
      (N == NULL) ||
16604
2.56k
      (two == NULL)) {
16605
129
    res = MP_MEM;
16606
129
    goto out;
16607
129
  }
16608
2.55k
#endif
16609
16610
  /* first handle the simple cases n = 0 or n = 1 */
16611
2.55k
  if (mp_cmp_d(n, 0) == MP_EQ) {
16612
3
    mp_zero(ret);
16613
3
    res = MP_OKAY;
16614
3
    goto out;
16615
3
  }
16616
2.55k
  if (mp_cmp_d(n, 1) == MP_EQ) {
16617
3
    res = mp_set(ret, 1);
16618
3
    goto out;
16619
3
  }
16620
16621
  /* prime must be odd */
16622
2.54k
  if (mp_cmp_d(prime, 2) == MP_EQ) {
16623
1
    res = MP_VAL;
16624
1
    goto out;
16625
1
  }
16626
16627
  /* reduce n to less than prime */
16628
2.54k
  res = mp_mod(n, prime, N);
16629
2.54k
  if (res != MP_OKAY) {
16630
4
    goto out;
16631
4
  }
16632
  /* when N is zero, sqrt is zero */
16633
2.54k
  if (mp_iszero(N)) {
16634
9
    mp_set(ret, 0);
16635
9
    goto out;
16636
9
  }
16637
16638
  /* is quadratic non-residue mod prime */
16639
2.53k
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
16640
50
    goto out;
16641
50
  }
16642
2.48k
  if (legendre == -1) {
16643
522
    res = MP_VAL;
16644
522
    goto out;
16645
522
  }
16646
16647
  /* SPECIAL CASE: if prime mod 4 == 3
16648
   * compute directly: res = n^(prime+1)/4 mod prime
16649
   * Handbook of Applied Cryptography algorithm 3.36
16650
   */
16651
1.96k
  res = mp_mod_d(prime, 4, &i);
16652
1.96k
  if (res == MP_OKAY && i == 3) {
16653
1.23k
    res = mp_add_d(prime, 1, t1);
16654
16655
1.23k
    if (res == MP_OKAY)
16656
1.23k
      res = mp_div_2(t1, t1);
16657
1.23k
    if (res == MP_OKAY)
16658
1.23k
      res = mp_div_2(t1, t1);
16659
1.23k
    if (res == MP_OKAY)
16660
1.23k
      res = mp_exptmod(N, t1, prime, ret);
16661
16662
1.23k
    done = 1;
16663
1.23k
  }
16664
16665
  /* NOW: TonelliShanks algorithm */
16666
1.96k
  if (res == MP_OKAY && done == 0) {
16667
16668
    /* factor out powers of 2 from prime-1, defining Q and S
16669
    *                                      as: prime-1 = Q*2^S */
16670
    /* Q = prime - 1 */
16671
731
    res = mp_copy(prime, Q);
16672
731
    if (res == MP_OKAY)
16673
731
      res = mp_sub_d(Q, 1, Q);
16674
16675
    /* S = 0 */
16676
731
    if (res == MP_OKAY)
16677
731
      mp_zero(S);
16678
16679
29.8k
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
16680
      /* Q = Q / 2 */
16681
29.1k
      res = mp_div_2(Q, Q);
16682
16683
      /* S = S + 1 */
16684
29.1k
      if (res == MP_OKAY)
16685
29.1k
        res = mp_add_d(S, 1, S);
16686
29.1k
    }
16687
16688
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
16689
    /* Z = 2 */
16690
731
    if (res == MP_OKAY)
16691
731
      res = mp_set_int(Z, 2);
16692
16693
4.14k
    while (res == MP_OKAY) {
16694
4.12k
      res = mp_jacobi(Z, prime, &legendre);
16695
4.12k
      if (res == MP_OKAY && legendre == -1)
16696
714
        break;
16697
16698
3.41k
#if defined(WOLFSSL_CUSTOM_CURVES)
16699
      /* P224R1 succeeds with a value of 11. */
16700
3.41k
      if (mp_cmp_d(Z, 22) == MP_EQ) {
16701
        /* This is to clamp the loop in case 'prime' is not really prime */
16702
1
        res = MP_VAL;
16703
1
        break;
16704
1
      }
16705
3.41k
#endif
16706
16707
      /* Z = Z + 1 */
16708
3.41k
      if (res == MP_OKAY)
16709
3.39k
        res = mp_add_d(Z, 1, Z);
16710
16711
3.41k
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
16712
        /* This is to clamp the loop in case 'prime' is not really prime */
16713
1
        res = MP_VAL;
16714
1
        break;
16715
1
      }
16716
3.41k
    }
16717
16718
    /* C = Z ^ Q mod prime */
16719
731
    if (res == MP_OKAY)
16720
714
      res = mp_exptmod(Z, Q, prime, C);
16721
16722
    /* t1 = (Q + 1) / 2 */
16723
731
    if (res == MP_OKAY)
16724
695
      res = mp_add_d(Q, 1, t1);
16725
731
    if (res == MP_OKAY)
16726
695
      res = mp_div_2(t1, t1);
16727
16728
    /* R = n ^ ((Q + 1) / 2) mod prime */
16729
731
    if (res == MP_OKAY)
16730
695
      res = mp_exptmod(N, t1, prime, R);
16731
16732
    /* T = n ^ Q mod prime */
16733
731
    if (res == MP_OKAY)
16734
695
      res = mp_exptmod(N, Q, prime, T);
16735
16736
    /* M = S */
16737
731
    if (res == MP_OKAY)
16738
695
      res = mp_copy(S, M);
16739
16740
731
    if (res == MP_OKAY)
16741
695
      res = mp_set_int(two, 2);
16742
16743
14.8k
    while (res == MP_OKAY && done == 0) {
16744
14.1k
      res = mp_copy(T, t1);
16745
16746
      /* reduce to 1 and count */
16747
14.1k
      i = 0;
16748
609k
      while (res == MP_OKAY) {
16749
609k
        if (mp_cmp_d(t1, 1) == MP_EQ)
16750
13.9k
            break;
16751
596k
        res = mp_exptmod(t1, two, prime, t1);
16752
596k
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
16753
          /* This is to clamp the loop in case 'prime' is not really prime */
16754
204
          res = MP_VAL;
16755
204
          break;
16756
204
        }
16757
595k
        if (res == MP_OKAY)
16758
595k
          i++;
16759
595k
      }
16760
14.1k
      if (res == MP_OKAY && i == 0) {
16761
488
        res = mp_copy(R, ret);
16762
488
        done = 1;
16763
488
      }
16764
16765
14.1k
      if (done == 0) {
16766
        /* t1 = 2 ^ (M - i - 1) */
16767
13.6k
        if (res == MP_OKAY)
16768
13.4k
          res = mp_sub_d(M, i, t1);
16769
13.6k
        if (res == MP_OKAY)
16770
13.4k
          res = mp_sub_d(t1, 1, t1);
16771
13.6k
        if (res == MP_OKAY)
16772
13.4k
          res = mp_exptmod(two, t1, prime, t1);
16773
16774
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
16775
13.6k
        if (res == MP_OKAY)
16776
13.4k
          res = mp_exptmod(C, t1, prime, t1);
16777
16778
        /* C = (t1 * t1) mod prime */
16779
13.6k
        if (res == MP_OKAY)
16780
13.4k
          res = mp_sqrmod(t1, prime, C);
16781
16782
        /* R = (R * t1) mod prime */
16783
13.6k
        if (res == MP_OKAY)
16784
13.4k
          res = mp_mulmod(R, t1, prime, R);
16785
16786
        /* T = (T * C) mod prime */
16787
13.6k
        if (res == MP_OKAY)
16788
13.4k
          res = mp_mulmod(T, C, prime, T);
16789
16790
        /* M = i */
16791
13.6k
        if (res == MP_OKAY)
16792
13.4k
          res = mp_set(M, i);
16793
13.6k
      }
16794
14.1k
    }
16795
731
  }
16796
16797
2.68k
  out:
16798
16799
2.68k
#ifdef WOLFSSL_SMALL_STACK
16800
2.68k
  if (t1) {
16801
2.66k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16802
2.66k
      mp_clear(t1);
16803
2.66k
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16804
2.66k
  }
16805
2.68k
  if (C) {
16806
2.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16807
2.64k
      mp_clear(C);
16808
2.64k
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16809
2.64k
  }
16810
2.68k
  if (Q) {
16811
2.65k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16812
2.65k
      mp_clear(Q);
16813
2.65k
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16814
2.65k
  }
16815
2.68k
  if (S) {
16816
2.65k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16817
2.65k
      mp_clear(S);
16818
2.65k
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16819
2.65k
  }
16820
2.68k
  if (Z) {
16821
2.65k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16822
2.65k
      mp_clear(Z);
16823
2.65k
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16824
2.65k
  }
16825
2.68k
  if (M) {
16826
2.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16827
2.64k
      mp_clear(M);
16828
2.64k
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16829
2.64k
  }
16830
2.68k
  if (T) {
16831
2.63k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16832
2.63k
      mp_clear(T);
16833
2.63k
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16834
2.63k
  }
16835
2.68k
  if (R) {
16836
2.62k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16837
2.62k
      mp_clear(R);
16838
2.62k
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16839
2.62k
  }
16840
2.68k
  if (N) {
16841
2.64k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16842
2.64k
      mp_clear(N);
16843
2.64k
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16844
2.64k
  }
16845
2.68k
  if (two) {
16846
2.63k
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16847
2.63k
      mp_clear(two);
16848
2.63k
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16849
2.63k
  }
16850
#else
16851
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
16852
    mp_clear(t1);
16853
    mp_clear(C);
16854
    mp_clear(Q);
16855
    mp_clear(S);
16856
    mp_clear(Z);
16857
    mp_clear(M);
16858
    mp_clear(T);
16859
    mp_clear(R);
16860
    mp_clear(N);
16861
    mp_clear(two);
16862
  }
16863
#endif
16864
16865
2.68k
  return res;
16866
1.96k
#endif
16867
1.96k
}
16868
#endif /* !WOLFSSL_SP_MATH */
16869
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
16870
16871
#ifdef HAVE_ECC_KEY_EXPORT
16872
/* export public ECC key in ANSI X9.63 format compressed */
16873
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
16874
2.29k
{
16875
2.29k
   word32 numlen;
16876
2.29k
   int    ret = MP_OKAY;
16877
16878
2.29k
   if (key == NULL || outLen == NULL)
16879
0
       return BAD_FUNC_ARG;
16880
16881
2.29k
   if (key->type == ECC_PRIVATEKEY_ONLY)
16882
63
       return ECC_PRIVATEONLY_E;
16883
16884
2.23k
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
16885
290
       return ECC_BAD_ARG_E;
16886
290
   }
16887
16888
1.94k
   numlen = (word32)key->dp->size;
16889
16890
1.94k
   if (*outLen < (1 + numlen)) {
16891
973
      *outLen = 1 + numlen;
16892
973
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
16893
973
   }
16894
16895
973
   if (out == NULL)
16896
0
       return BAD_FUNC_ARG;
16897
16898
973
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
16899
0
       return ECC_BAD_ARG_E;
16900
16901
   /* store first byte */
16902
973
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
16903
16904
   /* pad and store x */
16905
973
   XMEMSET(out+1, 0, numlen);
16906
973
   ret = mp_to_unsigned_bin(
16907
973
       key->pubkey.x,
16908
973
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
16909
973
   *outLen = 1 + numlen;
16910
16911
973
   return ret;
16912
973
}
16913
#endif /* HAVE_ECC_KEY_EXPORT */
16914
#endif /* HAVE_COMP_KEY */
16915
16916
#ifdef HAVE_OID_ENCODING
16917
int wc_ecc_oid_cache_init(void)
16918
{
16919
    int ret = 0;
16920
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16921
    if (eccOidLockInit == 0) {
16922
        ret = wc_InitMutex(&ecc_oid_cache_lock);
16923
        if (ret == 0) {
16924
            eccOidLockInit = 1;
16925
        }
16926
    }
16927
#endif
16928
    return ret;
16929
}
16930
16931
void wc_ecc_oid_cache_free(void)
16932
{
16933
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16934
    wc_FreeMutex(&ecc_oid_cache_lock);
16935
    eccOidLockInit = 0;
16936
#endif
16937
}
16938
#endif /* HAVE_OID_ENCODING */
16939
16940
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
16941
6.26k
{
16942
6.26k
    int x;
16943
6.26k
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
16944
#ifdef HAVE_OID_ENCODING
16945
    oid_cache_t* o = NULL;
16946
#endif
16947
16948
6.26k
    if (oidSum == 0) {
16949
34
        return BAD_FUNC_ARG;
16950
34
    }
16951
16952
#ifdef HAVE_OID_ENCODING
16953
    #ifndef WOLFSSL_MUTEX_INITIALIZER
16954
        /* extra sanity check if wolfCrypt_Init not called */
16955
        if (eccOidLockInit == 0) {
16956
            ret = wc_InitMutex(&ecc_oid_cache_lock);
16957
            if (ret != 0) {
16958
                return BAD_MUTEX_E;
16959
            }
16960
            eccOidLockInit = 1;
16961
        }
16962
    #endif
16963
16964
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
16965
        return BAD_MUTEX_E;
16966
    }
16967
#endif
16968
16969
    /* find matching OID sum (based on encoded value) */
16970
26.3k
    for (x = 0; ecc_sets[x].size != 0; x++) {
16971
24.2k
        if (ecc_sets[x].oidSum == oidSum) {
16972
        #ifdef HAVE_OID_ENCODING
16973
            /* check cache */
16974
            ret = 0;
16975
            o = &ecc_oid_cache[x];
16976
            if (o->oidSz == 0) {
16977
                o->oidSz = sizeof(o->oid);
16978
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
16979
                                                            o->oid, &o->oidSz);
16980
            }
16981
            if (oidSz) {
16982
                *oidSz = o->oidSz;
16983
            }
16984
            if (oid) {
16985
                *oid = o->oid;
16986
            }
16987
16988
            /* on success return curve id */
16989
            if (ret == 0) {
16990
                ret = ecc_sets[x].id;
16991
            }
16992
            break;
16993
        #else
16994
4.17k
            if (oidSz) {
16995
4.17k
                *oidSz = ecc_sets[x].oidSz;
16996
4.17k
            }
16997
4.17k
            if (oid) {
16998
4.17k
                *oid = ecc_sets[x].oid;
16999
4.17k
            }
17000
4.17k
            ret = ecc_sets[x].id;
17001
4.17k
            break;
17002
4.17k
        #endif
17003
4.17k
        }
17004
24.2k
    }
17005
17006
#ifdef HAVE_OID_ENCODING
17007
    wc_UnLockMutex(&ecc_oid_cache_lock);
17008
#endif
17009
17010
6.23k
    return ret;
17011
6.26k
}
17012
17013
#ifdef WOLFSSL_CUSTOM_CURVES
17014
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
17015
442
{
17016
442
    if (key == NULL || dp == NULL) {
17017
0
        return BAD_FUNC_ARG;
17018
0
    }
17019
17020
442
    key->idx = ECC_CUSTOM_IDX;
17021
442
    key->dp = dp;
17022
17023
442
    return 0;
17024
442
}
17025
#endif /* WOLFSSL_CUSTOM_CURVES */
17026
17027
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
17028
17029
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
17030
0
{
17031
0
    int i;
17032
17033
    /* in network byte order so start at end and work back */
17034
0
    for (i = 3; i >= 0; i--) {
17035
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
17036
0
            return;
17037
0
    }
17038
0
}
17039
17040
/* ASN X9.63 Key Derivation Function (SEC1) */
17041
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
17042
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
17043
0
{
17044
0
    int ret;
17045
0
    word32 digestSz, copySz, remaining = outSz;
17046
0
    byte* outIdx;
17047
0
    byte  counter[4];
17048
0
    byte  tmp[WC_MAX_DIGEST_SIZE];
17049
17050
0
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
17051
17052
0
    if (secret == NULL || secretSz == 0 || out == NULL)
17053
0
        return BAD_FUNC_ARG;
17054
17055
    /* X9.63 allowed algos only */
17056
0
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
17057
0
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
17058
0
        type != WC_HASH_TYPE_SHA512)
17059
0
        return BAD_FUNC_ARG;
17060
17061
0
    ret = wc_HashGetDigestSize(type);
17062
0
    if (ret < 0)
17063
0
        return ret;
17064
0
    digestSz = (word32)ret;
17065
17066
0
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
17067
0
        return MEMORY_E);
17068
17069
0
    ret = wc_HashInit(hash, type);
17070
0
    if (ret != 0) {
17071
0
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17072
0
        return ret;
17073
0
    }
17074
17075
0
    outIdx = out;
17076
0
    XMEMSET(counter, 0, sizeof(counter));
17077
17078
0
    while (remaining > 0) {
17079
17080
0
        IncrementX963KdfCounter(counter);
17081
17082
0
        ret = wc_HashUpdate(hash, type, secret, secretSz);
17083
0
        if (ret != 0) {
17084
0
            break;
17085
0
        }
17086
17087
0
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
17088
0
        if (ret != 0) {
17089
0
            break;
17090
0
        }
17091
17092
0
        if (sinfo) {
17093
0
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
17094
0
            if (ret != 0) {
17095
0
                break;
17096
0
            }
17097
0
        }
17098
17099
0
        ret = wc_HashFinal(hash, type, tmp);
17100
0
        if (ret != 0) {
17101
0
            break;
17102
0
        }
17103
17104
0
        copySz = min(remaining, digestSz);
17105
0
        XMEMCPY(outIdx, tmp, copySz);
17106
17107
0
        remaining -= copySz;
17108
0
        outIdx += copySz;
17109
0
    }
17110
17111
0
    wc_HashFree(hash, type);
17112
17113
0
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17114
17115
0
    return ret;
17116
0
}
17117
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
17118
17119
#ifdef WOLFSSL_SE050
17120
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
17121
 * keyId is a word32, can be used for key IDs larger than an int.
17122
 *
17123
 * key    initialized ecc_key struct
17124
 * keyId  hardware key ID which stores ECC key
17125
 * flags  optional flags, currently unused
17126
 *
17127
 * Return 0 on success, negative on error */
17128
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
17129
{
17130
    (void)flags;
17131
17132
    if (key == NULL) {
17133
        return BAD_FUNC_ARG;
17134
    }
17135
17136
    return se050_ecc_use_key_id(key, keyId);
17137
}
17138
17139
/* Get hardware key ID associated with this ecc_key structure.
17140
 *
17141
 * key    initialized ecc_key struct
17142
 * keyId  [OUT] output for key ID associated with this structure
17143
 *
17144
 * Returns 0 on success, negative on error.
17145
 */
17146
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
17147
{
17148
    if (key == NULL || keyId == NULL) {
17149
        return BAD_FUNC_ARG;
17150
    }
17151
17152
    return se050_ecc_get_key_id(key, keyId);
17153
}
17154
#endif /* WOLFSSL_SE050 */
17155
17156
17157
#ifdef WC_ECC_NONBLOCK
17158
/* Enable ECC support for non-blocking operations */
17159
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
17160
{
17161
    if (key == NULL) {
17162
        return BAD_FUNC_ARG;
17163
    }
17164
    /* If a different context is already set, clear it before replacing.
17165
     * The caller is responsible for freeing any heap-allocated context. */
17166
    if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
17167
        XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
17168
    }
17169
    if (ctx != NULL) {
17170
        XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
17171
    }
17172
    key->nb_ctx = ctx;
17173
    return 0;
17174
}
17175
#endif /* WC_ECC_NONBLOCK */
17176
17177
#endif /* HAVE_ECC */