Coverage Report

Created: 2026-11-12 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/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
/* Shared contexts must retain the library-wide allocation configuration. */
29
#include <wolfssl/wolfcrypt/hash.h>
30
#include <wolfssl/wolfcrypt/random.h>
31
#ifdef HAVE_ECC_ENCRYPT
32
#include <wolfssl/wolfcrypt/aes.h>
33
#endif
34
#undef WOLFSSL_SMALL_STACK
35
#undef WOLFSSL_SMALL_STACK_CACHE
36
#endif
37
38
/*
39
Possible ECC enable options:
40
 * HAVE_ECC:            Overall control of ECC                  default: on
41
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
42
 * HAVE_ECC_SIGN:       ECC sign                                default: on
43
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
44
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
45
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
46
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
47
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
48
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
49
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
50
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
51
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
52
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
53
 *                        Includes the curve "a" variable in calculation
54
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
55
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
56
 *                                                              default: off
57
 * FP_ECC:              ECC Fixed Point Cache                   default: off
58
 *                      FP cache is not supported for SECP160R1, SECP160R2,
59
 *                      SECP160K1 and SECP224K1. These do not work with scalars
60
 *                      that are the length of the order when the order is
61
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
62
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
63
 *                      For the ECC curve parameters `ecc_set_type` use fixed
64
 *                      array for hex string
65
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify/keygen/secret.
66
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
67
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
68
 *                      normal blocking API's
69
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
70
 *                      signing. If the value is invalid, a new random 'k' is
71
 *                      generated in the loop. (For testing)
72
 *                                                              default: off
73
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
74
 *                      Enables the setting of the 'k' value to use during ECDSA
75
 *                      signing. If the value is invalid then an error is
76
 *                      returned rather than generating a new 'k'. (For testing)
77
 *                                                              default: off
78
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
79
 *                      deterministic ECC signatures. The following function
80
 *                      can be used to set the deterministic signing flag in the
81
 *                      ecc key structure.
82
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
83
 *                                                              default: off
84
 *
85
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
86
 *                      hash directly instead of doing bits2octets(H(m)), when
87
 *                      the variant macro is used the bits2octets operation on
88
 *                      the hash is removed.
89
 *                                                              default: off
90
 *
91
 * WC_PROTECT_ENCRYPTED_MEM:
92
 *                      Enables implementations that protect data that is in
93
 *                      encrypted memory.
94
 *                                                              default: off
95
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
96
 *                      Enables generation of scalar (private key and ECDSA
97
 *                      nonce) to be performed using reject sampling algorithm.
98
 *                      Use this when CPU state can be closely observed by
99
 *                      attacker.
100
 *                                                              default: off
101
 * WOLFSSL_ECC_BLIND_K
102
 *                      Blind the private key k by using a random mask.
103
 *                      The private key is never stored unprotected but an
104
 *                      unmasked copy is computed and stored each time it is
105
 *                      needed.
106
 *                                                              default: off
107
 * WOLFSSL_CHECK_VER_FAULTS
108
 *                      Sanity check on verification steps in case of faults.
109
 *                                                              default: off
110
 * ECC_TIMING_RESISTANT: Enables constant-time ECC operations   default: on
111
 *                      to prevent timing side-channel attacks.
112
 *                      Auto-enabled for FIPS and some embedded builds.
113
 * WC_NO_CACHE_RESISTANT: Disables cache-resistant operations   default: off
114
 *                      (conditional swaps) in ECC scalar multiply to
115
 *                      reduce overhead. Not recommended for secure use.
116
 * ALT_ECC_SIZE:        Uses alternate smaller fixed-size arrays default: off
117
 *                      for ECC points instead of full mp_int arrays,
118
 *                      reducing memory. Requires USE_FAST_MATH.
119
 * WOLFSSL_ECC_NO_SMALL_STACK: Disables WOLFSSL_SMALL_STACK     default: off
120
 *                      optimizations for ECC, using stack instead of heap.
121
 * HAVE_ECC_CHECK_PUBKEY_ORDER: Validates ECC public key order  default: on
122
 *                      during import. Auto-enabled unless
123
 *                      NO_ECC_CHECK_PUBKEY_ORDER is defined.
124
 * NO_ECC_CHECK_PUBKEY_ORDER: Disables public key order check   default: off
125
 *                      during ECC key import. Not recommended.
126
 * HAVE_ECC_MAKE_PUB:   Enables computing public key from       default: on
127
 *                      private key via wc_ecc_make_pub.
128
 * HAVE_ECC_VERIFY_HELPER: Enables ECC verify helper functions  default: on
129
 *                      Auto-enabled unless using hardware accelerators.
130
 * WOLFSSL_PUBLIC_ECC_ADD_DBL: Makes ecc_projective_add_point   default: off
131
 *                      and ecc_projective_dbl_point public APIs.
132
 * SQRTMOD_USE_MOD_EXP: Computes square root mod prime with a    default: off
133
 *                      single modular exponentiation, using less
134
 *                      stack than Tonelli-Shanks. Primes that are
135
 *                      1 mod 8 (P-224) are not supported, and
136
 *                      5 mod 8 (secp224k1) only with
137
 *                      HAVE_ECC_KOBLITZ or WOLFSSL_CUSTOM_CURVES.
138
 *
139
 * ECIES options:
140
 * WOLFSSL_ECIES_OLD:   Uses original wolfSSL ECIES format      default: off
141
 *                      (public key not in shared secret material).
142
 * WOLFSSL_ECIES_ISO18033: Uses ISO 18033 ECIES standard        default: off
143
 *                      (includes public key in shared secret).
144
 * WOLFSSL_ECIES_GEN_IV: Generates random IV for ECIES          default: off
145
 *                      encryption instead of deriving from KDF.
146
 * WOLFSSL_ECIES_STATIC_GCM_NONCE:                              default: off
147
 *                      Allows the AES-GCM DEM in the default IV mode, where the
148
 *                      GCM nonce is a fixed all-zero value that is not sent.
149
 *                      This is ONLY safe because ECIES derives a fresh key from
150
 *                      a fresh ephemeral key each message, so the (key, nonce)
151
 *                      pair never repeats.  Reusing the ephemeral key would
152
 *                      reuse both the key and the nonce - catastrophic for GCM.
153
 *                      Off by default: without this define, the GCM DEM returns
154
 *                      NOT_COMPILED_IN in the default IV mode so the fixed nonce
155
 *                      cannot be selected by accident.  Not needed with
156
 *                      WOLFSSL_ECIES_GEN_IV (random nonce) or WOLFSSL_ECIES_OLD
157
 *                      (KDF-derived nonce).
158
 *
159
 * Fixed Point Cache options (requires FP_ECC):
160
 * FP_ENTRIES:          Number of FP cache entries               default: 15
161
 * FP_LUT:              FP lookup table bit size (2-12). Larger  default: 8
162
 *                      values use more memory but faster verify.
163
 * FP_ECC_CONTROL:      Auto-selects cached FP ECC verify with  default: on
164
 *                      SP when WOLFSSL_HAVE_SP_ECC is available.
165
 *
166
 * SP Math ECC options:
167
 * WOLFSSL_HAVE_SP_ECC: Enables SP math optimizations for ECC   default: on
168
 *                      Provides significant performance improvement.
169
 * WOLFSSL_SP_NO_256:   Disables SP P-256 support               default: off
170
 * WOLFSSL_SP_384:      Enables SP P-384 support                default: off
171
 * WOLFSSL_SP_521:      Enables SP P-521 support                default: off
172
 * WOLFSSL_SP_1024:     Enables SP 1024-bit support for SAKKE   default: off
173
 * WOLFSSL_SP_SM2:      Enables SP SM2 curve support            default: off
174
 *                      Auto-enabled with WOLFSSL_SM2.
175
 *
176
 * Hardware/Offload options:
177
 * WOLFSSL_KCAPI_ECC:   Offload ECC to Linux Kernel Crypto API  default: off
178
 * WC_ASYNC_ENABLE_ECC: Enables async ECC with crypto callbacks default: off
179
 *                      Requires WOLFSSL_ASYNC_CRYPT.
180
 * WC_ASYNC_ENABLE_ECC_KEYGEN: Enables async ECC key gen        default: off
181
 * PLUTON_CRYPTO_ECC:   Uses ARM Pluton TEE for ECC operations  default: off
182
 * WOLFSSL_CAAM_BLACK_KEY_SM: Uses NXP CAAM secure memory for   default: off
183
 *                      encrypted black key storage.
184
 */
185
186
/*
187
ECC Curve Types:
188
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
189
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
190
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
191
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
192
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
193
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
194
 */
195
196
/*
197
ECC Curve Sizes:
198
 * ECC_USER_CURVES: Allows custom combination of key sizes below
199
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
200
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
201
 * HAVE_ECC112: 112 bit key
202
 * HAVE_ECC128: 128 bit key
203
 * HAVE_ECC160: 160 bit key
204
 * HAVE_ECC192: 192 bit key
205
 * HAVE_ECC224: 224 bit key
206
 * HAVE_ECC239: 239 bit key
207
 * NO_ECC256: Disables 256 bit key (on by default)
208
 * HAVE_ECC320: 320 bit key
209
 * HAVE_ECC384: 384 bit key
210
 * HAVE_ECC512: 512 bit key
211
 * HAVE_ECC521: 521 bit key
212
 */
213
214
215
#ifdef HAVE_ECC
216
217
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
218
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
219
    !defined(WOLFSSL_CUSTOM_CURVES)
220
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
221
#endif
222
223
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
224
    #if defined(USE_WINDOWS_API) && defined(_MSC_VER)
225
        #pragma code_seg(".fipsA$f")
226
        #pragma const_seg(".fipsB$f")
227
    #endif
228
#endif
229
230
/* public ASN interface */
231
#include <wolfssl/wolfcrypt/asn_public.h>
232
233
#include <wolfssl/wolfcrypt/ecc.h>
234
#include <wolfssl/wolfcrypt/asn.h>
235
#include <wolfssl/wolfcrypt/hash.h>
236
237
#ifdef WOLFSSL_HAVE_SP_ECC
238
#include <wolfssl/wolfcrypt/sp.h>
239
#endif
240
241
#ifdef HAVE_ECC_ENCRYPT
242
    #include <wolfssl/wolfcrypt/kdf.h>
243
244
    /* For wc_AesGcmEncrypt() wrapper, if needed. */
245
    #include <wolfssl/wolfcrypt/wc_compat.h>
246
247
    #include <wolfssl/wolfcrypt/aes.h>
248
#endif
249
250
#ifdef WOLF_CRYPTO_CB
251
    #include <wolfssl/wolfcrypt/cryptocb.h>
252
#endif
253
254
#ifdef NO_INLINE
255
    #include <wolfssl/wolfcrypt/misc.h>
256
#else
257
    #define WOLFSSL_MISC_INCLUDED
258
    #include <wolfcrypt/src/misc.c>
259
#endif
260
261
#if FIPS_VERSION3_GE(6,0,0)
262
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
263
                                                     { 0x1a2b3c4d, 0x00000005 };
264
    int wolfCrypt_FIPS_ECC_sanity(void)
265
    {
266
        return 0;
267
    }
268
#endif
269
270
#if defined(FREESCALE_LTC_ECC)
271
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
272
#endif
273
274
#if defined(WOLFSSL_STM32_PKA) || defined(WOLFSSL_STM32_CCB) || \
275
    defined(WOLFSSL_DHUK)
276
    /* CCB without PKA still needs stm32.h so its consistency #errors (e.g. CCB
277
     * requires DHUK + BARE/CUBEMX) are visible to this translation unit, and
278
     * the DHUK case needs WC_STM32_HAS_DHUK visible so the
279
     * wc_ecc_import_wrapped_private definition below is gated the same way as
280
     * its prototype in ecc.h. */
281
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
282
#endif
283
284
#if defined(WOLFSSL_PSOC6_CRYPTO)
285
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
286
#endif
287
288
#if defined(WOLFSSL_CAAM)
289
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
290
#endif
291
292
#if defined(WOLFSSL_KCAPI_ECC)
293
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
294
#endif
295
296
#ifdef WOLFSSL_SE050
297
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
298
#endif
299
300
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
301
    #include <xsecure_ellipticclient.h>
302
#endif
303
304
#ifdef TI_MCU_PLUS_SDK
305
    #include <strings.h>
306
#endif
307
308
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
309
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
310
    #include <wolfssl/wolfcrypt/hmac.h>
311
#endif
312
313
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
314
    !defined(WOLFSSL_MICROCHIP_TA100) && \
315
    !defined(WOLFSSL_SILABS_SE_ACCEL) && \
316
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
317
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && \
318
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
319
    !defined(PSOC6_CRYPTO_ECC)
320
    /* STM32 sign-only (e.g. C5): the HW PKA cannot run the integrated ECDSA
321
     * verify (mode 0x26) correctly, so use the SW verify helper rather than the
322
     * HW-accelerator sigRS path. Note the helper's scalar multiplications still
323
     * run on the HW PKA generic-mul (stm32.c provides wc_ecc_mulmod_ex under
324
     * !WC_STM32_PKA_VERIFY_ONLY) -- the C5 issue is specifically the verify-mode
325
     * wrapper, not the point math, which is exercised and correct (the lead for
326
     * a future real HW verify). */
327
    #undef  HAVE_ECC_VERIFY_HELPER
328
    #define HAVE_ECC_VERIFY_HELPER
329
#endif
330
/* Compile in the software verify helper whenever SE050 hardware ECDSA verify is
331
 * bypassed:
332
 *  - WOLFSSL_SE050_NO_ECDSA_VERIFY disables SE050 ECDSA verify outright.
333
 *  - WOLFSSL_SE050_ONLY_KEY_ID verifies software keys (keyIdSet == 0) in
334
 *    wolfCrypt; the SE050 is used at runtime only for keys resident in HW. */
335
#if (defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) || \
336
     (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID))) && \
337
    defined(HAVE_ECC_VERIFY)
338
    #define HAVE_ECC_VERIFY_HELPER
339
#endif
340
341
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
342
        !defined(WOLFSSL_MICROCHIP_TA100) && \
343
    !defined(WOLFSSL_SILABS_SE_ACCEL) && \
344
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
345
    !defined(WOLFSSL_NO_ECC_SW)
346
    #undef  HAVE_ECC_MAKE_PUB
347
    #define HAVE_ECC_MAKE_PUB
348
#endif
349
350
351
/* macro guard for ecc_check_pubkey_order functionality */
352
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
353
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
354
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
355
     !defined(WOLFSSL_MICROCHIP_TA100) && \
356
     !defined(WOLFSSL_SILABS_SE_ACCEL) && \
357
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
358
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
359
360
    /* CAAM builds use public key validation as a means to check if an
361
     * imported private key is an encrypted black key or not */
362
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
363
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
364
#endif
365
366
/* MAX_ECC_BITS is the largest curve compiled in unless the user raised it, and
367
 * ecc.h rejects a smaller one.  MAX_ECC_BITS_EXTRA is the bit ECC_KEY_MAX_BITS
368
 * adds below, so the working values need room for it too. */
369
#if defined(WOLFSSL_SP_MATH_ALL) && \
370
    SP_INT_BITS < (MAX_ECC_BITS + MAX_ECC_BITS_EXTRA)
371
#define MAX_ECC_BITS_USE    SP_INT_BITS
372
#else
373
#define MAX_ECC_BITS_USE    (MAX_ECC_BITS + MAX_ECC_BITS_EXTRA)
374
#endif
375
376
/* Size sp_int curve parameters for the largest curve, up to SP_INT_DIGITS */
377
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)
378
    #define ECC_SPEC_INTS_SIZED
379
    #define ECC_SPEC_INT_CNT                                        \
380
2.49k
        ((MP_BITS_CNT(MAX_ECC_BITS_USE) < SP_INT_DIGITS) ?          \
381
2.49k
         MP_BITS_CNT(MAX_ECC_BITS_USE) : (unsigned int)SP_INT_DIGITS)
382
#endif
383
384
/* MAX_ECC_BITS_EXTRA (ecc.h) is the one bit the builds whose order can be a bit
385
 * greater than the prime need, and the ceiling is sized from the same macro. */
386
#define ECC_KEY_MAX_BITS(key)                                       \
387
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
388
        ((unsigned)((key)->dp->size * 8 + MAX_ECC_BITS_EXTRA)))
389
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
390
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
391
        ((unsigned)((key)->dp->size * 8 + MAX_ECC_BITS_EXTRA)))
392
393
#ifdef WOLFSSL_ECC_BLIND_K
394
/* Width of the XORs below. It covers the order, which can be a bit longer
395
 * than the prime. */
396
#define ECC_BLIND_K_BYTES(key) \
397
    ((int)((ECC_KEY_MAX_BITS_NONULLCHECK(key) + 7) / 8))
398
/* Number of digits covered by the fixed-width XORs below. */
399
#define ECC_BLIND_K_DIGITS(key) \
400
    ((int)((ECC_BLIND_K_BYTES(key) + sizeof(mp_digit) - 1) / sizeof(mp_digit)))
401
402
/* The XORs read this many whole digits regardless of each operand's current
403
 * length, so operands written at partial width (e.g. by mp_copy()) must be
404
 * zero-extended first or stale digits fold into the value. mp_grow() cannot
405
 * fail for a curve-sized key; fail closed if it ever does. */
406
mp_int* ecc_get_k(ecc_key* key)
407
{
408
    if ((mp_grow(key->k, ECC_BLIND_K_DIGITS(key)) != MP_OKAY) ||
409
        (mp_grow(key->kb, ECC_BLIND_K_DIGITS(key)) != MP_OKAY)) {
410
        mp_forcezero(key->ku);
411
    }
412
    else {
413
        mp_xor_ct(key->k, key->kb, ECC_BLIND_K_BYTES(key), key->ku);
414
    }
415
    return key->ku;
416
}
417
void ecc_blind_k(ecc_key* key, mp_int* b)
418
{
419
    if ((mp_grow(key->k, ECC_BLIND_K_DIGITS(key)) == MP_OKAY) &&
420
        (mp_grow(key->kb, ECC_BLIND_K_DIGITS(key)) == MP_OKAY) &&
421
        (mp_grow(b, ECC_BLIND_K_DIGITS(key)) == MP_OKAY)) {
422
        mp_xor_ct(key->k, b, ECC_BLIND_K_BYTES(key), key->k);
423
        mp_xor_ct(key->kb, b, ECC_BLIND_K_BYTES(key), key->kb);
424
    }
425
}
426
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
427
{
428
    int ret = 0;
429
    WC_RNG local_rng;
430
431
#ifdef ECC_TIMING_RESISTANT
432
    if (rng == NULL) {
433
        rng = key->rng;
434
    }
435
#endif
436
    if (rng == NULL) {
437
        ret = wc_InitRng(&local_rng);
438
        if (ret == 0) {
439
            rng = &local_rng;
440
        }
441
    }
442
    if (ret == 0) {
443
        ret = mp_rand(key->kb, ECC_BLIND_K_DIGITS(key), rng);
444
        if (ret == 0) {
445
            ret = mp_grow(key->k, ECC_BLIND_K_DIGITS(key));
446
        }
447
        if (ret == 0) {
448
            mp_xor_ct(key->k, key->kb, ECC_BLIND_K_BYTES(key), key->k);
449
        }
450
        else {
451
            /* No blind installed - keep the stored pair consistent. */
452
            mp_forcezero(key->kb);
453
        }
454
    }
455
456
    if (rng == &local_rng) {
457
        wc_FreeRng(&local_rng);
458
    }
459
    return ret;
460
}
461
462
void ecc_forcezero_k(ecc_key* key)
463
{
464
    mp_forcezero(key->k);
465
    mp_forcezero(key->kb);
466
    mp_forcezero(key->ku);
467
}
468
469
/* Drop the unblinded copy once the caller is done with it. */
470
void ecc_put_k(ecc_key* key)
471
{
472
    mp_forcezero(key->ku);
473
}
474
475
mp_int* wc_ecc_key_get_priv(ecc_key* key)
476
{
477
    return ecc_get_k(key);
478
}
479
#endif
480
481
/* forward declarations */
482
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
483
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
484
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
485
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
486
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
487
#endif
488
489
/* internal ECC states */
490
enum {
491
    ECC_STATE_NONE = 0,
492
493
    ECC_STATE_SHARED_SEC_GEN,
494
    ECC_STATE_SHARED_SEC_RES,
495
496
    ECC_STATE_SIGN_DO,
497
    ECC_STATE_SIGN_ENCODE,
498
499
    ECC_STATE_VERIFY_DECODE,
500
    ECC_STATE_VERIFY_DO,
501
    ECC_STATE_VERIFY_RES
502
};
503
504
505
/* map
506
   ptmul -> mulmod
507
*/
508
509
/* 256-bit curve on by default whether user curves or not */
510
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
511
    #define ECC112
512
#endif
513
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
514
    #define ECC128
515
#endif
516
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
517
    #define ECC160
518
#endif
519
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
520
    #define ECC192
521
#endif
522
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
523
    #define ECC224
524
#endif
525
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
526
    #define ECC239
527
#endif
528
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
529
    #define ECC256
530
#endif
531
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
532
    #define ECC320
533
#endif
534
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
535
    #define ECC384
536
#endif
537
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
538
    #define ECC512
539
#endif
540
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
541
    #define ECC521
542
#endif
543
544
/* The encoded OID's for ECC curves */
545
#ifdef ECC112
546
    #ifndef NO_ECC_SECP
547
        #ifdef HAVE_OID_ENCODING
548
            #define CODED_SECP112R1    {1,3,132,0,6}
549
            #define CODED_SECP112R1_SZ 5
550
        #else
551
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
552
            #define CODED_SECP112R1_SZ 5
553
        #endif
554
        #ifndef WOLFSSL_ECC_CURVE_STATIC
555
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
556
        #else
557
            #define ecc_oid_secp112r1 CODED_SECP112R1
558
        #endif
559
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
560
    #endif /* !NO_ECC_SECP */
561
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
562
        #ifdef HAVE_OID_ENCODING
563
            #define CODED_SECP112R2    {1,3,132,0,7}
564
            #define CODED_SECP112R2_SZ 5
565
        #else
566
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
567
            #define CODED_SECP112R2_SZ 5
568
        #endif
569
        #ifndef WOLFSSL_ECC_CURVE_STATIC
570
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
571
        #else
572
            #define ecc_oid_secp112r2 CODED_SECP112R2
573
        #endif
574
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
575
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
576
#endif /* ECC112 */
577
#ifdef ECC128
578
    #ifndef NO_ECC_SECP
579
        #ifdef HAVE_OID_ENCODING
580
            #define CODED_SECP128R1    {1,3,132,0,28}
581
            #define CODED_SECP128R1_SZ 5
582
        #else
583
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
584
            #define CODED_SECP128R1_SZ 5
585
        #endif
586
        #ifndef WOLFSSL_ECC_CURVE_STATIC
587
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
588
        #else
589
            #define ecc_oid_secp128r1 CODED_SECP128R1
590
        #endif
591
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
592
    #endif /* !NO_ECC_SECP */
593
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
594
        #ifdef HAVE_OID_ENCODING
595
            #define CODED_SECP128R2    {1,3,132,0,29}
596
            #define CODED_SECP128R2_SZ 5
597
        #else
598
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
599
            #define CODED_SECP128R2_SZ 5
600
        #endif
601
        #ifndef WOLFSSL_ECC_CURVE_STATIC
602
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
603
        #else
604
            #define ecc_oid_secp128r2 CODED_SECP128R2
605
        #endif
606
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
607
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
608
#endif /* ECC128 */
609
#ifdef ECC160
610
#ifndef FP_ECC
611
    #ifndef NO_ECC_SECP
612
        #ifdef HAVE_OID_ENCODING
613
            #define CODED_SECP160R1    {1,3,132,0,8}
614
            #define CODED_SECP160R1_SZ 5
615
        #else
616
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
617
            #define CODED_SECP160R1_SZ 5
618
        #endif
619
        #ifndef WOLFSSL_ECC_CURVE_STATIC
620
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
621
        #else
622
            #define ecc_oid_secp160r1 CODED_SECP160R1
623
        #endif
624
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
625
    #endif /* !NO_ECC_SECP */
626
    #ifdef HAVE_ECC_SECPR2
627
        #ifdef HAVE_OID_ENCODING
628
            #define CODED_SECP160R2    {1,3,132,0,30}
629
            #define CODED_SECP160R2_SZ 5
630
        #else
631
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
632
            #define CODED_SECP160R2_SZ 5
633
        #endif
634
        #ifndef WOLFSSL_ECC_CURVE_STATIC
635
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
636
        #else
637
            #define ecc_oid_secp160r2 CODED_SECP160R2
638
        #endif
639
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
640
    #endif /* HAVE_ECC_SECPR2 */
641
    #ifdef HAVE_ECC_KOBLITZ
642
        #ifdef HAVE_OID_ENCODING
643
            #define CODED_SECP160K1    {1,3,132,0,9}
644
            #define CODED_SECP160K1_SZ 5
645
        #else
646
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
647
            #define CODED_SECP160K1_SZ 5
648
        #endif
649
        #ifndef WOLFSSL_ECC_CURVE_STATIC
650
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
651
        #else
652
            #define ecc_oid_secp160k1 CODED_SECP160K1
653
        #endif
654
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
655
    #endif /* HAVE_ECC_KOBLITZ */
656
#endif /* !FP_ECC */
657
    #ifdef HAVE_ECC_BRAINPOOL
658
        #ifdef HAVE_OID_ENCODING
659
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
660
            #define CODED_BRAINPOOLP160R1_SZ 10
661
        #else
662
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
663
            #define CODED_BRAINPOOLP160R1_SZ 9
664
        #endif
665
        #ifndef WOLFSSL_ECC_CURVE_STATIC
666
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
667
        #else
668
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
669
        #endif
670
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
671
    #endif /* HAVE_ECC_BRAINPOOL */
672
#endif /* ECC160 */
673
#ifdef ECC192
674
    #ifndef NO_ECC_SECP
675
        #ifdef HAVE_OID_ENCODING
676
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
677
            #define CODED_SECP192R1_SZ 7
678
        #else
679
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
680
            #define CODED_SECP192R1_SZ 8
681
        #endif
682
        #ifndef WOLFSSL_ECC_CURVE_STATIC
683
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
684
        #else
685
            #define ecc_oid_secp192r1 CODED_SECP192R1
686
        #endif
687
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
688
    #endif /* !NO_ECC_SECP */
689
    #ifdef HAVE_ECC_SECPR2
690
        #ifdef HAVE_OID_ENCODING
691
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
692
            #define CODED_PRIME192V2_SZ 7
693
        #else
694
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
695
            #define CODED_PRIME192V2_SZ 8
696
        #endif
697
        #ifndef WOLFSSL_ECC_CURVE_STATIC
698
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
699
        #else
700
            #define ecc_oid_prime192v2 CODED_PRIME192V2
701
        #endif
702
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
703
    #endif /* HAVE_ECC_SECPR2 */
704
    #ifdef HAVE_ECC_SECPR3
705
        #ifdef HAVE_OID_ENCODING
706
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
707
            #define CODED_PRIME192V3_SZ 7
708
        #else
709
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
710
            #define CODED_PRIME192V3_SZ 8
711
        #endif
712
        #ifndef WOLFSSL_ECC_CURVE_STATIC
713
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
714
        #else
715
            #define ecc_oid_prime192v3 CODED_PRIME192V3
716
        #endif
717
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
718
    #endif /* HAVE_ECC_SECPR3 */
719
    #ifdef HAVE_ECC_KOBLITZ
720
        #ifdef HAVE_OID_ENCODING
721
            #define CODED_SECP192K1    {1,3,132,0,31}
722
            #define CODED_SECP192K1_SZ 5
723
        #else
724
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
725
            #define CODED_SECP192K1_SZ 5
726
        #endif
727
        #ifndef WOLFSSL_ECC_CURVE_STATIC
728
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
729
        #else
730
            #define ecc_oid_secp192k1 CODED_SECP192K1
731
        #endif
732
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
733
    #endif /* HAVE_ECC_KOBLITZ */
734
    #ifdef HAVE_ECC_BRAINPOOL
735
        #ifdef HAVE_OID_ENCODING
736
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
737
            #define CODED_BRAINPOOLP192R1_SZ 10
738
        #else
739
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
740
            #define CODED_BRAINPOOLP192R1_SZ 9
741
        #endif
742
        #ifndef WOLFSSL_ECC_CURVE_STATIC
743
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
744
        #else
745
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
746
        #endif
747
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
748
    #endif /* HAVE_ECC_BRAINPOOL */
749
#endif /* ECC192 */
750
#ifdef ECC224
751
    #ifndef NO_ECC_SECP
752
        #ifdef HAVE_OID_ENCODING
753
            #define CODED_SECP224R1    {1,3,132,0,33}
754
            #define CODED_SECP224R1_SZ 5
755
        #else
756
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
757
            #define CODED_SECP224R1_SZ 5
758
        #endif
759
        #ifndef WOLFSSL_ECC_CURVE_STATIC
760
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
761
        #else
762
            #define ecc_oid_secp224r1 CODED_SECP224R1
763
        #endif
764
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
765
    #endif /* !NO_ECC_SECP */
766
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
767
        #ifdef HAVE_OID_ENCODING
768
            #define CODED_SECP224K1    {1,3,132,0,32}
769
            #define CODED_SECP224K1_SZ 5
770
        #else
771
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
772
            #define CODED_SECP224K1_SZ 5
773
        #endif
774
        #ifndef WOLFSSL_ECC_CURVE_STATIC
775
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
776
        #else
777
            #define ecc_oid_secp224k1 CODED_SECP224K1
778
        #endif
779
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
780
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
781
    #ifdef HAVE_ECC_BRAINPOOL
782
        #ifdef HAVE_OID_ENCODING
783
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
784
            #define CODED_BRAINPOOLP224R1_SZ 10
785
        #else
786
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
787
            #define CODED_BRAINPOOLP224R1_SZ 9
788
        #endif
789
        #ifndef WOLFSSL_ECC_CURVE_STATIC
790
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
791
        #else
792
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
793
        #endif
794
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
795
    #endif /* HAVE_ECC_BRAINPOOL */
796
#endif /* ECC224 */
797
#ifdef ECC239
798
    #ifndef NO_ECC_SECP
799
        #ifdef HAVE_OID_ENCODING
800
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
801
            #define CODED_PRIME239V1_SZ 7
802
        #else
803
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
804
            #define CODED_PRIME239V1_SZ 8
805
        #endif
806
        #ifndef WOLFSSL_ECC_CURVE_STATIC
807
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
808
        #else
809
            #define ecc_oid_prime239v1 CODED_PRIME239V1
810
        #endif
811
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
812
    #endif /* !NO_ECC_SECP */
813
    #ifdef HAVE_ECC_SECPR2
814
        #ifdef HAVE_OID_ENCODING
815
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
816
            #define CODED_PRIME239V2_SZ 7
817
        #else
818
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
819
            #define CODED_PRIME239V2_SZ 8
820
        #endif
821
        #ifndef WOLFSSL_ECC_CURVE_STATIC
822
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
823
        #else
824
            #define ecc_oid_prime239v2 CODED_PRIME239V2
825
        #endif
826
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
827
    #endif /* HAVE_ECC_SECPR2 */
828
    #ifdef HAVE_ECC_SECPR3
829
        #ifdef HAVE_OID_ENCODING
830
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
831
            #define CODED_PRIME239V3_SZ 7
832
        #else
833
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
834
            #define CODED_PRIME239V3_SZ 8
835
        #endif
836
        #ifndef WOLFSSL_ECC_CURVE_STATIC
837
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
838
        #else
839
            #define ecc_oid_prime239v3 CODED_PRIME239V3
840
        #endif
841
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
842
    #endif /* HAVE_ECC_SECPR3 */
843
#endif /* ECC239 */
844
#ifdef ECC256
845
    #ifndef NO_ECC_SECP
846
        #ifdef HAVE_OID_ENCODING
847
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
848
            #define CODED_SECP256R1_SZ 7
849
        #else
850
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
851
            #define CODED_SECP256R1_SZ 8
852
        #endif
853
        #ifndef WOLFSSL_ECC_CURVE_STATIC
854
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
855
        #else
856
            #define ecc_oid_secp256r1 CODED_SECP256R1
857
        #endif
858
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
859
    #endif /* !NO_ECC_SECP */
860
    #ifdef HAVE_ECC_KOBLITZ
861
        #ifdef HAVE_OID_ENCODING
862
            #define CODED_SECP256K1    {1,3,132,0,10}
863
            #define CODED_SECP256K1_SZ 5
864
        #else
865
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
866
            #define CODED_SECP256K1_SZ 5
867
        #endif
868
        #ifndef WOLFSSL_ECC_CURVE_STATIC
869
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
870
        #else
871
            #define ecc_oid_secp256k1 CODED_SECP256K1
872
        #endif
873
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
874
    #endif /* HAVE_ECC_KOBLITZ */
875
    #ifdef HAVE_ECC_BRAINPOOL
876
        #ifdef HAVE_OID_ENCODING
877
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
878
            #define CODED_BRAINPOOLP256R1_SZ 10
879
        #else
880
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
881
            #define CODED_BRAINPOOLP256R1_SZ 9
882
        #endif
883
        #ifndef WOLFSSL_ECC_CURVE_STATIC
884
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
885
        #else
886
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
887
        #endif
888
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
889
    #endif /* HAVE_ECC_BRAINPOOL */
890
#endif /* ECC256 */
891
    #if defined(WOLFSSL_SM2)
892
        #ifdef HAVE_OID_ENCODING
893
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
894
            #define CODED_SM2P256V1_SZ 6
895
        #else
896
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
897
            #define CODED_SM2P256V1_SZ 8
898
        #endif
899
        #ifndef WOLFSSL_ECC_CURVE_STATIC
900
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
901
        #else
902
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
903
        #endif
904
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
905
    #endif /* WOLFSSL_SM2 */
906
#ifdef ECC320
907
    #ifdef HAVE_ECC_BRAINPOOL
908
        #ifdef HAVE_OID_ENCODING
909
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
910
            #define CODED_BRAINPOOLP320R1_SZ 10
911
        #else
912
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
913
            #define CODED_BRAINPOOLP320R1_SZ 9
914
        #endif
915
        #ifndef WOLFSSL_ECC_CURVE_STATIC
916
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
917
        #else
918
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
919
        #endif
920
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
921
    #endif /* HAVE_ECC_BRAINPOOL */
922
#endif /* ECC320 */
923
#ifdef ECC384
924
    #ifndef NO_ECC_SECP
925
        #ifdef HAVE_OID_ENCODING
926
            #define CODED_SECP384R1    {1,3,132,0,34}
927
            #define CODED_SECP384R1_SZ 5
928
        #else
929
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
930
            #define CODED_SECP384R1_SZ 5
931
        #endif
932
        #ifndef WOLFSSL_ECC_CURVE_STATIC
933
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
934
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
935
        #else
936
            #define ecc_oid_secp384r1 CODED_SECP384R1
937
        #endif
938
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
939
    #endif /* !NO_ECC_SECP */
940
    #ifdef HAVE_ECC_BRAINPOOL
941
        #ifdef HAVE_OID_ENCODING
942
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
943
            #define CODED_BRAINPOOLP384R1_SZ 10
944
        #else
945
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
946
            #define CODED_BRAINPOOLP384R1_SZ 9
947
        #endif
948
        #ifndef WOLFSSL_ECC_CURVE_STATIC
949
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
950
        #else
951
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
952
        #endif
953
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
954
    #endif /* HAVE_ECC_BRAINPOOL */
955
#endif /* ECC384 */
956
#ifdef ECC512
957
    #ifdef HAVE_ECC_BRAINPOOL
958
        #ifdef HAVE_OID_ENCODING
959
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
960
            #define CODED_BRAINPOOLP512R1_SZ 10
961
        #else
962
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
963
            #define CODED_BRAINPOOLP512R1_SZ 9
964
        #endif
965
        #ifndef WOLFSSL_ECC_CURVE_STATIC
966
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
967
        #else
968
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
969
        #endif
970
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
971
    #endif /* HAVE_ECC_BRAINPOOL */
972
#endif /* ECC512 */
973
#ifdef ECC521
974
    #ifndef NO_ECC_SECP
975
        #ifdef HAVE_OID_ENCODING
976
            #define CODED_SECP521R1     {1,3,132,0,35}
977
            #define CODED_SECP521R1_SZ 5
978
        #else
979
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
980
            #define CODED_SECP521R1_SZ 5
981
        #endif
982
        #ifndef WOLFSSL_ECC_CURVE_STATIC
983
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
984
        #else
985
            #define ecc_oid_secp521r1 CODED_SECP521R1
986
        #endif
987
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
988
    #endif /* !NO_ECC_SECP */
989
#endif /* ECC521 */
990
991
992
/* This holds the key settings.
993
   ***MUST*** be organized by size from smallest to largest. */
994
995
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
996
    #undef ecc_sets
997
    #undef ecc_sets_count
998
#endif
999
1000
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1001
static
1002
#endif
1003
const ecc_set_type ecc_sets[] = {
1004
#ifdef ECC112
1005
    #ifndef NO_ECC_SECP
1006
    {
1007
        14,                             /* size/bytes */
1008
        ECC_SECP112R1,                  /* ID         */
1009
        "SECP112R1",                    /* curve name */
1010
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
1011
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
1012
        "659EF8BA043916EEDE8911702B22", /* B          */
1013
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
1014
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
1015
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
1016
        ecc_oid_secp112r1,              /* oid/oidSz  */
1017
        ecc_oid_secp112r1_sz,
1018
        ECC_SECP112R1_OID,              /* oid sum    */
1019
        1,                              /* cofactor   */
1020
    },
1021
    #endif /* !NO_ECC_SECP */
1022
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
1023
    {
1024
        14,                             /* size/bytes */
1025
        ECC_SECP112R2,                  /* ID         */
1026
        "SECP112R2",                    /* curve name */
1027
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
1028
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
1029
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
1030
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
1031
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
1032
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
1033
        ecc_oid_secp112r2,              /* oid/oidSz  */
1034
        ecc_oid_secp112r2_sz,
1035
        ECC_SECP112R2_OID,              /* oid sum    */
1036
        4,                              /* cofactor   */
1037
    },
1038
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
1039
#endif /* ECC112 */
1040
#ifdef ECC128
1041
    #ifndef NO_ECC_SECP
1042
    {
1043
        16,                                 /* size/bytes */
1044
        ECC_SECP128R1,                      /* ID         */
1045
        "SECP128R1",                        /* curve name */
1046
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1047
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1048
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
1049
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
1050
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
1051
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
1052
        ecc_oid_secp128r1,                  /* oid/oidSz  */
1053
        ecc_oid_secp128r1_sz,
1054
        ECC_SECP128R1_OID,                  /* oid sum    */
1055
        1,                                  /* cofactor   */
1056
    },
1057
    #endif /* !NO_ECC_SECP */
1058
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
1059
    {
1060
        16,                                 /* size/bytes */
1061
        ECC_SECP128R2,                      /* ID         */
1062
        "SECP128R2",                        /* curve name */
1063
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1064
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
1065
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
1066
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
1067
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
1068
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
1069
        ecc_oid_secp128r2,                  /* oid/oidSz  */
1070
        ecc_oid_secp128r2_sz,
1071
        ECC_SECP128R2_OID,                  /* oid sum    */
1072
        4,                                  /* cofactor   */
1073
    },
1074
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
1075
#endif /* ECC128 */
1076
#ifdef ECC160
1077
#ifndef FP_ECC
1078
    #ifndef NO_ECC_SECP
1079
    {
1080
        20,                                         /* size/bytes */
1081
        ECC_SECP160R1,                              /* ID         */
1082
        "SECP160R1",                                /* curve name */
1083
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
1084
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
1085
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
1086
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
1087
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
1088
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
1089
        ecc_oid_secp160r1,                          /* oid/oidSz  */
1090
        ecc_oid_secp160r1_sz,
1091
        ECC_SECP160R1_OID,                          /* oid sum    */
1092
        1,                                          /* cofactor   */
1093
    },
1094
    #endif /* !NO_ECC_SECP */
1095
    #ifdef HAVE_ECC_SECPR2
1096
    {
1097
        20,                                         /* size/bytes */
1098
        ECC_SECP160R2,                              /* ID         */
1099
        "SECP160R2",                                /* curve name */
1100
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1101
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
1102
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
1103
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
1104
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
1105
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
1106
        ecc_oid_secp160r2,                          /* oid/oidSz  */
1107
        ecc_oid_secp160r2_sz,
1108
        ECC_SECP160R2_OID,                          /* oid sum    */
1109
        1,                                          /* cofactor   */
1110
    },
1111
    #endif /* HAVE_ECC_SECPR2 */
1112
    #ifdef HAVE_ECC_KOBLITZ
1113
    {
1114
        20,                                         /* size/bytes */
1115
        ECC_SECP160K1,                              /* ID         */
1116
        "SECP160K1",                                /* curve name */
1117
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1118
        "0000000000000000000000000000000000000000", /* A          */
1119
        "0000000000000000000000000000000000000007", /* B          */
1120
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
1121
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
1122
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
1123
        ecc_oid_secp160k1,                          /* oid/oidSz  */
1124
        ecc_oid_secp160k1_sz,
1125
        ECC_SECP160K1_OID,                          /* oid sum    */
1126
        1,                                          /* cofactor   */
1127
    },
1128
    #endif /* HAVE_ECC_KOBLITZ */
1129
#endif /* !FP_ECC */
1130
    #ifdef HAVE_ECC_BRAINPOOL
1131
    {
1132
        20,                                         /* size/bytes */
1133
        ECC_BRAINPOOLP160R1,                        /* ID         */
1134
        "BRAINPOOLP160R1",                          /* curve name */
1135
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
1136
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
1137
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
1138
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
1139
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
1140
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
1141
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1142
        ecc_oid_brainpoolp160r1_sz,
1143
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1144
        1,                                          /* cofactor   */
1145
    },
1146
    #endif /* HAVE_ECC_BRAINPOOL */
1147
#endif /* ECC160 */
1148
#ifdef ECC192
1149
    #ifndef NO_ECC_SECP
1150
    {
1151
        24,                                                 /* size/bytes */
1152
        ECC_SECP192R1,                                      /* ID         */
1153
        "SECP192R1",                                        /* curve name */
1154
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1155
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1156
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1157
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1158
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1159
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1160
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1161
        ecc_oid_secp192r1_sz,
1162
        ECC_SECP192R1_OID,                                  /* oid sum    */
1163
        1,                                                  /* cofactor   */
1164
    },
1165
    #endif /* !NO_ECC_SECP */
1166
    #ifdef HAVE_ECC_SECPR2
1167
    {
1168
        24,                                                 /* size/bytes */
1169
        ECC_PRIME192V2,                                     /* ID         */
1170
        "PRIME192V2",                                       /* curve name */
1171
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1172
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1173
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1174
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1175
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1176
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1177
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1178
        ecc_oid_prime192v2_sz,
1179
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1180
        1,                                                  /* cofactor   */
1181
    },
1182
    #endif /* HAVE_ECC_SECPR2 */
1183
    #ifdef HAVE_ECC_SECPR3
1184
    {
1185
        24,                                                 /* size/bytes */
1186
        ECC_PRIME192V3,                                     /* ID         */
1187
        "PRIME192V3",                                       /* curve name */
1188
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1189
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1190
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1191
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1192
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1193
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1194
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1195
        ecc_oid_prime192v3_sz,
1196
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1197
        1,                                                  /* cofactor   */
1198
    },
1199
    #endif /* HAVE_ECC_SECPR3 */
1200
    #ifdef HAVE_ECC_KOBLITZ
1201
    {
1202
        24,                                                 /* size/bytes */
1203
        ECC_SECP192K1,                                      /* ID         */
1204
        "SECP192K1",                                        /* curve name */
1205
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1206
        "000000000000000000000000000000000000000000000000", /* A          */
1207
        "000000000000000000000000000000000000000000000003", /* B          */
1208
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1209
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1210
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1211
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1212
        ecc_oid_secp192k1_sz,
1213
        ECC_SECP192K1_OID,                                  /* oid sum    */
1214
        1,                                                  /* cofactor   */
1215
    },
1216
    #endif /* HAVE_ECC_KOBLITZ */
1217
    #ifdef HAVE_ECC_BRAINPOOL
1218
    {
1219
        24,                                                 /* size/bytes */
1220
        ECC_BRAINPOOLP192R1,                                /* ID         */
1221
        "BRAINPOOLP192R1",                                  /* curve name */
1222
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1223
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1224
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1225
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1226
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1227
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1228
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1229
        ecc_oid_brainpoolp192r1_sz,
1230
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1231
        1,                                                  /* cofactor   */
1232
    },
1233
    #endif /* HAVE_ECC_BRAINPOOL */
1234
#endif /* ECC192 */
1235
#ifdef ECC224
1236
    #ifndef NO_ECC_SECP
1237
    {
1238
        28,                                                         /* size/bytes */
1239
        ECC_SECP224R1,                                              /* ID         */
1240
        "SECP224R1",                                                /* curve name */
1241
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1242
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1243
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1244
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1245
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1246
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1247
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1248
        ecc_oid_secp224r1_sz,
1249
        ECC_SECP224R1_OID,                                          /* oid sum    */
1250
        1,                                                          /* cofactor   */
1251
    },
1252
    #endif /* !NO_ECC_SECP */
1253
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1254
    {
1255
        28,                                                         /* size/bytes */
1256
        ECC_SECP224K1,                                              /* ID         */
1257
        "SECP224K1",                                                /* curve name */
1258
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1259
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1260
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1261
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1262
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1263
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1264
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1265
        ecc_oid_secp224k1_sz,
1266
        ECC_SECP224K1_OID,                                          /* oid sum    */
1267
        1,                                                          /* cofactor   */
1268
    },
1269
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1270
    #ifdef HAVE_ECC_BRAINPOOL
1271
    {
1272
        28,                                                         /* size/bytes */
1273
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1274
        "BRAINPOOLP224R1",                                          /* curve name */
1275
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1276
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1277
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1278
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1279
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1280
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1281
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1282
        ecc_oid_brainpoolp224r1_sz,
1283
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1284
        1,                                                          /* cofactor   */
1285
    },
1286
    #endif /* HAVE_ECC_BRAINPOOL */
1287
#endif /* ECC224 */
1288
#ifdef ECC239
1289
    #ifndef NO_ECC_SECP
1290
    {
1291
        30,                                                             /* size/bytes */
1292
        ECC_PRIME239V1,                                                 /* ID         */
1293
        "PRIME239V1",                                                   /* curve name */
1294
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1295
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1296
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1297
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1298
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1299
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1300
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1301
        ecc_oid_prime239v1_sz,
1302
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1303
        1,                                                              /* cofactor   */
1304
    },
1305
    #endif /* !NO_ECC_SECP */
1306
    #ifdef HAVE_ECC_SECPR2
1307
    {
1308
        30,                                                             /* size/bytes */
1309
        ECC_PRIME239V2,                                                 /* ID         */
1310
        "PRIME239V2",                                                   /* curve name */
1311
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1312
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1313
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1314
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1315
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1316
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1317
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1318
        ecc_oid_prime239v2_sz,
1319
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1320
        1,                                                              /* cofactor   */
1321
    },
1322
    #endif /* HAVE_ECC_SECPR2 */
1323
    #ifdef HAVE_ECC_SECPR3
1324
    {
1325
        30,                                                             /* size/bytes */
1326
        ECC_PRIME239V3,                                                 /* ID         */
1327
        "PRIME239V3",                                                   /* curve name */
1328
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1329
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1330
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1331
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1332
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1333
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1334
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1335
        ecc_oid_prime239v3_sz,
1336
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1337
        1,                                                              /* cofactor   */
1338
    },
1339
    #endif /* HAVE_ECC_SECPR3 */
1340
#endif /* ECC239 */
1341
#ifdef ECC256
1342
    #ifndef NO_ECC_SECP
1343
    {
1344
        32,                                                                 /* size/bytes */
1345
        ECC_SECP256R1,                                                      /* ID         */
1346
        "SECP256R1",                                                        /* curve name */
1347
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1348
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1349
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1350
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1351
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1352
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1353
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1354
        ecc_oid_secp256r1_sz,
1355
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1356
        1,                                                                  /* cofactor   */
1357
    },
1358
    #endif /* !NO_ECC_SECP */
1359
    #ifdef HAVE_ECC_KOBLITZ
1360
    {
1361
        32,                                                                 /* size/bytes */
1362
        ECC_SECP256K1,                                                      /* ID         */
1363
        "SECP256K1",                                                        /* curve name */
1364
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1365
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1366
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1367
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1368
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1369
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1370
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1371
        ecc_oid_secp256k1_sz,
1372
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1373
        1,                                                                  /* cofactor   */
1374
    },
1375
    #endif /* HAVE_ECC_KOBLITZ */
1376
    #ifdef HAVE_ECC_BRAINPOOL
1377
    {
1378
        32,                                                                 /* size/bytes */
1379
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1380
        "BRAINPOOLP256R1",                                                  /* curve name */
1381
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1382
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1383
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1384
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1385
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1386
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1387
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1388
        ecc_oid_brainpoolp256r1_sz,
1389
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1390
        1,                                                                  /* cofactor   */
1391
    },
1392
    #endif /* HAVE_ECC_BRAINPOOL */
1393
#endif /* ECC256 */
1394
    #if defined(WOLFSSL_SM2)
1395
    {
1396
        32,                                                     /* size/bytes */
1397
        ECC_SM2P256V1,                                          /* ID         */
1398
        "SM2P256V1",                                            /* curve name */
1399
1400
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1401
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1402
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1403
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1404
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1405
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1406
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1407
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1408
        ecc_oid_sm2p256v1_sz,
1409
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1410
        1,                                                      /* cofactor   */
1411
    },
1412
    #endif /* WOLFSSL_SM2 */
1413
#ifdef ECC320
1414
    #ifdef HAVE_ECC_BRAINPOOL
1415
    {
1416
        40,                                                                                 /* size/bytes */
1417
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1418
        "BRAINPOOLP320R1",                                                                  /* curve name */
1419
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1420
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1421
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1422
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1423
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1424
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1425
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1426
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1427
        1,                                                                                  /* cofactor   */
1428
    },
1429
    #endif /* HAVE_ECC_BRAINPOOL */
1430
#endif /* ECC320 */
1431
#ifdef ECC384
1432
    #ifndef NO_ECC_SECP
1433
    {
1434
        48,                                                                                                 /* size/bytes */
1435
        ECC_SECP384R1,                                                                                      /* ID         */
1436
        "SECP384R1",                                                                                        /* curve name */
1437
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1438
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1439
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1440
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1441
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1442
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1443
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1444
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1445
        1,                                                                                                  /* cofactor   */
1446
    },
1447
    #endif /* !NO_ECC_SECP */
1448
    #ifdef HAVE_ECC_BRAINPOOL
1449
    {
1450
        48,                                                                                                 /* size/bytes */
1451
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1452
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1453
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1454
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1455
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1456
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1457
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1458
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1459
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1460
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1461
        1,                                                                                                  /* cofactor   */
1462
    },
1463
    #endif /* HAVE_ECC_BRAINPOOL */
1464
#endif /* ECC384 */
1465
#ifdef ECC512
1466
    #ifdef HAVE_ECC_BRAINPOOL
1467
    {
1468
        64,                                                                                                                                 /* size/bytes */
1469
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1470
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1471
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1472
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1473
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1474
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1475
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1476
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1477
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1478
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1479
        1,                                                                                                                                  /* cofactor   */
1480
    },
1481
    #endif /* HAVE_ECC_BRAINPOOL */
1482
#endif /* ECC512 */
1483
#ifdef ECC521
1484
    #ifndef NO_ECC_SECP
1485
    {
1486
        66,                                                                                                                                    /* size/bytes */
1487
        ECC_SECP521R1,                                                                                                                         /* ID         */
1488
        "SECP521R1",                                                                                                                           /* curve name */
1489
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1490
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1491
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1492
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1493
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1494
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1495
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1496
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1497
        1,                                                                                                                                     /* cofactor   */
1498
    },
1499
    #endif /* !NO_ECC_SECP */
1500
#endif /* ECC521 */
1501
#ifdef WOLFCRYPT_HAVE_SAKKE
1502
    {
1503
        128,
1504
        ECC_SAKKE_1,
1505
        "SAKKE1",
1506
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1507
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1508
        "0",
1509
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1510
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1511
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1512
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1513
            NULL, 0,
1514
        #else
1515
            {0}, 0,
1516
        #endif
1517
        0,
1518
        4,
1519
    },
1520
#endif
1521
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1522
    /* place holder for custom curve index for cache */
1523
    {
1524
        1, /* non-zero */
1525
        ECC_CURVE_CUSTOM,
1526
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1527
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1528
        #else
1529
            {0},{0},{0},{0},{0},{0},{0},{0},
1530
        #endif
1531
        0, 0, 0
1532
    },
1533
#endif
1534
    {
1535
        0,
1536
        ECC_CURVE_INVALID,
1537
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1538
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1539
        #else
1540
            {0},{0},{0},{0},{0},{0},{0},{0},
1541
        #endif
1542
        0, 0, 0
1543
    }
1544
};
1545
1.66k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1546
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1547
static
1548
#endif
1549
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1550
1551
0
const ecc_set_type *wc_ecc_get_sets(void) {
1552
0
    return ecc_sets;
1553
0
}
1554
0
size_t wc_ecc_get_sets_count(void) {
1555
0
    return ecc_sets_count;
1556
0
}
1557
1558
#ifdef HAVE_OID_ENCODING
1559
    /* encoded OID cache */
1560
    typedef struct {
1561
        word32 oidSz;
1562
        byte oid[ECC_MAX_OID_LEN];
1563
    } oid_cache_t;
1564
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1565
1566
    static wolfSSL_Mutex ecc_oid_cache_lock
1567
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1568
#ifndef WOLFSSL_MUTEX_INITIALIZER
1569
    static wc_MutexOnceFlag eccOidLockInit = WOLFSSL_ATOMIC_INITIALIZER(0);
1570
#endif
1571
#endif /* HAVE_OID_ENCODING */
1572
1573
/* Forward declarations */
1574
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1575
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1576
#endif
1577
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1578
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1579
    mp_int* prime, mp_int* order);
1580
#endif
1581
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1582
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1583
    !defined(WOLFSSL_KCAPI_ECC)
1584
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1585
#endif
1586
#if defined(HAVE_ECC_DHE) && !defined(WOLFSSL_ATECC508A) && \
1587
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
1588
    !defined(WOLFSSL_KCAPI_ECC) && \
1589
    !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
1590
static int ecc_shared_secret_point(ecc_key* private_key, ecc_point* point,
1591
    byte* out, word32* outlen, int checkPoint);
1592
#endif
1593
1594
1595
#ifdef HAVE_COMP_KEY
1596
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1597
    !defined(WOLFSSL_NO_ECC_SW)
1598
1599
#ifndef WOLFSSL_SP_MATH
1600
#if !defined(SQRTMOD_USE_MOD_EXP)
1601
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1602
#endif
1603
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1604
#endif
1605
#endif
1606
#endif
1607
1608
1609
/* Curve Specs */
1610
typedef struct ecc_curve_spec {
1611
    const ecc_set_type* dp;
1612
1613
    mp_int* prime;
1614
    mp_int* Af;
1615
    mp_int* Bf;
1616
    mp_int* order;
1617
    mp_int* Gx;
1618
    mp_int* Gy;
1619
1620
#ifdef ECC_CACHE_CURVE
1621
    mp_int prime_lcl;
1622
    mp_int Af_lcl;
1623
    mp_int Bf_lcl;
1624
    mp_int order_lcl;
1625
    mp_int Gx_lcl;
1626
    mp_int Gy_lcl;
1627
#else
1628
#ifdef ECC_SPEC_INTS_SIZED
1629
    unsigned char* spec_ints;
1630
#else
1631
    mp_int* spec_ints;
1632
#endif
1633
    word32 spec_count;
1634
    word32 spec_use;
1635
#endif
1636
1637
    byte load_mask;
1638
} ecc_curve_spec;
1639
1640
    #define ECC_CURVE_FIELD_NONE    0x00
1641
4.15k
    #define ECC_CURVE_FIELD_PRIME   0x01
1642
4.15k
    #define ECC_CURVE_FIELD_AF      0x02
1643
4.15k
    #define ECC_CURVE_FIELD_BF      0x04
1644
1.66k
    #define ECC_CURVE_FIELD_ORDER   0x08
1645
1.66k
    #define ECC_CURVE_FIELD_GX      0x10
1646
1.66k
    #define ECC_CURVE_FIELD_GY      0x20
1647
0
    #define ECC_CURVE_FIELD_ALL     0x3F
1648
    #define ECC_CURVE_FIELD_COUNT   6
1649
1650
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1651
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1652
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1653
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1654
};
1655
1656
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1657
{
1658
    word32 up, down;
1659
    up = 0;
1660
    down = len - 1;
1661
    while (up < len)
1662
        outbuf[up++] = inbuf[down--];
1663
}
1664
1665
static int xil_mpi_import(mp_int *mpi,
1666
                          const byte *inbuf,
1667
                          word32 len,
1668
                          void* heap)
1669
{
1670
    int err;
1671
#ifdef WOLFSSL_SMALL_STACK
1672
    byte* buf = NULL;
1673
#else
1674
    byte buf[MAX_ECC_BYTES];
1675
1676
    if (len > MAX_ECC_BYTES)
1677
        return BUFFER_E;
1678
#endif
1679
1680
    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
1681
        return MEMORY_E);
1682
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1683
    /* Register the stack buffer before it is filled so any future exit before
1684
     * the ForceZero is checked. XMEMSET makes it defined for registration. */
1685
    XMEMSET(buf, 0, len);
1686
    wc_MemZero_Add("xil_mpi_import buf", buf, len);
1687
#endif
1688
    buf_reverse(buf, inbuf, len);
1689
1690
    err = mp_read_unsigned_bin(mpi, buf, len);
1691
    ForceZero(buf, len);
1692
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1693
    wc_MemZero_Check(buf, len);
1694
#endif
1695
    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1696
    return err;
1697
}
1698
#endif
1699
1700
#ifdef ECC_CACHE_CURVE
1701
    /* cache (mp_int) of the curve parameters */
1702
    #ifdef WOLFSSL_NO_MALLOC
1703
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1704
    #else
1705
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1706
    #endif
1707
    #ifndef SINGLE_THREADED
1708
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1709
    #endif
1710
1711
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1712
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1713
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1714
#elif defined(WOLFSSL_SMALL_STACK)
1715
#ifdef ECC_SPEC_INTS_SIZED
1716
    #define DECLARE_CURVE_SPECS(intcount)                               \
1717
        unsigned char* spec_ints = NULL;                                \
1718
        ecc_curve_spec curve_lcl;                                       \
1719
        ecc_curve_spec* curve = &curve_lcl;                             \
1720
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1721
        curve->spec_count = intcount
1722
1723
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1724
    do {                                                                \
1725
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(              \
1726
            ECC_SPEC_INT_CNT) * (intcount), NULL,                       \
1727
            DYNAMIC_TYPE_ECC);                                          \
1728
        if (spec_ints == NULL)                                          \
1729
            (err) = MEMORY_E;                                           \
1730
        else {                                                          \
1731
            curve->spec_ints = spec_ints;                               \
1732
            (err) = MP_OKAY;                                            \
1733
        }                                                               \
1734
    } while (0)
1735
#else
1736
    #define DECLARE_CURVE_SPECS(intcount)                               \
1737
        mp_int* spec_ints = NULL;                                       \
1738
        ecc_curve_spec curve_lcl;                                       \
1739
        ecc_curve_spec* curve = &curve_lcl;                             \
1740
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1741
        curve->spec_count = intcount
1742
1743
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1744
    do {                                                                \
1745
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1746
                            DYNAMIC_TYPE_ECC);                          \
1747
        if (spec_ints == NULL)                                          \
1748
            (err) = MEMORY_E;                                           \
1749
        else {                                                          \
1750
            curve->spec_ints = spec_ints;                               \
1751
            (err) = MP_OKAY;                                            \
1752
        }                                                               \
1753
    } while (0)
1754
#endif
1755
    #define FREE_CURVE_SPECS()                                          \
1756
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1757
#else
1758
#ifdef ECC_SPEC_INTS_SIZED
1759
    #define DECLARE_CURVE_SPECS(intcount)                               \
1760
830
        sp_int_digit spec_ints[MP_INT_SIZEOF_DIGITS(ECC_SPEC_INT_CNT) * \
1761
830
            (intcount)];                                                \
1762
830
        ecc_curve_spec curve_lcl;                                       \
1763
830
        ecc_curve_spec* curve = &curve_lcl;                             \
1764
830
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1765
830
        curve->spec_ints = (unsigned char*)spec_ints;                   \
1766
830
        curve->spec_count = (intcount)
1767
#else
1768
    #define DECLARE_CURVE_SPECS(intcount)                               \
1769
        mp_int spec_ints[(intcount)];                                   \
1770
        ecc_curve_spec curve_lcl;                                       \
1771
        ecc_curve_spec* curve = &curve_lcl;                             \
1772
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1773
        curve->spec_ints = spec_ints;                                   \
1774
        curve->spec_count = (intcount)
1775
#endif
1776
830
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1777
830
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1778
#endif /* ECC_CACHE_CURVE */
1779
1780
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1781
    byte mask)
1782
2.49k
{
1783
2.49k
    if (item) {
1784
    #ifdef HAVE_WOLF_BIGINT
1785
        wc_bigint_free(&item->raw);
1786
    #endif
1787
2.49k
        mp_clear(item);
1788
2.49k
    }
1789
2.49k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1790
2.49k
}
1791
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1792
830
{
1793
830
    if (curve == NULL) {
1794
0
        return;
1795
0
    }
1796
1797
830
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1798
830
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1799
830
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1800
830
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1801
830
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1802
830
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1803
830
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1804
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1805
830
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1806
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1807
830
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1808
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1809
1810
830
    curve->load_mask = 0;
1811
830
}
1812
1813
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1814
830
{
1815
830
    if (curve) {
1816
    #ifdef ECC_CACHE_CURVE
1817
        #ifdef WOLFSSL_CUSTOM_CURVES
1818
        /* only free custom curves (rest are globally cached) */
1819
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1820
            wc_ecc_curve_cache_free_spec(curve);
1821
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1822
        }
1823
        #endif
1824
    #else
1825
830
        wc_ecc_curve_cache_free_spec(curve);
1826
830
    #endif
1827
830
    }
1828
830
}
1829
1830
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1831
    mp_int** dst, byte mask)
1832
2.49k
{
1833
2.49k
    int err;
1834
1835
2.49k
#ifndef ECC_CACHE_CURVE
1836
    /* get mp_int from temp */
1837
2.49k
    if (curve->spec_use >= curve->spec_count) {
1838
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1839
0
        return ECC_BAD_ARG_E;
1840
0
    }
1841
2.49k
#ifdef ECC_SPEC_INTS_SIZED
1842
2.49k
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(ECC_SPEC_INT_CNT) *
1843
2.49k
        curve->spec_use++);
1844
#else
1845
    *dst = &curve->spec_ints[curve->spec_use++];
1846
#endif
1847
2.49k
#endif
1848
1849
2.49k
#ifdef ECC_SPEC_INTS_SIZED
1850
2.49k
    err = mp_init_size(*dst, ECC_SPEC_INT_CNT);
1851
#else
1852
    err = mp_init(*dst);
1853
#endif
1854
2.49k
    if (err == MP_OKAY) {
1855
2.49k
        curve->load_mask |= mask;
1856
1857
2.49k
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1858
1859
    #ifdef HAVE_WOLF_BIGINT
1860
        if (err == MP_OKAY)
1861
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1862
    #endif
1863
2.49k
    }
1864
2.49k
    return err;
1865
2.49k
}
1866
1867
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1868
    byte load_mask)
1869
830
{
1870
830
    int ret = 0;
1871
830
    ecc_curve_spec* curve;
1872
830
    byte load_items = 0; /* mask of items to load */
1873
#ifdef ECC_CACHE_CURVE
1874
    int x;
1875
#endif
1876
1877
830
    if (dp == NULL || pCurve == NULL)
1878
0
        return BAD_FUNC_ARG;
1879
1880
#ifdef ECC_CACHE_CURVE
1881
    x = wc_ecc_get_curve_idx(dp->id);
1882
    if (x == ECC_CURVE_INVALID)
1883
        return ECC_BAD_ARG_E;
1884
1885
#if !defined(SINGLE_THREADED)
1886
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1887
    if (ret != 0) {
1888
        return ret;
1889
    }
1890
#endif
1891
1892
#ifdef WOLFSSL_NO_MALLOC
1893
    curve = &ecc_curve_spec_cache[x];
1894
#else
1895
    /* make sure cache has been allocated */
1896
    if (ecc_curve_spec_cache[x] == NULL
1897
    #ifdef WOLFSSL_CUSTOM_CURVES
1898
        || dp->id == ECC_CURVE_CUSTOM
1899
    #endif
1900
    ) {
1901
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1902
        if (curve == NULL) {
1903
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1904
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1905
        #endif
1906
            return MEMORY_E;
1907
        }
1908
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1909
1910
        /* set curve pointer to cache */
1911
    #ifdef WOLFSSL_CUSTOM_CURVES
1912
        if (dp->id != ECC_CURVE_CUSTOM)
1913
    #endif
1914
        {
1915
            ecc_curve_spec_cache[x] = curve;
1916
        }
1917
    }
1918
    else {
1919
        curve = ecc_curve_spec_cache[x];
1920
    }
1921
#endif /* WOLFSSL_NO_MALLOC */
1922
1923
    /* return new or cached curve */
1924
    *pCurve = curve;
1925
#else
1926
830
    curve = *pCurve;
1927
830
#endif /* ECC_CACHE_CURVE */
1928
1929
    /* make sure the curve is initialized */
1930
830
    if (curve->dp != dp) {
1931
830
        curve->load_mask = 0;
1932
1933
    #ifdef ECC_CACHE_CURVE
1934
        curve->prime = &curve->prime_lcl;
1935
        curve->Af = &curve->Af_lcl;
1936
        curve->Bf = &curve->Bf_lcl;
1937
        curve->order = &curve->order_lcl;
1938
        curve->Gx = &curve->Gx_lcl;
1939
        curve->Gy = &curve->Gy_lcl;
1940
    #endif
1941
830
    }
1942
830
    curve->dp = dp; /* set dp info */
1943
1944
    /* determine items to load */
1945
830
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1946
830
    curve->load_mask |= load_items;
1947
1948
    /* load items */
1949
830
    if (load_items & ECC_CURVE_FIELD_PRIME)
1950
830
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1951
830
            ECC_CURVE_FIELD_PRIME);
1952
830
    if (load_items & ECC_CURVE_FIELD_AF)
1953
830
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1954
830
            ECC_CURVE_FIELD_AF);
1955
830
    if (load_items & ECC_CURVE_FIELD_BF)
1956
830
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1957
830
            ECC_CURVE_FIELD_BF);
1958
830
    if (load_items & ECC_CURVE_FIELD_ORDER)
1959
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1960
0
            ECC_CURVE_FIELD_ORDER);
1961
830
    if (load_items & ECC_CURVE_FIELD_GX)
1962
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1963
0
            ECC_CURVE_FIELD_GX);
1964
830
    if (load_items & ECC_CURVE_FIELD_GY)
1965
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1966
0
            ECC_CURVE_FIELD_GY);
1967
1968
    /* check for error */
1969
830
    if (ret != 0) {
1970
0
        wc_ecc_curve_free(curve);
1971
0
        ret = MP_READ_E;
1972
0
    }
1973
1974
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1975
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1976
#endif
1977
1978
830
    return ret;
1979
830
}
1980
1981
#ifdef ECC_CACHE_CURVE
1982
int wc_ecc_curve_cache_init(void)
1983
{
1984
    int ret = 0;
1985
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1986
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1987
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1988
#endif
1989
    return ret;
1990
}
1991
1992
void wc_ecc_curve_cache_free(void)
1993
{
1994
    int x;
1995
    /* free all ECC curve caches */
1996
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1997
    #ifdef WOLFSSL_NO_MALLOC
1998
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1999
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
2000
    #else
2001
        if (ecc_curve_spec_cache[x]) {
2002
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
2003
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
2004
            ecc_curve_spec_cache[x] = NULL;
2005
        }
2006
    #endif /* WOLFSSL_NO_MALLOC */
2007
    }
2008
2009
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
2010
        !defined(WOLFSSL_MUTEX_INITIALIZER)
2011
    wc_FreeMutex(&ecc_curve_cache_mutex);
2012
#endif
2013
}
2014
#endif /* ECC_CACHE_CURVE */
2015
2016
2017
/* Retrieve the curve name for the ECC curve id.
2018
 *
2019
 * curve_id  The id of the curve.
2020
 * returns the name stored from the curve if available, otherwise NULL.
2021
 */
2022
const char* wc_ecc_get_name(int curve_id)
2023
0
{
2024
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
2025
0
    if (curve_idx == ECC_CURVE_INVALID)
2026
0
        return NULL;
2027
0
    return ecc_sets[curve_idx].name;
2028
0
}
2029
2030
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
2031
849
{
2032
849
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
2033
0
        return BAD_FUNC_ARG;
2034
0
    }
2035
2036
849
    if (keysize > ECC_MAXSIZE) {
2037
2
        return ECC_BAD_ARG_E;
2038
2
    }
2039
2040
#ifdef WOLFSSL_SILABS_SE_TYPES
2041
    /* Every import and keygen path resolves the curve here, so this is where
2042
     * a key stops representing whatever wc_SilabsSe_EccUse*Key() bound to it.
2043
     * Leaving the binding set would keep the SE on the old resident key. */
2044
    ForceZero(key->key_raw, sizeof(key->key_raw));
2045
    key->silabsKeySet = 0;
2046
#endif
2047
2048
    /* handle custom case */
2049
847
    if (key->idx != ECC_CUSTOM_IDX) {
2050
847
        int x;
2051
2052
        /* default values */
2053
847
        key->idx = 0;
2054
847
        key->dp = NULL;
2055
2056
        /* find ecc_set based on curve_id or key size */
2057
2.85k
        for (x = 0; ecc_sets[x].size != 0; x++) {
2058
2.85k
            if (curve_id > ECC_CURVE_DEF) {
2059
2.85k
                if (curve_id == ecc_sets[x].id)
2060
847
                  break;
2061
2.85k
            }
2062
0
            else if (keysize <= ecc_sets[x].size) {
2063
0
                break;
2064
0
            }
2065
2.85k
        }
2066
847
        if (ecc_sets[x].size == 0) {
2067
0
            WOLFSSL_MSG("ECC Curve not found");
2068
0
            return ECC_CURVE_OID_E;
2069
0
        }
2070
2071
847
        key->idx = x;
2072
847
        key->dp  = &ecc_sets[x];
2073
847
    }
2074
2075
847
    return 0;
2076
847
}
2077
2078
2079
#ifdef ALT_ECC_SIZE
2080
static void alt_fp_init(mp_int* a)
2081
{
2082
    a->size = FP_SIZE_ECC;
2083
    mp_zero(a);
2084
}
2085
#endif /* ALT_ECC_SIZE */
2086
2087
2088
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
2089
    !defined(WOLFSSL_NO_ECC_SW) && \
2090
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
2091
      defined(WOLFSSL_IMXRT1170_CAAM))
2092
2093
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
2094
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2095
                                     mp_int* modulus, mp_digit mp);
2096
2097
/**
2098
   Add two ECC points
2099
   P        The point to add
2100
   Q        The point to add
2101
   R        [out] The sum; the point at infinity has a z of zero
2102
   a        ECC curve parameter a
2103
   modulus  The modulus of the field the ECC curve is in
2104
   mp       The "b" value from montgomery_setup()
2105
   return   MP_OKAY on success
2106
*/
2107
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2108
                                     mp_int* a, mp_int* modulus, mp_digit mp)
2109
0
{
2110
0
#if !defined(WOLFSSL_SP_MATH)
2111
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2112
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2113
#ifdef ALT_ECC_SIZE
2114
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2115
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2116
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2117
#endif
2118
0
   mp_int  *x, *y, *z;
2119
0
   int     err;
2120
2121
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2122
0
       return WC_KEY_SIZE_E;
2123
0
   }
2124
2125
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
2126
0
   if (Q == R) {
2127
0
      ecc_point* tPt  = P;
2128
0
      P = Q;
2129
0
      Q = tPt;
2130
0
   }
2131
2132
#ifdef WOLFSSL_SMALL_STACK
2133
#ifdef WOLFSSL_SMALL_STACK_CACHE
2134
   if (R->key != NULL) {
2135
       t1 = R->key->t1;
2136
       t2 = R->key->t2;
2137
#ifdef ALT_ECC_SIZE
2138
       rx = R->key->x;
2139
       ry = R->key->y;
2140
       rz = R->key->z;
2141
#endif
2142
   }
2143
   else
2144
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2145
#endif /* WOLFSSL_SMALL_STACK */
2146
0
   {
2147
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2148
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2149
   #ifdef MP_INT_SIZE_CHECK_NULL
2150
      if (t1 == NULL || t2 == NULL) {
2151
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2152
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2153
         return MEMORY_E;
2154
      }
2155
   #endif
2156
#ifdef ALT_ECC_SIZE
2157
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2158
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2159
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2160
   #ifdef MP_INT_SIZE_CHECK_NULL
2161
      if (rx == NULL || ry == NULL || rz == NULL) {
2162
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2163
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2164
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2165
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2166
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2167
         return MEMORY_E;
2168
      }
2169
   #endif
2170
#endif
2171
0
   }
2172
2173
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2174
0
   if (err == MP_OKAY) {
2175
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2176
0
   }
2177
0
   if (err != MP_OKAY) {
2178
#ifdef WOLFSSL_SMALL_STACK
2179
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2180
      if (R->key == NULL)
2181
   #endif
2182
#endif
2183
0
      {
2184
      #ifdef ALT_ECC_SIZE
2185
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2186
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2187
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2188
      #endif
2189
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2190
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2191
0
      }
2192
0
      return err;
2193
0
   }
2194
2195
   /* should we dbl instead? */
2196
0
   if (err == MP_OKAY) {
2197
0
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2198
0
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2199
0
           (mp_cmp(P->y, Q->y) == MP_EQ)) {
2200
0
          mp_clear(t1);
2201
0
          mp_clear(t2);
2202
   #ifdef WOLFSSL_SMALL_STACK
2203
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2204
         if (R->key == NULL)
2205
      #endif
2206
   #endif
2207
0
         {
2208
         #ifdef ALT_ECC_SIZE
2209
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2210
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2211
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2212
         #endif
2213
0
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2214
0
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2215
0
         }
2216
0
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2217
0
      }
2218
0
   }
2219
2220
0
   if (err != MP_OKAY) {
2221
0
      goto done;
2222
0
   }
2223
2224
/* If use ALT_ECC_SIZE we need to use local stack variable since
2225
   ecc_point x,y,z is reduced size */
2226
#ifdef ALT_ECC_SIZE
2227
   /* Use local stack variable */
2228
   x = rx;
2229
   y = ry;
2230
   z = rz;
2231
2232
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2233
   if (err == MP_OKAY) {
2234
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2235
   }
2236
   if (err == MP_OKAY) {
2237
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2238
   }
2239
   if (err != MP_OKAY) {
2240
      goto done;
2241
   }
2242
#else
2243
   /* Use destination directly */
2244
0
   x = R->x;
2245
0
   y = R->y;
2246
0
   z = R->z;
2247
0
#endif
2248
2249
0
   if (err == MP_OKAY)
2250
0
       err = mp_copy(P->x, x);
2251
0
   if (err == MP_OKAY)
2252
0
       err = mp_copy(P->y, y);
2253
0
   if (err == MP_OKAY)
2254
0
       err = mp_copy(P->z, z);
2255
2256
   /* if Z is one then these are no-operations */
2257
0
   if (err == MP_OKAY) {
2258
0
       if (!mp_iszero(Q->z)) {
2259
           /* T1 = Z' * Z' */
2260
0
           err = mp_sqr(Q->z, t1);
2261
0
           if (err == MP_OKAY)
2262
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2263
2264
           /* X = X * T1 */
2265
0
           if (err == MP_OKAY)
2266
0
               err = mp_mul(t1, x, x);
2267
0
           if (err == MP_OKAY)
2268
0
               err = mp_montgomery_reduce(x, modulus, mp);
2269
2270
           /* T1 = Z' * T1 */
2271
0
           if (err == MP_OKAY)
2272
0
               err = mp_mul(Q->z, t1, t1);
2273
0
           if (err == MP_OKAY)
2274
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2275
2276
           /* Y = Y * T1 */
2277
0
           if (err == MP_OKAY)
2278
0
               err = mp_mul(t1, y, y);
2279
0
           if (err == MP_OKAY)
2280
0
               err = mp_montgomery_reduce(y, modulus, mp);
2281
0
       }
2282
0
   }
2283
2284
   /* T1 = Z*Z */
2285
0
   if (err == MP_OKAY)
2286
0
       err = mp_sqr(z, t1);
2287
0
   if (err == MP_OKAY)
2288
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2289
2290
   /* T2 = X' * T1 */
2291
0
   if (err == MP_OKAY)
2292
0
       err = mp_mul(Q->x, t1, t2);
2293
0
   if (err == MP_OKAY)
2294
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2295
2296
   /* T1 = Z * T1 */
2297
0
   if (err == MP_OKAY)
2298
0
       err = mp_mul(z, t1, t1);
2299
0
   if (err == MP_OKAY)
2300
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2301
2302
   /* T1 = Y' * T1 */
2303
0
   if (err == MP_OKAY)
2304
0
       err = mp_mul(Q->y, t1, t1);
2305
0
   if (err == MP_OKAY)
2306
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2307
2308
   /* Y = Y - T1 */
2309
0
   if (err == MP_OKAY)
2310
0
       err = mp_submod_ct(y, t1, modulus, y);
2311
   /* T1 = 2T1 */
2312
0
   if (err == MP_OKAY)
2313
0
       err = mp_addmod_ct(t1, t1, modulus, t1);
2314
   /* T1 = Y + T1 */
2315
0
   if (err == MP_OKAY)
2316
0
       err = mp_addmod_ct(t1, y, modulus, t1);
2317
   /* X = X - T2 */
2318
0
   if (err == MP_OKAY)
2319
0
       err = mp_submod_ct(x, t2, modulus, x);
2320
   /* T2 = 2T2 */
2321
0
   if (err == MP_OKAY)
2322
0
       err = mp_addmod_ct(t2, t2, modulus, t2);
2323
   /* T2 = X + T2 */
2324
0
   if (err == MP_OKAY)
2325
0
       err = mp_addmod_ct(t2, x, modulus, t2);
2326
2327
0
   if (err == MP_OKAY) {
2328
0
       if (!mp_iszero(Q->z)) {
2329
           /* Z = Z * Z' */
2330
0
           err = mp_mul(z, Q->z, z);
2331
0
           if (err == MP_OKAY)
2332
0
               err = mp_montgomery_reduce(z, modulus, mp);
2333
0
       }
2334
0
   }
2335
2336
   /* Z = Z * X */
2337
0
   if (err == MP_OKAY)
2338
0
       err = mp_mul(z, x, z);
2339
0
   if (err == MP_OKAY)
2340
0
       err = mp_montgomery_reduce(z, modulus, mp);
2341
2342
   /* T1 = T1 * X  */
2343
0
   if (err == MP_OKAY)
2344
0
       err = mp_mul(t1, x, t1);
2345
0
   if (err == MP_OKAY)
2346
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2347
2348
   /* X = X * X */
2349
0
   if (err == MP_OKAY)
2350
0
       err = mp_sqr(x, x);
2351
0
   if (err == MP_OKAY)
2352
0
       err = mp_montgomery_reduce(x, modulus, mp);
2353
2354
   /* T2 = T2 * x */
2355
0
   if (err == MP_OKAY)
2356
0
       err = mp_mul(t2, x, t2);
2357
0
   if (err == MP_OKAY)
2358
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2359
2360
   /* T1 = T1 * X  */
2361
0
   if (err == MP_OKAY)
2362
0
       err = mp_mul(t1, x, t1);
2363
0
   if (err == MP_OKAY)
2364
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2365
2366
   /* X = Y*Y */
2367
0
   if (err == MP_OKAY)
2368
0
       err = mp_sqr(y, x);
2369
0
   if (err == MP_OKAY)
2370
0
       err = mp_montgomery_reduce(x, modulus, mp);
2371
2372
   /* X = X - T2 */
2373
0
   if (err == MP_OKAY)
2374
0
       err = mp_submod_ct(x, t2, modulus, x);
2375
   /* T2 = T2 - X */
2376
0
   if (err == MP_OKAY)
2377
0
       err = mp_submod_ct(t2, x, modulus, t2);
2378
   /* T2 = T2 - X */
2379
0
   if (err == MP_OKAY)
2380
0
       err = mp_submod_ct(t2, x, modulus, t2);
2381
   /* T2 = T2 * Y */
2382
0
   if (err == MP_OKAY)
2383
0
       err = mp_mul(t2, y, t2);
2384
0
   if (err == MP_OKAY)
2385
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2386
2387
   /* Y = T2 - T1 */
2388
0
   if (err == MP_OKAY)
2389
0
       err = mp_submod_ct(t2, t1, modulus, y);
2390
   /* Y = Y/2 */
2391
0
   if (err == MP_OKAY)
2392
0
       err = mp_div_2_mod_ct(y, modulus, y);
2393
2394
#ifdef ALT_ECC_SIZE
2395
   if (err == MP_OKAY)
2396
       err = mp_copy(x, R->x);
2397
   if (err == MP_OKAY)
2398
       err = mp_copy(y, R->y);
2399
   if (err == MP_OKAY)
2400
       err = mp_copy(z, R->z);
2401
#endif
2402
2403
0
done:
2404
2405
   /* clean up */
2406
0
   mp_clear(t1);
2407
0
   mp_clear(t2);
2408
#ifdef WOLFSSL_SMALL_STACK
2409
#ifdef WOLFSSL_SMALL_STACK_CACHE
2410
   if (R->key == NULL)
2411
#endif
2412
#endif
2413
0
   {
2414
   #ifdef ALT_ECC_SIZE
2415
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2416
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2417
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2418
   #endif
2419
0
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2420
0
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2421
0
   }
2422
2423
0
   return err;
2424
#else
2425
    int modBits = mp_count_bits(modulus);
2426
2427
    (void)a;
2428
    (void)mp;
2429
2430
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2431
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2432
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2433
                                            R->x, R->y, R->z);
2434
    }
2435
#endif
2436
#ifndef WOLFSSL_SP_NO_256
2437
    if (modBits == 256) {
2438
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2439
                                         R->x, R->y, R->z);
2440
    }
2441
#endif
2442
#ifdef WOLFSSL_SP_384
2443
    if (modBits == 384) {
2444
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2445
                                         R->x, R->y, R->z);
2446
    }
2447
#endif
2448
#ifdef WOLFSSL_SP_521
2449
    if (modBits == 521) {
2450
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2451
                                         R->x, R->y, R->z);
2452
    }
2453
#endif
2454
    return ECC_BAD_ARG_E;
2455
#endif
2456
0
}
2457
2458
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2459
                             mp_int* a, mp_int* modulus, mp_digit mp)
2460
0
{
2461
0
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2462
0
        return ECC_BAD_ARG_E;
2463
0
    }
2464
2465
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2466
0
        mp_cmp(P->y, modulus) != MP_LT ||
2467
0
        mp_cmp(P->z, modulus) != MP_LT ||
2468
0
        mp_cmp(Q->x, modulus) != MP_LT ||
2469
0
        mp_cmp(Q->y, modulus) != MP_LT ||
2470
0
        mp_cmp(Q->z, modulus) != MP_LT) {
2471
0
        return ECC_OUT_OF_RANGE_E;
2472
0
    }
2473
2474
0
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2475
0
}
2476
2477
/* ### Point doubling in Jacobian coordinate system ###
2478
 *
2479
 * let us have a curve:                 y^2 = x^3 + a*x + b
2480
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2481
 *
2482
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2483
 * Xr = M^2 - 2*S
2484
 * Yr = M * (S - Xr) - 8*T
2485
 * Zr = 2 * Yp * Zp
2486
 *
2487
 * M = 3 * Xp^2 + a*Zp^4
2488
 * T = Yp^4
2489
 * S = 4 * Xp * Yp^2
2490
 *
2491
 * SPECIAL CASE: when a == 3 we can compute M as
2492
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2493
 */
2494
2495
/**
2496
   Double an ECC point
2497
   P   The point to double
2498
   R   [out] The destination of the double
2499
   a   ECC curve parameter a
2500
   modulus  The modulus of the field the ECC curve is in
2501
   mp       The "b" value from montgomery_setup()
2502
   return   MP_OKAY on success
2503
*/
2504
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2505
                                     mp_int* modulus, mp_digit mp)
2506
0
{
2507
0
#if !defined(WOLFSSL_SP_MATH)
2508
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2509
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2510
#ifdef ALT_ECC_SIZE
2511
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2512
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2513
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2514
#endif
2515
0
   mp_int *x, *y, *z;
2516
0
   int    err;
2517
2518
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2519
0
       return WC_KEY_SIZE_E;
2520
0
   }
2521
2522
#ifdef WOLFSSL_SMALL_STACK
2523
#ifdef WOLFSSL_SMALL_STACK_CACHE
2524
   if (R->key != NULL) {
2525
       t1 = R->key->t1;
2526
       t2 = R->key->t2;
2527
   #ifdef ALT_ECC_SIZE
2528
       rx = R->key->x;
2529
       ry = R->key->y;
2530
       rz = R->key->z;
2531
   #endif
2532
   }
2533
   else
2534
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2535
#endif
2536
0
   {
2537
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2538
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2539
   #ifdef MP_INT_SIZE_CHECK_NULL
2540
      if (t1 == NULL || t2 == NULL) {
2541
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2542
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2543
         return MEMORY_E;
2544
      }
2545
   #endif
2546
   #ifdef ALT_ECC_SIZE
2547
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2548
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2549
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2550
   #ifdef MP_INT_SIZE_CHECK_NULL
2551
      if (rx == NULL || ry == NULL || rz == NULL) {
2552
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2553
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2554
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2555
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2556
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2557
          return MEMORY_E;
2558
      }
2559
   #endif
2560
   #endif
2561
0
   }
2562
2563
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2564
0
   if (err == MP_OKAY) {
2565
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2566
0
   }
2567
0
   if (err != MP_OKAY) {
2568
#ifdef WOLFSSL_SMALL_STACK
2569
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2570
      if (R->key == NULL)
2571
   #endif
2572
#endif
2573
0
      {
2574
      #ifdef ALT_ECC_SIZE
2575
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2576
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2577
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2578
      #endif
2579
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2580
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2581
0
      }
2582
0
      return err;
2583
0
   }
2584
2585
/* If use ALT_ECC_SIZE we need to use local stack variable since
2586
   ecc_point x,y,z is reduced size */
2587
#ifdef ALT_ECC_SIZE
2588
   /* Use local stack variable */
2589
   x = rx;
2590
   y = ry;
2591
   z = rz;
2592
2593
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2594
   if (err == MP_OKAY) {
2595
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2596
   }
2597
   if (err == MP_OKAY) {
2598
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2599
   }
2600
   if (err != MP_OKAY) {
2601
#ifdef WOLFSSL_SMALL_STACK
2602
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2603
      if (R->key == NULL)
2604
   #endif
2605
#endif
2606
      {
2607
      #ifdef ALT_ECC_SIZE
2608
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2609
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2610
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2611
      #endif
2612
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2613
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2614
      }
2615
      return err;
2616
   }
2617
#else
2618
   /* Use destination directly */
2619
0
   x = R->x;
2620
0
   y = R->y;
2621
0
   z = R->z;
2622
0
#endif
2623
2624
0
   if (err == MP_OKAY)
2625
0
       err = mp_copy(P->x, x);
2626
0
   if (err == MP_OKAY)
2627
0
       err = mp_copy(P->y, y);
2628
0
   if (err == MP_OKAY)
2629
0
       err = mp_copy(P->z, z);
2630
2631
   /* T1 = Z * Z */
2632
0
   if (err == MP_OKAY)
2633
0
       err = mp_sqr(z, t1);
2634
0
   if (err == MP_OKAY)
2635
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2636
2637
   /* Z = Y * Z */
2638
0
   if (err == MP_OKAY)
2639
0
       err = mp_mul(z, y, z);
2640
0
   if (err == MP_OKAY)
2641
0
       err = mp_montgomery_reduce(z, modulus, mp);
2642
2643
   /* Z = 2Z */
2644
0
   if (err == MP_OKAY)
2645
0
       err = mp_addmod_ct(z, z, modulus, z);
2646
2647
   /* Determine if curve "a" should be used in calc */
2648
#ifdef WOLFSSL_CUSTOM_CURVES
2649
   if (err == MP_OKAY) {
2650
      /* Use a and prime to determine if a == 3 */
2651
      err = mp_submod(modulus, a, modulus, t2);
2652
   }
2653
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2654
      /* T2 = X * X */
2655
      err = mp_sqr(x, t2);
2656
      if (err == MP_OKAY)
2657
          err = mp_montgomery_reduce(t2, modulus, mp);
2658
      /* T1 = T2 + T1 */
2659
      if (err == MP_OKAY)
2660
          err = mp_addmod_ct(t2, t2, modulus, t1);
2661
      /* T1 = T2 + T1 */
2662
      if (err == MP_OKAY)
2663
          err = mp_addmod_ct(t1, t2, modulus, t1);
2664
   }
2665
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2666
      /* use "a" in calc */
2667
2668
      /* T2 = T1 * T1 */
2669
      err = mp_sqr(t1, t2);
2670
      if (err == MP_OKAY)
2671
          err = mp_montgomery_reduce(t2, modulus, mp);
2672
      /* T1 = T2 * a */
2673
      if (err == MP_OKAY)
2674
          err = mp_mulmod(t2, a, modulus, t1);
2675
      /* T2 = X * X */
2676
      if (err == MP_OKAY)
2677
          err = mp_sqr(x, t2);
2678
      if (err == MP_OKAY)
2679
          err = mp_montgomery_reduce(t2, modulus, mp);
2680
      /* T1 = T2 + T1 */
2681
      if (err == MP_OKAY)
2682
          err = mp_addmod_ct(t1, t2, modulus, t1);
2683
      /* T1 = T2 + T1 */
2684
      if (err == MP_OKAY)
2685
          err = mp_addmod_ct(t1, t2, modulus, t1);
2686
      /* T1 = T2 + T1 */
2687
      if (err == MP_OKAY)
2688
          err = mp_addmod_ct(t1, t2, modulus, t1);
2689
   }
2690
   else
2691
#endif /* WOLFSSL_CUSTOM_CURVES */
2692
0
   {
2693
      /* assumes "a" == 3 */
2694
0
      (void)a;
2695
2696
      /* T2 = X - T1 */
2697
0
      if (err == MP_OKAY)
2698
0
          err = mp_submod_ct(x, t1, modulus, t2);
2699
      /* T1 = X + T1 */
2700
0
      if (err == MP_OKAY)
2701
0
          err = mp_addmod_ct(t1, x, modulus, t1);
2702
      /* T2 = T1 * T2 */
2703
0
      if (err == MP_OKAY)
2704
0
          err = mp_mul(t1, t2, t2);
2705
0
      if (err == MP_OKAY)
2706
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2707
2708
      /* T1 = 2T2 */
2709
0
      if (err == MP_OKAY)
2710
0
          err = mp_addmod_ct(t2, t2, modulus, t1);
2711
      /* T1 = T1 + T2 */
2712
0
      if (err == MP_OKAY)
2713
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2714
0
   }
2715
2716
   /* Y = 2Y */
2717
0
   if (err == MP_OKAY)
2718
0
       err = mp_addmod_ct(y, y, modulus, y);
2719
   /* Y = Y * Y */
2720
0
   if (err == MP_OKAY)
2721
0
       err = mp_sqr(y, y);
2722
0
   if (err == MP_OKAY)
2723
0
       err = mp_montgomery_reduce(y, modulus, mp);
2724
2725
   /* T2 = Y * Y */
2726
0
   if (err == MP_OKAY)
2727
0
       err = mp_sqr(y, t2);
2728
0
   if (err == MP_OKAY)
2729
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2730
2731
   /* T2 = T2/2 */
2732
0
   if (err == MP_OKAY)
2733
0
       err = mp_div_2_mod_ct(t2, modulus, t2);
2734
2735
   /* Y = Y * X */
2736
0
   if (err == MP_OKAY)
2737
0
       err = mp_mul(y, x, y);
2738
0
   if (err == MP_OKAY)
2739
0
       err = mp_montgomery_reduce(y, modulus, mp);
2740
2741
   /* X = T1 * T1 */
2742
0
   if (err == MP_OKAY)
2743
0
       err = mp_sqr(t1, x);
2744
0
   if (err == MP_OKAY)
2745
0
       err = mp_montgomery_reduce(x, modulus, mp);
2746
2747
   /* X = X - Y */
2748
0
   if (err == MP_OKAY)
2749
0
       err = mp_submod_ct(x, y, modulus, x);
2750
   /* X = X - Y */
2751
0
   if (err == MP_OKAY)
2752
0
       err = mp_submod_ct(x, y, modulus, x);
2753
2754
   /* Y = Y - X */
2755
0
   if (err == MP_OKAY)
2756
0
       err = mp_submod_ct(y, x, modulus, y);
2757
   /* Y = Y * T1 */
2758
0
   if (err == MP_OKAY)
2759
0
       err = mp_mul(y, t1, y);
2760
0
   if (err == MP_OKAY)
2761
0
       err = mp_montgomery_reduce(y, modulus, mp);
2762
2763
   /* Y = Y - T2 */
2764
0
   if (err == MP_OKAY)
2765
0
       err = mp_submod_ct(y, t2, modulus, y);
2766
2767
#ifdef ALT_ECC_SIZE
2768
   if (err == MP_OKAY)
2769
       err = mp_copy(x, R->x);
2770
   if (err == MP_OKAY)
2771
       err = mp_copy(y, R->y);
2772
   if (err == MP_OKAY)
2773
       err = mp_copy(z, R->z);
2774
#endif
2775
2776
   /* clean up */
2777
0
   mp_clear(t1);
2778
0
   mp_clear(t2);
2779
2780
#ifdef WOLFSSL_SMALL_STACK
2781
#ifdef WOLFSSL_SMALL_STACK_CACHE
2782
   if (R->key == NULL)
2783
#endif
2784
#endif
2785
0
   {
2786
    #ifdef ALT_ECC_SIZE
2787
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2788
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2789
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2790
    #endif
2791
0
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2792
0
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2793
0
    }
2794
2795
0
   return err;
2796
#else
2797
    int modBits = mp_count_bits(modulus);
2798
2799
    (void)a;
2800
    (void)mp;
2801
2802
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2803
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2804
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2805
    }
2806
#endif
2807
#ifndef WOLFSSL_SP_NO_256
2808
    if (modBits == 256) {
2809
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2810
    }
2811
#endif
2812
#ifdef WOLFSSL_SP_384
2813
    if (modBits == 384) {
2814
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2815
    }
2816
#endif
2817
#ifdef WOLFSSL_SP_521
2818
    if (modBits == 521) {
2819
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2820
    }
2821
#endif
2822
    return ECC_BAD_ARG_E;
2823
#endif
2824
0
}
2825
2826
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2827
                             mp_int* modulus, mp_digit mp)
2828
0
{
2829
0
    if (P == NULL || R == NULL || modulus == NULL)
2830
0
        return ECC_BAD_ARG_E;
2831
2832
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2833
0
        mp_cmp(P->y, modulus) != MP_LT ||
2834
0
        mp_cmp(P->z, modulus) != MP_LT) {
2835
0
        return ECC_OUT_OF_RANGE_E;
2836
0
    }
2837
2838
0
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2839
0
}
2840
2841
#if !defined(FREESCALE_LTC_ECC) && \
2842
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY))
2843
2844
2845
/**
2846
  Map a projective Jacobian point back to affine space
2847
  P        [in/out] The point to map
2848
  modulus  The modulus of the field the ECC curve is in
2849
  mp       The "b" value from montgomery_setup()
2850
  ct       Operation should be constant time.
2851
  return   MP_OKAY on success
2852
*/
2853
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2854
0
{
2855
0
    int err = MP_OKAY;
2856
0
    (void)ct;
2857
2858
0
    if (P == NULL || modulus == NULL){
2859
0
        return ECC_BAD_ARG_E;
2860
0
    }
2861
0
    {
2862
0
        #if !defined(WOLFSSL_SP_MATH)
2863
0
        DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2864
0
        DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2865
        #ifdef ALT_ECC_SIZE
2866
        DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2867
        DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2868
        DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2869
        #endif
2870
0
        mp_int *x, *y, *z;
2871
2872
0
        if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2873
0
            return WC_KEY_SIZE_E;
2874
0
        }
2875
2876
        /* special case for point at infinity */
2877
0
        if (mp_cmp_d(P->z, 0) == MP_EQ) {
2878
0
            err = mp_set(P->x, 0);
2879
0
            if (err == MP_OKAY)
2880
0
                err = mp_set(P->y, 0);
2881
0
            if (err == MP_OKAY)
2882
0
                err = mp_set(P->z, 1);
2883
0
            return err;
2884
0
        }
2885
2886
        #ifdef WOLFSSL_SMALL_STACK
2887
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2888
        if (P->key != NULL) {
2889
            t1 = P->key->t1;
2890
            t2 = P->key->t2;
2891
        #ifdef ALT_ECC_SIZE
2892
            rx = P->key->x;
2893
            ry = P->key->y;
2894
            rz = P->key->z;
2895
        #endif
2896
        }
2897
        else
2898
        #endif /* WOLFSSL_SMALL_STACK_CACHE */
2899
        #endif
2900
0
        {
2901
0
            NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2902
0
            NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2903
        #ifdef MP_INT_SIZE_CHECK_NULL
2904
            if (t1 == NULL || t2 == NULL) {
2905
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2906
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2907
                return MEMORY_E;
2908
            }
2909
        #endif
2910
        #ifdef ALT_ECC_SIZE
2911
            NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2912
            NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2913
            NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2914
        #ifdef MP_INT_SIZE_CHECK_NULL
2915
            if (rx == NULL || ry == NULL || rz == NULL) {
2916
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2917
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2918
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2919
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2920
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2921
                return MEMORY_E;
2922
            }
2923
        #endif
2924
        #endif
2925
0
        }
2926
2927
0
        err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2928
0
        if (err == MP_OKAY) {
2929
0
            err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2930
0
        }
2931
0
        if (err != MP_OKAY) {
2932
        #ifdef WOLFSSL_SMALL_STACK
2933
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2934
            if (P->key == NULL)
2935
        #endif
2936
        #endif
2937
0
            {
2938
            #ifdef ALT_ECC_SIZE
2939
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2940
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2941
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2942
            #endif
2943
0
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2944
0
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2945
0
            }
2946
0
            return MEMORY_E;
2947
0
        }
2948
2949
        #ifdef ALT_ECC_SIZE
2950
        /* Use local stack variable */
2951
        x = rx;
2952
        y = ry;
2953
        z = rz;
2954
2955
        err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2956
        if (err == MP_OKAY) {
2957
            err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2958
        }
2959
        if (err == MP_OKAY) {
2960
            err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2961
        }
2962
        if (err != MP_OKAY) {
2963
            goto done;
2964
        }
2965
2966
        if (err == MP_OKAY)
2967
            err = mp_copy(P->x, x);
2968
        if (err == MP_OKAY)
2969
            err = mp_copy(P->y, y);
2970
        if (err == MP_OKAY)
2971
            err = mp_copy(P->z, z);
2972
2973
        if (err != MP_OKAY) {
2974
            goto done;
2975
        }
2976
        #else
2977
        /* Use destination directly */
2978
0
        x = P->x;
2979
0
        y = P->y;
2980
0
        z = P->z;
2981
0
        #endif
2982
2983
        /* get 1/z */
2984
0
        if (err == MP_OKAY) {
2985
0
        #if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2986
0
                        defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2987
0
            if (ct) {
2988
0
                err = mp_invmod_mont_ct(z, modulus, t1, mp);
2989
0
                if (err == MP_OKAY)
2990
0
                    err = mp_montgomery_reduce(t1, modulus, mp);
2991
0
            }
2992
0
            else
2993
0
        #endif
2994
0
            {
2995
                /* first map z back to normal */
2996
0
                err = mp_montgomery_reduce(z, modulus, mp);
2997
0
                if (err == MP_OKAY)
2998
0
                    err = mp_invmod(z, modulus, t1);
2999
0
            }
3000
0
        }
3001
3002
        /* get 1/z^2 and 1/z^3 */
3003
0
        if (err == MP_OKAY)
3004
0
            err = mp_sqr(t1, t2);
3005
0
        if (err == MP_OKAY)
3006
0
            err = mp_mod(t2, modulus, t2);
3007
0
        if (err == MP_OKAY)
3008
0
            err = mp_mul(t1, t2, t1);
3009
0
        if (err == MP_OKAY)
3010
0
            err = mp_mod(t1, modulus, t1);
3011
3012
        /* multiply against x/y */
3013
0
        if (err == MP_OKAY)
3014
0
            err = mp_mul(x, t2, x);
3015
0
        if (err == MP_OKAY)
3016
0
            err = mp_montgomery_reduce(x, modulus, mp);
3017
0
        if (err == MP_OKAY)
3018
0
            err = mp_mul(y, t1, y);
3019
0
        if (err == MP_OKAY)
3020
0
            err = mp_montgomery_reduce(y, modulus, mp);
3021
3022
0
        if (err == MP_OKAY)
3023
0
            err = mp_set(z, 1);
3024
3025
        #ifdef ALT_ECC_SIZE
3026
        /* return result */
3027
        if (err == MP_OKAY)
3028
            err = mp_copy(x, P->x);
3029
        if (err == MP_OKAY)
3030
            err = mp_copy(y, P->y);
3031
        if (err == MP_OKAY)
3032
            err = mp_copy(z, P->z);
3033
3034
        done:
3035
        #endif
3036
3037
        /* clean up */
3038
0
        mp_clear(t1);
3039
0
        mp_clear(t2);
3040
3041
        #ifdef WOLFSSL_SMALL_STACK
3042
        #ifdef WOLFSSL_SMALL_STACK_CACHE
3043
        if (P->key == NULL)
3044
        #endif
3045
        #endif
3046
0
        {
3047
        #ifdef ALT_ECC_SIZE
3048
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
3049
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
3050
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
3051
        #endif
3052
0
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
3053
0
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
3054
0
        }
3055
3056
0
        return err;
3057
        /* end !defined(WOLFSSL_SP_MATH) */
3058
3059
        #else
3060
        /* begin defined(WOLFSSL_SP_MATH) */
3061
        if (P == NULL || modulus == NULL)
3062
            return ECC_BAD_ARG_E;
3063
3064
        (void)mp;
3065
        (void)ct;
3066
3067
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3068
        if ((mp_count_bits(modulus) == 256) &&
3069
            (!mp_is_bit_set(modulus, 224))) {
3070
            err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
3071
        }
3072
        #elif !defined(WOLFSSL_SP_NO_256)
3073
        if (mp_count_bits(modulus) == 256) {
3074
            err = sp_ecc_map_256(P->x, P->y, P->z);
3075
        }
3076
        #elif defined(WOLFSSL_SP_384)
3077
        if (mp_count_bits(modulus) == 384) {
3078
            err = sp_ecc_map_384(P->x, P->y, P->z);
3079
        }
3080
        #elif defined(WOLFSSL_SP_521)
3081
        if (mp_count_bits(modulus) == 521) {
3082
            err = sp_ecc_map_521(P->x, P->y, P->z);
3083
        }
3084
        #else
3085
        err = ECC_BAD_ARG_E;
3086
        #endif
3087
3088
        WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
3089
    return err;
3090
#endif /* WOLFSSL_SP_MATH */
3091
0
    }
3092
0
}
3093
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
3094
3095
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
3096
0
{
3097
0
    return ecc_map_ex(P, modulus, mp, 0);
3098
0
}
3099
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
3100
3101
#if !defined(FREESCALE_LTC_ECC) && \
3102
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY))
3103
#if !defined(WOLFSSL_SP_MATH)
3104
3105
#ifndef ECC_TIMING_RESISTANT
3106
3107
/* size of sliding window, don't change this! */
3108
#define WINSIZE  4
3109
#define M_POINTS 8
3110
3111
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
3112
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3113
{
3114
   int      err = MP_OKAY;
3115
   int      i;
3116
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
3117
   int      bitcnt = 0, mode = 0, digidx = 0;
3118
   mp_digit buf;
3119
   int      infinity;
3120
3121
   (void)rng;
3122
3123
   /* calc the M tab, which holds kG for k==8..15 */
3124
   /* M[0] == 8G */
3125
   if (err == MP_OKAY)
3126
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
3127
   if (err == MP_OKAY)
3128
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3129
   if (err == MP_OKAY)
3130
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3131
3132
   /* now find (8+k)G for k=1..7 */
3133
   if (err == MP_OKAY)
3134
       for (j = 9; j < 16; j++) {
3135
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
3136
                                                        modulus, mp, &infinity);
3137
           if (err != MP_OKAY) break;
3138
       }
3139
3140
   /* setup sliding window */
3141
   if (err == MP_OKAY) {
3142
       mode   = 0;
3143
       bitcnt = 1;
3144
       buf    = 0;
3145
       digidx = mp_get_digit_count(k) - 1;
3146
       bitcpy = bitbuf = 0;
3147
       first  = 1;
3148
3149
       /* perform ops */
3150
       for (;;) {
3151
           /* grab next digit as required */
3152
           if (--bitcnt == 0) {
3153
               if (digidx == -1) {
3154
                   break;
3155
               }
3156
               buf    = mp_get_digit(k, digidx);
3157
               bitcnt = (int) DIGIT_BIT;
3158
               --digidx;
3159
           }
3160
3161
           /* grab the next msb from the ltiplicand */
3162
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3163
           buf <<= 1;
3164
3165
           /* skip leading zero bits */
3166
           if (mode == 0 && i == 0)
3167
               continue;
3168
3169
           /* if the bit is zero and mode == 1 then we double */
3170
           if (mode == 1 && i == 0) {
3171
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3172
               if (err != MP_OKAY) break;
3173
               continue;
3174
           }
3175
3176
           /* else we add it to the window */
3177
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3178
           mode = 2;
3179
3180
           if (bitcpy == WINSIZE) {
3181
               /* if this is the first window we do a simple copy */
3182
               if (first == 1) {
3183
                   /* R = kG [k = first window] */
3184
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3185
                   if (err != MP_OKAY) break;
3186
3187
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3188
                   if (err != MP_OKAY) break;
3189
3190
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3191
                   first = 0;
3192
               } else {
3193
                   /* normal window */
3194
                   /* ok window is filled so double as required and add  */
3195
                   /* double first */
3196
                   for (j = 0; j < WINSIZE; j++) {
3197
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3198
                                                                            mp);
3199
                       if (err != MP_OKAY) break;
3200
                   }
3201
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3202
3203
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3204
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3205
                                                     a, modulus, mp, &infinity);
3206
               }
3207
               if (err != MP_OKAY) break;
3208
               /* empty window and reset */
3209
               bitcpy = bitbuf = 0;
3210
               mode = 1;
3211
           }
3212
       }
3213
   }
3214
3215
   /* if bits remain then double/add */
3216
   if (err == MP_OKAY) {
3217
       if (mode == 2 && bitcpy > 0) {
3218
           /* double then add */
3219
           for (j = 0; j < bitcpy; j++) {
3220
               /* only double if we have had at least one add first */
3221
               if (first == 0) {
3222
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3223
                   if (err != MP_OKAY) break;
3224
               }
3225
3226
               bitbuf <<= 1;
3227
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3228
                   if (first == 1) {
3229
                       /* first add, so copy */
3230
                       err = mp_copy(tG->x, R->x);
3231
                       if (err != MP_OKAY) break;
3232
3233
                       err = mp_copy(tG->y, R->y);
3234
                       if (err != MP_OKAY) break;
3235
3236
                       err = mp_copy(tG->z, R->z);
3237
                       if (err != MP_OKAY) break;
3238
                       first = 0;
3239
                   } else {
3240
                       /* then add */
3241
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3242
                                                                 mp, &infinity);
3243
                       if (err != MP_OKAY) break;
3244
                   }
3245
               }
3246
           }
3247
       }
3248
   }
3249
3250
   #undef WINSIZE
3251
3252
   return err;
3253
}
3254
3255
#else
3256
3257
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3258
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3259
0
{
3260
0
    int err = MP_OKAY;
3261
3262
0
    err = mp_montgomery_calc_normalization(mu, modulus);
3263
    /* Generate random value to multiply into p->z. */
3264
0
    if (err == MP_OKAY)
3265
0
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3266
    /* Convert to montogmery form. */
3267
0
    if (err == MP_OKAY)
3268
0
        err = mp_mulmod(ty, mu, modulus, ty);
3269
    /* Multiply random value into p->z. */
3270
0
    if (err == MP_OKAY)
3271
0
        err = mp_mul(p->z, ty, p->z);
3272
0
    if (err == MP_OKAY)
3273
0
        err = mp_montgomery_reduce(p->z, modulus, mp);
3274
    /* Square random value for X (X' = X / Z^2). */
3275
0
    if (err == MP_OKAY)
3276
0
        err = mp_sqr(ty, tx);
3277
0
    if (err == MP_OKAY)
3278
0
        err = mp_montgomery_reduce(tx, modulus, mp);
3279
    /* Multiply square of random by random value for Y. */
3280
0
    if (err == MP_OKAY)
3281
0
        err = mp_mul(ty, tx, ty);
3282
0
    if (err == MP_OKAY)
3283
0
        err = mp_montgomery_reduce(ty, modulus, mp);
3284
    /* Multiply square into X. */
3285
0
    if (err == MP_OKAY)
3286
0
        err = mp_mul(p->x, tx, p->x);
3287
0
    if (err == MP_OKAY)
3288
0
        err = mp_montgomery_reduce(p->x, modulus, mp);
3289
    /* Multiply cube into Y (Y' = Y / Z^3). */
3290
0
    if (err == MP_OKAY)
3291
0
        err = mp_mul(p->y, ty, p->y);
3292
0
    if (err == MP_OKAY)
3293
0
        err = mp_montgomery_reduce(p->y, modulus, mp);
3294
3295
0
    return err;
3296
0
}
3297
3298
#ifndef WC_PROTECT_ENCRYPTED_MEM
3299
0
#define M_POINTS 3
3300
3301
/* Joye double-add ladder.
3302
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3303
 * by Marc Joye (2007)
3304
 *
3305
 * Algorithm 1':
3306
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3307
 *   Output: Q = kP
3308
 *   1: R[0] = P; R[1] = P
3309
 *   2: for j = 1 to t-1 do
3310
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3311
 *   4: end for
3312
 *   5: b = k[0]; R[b] = R[b] - P
3313
 *   6: return R[0]
3314
 *
3315
 * Assumes: k < order.
3316
 */
3317
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3318
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3319
0
{
3320
0
    int      err = MP_OKAY;
3321
0
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3322
0
    int      i;
3323
0
    int      j = 1;
3324
0
    int      cnt = DIGIT_BIT;
3325
0
    int      t = 0;
3326
0
    mp_digit b;
3327
0
    mp_digit v = 0;
3328
0
    mp_int*  kt = R[2]->x;
3329
0
#ifndef WC_NO_CACHE_RESISTANT
3330
    /* First bit always 1 (fix at end) and swap equals first bit */
3331
0
    int      swap = 1;
3332
0
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3333
0
    int      tmpInit = 0;
3334
0
#endif
3335
0
    int      infinity;
3336
3337
0
#ifndef WC_NO_CACHE_RESISTANT
3338
0
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3339
0
    if (err == MP_OKAY) {
3340
0
        err = mp_init(tmp);
3341
0
        tmpInit = (err == MP_OKAY);
3342
0
    }
3343
0
#endif
3344
3345
    /* Step 1: R[0] = P; R[1] = P */
3346
    /* R[0] = P */
3347
0
    if (err == MP_OKAY)
3348
0
        err = mp_copy(P->x, R[0]->x);
3349
0
    if (err == MP_OKAY)
3350
0
        err = mp_copy(P->y, R[0]->y);
3351
0
    if (err == MP_OKAY)
3352
0
        err = mp_copy(P->z, R[0]->z);
3353
3354
    /* R[1] = P */
3355
0
    if (err == MP_OKAY)
3356
0
        err = mp_copy(P->x, R[1]->x);
3357
0
    if (err == MP_OKAY)
3358
0
        err = mp_copy(P->y, R[1]->y);
3359
0
    if (err == MP_OKAY)
3360
0
        err = mp_copy(P->z, R[1]->z);
3361
3362
    /* Randomize z ordinates to obfuscate timing. */
3363
0
    if ((err == MP_OKAY) && (rng != NULL))
3364
0
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3365
0
    if ((err == MP_OKAY) && (rng != NULL))
3366
0
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3367
3368
0
    if (err == MP_OKAY) {
3369
        /* Order could be one greater than the size of the modulus. */
3370
0
        t = mp_count_bits(modulus) + 1;
3371
0
        v = k->dp[0] >> 1;
3372
0
        if (cnt > t) {
3373
0
            cnt = t;
3374
0
        }
3375
0
        err = mp_copy(k, kt);
3376
0
    }
3377
0
    if (err == MP_OKAY) {
3378
0
        err = mp_grow(kt, (int)modulus->used + 1);
3379
0
    }
3380
    /* Step 2: for j = 1 to t-1 do */
3381
0
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3382
0
        if (--cnt == 0) {
3383
0
            v = kt->dp[j++];
3384
0
            cnt = DIGIT_BIT;
3385
0
        }
3386
3387
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3388
0
        b = v & 1;
3389
0
        v >>= 1;
3390
#ifdef WC_NO_CACHE_RESISTANT
3391
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3392
        if (err == MP_OKAY) {
3393
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3394
                                                        modulus, mp, &infinity);
3395
        }
3396
#else
3397
        /* Swap R[0] and R[1] if other index is needed. */
3398
0
        swap ^= (int)b;
3399
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3400
0
            tmp);
3401
0
        if (err == MP_OKAY) {
3402
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3403
0
                tmp);
3404
0
        }
3405
0
        if (err == MP_OKAY) {
3406
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3407
0
                tmp);
3408
0
        }
3409
0
        swap = (int)b;
3410
3411
0
        if (err == MP_OKAY)
3412
0
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3413
0
        if (err == MP_OKAY) {
3414
0
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3415
0
                                                                 mp, &infinity);
3416
0
        }
3417
0
#endif /* WC_NO_CACHE_RESISTANT */
3418
0
    }
3419
    /* Step 4: end for */
3420
0
#ifndef WC_NO_CACHE_RESISTANT
3421
    /* Swap back if last bit is 0. */
3422
0
    swap ^= 1;
3423
0
    if (err == MP_OKAY) {
3424
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3425
0
            tmp);
3426
0
    }
3427
0
    if (err == MP_OKAY) {
3428
0
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3429
0
            tmp);
3430
0
    }
3431
0
    if (err == MP_OKAY) {
3432
0
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3433
0
            tmp);
3434
0
    }
3435
0
#endif
3436
3437
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3438
    /* R[2] = -P */
3439
0
    if (err == MP_OKAY)
3440
0
        err = mp_copy(P->x, R[2]->x);
3441
0
    if (err == MP_OKAY)
3442
0
        err = mp_sub(modulus, P->y, R[2]->y);
3443
0
    if (err == MP_OKAY)
3444
0
        err = mp_copy(P->z, R[2]->z);
3445
    /* Subtract point by adding negative. */
3446
0
    if (err == MP_OKAY) {
3447
0
        b = k->dp[0] & 1;
3448
#ifdef WC_NO_CACHE_RESISTANT
3449
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3450
                                                                     &infinity);
3451
#else
3452
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3453
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3454
0
            tmp);
3455
0
        if (err == MP_OKAY) {
3456
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3457
0
                (int)b, tmp);
3458
0
        }
3459
0
        if (err == MP_OKAY) {
3460
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3461
0
                (int)b, tmp);
3462
0
        }
3463
0
        if (err == MP_OKAY)
3464
0
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3465
0
                                                                 mp, &infinity);
3466
        /* Swap back if necessary. */
3467
0
        if (err == MP_OKAY) {
3468
0
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3469
0
                (int)b, tmp);
3470
0
        }
3471
0
        if (err == MP_OKAY) {
3472
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3473
0
                (int)b, tmp);
3474
0
        }
3475
0
        if (err == MP_OKAY) {
3476
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3477
0
                (int)b, tmp);
3478
0
        }
3479
0
#endif
3480
0
    }
3481
3482
    /* Step 6: return R[0] */
3483
0
    if (err == MP_OKAY)
3484
0
        err = mp_copy(R[0]->x, Q->x);
3485
0
    if (err == MP_OKAY)
3486
0
        err = mp_copy(R[0]->y, Q->y);
3487
0
    if (err == MP_OKAY)
3488
0
        err = mp_copy(R[0]->z, Q->z);
3489
3490
    /* kt holds a copy of the scalar (ISO/IEC 19790:2012 7.9.7). */
3491
0
    mp_forcezero(kt);
3492
0
#ifndef WC_NO_CACHE_RESISTANT
3493
    /* tmp can hold scalar-dependent coordinates even after a ladder error. */
3494
0
    if (tmpInit)
3495
0
        mp_forcezero(tmp);
3496
0
#endif
3497
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3498
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3499
#endif
3500
3501
0
    return err;
3502
0
}
3503
3504
#else
3505
/* Number of points to allocate for use during scalar multiplication. */
3506
#define M_POINTS        5
3507
/* Last of the points is used as a temporary during calculations. */
3508
#define TMP_IDX         M_POINTS - 1
3509
3510
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3511
    int digits, int m)
3512
{
3513
    int i;
3514
3515
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3516
    /* Only using positive numbers in ECC operations. */
3517
    ra->sign = 0;
3518
    rb->sign = 0;
3519
#endif
3520
    /* Don't store 0 when mask is 0, it will be in a register. */
3521
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3522
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3523
    for (i = 0; i < digits; i++) {
3524
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3525
                    a->dp[i];
3526
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3527
                    b->dp[i];
3528
    }
3529
}
3530
3531
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3532
    ecc_point* b, int digits, int m)
3533
{
3534
    /* Conditionally swap each ordinate. */
3535
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3536
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3537
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3538
}
3539
3540
/* Joye double-add ladder.
3541
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3542
 * by Marc Joye (2007)
3543
 *
3544
 * Algorithm 1':
3545
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3546
 *   Output: Q = kP
3547
 *   1: R[0] = P; R[1] = P
3548
 *   2: for j = 1 to t-1 do
3549
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3550
 *   4: end for
3551
 *   5: b = k[0]; R[b] = R[b] - P
3552
 *   6: return R[0]
3553
 *
3554
 * Assumes: k < order.
3555
 */
3556
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3557
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3558
{
3559
    int          err = MP_OKAY;
3560
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3561
    int          i;
3562
    int          j = 1;
3563
    int          cnt;
3564
    int          t = 0;
3565
    mp_int*      kt = R[TMP_IDX]->x;
3566
    /* First bit always 1 (fix at end) and swap equals first bit */
3567
    register int swap = 1;
3568
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3569
    int          set = 0;
3570
    int          infinity;
3571
3572
    /* Step 1: R[0] = P; R[1] = P */
3573
    /* R[0] = P */
3574
    if (err == MP_OKAY)
3575
        err = mp_copy(P->x, R[0]->x);
3576
    if (err == MP_OKAY)
3577
        err = mp_copy(P->y, R[0]->y);
3578
    if (err == MP_OKAY)
3579
        err = mp_copy(P->z, R[0]->z);
3580
3581
    /* R[1] = P */
3582
    if (err == MP_OKAY)
3583
        err = mp_copy(P->x, R[1]->x);
3584
    if (err == MP_OKAY)
3585
        err = mp_copy(P->y, R[1]->y);
3586
    if (err == MP_OKAY)
3587
        err = mp_copy(P->z, R[1]->z);
3588
3589
    /* Randomize z ordinates to obfuscate timing. */
3590
    if ((err == MP_OKAY) && (rng != NULL))
3591
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3592
                           R[TMP_IDX]->y, kt);
3593
    if ((err == MP_OKAY) && (rng != NULL))
3594
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3595
                           R[TMP_IDX]->y, kt);
3596
3597
    if (err == MP_OKAY) {
3598
        /* Order could be one greater than the size of the modulus. */
3599
        t = mp_count_bits(modulus) + 1;
3600
        err = mp_copy(k, kt);
3601
    }
3602
    if (err == MP_OKAY) {
3603
        err = mp_grow(kt, modulus->used + 1);
3604
    }
3605
    /* Step 2: for j = 1 to t-1 do */
3606
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3607
        if (++cnt == DIGIT_BIT) {
3608
            j++;
3609
            cnt = 0;
3610
        }
3611
3612
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3613
        /* Swap R[0] and R[1] if other index is needed. */
3614
        /* Ensure 'swap' changes when shifted word is 0. */
3615
        swap += (kt->dp[j] >> cnt) + 2;
3616
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3617
                              R[set + 0], R[set + 1], modulus->used, swap);
3618
        /* Change to operate on set copied into. */
3619
        set = 2 - set;
3620
        /* Ensure 'swap' changes to a previously unseen value. */
3621
        swap += (kt->dp[j] >> cnt) + swap;
3622
3623
        /* R[0] = 2*R[0] */
3624
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3625
                                            mp);
3626
        if (err == MP_OKAY) {
3627
            /* R[0] = R[1] + R[0] */
3628
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3629
                                         R[set + 0], a, modulus, mp, &infinity);
3630
        }
3631
        /*  R[1]->z * 2 - same point. */
3632
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3633
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3634
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3635
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3636
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3637
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3638
    }
3639
    /* Step 4: end for */
3640
    /* Swap back if last bit is 0. */
3641
    /* Ensure 'swap' changes. */
3642
    swap += 1;
3643
    if (err == MP_OKAY) {
3644
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3645
                              R[set + 0], R[set + 1], modulus->used, swap);
3646
        set = 2 - set;
3647
    }
3648
3649
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3650
    /* R[TMP_IDX] = -P */
3651
    if (err == MP_OKAY)
3652
        err = mp_copy(P->x, R[TMP_IDX]->x);
3653
    if (err == MP_OKAY)
3654
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3655
    if (err == MP_OKAY)
3656
        err = mp_copy(P->z, R[TMP_IDX]->z);
3657
    /* Subtract point by adding negative. */
3658
    if (err == MP_OKAY) {
3659
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3660
         * Last bit of k->dp[0] is being used to make decision to swap.
3661
         */
3662
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3663
                              R[set + 0], R[set + 1], modulus->used,
3664
                              (int)k->dp[0]);
3665
        set = 2 - set;
3666
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3667
                                            a, modulus, mp, &infinity);
3668
        /* Swap back if necessary. */
3669
        if (err == MP_OKAY) {
3670
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3671
                                  R[set + 0], R[set + 1], modulus->used,
3672
                                  (int)k->dp[0]);
3673
            set = 2 - set;
3674
        }
3675
    }
3676
3677
    /* Step 6: return R[0] */
3678
    if (err == MP_OKAY)
3679
        err = mp_copy(R[set + 0]->x, Q->x);
3680
    if (err == MP_OKAY)
3681
        err = mp_copy(R[set + 0]->y, Q->y);
3682
    if (err == MP_OKAY)
3683
        err = mp_copy(R[set + 0]->z, Q->z);
3684
3685
    /* kt holds a copy of the scalar (ISO/IEC 19790:2012 7.9.7). */
3686
    mp_forcezero(kt);
3687
3688
    return err;
3689
}
3690
3691
#endif
3692
3693
#endif
3694
3695
/* Convert the point to montgomery form.
3696
 *
3697
 * @param  [in]   p        Point to convert.
3698
 * @param  [out]  r        Point in montgomery form.
3699
 * @param  [in]   modulus  Modulus of ordinates.
3700
 * @return  0 on success.
3701
 * @return  -ve on failure.
3702
 */
3703
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3704
                             void* heap)
3705
0
{
3706
0
   int err = MP_OKAY;
3707
3708
0
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3709
3710
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
3711
0
       return WC_KEY_SIZE_E;
3712
0
   }
3713
3714
0
   (void)heap;
3715
3716
0
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3717
#ifdef MP_INT_SIZE_CHECK_NULL
3718
   if (mu == NULL)
3719
       err = MEMORY_E;
3720
#endif
3721
0
   if (err == MP_OKAY)
3722
0
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3723
0
   if (err == MP_OKAY) {
3724
0
       err = mp_montgomery_calc_normalization(mu, modulus);
3725
3726
0
       if (err == MP_OKAY) {
3727
0
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3728
               /* Montgomery form is the same as normal form (e.g. P-521 with
3729
                * SP int math) but the ordinates must still be reduced as the
3730
                * point arithmetic requires them to be less than the modulus.
3731
                */
3732
0
               err = mp_mod(p->x, modulus, r->x);
3733
0
               if (err == MP_OKAY)
3734
0
                   err = mp_mod(p->y, modulus, r->y);
3735
0
               if (err == MP_OKAY)
3736
0
                   err = mp_mod(p->z, modulus, r->z);
3737
0
           }
3738
0
           else {
3739
0
               err = mp_mulmod(p->x, mu, modulus, r->x);
3740
0
               if (err == MP_OKAY)
3741
0
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3742
0
               if (err == MP_OKAY)
3743
0
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3744
0
           }
3745
0
       }
3746
3747
0
       mp_clear(mu);
3748
0
   }
3749
3750
0
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3751
0
   return err;
3752
0
}
3753
3754
#ifdef WOLFSSL_SMALL_STACK_CACHE
3755
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3756
{
3757
   int err = MP_OKAY;
3758
3759
   (void)heap;
3760
3761
   if (key == NULL) {
3762
       return ECC_BAD_ARG_E;
3763
   }
3764
3765
   XMEMSET(key, 0, sizeof(*key));
3766
3767
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3768
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3769
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3770
#ifdef ALT_ECC_SIZE
3771
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3772
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3773
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3774
#endif
3775
   if (key->t1 == NULL || key->t2 == NULL
3776
#ifdef ALT_ECC_SIZE
3777
      || key->x == NULL || key->y == NULL || key->z == NULL
3778
#endif
3779
   ) {
3780
       err = MEMORY_E;
3781
   }
3782
   if (err == 0) {
3783
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3784
   }
3785
   if (err == 0) {
3786
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3787
   }
3788
#ifdef ALT_ECC_SIZE
3789
   if (err == 0) {
3790
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3791
   }
3792
   if (err == 0) {
3793
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3794
   }
3795
   if (err == 0) {
3796
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3797
   }
3798
#endif
3799
#else
3800
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3801
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3802
#ifdef ALT_ECC_SIZE
3803
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3804
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3805
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3806
#endif
3807
   if (key->t1 == NULL || key->t2 == NULL
3808
#ifdef ALT_ECC_SIZE
3809
      || key->x == NULL || key->y == NULL || key->z == NULL
3810
#endif
3811
   ) {
3812
       err = MEMORY_E;
3813
   }
3814
#endif
3815
3816
   return err;
3817
}
3818
3819
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3820
{
3821
    (void)heap;
3822
3823
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3824
#ifdef ALT_ECC_SIZE
3825
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3826
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3827
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3828
#endif
3829
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3830
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3831
#else
3832
#ifdef ALT_ECC_SIZE
3833
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3834
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3835
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3836
#endif
3837
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3838
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3839
#endif
3840
}
3841
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3842
#endif /* !WOLFSSL_SP_MATH */
3843
3844
#if defined(WOLFSSL_HAVE_SP_ECC) && !defined(WOLFSSL_SP_MATH)
3845
/* Point multiplication with the SP code for callers of wc_ecc_mulmod() and
3846
 * wc_ecc_mulmod_ex() (hostapd's SAE, for example) when the curve is one the SP
3847
 * code implements. Only the modulus and a are given, so the curve is
3848
 * identified by both, as other curves of the same size may be compiled in.
3849
 * Only when mapping back to affine coordinates, as otherwise the result is
3850
 * expected in the generic code's representation.
3851
 *
3852
 * Returns NOT_COMPILED_IN when the SP code does not apply.
3853
 */
3854
static int ecc_sp_mulmod(const mp_int* k, ecc_point* G, ecc_point* R,
3855
                         mp_int* a, mp_int* modulus, int map, void* heap)
3856
{
3857
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3858
    int bits = mp_count_bits(modulus);
3859
    int curveId;
3860
    int idx;
3861
    int err;
3862
3863
    if (!map || a == NULL || MP_BITS_OVER_MAX(bits, MAX_ECC_BITS_USE)) {
3864
        return NOT_COMPILED_IN;
3865
    }
3866
    switch (bits) {
3867
#ifndef WOLFSSL_SP_NO_256
3868
    case 256:
3869
        curveId = ECC_SECP256R1;
3870
        break;
3871
#endif
3872
#ifdef WOLFSSL_SP_384
3873
    case 384:
3874
        curveId = ECC_SECP384R1;
3875
        break;
3876
#endif
3877
#ifdef WOLFSSL_SP_521
3878
    case 521:
3879
        curveId = ECC_SECP521R1;
3880
        break;
3881
#endif
3882
    default:
3883
        return NOT_COMPILED_IN;
3884
    }
3885
    /* The SP code takes a non-negative scalar no longer than the curve and an
3886
     * affine point (z = 1) with coordinates already reduced modulo the prime:
3887
     * it would truncate wider values, and with FP_ECC it caches tables by x
3888
     * and y only. It writes the result's digits but not their signs, so the
3889
     * result point's ordinates must not be negative either. Leave anything
3890
     * else to the generic code, which handles them. */
3891
    if (mp_isneg(k) || (mp_count_bits(k) > bits)) {
3892
        return NOT_COMPILED_IN;
3893
    }
3894
    if (mp_isneg(G->x) || mp_isneg(G->y) ||
3895
            (mp_cmp(G->x, modulus) != MP_LT) ||
3896
            (mp_cmp(G->y, modulus) != MP_LT) ||
3897
            (mp_cmp_d(G->z, 1) != MP_EQ)) {
3898
        return NOT_COMPILED_IN;
3899
    }
3900
    if (mp_isneg(R->x) || mp_isneg(R->y) || mp_isneg(R->z)) {
3901
        return NOT_COMPILED_IN;
3902
    }
3903
    idx = wc_ecc_get_curve_idx(curveId);
3904
    if (idx < 0) {
3905
        return NOT_COMPILED_IN;
3906
    }
3907
3908
    NEW_MP_INT_SIZE(t, bits, heap, DYNAMIC_TYPE_ECC);
3909
#ifdef MP_INT_SIZE_CHECK_NULL
3910
    if (t == NULL) {
3911
        return MEMORY_E;
3912
    }
3913
#endif
3914
    err = INIT_MP_INT_SIZE(t, bits);
3915
    if (err == MP_OKAY) {
3916
        err = mp_read_radix(t, ecc_sets[idx].prime, MP_RADIX_HEX);
3917
    }
3918
    if ((err == MP_OKAY) && (mp_cmp(t, modulus) != MP_EQ)) {
3919
        err = NOT_COMPILED_IN;
3920
    }
3921
    if (err == MP_OKAY) {
3922
        err = mp_read_radix(t, ecc_sets[idx].Af, MP_RADIX_HEX);
3923
    }
3924
    if ((err == MP_OKAY) && (mp_cmp(t, a) != MP_EQ)) {
3925
        err = NOT_COMPILED_IN;
3926
    }
3927
    mp_clear(t);
3928
    FREE_MP_INT_SIZE(t, heap, DYNAMIC_TYPE_ECC);
3929
    if (err != MP_OKAY) {
3930
        return err;
3931
    }
3932
3933
    switch (bits) {
3934
#ifndef WOLFSSL_SP_NO_256
3935
    case 256:
3936
        return sp_ecc_mulmod_256(k, G, R, map, heap);
3937
#endif
3938
#ifdef WOLFSSL_SP_384
3939
    case 384:
3940
        return sp_ecc_mulmod_384(k, G, R, map, heap);
3941
#endif
3942
#ifdef WOLFSSL_SP_521
3943
    case 521:
3944
        return sp_ecc_mulmod_521(k, G, R, map, heap);
3945
#endif
3946
    default:
3947
        return NOT_COMPILED_IN;
3948
    }
3949
}
3950
#endif /* WOLFSSL_HAVE_SP_ECC && !WOLFSSL_SP_MATH */
3951
3952
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3953
/**
3954
   Perform a point multiplication
3955
   k    The scalar to multiply by
3956
   G    The base point
3957
   R    [out] Destination for kG
3958
   a    ECC curve parameter a
3959
   modulus  The modulus of the field the ECC curve is in
3960
   map      Boolean whether to map back to affine or not
3961
                (1==map, 0 == leave in projective)
3962
   return MP_OKAY on success
3963
*/
3964
#ifdef FP_ECC
3965
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3966
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3967
                             void* heap)
3968
#else
3969
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3970
                     mp_int* modulus, int map, void* heap)
3971
#endif
3972
#if !defined(WOLFSSL_SP_MATH)
3973
0
{
3974
0
   ecc_point     *tG, *M[M_POINTS];
3975
#ifdef WOLFSSL_NO_MALLOC
3976
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3977
#endif
3978
0
   int           i, err;
3979
#ifdef WOLFSSL_SMALL_STACK_CACHE
3980
   ecc_key       *key = NULL;
3981
#endif
3982
0
   mp_digit      mp;
3983
3984
   /* init variables */
3985
0
   tG = NULL;
3986
0
   XMEMSET(M, 0, sizeof(M));
3987
3988
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3989
0
       err = ECC_BAD_ARG_E;
3990
0
       goto exit;
3991
0
   }
3992
3993
   /* k can't be negative or have more bits than modulus count plus 1 */
3994
0
   if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus) + 1)) {
3995
0
       err = ECC_OUT_OF_RANGE_E;
3996
0
       goto exit;
3997
0
   }
3998
3999
0
   if (mp_iszero(k)) {
4000
0
       err = mp_set(R->x, 0);
4001
0
       if (err == MP_OKAY)
4002
0
           err = mp_set(R->y, 0);
4003
0
       if (err == MP_OKAY)
4004
0
           err = mp_set(R->z, 1);
4005
0
       goto exit;
4006
0
   }
4007
4008
#if defined(WOLFSSL_HAVE_SP_ECC) && !defined(WOLFSSL_SP_MATH)
4009
   err = ecc_sp_mulmod(k, G, R, a, modulus, map, heap);
4010
   if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
4011
       return err;
4012
   }
4013
#endif
4014
4015
#ifdef WOLFSSL_SMALL_STACK_CACHE
4016
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
4017
   if (key == NULL) {
4018
       err = MP_MEM;
4019
       goto exit;
4020
   }
4021
   err = ecc_key_tmp_init(key, heap);
4022
   if (err != MP_OKAY)
4023
      goto exit;
4024
   R->key = key;
4025
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4026
4027
  /* alloc ram for window temps */
4028
0
  for (i = 0; i < M_POINTS; i++) {
4029
  #ifdef WOLFSSL_NO_MALLOC
4030
      M[i] = &lcl_M[i];
4031
  #endif
4032
0
      err = wc_ecc_new_point_ex(&M[i], heap);
4033
0
      if (err != MP_OKAY) {
4034
0
         goto exit;
4035
0
      }
4036
#ifdef WOLFSSL_SMALL_STACK_CACHE
4037
      M[i]->key = key;
4038
#endif
4039
0
  }
4040
4041
   /* make a copy of G in case R==G */
4042
#ifdef WOLFSSL_NO_MALLOC
4043
   tG = &lcl_tG;
4044
#endif
4045
0
   err = wc_ecc_new_point_ex(&tG, heap);
4046
0
   if (err != MP_OKAY) {
4047
0
       goto exit;
4048
0
   }
4049
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
4050
0
       goto exit;
4051
0
   }
4052
4053
   /* init montgomery reduction */
4054
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
4055
0
       goto exit;
4056
0
   }
4057
4058
#ifdef FP_ECC
4059
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
4060
#else
4061
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
4062
0
#endif
4063
   /* map R back from projective space */
4064
0
   if (err == MP_OKAY && map)
4065
0
       err = ecc_map(R, modulus, mp);
4066
4067
0
exit:
4068
4069
   /* done */
4070
0
   wc_ecc_del_point_ex(tG, heap);
4071
0
   for (i = 0; i < M_POINTS; i++) {
4072
0
       wc_ecc_del_point_ex(M[i], heap);
4073
0
   }
4074
4075
#ifdef WOLFSSL_SMALL_STACK_CACHE
4076
   if (key) {
4077
       if (R)
4078
           R->key = NULL;
4079
       ecc_key_tmp_final(key, heap);
4080
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
4081
   }
4082
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4083
4084
0
   return err;
4085
0
}
4086
#else
4087
{
4088
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4089
       return ECC_BAD_ARG_E;
4090
   }
4091
4092
   (void)a;
4093
4094
   /* For supported curves the order is the same length in bits as the modulus.
4095
    * Can't have more than order bits for the scalar.
4096
    */
4097
   if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus))) {
4098
       return ECC_OUT_OF_RANGE_E;
4099
   }
4100
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4101
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4102
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4103
       return IS_POINT_E;
4104
   }
4105
4106
#ifdef WOLFSSL_HAVE_SP_ECC
4107
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4108
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4109
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4110
   }
4111
#endif
4112
#ifndef WOLFSSL_SP_NO_256
4113
   if (mp_count_bits(modulus) == 256) {
4114
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4115
   }
4116
#endif
4117
#ifdef WOLFSSL_SP_384
4118
   if (mp_count_bits(modulus) == 384) {
4119
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4120
   }
4121
#endif
4122
#ifdef WOLFSSL_SP_521
4123
   if (mp_count_bits(modulus) == 521) {
4124
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4125
   }
4126
#endif
4127
#else
4128
   (void)map;
4129
   (void)map;
4130
   (void)heap;
4131
#endif
4132
   return ECC_BAD_ARG_E;
4133
}
4134
#endif
4135
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
4136
4137
#ifndef FP_ECC
4138
#if !defined(WOLFSSL_SP_MATH)
4139
#ifdef ECC_TIMING_RESISTANT
4140
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
4141
   mp_int* modulus, mp_int* order)
4142
0
{
4143
0
    int err;
4144
0
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
4145
4146
0
    if (MP_BITS_OVER_MAX(mp_bitsused(order), MAX_ECC_BITS_USE) ||
4147
0
            MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
4148
0
        return WC_KEY_SIZE_E;
4149
0
    }
4150
4151
0
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
4152
#ifdef MP_INT_SIZE_CHECK_NULL
4153
    if (t == NULL) {
4154
        err = MEMORY_E;
4155
    }
4156
    else
4157
#endif
4158
0
    {
4159
0
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
4160
0
    }
4161
0
    if (err == MP_OKAY) {
4162
        /* Check for k == order - 1. Result will be 0 point which is not correct
4163
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
4164
         * (with constant time implementation)
4165
         */
4166
0
        err = mp_sub_d(order, 1, t);
4167
0
        if (err == MP_OKAY) {
4168
0
            int kIsMinusOne = (mp_cmp((const mp_int*)k, t) == MP_EQ);
4169
0
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
4170
0
            if (err == MP_OKAY) {
4171
0
                err = mp_sub(modulus, tG->y, t);
4172
0
            }
4173
0
            if (err == MP_OKAY) {
4174
0
                err = mp_cond_copy(t, kIsMinusOne, R->y);
4175
0
            }
4176
0
            if (err == MP_OKAY) {
4177
0
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
4178
0
            }
4179
0
        }
4180
4181
0
        mp_free(t);
4182
0
    }
4183
4184
0
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
4185
0
    return err;
4186
0
}
4187
#endif /* ECC_TIMING_RESISTANT */
4188
#endif
4189
4190
/**
4191
   Perform a point multiplication
4192
   k    The scalar to multiply by
4193
   G    The base point
4194
   R    [out] Destination for kG
4195
   a    ECC curve parameter a
4196
   modulus  The modulus of the field the ECC curve is in
4197
   map      Boolean whether to map back to affine or not
4198
                (1==map, 0 == leave in projective)
4199
   return MP_OKAY on success
4200
*/
4201
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
4202
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
4203
                      void* heap)
4204
#if !defined(WOLFSSL_SP_MATH)
4205
0
{
4206
0
   ecc_point     *tG, *M[M_POINTS];
4207
#ifdef WOLFSSL_NO_MALLOC
4208
   ecc_point     lcl_tG, lcl_M[M_POINTS];
4209
#endif
4210
0
   int           i, err;
4211
#ifdef WOLFSSL_SMALL_STACK_CACHE
4212
   ecc_key       *key = NULL;
4213
#endif
4214
0
   mp_digit      mp;
4215
4216
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4217
0
      return ECC_BAD_ARG_E;
4218
0
   }
4219
0
   if (mp_isneg(k) == MP_YES) {
4220
0
      return ECC_OUT_OF_RANGE_E;
4221
0
   }
4222
4223
#ifdef HAVE_ECC_CDH
4224
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
4225
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
4226
          return ECC_OUT_OF_RANGE_E;
4227
      }
4228
   }
4229
   else
4230
#endif
4231
   /* k can't have more bits than order */
4232
0
   if (mp_count_bits(k) > mp_count_bits(order)) {
4233
0
      WOLFSSL_MSG("Private key length is greater than order in bits.");
4234
0
      return ECC_OUT_OF_RANGE_E;
4235
0
   }
4236
4237
0
   if (mp_iszero(k)) {
4238
0
      err = mp_set(R->x, 0);
4239
0
      if (err == MP_OKAY)
4240
0
         err = mp_set(R->y, 0);
4241
0
      if (err == MP_OKAY)
4242
0
         err = mp_set(R->z, 1);
4243
0
      return err;
4244
0
   }
4245
4246
   /* init variables */
4247
0
   tG = NULL;
4248
0
   XMEMSET(M, 0, sizeof(M));
4249
4250
#ifdef WOLFSSL_SMALL_STACK_CACHE
4251
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
4252
   if (key == NULL)
4253
       return MEMORY_E;
4254
   err = ecc_key_tmp_init(key, heap);
4255
   if (err != MP_OKAY)
4256
      goto exit;
4257
   R->key = key;
4258
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4259
4260
   /* alloc ram for window temps */
4261
0
   for (i = 0; i < M_POINTS; i++) {
4262
   #ifdef WOLFSSL_NO_MALLOC
4263
      M[i] = &lcl_M[i];
4264
   #endif
4265
0
      err = wc_ecc_new_point_ex(&M[i], heap);
4266
0
      if (err != MP_OKAY) {
4267
0
         goto exit;
4268
0
      }
4269
#ifdef WOLFSSL_SMALL_STACK_CACHE
4270
      M[i]->key = key;
4271
#endif
4272
0
  }
4273
4274
   /* make a copy of G in case R==G */
4275
#ifdef WOLFSSL_NO_MALLOC
4276
   tG = &lcl_tG;
4277
#endif
4278
0
   err = wc_ecc_new_point_ex(&tG, heap);
4279
0
   if (err != MP_OKAY) {
4280
0
       goto exit;
4281
0
   }
4282
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
4283
0
       goto exit;
4284
0
   }
4285
4286
   /* init montgomery reduction */
4287
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
4288
0
      goto exit;
4289
0
   }
4290
4291
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
4292
0
#ifdef ECC_TIMING_RESISTANT
4293
0
   if (err == MP_OKAY) {
4294
0
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
4295
0
   }
4296
#else
4297
   (void)order;
4298
#endif
4299
   /* map R back from projective space */
4300
0
   if (err == MP_OKAY && map)
4301
0
      err = ecc_map(R, modulus, mp);
4302
4303
0
exit:
4304
4305
   /* Ladder points are scalar dependent; mp_clear only wipes under FIPS. */
4306
0
   wc_ecc_forcezero_point(tG);
4307
0
   wc_ecc_del_point_ex(tG, heap);
4308
0
   for (i = 0; i < M_POINTS; i++) {
4309
0
      wc_ecc_forcezero_point(M[i]);
4310
0
      wc_ecc_del_point_ex(M[i], heap);
4311
0
   }
4312
#ifdef WOLFSSL_SMALL_STACK_CACHE
4313
   R->key = NULL;
4314
   ecc_key_tmp_final(key, heap);
4315
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
4316
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4317
4318
0
   return err;
4319
0
}
4320
#else
4321
{
4322
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4323
       return ECC_BAD_ARG_E;
4324
   }
4325
   if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus))) {
4326
       return ECC_OUT_OF_RANGE_E;
4327
   }
4328
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4329
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4330
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4331
       return IS_POINT_E;
4332
   }
4333
4334
   (void)a;
4335
   (void)order;
4336
   (void)rng;
4337
4338
#ifdef WOLFSSL_HAVE_SP_ECC
4339
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4340
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4341
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4342
   }
4343
#endif
4344
#ifndef WOLFSSL_SP_NO_256
4345
   if (mp_count_bits(modulus) == 256) {
4346
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4347
   }
4348
#endif
4349
#ifdef WOLFSSL_SP_384
4350
   if (mp_count_bits(modulus) == 384) {
4351
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4352
   }
4353
#endif
4354
#ifdef WOLFSSL_SP_521
4355
   if (mp_count_bits(modulus) == 521) {
4356
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4357
   }
4358
#endif
4359
#else
4360
   (void)map;
4361
   (void)heap;
4362
#endif
4363
   return ECC_BAD_ARG_E;
4364
}
4365
#endif /* !WOLFSSL_SP_MATH */
4366
#endif /* !FP_ECC */
4367
4368
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4369
4370
/** ECC Fixed Point mulmod global
4371
    k        The multiplicand
4372
    G        Base point to multiply
4373
    R        [out] Destination of product
4374
    a        ECC curve parameter a
4375
    modulus  The modulus for the curve
4376
    map      [boolean] If non-zero maps the point back to affine coordinates,
4377
             otherwise it's left in jacobian-montgomery form
4378
    return MP_OKAY if successful
4379
*/
4380
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4381
                  mp_int* modulus, int map)
4382
0
{
4383
0
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4384
0
        mp_zero(R->x);
4385
0
        mp_zero(R->y);
4386
0
        mp_set(R->z, 1);
4387
0
        return MP_OKAY;
4388
0
    }
4389
0
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4390
0
}
4391
4392
#endif
4393
4394
/**
4395
 * Allocate a new ECC point (if one not provided)
4396
 * use a heap hint when creating new ecc_point
4397
 * @return 0 on success
4398
 * @return BAD_FUNC_ARG for invalid arguments
4399
 * @return MEMORY_E on failure to allocate memory
4400
*/
4401
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4402
0
{
4403
0
   int err = MP_OKAY;
4404
0
   ecc_point* p;
4405
4406
0
   if (point == NULL) {
4407
0
       return BAD_FUNC_ARG;
4408
0
   }
4409
4410
0
   p = *point;
4411
0
   if (p == NULL) {
4412
0
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4413
0
   }
4414
0
   if (p == NULL) {
4415
0
      return MEMORY_E;
4416
0
   }
4417
0
   XMEMSET(p, 0, sizeof(ecc_point));
4418
4419
0
   if (*point == NULL)
4420
0
       p->isAllocated = 1;
4421
4422
0
#ifndef ALT_ECC_SIZE
4423
0
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4424
0
   if (err != MP_OKAY) {
4425
0
      WOLFSSL_MSG("mp_init_multi failed.");
4426
0
      if (p->isAllocated)
4427
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4428
0
      p = NULL;
4429
0
   }
4430
#else
4431
   p->x = (mp_int*)&p->xyz[0];
4432
   p->y = (mp_int*)&p->xyz[1];
4433
   p->z = (mp_int*)&p->xyz[2];
4434
   alt_fp_init(p->x);
4435
   alt_fp_init(p->y);
4436
   alt_fp_init(p->z);
4437
#endif
4438
4439
0
   *point = p;
4440
0
   (void)heap;
4441
0
   return err;
4442
0
} /* wc_ecc_new_point_ex */
4443
4444
ecc_point* wc_ecc_new_point_h(void* heap)
4445
0
{
4446
0
    ecc_point* p = NULL;
4447
0
    (void)wc_ecc_new_point_ex(&p, heap);
4448
0
    return p;
4449
0
}
4450
4451
ecc_point* wc_ecc_new_point(void)
4452
0
{
4453
0
   ecc_point* p = NULL;
4454
0
   (void)wc_ecc_new_point_ex(&p, NULL);
4455
0
   return p;
4456
0
}
4457
4458
/** Free an ECC point from memory
4459
  p   The point to free
4460
*/
4461
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4462
0
{
4463
0
   if (p != NULL) {
4464
0
      mp_clear(p->x);
4465
0
      mp_clear(p->y);
4466
0
      mp_clear(p->z);
4467
0
      if (p->isAllocated)
4468
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4469
0
   }
4470
0
   (void)heap;
4471
0
}
4472
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4473
0
{
4474
0
   wc_ecc_del_point_ex(p, heap);
4475
0
}
4476
void wc_ecc_del_point(ecc_point* p)
4477
0
{
4478
0
    wc_ecc_del_point_ex(p, NULL);
4479
0
}
4480
4481
void wc_ecc_forcezero_point(ecc_point* p)
4482
0
{
4483
0
    if (p != NULL) {
4484
0
        mp_forcezero(p->x);
4485
0
        mp_forcezero(p->y);
4486
0
        mp_forcezero(p->z);
4487
0
    }
4488
0
}
4489
4490
4491
/** Copy the value of a point to an other one
4492
  p    The point to copy
4493
  r    The created point
4494
*/
4495
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4496
0
{
4497
0
    int ret;
4498
4499
    /* prevents null arguments */
4500
0
    if (p == NULL || r == NULL)
4501
0
        return ECC_BAD_ARG_E;
4502
4503
0
    ret = mp_copy(p->x, r->x);
4504
0
    if (ret != MP_OKAY)
4505
0
        return ret;
4506
0
    ret = mp_copy(p->y, r->y);
4507
0
    if (ret != MP_OKAY)
4508
0
        return ret;
4509
0
    ret = mp_copy(p->z, r->z);
4510
0
    if (ret != MP_OKAY)
4511
0
        return ret;
4512
4513
0
    return MP_OKAY;
4514
0
}
4515
4516
/** Compare the value of a point with an other one
4517
 a    The point to compare
4518
 b    The other point to compare
4519
4520
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4521
 */
4522
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4523
0
{
4524
0
    int ret;
4525
4526
    /* prevents null arguments */
4527
0
    if (a == NULL || b == NULL)
4528
0
        return BAD_FUNC_ARG;
4529
4530
0
    ret = mp_cmp(a->x, b->x);
4531
0
    if (ret != MP_EQ)
4532
0
        return ret;
4533
0
    ret = mp_cmp(a->y, b->y);
4534
0
    if (ret != MP_EQ)
4535
0
        return ret;
4536
0
    ret = mp_cmp(a->z, b->z);
4537
0
    if (ret != MP_EQ)
4538
0
        return ret;
4539
4540
0
    return MP_EQ;
4541
0
}
4542
4543
4544
/** Returns whether an ECC idx is valid or not
4545
  n      The idx number to check
4546
  return 1 if valid, 0 if not
4547
*/
4548
int wc_ecc_is_valid_idx(int n)
4549
830
{
4550
830
   int x;
4551
4552
830
   if (n >= (int)ECC_SET_COUNT)
4553
0
       return 0;
4554
4555
4.98k
   for (x = 0; ecc_sets[x].size != 0; x++)
4556
4.15k
       ;
4557
   /* -1 is a valid index --- indicating that the domain params
4558
      were supplied by the user */
4559
830
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4560
830
      return 1;
4561
830
   }
4562
4563
0
   return 0;
4564
830
}
4565
4566
int wc_ecc_get_curve_idx(int curve_id)
4567
0
{
4568
0
    int curve_idx;
4569
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4570
0
        if (curve_id == ecc_sets[curve_idx].id)
4571
0
            break;
4572
0
    }
4573
0
    if (ecc_sets[curve_idx].size == 0) {
4574
0
        return ECC_CURVE_INVALID;
4575
0
    }
4576
0
    return curve_idx;
4577
0
}
4578
4579
int wc_ecc_get_curve_id(int curve_idx)
4580
0
{
4581
0
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4582
0
        return ecc_sets[curve_idx].id;
4583
0
    }
4584
0
    return ECC_CURVE_INVALID;
4585
0
}
4586
4587
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4588
 *
4589
 * id      curve id, from ecc_curve_id enum in ecc.h
4590
 * return  curve size, from ecc_sets[] on success, negative on error
4591
 */
4592
int wc_ecc_get_curve_size_from_id(int curve_id)
4593
0
{
4594
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4595
0
    if (curve_idx == ECC_CURVE_INVALID)
4596
0
        return ECC_BAD_ARG_E;
4597
0
    return ecc_sets[curve_idx].size;
4598
0
}
4599
4600
/* Returns the curve index that corresponds to a given curve name in
4601
 * ecc_sets[] of ecc.c
4602
 *
4603
 * name    curve name, from ecc_sets[].name in ecc.c
4604
 * return  curve index in ecc_sets[] on success, negative on error
4605
 */
4606
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4607
0
{
4608
0
    int curve_idx;
4609
4610
0
    if (curveName == NULL)
4611
0
        return BAD_FUNC_ARG;
4612
4613
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4614
0
        if (
4615
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4616
0
            ecc_sets[curve_idx].name &&
4617
0
        #endif
4618
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4619
0
            break;
4620
0
        }
4621
0
    }
4622
0
    if (ecc_sets[curve_idx].size == 0) {
4623
0
        WOLFSSL_MSG("ecc_set curve name not found");
4624
0
        return ECC_CURVE_INVALID;
4625
0
    }
4626
0
    return curve_idx;
4627
0
}
4628
4629
/* Returns the curve size that corresponds to a given curve name,
4630
 * as listed in ecc_sets[] of ecc.c.
4631
 *
4632
 * name    curve name, from ecc_sets[].name in ecc.c
4633
 * return  curve size, from ecc_sets[] on success, negative on error
4634
 */
4635
int wc_ecc_get_curve_size_from_name(const char* curveName)
4636
0
{
4637
0
    int curve_idx;
4638
4639
0
    if (curveName == NULL)
4640
0
        return BAD_FUNC_ARG;
4641
4642
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4643
0
    if (curve_idx < 0)
4644
0
        return curve_idx;
4645
4646
0
    return ecc_sets[curve_idx].size;
4647
0
}
4648
4649
/* Returns the curve id that corresponds to a given curve name,
4650
 * as listed in ecc_sets[] of ecc.c.
4651
 *
4652
 * name   curve name, from ecc_sets[].name in ecc.c
4653
 * return curve id, from ecc_sets[] on success, negative on error
4654
 */
4655
int wc_ecc_get_curve_id_from_name(const char* curveName)
4656
0
{
4657
0
    int curve_idx;
4658
4659
0
    if (curveName == NULL)
4660
0
        return BAD_FUNC_ARG;
4661
4662
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4663
0
    if (curve_idx < 0)
4664
0
        return curve_idx;
4665
4666
0
    return ecc_sets[curve_idx].id;
4667
0
}
4668
4669
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4670
 * parameter for equality.
4671
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4672
 * Returns MP_EQ on success, negative on error */
4673
static int wc_ecc_cmp_param(const char* curveParam,
4674
                            const byte* param, word32 paramSz, int encType)
4675
0
{
4676
0
    int err = MP_OKAY;
4677
#ifdef WOLFSSL_SMALL_STACK
4678
    mp_int* a = NULL;
4679
    mp_int* b = NULL;
4680
#else
4681
0
    mp_int  a[1], b[1];
4682
0
#endif
4683
4684
0
    if (param == NULL || curveParam == NULL)
4685
0
        return BAD_FUNC_ARG;
4686
4687
0
    if (encType == WC_TYPE_HEX_STR) {
4688
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4689
0
            return -1;
4690
0
        return (XSTRNCMP(curveParam, (const char*) param, paramSz) == 0)
4691
0
            ? 0 : -1;
4692
0
    }
4693
4694
#ifdef WOLFSSL_SMALL_STACK
4695
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4696
    if (a == NULL)
4697
        return MEMORY_E;
4698
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4699
    if (b == NULL) {
4700
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4701
        return MEMORY_E;
4702
    }
4703
#endif
4704
4705
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4706
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4707
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4708
0
        return err;
4709
0
    }
4710
4711
0
    if (err == MP_OKAY) {
4712
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4713
0
    }
4714
0
    if (err == MP_OKAY)
4715
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4716
4717
0
    if (err == MP_OKAY) {
4718
0
        if (mp_cmp(a, b) != MP_EQ) {
4719
0
            err = -1;
4720
0
        } else {
4721
0
            err = MP_EQ;
4722
0
        }
4723
0
    }
4724
4725
0
    mp_clear(a);
4726
0
    mp_clear(b);
4727
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4728
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4729
4730
0
    return err;
4731
0
}
4732
4733
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4734
 * curve parameters.
4735
 *
4736
 * fieldSize  the field size in bits
4737
 * prime      prime of the finite field
4738
 * primeSz    size of prime in octets
4739
 * Af         first coefficient a of the curve
4740
 * AfSz       size of Af in octets
4741
 * Bf         second coefficient b of the curve
4742
 * BfSz       size of Bf in octets
4743
 * order      curve order
4744
 * orderSz    size of curve in octets
4745
 * Gx         affine x coordinate of base point
4746
 * GxSz       size of Gx in octets
4747
 * Gy         affine y coordinate of base point
4748
 * GySz       size of Gy in octets
4749
 * cofactor   curve cofactor
4750
 *
4751
 * return curve id, from ecc_sets[] on success, negative on error
4752
 */
4753
int wc_ecc_get_curve_id_from_params(int fieldSize,
4754
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4755
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4756
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4757
0
{
4758
0
    int idx;
4759
0
    int curveSz;
4760
4761
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4762
0
        Gx == NULL || Gy == NULL)
4763
0
        return BAD_FUNC_ARG;
4764
4765
0
    if (fieldSize <= 0)
4766
0
        return ECC_CURVE_INVALID;
4767
4768
0
    curveSz = (int)WC_BITS_TO_BYTES((word32)fieldSize);
4769
4770
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4771
0
        if (curveSz == ecc_sets[idx].size) {
4772
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4773
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4774
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4775
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4776
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4777
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4778
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4779
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4780
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4781
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4782
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4783
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4784
0
                (cofactor == ecc_sets[idx].cofactor)) {
4785
0
                    break;
4786
0
            }
4787
0
        }
4788
0
    }
4789
4790
0
    if (ecc_sets[idx].size == 0)
4791
0
        return ECC_CURVE_INVALID;
4792
4793
0
    return ecc_sets[idx].id;
4794
0
}
4795
4796
/* Returns the curve id in ecc_sets[] that corresponds
4797
 * to a given domain parameters pointer.
4798
 *
4799
 * dp   domain parameters pointer
4800
 *
4801
 * return curve id, from ecc_sets[] on success, negative on error
4802
 */
4803
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4804
0
{
4805
0
    int idx;
4806
4807
0
    if (dp == NULL
4808
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4809
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4810
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4811
0
    #endif
4812
0
    ) {
4813
0
        return BAD_FUNC_ARG;
4814
0
    }
4815
4816
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4817
0
        if (dp->size == ecc_sets[idx].size) {
4818
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4819
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4820
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4821
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4822
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4823
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4824
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4825
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4826
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4827
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4828
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4829
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4830
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4831
0
                    break;
4832
0
            }
4833
0
        }
4834
0
    }
4835
4836
0
    if (ecc_sets[idx].size == 0)
4837
0
        return ECC_CURVE_INVALID;
4838
4839
0
    return ecc_sets[idx].id;
4840
0
}
4841
4842
/* Returns the curve id that corresponds to a given OID,
4843
 * as listed in ecc_sets[] of ecc.c.
4844
 *
4845
 * oid   OID, from ecc_sets[].name in ecc.c
4846
 * len   OID len, from ecc_sets[].name in ecc.c
4847
 * return curve id, from ecc_sets[] on success, negative on error
4848
 */
4849
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4850
0
{
4851
0
    int curve_idx;
4852
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4853
    int ret;
4854
    #ifdef HAVE_OID_DECODING
4855
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4856
    #else
4857
    byte  decOid[MAX_OID_SZ];
4858
    #endif
4859
    word32 decOidSz;
4860
#endif
4861
4862
0
    if (oid == NULL)
4863
0
        return BAD_FUNC_ARG;
4864
4865
#ifdef HAVE_OID_DECODING
4866
    /* in elements, not bytes */
4867
    decOidSz = (word32)(sizeof(decOid) / sizeof(decOid[0]));
4868
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4869
    if (ret != 0) {
4870
        return ret;
4871
    }
4872
#endif
4873
4874
0
    if (len == 0) {
4875
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4876
0
        WOLFSSL_MSG("zero oidSz");
4877
0
        return ECC_CURVE_INVALID;
4878
0
    }
4879
4880
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4881
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4882
        decOidSz = (word32)sizeof(decOid);
4883
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4884
            decOid, &decOidSz);
4885
        if (ret != 0) {
4886
            continue;
4887
        }
4888
    #endif
4889
4890
0
        if (
4891
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4892
0
            ecc_sets[curve_idx].oid &&
4893
0
        #endif
4894
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4895
            decOidSz == len &&
4896
                XMEMCMP(decOid, oid, len) == 0
4897
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4898
            /* We double because decOidSz is a count of word16 elements. */
4899
            ecc_sets[curve_idx].oidSz == decOidSz &&
4900
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4901
        #else
4902
0
            ecc_sets[curve_idx].oidSz == len &&
4903
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4904
0
        #endif
4905
0
        ) {
4906
0
            break;
4907
0
        }
4908
0
    }
4909
0
    if (ecc_sets[curve_idx].size == 0) {
4910
0
        WOLFSSL_MSG("ecc_set curve name not found");
4911
0
        return ECC_CURVE_INVALID;
4912
0
    }
4913
4914
0
    return ecc_sets[curve_idx].id;
4915
0
}
4916
4917
/* Get curve parameters using curve index */
4918
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4919
830
{
4920
830
    const ecc_set_type* ecc_set = NULL;
4921
4922
830
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4923
830
        ecc_set = &ecc_sets[curve_idx];
4924
830
    }
4925
830
    return ecc_set;
4926
830
}
4927
4928
4929
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4930
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4931
{
4932
   if (key == NULL || mp == NULL)
4933
      return BAD_FUNC_ARG;
4934
   if (*mp == NULL) {
4935
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4936
      if (*mp == NULL) {
4937
         return MEMORY_E;
4938
      }
4939
      XMEMSET(*mp, 0, sizeof(mp_int));
4940
   }
4941
   return 0;
4942
}
4943
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4944
{
4945
   if (key && mp && *mp) {
4946
      mp_clear(*mp);
4947
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4948
      *mp = NULL;
4949
   }
4950
}
4951
4952
static int wc_ecc_alloc_async(ecc_key* key)
4953
{
4954
    int err = wc_ecc_alloc_mpint(key, &key->r);
4955
    if (err == 0)
4956
        err = wc_ecc_alloc_mpint(key, &key->s);
4957
    return err;
4958
}
4959
4960
static void wc_ecc_free_async(ecc_key* key)
4961
{
4962
    wc_ecc_free_mpint(key, &key->r);
4963
    wc_ecc_free_mpint(key, &key->s);
4964
#ifdef HAVE_CAVIUM_V
4965
    wc_ecc_free_mpint(key, &key->e);
4966
    wc_ecc_free_mpint(key, &key->signK);
4967
#endif /* HAVE_CAVIUM_V */
4968
}
4969
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4970
4971
4972
#ifdef HAVE_ECC_DHE
4973
/**
4974
  Create an ECC shared secret between two keys
4975
  private_key      The private ECC key (heap hint based off of private key)
4976
  public_key       The public key
4977
  out              [out] Destination of the shared secret
4978
                         Conforms to EC-DH from ANSI X9.63
4979
  outlen           [in/out] The max size and resulting size of the shared secret
4980
  return           MP_OKAY if successful
4981
*/
4982
WOLFSSL_ABI
4983
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4984
                      word32* outlen)
4985
0
{
4986
0
   int err = 0;
4987
0
   int privateKeyOk = 0;
4988
4989
0
   (void)err;
4990
0
   (void)privateKeyOk;
4991
4992
0
   if (private_key == NULL || public_key == NULL || out == NULL ||
4993
0
                                                            outlen == NULL) {
4994
0
       return BAD_FUNC_ARG;
4995
0
   }
4996
4997
#ifdef WOLF_CRYPTO_CB
4998
    #ifndef WOLF_CRYPTO_CB_FIND
4999
    if (private_key->devId != INVALID_DEVID)
5000
    #endif
5001
    {
5002
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
5003
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5004
            return err;
5005
        /* fall-through when unavailable */
5006
    }
5007
#endif
5008
5009
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5010
    return NO_VALID_DEVID;
5011
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5012
   /* type valid? */
5013
0
   privateKeyOk = private_key->type == ECC_PRIVATEKEY ||
5014
0
                  private_key->type == ECC_PRIVATEKEY_ONLY;
5015
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
5016
      defined(WOLFSSL_SE050_ONLY_KEY_ID)
5017
   /* A SE050 key-id handle can represent a private key even though
5018
    * wc_ecc_use_key_id() only loads the public point into the ecc_key. */
5019
   if (private_key->keyIdSet)
5020
      privateKeyOk = 1;
5021
#endif
5022
0
   if (!privateKeyOk) {
5023
0
      return ECC_BAD_ARG_E;
5024
0
   }
5025
5026
   /* Verify domain params supplied */
5027
0
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
5028
0
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
5029
0
      return ECC_BAD_ARG_E;
5030
0
   }
5031
5032
   /* Verify curve id matches */
5033
0
   if (private_key->dp->id != public_key->dp->id) {
5034
0
      return ECC_BAD_ARG_E;
5035
0
   }
5036
5037
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5038
    defined(WOLFSSL_MICROCHIP_TA100)
5039
   /* For SECP256R1 use hardware */
5040
   if (private_key->dp->id == ECC_SECP256R1 &&
5041
       private_key->slot != ATECC_INVALID_SLOT) {
5042
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
5043
       *outlen = private_key->dp->size;
5044
   }
5045
   else {
5046
      err = NOT_COMPILED_IN;
5047
   }
5048
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5049
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
5050
#elif defined(WOLFSSL_KCAPI_ECC)
5051
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
5052
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE)
5053
   /* SE050-resident private key uses hardware ECDH; a software private key
5054
    * (keyIdSet == 0, e.g. decoded from DER as in PKCS#7 KARI) has no key in
5055
    * the SE050 to derive with, so it uses the wolfCrypt software
5056
    * implementation. */
5057
   if (private_key->keyIdSet)
5058
       err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
5059
   else
5060
   #ifdef WOLFSSL_NO_ECC_SW
5061
       /* No software ECDH compiled in, so there is nothing to fall back to. */
5062
       err = NOT_COMPILED_IN;
5063
   #else
5064
       err = ecc_shared_secret_point(private_key, &public_key->pubkey, out,
5065
                                     outlen, 0);
5066
   #endif
5067
#else
5068
   /* No point check: the key got whatever its import ran, in full under
5069
    * WOLFSSL_VALIDATE_ECC_IMPORT. */
5070
0
   err = ecc_shared_secret_point(private_key, &public_key->pubkey, out, outlen,
5071
0
                                 0);
5072
0
#endif /* WOLFSSL_ATECC508A */
5073
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
5074
5075
0
   return err;
5076
0
}
5077
5078
5079
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5080
    !defined(WOLFSSL_MICROCHIP_TA100) && \
5081
    !defined(WOLFSSL_KCAPI_ECC) && \
5082
    !defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLFSSL_NO_ECC_SW)
5083
5084
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
5085
                               byte* out, word32* outlen)
5086
0
{
5087
0
    int err = MP_OKAY;
5088
0
    mp_int* k = ecc_get_k(private_key);
5089
#ifdef WOLFSSL_SE050
5090
    /* A key-id handle holds no software private scalar - ECDH for such a key
5091
     * runs on the SE050 - so the identity this function computes from the
5092
     * all-zero scalar is not a shared secret and must not be rejected here. */
5093
    int checkInf = !private_key->keyIdSet;
5094
#else
5095
0
    int checkInf = 1;
5096
0
#endif
5097
#ifdef HAVE_ECC_CDH
5098
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
5099
#endif
5100
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5101
    defined(WC_ECC_NONBLOCK_ONLY)
5102
    ecc_nb_ctx_t nb_ctx;
5103
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5104
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5105
5106
#ifdef HAVE_ECC_CDH
5107
    /* if cofactor flag has been set */
5108
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
5109
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
5110
        /* only perform cofactor calc if not equal to 1 */
5111
        if (cofactor != 1) {
5112
#ifdef WOLFSSL_SMALL_STACK
5113
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
5114
                return MEMORY_E;
5115
#endif
5116
            k = k_lcl;
5117
            if (mp_init(k) != MP_OKAY) {
5118
                err = MEMORY_E;
5119
                goto errout;
5120
            }
5121
            /* multiply cofactor times private key "k" */
5122
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
5123
            if (err != MP_OKAY)
5124
                goto errout;
5125
        }
5126
    }
5127
#endif
5128
5129
#ifdef WOLFSSL_HAVE_SP_ECC
5130
5131
#ifndef WOLFSSL_SP_NO_256
5132
    if (private_key->idx != ECC_CUSTOM_IDX &&
5133
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
5134
    #ifndef WC_ECC_NONBLOCK
5135
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
5136
    #else
5137
        if (private_key->nb_ctx) {
5138
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
5139
                                           point, out, outlen,
5140
                                           private_key->heap);
5141
        }
5142
        else {
5143
        #ifdef WC_ECC_NONBLOCK_ONLY
5144
            do { /* perform blocking call to non-blocking function */
5145
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
5146
                                               outlen, private_key->heap);
5147
            } while (err == FP_WOULDBLOCK);
5148
        #else
5149
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
5150
                                        private_key->heap);
5151
        #endif /* WC_ECC_NONBLOCK_ONLY */
5152
        }
5153
    #endif /* !WC_ECC_NONBLOCK */
5154
    }
5155
    else
5156
#endif /* ! WOLFSSL_SP_NO_256 */
5157
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5158
    if (private_key->idx != ECC_CUSTOM_IDX &&
5159
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
5160
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
5161
                                                             private_key->heap);
5162
    }
5163
    else
5164
#endif
5165
#ifdef WOLFSSL_SP_384
5166
    if (private_key->idx != ECC_CUSTOM_IDX &&
5167
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
5168
    #ifndef WC_ECC_NONBLOCK
5169
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
5170
    #else
5171
        if (private_key->nb_ctx) {
5172
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
5173
                                           point, out, outlen,
5174
                                           private_key->heap);
5175
        }
5176
        else {
5177
        #ifdef WC_ECC_NONBLOCK_ONLY
5178
            do { /* perform blocking call to non-blocking function */
5179
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
5180
                                               outlen, private_key->heap);
5181
            } while (err == FP_WOULDBLOCK);
5182
        #else
5183
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
5184
                                        private_key->heap);
5185
        #endif /* WC_ECC_NONBLOCK_ONLY */
5186
        }
5187
    #endif /* !WC_ECC_NONBLOCK */
5188
    }
5189
    else
5190
#endif /* WOLFSSL_SP_384 */
5191
#ifdef WOLFSSL_SP_521
5192
    if (private_key->idx != ECC_CUSTOM_IDX &&
5193
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
5194
    #ifndef WC_ECC_NONBLOCK
5195
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
5196
    #else
5197
        if (private_key->nb_ctx) {
5198
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
5199
                                           point, out, outlen,
5200
                                           private_key->heap);
5201
        }
5202
        else {
5203
        #ifdef WC_ECC_NONBLOCK_ONLY
5204
            do { /* perform blocking call to non-blocking function */
5205
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
5206
                                               outlen, private_key->heap);
5207
            } while (err == FP_WOULDBLOCK);
5208
        #else
5209
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
5210
                                        private_key->heap);
5211
        #endif /* WC_ECC_NONBLOCK_ONLY */
5212
        }
5213
    #endif /* !WC_ECC_NONBLOCK */
5214
    }
5215
    else
5216
#endif /* WOLFSSL_SP_521 */
5217
#else
5218
0
    (void)point;
5219
0
    (void)out;
5220
0
    (void)outlen;
5221
0
    (void)k;
5222
0
#endif
5223
#if defined(WOLFSSL_SP_MATH)
5224
    {
5225
        (void)checkInf;
5226
        err = WC_KEY_SIZE_E;
5227
        goto errout;
5228
    }
5229
#else
5230
0
    {
5231
0
        ecc_point* result = NULL;
5232
        #ifdef WOLFSSL_NO_MALLOC
5233
        ecc_point  lcl_result;
5234
        #endif
5235
0
        int x = 0;
5236
0
        mp_digit mp = 0;
5237
0
        DECLARE_CURVE_SPECS(3);
5238
5239
        /* load curve info */
5240
0
        ALLOC_CURVE_SPECS(3, err);
5241
0
        if (err == MP_OKAY) {
5242
0
            err = wc_ecc_curve_load(private_key->dp, &curve,
5243
0
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5244
0
                 ECC_CURVE_FIELD_ORDER));
5245
0
        }
5246
5247
0
        if (err != MP_OKAY) {
5248
0
            FREE_CURVE_SPECS();
5249
0
            goto errout;
5250
0
        }
5251
5252
        /* make new point */
5253
    #ifdef WOLFSSL_NO_MALLOC
5254
        result = &lcl_result;
5255
    #endif
5256
0
        err = wc_ecc_new_point_ex(&result, private_key->heap);
5257
0
        if (err != MP_OKAY) {
5258
0
            wc_ecc_curve_free(curve);
5259
0
            FREE_CURVE_SPECS();
5260
0
            goto errout;
5261
0
        }
5262
5263
0
#ifdef ECC_TIMING_RESISTANT
5264
0
        if (private_key->rng == NULL) {
5265
0
            err = MISSING_RNG_E;
5266
0
        }
5267
0
#endif
5268
5269
0
        if (err == MP_OKAY) {
5270
            /* Map in a separate call as this should be constant time */
5271
0
#ifdef ECC_TIMING_RESISTANT
5272
0
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5273
0
                                              curve->order, private_key->rng, 0,
5274
0
                                              private_key->heap);
5275
#else
5276
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5277
                                      curve->order, NULL, 0, private_key->heap);
5278
#endif
5279
0
        }
5280
0
        if (err == MP_OKAY) {
5281
        #ifdef WOLFSSL_CHECK_MEM_ZERO
5282
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
5283
                result->x);
5284
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
5285
                result->y);
5286
        #endif
5287
0
            err = mp_montgomery_setup(curve->prime, &mp);
5288
0
        }
5289
0
        if (err == MP_OKAY) {
5290
            /* Use constant time map if compiled in */
5291
0
            err = ecc_map_ex(result, curve->prime, mp, 1);
5292
0
        }
5293
0
        if (err == MP_OKAY) {
5294
            /* SP 800-56Ar3 5.7.1.2: the shared secret must not be the point at
5295
             * infinity. ecc_map_ex reports that case as x, y of zero with a
5296
             * success code, so check the point explicitly. */
5297
0
            if (checkInf && wc_ecc_point_is_at_infinity(result)) {
5298
0
                err = ECC_INF_E;
5299
0
            }
5300
0
        }
5301
0
        if (err == MP_OKAY) {
5302
0
            x = mp_unsigned_bin_size(curve->prime);
5303
0
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
5304
0
                err = BUFFER_E;
5305
0
            }
5306
0
        }
5307
5308
0
        if (err == MP_OKAY) {
5309
0
            XMEMSET(out, 0, (size_t)x);
5310
0
            err = mp_to_unsigned_bin(result->x, out +
5311
0
                                     (x - mp_unsigned_bin_size(result->x)));
5312
0
        }
5313
0
        *outlen = (word32)x;
5314
5315
0
        mp_forcezero(result->x);
5316
0
        mp_forcezero(result->y);
5317
0
        wc_ecc_del_point_ex(result, private_key->heap);
5318
5319
0
        wc_ecc_curve_free(curve);
5320
0
        FREE_CURVE_SPECS();
5321
0
    }
5322
0
#endif
5323
5324
#ifdef WOLFSSL_HAVE_SP_ECC
5325
    if ((err == MP_OKAY) && checkInf) {
5326
        /* The single precision implementations above serialize the point at
5327
         * infinity as an all-zero x-coordinate and report success, so the
5328
         * identity has to be recognized from the output. SP 800-56Ar3 5.7.1.2
5329
         * requires an error and stop in that case. Accumulate over the whole
5330
         * buffer so the scan does not branch on the secret. */
5331
        word32 i;
5332
        byte   acc = 0;
5333
5334
        for (i = 0; i < *outlen; i++) {
5335
            acc |= out[i];
5336
        }
5337
        if (acc == 0) {
5338
            err = ECC_INF_E;
5339
        }
5340
    }
5341
#endif
5342
5343
0
  errout:
5344
5345
#ifdef HAVE_ECC_CDH
5346
    if (k == k_lcl)
5347
        mp_forcezero(k);
5348
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
5349
#endif
5350
#ifdef WC_ECC_NONBLOCK
5351
    /* An incomplete operation still needs k. */
5352
    if (err != FP_WOULDBLOCK)
5353
#endif
5354
0
    {
5355
0
        ecc_put_k(private_key);
5356
0
    }
5357
5358
0
    return err;
5359
0
}
5360
5361
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5362
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
5363
            ecc_point* point, byte* out, word32 *outlen)
5364
{
5365
    int err = 0;
5366
5367
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5368
    DECLARE_CURVE_SPECS(3);
5369
5370
    /* load curve info */
5371
    ALLOC_CURVE_SPECS(3, err);
5372
    if (err == MP_OKAY) {
5373
        err = wc_ecc_curve_load(private_key->dp, &curve,
5374
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5375
             ECC_CURVE_FIELD_ORDER));
5376
    }
5377
5378
    if (err != MP_OKAY) {
5379
        FREE_CURVE_SPECS();
5380
        return err;
5381
    }
5382
5383
    if (private_key->dp
5384
    #ifdef WOLFSSL_CUSTOM_CURVES
5385
        && private_key->dp->id != ECC_CURVE_CUSTOM
5386
    #endif
5387
    #ifdef HAVE_CAVIUM_V
5388
        /* verify the curve is supported by hardware */
5389
        && NitroxEccIsCurveSupported(private_key)
5390
    #endif
5391
    ) {
5392
        word32 keySz = private_key->dp->size;
5393
5394
        /* sync public key x/y */
5395
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5396
            &ecc_get_k(private_key)->raw, keySz);
5397
        if (err == MP_OKAY)
5398
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5399
        if (err == MP_OKAY)
5400
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5401
    #ifdef HAVE_CAVIUM_V
5402
        /* allocate buffer for output */
5403
        if (err == MP_OKAY)
5404
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5405
        if (err == MP_OKAY)
5406
            err = wc_bigint_alloc(&private_key->e->raw,
5407
                NitroxEccGetSize(private_key)*2);
5408
        if (err == MP_OKAY)
5409
            err = NitroxEcdh(private_key,
5410
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5411
                private_key->e->raw.buf, &private_key->e->raw.len,
5412
                &curve->prime->raw);
5413
    #else
5414
        if (err == MP_OKAY)
5415
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5416
        if (err == MP_OKAY)
5417
            err = IntelQaEcdh(&private_key->asyncDev,
5418
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5419
                out, outlen,
5420
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5421
                private_key->dp->cofactor);
5422
    #endif
5423
    }
5424
    else
5425
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5426
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5427
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5428
        sw->eccSharedSec.private_key = private_key;
5429
        sw->eccSharedSec.public_point = point;
5430
        sw->eccSharedSec.out = out;
5431
        sw->eccSharedSec.outLen = outlen;
5432
        err = WC_PENDING_E;
5433
    }
5434
    else
5435
#endif
5436
    {
5437
        /* use sync in other cases */
5438
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5439
    }
5440
5441
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5442
        private_key->state++;
5443
    }
5444
5445
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5446
    wc_ecc_curve_free(curve);
5447
    FREE_CURVE_SPECS();
5448
#endif
5449
5450
    return err;
5451
}
5452
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5453
5454
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5455
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
5456
/* Full public key validation of a peer point through wc_ecc_check_key,
5457
 * SP 800-56Ar3 5.6.2.3.3. */
5458
static int ecc_check_peer_point(ecc_key* key, ecc_point* point)
5459
0
{
5460
0
    int err;
5461
0
    WC_DECLARE_VAR(peer, ecc_key, 1, key->heap);
5462
5463
0
    WC_ALLOC_VAR_EX(peer, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
5464
0
                    return MEMORY_E);
5465
0
    err = wc_ecc_init_ex(peer, key->heap, INVALID_DEVID);
5466
0
    if (err == MP_OKAY) {
5467
    #ifdef WOLFSSL_CUSTOM_CURVES
5468
        if (key->idx == ECC_CUSTOM_IDX)
5469
            err = wc_ecc_set_custom_curve(peer, key->dp);
5470
        else
5471
    #endif
5472
0
            err = wc_ecc_set_curve(peer, key->dp->size, key->dp->id);
5473
0
        if (err == MP_OKAY)
5474
0
            err = wc_ecc_copy_point(point, &peer->pubkey);
5475
0
        if (err == MP_OKAY) {
5476
0
            peer->type = ECC_PUBLICKEY;
5477
0
            err = wc_ecc_check_key(peer);
5478
0
        }
5479
0
        wc_ecc_free(peer);
5480
0
    }
5481
0
    WC_FREE_VAR_EX(peer, key->heap, DYNAMIC_TYPE_ECC);
5482
0
    return err;
5483
0
}
5484
#else
5485
/* wc_ecc_check_key checks nothing in this build: still reject the identity,
5486
 * out of range and off-curve points, SP 800-56Ar3 5.6.2.3.4. */
5487
static int ecc_check_peer_point(ecc_key* key, ecc_point* point)
5488
{
5489
    int err;
5490
    DECLARE_CURVE_SPECS(3);
5491
5492
    if (wc_ecc_point_is_at_infinity(point))
5493
        return ECC_INF_E;
5494
    ALLOC_CURVE_SPECS(3, err);
5495
    if (err == MP_OKAY) {
5496
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
5497
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_BF));
5498
    }
5499
    if (err == MP_OKAY)
5500
        err = wc_ecc_is_point(point, curve->Af, curve->Bf, curve->prime);
5501
    wc_ecc_curve_free(curve);
5502
    FREE_CURVE_SPECS();
5503
    return err;
5504
}
5505
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
5506
5507
/* checkPoint is 0 only for a public key that went through key import. */
5508
static int ecc_shared_secret_point(ecc_key* private_key, ecc_point* point,
5509
                                   byte* out, word32* outlen, int checkPoint)
5510
0
{
5511
0
    int err;
5512
5513
0
    if (private_key == NULL || point == NULL || out == NULL ||
5514
0
                                                            outlen == NULL) {
5515
0
        return BAD_FUNC_ARG;
5516
0
    }
5517
5518
    /* type valid? */
5519
0
    if (private_key->type != ECC_PRIVATEKEY &&
5520
0
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5521
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5522
0
        return ECC_BAD_ARG_E;
5523
0
    }
5524
5525
    /* Verify domain params supplied */
5526
0
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5527
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5528
0
        return ECC_BAD_ARG_E;
5529
0
    }
5530
5531
0
    if (checkPoint && private_key->state == ECC_STATE_NONE) {
5532
0
        err = ecc_check_peer_point(private_key, point);
5533
0
        if (err != MP_OKAY)
5534
0
            return err;
5535
0
    }
5536
5537
0
    switch (private_key->state) {
5538
0
        case ECC_STATE_NONE:
5539
0
        case ECC_STATE_SHARED_SEC_GEN:
5540
0
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5541
5542
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5543
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5544
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5545
                    out, outlen);
5546
            }
5547
            else
5548
        #endif
5549
0
            {
5550
0
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5551
0
                    out, outlen);
5552
0
            }
5553
0
            if (err < 0) {
5554
0
                break;
5555
0
            }
5556
0
            FALL_THROUGH;
5557
5558
0
        case ECC_STATE_SHARED_SEC_RES:
5559
0
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5560
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5561
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5562
            #ifdef HAVE_CAVIUM_V
5563
                /* verify the curve is supported by hardware */
5564
                if (NitroxEccIsCurveSupported(private_key)) {
5565
                    /* copy output */
5566
                    *outlen = private_key->dp->size;
5567
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5568
                }
5569
            #endif /* HAVE_CAVIUM_V */
5570
            }
5571
        #endif /* WOLFSSL_ASYNC_CRYPT */
5572
0
            err = 0;
5573
0
            break;
5574
5575
0
        default:
5576
0
            err = BAD_STATE_E;
5577
0
    } /* switch */
5578
5579
    /* if async pending or non-blocking then return and skip done cleanup below
5580
     * so the peer point is checked once per operation, not once per call */
5581
0
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)
5582
    #ifdef WC_ECC_NONBLOCK
5583
            || err == WC_NO_ERR_TRACE(MP_WOULDBLOCK)
5584
    #endif
5585
0
            ) {
5586
0
        return err;
5587
0
    }
5588
5589
    /* cleanup */
5590
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5591
    wc_ecc_free_async(private_key);
5592
#endif
5593
0
    private_key->state = ECC_STATE_NONE;
5594
5595
0
    return err;
5596
0
}
5597
5598
/**
5599
 Create an ECC shared secret between private key and public point
5600
 private_key      The private ECC key (heap hint based on private key)
5601
 point            The point to use (public key), fully validated here
5602
 out              [out] Destination of the shared secret
5603
                        Conforms to EC-DH from ANSI X9.63
5604
 outlen           [in/out] The max size and resulting size of the shared secret
5605
 return           MP_OKAY if successful
5606
*/
5607
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5608
                            byte* out, word32 *outlen)
5609
0
{
5610
0
    return ecc_shared_secret_point(private_key, point, out, outlen, 1);
5611
0
}
5612
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5613
#elif defined(WOLFSSL_KCAPI_ECC)
5614
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5615
                            byte* out, word32 *outlen)
5616
{
5617
    int err;
5618
    WC_DECLARE_VAR(public_key, ecc_key, 1,
5619
                   private_key ? private_key->heap : NULL);
5620
5621
    WC_ALLOC_VAR_EX(public_key, ecc_key, 1, private_key->heap, DYNAMIC_TYPE_ECC,
5622
                    return MEMORY_E);
5623
5624
    err = wc_ecc_init_ex(public_key, private_key->heap, INVALID_DEVID);
5625
    if (err == MP_OKAY) {
5626
        #if FIPS_VERSION3_GE(6,0,0)
5627
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5628
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5629
         * keysize here when relying on default selection */
5630
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5631
            if (private_key->dp->size == 0 &&
5632
                (private_key->dp->id == ECC_SECP256R1 ||
5633
                private_key->dp->id == ECC_SECP224R1 ||
5634
                private_key->dp->id == ECC_SECP384R1 ||
5635
                private_key->dp->id == ECC_SECP521R1)) {
5636
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5637
                err = 0;
5638
            } else {
5639
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5640
                err = ECC_CURVE_OID_E;
5641
            }
5642
        }
5643
        if (err == 0) { /* FIPS specific check */
5644
        #endif
5645
        err = wc_ecc_set_curve(public_key, private_key->dp->size,
5646
                               private_key->dp->id);
5647
        if (err == MP_OKAY) {
5648
            err = mp_copy(point->x, public_key->pubkey.x);
5649
        }
5650
        #if FIPS_VERSION3_GE(6,0,0)
5651
        } /* end FIPS specific check */
5652
        #endif
5653
        if (err == MP_OKAY) {
5654
            err = mp_copy(point->y, public_key->pubkey.y);
5655
        }
5656
        if (err == MP_OKAY) {
5657
            err = wc_ecc_shared_secret(private_key, public_key, out, outlen);
5658
        }
5659
5660
        wc_ecc_free(public_key);
5661
    }
5662
5663
    WC_FREE_VAR_EX(public_key, private_key->heap, DYNAMIC_TYPE_ECC);
5664
    return err;
5665
}
5666
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_KCAPI_ECC */
5667
#endif /* HAVE_ECC_DHE */
5668
5669
/* Checks if a point p lies on the curve with index curve_idx */
5670
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5671
830
{
5672
830
    int err = MP_OKAY;
5673
830
    DECLARE_CURVE_SPECS(3);
5674
5675
830
    if (p == NULL)
5676
0
        return BAD_FUNC_ARG;
5677
5678
    /* is the IDX valid ?  */
5679
830
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5680
0
       return ECC_BAD_ARG_E;
5681
0
    }
5682
5683
830
    ALLOC_CURVE_SPECS(3, err);
5684
830
    if (err == MP_OKAY) {
5685
830
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5686
830
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5687
830
                                ECC_CURVE_FIELD_BF);
5688
830
    }
5689
5690
830
    if (err == MP_OKAY) {
5691
830
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5692
830
    }
5693
5694
830
    wc_ecc_curve_free(curve);
5695
830
    FREE_CURVE_SPECS();
5696
5697
830
    return err;
5698
830
}
5699
5700
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5701
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5702
      defined(WOLFSSL_IMXRT1170_CAAM))
5703
/* Deliberately not excluded under WOLFSSL_NO_ECC_SW: this is two mp_iszero()
5704
 * calls, not curve arithmetic, and the untrusted public key validation below
5705
 * needs it. */
5706
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5707
int wc_ecc_point_is_at_infinity(ecc_point* p)
5708
831
{
5709
831
    if (p == NULL)
5710
0
        return BAD_FUNC_ARG;
5711
831
    if (mp_iszero(p->x) && mp_iszero(p->y))
5712
1
        return 1;
5713
5714
830
    return 0;
5715
831
}
5716
#endif
5717
5718
/* generate random and ensure its greater than 0 and less than order */
5719
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5720
0
{
5721
0
#ifndef WC_NO_RNG
5722
0
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5723
0
    int err;
5724
0
    byte buf[ECC_MAXSIZE_GEN];
5725
0
    DECL_MP_INT_SIZE_DYN(nm1, MAX_ECC_BITS_USE, MAX_ECC_BITS_USE);
5726
5727
0
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5728
0
                                                                order == NULL) {
5729
0
        return BAD_FUNC_ARG;
5730
0
    }
5731
    /* FIPS 186-5 A.4.1 input 2: the order must be at least 2. */
5732
0
    if (mp_cmp_d(order, 1) != MP_GT) {
5733
0
        return BAD_FUNC_ARG;
5734
0
    }
5735
5736
0
    NEW_MP_INT_SIZE(nm1, MAX_ECC_BITS_USE, rng->heap, DYNAMIC_TYPE_ECC);
5737
#ifdef MP_INT_SIZE_CHECK_NULL
5738
    if (nm1 == NULL)
5739
        return MEMORY_E;
5740
#endif
5741
0
    err = INIT_MP_INT_SIZE(nm1, MAX_ECC_BITS_USE);
5742
5743
    /* 8 extra bytes: t >= 64 in FIPS 186-5 A.2.1 step 3 and A.3.1 step 3. */
5744
0
    size += 8;
5745
5746
    /* make up random string */
5747
0
    if (err == MP_OKAY)
5748
0
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5749
#ifdef WOLFSSL_CHECK_MEM_ZERO
5750
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5751
#endif
5752
5753
    /* load random buffer data into k */
5754
0
    if (err == 0)
5755
0
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5756
5757
    /* FIPS 186-5 A.4.1 steps 4-5: k = (k mod (n - 1)) + 1, in [1, n - 1]. */
5758
0
    if (err == MP_OKAY)
5759
0
        err = mp_sub_d(order, 1, nm1);
5760
0
    if (err == MP_OKAY)
5761
0
        err = mp_mod(k, nm1, k);
5762
0
    if (err == MP_OKAY)
5763
0
        err = mp_add_d(k, 1, k);
5764
5765
0
    mp_clear(nm1);
5766
0
    FREE_MP_INT_SIZE(nm1, rng->heap, DYNAMIC_TYPE_ECC);
5767
0
    ForceZero(buf, ECC_MAXSIZE_GEN);
5768
#ifdef WOLFSSL_CHECK_MEM_ZERO
5769
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5770
#endif
5771
5772
0
    return err;
5773
#else
5774
    int err;
5775
    byte buf[ECC_MAXSIZE_GEN];
5776
    int bits;
5777
5778
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5779
            (k == NULL) || (order == NULL)) {
5780
        return BAD_FUNC_ARG;
5781
    }
5782
5783
    /* Get actual bit count of order. */
5784
    bits = mp_count_bits(order);
5785
    size = (bits + 7) >> 3;
5786
5787
    /* generate number in range of order through rejection sampling. */
5788
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5789
    do {
5790
        /* A.2.2 step 3: make up random string */
5791
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5792
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5793
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5794
    #endif
5795
        /* Generated multiple of 8 bits but now make it size of order. */
5796
        if ((bits & 0x7) > 0) {
5797
            buf[0] &= (1 << (bits & 0x7)) - 1;
5798
        }
5799
5800
        /* A.2.2 step 4: convert to integer. */
5801
        /* A.4.2 step 3: Convert the bit string to integer x. */
5802
        if (err == 0) {
5803
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5804
        }
5805
5806
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5807
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5808
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5809
            break;
5810
        }
5811
    }
5812
    while (err == MP_OKAY);
5813
5814
    ForceZero(buf, ECC_MAXSIZE_GEN);
5815
#ifdef WOLFSSL_CHECK_MEM_ZERO
5816
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5817
#endif
5818
5819
    return err;
5820
#endif
5821
#else
5822
    (void)rng;
5823
    (void)size;
5824
    (void)k;
5825
    (void)order;
5826
    return NOT_COMPILED_IN;
5827
#endif /* !WC_NO_RNG */
5828
0
}
5829
5830
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5831
865
{
5832
    /* make sure required key variables are reset */
5833
865
    key->state = ECC_STATE_NONE;
5834
865
}
5835
5836
5837
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
5838
/* compute the public key Q = d*G in software.
5839
 *
5840
 * key    private key holding the scalar d, must be present and in range
5841
 * curve  [in]curve for key, cannot be NULL
5842
 * pub    [out]initialized ecc_point receiving the public key
5843
 * rng    optional RNG for a timing-resistant point multiply, may be NULL
5844
 *
5845
 * returns MP_OKAY on success
5846
 */
5847
static int ecc_make_pub_sw(ecc_key* key, ecc_curve_spec* curve,
5848
        ecc_point* pub, WC_RNG* rng)
5849
0
{
5850
0
    int err = MP_OKAY;
5851
5852
0
    (void)rng;
5853
5854
    /* The private scalar must be in range for the base-point multiply
5855
     * below. */
5856
0
    if (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
5857
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT)) {
5858
0
        err = ECC_PRIV_KEY_E;
5859
0
    }
5860
5861
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5862
    defined(HAVE_INTEL_QA)
5863
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5864
        word32 keySz = key->dp->size;
5865
        /* sync private key to raw */
5866
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5867
        if (err == MP_OKAY) {
5868
            err = IntelQaEccPointMul(&key->asyncDev,
5869
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5870
                &curve->Gx->raw, &curve->Gy->raw,
5871
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5872
                key->dp->cofactor);
5873
        }
5874
    }
5875
    else
5876
#endif
5877
0
    { /* BEGIN: Software Crypto */
5878
#ifdef WOLFSSL_HAVE_SP_ECC
5879
    /* Single-Precision Math (optimized for specific curves) */
5880
    if (err != MP_OKAY) {
5881
    }
5882
    else
5883
#ifndef WOLFSSL_SP_NO_256
5884
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5885
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5886
    }
5887
    else
5888
#endif /* WOLFSSL_SP_NO_256 */
5889
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5890
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5891
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5892
    }
5893
    else
5894
#endif
5895
#ifdef WOLFSSL_SP_384
5896
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5897
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5898
    }
5899
    else
5900
#endif
5901
#ifdef WOLFSSL_SP_521
5902
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5903
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5904
    }
5905
    else
5906
#endif
5907
#endif /* WOLFSSL_HAVE_SP_ECC */
5908
5909
#if defined(WOLFSSL_SP_MATH)
5910
        err = WC_KEY_SIZE_E;
5911
#else
5912
0
    if (err == MP_OKAY) {
5913
        /* Multi-Precision Math: compute public curve */
5914
0
        mp_digit mp = 0;
5915
0
        ecc_point* base = NULL;
5916
    #ifdef WOLFSSL_NO_MALLOC
5917
        ecc_point  lcl_base;
5918
        base = &lcl_base;
5919
    #endif
5920
0
        err = wc_ecc_new_point_ex(&base, key->heap);
5921
5922
        /* read in the x/y for this key */
5923
0
        if (err == MP_OKAY)
5924
0
            err = mp_copy(curve->Gx, base->x);
5925
0
        if (err == MP_OKAY)
5926
0
            err = mp_copy(curve->Gy, base->y);
5927
0
        if (err == MP_OKAY)
5928
0
            err = mp_montgomery_setup(curve->prime, &mp);
5929
0
        if (err == MP_OKAY)
5930
0
            err = mp_set(base->z, 1);
5931
5932
        /* make the public key */
5933
0
        if (err == MP_OKAY) {
5934
            /* Map in a separate call as this should be constant time */
5935
0
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5936
0
                                 curve->prime, curve->order, rng, 0, key->heap);
5937
0
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5938
0
               err = MEMORY_E;
5939
0
            }
5940
0
        }
5941
0
        if (err == MP_OKAY) {
5942
            /* Use constant time map if compiled in */
5943
0
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5944
0
        }
5945
5946
0
        wc_ecc_del_point_ex(base, key->heap);
5947
0
    }
5948
0
#endif /* WOLFSSL_SP_MATH */
5949
0
        ecc_put_k(key);
5950
0
    } /* END: Software Crypto */
5951
5952
0
    return err;
5953
0
}
5954
#endif /* HAVE_ECC_MAKE_PUB && !WOLF_CRYPTO_CB_ONLY_ECC */
5955
5956
/* create the public ECC key from a private key
5957
 *
5958
 * key     an initialized private key to generate public part from
5959
 * curve   [in]curve for key, cannot be NULL
5960
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5961
 *         is cached in key instead.
5962
 *
5963
 * Note this function is local to the file because of the argument type
5964
 *      ecc_curve_spec. Having this argument allows for not having to load the
5965
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5966
 * For async the results are placed directly into pubOut, so this function
5967
 *      does not need to be called again
5968
 *
5969
 * returns MP_OKAY on success
5970
 */
5971
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5972
        ecc_point* pubOut, WC_RNG* rng)
5973
0
{
5974
0
    int err = MP_OKAY;
5975
0
#ifdef HAVE_ECC_MAKE_PUB
5976
0
    ecc_point* pub;
5977
0
    int doneInCb = 0;
5978
0
#endif /* HAVE_ECC_MAKE_PUB */
5979
5980
0
    (void)rng;
5981
5982
0
    if (key == NULL) {
5983
0
        return BAD_FUNC_ARG;
5984
0
    }
5985
5986
0
#ifdef HAVE_ECC_MAKE_PUB
5987
    /* if ecc_point passed in then use it as output for public key point */
5988
0
    if (pubOut != NULL) {
5989
0
        pub = pubOut;
5990
0
    }
5991
0
    else {
5992
        /* caching public key making it a ECC_PRIVATEKEY instead of
5993
           ECC_PRIVATEKEY_ONLY */
5994
0
        pub = &key->pubkey;
5995
0
        key->type = ECC_PRIVATEKEY_ONLY;
5996
0
    }
5997
5998
0
    if (err == MP_OKAY) {
5999
0
    #ifndef ALT_ECC_SIZE
6000
0
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
6001
    #else
6002
        pub->x = (mp_int*)&pub->xyz[0];
6003
        pub->y = (mp_int*)&pub->xyz[1];
6004
        pub->z = (mp_int*)&pub->xyz[2];
6005
        alt_fp_init(pub->x);
6006
        alt_fp_init(pub->y);
6007
        alt_fp_init(pub->z);
6008
    #endif
6009
0
    }
6010
6011
#ifdef WOLF_CRYPTO_CB
6012
    /* offload Q = d*G to the device; fall through to software only when the
6013
     * device reports the operation unavailable.
6014
     *
6015
     * Under WOLF_CRYPTO_CB_FIND the devId gate is dropped so a find callback
6016
     * can route a key initialized with INVALID_DEVID. This helper is also
6017
     * shared by internal callers that compute a point from a transient scalar
6018
     * in key->k - the ECDSA software-sign nonce R = k*G (ecc_sign_hash_sw),
6019
     * keygen public-part derivation, and verify-time public-key recovery.
6020
     * Reaching the software signer means the device already declined to sign
6021
     * (the whole-sign offload wc_CryptoCb_EccSign ran first), so a find
6022
     * callback that hands this make-pub to a device notwithstanding the
6023
     * INVALID_DEVID is expected to likewise decline it. If it does not decline
6024
     * *and* the device ignores key->k (e.g. relying on an internal key
6025
     * representation), it returns d*G instead of the requested k*G and the
6026
     * resulting signature is wrong - but such a scenario is very unlikely. */
6027
    #ifndef WOLF_CRYPTO_CB_FIND
6028
    if ((err == MP_OKAY) && (key->devId != INVALID_DEVID))
6029
    #else
6030
    if (err == MP_OKAY)
6031
    #endif
6032
    {
6033
        err = wc_CryptoCb_EccMakePub(key, pub);
6034
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6035
            doneInCb = 1;
6036
        else
6037
            err = MP_OKAY; /* device declined the offload; fall back */
6038
    }
6039
#endif
6040
6041
0
    if ((err == MP_OKAY) && !doneInCb) {
6042
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6043
        /* software derivation is stripped and no device handled the op;
6044
         * fail closed */
6045
        (void)curve;
6046
        err = NO_VALID_DEVID;
6047
#else
6048
0
        err = ecc_make_pub_sw(key, curve, pub, rng);
6049
0
#endif
6050
0
    }
6051
6052
0
    if (err != MP_OKAY
6053
    #ifdef WOLFSSL_ASYNC_CRYPT
6054
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
6055
    #endif
6056
0
    ) {
6057
        /* clean up if failed */
6058
0
    #ifndef ALT_ECC_SIZE
6059
0
        mp_clear(pub->x);
6060
0
        mp_clear(pub->y);
6061
0
        mp_clear(pub->z);
6062
0
    #endif
6063
0
    }
6064
6065
#else
6066
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
6067
    (void)curve;
6068
    err = NOT_COMPILED_IN;
6069
#endif /* HAVE_ECC_MAKE_PUB */
6070
6071
    /* Change key state if the public part is cached. Only on success: a failed
6072
     * derivation (no software implementation compiled in, no device registered,
6073
     * or the point multiply itself failing) leaves key->pubkey empty, and
6074
     * marking the key ECC_PRIVATEKEY would have a later export or verify
6075
     * consume those empty ordinates. */
6076
0
    if ((err == MP_OKAY
6077
    #ifdef WOLFSSL_ASYNC_CRYPT
6078
         || err == WC_NO_ERR_TRACE(WC_PENDING_E)
6079
    #endif
6080
0
        ) && key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
6081
0
        key->type = ECC_PRIVATEKEY;
6082
0
    }
6083
6084
0
    return err;
6085
0
}
6086
6087
6088
/* create the public ECC key from a private key
6089
 *
6090
 * key     an initialized private key to generate public part from
6091
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
6092
 *         is cached in key instead.
6093
 *
6094
 *
6095
 * returns MP_OKAY on success
6096
 */
6097
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
6098
0
{
6099
0
    WOLFSSL_ENTER("wc_ecc_make_pub");
6100
6101
0
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
6102
0
}
6103
6104
/* create the public ECC key from a private key - mask timing use random z
6105
 *
6106
 * key     an initialized private key to generate public part from
6107
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
6108
 *         is cached in key instead.
6109
 *
6110
 *
6111
 * returns MP_OKAY on success
6112
 */
6113
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
6114
0
{
6115
0
    int err = MP_OKAY;
6116
0
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6117
6118
0
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
6119
6120
0
    if (key == NULL) {
6121
0
        return BAD_FUNC_ARG;
6122
0
    }
6123
6124
    /* load curve info */
6125
0
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6126
0
    if (err == MP_OKAY) {
6127
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6128
0
    }
6129
0
    if (err == MP_OKAY) {
6130
0
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
6131
0
    }
6132
6133
0
    wc_ecc_curve_free(curve);
6134
0
    FREE_CURVE_SPECS();
6135
6136
0
    return err;
6137
0
}
6138
6139
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6140
    defined(WOLFSSL_MICROCHIP_TA100)
6141
/* Resolve the curve id to pass to the Microchip backend. Keep the curve
6142
 * distinction by id (not size): SECP256R1, SECP256K1 and BRAINPOOLP256R1 are
6143
 * all 32 bytes and must NOT be collapsed onto SECP256R1. */
6144
static WC_INLINE int microchip_curve_id_for_key(const ecc_key* key)
6145
{
6146
    if (key != NULL && key->dp != NULL) {
6147
        return key->dp->id;
6148
    }
6149
    return ECC_CURVE_DEF;
6150
}
6151
#endif
6152
6153
6154
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
6155
        int curve_id, int flags)
6156
0
{
6157
0
    int err = 0;
6158
#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
6159
    int idKey;
6160
    int idDevId;
6161
#endif
6162
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
6163
    defined(WC_ECC_NONBLOCK_ONLY)
6164
    ecc_nb_ctx_t nb_ctx;
6165
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
6166
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
6167
6168
0
    if (key == NULL || rng == NULL) {
6169
0
        return BAD_FUNC_ARG;
6170
0
    }
6171
6172
    /* make sure required variables are reset */
6173
0
    wc_ecc_reset(key);
6174
6175
    #if FIPS_VERSION3_GE(6,0,0)
6176
    /* Refuse a key size below the FIPS minimum unless keysize is 0 and an
6177
     * approved curve is named. */
6178
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
6179
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
6180
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
6181
             curve_id == ECC_SECP521R1)) {
6182
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
6183
        } else {
6184
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
6185
            return BAD_FUNC_ARG;
6186
        }
6187
    }
6188
    #endif
6189
0
    err = wc_ecc_set_curve(key, keysize, curve_id);
6190
0
    if (err != 0) {
6191
0
        return err;
6192
0
    }
6193
0
    key->flags = (byte)flags;
6194
6195
#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
6196
    idKey = WC_CRYPTOCB_HAS_ID(key);
6197
    idDevId = key->devId;
6198
#endif
6199
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
6200
    #ifndef WOLF_CRYPTO_CB_FIND
6201
    if (key->devId != INVALID_DEVID)
6202
    #endif
6203
    {
6204
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
6205
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
6206
            return err;
6207
        /* fall-through when unavailable */
6208
    }
6209
#endif
6210
#ifdef WC_CRYPTOCB_KEYGEN_ID_CHECK
6211
    if (idKey && wc_CryptoCb_HasPkDevice(idDevId))
6212
        return NO_VALID_DEVID;
6213
#endif
6214
6215
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
6216
    return NO_VALID_DEVID;
6217
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
6218
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6219
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6220
    #ifdef HAVE_CAVIUM
6221
        /* TODO: Not implemented */
6222
    #elif defined(HAVE_INTEL_QA)
6223
        /* Implemented in ecc_make_pub_ex for the pub calc */
6224
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
6225
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
6226
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
6227
            sw->eccMake.rng = rng;
6228
            sw->eccMake.key = key;
6229
            sw->eccMake.size = keysize;
6230
            sw->eccMake.curve_id = curve_id;
6231
            return WC_PENDING_E;
6232
        }
6233
    #endif
6234
    }
6235
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6236
6237
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6238
    defined(WOLFSSL_MICROCHIP_TA100)
6239
#if defined(WOLFSSL_MICROCHIP_TA100)
6240
    /* TA100 supports multiple curves natively. */
6241
    if (key->dp->id == ECC_SECP256R1 ||
6242
        key->dp->id == ECC_SECP224R1 ||
6243
        key->dp->id == ECC_SECP384R1 ||
6244
        key->dp->id == ECC_SECP256K1 ||
6245
        key->dp->id == ECC_BRAINPOOLP256R1) {
6246
#else
6247
    /* ATECC508A/608A hardware only supports SECP256R1. */
6248
    if (key->dp->id == ECC_SECP256R1) {
6249
#endif
6250
       key->type = ECC_PRIVATEKEY;
6251
       if (key->slot == ATECC_INVALID_SLOT)
6252
           key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
6253
       err = atmel_ecc_create_key(key->slot, microchip_curve_id_for_key(key),
6254
           key->pubkey_raw);
6255
6256
       /* populate key->pubkey */
6257
       if (err == 0
6258
       #ifdef ALT_ECC_SIZE
6259
          && key->pubkey.x
6260
       #endif
6261
       ) {
6262
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
6263
                                      (word32)key->dp->size);
6264
       }
6265
       if (err == 0
6266
       #ifdef ALT_ECC_SIZE
6267
          && key->pubkey.y
6268
       #endif
6269
       ) {
6270
           err = mp_read_unsigned_bin(key->pubkey.y,
6271
                                      key->pubkey_raw + key->dp->size,
6272
                                      (word32)key->dp->size);
6273
       }
6274
   }
6275
   else {
6276
      err = NOT_COMPILED_IN;
6277
   }
6278
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
6279
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
6280
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
6281
    key->type = ECC_PRIVATEKEY;
6282
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6283
    return silabs_ecc_make_key(key, keysize);
6284
#elif defined(WOLFSSL_KCAPI_ECC)
6285
6286
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
6287
    (void)rng;
6288
6289
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6290
    if (xil_curve_type[key->dp->id] == 0)
6291
        return ECC_CURVE_OID_E;
6292
6293
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
6294
    if (err)
6295
        return err;
6296
    /* Make sure that private key is max. 521 bits */
6297
    if (key->dp->size == 66)
6298
        key->privKey[65] &= 0x1U;
6299
6300
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
6301
6302
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6303
                                        2 * key->dp->size);
6304
6305
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
6306
                                      xil_curve_type[key->dp->id],
6307
                                      XIL_CAST_U64(key->privKey),
6308
                                      XIL_CAST_U64(key->keyRaw));
6309
    if (err != XST_SUCCESS) {
6310
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
6311
        err = WC_HW_E;
6312
    }
6313
6314
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6315
                                        2 * key->dp->size);
6316
6317
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
6318
    if (err == 0)
6319
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
6320
                                          xil_curve_type[key->dp->id],
6321
                                          XIL_CAST_U64(key->keyRaw));
6322
#endif
6323
6324
    if (err == 0)
6325
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
6326
                             key->heap);
6327
    if (err == 0)
6328
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
6329
                             key->dp->size, key->heap);
6330
    if (err == 0)
6331
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
6332
                             key->heap);
6333
#ifdef WOLFSSL_ECC_BLIND_K
6334
    if (err == 0)
6335
        err = ecc_blind_k_rng(key, rng);
6336
#endif
6337
    if (err == 0)
6338
        err = mp_set(key->pubkey.z, 1);
6339
    if (err) {
6340
        key->privKey = NULL;
6341
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
6342
        return err;
6343
    }
6344
6345
    key->type = ECC_PRIVATEKEY;
6346
6347
#else
6348
6349
#ifdef WOLFSSL_HAVE_SP_ECC
6350
6351
#ifndef WOLFSSL_SP_NO_256
6352
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
6353
    #ifndef WC_ECC_NONBLOCK
6354
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6355
    #else
6356
        if (key->nb_ctx) {
6357
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6358
                                         &key->pubkey, key->heap);
6359
        }
6360
        else {
6361
        #ifdef WC_ECC_NONBLOCK_ONLY
6362
            do { /* perform blocking call to non-blocking function */
6363
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
6364
                                             &key->pubkey, key->heap);
6365
            } while (err == FP_WOULDBLOCK);
6366
        #else
6367
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6368
        #endif /* WC_ECC_NONBLOCK_ONLY */
6369
        }
6370
    #endif /* !WC_ECC_NONBLOCK */
6371
6372
        if (err == MP_OKAY) {
6373
            key->type = ECC_PRIVATEKEY;
6374
        }
6375
    }
6376
    else
6377
#endif /* !WOLFSSL_SP_NO_256 */
6378
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
6379
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
6380
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
6381
        if (err == MP_OKAY) {
6382
            key->type = ECC_PRIVATEKEY;
6383
        }
6384
    }
6385
    else
6386
#endif
6387
#ifdef WOLFSSL_SP_384
6388
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
6389
    #ifndef WC_ECC_NONBLOCK
6390
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6391
    #else
6392
        if (key->nb_ctx) {
6393
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6394
                                         &key->pubkey, key->heap);
6395
        }
6396
        else {
6397
        #ifdef WC_ECC_NONBLOCK_ONLY
6398
            do { /* perform blocking call to non-blocking function */
6399
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
6400
                                             &key->pubkey, key->heap);
6401
            } while (err == FP_WOULDBLOCK);
6402
        #else
6403
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6404
        #endif /* WC_ECC_NONBLOCK_ONLY */
6405
        }
6406
    #endif /* !WC_ECC_NONBLOCK */
6407
6408
        if (err == MP_OKAY) {
6409
            key->type = ECC_PRIVATEKEY;
6410
        }
6411
    }
6412
    else
6413
#endif /* WOLFSSL_SP_384 */
6414
#ifdef WOLFSSL_SP_521
6415
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
6416
    #ifndef WC_ECC_NONBLOCK
6417
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6418
    #else
6419
        if (key->nb_ctx) {
6420
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6421
                                         &key->pubkey, key->heap);
6422
        }
6423
        else {
6424
        #ifdef WC_ECC_NONBLOCK_ONLY
6425
            do { /* perform blocking call to non-blocking function */
6426
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
6427
                                             &key->pubkey, key->heap);
6428
            } while (err == FP_WOULDBLOCK);
6429
        #else
6430
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6431
        #endif /* WC_ECC_NONBLOCK_ONLY */
6432
        }
6433
    #endif /* !WC_ECC_NONBLOCK */
6434
6435
        if (err == MP_OKAY) {
6436
            key->type = ECC_PRIVATEKEY;
6437
        }
6438
    }
6439
    else
6440
#endif /* WOLFSSL_SP_521 */
6441
#endif /* WOLFSSL_HAVE_SP_ECC */
6442
6443
0
   { /* software key gen */
6444
#if defined(WOLFSSL_SP_MATH)
6445
        err = WC_KEY_SIZE_E;
6446
#else
6447
0
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6448
6449
        /* setup the key variables */
6450
0
#ifndef ALT_ECC_SIZE
6451
0
        err = mp_init(key->k);
6452
#else
6453
        err = 0;
6454
        key->k = (mp_int*)key->ka;
6455
        alt_fp_init(key->k);
6456
#endif
6457
6458
        /* load curve info */
6459
0
        if (err == MP_OKAY) {
6460
0
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6461
0
            if (err != MP_OKAY) {
6462
0
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6463
0
            }
6464
0
        }
6465
6466
0
        if (err == MP_OKAY) {
6467
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6468
0
            if (err != MP_OKAY) {
6469
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
6470
0
            }
6471
0
        }
6472
6473
        /* generate k */
6474
0
        if (err == MP_OKAY) {
6475
0
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
6476
0
            if (err != MP_OKAY) {
6477
0
                WOLFSSL_MSG("wc_ecc_gen_k failed");
6478
0
            }
6479
0
        }
6480
6481
        /* generate public key from k */
6482
0
        if (err == MP_OKAY) {
6483
0
            err = ecc_make_pub_ex(key, curve, NULL, rng);
6484
0
            if (err != MP_OKAY) {
6485
0
                WOLFSSL_MSG("ecc_make_pub_ex failed");
6486
0
            }
6487
0
        }
6488
6489
0
        if (err == MP_OKAY
6490
        #ifdef WOLFSSL_ASYNC_CRYPT
6491
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
6492
        #endif
6493
0
        ) {
6494
0
            key->type = ECC_PRIVATEKEY;
6495
0
        }
6496
0
        else {
6497
            /* cleanup these on failure case only */
6498
0
            mp_forcezero(key->k);
6499
0
        }
6500
6501
        /* cleanup allocations */
6502
0
        wc_ecc_curve_free(curve);
6503
0
        FREE_CURVE_SPECS();
6504
0
#endif /* WOLFSSL_SP_MATH */
6505
0
    }
6506
6507
#ifdef HAVE_WOLF_BIGINT
6508
    if (err == MP_OKAY)
6509
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6510
    if (err == MP_OKAY)
6511
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6512
    if (err == MP_OKAY)
6513
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6514
    if (err == MP_OKAY)
6515
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6516
#endif
6517
6518
#ifdef WOLFSSL_ECC_BLIND_K
6519
    if (err == MP_OKAY)
6520
        err = ecc_blind_k_rng(key, rng);
6521
#endif
6522
6523
0
#endif /* HAVE_ECC_MAKE_PUB */
6524
6525
0
    return err;
6526
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6527
0
}
6528
6529
6530
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6531
                        int flags)
6532
0
{
6533
0
    int err;
6534
6535
0
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6536
6537
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6538
    !defined(WOLFSSL_KCAPI_ECC)
6539
    if (err == MP_OKAY) {
6540
        err = _ecc_validate_public_key(key, 0, 0);
6541
    }
6542
    if (err == MP_OKAY
6543
#if defined(WOLF_CRYPTO_CB)
6544
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6545
        && key->devId == INVALID_DEVID
6546
#endif
6547
        ) {
6548
        err = _ecc_pairwise_consistency_test(key, rng);
6549
    }
6550
    /* Free a key that failed its check, so a caller ignoring the return
6551
     * value cannot use it.  ISO/IEC 19790:2012 sec 7.10.1 forbids using
6552
     * anything that failed a self-test. */
6553
    if (err != MP_OKAY) {
6554
        wc_ecc_free(key);
6555
    }
6556
#endif
6557
6558
0
    return err;
6559
0
}
6560
6561
WOLFSSL_ABI
6562
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6563
0
{
6564
0
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6565
0
}
6566
6567
#ifdef ECC_DUMP_OID
6568
/* Optional dump of encoded OID for adding new curves */
6569
static int mOidDumpDone;
6570
static void wc_ecc_dump_oids(void)
6571
{
6572
    int x;
6573
6574
    if (mOidDumpDone) {
6575
        return;
6576
    }
6577
6578
    /* find matching OID sum (based on encoded value) */
6579
    for (x = 0; ecc_sets[x].size != 0; x++) {
6580
        int i;
6581
        byte* oid;
6582
        word32 oidSz, sum = 0;
6583
6584
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6585
6586
    #ifdef HAVE_OID_ENCODING
6587
        byte oidEnc[ECC_MAX_OID_LEN];
6588
6589
        oid = oidEnc;
6590
        oidSz = ECC_MAX_OID_LEN;
6591
6592
        printf("OID: ");
6593
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6594
            printf("%d.", ecc_sets[x].oid[i]);
6595
        }
6596
        printf("\n");
6597
6598
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6599
    #else
6600
        oid = (byte*)ecc_sets[x].oid;
6601
        oidSz = ecc_sets[x].oidSz;
6602
    #endif
6603
6604
        printf("OID Encoded: ");
6605
        for (i = 0; i < (int)oidSz; i++) {
6606
            printf("0x%02X,", oid[i]);
6607
        }
6608
        printf("\n");
6609
6610
        for (i = 0; i < (int)oidSz; i++) {
6611
            sum += oid[i];
6612
        }
6613
        printf("Sum: %u\n", sum);
6614
6615
        /* validate sum */
6616
        if (ecc_sets[x].oidSum != sum) {
6617
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6618
        }
6619
    }
6620
    mOidDumpDone = 1;
6621
}
6622
#endif /* ECC_DUMP_OID */
6623
6624
6625
WOLFSSL_ABI
6626
ecc_key* wc_ecc_key_new_ex(void* heap, int devId)
6627
0
{
6628
0
    ecc_key* key;
6629
6630
0
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6631
0
    if (key) {
6632
0
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6633
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6634
0
            key = NULL;
6635
0
        }
6636
0
    }
6637
6638
0
    return key;
6639
0
}
6640
6641
WOLFSSL_ABI
6642
ecc_key* wc_ecc_key_new(void* heap)
6643
0
{
6644
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6645
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6646
    int devId = WOLFSSL_CAAM_DEVID;
6647
#else
6648
0
    int devId = INVALID_DEVID;
6649
0
#endif
6650
6651
0
    return wc_ecc_key_new_ex(heap, devId);
6652
0
}
6653
6654
6655
WOLFSSL_ABI
6656
void wc_ecc_key_free(ecc_key* key)
6657
0
{
6658
0
    if (key) {
6659
0
        void* heap = key->heap;
6660
6661
0
        wc_ecc_free(key);
6662
0
        ForceZero(key, sizeof(ecc_key));
6663
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6664
0
        (void)heap;
6665
0
    }
6666
0
}
6667
6668
6669
/**
6670
 Make a new ECC key
6671
 rng          An active RNG state
6672
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6673
 key          [out] Destination of the newly created key
6674
 return       MP_OKAY if successful,
6675
 upon error all allocated memory will be freed
6676
 */
6677
WOLFSSL_ABI
6678
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6679
0
{
6680
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6681
0
}
6682
6683
/* Setup dynamic pointers if using normal math for proper freeing */
6684
WOLFSSL_ABI
6685
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6686
1.75k
{
6687
1.75k
    int ret      = 0;
6688
6689
1.75k
    if (key == NULL) {
6690
0
        return BAD_FUNC_ARG;
6691
0
    }
6692
6693
#ifdef ECC_DUMP_OID
6694
    wc_ecc_dump_oids();
6695
#endif
6696
6697
1.75k
    XMEMSET(key, 0, sizeof(ecc_key));
6698
1.75k
    key->state = ECC_STATE_NONE;
6699
6700
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6701
    key->devId = devId;
6702
#else
6703
1.75k
    (void)devId;
6704
1.75k
#endif
6705
6706
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6707
    defined(WOLFSSL_MICROCHIP_TA100)
6708
    key->slot = ATECC_INVALID_SLOT;
6709
#ifdef WOLFSSL_MICROCHIP_TA100
6710
    /* TA100 needs pubkey initialized to populate after genkey. With
6711
     * ALT_ECC_SIZE the x/y/z pointers must first be aimed at the inline
6712
     * xyz[] storage; mp_init_multi otherwise dereferences NULL. */
6713
#ifdef ALT_ECC_SIZE
6714
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6715
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6716
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6717
    alt_fp_init(key->pubkey.x);
6718
    alt_fp_init(key->pubkey.y);
6719
    alt_fp_init(key->pubkey.z);
6720
#else
6721
    ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
6722
                        NULL, NULL, NULL);
6723
    if (ret != MP_OKAY) {
6724
        return MEMORY_E;
6725
    }
6726
#endif
6727
#endif
6728
#else
6729
#if defined(WOLFSSL_KCAPI_ECC)
6730
    key->handle = NULL;
6731
#endif
6732
#ifdef ALT_ECC_SIZE
6733
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6734
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6735
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6736
    alt_fp_init(key->pubkey.x);
6737
    alt_fp_init(key->pubkey.y);
6738
    alt_fp_init(key->pubkey.z);
6739
    key->k = (mp_int*)key->ka;
6740
    alt_fp_init(key->k);
6741
#ifdef WOLFSSL_ECC_BLIND_K
6742
    key->kb = (mp_int*)key->kba;
6743
    key->ku = (mp_int*)key->kua;
6744
    alt_fp_init(key->kb);
6745
    alt_fp_init(key->ku);
6746
#endif
6747
#else
6748
1.75k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6749
1.75k
#ifndef WOLFSSL_ECC_BLIND_K
6750
1.75k
                                                                      NULL, NULL
6751
#else
6752
                                                                key->kb, key->ku
6753
#endif
6754
1.75k
                        );
6755
1.75k
    if (ret != MP_OKAY) {
6756
0
        return MEMORY_E;
6757
0
    }
6758
1.75k
#endif /* ALT_ECC_SIZE */
6759
#ifdef WOLFSSL_ECC_BLIND_K
6760
    mp_forcezero(key->kb);
6761
#endif
6762
1.75k
#endif /* WOLFSSL_ATECC508A */
6763
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6764
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6765
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6766
     defined(WOLFSSL_NO_MALLOC)
6767
    ret = mp_init(key->sign_k);
6768
    if (ret != MP_OKAY) {
6769
        return MEMORY_E;
6770
    }
6771
#endif
6772
6773
#ifdef WOLFSSL_HEAP_TEST
6774
    (void)heap;
6775
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6776
#else
6777
1.75k
    key->heap = heap;
6778
1.75k
#endif
6779
6780
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6781
    #ifdef WOLF_CRYPTO_CB
6782
    /* prefer crypto callback */
6783
    if (key->devId != INVALID_DEVID)
6784
    #endif
6785
    {
6786
        /* handle as async */
6787
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6788
                                                        key->heap, devId);
6789
    }
6790
    if (ret != 0)
6791
        return ret;
6792
#endif
6793
6794
#if defined(WOLFSSL_DSP)
6795
    key->handle = -1;
6796
#endif
6797
6798
#ifdef WOLFSSL_SE050
6799
    key->keyId = 0;
6800
    key->keyIdSet = 0;
6801
#endif
6802
6803
#ifdef WOLFSSL_CHECK_MEM_ZERO
6804
    mp_memzero_add("ECC k", key->k);
6805
#ifdef WOLFSSL_ECC_BLIND_K
6806
    mp_memzero_add("ECC kb", key->kb);
6807
    mp_memzero_add("ECC ku", key->ku);
6808
#endif
6809
#endif
6810
6811
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6812
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6813
6814
    if (wc_InitXsecure(&(key->xSec))) {
6815
        WOLFSSL_MSG("Can't initialize Xsecure");
6816
        return WC_HW_E;
6817
    }
6818
#endif
6819
6820
1.75k
    return ret;
6821
1.75k
}
6822
6823
WOLFSSL_ABI
6824
int wc_ecc_init(ecc_key* key)
6825
0
{
6826
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6827
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6828
#else
6829
0
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6830
0
#endif
6831
0
}
6832
6833
#ifdef WOLF_PRIVATE_KEY_ID
6834
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6835
                   int devId)
6836
{
6837
    int ret = 0;
6838
#ifdef WOLFSSL_SE050
6839
    /* SE050 TLS users store a word32 at id, need to read it back */
6840
    word32 keyId = 0;
6841
#endif
6842
6843
    if (key == NULL || (id == NULL && len > 0))
6844
        ret = BAD_FUNC_ARG;
6845
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6846
        ret = BUFFER_E;
6847
    if (ret == 0)
6848
        ret = wc_ecc_init_ex(key, heap, devId);
6849
    if (ret == 0 && id != NULL && len != 0) {
6850
        XMEMCPY(key->id, id, (size_t)len);
6851
        key->idLen = len;
6852
    #ifdef WOLFSSL_SE050
6853
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6854
        if (len == (int)sizeof(word32)) {
6855
            keyId = readUnalignedWord32(key->id);
6856
            ret = wc_ecc_use_key_id(key, keyId, 0);
6857
        }
6858
    #endif
6859
    }
6860
6861
    return ret;
6862
}
6863
6864
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6865
{
6866
    int ret = 0;
6867
    int labelLen = 0;
6868
6869
    if (key == NULL || label == NULL)
6870
        ret = BAD_FUNC_ARG;
6871
    if (ret == 0) {
6872
        labelLen = (int)XSTRLEN(label);
6873
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6874
            ret = BUFFER_E;
6875
    }
6876
    if (ret == 0)
6877
        ret = wc_ecc_init_ex(key, heap, devId);
6878
    if (ret == 0) {
6879
        XMEMCPY(key->label, label, (size_t)labelLen);
6880
        key->labelLen = labelLen;
6881
    }
6882
6883
    return ret;
6884
}
6885
#endif /* WOLF_PRIVATE_KEY_ID */
6886
6887
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6888
0
{
6889
0
    if (key == NULL) {
6890
0
        return BAD_FUNC_ARG;
6891
0
    }
6892
0
    key->flags |= flags;
6893
0
    return 0;
6894
0
}
6895
6896
6897
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6898
0
{
6899
0
    int err = MP_OKAY;
6900
0
    int orderBits;
6901
0
    DECLARE_CURVE_SPECS(1);
6902
6903
0
    ALLOC_CURVE_SPECS(1, err);
6904
0
    if (err == MP_OKAY) {
6905
0
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6906
0
    }
6907
6908
0
    if (err != 0) {
6909
0
       FREE_CURVE_SPECS();
6910
0
       return err;
6911
0
    }
6912
0
    orderBits = mp_count_bits(curve->order);
6913
6914
0
    wc_ecc_curve_free(curve);
6915
0
    FREE_CURVE_SPECS();
6916
0
    return orderBits;
6917
0
}
6918
6919
#if defined(HAVE_ECC_KEY_EXPORT) || defined(HAVE_ECC_KEY_IMPORT) || \
6920
    (defined(NO_ASN) && defined(HAVE_ECC_VERIFY) && \
6921
     !defined(WOLF_CRYPTO_CB_ONLY_ECC))
6922
/* Size in bytes of a value modulo the order: the private key, r and s. */
6923
static word32 ecc_order_size(const ecc_set_type* dp)
6924
0
{
6925
0
    word32 sz = (word32)dp->size;
6926
0
    word32 i = 0;
6927
0
    word32 digits;
6928
6929
0
    while (dp->order[i] == '0') {
6930
0
        i++;
6931
0
    }
6932
0
    digits = (word32)XSTRLEN(dp->order + i);
6933
0
    if ((digits + 1) / 2 > sz) {
6934
0
        sz = (digits + 1) / 2;
6935
0
    }
6936
0
    return sz;
6937
0
}
6938
#endif
6939
6940
#ifdef HAVE_ECC_SIGN
6941
6942
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6943
    defined(WOLFSSL_MICROCHIP_TA100) || \
6944
    defined(PLUTON_CRYPTO_ECC) || \
6945
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6946
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6947
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6948
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6949
    ecc_key* key)
6950
{
6951
    int err;
6952
#ifdef PLUTON_CRYPTO_ECC
6953
    if (key->devId != INVALID_DEVID) /* use hardware */
6954
#endif
6955
    {
6956
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6957
#ifdef WOLFSSL_SMALL_STACK
6958
        byte* K = NULL;
6959
        byte* incopy = NULL;
6960
#else
6961
        byte K[MAX_ECC_BYTES] = {0};
6962
        byte incopy[MAX_ECC_BYTES] = {0};
6963
#endif
6964
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6965
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6966
        word32 Ksize;
6967
#endif
6968
#endif
6969
        word32 keysize = (word32)key->dp->size;
6970
    #ifdef PLUTON_CRYPTO_ECC
6971
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6972
    #endif
6973
6974
    #ifndef WOLFSSL_KCAPI_ECC
6975
        /* Check args */
6976
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6977
            return ECC_BAD_ARG_E;
6978
        }
6979
    #endif
6980
6981
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6982
         defined(WOLFSSL_MICROCHIP_TA100)
6983
#if defined(WOLFSSL_MICROCHIP_TA100)
6984
        if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
6985
            (void)inlen;
6986
            /* Sign: Result is 32-bytes of R then 32-bytes of S */
6987
            err = atmel_ecc_sign(key->slot, in, out);
6988
        }
6989
        else {
6990
            /* Sign: Result is raw R||S */
6991
            err = atmel_ecc_sign_ex(key->slot, microchip_curve_id_for_key(key),
6992
                in, inlen, out);
6993
        }
6994
#else
6995
        (void)inlen;
6996
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6997
        err = atmel_ecc_sign(key->slot, in, out);
6998
#endif
6999
7000
        if (err != 0) {
7001
           return err;
7002
        }
7003
    #elif defined(PLUTON_CRYPTO_ECC)
7004
        {
7005
            /* if the input is larger than curve order, we must truncate */
7006
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
7007
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7008
            }
7009
7010
            /* perform ECC sign */
7011
            word32 raw_sig_size = *outlen;
7012
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
7013
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
7014
               return BAD_COND_E;
7015
            }
7016
        }
7017
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
7018
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
7019
        if (err != 0) {
7020
               return WC_HW_E;
7021
        }
7022
    #elif defined(WOLFSSL_KCAPI_ECC)
7023
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
7024
        if (err != MP_OKAY) {
7025
            return err;
7026
        }
7027
        (void)rng;
7028
    #elif defined(WOLFSSL_SE050)
7029
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
7030
        if (err != MP_OKAY) {
7031
            return err;
7032
        }
7033
        (void)rng;
7034
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7035
7036
#ifdef WOLFSSL_SMALL_STACK
7037
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
7038
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
7039
        if (K == NULL || incopy == NULL) {
7040
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
7041
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
7042
            return MEMORY_E;
7043
        }
7044
#else
7045
        if (inlen > sizeof(incopy))
7046
            return ECC_BAD_ARG_E;
7047
#endif
7048
7049
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7050
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7051
        err = deterministic_sign_helper(in, inlen, key);
7052
        if (err)
7053
            return err;
7054
        Ksize = mp_unsigned_bin_size(key->sign_k);
7055
        if (Ksize > keysize) {
7056
            err = BUFFER_E;
7057
            goto error_out;
7058
        }
7059
        err = mp_to_unsigned_bin(key->sign_k, K);
7060
        if (err)
7061
            goto error_out;
7062
        mp_reverse(K, Ksize);
7063
#else
7064
        err = wc_RNG_GenerateBlock(rng, K, keysize);
7065
        if (err)
7066
            goto error_out;
7067
        /* Make sure that K is max. 521 bits */
7068
        if (keysize == 66)
7069
            K[65] &= 0x1;
7070
#endif
7071
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
7072
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
7073
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
7074
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
7075
7076
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
7077
7078
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
7079
                                           xil_curve_type[key->dp->id],
7080
                                           XIL_CAST_U64(incopy), keysize,
7081
                                           XIL_CAST_U64(key->privKey),
7082
                                           XIL_CAST_U64(K),
7083
                                           XIL_CAST_U64(out));
7084
        if (err) {
7085
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
7086
            err = WC_HW_E;
7087
        }
7088
7089
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
7090
        mp_reverse(&out[0], keysize);
7091
        mp_reverse(&out[keysize], keysize);
7092
7093
error_out:
7094
        ForceZero(K, keysize);
7095
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
7096
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
7097
        if (err) {
7098
            ForceZero(out, keysize * 2);
7099
            return err;
7100
        }
7101
    #endif /* HW-specific #if-#elif chain */
7102
7103
    #ifndef WOLFSSL_SE050
7104
        /* Load R and S, SE050 does this in port layer */
7105
        err = mp_read_unsigned_bin(r, &out[0], keysize);
7106
        if (err != MP_OKAY) {
7107
            return err;
7108
        }
7109
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
7110
        if (err != MP_OKAY) {
7111
            return err;
7112
        }
7113
    #endif
7114
7115
        /* Check for zeros */
7116
        if (mp_iszero(r) || mp_iszero(s)) {
7117
            return MP_ZERO_E;
7118
        }
7119
    }
7120
#ifdef PLUTON_CRYPTO_ECC
7121
    else {
7122
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7123
    }
7124
#endif
7125
    (void)rng;
7126
7127
    return err;
7128
}
7129
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */
7130
7131
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7132
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
7133
    word32 *outlen, WC_RNG* rng, ecc_key* key)
7134
{
7135
    int err;
7136
    mp_int *r = NULL, *s = NULL;
7137
7138
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
7139
                                                                rng == NULL) {
7140
        return ECC_BAD_ARG_E;
7141
    }
7142
7143
    err = wc_ecc_alloc_async(key);
7144
    if (err != 0) {
7145
        return err;
7146
    }
7147
    r = key->r;
7148
    s = key->s;
7149
7150
    switch (key->state) {
7151
        case ECC_STATE_NONE:
7152
        case ECC_STATE_SIGN_DO:
7153
            key->state = ECC_STATE_SIGN_DO;
7154
7155
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
7156
                break;
7157
            }
7158
7159
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7160
            if (err < 0) {
7161
                break;
7162
            }
7163
7164
            FALL_THROUGH;
7165
7166
        case ECC_STATE_SIGN_ENCODE:
7167
            key->state = ECC_STATE_SIGN_ENCODE;
7168
7169
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7170
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
7171
                    DECLARE_CURVE_SPECS(1);
7172
                    ALLOC_CURVE_SPECS(1, err);
7173
                    if (err != MP_OKAY) {
7174
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
7175
                        break;
7176
                    }
7177
7178
                    /* get curve order */
7179
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7180
                #endif
7181
7182
                #ifdef HAVE_CAVIUM_V
7183
                    /* Nitrox requires r and s in sep buffer, so split it */
7184
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
7185
                #endif
7186
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
7187
                    /* only do this if not software, since it overwrites result */
7188
                    wc_bigint_to_mp(&r->raw, r);
7189
                    wc_bigint_to_mp(&s->raw, s);
7190
7191
                /* if using a curve with cofactor != 1 then reduce by mod order */
7192
                #ifdef HAVE_ECC_CDH
7193
                    /* if r is not less than order than reduce */
7194
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
7195
                        err = mp_mod(r, curve->order, r);
7196
                    }
7197
                    wc_ecc_curve_free(curve);
7198
                    FREE_CURVE_SPECS();
7199
                #endif
7200
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
7201
            }
7202
7203
            /* encoded with DSA header */
7204
            if (err == 0) {
7205
                err = StoreECC_DSA_Sig(out, outlen, r, s);
7206
            }
7207
7208
            /* done with R/S */
7209
            mp_clear(r);
7210
            mp_clear(s);
7211
            break;
7212
7213
        default:
7214
            err = BAD_STATE_E;
7215
            break;
7216
    }
7217
7218
    /* if async pending then return and skip done cleanup below */
7219
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
7220
        key->state++;
7221
        return err;
7222
    }
7223
7224
    /* cleanup */
7225
    wc_ecc_free_async(key);
7226
    key->state = ECC_STATE_NONE;
7227
7228
    return err;
7229
}
7230
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7231
7232
/**
7233
 Sign a message digest
7234
 in        The message digest to sign
7235
 inlen     The length of the digest
7236
 out       [out] The destination for the signature
7237
 outlen    [in/out] The max size and resulting size of the signature
7238
 key       A private ECC key
7239
 return    MP_OKAY if successful
7240
 */
7241
WOLFSSL_ABI
7242
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
7243
                     WC_RNG* rng, ecc_key* key)
7244
0
{
7245
0
    int err;
7246
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
7247
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7248
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7249
0
#endif
7250
#if defined(NO_ASN) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
7251
    word32 keySz;
7252
#endif
7253
7254
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7255
0
        return WC_KEY_SIZE_E;
7256
0
    }
7257
7258
0
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
7259
0
        return ECC_BAD_ARG_E;
7260
0
    }
7261
0
    if ((inlen > WC_MAX_DIGEST_SIZE) ||
7262
0
        (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7263
0
    {
7264
0
        return BAD_LENGTH_E;
7265
0
    }
7266
7267
#ifdef WOLF_CRYPTO_CB
7268
    #ifndef WOLF_CRYPTO_CB_FIND
7269
    if (key->devId != INVALID_DEVID)
7270
    #endif
7271
    {
7272
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
7273
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7274
            return err;
7275
        /* fall-through when unavailable */
7276
    }
7277
#endif
7278
7279
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
7280
    (void)rng;
7281
    (void)inlen;
7282
    (void)s;
7283
    (void)r;
7284
    (void)err;
7285
    return NO_VALID_DEVID;
7286
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
7287
#ifdef NO_ASN
7288
    /* No support for DSA ASN.1 header.
7289
     * Signature will be r+s directly. */
7290
    keySz = 0;
7291
    if (key->dp != NULL) {
7292
        keySz = (word32)key->dp->size;
7293
    }
7294
    if (keySz == 0) {
7295
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
7296
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
7297
    }
7298
    if (*outlen < keySz * 2) {
7299
        *outlen = keySz * 2;
7300
        return BUFFER_E;
7301
    }
7302
#endif
7303
0
    if (rng == NULL) {
7304
0
        WOLFSSL_MSG("ECC sign RNG missing");
7305
0
        return ECC_BAD_ARG_E;
7306
0
    }
7307
7308
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7309
    /* handle async cases */
7310
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
7311
#else
7312
7313
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7314
    #ifdef MP_INT_SIZE_CHECK_NULL
7315
    if (r == NULL)
7316
        return MEMORY_E;
7317
    #endif
7318
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7319
    #ifdef MP_INT_SIZE_CHECK_NULL
7320
    if (s == NULL) {
7321
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7322
        return MEMORY_E;
7323
    }
7324
    #endif
7325
7326
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7327
0
    if (err != 0) {
7328
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7329
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7330
0
        return err;
7331
0
    }
7332
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7333
0
    if (err != 0) {
7334
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7335
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7336
0
        return err;
7337
0
    }
7338
7339
/* hardware crypto */
7340
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID)
7341
    /* Route by key location: SE050-resident keys sign in hardware, software
7342
     * keys (keyIdSet == 0) sign with the wolfCrypt software implementation. */
7343
    if (key->keyIdSet)
7344
        err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7345
    else
7346
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7347
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
7348
    defined(WOLFSSL_MICROCHIP_TA100) || \
7349
    defined(PLUTON_CRYPTO_ECC) || \
7350
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
7351
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7352
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7353
#else
7354
0
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7355
0
#endif
7356
0
    if (err < 0) {
7357
0
        mp_clear(r);
7358
0
        mp_clear(s);
7359
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7360
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7361
0
        return err;
7362
0
    }
7363
7364
0
#ifndef NO_ASN
7365
    /* encoded with DSA header */
7366
0
    err = StoreECC_DSA_Sig(out, outlen, r, s);
7367
#else
7368
    /* Export signature into r,s */
7369
    err = mp_to_unsigned_bin_len(r, out, (int)keySz);
7370
    if (err == MP_OKAY) {
7371
        err = mp_to_unsigned_bin_len(s, out + keySz, (int)keySz);
7372
    }
7373
    if (err == MP_OKAY) {
7374
        *outlen = keySz * 2;
7375
    }
7376
#endif /* !NO_ASN */
7377
7378
    /* cleanup */
7379
0
    mp_clear(r);
7380
0
    mp_clear(s);
7381
7382
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7383
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7384
0
#endif /* WOLFSSL_ASYNC_CRYPT */
7385
0
    return err;
7386
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
7387
0
}
7388
7389
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7390
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7391
/* returns MP_OKAY on success */
7392
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
7393
{
7394
    int err = MP_OKAY;
7395
    DECLARE_CURVE_SPECS(1);
7396
    ALLOC_CURVE_SPECS(1, err);
7397
7398
    /* get curve order */
7399
    if (err == MP_OKAY) {
7400
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7401
    }
7402
7403
    if (err == MP_OKAY) {
7404
    #ifndef WOLFSSL_NO_MALLOC
7405
        /* if key->sign_k is NULL then create a buffer for the mp_int
7406
         * if not NULL then assume the user correctly set deterministic flag and
7407
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
7408
        if (key->sign_k == NULL) {
7409
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7410
                                                            DYNAMIC_TYPE_ECC);
7411
            if (key->sign_k != NULL) {
7412
                err = mp_init(key->sign_k);
7413
                if (err != MP_OKAY) {
7414
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7415
                    key->sign_k = NULL;
7416
                }
7417
            }
7418
        }
7419
        if (key->sign_k != NULL) {
7420
            if (wc_ecc_gen_deterministic_k(in, inlen,
7421
                        key->hashType, ecc_get_k(key), key->sign_k,
7422
                        curve->order, key->heap) != 0) {
7423
                mp_forcezero(key->sign_k);
7424
                mp_free(key->sign_k);
7425
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7426
                key->sign_k = NULL;
7427
                err = ECC_PRIV_KEY_E;
7428
            }
7429
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7430
            else {
7431
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
7432
            }
7433
        #endif
7434
        }
7435
        else {
7436
            err = MEMORY_E;
7437
        }
7438
    #else
7439
        key->sign_k_set = 0;
7440
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
7441
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
7442
            mp_forcezero(key->sign_k);
7443
            err = ECC_PRIV_KEY_E;
7444
        }
7445
        else {
7446
            key->sign_k_set = 1;
7447
        }
7448
    #endif
7449
        ecc_put_k(key);
7450
    }
7451
7452
    wc_ecc_curve_free(curve);
7453
    FREE_CURVE_SPECS();
7454
    return err;
7455
}
7456
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
7457
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
7458
7459
/* WOLFSSL_STM32_PKA routes HW ECDSA sign/verify through the STM32 PKA
7460
 * (HAL_PKA_ECDSASign / Verify). Works under both the CubeMX-HAL path
7461
 * and the bare-metal direct-register path (WOLFSSL_STM32_BARE) -- the
7462
 * bare-metal driver implements the same HAL_PKA_ECDSA* surface.
7463
 *
7464
 * The non-FIPS input-validation checks (length range, all-zero digest
7465
 * rejection) live inside the SW body of wc_ecc_sign_hash_ex below.
7466
 * Since the STM32_PKA branch returns early without reaching them,
7467
 * mirror those checks here so HW + SW paths share the same input
7468
 * contract. Without this, an all-zero digest reaches the PKA IP and
7469
 * succeeds at the HW layer -- the wolfcrypt_test ECC sweep then fails
7470
 * at the post-call assertion that expected ECC_BAD_ARG_E for a zero
7471
 * digest. */
7472
/* The STM32H563 "light" PKA can verify but not sign (per ST: H563
7473
 * verify-only, H573 full). WC_STM32_PKA_VERIFY_ONLY routes sign to the
7474
 * software path (the #elif branch below) while verify stays on the HW PKA. */
7475
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_VERIFY_ONLY)
7476
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7477
                     ecc_key* key, mp_int *r, mp_int *s)
7478
{
7479
#ifndef WC_ALLOW_ECC_ZERO_HASH
7480
    byte hashIsZero = 0;
7481
    word32 zIdx;
7482
#endif
7483
7484
    if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7485
        return ECC_BAD_ARG_E;
7486
    }
7487
    if ((inlen > WC_MAX_DIGEST_SIZE) || (inlen < WC_MIN_DIGEST_SIZE)) {
7488
        return BAD_LENGTH_E;
7489
    }
7490
#ifndef WC_ALLOW_ECC_ZERO_HASH
7491
    /* reject all 0's hash */
7492
    for (zIdx = 0; zIdx < inlen; zIdx++)
7493
        hashIsZero |= in[zIdx];
7494
    if (hashIsZero == 0)
7495
        return ECC_BAD_ARG_E;
7496
#endif
7497
7498
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7499
}
7500
7501
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7502
      !defined(WOLFSSL_MICROCHIP_TA100) && \
7503
      !defined(WOLFSSL_KCAPI_ECC) && \
7504
      !defined(WOLFSSL_NO_ECC_SW)
7505
#ifndef WOLFSSL_SP_MATH
7506
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
7507
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
7508
                            mp_int* s)
7509
0
{
7510
0
    int err = MP_OKAY;
7511
0
    int loop_check = 0;
7512
7513
0
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
7514
7515
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
7516
0
        return WC_KEY_SIZE_E;
7517
0
    }
7518
7519
0
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7520
#ifdef MP_INT_SIZE_CHECK_NULL
7521
    if (b == NULL)
7522
        err = MEMORY_E;
7523
#endif
7524
7525
0
    if (err == MP_OKAY) {
7526
0
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7527
0
    }
7528
7529
#ifdef WOLFSSL_CUSTOM_CURVES
7530
    /* if custom curve, apply params to pubkey */
7531
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
7532
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
7533
    }
7534
#endif
7535
7536
0
    if (err == MP_OKAY) {
7537
        /* Generate blinding value - non-zero value. */
7538
0
        do {
7539
0
            if (++loop_check > 64) {
7540
0
                 err = RNG_FAILURE_E;
7541
0
                 break;
7542
0
            }
7543
7544
0
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
7545
0
        }
7546
0
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
7547
0
        loop_check = 0;
7548
0
    }
7549
#ifdef WOLFSSL_CHECK_MEM_ZERO
7550
    if (err == MP_OKAY) {
7551
        mp_memzero_add("ecc_sign_hash_sw b", b);
7552
    }
7553
#endif
7554
7555
0
    for (; err == MP_OKAY;) {
7556
0
        if (++loop_check > 64) {
7557
0
             err = RNG_FAILURE_E;
7558
0
             break;
7559
0
        }
7560
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7561
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7562
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7563
#ifndef WOLFSSL_NO_MALLOC
7564
        if (key->sign_k != NULL)
7565
#else
7566
        if (key->sign_k_set)
7567
#endif
7568
        {
7569
            if (loop_check > 1) {
7570
               err = RNG_FAILURE_E;
7571
               break;
7572
            }
7573
7574
            /* use provided sign_k */
7575
            err = mp_copy(key->sign_k, pubkey->k);
7576
            if (err != MP_OKAY) break;
7577
7578
            /* free sign_k, so only used once */
7579
            mp_forcezero(key->sign_k);
7580
#ifndef WOLFSSL_NO_MALLOC
7581
            mp_free(key->sign_k);
7582
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7583
            key->sign_k = NULL;
7584
#else
7585
            key->sign_k_set = 0;
7586
#endif
7587
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
7588
            loop_check = 64;
7589
    #endif
7590
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7591
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7592
            if (key->deterministic == 1) {
7593
                /* sign_k generated earlier in function for SP calls.
7594
                 * Only go through the loop once and fail if error */
7595
                loop_check = 64;
7596
            }
7597
    #endif
7598
7599
            /* compute public key based on provided "k" */
7600
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
7601
        }
7602
        else
7603
#endif
7604
0
        {
7605
0
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
7606
0
                    WC_ECC_FLAG_NONE);
7607
0
        }
7608
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7609
        if (err == MP_OKAY) {
7610
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7611
        }
7612
    #endif
7613
    #ifdef WOLFSSL_ASYNC_CRYPT
7614
        /* for async do blocking wait here */
7615
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7616
    #endif
7617
0
        if (err != MP_OKAY) break;
7618
7619
        /* find r = x1 mod n */
7620
0
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7621
0
        if (err != MP_OKAY) break;
7622
7623
0
        if (mp_iszero(r) == MP_NO) {
7624
0
            mp_int* kp = ecc_get_k(pubkey);
7625
0
            mp_int* ep = kp;
7626
0
            mp_int* x  = ecc_get_k(key);
7627
7628
            /* Blind after getting. */
7629
0
            ecc_blind_k(key, b);
7630
7631
            /* find s = (e + xr)/k
7632
                      = b.(e/k.b + x.r/k.b) */
7633
7634
            /* k' = k.b */
7635
0
            err = mp_mulmod(kp, b, curve->order, kp);
7636
0
            if (err != MP_OKAY) break;
7637
7638
            /* k' = 1/k.b
7639
                  = 1/k' */
7640
0
            err = mp_invmod(kp, curve->order, kp);
7641
0
            if (err != MP_OKAY) break;
7642
7643
            /* s = x.r */
7644
0
            err = mp_mulmod(x, r, curve->order, s);
7645
0
            if (err != MP_OKAY) break;
7646
7647
            /* s = x.r/k.b
7648
                 = k'.s */
7649
0
            err = mp_mulmod(kp, s, curve->order, s);
7650
0
            if (err != MP_OKAY) break;
7651
7652
            /* e' = e/k.b
7653
                  = e.k' */
7654
0
            err = mp_mulmod(kp, e, curve->order, ep);
7655
0
            if (err != MP_OKAY) break;
7656
7657
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7658
                 = e' + s */
7659
0
            err = mp_addmod_ct(ep, s, curve->order, s);
7660
0
            if (err != MP_OKAY) break;
7661
7662
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7663
                 = b.s */
7664
0
            err = mp_mulmod(s, b, curve->order, s);
7665
0
            if (err != MP_OKAY) break;
7666
7667
0
            if (mp_iszero(s) == MP_NO) {
7668
                /* sign successful */
7669
0
                break;
7670
0
            }
7671
0
         }
7672
0
     #ifndef ALT_ECC_SIZE
7673
0
         mp_clear(pubkey->pubkey.x);
7674
0
         mp_clear(pubkey->pubkey.y);
7675
0
         mp_clear(pubkey->pubkey.z);
7676
0
     #endif
7677
0
         mp_forcezero(pubkey->k);
7678
7679
0
         err = WC_CHECK_FOR_INTR_SIGNALS();
7680
0
         if (err != 0)
7681
0
             break;
7682
0
         WC_RELAX_LONG_LOOP();
7683
0
    }
7684
0
    ecc_put_k(key);
7685
0
    mp_forcezero(b);
7686
0
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7687
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7688
    mp_memzero_check(b);
7689
#endif
7690
7691
0
    return err;
7692
0
}
7693
#endif
7694
7695
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7696
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7697
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7698
/* The nonce is consumed by every sign result; SP only resets its length. */
7699
static void ecc_sign_k_forcezero(ecc_key* key)
7700
{
7701
#ifndef WOLFSSL_NO_MALLOC
7702
    if (key->sign_k != NULL) {
7703
        mp_forcezero(key->sign_k);
7704
        mp_free(key->sign_k);
7705
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7706
        key->sign_k = NULL;
7707
    }
7708
#else
7709
    mp_forcezero(key->sign_k);
7710
    key->sign_k_set = 0;
7711
#endif
7712
}
7713
#endif
7714
7715
#ifdef WOLFSSL_HAVE_SP_ECC
7716
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7717
    ecc_key* key, mp_int *r, mp_int *s)
7718
{
7719
    if (key->idx != ECC_CUSTOM_IDX) {
7720
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7721
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7722
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7723
        mp_int* sign_k = key->sign_k;
7724
    #else
7725
        mp_int* sign_k = NULL;
7726
    #endif
7727
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7728
        /* perform blocking call to non-blocking function */
7729
        ecc_nb_ctx_t nb_ctx;
7730
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7731
    #endif
7732
    #ifndef WOLFSSL_SP_NO_256
7733
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7734
        #ifdef WC_ECC_NONBLOCK
7735
            #ifdef WC_ECC_NONBLOCK_ONLY
7736
            int err;
7737
            #endif
7738
            if (key->nb_ctx) {
7739
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7740
                    ecc_get_k(key), r, s, sign_k, key->heap);
7741
            }
7742
            #ifdef WC_ECC_NONBLOCK_ONLY
7743
            do { /* perform blocking call to non-blocking function */
7744
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7745
                    ecc_get_k(key), r, s, sign_k, key->heap);
7746
            } while (err == FP_WOULDBLOCK);
7747
            return err;
7748
            #endif
7749
        #endif /* WC_ECC_NONBLOCK */
7750
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7751
            {
7752
                int ret;
7753
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7754
                                      sign_k, key->heap);
7755
                return ret;
7756
            }
7757
        #endif
7758
        }
7759
    #endif
7760
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7761
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7762
            int ret;
7763
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7764
                                      sign_k, key->heap);
7765
            return ret;
7766
        }
7767
    #endif
7768
    #ifdef WOLFSSL_SP_384
7769
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7770
        #ifdef WC_ECC_NONBLOCK
7771
            #ifdef WC_ECC_NONBLOCK_ONLY
7772
            int err;
7773
            #endif
7774
            if (key->nb_ctx) {
7775
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7776
                    ecc_get_k(key), r, s, sign_k, key->heap);
7777
            }
7778
            #ifdef WC_ECC_NONBLOCK_ONLY
7779
            do { /* perform blocking call to non-blocking function */
7780
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7781
                    ecc_get_k(key), r, s, sign_k, key->heap);
7782
            } while (err == FP_WOULDBLOCK);
7783
            return err;
7784
            #endif
7785
        #endif /* WC_ECC_NONBLOCK */
7786
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7787
            {
7788
                int ret;
7789
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7790
                                      sign_k, key->heap);
7791
                return ret;
7792
            }
7793
        #endif
7794
        }
7795
    #endif
7796
    #ifdef WOLFSSL_SP_521
7797
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7798
        #ifdef WC_ECC_NONBLOCK
7799
            #ifdef WC_ECC_NONBLOCK_ONLY
7800
            int err;
7801
            #endif
7802
            if (key->nb_ctx) {
7803
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7804
                    ecc_get_k(key), r, s, sign_k, key->heap);
7805
            }
7806
            #ifdef WC_ECC_NONBLOCK_ONLY
7807
            do { /* perform blocking call to non-blocking function */
7808
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7809
                    ecc_get_k(key), r, s, sign_k, key->heap);
7810
            } while (err == FP_WOULDBLOCK);
7811
            return err;
7812
            #endif
7813
        #endif /* WC_ECC_NONBLOCK */
7814
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7815
            {
7816
                int ret;
7817
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7818
                                      sign_k, key->heap);
7819
                return ret;
7820
            }
7821
        #endif
7822
        }
7823
    #endif
7824
        (void)sign_k;
7825
    }
7826
7827
    /* SP doesn't support curve. */
7828
    return WC_KEY_SIZE_E;
7829
}
7830
#endif
7831
7832
/**
7833
  Sign a message digest
7834
  in        The message digest to sign
7835
  inlen     The length of the digest
7836
  key       A private ECC key
7837
  r         [out] The destination for r component of the signature
7838
  s         [out] The destination for s component of the signature
7839
  return    MP_OKAY if successful
7840
*/
7841
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7842
                     ecc_key* key, mp_int *r, mp_int *s)
7843
0
{
7844
0
   int    err = 0;
7845
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
7846
0
   byte hashIsZero = 0;
7847
0
   word32 zIdx;
7848
0
#endif
7849
0
#if !defined(WOLFSSL_SP_MATH)
7850
0
   mp_int* e;
7851
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7852
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7853
0
#endif
7854
7855
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7856
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7857
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7858
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7859
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7860
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7861
#else
7862
0
   DECLARE_CURVE_SPECS(1);
7863
0
#endif
7864
0
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7865
0
       return WC_KEY_SIZE_E;
7866
0
   }
7867
0
#endif /* !WOLFSSL_SP_MATH */
7868
7869
0
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7870
0
       return ECC_BAD_ARG_E;
7871
0
   }
7872
0
   if ((inlen > WC_MAX_DIGEST_SIZE) ||
7873
0
       (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7874
0
   {
7875
0
       return BAD_LENGTH_E;
7876
0
   }
7877
7878
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
7879
   /* reject all 0's hash */
7880
0
   for (zIdx = 0; zIdx < inlen; zIdx++)
7881
0
       hashIsZero |= in[zIdx];
7882
0
   if (hashIsZero == 0)
7883
0
       return ECC_BAD_ARG_E;
7884
0
#endif
7885
7886
   /* is this a private key? */
7887
0
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7888
0
      return ECC_BAD_ARG_E;
7889
0
   }
7890
7891
   /* is the IDX valid ?  */
7892
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7893
0
      return ECC_BAD_ARG_E;
7894
0
   }
7895
7896
#if defined(WOLFSSL_SP_MATH)
7897
    if (key->idx == ECC_CUSTOM_IDX || (1
7898
    #ifndef WOLFSSL_SP_NO_256
7899
         && ecc_sets[key->idx].id != ECC_SECP256R1
7900
    #endif
7901
    #ifdef WOLFSSL_SP_SM2
7902
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7903
    #endif
7904
    #ifdef WOLFSSL_SP_384
7905
         && ecc_sets[key->idx].id != ECC_SECP384R1
7906
    #endif
7907
    #ifdef WOLFSSL_SP_521
7908
         && ecc_sets[key->idx].id != ECC_SECP521R1
7909
    #endif
7910
        )) {
7911
        return WC_KEY_SIZE_E;
7912
    }
7913
#endif
7914
7915
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7916
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7917
    /* generate deterministic 'k' value to be used either with SP or normal */
7918
    if (key->deterministic == 1) {
7919
        if (deterministic_sign_helper(in, inlen, key)) {
7920
            WOLFSSL_MSG("Error generating deterministic k to sign");
7921
            return ECC_PRIV_KEY_E;
7922
        }
7923
    }
7924
#endif
7925
7926
7927
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7928
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7929
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7930
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7931
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7932
            sw->eccSign.in = in;
7933
            sw->eccSign.inSz = inlen;
7934
            sw->eccSign.rng = rng;
7935
            sw->eccSign.key = key;
7936
            sw->eccSign.r = r;
7937
            sw->eccSign.s = s;
7938
            return WC_PENDING_E;
7939
        }
7940
    }
7941
#endif
7942
7943
#if defined(WOLFSSL_HAVE_SP_ECC)
7944
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7945
   /* WC_KEY_SIZE_E only means SP left this curve to the software path below,
7946
    * which needs k and clears it itself. Every other result consumed k. */
7947
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7948
       #ifdef WC_ECC_NONBLOCK
7949
       /* An incomplete operation still needs k. */
7950
       if (err != FP_WOULDBLOCK)
7951
       #endif
7952
       {
7953
           ecc_put_k(key);
7954
   #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7955
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7956
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7957
           ecc_sign_k_forcezero(key);
7958
   #endif
7959
       }
7960
       return err;
7961
   }
7962
#else
7963
0
   (void)inlen;
7964
0
#endif
7965
7966
0
#if !defined(WOLFSSL_SP_MATH)
7967
7968
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7969
   err = wc_ecc_alloc_mpint(key, &key->e);
7970
   if (err != 0) {
7971
      return err;
7972
   }
7973
   e = key->e;
7974
#else
7975
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7976
#ifdef MP_INT_SIZE_CHECK_NULL
7977
   if (e_lcl == NULL) {
7978
      return MEMORY_E;
7979
   }
7980
#endif
7981
0
   e = e_lcl;
7982
0
#endif
7983
7984
   /* get the hash and load it as a bignum into 'e' */
7985
   /* init the bignums */
7986
0
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7987
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7988
0
      return err;
7989
0
   }
7990
7991
   /* load curve info */
7992
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7993
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7994
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7995
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7996
    if (err == MP_OKAY)
7997
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7998
#else
7999
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
8000
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
8001
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
8002
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
8003
        if (err == MP_OKAY)
8004
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
8005
    }
8006
    else
8007
    #endif
8008
0
    {
8009
0
        ALLOC_CURVE_SPECS(1, err);
8010
0
        if (err == MP_OKAY)
8011
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8012
0
    }
8013
0
#endif
8014
8015
   /* load digest into e */
8016
0
   if (err == MP_OKAY) {
8017
       /* we may need to truncate if hash is longer than key size */
8018
0
       word32 orderBits = (word32)mp_count_bits(curve->order);
8019
8020
       /* truncate down to byte size, may be all that's needed */
8021
0
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
8022
0
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
8023
0
       err = mp_read_unsigned_bin(e, in, inlen);
8024
8025
       /* may still need bit truncation too */
8026
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
8027
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
8028
0
   }
8029
8030
   /* make up a key and export the public copy */
8031
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8032
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
8033
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
8034
   #ifdef HAVE_CAVIUM_V
8035
       if (NitroxEccIsCurveSupported(key))
8036
   #endif
8037
       {
8038
           word32 keySz = key->dp->size;
8039
           mp_int* k;
8040
       #ifdef HAVE_CAVIUM_V
8041
           err = wc_ecc_alloc_mpint(key, &key->signK);
8042
           if (err != 0)
8043
              return err;
8044
           k = key->signK;
8045
       #else
8046
           mp_int k_lcl;
8047
           k = &k_lcl;
8048
       #endif
8049
8050
           err = mp_init(k);
8051
8052
            /* make sure r and s are allocated */
8053
       #ifdef HAVE_CAVIUM_V
8054
           /* Nitrox V needs single buffer for R and S */
8055
           if (err == MP_OKAY)
8056
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
8057
           /* Nitrox V only needs Prime and Order */
8058
           if (err == MP_OKAY)
8059
               err = wc_ecc_curve_load(key->dp, &curve,
8060
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
8061
       #else
8062
           if (err == MP_OKAY)
8063
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
8064
           if (err == MP_OKAY)
8065
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
8066
       #endif
8067
           if (err == MP_OKAY)
8068
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
8069
8070
           /* load e and k */
8071
           if (err == MP_OKAY)
8072
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
8073
           if (err == MP_OKAY)
8074
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
8075
                  keySz);
8076
           if (err == MP_OKAY)
8077
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
8078
           if (err == MP_OKAY)
8079
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
8080
8081
       #ifdef HAVE_CAVIUM_V
8082
           if (err == MP_OKAY)
8083
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
8084
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
8085
                  &curve->order->raw);
8086
       #else
8087
           if (err == MP_OKAY)
8088
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
8089
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
8090
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
8091
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
8092
       #endif
8093
8094
       #ifndef HAVE_CAVIUM_V
8095
           mp_clear(e);
8096
           mp_forcezero(k);
8097
       #endif
8098
           wc_ecc_curve_free(curve);
8099
           FREE_CURVE_SPECS();
8100
8101
           return err;
8102
       }
8103
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
8104
   }
8105
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
8106
8107
0
   if (err == MP_OKAY) {
8108
0
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
8109
8110
0
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
8111
0
           err=MEMORY_E);
8112
0
       if (WC_VAR_OK(pubkey))
8113
0
       {
8114
       /* don't use async for key, since we don't support async return here */
8115
0
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
8116
0
           if (err == MP_OKAY) {
8117
0
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
8118
0
              wc_ecc_free(pubkey);
8119
0
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
8120
0
           }
8121
0
       }
8122
0
   }
8123
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
8124
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
8125
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8126
   /* The nonce is consumed whatever the result. */
8127
   ecc_sign_k_forcezero(key);
8128
#endif
8129
8130
0
   mp_clear(e);
8131
0
   wc_ecc_curve_free(curve);
8132
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
8133
0
   FREE_CURVE_SPECS();
8134
0
#endif /* !WOLFSSL_SP_MATH */
8135
8136
0
   return err;
8137
0
}
8138
8139
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
8140
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8141
/* helper function to do HMAC operations
8142
 * returns 0 on success and updates "out" buffer
8143
 */
8144
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
8145
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
8146
        byte* out, enum wc_HashType hashType, void* heap)
8147
{
8148
    WC_DECLARE_VAR(hmac, Hmac, 1, heap);
8149
    int  ret, init;
8150
8151
    WC_ALLOC_VAR_EX(hmac, Hmac, 1, heap, DYNAMIC_TYPE_HMAC,
8152
                    return MEMORY_E);
8153
8154
    ret = init = wc_HmacInit(hmac, heap, INVALID_DEVID);
8155
    if (ret == 0)
8156
        ret = wc_HmacSetKey(hmac, (int)hashType, K, KSz);
8157
8158
    if (ret == 0)
8159
        ret = wc_HmacUpdate(hmac, V, VSz);
8160
8161
    if (ret == 0 && oct != NULL)
8162
        ret = wc_HmacUpdate(hmac, oct, 1);
8163
8164
    if (ret == 0)
8165
        ret = wc_HmacUpdate(hmac, x, xSz);
8166
8167
    if (ret == 0)
8168
        ret = wc_HmacUpdate(hmac, h1, h1Sz);
8169
8170
    if (ret == 0)
8171
        ret = wc_HmacFinal(hmac, out);
8172
8173
    if (init == 0)
8174
        wc_HmacFree(hmac);
8175
8176
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
8177
    return ret;
8178
}
8179
8180
8181
/* Generates a deterministic key based of the message using RFC6979
8182
 * @param  [in]   hash     Hash value to sign
8183
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
8184
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
8185
 *                WC_HASH_TYPE_SHA256
8186
 * @param  [in]   priv     Current ECC private key set
8187
 * @param  [out]  k        An initialized mp_int to set the k value generated in
8188
 * @param  [in]   order    ECC order parameter to use with generation
8189
 * @return  0 on success.
8190
 */
8191
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
8192
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
8193
        void* heap)
8194
{
8195
    int ret = 0;
8196
#ifndef WOLFSSL_SMALL_STACK
8197
    byte h1[MAX_ECC_ORDER_BYTES];
8198
    byte V[WC_MAX_DIGEST_SIZE];
8199
    byte K[WC_MAX_DIGEST_SIZE];
8200
    byte x[MAX_ECC_ORDER_BYTES];
8201
    mp_int z1[1];
8202
#else
8203
    byte *h1 = NULL;
8204
    byte *V  = NULL;
8205
    byte *K  = NULL;
8206
    byte *x  = NULL;
8207
    mp_int *z1 = NULL;
8208
#endif
8209
    word32 xSz, VSz, KSz, h1len, qLen;
8210
    byte intOct;
8211
    int qbits = 0;
8212
8213
    if (hash == NULL || k == NULL || order == NULL) {
8214
        return BAD_FUNC_ARG;
8215
    }
8216
8217
    if (hashSz > WC_MAX_DIGEST_SIZE) {
8218
        WOLFSSL_MSG("hash size was too large!");
8219
        return BAD_FUNC_ARG;
8220
    }
8221
8222
    /* if none is provided then detect has type based on hash size */
8223
    if (hashType == WC_HASH_TYPE_NONE) {
8224
        if (hashSz == 64) {
8225
            hashType = WC_HASH_TYPE_SHA512;
8226
        }
8227
        else if (hashSz == 48) {
8228
            hashType = WC_HASH_TYPE_SHA384;
8229
        }
8230
        else if (hashSz == 32) {
8231
            hashType = WC_HASH_TYPE_SHA256;
8232
        }
8233
        else {
8234
            return BAD_FUNC_ARG;
8235
        }
8236
    }
8237
8238
    if (wc_HmacSizeByType((int)hashType) != (int)hashSz) {
8239
        WOLFSSL_MSG("hash size does not match hash type");
8240
        return BAD_FUNC_ARG;
8241
    }
8242
8243
    if (mp_unsigned_bin_size(priv) > MAX_ECC_ORDER_BYTES) {
8244
        WOLFSSL_MSG("private key larger than max expected!");
8245
        return BAD_FUNC_ARG;
8246
    }
8247
8248
    /* x and h1 below are written to the order's length. */
8249
    if (mp_unsigned_bin_size(order) > MAX_ECC_ORDER_BYTES) {
8250
        WOLFSSL_MSG("order larger than max expected!");
8251
        return BAD_FUNC_ARG;
8252
    }
8253
8254
#ifdef WOLFSSL_SMALL_STACK
8255
    h1 = (byte*)XMALLOC(MAX_ECC_ORDER_BYTES, heap, DYNAMIC_TYPE_DIGEST);
8256
    if (h1 == NULL) {
8257
        ret = MEMORY_E;
8258
    }
8259
8260
    if (ret == 0) {
8261
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8262
        if (V == NULL)
8263
            ret = MEMORY_E;
8264
    }
8265
8266
    if (ret == 0) {
8267
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8268
        if (K == NULL)
8269
            ret = MEMORY_E;
8270
    }
8271
8272
    if (ret == 0) {
8273
        x = (byte*)XMALLOC(MAX_ECC_ORDER_BYTES, heap,
8274
                           DYNAMIC_TYPE_PRIVATE_KEY);
8275
        if (x == NULL)
8276
            ret = MEMORY_E;
8277
    }
8278
8279
    if (ret == 0) {
8280
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
8281
        if (z1 == NULL)
8282
            ret = MEMORY_E;
8283
    }
8284
8285
    /* bail out if any error has been hit at this point */
8286
    if (ret != 0) {
8287
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8288
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8289
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8290
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8291
        return ret;
8292
    }
8293
#endif
8294
8295
    VSz = KSz = hashSz;
8296
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
8297
8298
    /* 3.2 b. Set V = 0x01 0x01 ... */
8299
    XMEMSET(V, 0x01, VSz);
8300
8301
    /* 3.2 c. Set K = 0x00 0x00 ... */
8302
    XMEMSET(K, 0x00, KSz);
8303
8304
#ifdef WOLFSSL_CHECK_MEM_ZERO
8305
    wc_MemZero_Add("wc_ecc_gen_deterministic_k K", K, KSz);
8306
    wc_MemZero_Add("wc_ecc_gen_deterministic_k V", V, VSz);
8307
#endif
8308
8309
    if (ret == 0) {
8310
        ret = mp_init(z1); /* always init z1 and free z1 */
8311
    }
8312
    if (ret == 0) {
8313
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
8314
    }
8315
    if (ret == 0) {
8316
    #ifdef WOLFSSL_CHECK_MEM_ZERO
8317
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
8318
    #endif
8319
        qbits = mp_count_bits(order);
8320
        if (qbits < 0)
8321
            ret = MP_VAL;
8322
    }
8323
8324
    if (ret == 0) {
8325
         /* hash truncate if too long */
8326
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
8327
            /* calculate truncated hash size using bits rounded up byte */
8328
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
8329
        }
8330
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
8331
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8332
        /* RFC 6979 2.3.2 bits2int: keep only the leftmost qlen bits, the
8333
         * byte truncation above can leave up to 7 extra low bits */
8334
        if ((ret == 0) &&
8335
                (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits)) {
8336
            mp_rshb(z1, (int)((WOLFSSL_BIT_SIZE * hashSz) - (word32)qbits));
8337
        }
8338
    #endif
8339
    }
8340
8341
    /* bits2octets on h1 */
8342
    if (ret == 0) {
8343
        XMEMSET(h1, 0, MAX_ECC_ORDER_BYTES);
8344
8345
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8346
        /* mod reduce by order using conditional subtract
8347
         * RFC6979 lists a variant that uses the hash directly instead of
8348
         * doing bits2octets(H(m)), when variant macro is used avoid this
8349
         * bits2octets operation. */
8350
        if (mp_cmp(z1, order) != MP_LT) {
8351
            int z1Sz;
8352
8353
            ret  = mp_sub(z1, order, z1);
8354
            z1Sz = mp_unsigned_bin_size(z1);
8355
            if (ret == 0) {
8356
                if (z1Sz < 0 || z1Sz > MAX_ECC_ORDER_BYTES) {
8357
                    ret = BUFFER_E;
8358
                }
8359
                else {
8360
                    ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8361
                }
8362
            }
8363
        }
8364
        else
8365
    #endif
8366
        {
8367
            /* use original hash and keep leading 0's */
8368
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8369
        }
8370
    }
8371
    mp_free(z1);
8372
8373
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
8374
    if (ret == 0) {
8375
        intOct = 0x00;
8376
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
8377
                hashType, heap);
8378
    }
8379
8380
    /* 3.2 step e. V = HMAC_K(V) */
8381
    if (ret == 0) {
8382
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8383
                heap);
8384
    }
8385
8386
8387
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
8388
    if (ret == 0) {
8389
        intOct = 0x01;
8390
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
8391
                heap);
8392
    }
8393
8394
    /* 3.2 step g. V = HMAC_K(V) */
8395
    if (ret == 0) {
8396
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8397
                heap);
8398
    }
8399
8400
    /* 3.2 step h. loop through the next steps until a valid value is found */
8401
    if (ret == 0 ) {
8402
        int err;
8403
8404
        intOct = 0x00;
8405
        do {
8406
            xSz = 0; /* used as tLen */
8407
            err = 0; /* start as good until generated k is tested */
8408
8409
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
8410
            while (xSz < qLen) {
8411
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8412
                        hashType, heap);
8413
                if (ret == 0) {
8414
                    int sz;
8415
8416
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
8417
                    XMEMCPY(x + xSz, V, (size_t)sz);
8418
                    xSz += (word32)sz;
8419
                }
8420
                else {
8421
                    break; /* error case */
8422
                }
8423
            }
8424
8425
            if (ret == 0) {
8426
                mp_clear(k); /* 3.2 step h.1 clear T */
8427
                ret = mp_read_unsigned_bin(k, x, xSz);
8428
            }
8429
8430
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
8431
                /* handle odd case where shift of 'k' is needed with RFC 6979
8432
                 *  k = bits2int(T) in section 3.2 h.3 */
8433
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
8434
            }
8435
8436
            /* 3.2 step h.3 the key should be smaller than the order of base
8437
             * point */
8438
            if (ret == 0) {
8439
                if (mp_cmp(k, order) != MP_LT) {
8440
                    err = MP_VAL;
8441
                } else if (mp_iszero(k) == MP_YES) {
8442
                    /* no 0 key's */
8443
                    err = MP_ZERO_E;
8444
                }
8445
            }
8446
8447
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
8448
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
8449
            if (ret == 0 && err != 0) {
8450
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
8451
                    hashType, heap);
8452
                if (ret == 0) {
8453
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8454
                    hashType, heap);
8455
                }
8456
            }
8457
        } while (ret == 0 && err != 0);
8458
    }
8459
8460
    ForceZero(x, MAX_ECC_ORDER_BYTES);
8461
    ForceZero(K, WC_MAX_DIGEST_SIZE);
8462
    ForceZero(V, WC_MAX_DIGEST_SIZE);
8463
#ifdef WOLFSSL_SMALL_STACK
8464
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
8465
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8466
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8467
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8468
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8469
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8470
    wc_MemZero_Check(x, MAX_ECC_ORDER_BYTES);
8471
    wc_MemZero_Check(K, WC_MAX_DIGEST_SIZE);
8472
    wc_MemZero_Check(V, WC_MAX_DIGEST_SIZE);
8473
#endif
8474
8475
    return ret;
8476
}
8477
8478
8479
/* Sets the deterministic flag for 'k' generation with sign.
8480
 * returns 0 on success
8481
 */
8482
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
8483
                                enum wc_HashType hashType)
8484
{
8485
    if (key == NULL) {
8486
        return BAD_FUNC_ARG;
8487
    }
8488
8489
    key->deterministic = flag ? 1 : 0;
8490
    key->hashType = hashType;
8491
    return 0;
8492
}
8493
8494
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
8495
{
8496
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
8497
}
8498
8499
#endif /* end sign_ex and deterministic sign */
8500
8501
8502
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
8503
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
8504
{
8505
    int ret = MP_OKAY;
8506
    DECLARE_CURVE_SPECS(1);
8507
8508
    if (k == NULL || klen == 0 || key == NULL) {
8509
        return BAD_FUNC_ARG;
8510
    }
8511
8512
    ALLOC_CURVE_SPECS(1, ret);
8513
    if (ret == MP_OKAY) {
8514
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8515
    }
8516
8517
    if (ret != 0) {
8518
        FREE_CURVE_SPECS();
8519
        return ret;
8520
    }
8521
8522
#ifndef WOLFSSL_NO_MALLOC
8523
    if (key->sign_k == NULL) {
8524
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
8525
                                                            DYNAMIC_TYPE_ECC);
8526
        if (key->sign_k) {
8527
            ret = mp_init(key->sign_k);
8528
        }
8529
        else {
8530
            ret = MEMORY_E;
8531
        }
8532
    }
8533
#endif
8534
8535
    if (ret == 0) {
8536
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
8537
    }
8538
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
8539
        ret = MP_VAL;
8540
        ecc_sign_k_forcezero(key);
8541
    }
8542
#ifdef WOLFSSL_NO_MALLOC
8543
    if (ret == 0) {
8544
        key->sign_k_set = 1;
8545
    }
8546
#endif
8547
8548
    wc_ecc_curve_free(curve);
8549
    FREE_CURVE_SPECS();
8550
    return ret;
8551
}
8552
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
8553
#endif /* WOLFSSL_ATECC508A */
8554
8555
#if defined(WOLFSSL_DHUK) && defined(WC_STM32_HAS_DHUK) && \
8556
    (defined(WOLFSSL_STM32_BARE) || defined(WOLFSSL_STM32_CUBEMX))
8557
/* Import a hardware-wrapped ECC private scalar + its derivation seed onto the
8558
 * ecc_key for the DHUK crypto-callback sign path. The scalar is AES-encrypted
8559
 * (offline or on-chip) with the device key that the SAES derives from the seed;
8560
 * at sign time it is decrypted into a short-lived buffer. The devId is NOT set
8561
 * here -- enable the device by setting devId at init
8562
 * (wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID)). See ecc.h for the contract. */
8563
int wc_ecc_import_wrapped_private(ecc_key* key, int curve_id,
8564
                                  const byte* seed, word32 seedSz,
8565
                                  const byte* wrapped, word32 wrappedLen,
8566
                                  word32 plainLen)
8567
{
8568
    int ret;
8569
8570
    if (key == NULL || seed == NULL || wrapped == NULL) {
8571
        return BAD_FUNC_ARG;
8572
    }
8573
    /* Seed is the 256-bit DHUK derivation secret. */
8574
    if (seedSz != sizeof(key->dhuk_seed)) {
8575
        return BAD_FUNC_ARG;
8576
    }
8577
    /* Wrapped scalar blob must be a non-zero multiple of one AES block. */
8578
    if (wrappedLen == 0u || (wrappedLen % 16u) != 0u) {
8579
        return BAD_FUNC_ARG;
8580
    }
8581
    if (wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
8582
        return BAD_FUNC_ARG;
8583
    }
8584
    /* Plain length must fit inside the wrapped blob and be non-zero. */
8585
    if (plainLen == 0u || plainLen > wrappedLen) {
8586
        return BAD_FUNC_ARG;
8587
    }
8588
    /* Wrapped blob must be no larger than the plaintext padded up to a full
8589
     * AES block; a larger blob is malformed and would overrun the fixed-size
8590
     * unwrap buffer used during signing. */
8591
    if (wrappedLen > ((plainLen + 15u) & ~15u)) {
8592
        return BAD_FUNC_ARG;
8593
    }
8594
    /* Validate the scalar size against the curve before touching the key, so a
8595
     * rejected import leaves no curve behind on a key that has no blob. */
8596
    ret = wc_ecc_get_curve_size_from_id(curve_id);
8597
    if (ret < 0) {
8598
        return ret;
8599
    }
8600
    if ((word32)ret != plainLen) {
8601
        return BAD_FUNC_ARG;
8602
    }
8603
8604
    /* The sign path needs the domain parameters to drive the PKA and returns
8605
     * ECC_BAD_ARG_E without them, and a caller starting from a bare
8606
     * wc_ecc_init() has no other way to supply them for a key that never holds
8607
     * its scalar in software. */
8608
    ret = wc_ecc_set_curve(key, (int)plainLen, curve_id);
8609
    if (ret != 0) {
8610
        return ret;
8611
    }
8612
8613
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
8614
    XMEMCPY(key->dhuk_seed, seed, seedSz);
8615
    key->dhuk_wrapped_priv_len = wrappedLen;
8616
    key->dhuk_plain_priv_len   = plainLen;
8617
    key->dhuk_seed_sz          = seedSz;
8618
#ifdef WOLFSSL_STM32_CCB
8619
    /* This is a DHUK seed-wrapped (non-CCB) scalar; clear any CCB blob
8620
     * routing left from a prior import so signing uses the DHUK path. */
8621
    key->dhuk_is_ccb = 0;
8622
#endif
8623
    return 0;
8624
}
8625
#endif /* WOLFSSL_DHUK && WC_STM32_HAS_DHUK && (BARE || CUBEMX) */
8626
8627
/* Guard must match the ecc.h prototype and the ccb_ / dhuk_ ecc_key struct
8628
 * members (both WOLFSSL_DHUK && WOLFSSL_STM32_CCB) -- the implementation must
8629
 * not be broader than the members it dereferences. */
8630
#if defined(WOLFSSL_DHUK) && defined(WOLFSSL_STM32_CCB)
8631
/* Load a previously provisioned device-protected ECDSA blob (wrapped scalar +
8632
 * AES-GCM iv/tag) and its public key onto the ecc_key. Sets the curve so the
8633
 * sign path can derive the parameters, and marks the key for the device
8634
 * crypto-callback. The caller enables the device with
8635
 * wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID). Generic name -- the wrapping is
8636
 * the STM32 CCB, but the surface is not CCB-specific. */
8637
int wc_ecc_import_wrapped_private_ex(ecc_key* key, int curve_id,
8638
                           const byte* wrapped, word32 wrappedLen,
8639
                           const byte* iv, word32 ivLen,
8640
                           const byte* tag, word32 tagLen,
8641
                           const byte* pub, word32 pubLen)
8642
{
8643
    int modSz;
8644
    int ret;
8645
8646
    if (key == NULL || wrapped == NULL || iv == NULL || tag == NULL ||
8647
        pub == NULL) {
8648
        return BAD_FUNC_ARG;
8649
    }
8650
    /* Fixed 16-byte AES-GCM iv/tag -- validate explicitly (no over-read). */
8651
    if (ivLen != sizeof(key->ccb_iv) || tagLen != sizeof(key->ccb_tag)) {
8652
        return BAD_FUNC_ARG;
8653
    }
8654
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8655
    if (modSz <= 0) {
8656
        return BAD_FUNC_ARG;
8657
    }
8658
    if (wrappedLen == 0u || wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
8659
        return BAD_FUNC_ARG;
8660
    }
8661
    if (pubLen != (word32)(2 * modSz)) {
8662
        return BAD_FUNC_ARG;
8663
    }
8664
    /* Import public key (qx||qy) + set the curve (key->dp). */
8665
    ret = wc_ecc_import_unsigned(key, pub, pub + modSz, NULL, curve_id);
8666
    if (ret != 0) {
8667
        return ret;
8668
    }
8669
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
8670
    key->dhuk_wrapped_priv_len = wrappedLen;
8671
    XMEMCPY(key->ccb_iv,  iv,  sizeof(key->ccb_iv));
8672
    XMEMCPY(key->ccb_tag, tag, sizeof(key->ccb_tag));
8673
    key->dhuk_is_ccb = 1;
8674
    /* Clear any DHUK seed-import state left from a prior import; the CCB
8675
     * path keys off the wrapped blob + iv/tag, not the seed. */
8676
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8677
    key->dhuk_seed_sz        = 0;
8678
    key->dhuk_plain_priv_len = 0;
8679
    return 0;
8680
}
8681
8682
/* Crypto-callback keygen handler (WC_PK_TYPE_EC_KEYGEN). Provisions a fresh
8683
 * device-protected key: generate a scalar, have the CCB wrap it into a
8684
 * device-bound blob and derive its public key, and store both on the ecc_key
8685
 * (the scalar is zeroized and never leaves this call / the hardware). The
8686
 * scalar is generated in software with the supplied rng on a throwaway key with
8687
 * no devId (so no callback recursion). Returns CRYPTOCB_UNAVAILABLE for curves
8688
 * the CCB cannot wrap so keygen falls back to software. Not a public entry
8689
 * point -- reached via wc_ecc_make_key() on a WC_DHUK_DEVID key. */
8690
int wc_ecc_dev_make_key(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
8691
{
8692
#ifdef WOLFSSL_SMALL_STACK
8693
    ecc_key* tmp = NULL;             /* ecc_key is ~1-2KB -- heap it on the
8694
                                      * small-stack embedded targets this port
8695
                                      * runs on (repo convention). */
8696
#else
8697
    ecc_key  tmp[1];
8698
#endif
8699
#ifdef WOLFSSL_SMALL_STACK
8700
    /* d || pub || wrapped in one heap scratch buffer (~326 B) -- keep the
8701
     * fixed byte buffers off the stack too, like tmp above. */
8702
    byte*   scratch = NULL;
8703
    byte*   d;
8704
    byte*   pub;       /* qx || qy, contiguous */
8705
    byte*   wrapped;
8706
#else
8707
    byte    d[MAX_ECC_BYTES];
8708
    byte    pub[2 * MAX_ECC_BYTES];   /* qx || qy, contiguous */
8709
    byte    wrapped[96];
8710
#endif
8711
    byte    iv[16];
8712
    byte    tag[16];
8713
    word32  dLen;
8714
    word32  wrappedSz = 0;
8715
    int     modSz;
8716
    int     ret;
8717
    int     tmpInit = 0;
8718
8719
    (void)keysize;
8720
    if (rng == NULL || key == NULL) {
8721
        return BAD_FUNC_ARG;
8722
    }
8723
    /* wc_ecc_set_curve() ran before the callback, so key->dp is resolved even
8724
     * when curve_id came in as the default. */
8725
    if (curve_id <= 0 && key->dp != NULL) {
8726
        curve_id = key->dp->id;
8727
    }
8728
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8729
    if (modSz <= 0 || (word32)modSz > MAX_ECC_BYTES) {
8730
        return CRYPTOCB_UNAVAILABLE;   /* unsupported -> software keygen */
8731
    }
8732
8733
#ifdef WOLFSSL_SMALL_STACK
8734
    tmp = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
8735
    if (tmp == NULL) {
8736
        return MEMORY_E;
8737
    }
8738
    scratch = (byte*)XMALLOC((3 * MAX_ECC_BYTES) + 96, key->heap,
8739
                             DYNAMIC_TYPE_TMP_BUFFER);
8740
    if (scratch == NULL) {
8741
        XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8742
        return MEMORY_E;
8743
    }
8744
    d       = scratch;
8745
    pub     = scratch + MAX_ECC_BYTES;
8746
    wrapped = scratch + (3 * MAX_ECC_BYTES);
8747
#endif
8748
8749
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8750
    /* Register the stack private-key buffer before keygen/export so any exit
8751
     * before the ForceZero is checked. XMEMSET makes it defined. */
8752
    XMEMSET(d, 0, MAX_ECC_BYTES);
8753
    wc_MemZero_Add("wc_ecc_dev_make_key d", d, MAX_ECC_BYTES);
8754
#endif
8755
    ret = wc_ecc_init_ex(tmp, key->heap, INVALID_DEVID);
8756
    if (ret == 0) {
8757
        tmpInit = 1;
8758
        ret = wc_ecc_make_key_ex(rng, modSz, tmp, curve_id);
8759
    }
8760
    if (ret == 0) {
8761
        dLen = (word32)modSz;
8762
        ret = wc_ecc_export_private_only(tmp, d, &dLen);
8763
    }
8764
    if (ret == 0) {
8765
        ret = wc_Stm32_Ccb_EccMakeBlob(curve_id, d, dLen, iv, tag, wrapped,
8766
                                       &wrappedSz, pub, pub + modSz);
8767
        if (ret != 0) {
8768
            ret = CRYPTOCB_UNAVAILABLE;   /* curve not CCB-wrappable -> SW */
8769
        }
8770
    }
8771
    if (ret == 0) {
8772
        ret = wc_ecc_import_wrapped_private_ex(key, curve_id, wrapped, wrappedSz,
8773
                                     iv, (word32)sizeof(iv), tag,
8774
                                     (word32)sizeof(tag), pub,
8775
                                     (word32)(2 * modSz));
8776
    }
8777
8778
    ForceZero(d, MAX_ECC_BYTES);
8779
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8780
    wc_MemZero_Check(d, MAX_ECC_BYTES);
8781
#endif
8782
    if (tmpInit) {
8783
        wc_ecc_free(tmp);
8784
    }
8785
#ifdef WOLFSSL_SMALL_STACK
8786
    XFREE(scratch, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8787
    XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8788
#endif
8789
    return ret;
8790
}
8791
#endif /* WOLFSSL_DHUK && WOLFSSL_STM32_CCB */
8792
8793
#endif /* !HAVE_ECC_SIGN */
8794
8795
#ifdef WOLFSSL_CUSTOM_CURVES
8796
void wc_ecc_free_curve(ecc_set_type* curve, void* heap)
8797
{
8798
#ifndef WOLFSSL_ECC_CURVE_STATIC
8799
    if (curve->prime != NULL)
8800
        XFREE((void*)(wc_ptr_t)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
8801
    if (curve->Af != NULL)
8802
        XFREE((void*)(wc_ptr_t)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
8803
    if (curve->Bf != NULL)
8804
        XFREE((void*)(wc_ptr_t)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
8805
    if (curve->order != NULL)
8806
        XFREE((void*)(wc_ptr_t)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
8807
    if (curve->Gx != NULL)
8808
        XFREE((void*)(wc_ptr_t)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
8809
    if (curve->Gy != NULL)
8810
        XFREE((void*)(wc_ptr_t)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
8811
#endif
8812
8813
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
8814
8815
    (void)heap;
8816
}
8817
#endif /* WOLFSSL_CUSTOM_CURVES */
8818
8819
/**
8820
  Free an ECC key from memory
8821
  key   The key you wish to free
8822
*/
8823
WOLFSSL_ABI
8824
int wc_ecc_free(ecc_key* key)
8825
1.75k
{
8826
1.75k
    if (key == NULL) {
8827
0
        return 0;
8828
0
    }
8829
8830
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
8831
    if (key->devId != INVALID_DEVID) {
8832
        /* Best-effort HSM resource release; errors are intentionally discarded
8833
         * so that software cleanup always runs and wc_ecc_free() retains its
8834
         * ABI guarantee of returning 0 on success. */
8835
        (void)wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
8836
                         WC_PK_TYPE_EC_KEYGEN, 0, key);
8837
        /* always continue to software cleanup */
8838
    }
8839
#endif
8840
8841
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
8842
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
8843
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8844
#ifndef WOLFSSL_NO_MALLOC
8845
    if (key->sign_k != NULL)
8846
#endif
8847
    {
8848
        mp_forcezero(key->sign_k);
8849
        mp_free(key->sign_k);
8850
#ifndef WOLFSSL_NO_MALLOC
8851
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
8852
        key->sign_k = NULL;
8853
#endif
8854
    }
8855
#endif
8856
8857
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8858
    #ifdef WC_ASYNC_ENABLE_ECC
8859
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
8860
    #endif
8861
    wc_ecc_free_async(key);
8862
#endif
8863
8864
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
8865
    /* free secure memory */
8866
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
8867
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
8868
       caamFreePart(key->partNum);
8869
    }
8870
#endif
8871
8872
#ifdef WOLFSSL_SE050
8873
#ifdef WOLFSSL_SE050_AUTO_ERASE
8874
    wc_se050_erase_object(key->keyId);
8875
#endif
8876
    se050_ecc_free_key(key);
8877
#endif
8878
8879
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
8880
    defined(WOLFSSL_MICROCHIP_TA100)
8881
    atmel_ecc_free(key->slot);
8882
    key->slot = ATECC_INVALID_SLOT;
8883
#endif /* WOLFSSL_ATECC508A */
8884
8885
#ifdef WOLFSSL_KCAPI_ECC
8886
    KcapiEcc_Free(key);
8887
#endif
8888
8889
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
8890
    key->privKey = NULL;
8891
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
8892
    ForceZero(&key->xSec, sizeof(key->xSec));
8893
#endif
8894
8895
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
8896
    wc_MAXQ10XX_EccFree(key);
8897
#endif
8898
8899
#ifdef WOLFSSL_SILABS_SE_TYPES
8900
    /* key_raw holds the private scalar alongside the public point whenever the
8901
     * SE has been handed a plaintext key. Scrub it. */
8902
    ForceZero(key->key_raw, sizeof(key->key_raw));
8903
    key->silabsKeySet = 0;
8904
#endif
8905
8906
#ifdef WOLFSSL_DHUK
8907
    /* Scrub the DHUK derivation seed and wrapped scalar (both secret). */
8908
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8909
    ForceZero(key->dhuk_wrapped_priv, sizeof(key->dhuk_wrapped_priv));
8910
    key->dhuk_seed_sz = 0;
8911
    key->dhuk_wrapped_priv_len = 0;
8912
    key->dhuk_plain_priv_len = 0;
8913
#endif
8914
8915
1.75k
    mp_clear(key->pubkey.x);
8916
1.75k
    mp_clear(key->pubkey.y);
8917
1.75k
    mp_clear(key->pubkey.z);
8918
8919
#ifdef ALT_ECC_SIZE
8920
    if (key->k)
8921
#endif
8922
1.75k
        mp_forcezero(key->k);
8923
#ifdef WOLFSSL_ECC_BLIND_K
8924
#ifdef ALT_ECC_SIZE
8925
    if (key->kb)
8926
#endif
8927
        mp_forcezero(key->kb);
8928
#ifdef ALT_ECC_SIZE
8929
    if (key->ku)
8930
#endif
8931
        mp_forcezero(key->ku);
8932
#endif
8933
8934
#ifdef WOLFSSL_CUSTOM_CURVES
8935
    if (key->deallocSet && key->dp != NULL) {
8936
        wc_ecc_free_curve((ecc_set_type *)(wc_ptr_t)key->dp, key->heap);
8937
        key->dp = NULL;
8938
    }
8939
#endif
8940
8941
#ifdef WOLFSSL_CHECK_MEM_ZERO
8942
    wc_MemZero_Check(key, sizeof(ecc_key));
8943
#endif
8944
8945
1.75k
    return 0;
8946
1.75k
}
8947
8948
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
8949
    !defined(WOLFSSL_SP_MATH) && \
8950
    !defined(WOLFSSL_NO_ECC_SW) && \
8951
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
8952
      defined(WOLFSSL_IMXRT1170_CAAM))
8953
/* Set a point to the representation of infinity, (0, 0, 1). */
8954
static int ecc_set_point_infinity(ecc_point* P)
8955
0
{
8956
0
    int err = mp_set(P->x, 0);
8957
0
    if (err == MP_OKAY)
8958
0
        err = mp_set(P->y, 0);
8959
0
    if (err == MP_OKAY)
8960
0
        err = mp_set(P->z, 1);
8961
0
    return err;
8962
0
}
8963
8964
/* Copy S over D when copy is non-zero, without branching on copy. */
8965
static int ecc_cond_copy_point(ecc_point* S, int copy, ecc_point* D)
8966
0
{
8967
0
    int err = mp_cond_copy(S->x, copy, D->x);
8968
0
    if (err == MP_OKAY)
8969
0
        err = mp_cond_copy(S->y, copy, D->y);
8970
0
    if (err == MP_OKAY)
8971
0
        err = mp_cond_copy(S->z, copy, D->z);
8972
0
    return err;
8973
0
}
8974
8975
/* Add A and B, handling the exceptional cases the projective add formula
8976
 * cannot represent. The exceptional inputs are noted with non-short-circuit
8977
 * tests, then the add always runs and the exceptional results are selected
8978
 * in over its output:
8979
 *
8980
 *   A is infinity     -> B copied over the result.
8981
 *   B is infinity     -> A copied over the result.
8982
 *   A = B             -> Doubled by the add itself when the z values match;
8983
 *                        all-zero result when they differ - doubled here.
8984
 *   A + B = infinity  -> Add result has z == 0, x/y not 0; set to infinity.
8985
 *
8986
 * The infinity out-flag is set only for the last case - a finite pair whose
8987
 * sum is infinity - matching the original branching version, which never
8988
 * touched the flag when copying an operand out.
8989
 */
8990
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8991
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8992
0
{
8993
0
    int err;
8994
0
    int aInf;
8995
0
    int bInf;
8996
0
    int rInf = 0;
8997
#ifdef WOLFSSL_SMALL_STACK
8998
    ecc_point* T = NULL;
8999
#else
9000
0
    ecc_point  T_lcl[1];
9001
0
    ecc_point* T = T_lcl;
9002
0
#endif
9003
9004
    /* Note the exceptional inputs with non-short-circuit tests, then add
9005
     * regardless, so they cost the same as the ordinary case. The result
9006
     * goes to a temporary: callers pass the first operand as the
9007
     * destination, so writing R early would destroy A before the selection
9008
     * below. */
9009
0
    aInf  = (mp_iszero(A->x) == MP_YES);
9010
0
    aInf &= (mp_iszero(A->y) == MP_YES);
9011
0
    bInf  = (mp_iszero(B->x) == MP_YES);
9012
0
    bInf &= (mp_iszero(B->y) == MP_YES);
9013
9014
    /* Off the stack unless the build asked for small stacks. Inherit the
9015
     * key's heap and small-stack cache from R so the temporary behaves like
9016
     * the caller's own points - this is the scalar multiplication inner
9017
     * loop. */
9018
#if defined(WOLFSSL_SMALL_STACK_CACHE) && !defined(WOLFSSL_ECC_NO_SMALL_STACK)
9019
    err = wc_ecc_new_point_ex(&T, (R->key != NULL) ? R->key->heap : NULL);
9020
#else
9021
0
    err = wc_ecc_new_point_ex(&T, NULL);
9022
0
#endif
9023
0
    if (err != MP_OKAY) {
9024
0
        return err;
9025
0
    }
9026
#if defined(WOLFSSL_SMALL_STACK_CACHE) && !defined(WOLFSSL_ECC_NO_SMALL_STACK)
9027
    T->key = R->key;
9028
#endif
9029
9030
0
    err = _ecc_projective_add_point(A, B, T, a, modulus, mp);
9031
0
    if ((err == MP_OKAY) && mp_iszero(T->z)) {
9032
        /* When all zero then should have done a double */
9033
0
        if (mp_iszero(T->x) && mp_iszero(T->y)) {
9034
0
            if (mp_iszero(B->z)) {
9035
0
                err = wc_ecc_copy_point(B, T);
9036
0
                if (err == MP_OKAY) {
9037
0
                    err = mp_montgomery_calc_normalization(T->z, modulus);
9038
0
                }
9039
0
                if (err == MP_OKAY) {
9040
0
                    err = _ecc_projective_dbl_point(T, T, a, modulus, mp);
9041
0
                }
9042
0
            }
9043
0
            else {
9044
0
                err = _ecc_projective_dbl_point(B, T, a, modulus, mp);
9045
0
            }
9046
0
        }
9047
        /* When only Z zero then result is infinity */
9048
0
        else {
9049
0
            err = ecc_set_point_infinity(T);
9050
0
            rInf = 1;
9051
0
        }
9052
0
    }
9053
9054
    /* Select without branching on which operand was infinity: A infinity
9055
     * gives B, B infinity gives A. Both infinity leaves A, itself infinity,
9056
     * so needs no separate case. */
9057
0
    if (err == MP_OKAY)
9058
0
        err = ecc_cond_copy_point(B, aInf, T);
9059
0
    if (err == MP_OKAY)
9060
0
        err = ecc_cond_copy_point(A, bInf, T);
9061
0
    if (err == MP_OKAY)
9062
0
        err = wc_ecc_copy_point(T, R);
9063
9064
    /* An infinity operand feeds the raw formula a shape it cannot represent,
9065
     * so the add's infinity note may be spurious. The selection above then
9066
     * replaces the result with the other operand, and that selection
9067
     * overrides the note as well: the flag reports only a result the add
9068
     * itself produced. */
9069
0
    rInf &= (aInf == 0);
9070
0
    rInf &= (bInf == 0);
9071
0
    if ((err == MP_OKAY) && (infinity != NULL) && (rInf != 0))
9072
0
        *infinity = 1;
9073
9074
#if defined(WOLFSSL_SMALL_STACK_CACHE) && !defined(WOLFSSL_ECC_NO_SMALL_STACK)
9075
    T->key = NULL;
9076
    wc_ecc_del_point_ex(T, (R->key != NULL) ? R->key->heap : NULL);
9077
#else
9078
0
    wc_ecc_del_point_ex(T, NULL);
9079
0
#endif
9080
9081
0
    return err;
9082
0
}
9083
9084
/* Handles when P is the infinity point.
9085
 *
9086
 * Double infinity -> infinity.
9087
 * Otherwise do normal double - which can't lead to infinity as odd order.
9088
 */
9089
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
9090
                                  mp_int* modulus, mp_digit mp)
9091
0
{
9092
0
    int err;
9093
0
    int inf;
9094
9095
    /* Note infinity before doubling - callers alias source and destination -
9096
     * then double regardless so the exceptional case costs the same. Doubling
9097
     * infinity gives infinity, as does a zero Z; both are written (0, 0, 1). */
9098
0
    inf  = (mp_iszero(P->x) == MP_YES);
9099
0
    inf &= (mp_iszero(P->y) == MP_YES);
9100
9101
0
    err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
9102
0
    if (err == MP_OKAY) {
9103
0
        inf |= (mp_iszero(R->z) == MP_YES);
9104
0
        if (inf) {
9105
0
            err = ecc_set_point_infinity(R);
9106
0
        }
9107
0
    }
9108
9109
0
    return err;
9110
0
}
9111
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
9112
          !(WOLFSSL_SP_MATH) && \
9113
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
9114
            (WOLFSSL_IMXRT1170_CAAM))
9115
        */
9116
9117
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
9118
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
9119
    !defined(WOLFSSL_NO_ECC_SW) && \
9120
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9121
#ifdef ECC_SHAMIR
9122
9123
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
9124
    ecc_point* Bm, mp_int* modulus, void* heap)
9125
0
{
9126
0
    int err = MP_OKAY;
9127
9128
0
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
9129
9130
0
    if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
9131
0
        return WC_KEY_SIZE_E;
9132
0
    }
9133
9134
0
    (void)heap;
9135
9136
0
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
9137
#ifdef MP_INT_SIZE_CHECK_NULL
9138
    if (mu == NULL)
9139
       err = MEMORY_E;
9140
#endif
9141
0
    if (err == MP_OKAY) {
9142
0
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
9143
0
    }
9144
0
    if (err == MP_OKAY) {
9145
0
        err = mp_montgomery_calc_normalization(mu, modulus);
9146
9147
0
        if (err == MP_OKAY) {
9148
            /* copy ones ... */
9149
0
            err = mp_mulmod(A->x, mu, modulus, Am->x);
9150
0
        }
9151
9152
0
        if (err == MP_OKAY)
9153
0
            err = mp_mulmod(A->y, mu, modulus, Am->y);
9154
0
        if (err == MP_OKAY)
9155
0
            err = mp_mulmod(A->z, mu, modulus, Am->z);
9156
9157
0
        if (err == MP_OKAY)
9158
0
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
9159
0
        if (err == MP_OKAY)
9160
0
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
9161
0
        if (err == MP_OKAY)
9162
0
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
9163
9164
        /* done with mu */
9165
0
        mp_clear(mu);
9166
0
    }
9167
9168
0
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
9169
9170
0
    return err;
9171
0
}
9172
9173
/** Computes kA*A + kB*B = C using Shamir's Trick
9174
  A        First point to multiply
9175
  kA       What to multiple A by
9176
  B        Second point to multiply
9177
  kB       What to multiple B by
9178
  C        [out] Destination point (can overlap with A or B)
9179
  a        ECC curve parameter a
9180
  modulus  Modulus for curve
9181
  return MP_OKAY on success
9182
*/
9183
#ifdef FP_ECC
9184
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
9185
                             ecc_point* B, mp_int* kB,
9186
                             ecc_point* C, mp_int* a, mp_int* modulus,
9187
                             void* heap)
9188
#else
9189
int ecc_mul2add(ecc_point* A, mp_int* kA,
9190
                    ecc_point* B, mp_int* kB,
9191
                    ecc_point* C, mp_int* a, mp_int* modulus,
9192
                    void* heap)
9193
#endif
9194
0
{
9195
#ifdef WOLFSSL_SMALL_STACK_CACHE
9196
  ecc_key        *key = NULL;
9197
#endif
9198
#ifdef WOLFSSL_SMALL_STACK
9199
  ecc_point**    precomp = NULL;
9200
#else
9201
0
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
9202
  #ifdef WOLFSSL_NO_MALLOC
9203
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
9204
  #endif
9205
0
#endif
9206
0
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
9207
#ifdef WOLFSSL_NO_MALLOC
9208
  unsigned char tA[ECC_BUFSIZE];
9209
  unsigned char tB[ECC_BUFSIZE];
9210
#else
9211
0
  unsigned char* tA = NULL;
9212
0
  unsigned char* tB = NULL;
9213
0
#endif
9214
0
  int            err = MP_OKAY, first, x, y;
9215
0
  mp_digit       mp = 0;
9216
9217
  /* argchks */
9218
0
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
9219
0
                                                         modulus == NULL) {
9220
0
     return ECC_BAD_ARG_E;
9221
0
  }
9222
0
  if ((mp_isneg(kA) == MP_YES) || (mp_isneg(kB) == MP_YES)) {
9223
0
     return ECC_OUT_OF_RANGE_E;
9224
0
  }
9225
9226
0
#ifndef WOLFSSL_NO_MALLOC
9227
  /* allocate memory */
9228
0
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
9229
0
  if (tA == NULL) {
9230
0
     return MP_MEM;
9231
0
  }
9232
0
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
9233
0
  if (tB == NULL) {
9234
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9235
0
     return MP_MEM;
9236
0
  }
9237
0
#endif
9238
9239
#ifdef WOLFSSL_SMALL_STACK_CACHE
9240
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
9241
  if (key == NULL) {
9242
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9243
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9244
     return MP_MEM;
9245
  }
9246
#endif
9247
#ifdef WOLFSSL_SMALL_STACK
9248
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
9249
                                                       DYNAMIC_TYPE_ECC_BUFFER);
9250
  if (precomp == NULL) {
9251
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9252
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9253
  #ifdef WOLFSSL_SMALL_STACK_CACHE
9254
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
9255
  #endif
9256
     return MP_MEM;
9257
  }
9258
#endif
9259
#ifdef WOLFSSL_SMALL_STACK_CACHE
9260
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
9261
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
9262
#ifdef ALT_ECC_SIZE
9263
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
9264
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
9265
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
9266
#endif
9267
9268
  if (key->t1 == NULL || key->t2 == NULL
9269
#ifdef ALT_ECC_SIZE
9270
     || key->x == NULL || key->y == NULL || key->z == NULL
9271
#endif
9272
  ) {
9273
#ifdef ALT_ECC_SIZE
9274
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
9275
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
9276
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
9277
#endif
9278
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
9279
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
9280
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
9281
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9282
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9283
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
9284
      return MEMORY_E;
9285
  }
9286
  C->key = key;
9287
#endif /* WOLFSSL_SMALL_STACK_CACHE */
9288
9289
  /* init variables */
9290
0
  XMEMSET(tA, 0, ECC_BUFSIZE);
9291
0
  XMEMSET(tB, 0, ECC_BUFSIZE);
9292
0
#ifndef WOLFSSL_SMALL_STACK
9293
0
  XMEMSET(precomp, 0, sizeof(precomp));
9294
#else
9295
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
9296
#endif
9297
#ifdef WOLFSSL_CHECK_MEM_ZERO
9298
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
9299
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
9300
#endif
9301
9302
  /* get sizes */
9303
0
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
9304
0
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
9305
0
  len  = MAX(lenA, lenB);
9306
9307
  /* sanity check */
9308
0
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
9309
0
    err = BAD_FUNC_ARG;
9310
0
  }
9311
9312
0
  if (err == MP_OKAY) {
9313
    /* extract and justify kA */
9314
0
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
9315
9316
    /* extract and justify kB */
9317
0
    if (err == MP_OKAY)
9318
0
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
9319
9320
    /* allocate the table */
9321
0
    if (err == MP_OKAY) {
9322
0
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
9323
        #ifdef WOLFSSL_NO_MALLOC
9324
            precomp[x] = &lcl_precomp[x];
9325
        #endif
9326
0
            err = wc_ecc_new_point_ex(&precomp[x], heap);
9327
0
            if (err != MP_OKAY)
9328
0
                break;
9329
        #ifdef WOLFSSL_SMALL_STACK_CACHE
9330
            precomp[x]->key = key;
9331
        #endif
9332
0
        }
9333
0
    }
9334
0
  }
9335
9336
0
  if (err == MP_OKAY)
9337
    /* init montgomery reduction */
9338
0
    err = mp_montgomery_setup(modulus, &mp);
9339
9340
0
  if (err == MP_OKAY) {
9341
0
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
9342
0
  }
9343
9344
0
  if (err == MP_OKAY) {
9345
    /* precomp [i,0](A + B) table */
9346
0
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
9347
0
  }
9348
0
  if (err == MP_OKAY) {
9349
0
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
9350
0
                                                          a, modulus, mp, NULL);
9351
0
  }
9352
9353
0
  if (err == MP_OKAY) {
9354
    /* precomp [0,i](A + B) table */
9355
0
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
9356
0
  }
9357
0
  if (err == MP_OKAY) {
9358
0
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
9359
0
                                                             modulus, mp, NULL);
9360
0
  }
9361
9362
0
  if (err == MP_OKAY) {
9363
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
9364
0
    for (x = 1; x < 4; x++) {
9365
0
      for (y = 1; y < 4; y++) {
9366
0
        if (err == MP_OKAY) {
9367
0
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
9368
0
                                                  precomp[x+(y<<2)], a, modulus,
9369
0
                                                  mp, NULL);
9370
0
        }
9371
0
      }
9372
0
    }
9373
0
  }
9374
9375
0
  if (err == MP_OKAY) {
9376
0
    nibble  = 3;
9377
0
    first   = 1;
9378
0
    bitbufA = tA[0];
9379
0
    bitbufB = tB[0];
9380
9381
    /* for every byte of the multiplicands */
9382
0
    for (x = 0; x < (int)len || nibble != 3; ) {
9383
        /* grab a nibble */
9384
0
        if (++nibble == 4) {
9385
0
            if (x == (int)len) break;
9386
0
            bitbufA = tA[x];
9387
0
            bitbufB = tB[x];
9388
0
            nibble  = 0;
9389
0
            x++;
9390
0
        }
9391
9392
        /* extract two bits from both, shift/update */
9393
0
        nA = (bitbufA >> 6) & 0x03;
9394
0
        nB = (bitbufB >> 6) & 0x03;
9395
0
        bitbufA = (bitbufA << 2) & 0xFF;
9396
0
        bitbufB = (bitbufB << 2) & 0xFF;
9397
9398
        /* if both zero, if first, continue */
9399
0
        if ((nA == 0) && (nB == 0) && (first == 1)) {
9400
0
            continue;
9401
0
        }
9402
9403
        /* double twice, only if this isn't the first */
9404
0
        if (first == 0) {
9405
            /* double twice */
9406
0
            if (err == MP_OKAY)
9407
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9408
0
            if (err == MP_OKAY)
9409
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9410
0
            else
9411
0
                break;
9412
0
        }
9413
9414
        /* if not both zero */
9415
0
        if ((nA != 0) || (nB != 0)) {
9416
0
            unsigned int i = nA + (nB<<2);
9417
0
            if (first == 1) {
9418
                /* if first, copy from table */
9419
0
                first = 0;
9420
0
                if (err == MP_OKAY)
9421
0
                    err = mp_copy(precomp[i]->x, C->x);
9422
9423
0
                if (err == MP_OKAY)
9424
0
                    err = mp_copy(precomp[i]->y, C->y);
9425
9426
0
                if (err == MP_OKAY)
9427
0
                    err = mp_copy(precomp[i]->z, C->z);
9428
0
                else
9429
0
                    break;
9430
0
            } else {
9431
                /* if not first, add from table */
9432
0
                if (err == MP_OKAY)
9433
0
                    err = ecc_projective_add_point_safe(C, precomp[i],
9434
0
                                                        C, a, modulus, mp,
9435
0
                                                        &first);
9436
0
                if (err != MP_OKAY)
9437
0
                    break;
9438
0
            }
9439
0
        }
9440
0
    }
9441
9442
    /* kA and kB both 0, or the last add gave infinity */
9443
0
    if ((err == MP_OKAY) && (first == 1)) {
9444
0
        err = ecc_set_point_infinity(C);
9445
0
    }
9446
0
  }
9447
9448
  /* reduce to affine */
9449
0
  if (err == MP_OKAY)
9450
0
    err = ecc_map(C, modulus, mp);
9451
9452
  /* clean up */
9453
0
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
9454
0
     wc_ecc_del_point_ex(precomp[x], heap);
9455
0
  }
9456
9457
0
  ForceZero(tA, ECC_BUFSIZE);
9458
0
  ForceZero(tB, ECC_BUFSIZE);
9459
#ifdef WOLFSSL_SMALL_STACK_CACHE
9460
#ifdef ALT_ECC_SIZE
9461
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
9462
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
9463
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
9464
#endif
9465
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
9466
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
9467
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
9468
  C->key = NULL;
9469
#endif
9470
0
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
9471
0
#ifndef WOLFSSL_NO_MALLOC
9472
0
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9473
0
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9474
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
9475
  wc_MemZero_Check(tB, ECC_BUFSIZE);
9476
  wc_MemZero_Check(tA, ECC_BUFSIZE);
9477
#endif
9478
0
  return err;
9479
0
}
9480
9481
#endif /* ECC_SHAMIR */
9482
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
9483
        * !WOLFSSL_CRYPTOCEL */
9484
9485
9486
#ifdef HAVE_ECC_VERIFY
9487
/* verify
9488
 *
9489
 * w  = s^-1 mod n
9490
 * u1 = xw
9491
 * u2 = rw
9492
 * X = u1*G + u2*Q
9493
 * v = X_x1 mod n
9494
 * accept if v == r
9495
 */
9496
9497
/**
9498
 Verify an ECC signature
9499
 sig         The signature to verify
9500
 siglen      The length of the signature (octets)
9501
 hash        The hash (message digest) that was signed
9502
 hashlen     The length of the hash (octets)
9503
 res         Result of signature, 1==valid, 0==invalid
9504
 key         The corresponding public ECC key
9505
 return      MP_OKAY if successful (even if the signature is not valid)
9506
             Caller should check the *res value to determine if the signature
9507
             is valid or invalid. Other negative values are returned on error.
9508
 */
9509
WOLFSSL_ABI
9510
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
9511
                       word32 hashlen, int* res, ecc_key* key)
9512
0
{
9513
0
    int err;
9514
9515
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9516
    mp_int *r = NULL, *s = NULL;
9517
#else
9518
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9519
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9520
0
#endif
9521
#ifdef WOLFSSL_ASYNC_CRYPT
9522
    int isPrivateKeyOnly = 0;
9523
#endif
9524
#if defined(NO_ASN) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9525
    word32 keySz;
9526
#endif
9527
9528
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
9529
0
        return WC_KEY_SIZE_E;
9530
0
    }
9531
9532
0
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
9533
0
        return ECC_BAD_ARG_E;
9534
0
    }
9535
9536
    /* Check hash length */
9537
0
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
9538
0
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
9539
0
        return BAD_LENGTH_E;
9540
0
    }
9541
9542
#ifdef WOLF_CRYPTO_CB
9543
    #ifndef WOLF_CRYPTO_CB_FIND
9544
    if (key->devId != INVALID_DEVID)
9545
    #endif
9546
    {
9547
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
9548
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9549
            return err;
9550
        /* fall-through when unavailable */
9551
    }
9552
#endif
9553
9554
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
9555
    (void)siglen;
9556
    (void)hashlen;
9557
    (void)s;
9558
    (void)r;
9559
    (void)err;
9560
    return NO_VALID_DEVID;
9561
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
9562
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9563
    err = wc_ecc_alloc_async(key);
9564
    if (err != 0)
9565
        return err;
9566
    r = key->r;
9567
    s = key->s;
9568
#else
9569
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9570
0
        DYNAMIC_TYPE_ECC);
9571
    #ifdef MP_INT_SIZE_CHECK_NULL
9572
    if (r == NULL)
9573
        return MEMORY_E;
9574
    #endif
9575
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9576
0
        DYNAMIC_TYPE_ECC);
9577
    #ifdef MP_INT_SIZE_CHECK_NULL
9578
    if (s == NULL) {
9579
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9580
        return MEMORY_E;
9581
    }
9582
    #endif
9583
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9584
0
    if (err != 0) {
9585
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9586
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9587
0
        return err;
9588
0
    }
9589
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9590
0
    if (err != 0) {
9591
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9592
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9593
0
        return err;
9594
0
    }
9595
0
#endif /* WOLFSSL_ASYNC_CRYPT */
9596
9597
0
    switch (key->state) {
9598
0
        case ECC_STATE_NONE:
9599
0
        case ECC_STATE_VERIFY_DECODE:
9600
0
            key->state = ECC_STATE_VERIFY_DECODE;
9601
9602
            /* default to invalid signature */
9603
0
            *res = 0;
9604
9605
0
    #ifndef NO_ASN
9606
            /* Decode ASN.1 ECDSA signature. */
9607
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9608
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
9609
             * If either of those don't allocate correctly, none of
9610
             * the rest of this function will execute, and everything
9611
             * gets cleaned up at the end. */
9612
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
9613
        #else
9614
            /* r and s are initialized. */
9615
0
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
9616
0
        #endif
9617
0
            if (err < 0) {
9618
0
                break;
9619
0
            }
9620
    #else
9621
            /* No support for DSA ASN.1 header.
9622
             * Signature must be r+s directly. */
9623
            keySz = 0;
9624
            if (key->dp != NULL) {
9625
                keySz = (word32)key->dp->size;
9626
                /* Also accept r and s at the size of the order. */
9627
                if (siglen == ecc_order_size(key->dp) * 2) {
9628
                    keySz = siglen / 2;
9629
                }
9630
            }
9631
            if ((keySz == 0) || (siglen != keySz * 2)) {
9632
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
9633
                err = WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
9634
                break;
9635
            }
9636
9637
            /* Import signature into r,s */
9638
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9639
            err = mp_init_multi(r, s, NULL, NULL, NULL, NULL);
9640
            if (err != MP_OKAY) {
9641
                break;
9642
            }
9643
        #endif
9644
            err = mp_read_unsigned_bin(r, sig, keySz);
9645
            if (err == MP_OKAY) {
9646
                err = mp_read_unsigned_bin(s, sig + keySz, keySz);
9647
            }
9648
            if (err != MP_OKAY) {
9649
                break;
9650
            }
9651
    #endif /* !NO_ASN */
9652
0
            FALL_THROUGH;
9653
9654
0
        case ECC_STATE_VERIFY_DO:
9655
0
            key->state = ECC_STATE_VERIFY_DO;
9656
        #ifdef WOLFSSL_ASYNC_CRYPT
9657
            if (key->type == ECC_PRIVATEKEY_ONLY) {
9658
                isPrivateKeyOnly = 1;
9659
            }
9660
        #endif
9661
0
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9662
9663
0
        #ifndef WOLFSSL_ASYNC_CRYPT
9664
            /* done with R/S */
9665
0
            mp_clear(r);
9666
0
            mp_clear(s);
9667
0
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9668
0
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9669
        #ifdef MP_INT_SIZE_CHECK_NULL
9670
            r = NULL;
9671
            s = NULL;
9672
        #endif
9673
0
        #endif
9674
9675
0
            if (err < 0) {
9676
0
                break;
9677
0
            }
9678
0
            FALL_THROUGH;
9679
9680
0
        case ECC_STATE_VERIFY_RES:
9681
0
            key->state = ECC_STATE_VERIFY_RES;
9682
0
            err = 0;
9683
0
            break;
9684
9685
0
        default:
9686
0
            err = BAD_STATE_E;
9687
0
    }
9688
9689
#ifdef WOLFSSL_ASYNC_CRYPT
9690
    /* if async pending then return and skip done cleanup below */
9691
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
9692
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
9693
            key->state++;
9694
        return err;
9695
    }
9696
#endif
9697
9698
    /* cleanup */
9699
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9700
    wc_ecc_free_async(key);
9701
#else
9702
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9703
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9704
0
#endif
9705
9706
    /* make sure required variables are reset */
9707
0
    wc_ecc_reset(key);
9708
0
    return err;
9709
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
9710
0
}
9711
9712
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
9713
9714
#if (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
9715
    !defined(PSOC6_CRYPTO_ECC) && \
9716
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9717
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
9718
0
{
9719
0
    int err = MP_OKAY;
9720
0
    DECLARE_CURVE_SPECS(1);
9721
9722
0
    ALLOC_CURVE_SPECS(1, err);
9723
0
    if (err == MP_OKAY) {
9724
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
9725
0
    }
9726
0
    if (err != 0) {
9727
0
        FREE_CURVE_SPECS();
9728
0
        return err;
9729
0
    }
9730
9731
0
    if (mp_iszero(r) || mp_iszero(s)) {
9732
0
        err = MP_ZERO_E;
9733
0
    }
9734
    /* FIPS 186-5 sec 6.4.2 step 1: r and s must be in [1, n-1]. */
9735
0
    if ((err == 0) && (mp_isneg(r) || (mp_cmp(r, curve->order) != MP_LT))) {
9736
0
        err = MP_VAL;
9737
0
    }
9738
0
    if ((err == 0) && (mp_isneg(s) || (mp_cmp(s, curve->order) != MP_LT))) {
9739
0
        err = MP_VAL;
9740
0
    }
9741
9742
0
    wc_ecc_curve_free(curve);
9743
0
    FREE_CURVE_SPECS();
9744
0
    return err;
9745
0
}
9746
#endif /* !WOLFSSL_STM32_PKA && !PSOC6_CRYPTO_ECC */
9747
9748
#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP)
9749
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
9750
    word32 hashlen, int* res, ecc_key* key)
9751
0
{
9752
0
    (void)r;
9753
0
    (void)s;
9754
0
    (void)hash;
9755
0
    (void)hashlen;
9756
0
    (void)res;
9757
0
    (void)key;
9758
9759
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
9760
  if (key->handle != -1) {
9761
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
9762
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9763
  }
9764
  if (wolfSSL_GetHandleCbSet() == 1) {
9765
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
9766
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9767
  }
9768
#endif
9769
9770
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
9771
    if (key->idx == ECC_CUSTOM_IDX || (1
9772
    #ifndef WOLFSSL_SP_NO_256
9773
         && ecc_sets[key->idx].id != ECC_SECP256R1
9774
    #endif
9775
    #ifdef WOLFSSL_SP_SM2
9776
         && ecc_sets[key->idx].id != ECC_SM2P256V1
9777
    #endif
9778
    #ifdef WOLFSSL_SP_384
9779
         && ecc_sets[key->idx].id != ECC_SECP384R1
9780
    #endif
9781
    #ifdef WOLFSSL_SP_521
9782
         && ecc_sets[key->idx].id != ECC_SECP521R1
9783
    #endif
9784
        )) {
9785
        return WC_KEY_SIZE_E;
9786
    }
9787
#endif
9788
9789
#if defined(WOLFSSL_HAVE_SP_ECC)
9790
    if (key->idx != ECC_CUSTOM_IDX) {
9791
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
9792
        /* perform blocking call to non-blocking function */
9793
        ecc_nb_ctx_t nb_ctx;
9794
        int err;
9795
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
9796
        err = NOT_COMPILED_IN; /* set default error */
9797
    #endif
9798
    #ifndef WOLFSSL_SP_NO_256
9799
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
9800
        #ifdef WC_ECC_NONBLOCK
9801
            if (key->nb_ctx) {
9802
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9803
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9804
                    key->heap);
9805
            }
9806
            #ifdef WC_ECC_NONBLOCK_ONLY
9807
            do { /* perform blocking call to non-blocking function */
9808
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
9809
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9810
                    key->heap);
9811
            } while (err == FP_WOULDBLOCK);
9812
            return err;
9813
            #endif
9814
        #endif /* WC_ECC_NONBLOCK */
9815
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9816
            {
9817
                int ret;
9818
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
9819
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9820
                return ret;
9821
            }
9822
        #endif
9823
        }
9824
    #endif
9825
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9826
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
9827
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
9828
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
9829
                key->pubkey.y, key->pubkey.z, r, s, res,
9830
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
9831
                                          key->fpIdx, key->fpBuild, key->heap),
9832
                key->heap);
9833
            #endif
9834
            #if !defined(FP_ECC_CONTROL)
9835
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
9836
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9837
            #endif
9838
        }
9839
    #endif
9840
    #ifdef WOLFSSL_SP_384
9841
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
9842
        #ifdef WC_ECC_NONBLOCK
9843
            if (key->nb_ctx) {
9844
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9845
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9846
                    key->heap);
9847
            }
9848
            #ifdef WC_ECC_NONBLOCK_ONLY
9849
            do { /* perform blocking call to non-blocking function */
9850
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
9851
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9852
                    key->heap);
9853
            } while (err == FP_WOULDBLOCK);
9854
            return err;
9855
            #endif
9856
        #endif /* WC_ECC_NONBLOCK */
9857
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9858
            {
9859
                int ret;
9860
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
9861
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9862
                return ret;
9863
            }
9864
        #endif
9865
        }
9866
    #endif
9867
    #ifdef WOLFSSL_SP_521
9868
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
9869
        #ifdef WC_ECC_NONBLOCK
9870
            if (key->nb_ctx) {
9871
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9872
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9873
                    key->heap);
9874
            }
9875
            #ifdef WC_ECC_NONBLOCK_ONLY
9876
            do { /* perform blocking call to non-blocking function */
9877
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
9878
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9879
                    key->heap);
9880
            } while (err == FP_WOULDBLOCK);
9881
            return err;
9882
            #endif
9883
        #endif /* WC_ECC_NONBLOCK */
9884
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9885
            {
9886
                int ret;
9887
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
9888
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9889
                return ret;
9890
            }
9891
        #endif
9892
        }
9893
    #endif
9894
    }
9895
#endif
9896
9897
0
    return NOT_COMPILED_IN;
9898
0
}
9899
9900
#if !defined(WOLFSSL_MICROCHIP) && \
9901
    (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC))
9902
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
9903
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
9904
0
{
9905
0
   int        err;
9906
0
   ecc_point* mG = NULL;
9907
0
   ecc_point* mQ = NULL;
9908
#if defined(WOLFSSL_CHECK_VER_FAULTS) && !defined(ECC_SHAMIR) && \
9909
    !defined(FREESCALE_LTC_ECC)
9910
   ecc_point* mG1 = NULL;
9911
   ecc_point* mQ1 = NULL;
9912
#endif
9913
#ifdef WOLFSSL_NO_MALLOC
9914
   ecc_point  lcl_mG;
9915
   ecc_point  lcl_mQ;
9916
#if defined(WOLFSSL_CHECK_VER_FAULTS) && !defined(ECC_SHAMIR) && \
9917
    !defined(FREESCALE_LTC_ECC)
9918
   ecc_point  lcl_mG1;
9919
   ecc_point  lcl_mQ1;
9920
#endif
9921
#endif
9922
9923
0
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9924
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9925
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9926
0
#endif
9927
0
   mp_int*    e;
9928
0
   mp_int*    v = NULL;      /* Will be w. */
9929
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
9930
   mp_int     u1tmp[1];
9931
   mp_int     u2tmp[1];
9932
#endif
9933
0
   mp_int*    u1 = NULL;     /* Will be e. */
9934
0
   mp_int*    u2 = NULL;     /* Will be w. */
9935
9936
0
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
9937
0
       return WC_KEY_SIZE_E;
9938
0
   }
9939
9940
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
9941
   err = wc_ecc_alloc_mpint(key, &key->e);
9942
   if (err != 0) {
9943
      return err;
9944
   }
9945
   e = key->e;
9946
9947
   err = mp_init(e);
9948
#else
9949
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
9950
#ifdef MP_INT_SIZE_CHECK_NULL
9951
   if (e_lcl == NULL) {
9952
       return MEMORY_E;
9953
   }
9954
#endif
9955
0
   e = e_lcl;
9956
9957
0
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9958
0
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
9959
0
   if (err != MP_OKAY) {
9960
#ifdef WOLFSSL_SMALL_STACK
9961
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9962
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9963
   #endif
9964
#endif
9965
0
      return MEMORY_E;
9966
0
   }
9967
9968
   /* read hash */
9969
0
   if (err == MP_OKAY) {
9970
       /* we may need to truncate if hash is longer than key size */
9971
0
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
9972
9973
       /* truncate down to byte size, may be all that's needed */
9974
0
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9975
0
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
9976
0
       err = mp_read_unsigned_bin(e, hash, hashlen);
9977
9978
       /* may still need bit truncation too */
9979
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9980
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
9981
0
   }
9982
9983
   /* check for async hardware acceleration */
9984
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9985
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9986
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
9987
   #ifdef HAVE_CAVIUM_V
9988
      if (NitroxEccIsCurveSupported(key))
9989
   #endif
9990
      {
9991
          word32 keySz = (word32)key->dp->size;
9992
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
9993
          if (err == MP_OKAY)
9994
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
9995
          if (err == MP_OKAY)
9996
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
9997
          if (err == MP_OKAY)
9998
          #ifdef HAVE_CAVIUM_V
9999
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
10000
                    &key->pubkey.y->raw, &r->raw, &s->raw,
10001
                    &curve->prime->raw, &curve->order->raw, res);
10002
          #else
10003
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
10004
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
10005
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
10006
                    &curve->Gx->raw, &curve->Gy->raw, res);
10007
          #endif
10008
10009
      #ifndef HAVE_CAVIUM_V
10010
          mp_clear(e);
10011
      #endif
10012
10013
          return err;
10014
      }
10015
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
10016
   }
10017
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
10018
10019
0
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
10020
#ifdef MP_INT_SIZE_CHECK_NULL
10021
   if (w == NULL) {
10022
       err = MEMORY_E;
10023
   }
10024
#endif
10025
10026
0
   if (err == MP_OKAY) {
10027
#ifdef WOLFSSL_CHECK_VER_FAULTS
10028
    #ifndef WOLFSSL_NO_MALLOC
10029
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10030
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
10031
       if (u1 == NULL || u2 == NULL)
10032
            err = MEMORY_E;
10033
    #else
10034
        u1 = u1tmp;
10035
        u2 = u2tmp;
10036
    #endif
10037
       /* zeroed so the cleanup below no-ops if the init is skipped */
10038
       if (u1 != NULL)
10039
           XMEMSET(u1, 0, sizeof(mp_int));
10040
       if (u2 != NULL)
10041
           XMEMSET(u2, 0, sizeof(mp_int));
10042
#else
10043
0
       u1 = e;
10044
0
       u2 = w;
10045
0
#endif
10046
0
       v = w;
10047
0
   }
10048
0
   if (err == MP_OKAY) {
10049
0
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
10050
0
   }
10051
#ifdef WOLFSSL_CHECK_VER_FAULTS
10052
   if (err == MP_OKAY) {
10053
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
10054
   }
10055
   if (err == MP_OKAY) {
10056
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
10057
   }
10058
#endif
10059
10060
   /* allocate points */
10061
0
   if (err == MP_OKAY) {
10062
   #ifdef WOLFSSL_NO_MALLOC
10063
       mG = &lcl_mG;
10064
   #endif
10065
0
       err = wc_ecc_new_point_ex(&mG, key->heap);
10066
0
   }
10067
0
   if (err == MP_OKAY) {
10068
   #ifdef WOLFSSL_NO_MALLOC
10069
       mQ = &lcl_mQ;
10070
   #endif
10071
0
       err = wc_ecc_new_point_ex(&mQ, key->heap);
10072
0
   }
10073
#if defined(WOLFSSL_CHECK_VER_FAULTS) && !defined(ECC_SHAMIR) && \
10074
    !defined(FREESCALE_LTC_ECC)
10075
   if (err == MP_OKAY) {
10076
   #ifdef WOLFSSL_NO_MALLOC
10077
       mG1 = &lcl_mG1;
10078
   #endif
10079
       err = wc_ecc_new_point_ex(&mG1, key->heap);
10080
   }
10081
   if (err == MP_OKAY) {
10082
   #ifdef WOLFSSL_NO_MALLOC
10083
       mQ1 = &lcl_mQ1;
10084
   #endif
10085
       err = wc_ecc_new_point_ex(&mQ1, key->heap);
10086
   }
10087
#endif
10088
10089
   /*  w  = s^-1 mod n */
10090
0
   if (err == MP_OKAY)
10091
0
       err = mp_invmod(s, curve->order, w);
10092
10093
   /* u1 = ew */
10094
0
   if (err == MP_OKAY)
10095
0
       err = mp_mulmod(e, w, curve->order, u1);
10096
10097
#ifdef WOLFSSL_CHECK_VER_FAULTS
10098
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
10099
        err = BAD_STATE_E;
10100
    }
10101
#endif
10102
10103
   /* u2 = rw */
10104
0
   if (err == MP_OKAY)
10105
0
       err = mp_mulmod(r, w, curve->order, u2);
10106
10107
#ifdef WOLFSSL_CHECK_VER_FAULTS
10108
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
10109
        err = BAD_STATE_E;
10110
    }
10111
#endif
10112
10113
   /* find mG and mQ */
10114
0
   if (err == MP_OKAY)
10115
0
       err = mp_copy(curve->Gx, mG->x);
10116
0
   if (err == MP_OKAY)
10117
0
       err = mp_copy(curve->Gy, mG->y);
10118
0
   if (err == MP_OKAY)
10119
0
       err = mp_set(mG->z, 1);
10120
10121
0
   if (err == MP_OKAY)
10122
0
       err = mp_copy(key->pubkey.x, mQ->x);
10123
0
   if (err == MP_OKAY)
10124
0
       err = mp_copy(key->pubkey.y, mQ->y);
10125
0
   if (err == MP_OKAY)
10126
0
       err = mp_copy(key->pubkey.z, mQ->z);
10127
10128
#if defined(FREESCALE_LTC_ECC)
10129
   /* use PKHA to compute u1*mG + u2*mQ */
10130
   if (err == MP_OKAY)
10131
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
10132
   if (err == MP_OKAY)
10133
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
10134
   if (err == MP_OKAY)
10135
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
10136
#else
10137
#ifndef ECC_SHAMIR
10138
    if (err == MP_OKAY)
10139
    {
10140
        mp_digit mp = 0;
10141
10142
     #ifdef WOLFSSL_CHECK_VER_FAULTS
10143
        err = wc_ecc_copy_point(mQ, mQ1);
10144
        if (err == MP_OKAY)
10145
            err = wc_ecc_copy_point(mG, mG1);
10146
     #endif
10147
10148
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
10149
            /* compute u1*mG + u2*mQ = mG */
10150
         #ifdef WOLFSSL_CHECK_VER_FAULTS
10151
            if (err == MP_OKAY)
10152
         #endif
10153
            {
10154
                err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
10155
                                                                     key->heap);
10156
            }
10157
        #ifdef WOLFSSL_CHECK_VER_FAULTS
10158
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mG1) == MP_EQ) {
10159
                err = BAD_STATE_E;
10160
            }
10161
10162
            /* store new value for comparing with after add operation */
10163
            if (err == MP_OKAY)
10164
                err = wc_ecc_copy_point(mG, mG1);
10165
        #endif
10166
            if (err == MP_OKAY) {
10167
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
10168
                                                                     key->heap);
10169
            }
10170
        #ifdef WOLFSSL_CHECK_VER_FAULTS
10171
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, mQ1) == MP_EQ) {
10172
                err = BAD_STATE_E;
10173
            }
10174
        #endif
10175
10176
            /* find the montgomery mp */
10177
            if (err == MP_OKAY)
10178
                err = mp_montgomery_setup(curve->prime, &mp);
10179
10180
            /* add them - pass mG as A (first) not B (second): the safe-add
10181
             * recovery for a missed-double doubles B into R, which requires
10182
             * B and R to be different points. */
10183
            if (err == MP_OKAY)
10184
                err = ecc_projective_add_point_safe(mG, mQ, mG, curve->Af,
10185
                                                        curve->prime, mp, NULL);
10186
        #ifdef WOLFSSL_CHECK_VER_FAULTS
10187
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mG1) == MP_EQ) {
10188
                err = BAD_STATE_E;
10189
            }
10190
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
10191
                err = BAD_STATE_E;
10192
            }
10193
        #endif
10194
        }
10195
        else {
10196
            /* compute 0*mG + u2*mQ = mG */
10197
            if (err == MP_OKAY)
10198
                err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
10199
                                                                     key->heap);
10200
            /* find the montgomery mp */
10201
            if (err == MP_OKAY)
10202
                err = mp_montgomery_setup(curve->prime, &mp);
10203
        }
10204
10205
        /* reduce */
10206
        if (err == MP_OKAY)
10207
            err = ecc_map(mG, curve->prime, mp);
10208
    }
10209
#else
10210
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
10211
0
    if (err == MP_OKAY) {
10212
0
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
10213
0
                                                                     key->heap);
10214
0
    }
10215
0
#endif /* ECC_SHAMIR */
10216
0
#endif /* FREESCALE_LTC_ECC */
10217
10218
   /* v = X_x1 mod n */
10219
0
   if (err == MP_OKAY)
10220
0
       err = mp_mod(mG->x, curve->order, v);
10221
10222
   /* does v == r */
10223
0
   if (err == MP_OKAY) {
10224
0
       if (mp_cmp(v, r) == MP_EQ)
10225
0
           *res = 1;
10226
#ifdef WOLFSSL_CHECK_VER_FAULTS
10227
       /* redundant comparison as sanity check that first one happened */
10228
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
10229
           *res = 0;
10230
#endif
10231
0
   }
10232
10233
   /* cleanup */
10234
0
   wc_ecc_del_point_ex(mG, key->heap);
10235
0
   wc_ecc_del_point_ex(mQ, key->heap);
10236
#if defined(WOLFSSL_CHECK_VER_FAULTS) && !defined(ECC_SHAMIR) && \
10237
    !defined(FREESCALE_LTC_ECC)
10238
   wc_ecc_del_point_ex(mG1, key->heap);
10239
   wc_ecc_del_point_ex(mQ1, key->heap);
10240
#endif
10241
10242
0
   mp_clear(e);
10243
0
   mp_clear(w);
10244
0
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
10245
#ifdef WOLFSSL_CHECK_VER_FAULTS
10246
   mp_clear(u1);
10247
   mp_clear(u2);
10248
#ifndef WOLFSSL_NO_MALLOC
10249
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
10250
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
10251
#endif
10252
#endif
10253
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
10254
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
10255
0
#endif
10256
10257
0
   return err;
10258
0
}
10259
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
10260
#endif /* HAVE_ECC_VERIFY_HELPER */
10261
10262
/**
10263
   Verify an ECC signature
10264
   r           The signature R component to verify
10265
   s           The signature S component to verify
10266
   hash        The hash (message digest) that was signed
10267
   hashlen     The length of the hash (octets)
10268
   res         Result of signature, 1==valid, 0==invalid
10269
   key         The corresponding public ECC key
10270
   return      MP_OKAY if successful (even if the signature is not valid)
10271
               Caller should check the *res value to determine if the signature
10272
               is valid or invalid. Other negative values are returned on error.
10273
*/
10274
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
10275
                    word32 hashlen, int* res, ecc_key* key)
10276
0
{
10277
#if (defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_SIGN_ONLY)) || \
10278
    defined(PSOC6_CRYPTO_ECC)
10279
    /* HW ECDSA verify via STM32 PKA or the PSoC6/PSOC Edge crypto engine.
10280
     * STM32 PKA works under both the CubeMX-HAL and the bare-metal
10281
     * direct-register paths. (Under WC_STM32_PKA_SIGN_ONLY -- e.g. STM32C5 --
10282
     * verify falls through to the software body below.)
10283
     * Mirror the non-FIPS
10284
     * input-validation from the SW body below (length range, all-zero
10285
     * digest rejection) so HW + SW share the same input contract. */
10286
#ifndef WC_ALLOW_ECC_ZERO_HASH
10287
    byte hashIsZero = 0;
10288
    word32 zIdx;
10289
#endif
10290
10291
    if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) {
10292
        return ECC_BAD_ARG_E;
10293
    }
10294
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
10295
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
10296
        return BAD_LENGTH_E;
10297
    }
10298
#ifndef WC_ALLOW_ECC_ZERO_HASH
10299
    /* reject all 0's hash */
10300
    for (zIdx = 0; zIdx < hashlen; zIdx++)
10301
        hashIsZero |= hash[zIdx];
10302
    if (hashIsZero == 0)
10303
        return ECC_BAD_ARG_E;
10304
#endif
10305
10306
#if defined(PSOC6_CRYPTO_ECC)
10307
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
10308
#else
10309
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
10310
#endif
10311
#else
10312
0
   int           err;
10313
0
   word32        keySz = 0;
10314
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
10315
0
   byte hashIsZero = 0;
10316
0
   word32 zIdx;
10317
0
#endif
10318
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10319
   byte sigRS[ATECC_KEY_SIZE*2];
10320
#elif defined(WOLFSSL_MICROCHIP_TA100)
10321
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
10322
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10323
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
10324
#elif defined(WOLFSSL_KCAPI_ECC)
10325
   byte sigRS[MAX_ECC_BYTES*2];
10326
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10327
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
10328
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
10329
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) && \
10330
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
10331
#else
10332
   /* Software verify helper (also used for SE050 software keys under
10333
    * WOLFSSL_SE050_ONLY_KEY_ID) needs the curve specs. */
10334
0
   int curveLoaded = 0;
10335
0
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
10336
0
#endif
10337
10338
0
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
10339
0
       return ECC_BAD_ARG_E;
10340
10341
    /* Check hash length */
10342
0
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
10343
0
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
10344
0
        return BAD_LENGTH_E;
10345
0
    }
10346
10347
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
10348
    /* reject all 0's hash */
10349
0
    for (zIdx = 0; zIdx < hashlen; zIdx++)
10350
0
        hashIsZero |= hash[zIdx];
10351
0
    if (hashIsZero == 0)
10352
0
        return ECC_BAD_ARG_E;
10353
0
#endif
10354
10355
   /* default to invalid signature */
10356
0
   *res = 0;
10357
10358
   /* is the IDX valid ?  */
10359
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
10360
0
      return ECC_BAD_ARG_E;
10361
0
   }
10362
10363
0
   err = wc_ecc_check_r_s_range(key, r, s);
10364
0
   if (err != MP_OKAY) {
10365
0
      return err;
10366
0
   }
10367
10368
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID) && \
10369
    !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY)
10370
   /* Key resident in the SE050: verify in hardware. Software keys fall through
10371
    * to the wolfCrypt verify helper below. */
10372
   if (key->keyIdSet) {
10373
       return se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
10374
   }
10375
#endif
10376
10377
0
   keySz = (word32)key->dp->size;
10378
10379
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
10380
    defined(WOLFSSL_ASYNC_CRYPT_SW)
10381
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
10382
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
10383
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
10384
            sw->eccVerify.r = r;
10385
            sw->eccVerify.s = s;
10386
            sw->eccVerify.hash = hash;
10387
            sw->eccVerify.hashlen = hashlen;
10388
            sw->eccVerify.stat = res;
10389
            sw->eccVerify.key = key;
10390
            return WC_PENDING_E;
10391
        }
10392
    }
10393
#endif
10394
10395
#ifndef HAVE_ECC_VERIFY_HELPER
10396
10397
#ifndef WOLFSSL_SE050
10398
    /* Extract R and S with front zero padding (if required),
10399
     * SE050 does this in port layer  */
10400
    XMEMSET(sigRS, 0, sizeof(sigRS));
10401
    err = mp_to_unsigned_bin(r, sigRS +
10402
                                (keySz - mp_unsigned_bin_size(r)));
10403
    if (err != MP_OKAY) {
10404
        return err;
10405
    }
10406
    err = mp_to_unsigned_bin(s, sigRS + keySz +
10407
                                (keySz - mp_unsigned_bin_size(s)));
10408
    if (err != MP_OKAY) {
10409
        return err;
10410
    }
10411
#endif /* WOLFSSL_SE050 */
10412
10413
#if defined(WOLFSSL_MICROCHIP_TA100)
10414
    if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
10415
        err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
10416
        if (err != 0) {
10417
            return err;
10418
        }
10419
        (void)hashlen;
10420
    }
10421
    else {
10422
        err = atmel_ecc_verify_ex(hash, hashlen, sigRS, key->pubkey_raw,
10423
            keySz * 2, microchip_curve_id_for_key(key), res);
10424
        if (err != 0) {
10425
           return err;
10426
        }
10427
    }
10428
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
10429
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
10430
    if (err != 0) {
10431
       return err;
10432
    }
10433
    (void)hashlen;
10434
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10435
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
10436
                                hash, hashlen,
10437
                                res, key);
10438
#elif defined(WOLFSSL_KCAPI_ECC)
10439
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
10440
    if (err == 0) {
10441
        *res = 1;
10442
    }
10443
#elif defined(WOLFSSL_SE050)
10444
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
10445
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10446
    if (hashlen > sizeof(hashcopy))
10447
        return ECC_BAD_ARG_E;
10448
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
10449
    mp_reverse(sigRS, keySz);
10450
    mp_reverse(sigRS + keySz, keySz);
10451
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
10452
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
10453
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
10454
10455
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
10456
                                     xil_curve_type[key->dp->id],
10457
                                     XIL_CAST_U64(hashcopy), keySz,
10458
                                     XIL_CAST_U64(key->keyRaw),
10459
                                     XIL_CAST_U64(sigRS));
10460
10461
    if (err != XST_SUCCESS) {
10462
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
10463
        err = WC_HW_E;
10464
    } else {
10465
        *res = 1;
10466
    }
10467
#endif
10468
10469
#else
10470
  /* checking if private key with no public part */
10471
0
  if (key->type == ECC_PRIVATEKEY_ONLY) {
10472
0
      WOLFSSL_MSG("Verify called with private key, generating public part");
10473
0
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10474
0
      if (err != MP_OKAY) {
10475
0
          return err;
10476
0
      }
10477
0
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10478
0
      if (err != MP_OKAY) {
10479
0
          FREE_CURVE_SPECS();
10480
0
          return err;
10481
0
      }
10482
0
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
10483
0
      if (err != MP_OKAY) {
10484
0
           WOLFSSL_MSG("Unable to extract public key");
10485
0
           wc_ecc_curve_free(curve);
10486
0
           FREE_CURVE_SPECS();
10487
0
           return err;
10488
0
      }
10489
0
      curveLoaded = 1;
10490
0
  }
10491
10492
0
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
10493
0
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
10494
0
      if (curveLoaded) {
10495
0
           wc_ecc_curve_free(curve);
10496
0
           FREE_CURVE_SPECS();
10497
0
      }
10498
0
      return err;
10499
0
  }
10500
10501
0
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
10502
0
   if (!curveLoaded) {
10503
0
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10504
0
       if (err != 0) {
10505
0
          return err;
10506
0
       }
10507
       /* read in the specs for this curve */
10508
0
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10509
0
       if (err != 0) {
10510
0
          FREE_CURVE_SPECS();
10511
0
          return err;
10512
0
       }
10513
0
   }
10514
10515
0
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
10516
0
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
10517
10518
0
   (void)curveLoaded;
10519
0
   wc_ecc_curve_free(curve);
10520
0
   FREE_CURVE_SPECS();
10521
0
#endif /* HAVE_ECC_VERIFY_HELPER */
10522
10523
0
   (void)keySz;
10524
0
   (void)hashlen;
10525
10526
0
   return err;
10527
0
#endif /* WOLFSSL_STM32_PKA */
10528
0
}
10529
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
10530
#endif /* HAVE_ECC_VERIFY */
10531
10532
#ifdef HAVE_ECC_KEY_IMPORT
10533
/* import point from der
10534
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
10535
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
10536
                               const int curve_idx, ecc_point* point,
10537
                               int shortKeySize)
10538
0
{
10539
0
    int err = 0;
10540
#ifdef HAVE_COMP_KEY
10541
    int compressed = 0;
10542
#endif
10543
0
    int keysize;
10544
0
    byte pointType;
10545
10546
0
#ifndef HAVE_COMP_KEY
10547
0
    (void)shortKeySize;
10548
0
#endif
10549
10550
0
    if (in == NULL || point == NULL || (curve_idx < 0) ||
10551
0
        (wc_ecc_is_valid_idx(curve_idx) == 0))
10552
0
        return ECC_BAD_ARG_E;
10553
10554
    /* must be odd */
10555
0
    if ((inLen & 1) == 0) {
10556
0
        return ECC_BAD_ARG_E;
10557
0
    }
10558
10559
    /* validate point format byte before any memory operations */
10560
0
    pointType = in[0];
10561
0
    if (pointType != ECC_POINT_UNCOMP &&
10562
0
            pointType != ECC_POINT_COMP_EVEN &&
10563
0
            pointType != ECC_POINT_COMP_ODD) {
10564
0
        return ASN_PARSE_E;
10565
0
    }
10566
10567
    /* clear if previously allocated */
10568
0
    mp_clear(point->x);
10569
0
    mp_clear(point->y);
10570
0
    mp_clear(point->z);
10571
10572
    /* init point */
10573
#ifdef ALT_ECC_SIZE
10574
    point->x = (mp_int*)&point->xyz[0];
10575
    point->y = (mp_int*)&point->xyz[1];
10576
    point->z = (mp_int*)&point->xyz[2];
10577
    alt_fp_init(point->x);
10578
    alt_fp_init(point->y);
10579
    alt_fp_init(point->z);
10580
#else
10581
0
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
10582
10583
0
    if (err != MP_OKAY)
10584
0
        return MEMORY_E;
10585
0
#endif
10586
10587
    /* pointType already validated above; check for compressed format */
10588
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10589
#ifdef HAVE_COMP_KEY
10590
        compressed = 1;
10591
#else
10592
0
        err = NOT_COMPILED_IN;
10593
0
#endif
10594
0
    }
10595
10596
    /* adjust to skip first byte */
10597
0
    inLen -= 1;
10598
0
    in += 1;
10599
10600
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
10601
     * is true */
10602
#ifdef HAVE_COMP_KEY
10603
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
10604
#else
10605
0
    keysize = (int)(inLen>>1);
10606
0
#endif
10607
10608
    /* sanity check that x coordinate is expected size */
10609
0
    if (err == MP_OKAY) {
10610
0
        if (keysize != ecc_sets[curve_idx].size) {
10611
0
            err = ECC_BAD_ARG_E;
10612
0
        }
10613
0
    }
10614
10615
    /* read data */
10616
0
    if (err == MP_OKAY)
10617
0
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
10618
10619
#ifdef HAVE_COMP_KEY
10620
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10621
    #if defined(WOLFSSL_HAVE_SP_ECC)
10622
        #ifndef WOLFSSL_SP_NO_256
10623
        if (curve_idx != ECC_CUSTOM_IDX &&
10624
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
10625
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
10626
        }
10627
        else
10628
        #endif
10629
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10630
        if (curve_idx != ECC_CUSTOM_IDX &&
10631
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
10632
            err = sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
10633
        }
10634
        else
10635
        #endif
10636
        #ifdef WOLFSSL_SP_384
10637
        if (curve_idx != ECC_CUSTOM_IDX &&
10638
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
10639
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
10640
        }
10641
        else
10642
        #endif
10643
        #ifdef WOLFSSL_SP_521
10644
        if (curve_idx != ECC_CUSTOM_IDX &&
10645
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
10646
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
10647
        }
10648
        else
10649
        #endif
10650
    #endif
10651
    /* Recovering y needs mp_sqrtmod_prime(), which is only compiled in
10652
     * alongside the rest of the software ECC math. Ports that replace it fall
10653
     * to the #else below rather than calling a function that is not there. */
10654
    #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
10655
        !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
10656
        !defined(WOLFSSL_NO_ECC_SW)
10657
        {
10658
            int did_init = 0;
10659
        #ifdef WOLFSSL_SMALL_STACK
10660
            mp_int* t1 = NULL;
10661
            mp_int* t2 = NULL;
10662
        #else
10663
            mp_int t1[1], t2[1];
10664
        #endif
10665
            DECLARE_CURVE_SPECS(3);
10666
10667
            ALLOC_CURVE_SPECS(3, err);
10668
10669
        #ifdef WOLFSSL_SMALL_STACK
10670
            if (err == MP_OKAY) {
10671
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10672
                                      DYNAMIC_TYPE_BIGINT);
10673
                if (t1 == NULL) {
10674
                    err = MEMORY_E;
10675
                }
10676
            }
10677
            if (err == MP_OKAY) {
10678
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10679
                                      DYNAMIC_TYPE_BIGINT);
10680
                if (t2 == NULL) {
10681
                    err = MEMORY_E;
10682
                }
10683
            }
10684
        #endif
10685
10686
            if (err == MP_OKAY) {
10687
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10688
                    err = MEMORY_E;
10689
                else
10690
                    did_init = 1;
10691
            }
10692
10693
            /* load curve info */
10694
            if (err == MP_OKAY)
10695
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10696
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10697
                        ECC_CURVE_FIELD_BF));
10698
10699
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
10700
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10701
            /* validate prime is prime for custom curves */
10702
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
10703
                int isPrime = MP_NO;
10704
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10705
                if (err == MP_OKAY && isPrime == MP_NO)
10706
                    err = MP_VAL;
10707
            }
10708
        #endif
10709
10710
            /* compute x^3 */
10711
            if (err == MP_OKAY)
10712
                err = mp_sqr(point->x, t1);
10713
            if (err == MP_OKAY)
10714
                err = mp_mulmod(t1, point->x, curve->prime, t1);
10715
10716
            /* compute x^3 + a*x */
10717
            if (err == MP_OKAY)
10718
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
10719
            if (err == MP_OKAY)
10720
                err = mp_add(t1, t2, t1);
10721
10722
            /* compute x^3 + a*x + b */
10723
            if (err == MP_OKAY)
10724
                err = mp_add(t1, curve->Bf, t1);
10725
10726
            /* compute sqrt(x^3 + a*x + b) */
10727
            if (err == MP_OKAY)
10728
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
10729
10730
            /* adjust y */
10731
            if (err == MP_OKAY) {
10732
                if ((mp_isodd(t2) == MP_YES &&
10733
                                            pointType == ECC_POINT_COMP_ODD) ||
10734
                    (mp_isodd(t2) == MP_NO &&
10735
                                            pointType == ECC_POINT_COMP_EVEN)) {
10736
                    err = mp_mod(t2, curve->prime, point->y);
10737
                }
10738
                else {
10739
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
10740
                }
10741
            }
10742
10743
            if (did_init) {
10744
                mp_clear(t2);
10745
                mp_clear(t1);
10746
            }
10747
10748
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10749
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10750
10751
            wc_ecc_curve_free(curve);
10752
            FREE_CURVE_SPECS();
10753
        }
10754
    #else
10755
        {
10756
            err = WC_KEY_SIZE_E;
10757
        }
10758
    #endif
10759
    }
10760
#endif
10761
10762
0
    if (err == MP_OKAY) {
10763
#ifdef HAVE_COMP_KEY
10764
        if (compressed == 0)
10765
#endif
10766
0
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
10767
0
    }
10768
0
    if (err == MP_OKAY)
10769
0
        err = mp_set(point->z, 1);
10770
10771
0
    if (err != MP_OKAY) {
10772
0
        mp_clear(point->x);
10773
0
        mp_clear(point->y);
10774
0
        mp_clear(point->z);
10775
0
    }
10776
10777
0
    return err;
10778
0
}
10779
10780
/* function for backwards compatibility with previous implementations */
10781
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
10782
                            ecc_point* point)
10783
0
{
10784
0
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
10785
0
}
10786
#endif /* HAVE_ECC_KEY_IMPORT */
10787
10788
#ifdef HAVE_ECC_KEY_EXPORT
10789
/* export point to der */
10790
10791
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
10792
                               word32* outLen, int compressed)
10793
0
{
10794
0
    if (compressed == 0)
10795
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
10796
#ifdef HAVE_COMP_KEY
10797
    else
10798
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
10799
#else
10800
0
    return NOT_COMPILED_IN;
10801
0
#endif
10802
0
}
10803
10804
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
10805
                            word32* outLen)
10806
0
{
10807
0
    int    ret = MP_OKAY;
10808
0
    word32 numlen;
10809
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10810
10811
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10812
0
        return ECC_BAD_ARG_E;
10813
10814
0
    numlen = (word32)ecc_sets[curve_idx].size;
10815
10816
    /* return length needed only */
10817
0
    if (point != NULL && out == NULL && outLen != NULL) {
10818
0
        *outLen = 1 + 2*numlen;
10819
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10820
0
    }
10821
10822
0
    if (point == NULL || out == NULL || outLen == NULL)
10823
0
        return ECC_BAD_ARG_E;
10824
10825
0
    if (*outLen < (1 + 2*numlen)) {
10826
0
        *outLen = 1 + 2*numlen;
10827
0
        return BUFFER_E;
10828
0
    }
10829
10830
    /* Sanity check the ordinates' sizes. */
10831
0
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
10832
0
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
10833
0
        return ECC_BAD_ARG_E;
10834
0
    }
10835
10836
    /* store byte point type */
10837
0
    out[0] = ECC_POINT_UNCOMP;
10838
10839
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10840
0
        return MEMORY_E);
10841
10842
    /* pad and store x */
10843
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
10844
0
    ret = mp_to_unsigned_bin(point->x, buf +
10845
0
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
10846
0
    if (ret != MP_OKAY)
10847
0
        goto done;
10848
0
    XMEMCPY(out+1, buf, numlen);
10849
10850
    /* pad and store y */
10851
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
10852
0
    ret = mp_to_unsigned_bin(point->y, buf +
10853
0
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
10854
0
    if (ret != MP_OKAY)
10855
0
        goto done;
10856
0
    XMEMCPY(out+1+numlen, buf, numlen);
10857
10858
0
    *outLen = 1 + 2*numlen;
10859
10860
0
done:
10861
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10862
10863
0
    return ret;
10864
0
}
10865
10866
10867
/* export point to der */
10868
#ifdef HAVE_COMP_KEY
10869
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
10870
                                       byte* out, word32* outLen)
10871
{
10872
    int    ret = MP_OKAY;
10873
    word32 numlen;
10874
    word32 output_len;
10875
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10876
10877
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10878
        return ECC_BAD_ARG_E;
10879
10880
    numlen = (word32)ecc_sets[curve_idx].size;
10881
    output_len = 1 + numlen; /* y point type + x */
10882
10883
    /* return length needed only */
10884
    if (point != NULL && out == NULL && outLen != NULL) {
10885
        *outLen = output_len;
10886
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10887
    }
10888
10889
    if (point == NULL || out == NULL || outLen == NULL)
10890
        return ECC_BAD_ARG_E;
10891
10892
10893
    if (*outLen < output_len) {
10894
        *outLen = output_len;
10895
        return BUFFER_E;
10896
    }
10897
10898
    /* Sanity check the ordinate's size. */
10899
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
10900
        return ECC_BAD_ARG_E;
10901
    }
10902
10903
    /* store byte point type */
10904
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
10905
                                            ECC_POINT_COMP_EVEN;
10906
10907
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10908
        return MEMORY_E);
10909
10910
    /* pad and store x */
10911
    XMEMSET(buf, 0, ECC_BUFSIZE);
10912
    ret = mp_to_unsigned_bin(point->x, buf +
10913
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
10914
    if (ret != MP_OKAY)
10915
        goto done;
10916
    XMEMCPY(out+1, buf, numlen);
10917
10918
    *outLen = output_len;
10919
10920
done:
10921
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10922
10923
    return ret;
10924
}
10925
#endif /* HAVE_COMP_KEY */
10926
10927
/* Software-only export of public ECC key in ANSI X9.63 format.
10928
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
10929
static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10930
0
{
10931
0
   int    ret = MP_OKAY;
10932
0
   word32 numlen;
10933
0
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10934
0
   word32 pubxlen, pubylen;
10935
10936
   /* return length needed only */
10937
0
   if (key != NULL && out == NULL && outLen != NULL) {
10938
      /* if key hasn't been setup assume max bytes for size estimation */
10939
0
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10940
      /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10941
0
      *outLen = 1 + 2 * numlen;
10942
0
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10943
0
   }
10944
10945
0
   if (key == NULL || out == NULL || outLen == NULL) {
10946
0
      return ECC_BAD_ARG_E;
10947
0
   }
10948
10949
0
   if (key->type == ECC_PRIVATEKEY_ONLY) {
10950
0
       return ECC_PRIVATEONLY_E;
10951
0
   }
10952
10953
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10954
    /* check if public key in secure memory */
10955
    if (key->securePubKey > 0) {
10956
        int keySz = wc_ecc_size(key);
10957
10958
        /* store byte point type */
10959
        out[0] = ECC_POINT_UNCOMP;
10960
10961
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
10962
            return WC_HW_E;
10963
10964
        *outLen = 1 + 2*keySz;
10965
        return MP_OKAY;
10966
    }
10967
#endif
10968
10969
0
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
10970
0
       return ECC_BAD_ARG_E;
10971
0
   }
10972
10973
0
   numlen = (word32)key->dp->size;
10974
10975
    /* verify room in out buffer */
10976
0
   if (*outLen < (1 + 2*numlen)) {
10977
0
      *outLen = 1 + 2*numlen;
10978
0
      return BUFFER_E;
10979
0
   }
10980
10981
   /* verify public key length is less than key size */
10982
0
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
10983
0
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
10984
0
   if ((pubxlen > numlen) || (pubylen > numlen)) {
10985
0
      WOLFSSL_MSG("Public key x/y invalid!");
10986
0
      return BUFFER_E;
10987
0
   }
10988
10989
   /* store byte point type */
10990
0
   out[0] = ECC_POINT_UNCOMP;
10991
10992
0
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10993
0
       return MEMORY_E);
10994
10995
   /* pad and store x */
10996
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
10997
0
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
10998
0
   if (ret != MP_OKAY)
10999
0
      goto done;
11000
0
   XMEMCPY(out+1, buf, numlen);
11001
11002
   /* pad and store y */
11003
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
11004
0
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
11005
0
   if (ret != MP_OKAY)
11006
0
      goto done;
11007
0
   XMEMCPY(out+1+numlen, buf, numlen);
11008
11009
0
   *outLen = 1 + 2*numlen;
11010
11011
0
done:
11012
0
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
11013
11014
0
   return ret;
11015
0
}
11016
11017
11018
/* export public ECC key in ANSI X9.63 format */
11019
WOLFSSL_ABI
11020
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
11021
0
{
11022
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
11023
    int ret;
11024
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11025
#endif
11026
11027
0
    if (key == NULL || outLen == NULL) {
11028
0
        return ECC_BAD_ARG_E;
11029
0
    }
11030
11031
    /* return length needed only */
11032
0
    if (out == NULL) {
11033
0
        word32 numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
11034
        /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
11035
0
        *outLen = 1 + 2 * numlen;
11036
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
11037
0
    }
11038
11039
0
    if (key->type == ECC_PRIVATEKEY_ONLY) {
11040
0
        return ECC_PRIVATEONLY_E;
11041
0
    }
11042
11043
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
11044
    #ifndef WOLF_CRYPTO_CB_FIND
11045
    if (key->devId != INVALID_DEVID)
11046
    #endif
11047
    {
11048
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11049
        if (!WC_VAR_OK(tmpKey)) {
11050
            return MEMORY_E;
11051
        }
11052
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11053
11054
        ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11055
        if (ret != 0) {
11056
            WC_FREE_VAR(tmpKey, key->heap);
11057
            return ret;
11058
        }
11059
11060
        ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
11061
                                     key, tmpKey);
11062
        if (ret == 0) {
11063
            /* Call software helper (no callback recursion) */
11064
            ret = _ecc_export_x963(tmpKey, out, outLen);
11065
        }
11066
11067
        wc_ecc_free(tmpKey);
11068
        WC_FREE_VAR(tmpKey, key->heap);
11069
11070
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11071
            return ret;
11072
        }
11073
    }
11074
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
11075
11076
0
    return _ecc_export_x963(key, out, outLen);
11077
0
}
11078
11079
/* export public ECC key in ANSI X9.63 format, extended with
11080
 * compression option */
11081
WOLFSSL_ABI
11082
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
11083
                          int compressed)
11084
0
{
11085
0
    if (compressed == 0) {
11086
0
        return wc_ecc_export_x963(key, out, outLen);
11087
0
    }
11088
#ifdef HAVE_COMP_KEY
11089
    else
11090
        return wc_ecc_export_x963_compressed(key, out, outLen);
11091
#else
11092
0
    return NOT_COMPILED_IN;
11093
0
#endif
11094
0
}
11095
#endif /* HAVE_ECC_KEY_EXPORT */
11096
11097
11098
/* is ecc point on curve described by dp ? */
11099
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
11100
800
{
11101
800
#if !defined(WOLFSSL_SP_MATH)
11102
800
   int err;
11103
#ifdef WOLFSSL_SMALL_STACK
11104
   mp_int* t1;
11105
   mp_int* t2;
11106
#else
11107
800
   mp_int  t1[1], t2[1];
11108
800
#endif
11109
11110
#ifdef WOLFSSL_SMALL_STACK
11111
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11112
   if (t1 == NULL)
11113
       return MEMORY_E;
11114
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11115
   if (t2 == NULL) {
11116
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
11117
       return MEMORY_E;
11118
   }
11119
#endif
11120
11121
800
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
11122
0
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
11123
0
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
11124
0
      return err;
11125
0
   }
11126
11127
   /* compute y^2 */
11128
800
   if (err == MP_OKAY)
11129
800
       err = mp_sqr(ecp->y, t1);
11130
11131
   /* compute x^3 */
11132
800
   if (err == MP_OKAY)
11133
800
       err = mp_sqr(ecp->x, t2);
11134
800
   if (err == MP_OKAY)
11135
800
       err = mp_mod(t2, prime, t2);
11136
800
   if (err == MP_OKAY)
11137
800
       err = mp_mul(ecp->x, t2, t2);
11138
11139
   /* compute y^2 - x^3 */
11140
800
   if (err == MP_OKAY)
11141
800
       err = mp_submod(t1, t2, prime, t1);
11142
11143
   /* Determine if curve "a" should be used in calc */
11144
#ifdef WOLFSSL_CUSTOM_CURVES
11145
   if (err == MP_OKAY) {
11146
      /* Use a and prime to determine if a == 3 */
11147
      err = mp_set(t2, 0);
11148
      if (err == MP_OKAY)
11149
          err = mp_submod(prime, a, prime, t2);
11150
   }
11151
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
11152
      /* compute y^2 - x^3 + a*x */
11153
      if (err == MP_OKAY)
11154
          err = mp_mulmod(t2, ecp->x, prime, t2);
11155
      if (err == MP_OKAY)
11156
          err = mp_addmod(t1, t2, prime, t1);
11157
   }
11158
   else
11159
#endif /* WOLFSSL_CUSTOM_CURVES */
11160
800
   {
11161
      /* assumes "a" == 3 */
11162
800
      (void)a;
11163
11164
      /* compute y^2 - x^3 + 3x */
11165
800
      if (err == MP_OKAY)
11166
800
          err = mp_add(t1, ecp->x, t1);
11167
800
      if (err == MP_OKAY)
11168
800
          err = mp_add(t1, ecp->x, t1);
11169
800
      if (err == MP_OKAY)
11170
800
          err = mp_add(t1, ecp->x, t1);
11171
800
      if (err == MP_OKAY)
11172
800
          err = mp_mod(t1, prime, t1);
11173
800
  }
11174
11175
   /* adjust range (0, prime) */
11176
800
   while (err == MP_OKAY && mp_isneg(t1)) {
11177
0
      err = mp_add(t1, prime, t1);
11178
0
   }
11179
800
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
11180
0
      err = mp_sub(t1, prime, t1);
11181
0
   }
11182
11183
   /* compare to b */
11184
800
   if (err == MP_OKAY) {
11185
800
       if (mp_cmp(t1, b) != MP_EQ) {
11186
800
          err = IS_POINT_E;
11187
800
       } else {
11188
0
          err = MP_OKAY;
11189
0
       }
11190
800
   }
11191
11192
800
   mp_clear(t1);
11193
800
   mp_clear(t2);
11194
11195
800
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
11196
800
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
11197
11198
800
   return err;
11199
#else
11200
   (void)a;
11201
   (void)b;
11202
11203
#ifdef WOLFSSL_HAVE_SP_ECC
11204
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11205
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
11206
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
11207
   }
11208
#endif
11209
#ifndef WOLFSSL_SP_NO_256
11210
   if (mp_count_bits(prime) == 256) {
11211
       return sp_ecc_is_point_256(ecp->x, ecp->y);
11212
   }
11213
#endif
11214
#ifdef WOLFSSL_SP_384
11215
   if (mp_count_bits(prime) == 384) {
11216
       return sp_ecc_is_point_384(ecp->x, ecp->y);
11217
   }
11218
#endif
11219
#ifdef WOLFSSL_SP_521
11220
   if (mp_count_bits(prime) == 521) {
11221
       return sp_ecc_is_point_521(ecp->x, ecp->y);
11222
   }
11223
#endif
11224
#else
11225
   (void)ecp;
11226
   (void)prime;
11227
#endif
11228
   return WC_KEY_SIZE_E;
11229
#endif
11230
800
}
11231
11232
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
11233
830
{
11234
830
    int err = MP_OKAY;
11235
11236
    /* Validate parameters. */
11237
830
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
11238
0
        err = BAD_FUNC_ARG;
11239
0
    }
11240
11241
830
    if (err == MP_OKAY) {
11242
        /* x must be in the range [0, p-1] */
11243
830
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
11244
28
            err = ECC_OUT_OF_RANGE_E;
11245
28
        }
11246
830
    }
11247
11248
830
    if (err == MP_OKAY) {
11249
        /* y must be in the range [0, p-1] */
11250
802
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
11251
2
            err = ECC_OUT_OF_RANGE_E;
11252
2
        }
11253
802
    }
11254
11255
830
    if (err == MP_OKAY) {
11256
        /* z must be one, that is point must be in affine form. */
11257
800
        if (!mp_isone(ecp->z)) {
11258
0
            err = ECC_BAD_ARG_E;
11259
0
        }
11260
800
    }
11261
11262
830
    if (err == MP_OKAY) {
11263
        /* Check x and y are valid for curve equation. */
11264
800
        err = _ecc_is_point(ecp, a, b, prime);
11265
800
    }
11266
11267
830
    return err;
11268
830
}
11269
11270
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
11271
11272
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
11273
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
11274
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
11275
/* validate privkey * generator == pubkey, 0 on success */
11276
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
11277
{
11278
    int        err;
11279
    ecc_point* base = NULL;
11280
    ecc_point* res  = NULL;
11281
#ifdef WOLFSSL_NO_MALLOC
11282
    ecc_point lcl_base;
11283
    ecc_point lcl_res;
11284
#endif
11285
    DECLARE_CURVE_SPECS(3);
11286
11287
    if (key == NULL)
11288
        return BAD_FUNC_ARG;
11289
11290
    ALLOC_CURVE_SPECS(3, err);
11291
    if (err != MP_OKAY) {
11292
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
11293
        return err;
11294
    }
11295
11296
#ifdef WOLFSSL_NO_MALLOC
11297
    res = &lcl_res;
11298
#endif
11299
    err = wc_ecc_new_point_ex(&res, key->heap);
11300
11301
#ifdef WOLFSSL_HAVE_SP_ECC
11302
#ifndef WOLFSSL_SP_NO_256
11303
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
11304
        if (err == MP_OKAY) {
11305
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
11306
        }
11307
    }
11308
    else
11309
#endif
11310
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11311
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
11312
        if (err == MP_OKAY) {
11313
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
11314
        }
11315
    }
11316
    else
11317
#endif
11318
#ifdef WOLFSSL_SP_384
11319
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
11320
        if (err == MP_OKAY) {
11321
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
11322
        }
11323
    }
11324
    else
11325
#endif
11326
#ifdef WOLFSSL_SP_521
11327
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
11328
        if (err == MP_OKAY) {
11329
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
11330
        }
11331
    }
11332
    else
11333
#endif
11334
#endif
11335
    {
11336
        if (err == MP_OKAY) {
11337
        #ifdef WOLFSSL_NO_MALLOC
11338
            base = &lcl_base;
11339
        #endif
11340
            err = wc_ecc_new_point_ex(&base, key->heap);
11341
        }
11342
11343
        if (err == MP_OKAY) {
11344
            /* load curve info */
11345
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
11346
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
11347
        }
11348
11349
        /* set up base generator */
11350
        if (err == MP_OKAY)
11351
            err = mp_copy(curve->Gx, base->x);
11352
        if (err == MP_OKAY)
11353
            err = mp_copy(curve->Gy, base->y);
11354
        if (err == MP_OKAY)
11355
            err = mp_set(base->z, 1);
11356
11357
#ifdef WOLFSSL_KCAPI_ECC
11358
        if (err == MP_OKAY) {
11359
            word32 pubkey_sz = (word32)key->dp->size*2;
11360
            if (key->handle == NULL) {
11361
                /* if handle loaded, then pubkey_raw already populated */
11362
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
11363
            }
11364
            if (err == 0) {
11365
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
11366
                                           pubkey_sz/2);
11367
            }
11368
            if (err == MP_OKAY) {
11369
                err = mp_read_unsigned_bin(res->y,
11370
                                           key->pubkey_raw + pubkey_sz/2,
11371
                                           pubkey_sz/2);
11372
            }
11373
            if (err == MP_OKAY) {
11374
                err = mp_set(res->z, 1);
11375
            }
11376
        }
11377
        (void)a;
11378
        (void)prime;
11379
#else
11380
#ifdef ECC_TIMING_RESISTANT
11381
        if (err == MP_OKAY)
11382
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
11383
                                          curve->order, key->rng, 1, key->heap);
11384
#else
11385
        if (err == MP_OKAY)
11386
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
11387
                                              curve->order, NULL, 1, key->heap);
11388
#endif
11389
#endif /* WOLFSSL_KCAPI_ECC */
11390
    }
11391
11392
    if (err == MP_OKAY) {
11393
        /* compare result to public key */
11394
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
11395
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
11396
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
11397
            /* didn't match */
11398
            err = ECC_PRIV_KEY_E;
11399
        }
11400
    }
11401
11402
    ecc_put_k(key);
11403
    wc_ecc_curve_free(curve);
11404
    wc_ecc_del_point_ex(res, key->heap);
11405
    wc_ecc_del_point_ex(base, key->heap);
11406
    FREE_CURVE_SPECS();
11407
11408
    return err;
11409
}
11410
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
11411
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
11412
11413
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
11414
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
11415
11416
/* check privkey generator helper, creates prime needed */
11417
static int ecc_check_privkey_gen_helper(ecc_key* key)
11418
{
11419
    int    err;
11420
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11421
    !defined(WOLFSSL_MICROCHIP_TA100)
11422
    DECLARE_CURVE_SPECS(2);
11423
#endif
11424
11425
    if (key == NULL)
11426
        return BAD_FUNC_ARG;
11427
11428
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11429
    defined(WOLFSSL_MICROCHIP_TA100)
11430
    /* Hardware based private key, so this operation is not supported */
11431
    err = MP_OKAY; /* just report success */
11432
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11433
    /* Hardware based private key, so this operation is not supported */
11434
    err = MP_OKAY; /* just report success */
11435
#elif defined(WOLFSSL_KCAPI_ECC)
11436
    /* Hardware based private key, so this operation is not supported */
11437
    err = MP_OKAY; /* just report success */
11438
#else
11439
    ALLOC_CURVE_SPECS(2, err);
11440
11441
    /* load curve info */
11442
    if (err == MP_OKAY)
11443
        err = wc_ecc_curve_load(key->dp, &curve,
11444
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
11445
11446
    if (err == MP_OKAY)
11447
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11448
11449
    wc_ecc_curve_free(curve);
11450
    FREE_CURVE_SPECS();
11451
11452
#endif /* WOLFSSL_ATECC508A */
11453
11454
    return err;
11455
}
11456
11457
/* Performs a Pairwise Consistency Test on an ECC key pair. */
11458
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
11459
{
11460
    int err = 0;
11461
    word32 flags = key->flags;
11462
11463
    /* If flags not set default to cofactor and dec/sign */
11464
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
11465
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
11466
    }
11467
11468
    if (flags & WC_ECC_FLAG_COFACTOR) {
11469
        err = ecc_check_privkey_gen_helper(key);
11470
    }
11471
11472
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
11473
#ifndef WOLFSSL_SMALL_STACK
11474
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
11475
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
11476
#else
11477
        byte* sig;
11478
#endif
11479
        byte* digest;
11480
        word32 sigLen, digestLen;
11481
        int dynRng = 0, res = 0;
11482
11483
        sigLen = (word32)wc_ecc_sig_size(key);
11484
        digestLen = WC_SHA256_DIGEST_SIZE;
11485
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
11486
            DYNAMIC_TYPE_ECC, return MEMORY_E);
11487
        digest = sig + sigLen;
11488
11489
        if (rng == NULL) {
11490
            dynRng = 1;
11491
            rng = wc_rng_new(NULL, 0, key->heap);
11492
            if (rng == NULL) {
11493
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11494
                return MEMORY_E;
11495
            }
11496
        }
11497
11498
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
11499
11500
        if (!err)
11501
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
11502
                    rng, key);
11503
        if (!err)
11504
            err = wc_ecc_verify_hash(sig, sigLen,
11505
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
11506
11507
        if (res == 0)
11508
            err = ECC_PCT_E;
11509
11510
        if (dynRng) {
11511
            wc_rng_free(rng);
11512
        }
11513
        ForceZero(sig, sigLen + digestLen);
11514
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11515
    }
11516
    (void)rng;
11517
11518
    if (err != 0)
11519
        err = ECC_PCT_E;
11520
11521
    return err;
11522
}
11523
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
11524
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
11525
11526
#ifndef WOLFSSL_SP_MATH
11527
/* validate order * pubkey = point at infinity, 0 on success */
11528
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
11529
        mp_int* prime, mp_int* order)
11530
0
{
11531
0
    ecc_point* inf = NULL;
11532
#ifdef WOLFSSL_NO_MALLOC
11533
    ecc_point  lcl_inf;
11534
#endif
11535
0
    int err;
11536
11537
0
    if (key == NULL)
11538
0
        return BAD_FUNC_ARG;
11539
0
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
11540
0
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
11541
0
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
11542
0
       return IS_POINT_E;
11543
0
   }
11544
11545
#ifdef WOLFSSL_NO_MALLOC
11546
    inf = &lcl_inf;
11547
#endif
11548
0
    err = wc_ecc_new_point_ex(&inf, key->heap);
11549
0
    if (err == MP_OKAY) {
11550
#ifdef WOLFSSL_HAVE_SP_ECC
11551
#ifndef WOLFSSL_SP_NO_256
11552
        if (key->idx != ECC_CUSTOM_IDX &&
11553
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
11554
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
11555
        }
11556
        else
11557
#endif
11558
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11559
        if (key->idx != ECC_CUSTOM_IDX &&
11560
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
11561
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
11562
        }
11563
        else
11564
#endif
11565
#ifdef WOLFSSL_SP_384
11566
        if (key->idx != ECC_CUSTOM_IDX &&
11567
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
11568
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
11569
        }
11570
        else
11571
#endif
11572
#ifdef WOLFSSL_SP_521
11573
        if (key->idx != ECC_CUSTOM_IDX &&
11574
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
11575
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
11576
        }
11577
        else
11578
#endif
11579
#endif
11580
0
#if !defined(WOLFSSL_SP_MATH)
11581
0
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
11582
0
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
11583
0
            err = ECC_INF_E;
11584
#else
11585
        {
11586
            (void)a;
11587
            (void)prime;
11588
11589
            err = WC_KEY_SIZE_E;
11590
        }
11591
#endif
11592
0
    }
11593
11594
0
    wc_ecc_del_point_ex(inf, key->heap);
11595
11596
0
    return err;
11597
0
}
11598
#endif /* !WOLFSSL_SP_MATH */
11599
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11600
11601
11602
#ifdef OPENSSL_EXTRA
11603
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
11604
{
11605
    int err = MP_OKAY;
11606
    DECLARE_CURVE_SPECS(2);
11607
11608
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
11609
        return BAD_FUNC_ARG;
11610
11611
    ALLOC_CURVE_SPECS(2, err);
11612
11613
    if (err == MP_OKAY)
11614
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
11615
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
11616
    if (err == MP_OKAY)
11617
        err = mp_copy(curve->Gx, ecp->x);
11618
    if (err == MP_OKAY)
11619
        err = mp_copy(curve->Gy, ecp->y);
11620
    if (err == MP_OKAY)
11621
        err = mp_set(ecp->z, 1);
11622
11623
    wc_ecc_curve_free(curve);
11624
    FREE_CURVE_SPECS();
11625
11626
    return err;
11627
}
11628
#endif /* OPENSSL_EXTRA */
11629
11630
11631
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
11632
 * ECC Full Public Key Validation Routine. If the parameter
11633
 * partial is set, then it follows section 5.6.2.3.4, the ECC
11634
 * Partial Public Key Validation Routine.
11635
 * If the parameter priv is set, add in a few extra
11636
 * checks on the bounds of the private key. */
11637
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
11638
0
{
11639
0
    int err = MP_OKAY;
11640
0
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
11641
0
    mp_int* b = NULL;
11642
0
    DECLARE_CURVE_SPECS(4);
11643
0
#endif
11644
11645
0
    if (key == NULL)
11646
0
        return BAD_FUNC_ARG;
11647
11648
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_CHECK_KEY) && \
11649
    !defined(WOLFSSL_CAAM)
11650
    /* Device-first: when a device is configured, let it validate the public
11651
     * key. Fall through to the software/HW path below only when the
11652
     * device reports the operation unavailable.
11653
     * CAAM is excluded: it relies on the software order-check below to detect
11654
     * whether an imported private key is an encrypted black key. */
11655
    #ifndef WOLF_CRYPTO_CB_FIND
11656
    if (key->devId != INVALID_DEVID)
11657
    #endif
11658
    {
11659
        err = wc_CryptoCb_EccCheckPubKey(key, !partial, priv);
11660
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11661
            return err;
11662
        /* device declined; fall through. Every software/HW path below
11663
         * re-initializes err before reading it, so no reset is needed here. */
11664
    }
11665
#endif
11666
11667
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
11668
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
11669
    /* Software validation is stripped; the device-first check above either
11670
     * handled the key or reported the op unavailable, so fail closed rather
11671
     * than accept an unvalidated key. */
11672
    err = NO_VALID_DEVID;
11673
#else
11674
    /* consider key check success on HW crypto
11675
     * ex: ATECC508/608A, CryptoCell and Silabs which validate the key
11676
     * internally
11677
     */
11678
    err = MP_OKAY;
11679
#endif
11680
11681
#else
11682
11683
    /* ECDH uses the point's Z but the SP checks read only x and y, so accept
11684
     * only an affine point (Z = 1); all zero x and y still reports ECC_INF_E. */
11685
0
    if (!wc_ecc_point_is_at_infinity(&key->pubkey) &&
11686
0
            !mp_isone(key->pubkey.z)) {
11687
0
        return ECC_BAD_ARG_E;
11688
0
    }
11689
11690
#ifdef WOLFSSL_HAVE_SP_ECC
11691
#ifndef WOLFSSL_SP_NO_256
11692
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
11693
        err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
11694
            (priv && (key->type == ECC_PRIVATEKEY)) ? ecc_get_k(key) : NULL,
11695
            key->heap);
11696
        ecc_put_k(key);
11697
        return err;
11698
    }
11699
#endif
11700
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11701
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
11702
        err = sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
11703
            (priv && (key->type == ECC_PRIVATEKEY)) ? ecc_get_k(key) : NULL,
11704
            key->heap);
11705
        ecc_put_k(key);
11706
        return err;
11707
    }
11708
#endif
11709
#ifdef WOLFSSL_SP_384
11710
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
11711
        err = sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
11712
            (priv && (key->type == ECC_PRIVATEKEY)) ? ecc_get_k(key) : NULL,
11713
            key->heap);
11714
        ecc_put_k(key);
11715
        return err;
11716
    }
11717
#endif
11718
#ifdef WOLFSSL_SP_521
11719
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
11720
        err = sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
11721
            (priv && (key->type == ECC_PRIVATEKEY)) ? ecc_get_k(key) : NULL,
11722
            key->heap);
11723
        ecc_put_k(key);
11724
        return err;
11725
    }
11726
#endif
11727
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
11728
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
11729
        err = sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
11730
            (priv && (key->type == ECC_PRIVATEKEY)) ? ecc_get_k(key) : NULL,
11731
            key->heap);
11732
        ecc_put_k(key);
11733
        return err;
11734
    }
11735
#endif
11736
#endif
11737
11738
0
#ifndef WOLFSSL_SP_MATH
11739
0
    ALLOC_CURVE_SPECS(4, err);
11740
11741
    #ifdef WOLFSSL_CAAM
11742
    /* keys can be black encrypted ones which can not be checked like plain text
11743
     * keys */
11744
    if (key->blackKey > 0) {
11745
        /* encrypted key was used */
11746
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11747
        FREE_CURVE_SPECS();
11748
        return 0;
11749
    }
11750
    #endif
11751
11752
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
11753
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
11754
    /* pubkey point cannot be at infinity */
11755
0
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11756
0
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11757
0
        FREE_CURVE_SPECS();
11758
0
        return ECC_INF_E;
11759
0
    }
11760
11761
    /* load curve info */
11762
0
    if (err == MP_OKAY)
11763
0
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
11764
0
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER | ECC_CURVE_FIELD_BF));
11765
11766
0
    if (err == MP_OKAY)
11767
0
        b = curve->Bf;
11768
11769
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
11770
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
11771
    /* Qx must be in the range [0, p-1] */
11772
0
    if (err == MP_OKAY) {
11773
0
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
11774
0
                mp_isneg(key->pubkey.x)) {
11775
0
            err = ECC_OUT_OF_RANGE_E;
11776
0
        }
11777
0
    }
11778
11779
    /* Qy must be in the range [0, p-1] */
11780
0
    if (err == MP_OKAY) {
11781
0
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
11782
0
                mp_isneg(key->pubkey.y)) {
11783
0
            err = ECC_OUT_OF_RANGE_E;
11784
0
        }
11785
0
    }
11786
11787
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
11788
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
11789
    /* make sure point is actually on curve */
11790
0
    if (err == MP_OKAY)
11791
0
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
11792
11793
0
    if (!partial) {
11794
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
11795
        /* pubkey * order must be at infinity */
11796
0
        if (err == MP_OKAY)
11797
0
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
11798
0
                    curve->prime, curve->order);
11799
0
    }
11800
11801
0
    if (priv) {
11802
        /* SP 800-56Ar3, section 5.6.2.1.2 */
11803
        /* private keys must be in the range [1, n-1] */
11804
0
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
11805
0
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
11806
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
11807
        #ifdef WOLFSSL_KCAPI_ECC
11808
            && key->handle == NULL
11809
        #endif
11810
0
        ) {
11811
0
            err = ECC_PRIV_KEY_E;
11812
0
        }
11813
11814
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
11815
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
11816
        /* private * base generator must equal pubkey */
11817
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
11818
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11819
    #endif
11820
0
        ecc_put_k(key);
11821
0
    }
11822
11823
0
    wc_ecc_curve_free(curve);
11824
11825
0
    FREE_CURVE_SPECS();
11826
11827
#else
11828
    /* The single precision math curve is not available */
11829
    err = WC_KEY_SIZE_E;
11830
#endif /* !WOLFSSL_SP_MATH */
11831
0
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11832
11833
0
    (void)partial;
11834
0
    (void)priv;
11835
0
    return err;
11836
0
}
11837
11838
11839
/* perform sanity checks on ecc key validity, 0 on success */
11840
WOLFSSL_ABI
11841
int wc_ecc_check_key(ecc_key* key)
11842
0
{
11843
0
    int ret;
11844
    /* _ecc_validate_public_key is the single validation entry point: it is
11845
     * device-first (offloads to the crypto callback when a device is
11846
     * configured) and otherwise runs the software/HW checks, or fails closed
11847
     * under WOLF_CRYPTO_CB_ONLY_ECC. */
11848
0
    ret = _ecc_validate_public_key(key, 0, 1);
11849
0
    return ret;
11850
0
}
11851
11852
11853
#ifdef HAVE_ECC_KEY_IMPORT
11854
/* Software-only import of public ECC key in ANSI X9.63 format.
11855
 * This internal helper avoids recursion when called from the SETKEY path. */
11856
static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11857
                                int curve_id, int untrusted)
11858
865
{
11859
865
    int err = MP_OKAY;
11860
#ifdef HAVE_COMP_KEY
11861
    int compressed = 0;
11862
#endif
11863
865
    int keysize = 0;
11864
865
    byte pointType;
11865
865
    if (in == NULL || key == NULL) {
11866
0
        return BAD_FUNC_ARG;
11867
0
    }
11868
11869
    /* must be odd */
11870
865
    if ((inLen & 1) == 0) {
11871
0
        return ECC_BAD_ARG_E;
11872
0
    }
11873
11874
    /* make sure required variables are reset */
11875
865
    wc_ecc_reset(key);
11876
11877
    /* init key */
11878
    #ifdef ALT_ECC_SIZE
11879
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11880
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11881
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11882
        alt_fp_init(key->pubkey.x);
11883
        alt_fp_init(key->pubkey.y);
11884
        alt_fp_init(key->pubkey.z);
11885
        key->k = (mp_int*)key->ka;
11886
        alt_fp_init(key->k);
11887
    #ifdef WOLFSSL_ECC_BLIND_K
11888
        key->kb = (mp_int*)key->kba;
11889
        key->ku = (mp_int*)key->kua;
11890
        alt_fp_init(key->kb);
11891
        alt_fp_init(key->ku);
11892
    #endif
11893
    #else
11894
865
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11895
865
    #ifndef WOLFSSL_ECC_BLIND_K
11896
865
                                                                      NULL, NULL
11897
    #else
11898
                                                                key->kb, key->ku
11899
    #endif
11900
865
                            );
11901
11902
865
        if (err != MP_OKAY)
11903
0
            return MEMORY_E;
11904
865
    #endif
11905
#ifdef WOLFSSL_ECC_BLIND_K
11906
    mp_forcezero(key->kb);
11907
#endif
11908
11909
    /* check for point type (4, 2, or 3) */
11910
865
    pointType = in[0];
11911
865
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
11912
15
                                         pointType != ECC_POINT_COMP_ODD) {
11913
14
        err = ASN_PARSE_E;
11914
14
    }
11915
11916
865
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
11917
2
    #ifndef HAVE_COMP_KEY
11918
2
        err = NOT_COMPILED_IN;
11919
    #else
11920
        compressed = 1;
11921
    #endif
11922
2
    }
11923
11924
    /* adjust to skip first byte */
11925
865
    inLen -= 1;
11926
865
    in += 1;
11927
11928
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11929
    defined(WOLFSSL_MICROCHIP_TA100)
11930
    /* For SECP256R1 only save raw public key for hardware */
11931
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
11932
    #ifdef HAVE_COMP_KEY
11933
        if (!compressed)
11934
    #endif
11935
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11936
    }
11937
#elif defined(WOLFSSL_KCAPI_ECC)
11938
    if (inLen <= (word32)sizeof(key->pubkey_raw))
11939
        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11940
    else
11941
        err = BAD_FUNC_ARG;
11942
#endif
11943
11944
865
    if (err == MP_OKAY) {
11945
    #ifdef HAVE_COMP_KEY
11946
        /* adjust inLen if compressed */
11947
        if (compressed) {
11948
            /* a compressed coordinate cannot exceed MAX_ECC_BYTES; bound it
11949
             * before doubling so inLen*2 + 1 cannot overflow word32. */
11950
            if (inLen > MAX_ECC_BYTES)
11951
                err = ECC_BAD_ARG_E;
11952
            else
11953
                inLen = inLen*2 + 1;  /* used uncompressed len */
11954
        }
11955
        if (err == MP_OKAY)
11956
    #endif
11957
        /* determine key size */
11958
849
        {
11959
849
            keysize = (int)(inLen>>1);
11960
            /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys,
11961
             *       only on created keys or signatures */
11962
849
            err = wc_ecc_set_curve(key, keysize, curve_id);
11963
849
            key->type = ECC_PUBLICKEY;
11964
849
        }
11965
849
    }
11966
11967
    /* Ordinates must be exactly the curve's size, as wc_ecc_set_curve() only
11968
     * bounds keysize by ECC_MAXSIZE when a curve id is given. */
11969
865
    if (err == MP_OKAY) {
11970
847
        if ((key->dp == NULL) || (keysize != key->dp->size)) {
11971
16
            err = ECC_BAD_ARG_E;
11972
16
        }
11973
847
    }
11974
11975
    /* read data */
11976
865
    if (err == MP_OKAY)
11977
831
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
11978
11979
#ifdef HAVE_COMP_KEY
11980
    if (err == MP_OKAY && compressed == 1) {   /* build y */
11981
/* Recovering y needs mp_sqrtmod_prime(), which is only compiled in alongside
11982
 * the rest of the software ECC math. Ports that replace it use the SP
11983
 * uncompress helpers below, or fail with WC_KEY_SIZE_E when those are absent
11984
 * too. */
11985
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
11986
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
11987
    !defined(WOLFSSL_NO_ECC_SW)
11988
    #ifdef WOLFSSL_SMALL_STACK
11989
        mp_int* t1 = NULL;
11990
        mp_int* t2 = NULL;
11991
    #else
11992
        mp_int t1[1], t2[1];
11993
    #endif
11994
        int did_init = 0;
11995
11996
        DECLARE_CURVE_SPECS(3);
11997
        ALLOC_CURVE_SPECS(3, err);
11998
11999
        #ifdef WOLFSSL_SMALL_STACK
12000
        if (err == MP_OKAY) {
12001
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
12002
            if (t1 == NULL) {
12003
                err = MEMORY_E;
12004
            }
12005
        }
12006
        if (err == MP_OKAY) {
12007
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
12008
            if (t2 == NULL) {
12009
                err = MEMORY_E;
12010
            }
12011
        }
12012
        #endif
12013
        if (err == MP_OKAY) {
12014
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
12015
                err = MEMORY_E;
12016
            else
12017
                did_init = 1;
12018
        }
12019
12020
        /* load curve info */
12021
        if (err == MP_OKAY)
12022
            err = wc_ecc_curve_load(key->dp, &curve,
12023
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
12024
                 ECC_CURVE_FIELD_BF));
12025
12026
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
12027
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
12028
        /* validate prime is prime for custom curves */
12029
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
12030
            int isPrime = MP_NO;
12031
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
12032
            if (err == MP_OKAY && isPrime == MP_NO)
12033
                err = MP_VAL;
12034
        }
12035
    #endif
12036
12037
        /* compute x^3 */
12038
        if (err == MP_OKAY)
12039
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
12040
        if (err == MP_OKAY)
12041
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
12042
12043
        /* compute x^3 + a*x */
12044
        if (err == MP_OKAY)
12045
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
12046
        if (err == MP_OKAY)
12047
            err = mp_add(t1, t2, t1);
12048
12049
        /* compute x^3 + a*x + b */
12050
        if (err == MP_OKAY)
12051
            err = mp_add(t1, curve->Bf, t1);
12052
12053
        /* compute sqrt(x^3 + a*x + b) */
12054
        if (err == MP_OKAY)
12055
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
12056
12057
        /* adjust y */
12058
        if (err == MP_OKAY) {
12059
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
12060
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
12061
                err = mp_mod(t2, curve->prime, t2);
12062
            }
12063
            else {
12064
                err = mp_submod(curve->prime, t2, curve->prime, t2);
12065
            }
12066
            if (err == MP_OKAY)
12067
                err = mp_copy(t2, key->pubkey.y);
12068
        }
12069
12070
        if (did_init) {
12071
            mp_clear(t2);
12072
            mp_clear(t1);
12073
        }
12074
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
12075
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
12076
12077
        wc_ecc_curve_free(curve);
12078
        FREE_CURVE_SPECS();
12079
#else
12080
    /* The SP helpers only exist when SP ECC is compiled in; without them (a
12081
     * hardware port with no software math and no SP) there is no way to
12082
     * recover y. */
12083
    #ifdef WOLFSSL_HAVE_SP_ECC
12084
    #ifndef WOLFSSL_SP_NO_256
12085
        if (key->dp->id == ECC_SECP256R1) {
12086
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
12087
                key->pubkey.y);
12088
        }
12089
        else
12090
    #endif
12091
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
12092
        if (key->dp->id == ECC_SM2P256V1) {
12093
            err = sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
12094
        }
12095
        else
12096
    #endif
12097
    #ifdef WOLFSSL_SP_384
12098
        if (key->dp->id == ECC_SECP384R1) {
12099
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
12100
                key->pubkey.y);
12101
        }
12102
        else
12103
    #endif
12104
    #ifdef WOLFSSL_SP_521
12105
        if (key->dp->id == ECC_SECP521R1) {
12106
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
12107
                key->pubkey.y);
12108
        }
12109
        else
12110
    #endif
12111
    #endif /* WOLFSSL_HAVE_SP_ECC */
12112
        {
12113
            err = WC_KEY_SIZE_E;
12114
        }
12115
#endif
12116
    }
12117
#endif /* HAVE_COMP_KEY */
12118
12119
865
    if (err == MP_OKAY) {
12120
    #ifdef HAVE_COMP_KEY
12121
        if (compressed == 0)
12122
    #endif
12123
831
        {
12124
831
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
12125
831
                (word32)keysize);
12126
831
        }
12127
831
    }
12128
865
    if (err == MP_OKAY)
12129
831
        err = mp_set(key->pubkey.z, 1);
12130
12131
#ifdef WOLFSSL_SILABS_SE_ACCEL
12132
    if (err == MP_OKAY)
12133
        err = silabs_ecc_import(key, keysize, 1, 0);
12134
#elif defined(WOLFSSL_SE050)
12135
    if (err == MP_OKAY) {
12136
        /* reset key ID, in case used before */
12137
        key->keyId = 0;
12138
        key->keyIdSet = 0;
12139
    }
12140
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12141
    #ifndef HAVE_COMP_KEY
12142
    if (err == MP_OKAY) {
12143
    #else
12144
    if (err == MP_OKAY && !compressed) {
12145
    #endif
12146
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
12147
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
12148
    }
12149
#endif
12150
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12151
    if (err == MP_OKAY)
12152
        err = wc_ecc_check_key(key);
12153
#endif
12154
/* Deliberately not excluded under WOLFSSL_NO_ECC_SW: both checks below are
12155
 * plain modular arithmetic that stays compiled in, so an untrusted peer key is
12156
 * still rejected on the host rather than relying on the hardware to do it. */
12157
865
#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
12158
865
     !defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
12159
865
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
12160
865
     (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
12161
865
       defined(WOLFSSL_IMXRT1170_CAAM))
12162
865
    if ((err == MP_OKAY) && untrusted) {
12163
        /* Reject point at infinity. */
12164
831
        if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
12165
1
            err = ECC_INF_E;
12166
1
        }
12167
        /* Verify the point lies on the curve (y^2 = x^3 + ax + b mod p) */
12168
831
        if ((err == MP_OKAY) && (key->idx != ECC_CUSTOM_IDX)) {
12169
    #ifdef WOLFSSL_HAVE_SP_ECC
12170
        #ifndef WOLFSSL_SP_NO_256
12171
            if (ecc_sets[key->idx].id == ECC_SECP256R1) {
12172
                err = sp_ecc_is_point_256(key->pubkey.x, key->pubkey.y);
12173
            #if defined(WOLFSSL_SM2)
12174
                if (err != MP_OKAY && curve_id < 0) {
12175
                    /* Retry with SM2 curve when P-256 returns invalid.
12176
                     * Only when no explicit curve was requested (curve_id < 0).
12177
                     * Needed because SM2 keys can be mis-identified as
12178
                     * SECP256R1 during parsing. */
12179
                #if defined(WOLFSSL_SP_SM2)
12180
                    err = sp_ecc_is_point_sm2_256(key->pubkey.x,
12181
                                                  key->pubkey.y);
12182
                #else
12183
                    int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
12184
                    if (sm2_idx != ECC_CURVE_INVALID)
12185
                        err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
12186
                #endif
12187
                    if (err == MP_OKAY) {
12188
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
12189
                                               ECC_SM2P256V1);
12190
                    }
12191
                }
12192
            #endif
12193
            }
12194
            else
12195
        #endif
12196
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
12197
            if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
12198
                err = sp_ecc_is_point_sm2_256(key->pubkey.x, key->pubkey.y);
12199
            }
12200
            else
12201
        #endif
12202
        #ifdef WOLFSSL_SP_384
12203
            if (ecc_sets[key->idx].id == ECC_SECP384R1) {
12204
                err = sp_ecc_is_point_384(key->pubkey.x, key->pubkey.y);
12205
            }
12206
            else
12207
        #endif
12208
        #ifdef WOLFSSL_SP_521
12209
            if (ecc_sets[key->idx].id == ECC_SECP521R1) {
12210
                err = sp_ecc_is_point_521(key->pubkey.x, key->pubkey.y);
12211
            }
12212
            else
12213
        #endif
12214
            {
12215
                err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
12216
            }
12217
    #else
12218
830
            err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
12219
        #if defined(WOLFSSL_SM2)
12220
            if (err != MP_OKAY && curve_id < 0) {
12221
                /* Retry with SM2 curve when P-256 returns invalid.
12222
                 * Only when no explicit curve was requested (curve_id < 0).
12223
                 * Needed because SM2 keys can be mis-identified as
12224
                 * SECP256R1 during parsing. */
12225
                int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
12226
                if (sm2_idx != ECC_CURVE_INVALID) {
12227
                    err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
12228
                    if (err == MP_OKAY) {
12229
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
12230
                                               ECC_SM2P256V1);
12231
                    }
12232
                }
12233
            }
12234
        #endif
12235
830
    #endif /* WOLFSSL_HAVE_SP_ECC */
12236
830
        }
12237
831
    }
12238
865
#endif
12239
865
    (void)untrusted;
12240
12241
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12242
    if (err == MP_OKAY) {
12243
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
12244
    }
12245
#endif
12246
12247
865
    if (err != MP_OKAY) {
12248
865
        mp_clear(key->pubkey.x);
12249
865
        mp_clear(key->pubkey.y);
12250
865
        mp_clear(key->pubkey.z);
12251
865
        mp_forcezero(key->k);
12252
865
    }
12253
12254
865
    return err;
12255
865
}
12256
12257
/* import public ECC key in ANSI X9.63 format */
12258
int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
12259
                           int curve_id, int untrusted)
12260
878
{
12261
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12262
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12263
    int err = 0;
12264
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12265
#endif
12266
12267
878
    if (in == NULL || key == NULL) {
12268
0
        return BAD_FUNC_ARG;
12269
0
    }
12270
12271
    /* must be odd */
12272
878
    if ((inLen & 1) == 0) {
12273
13
        return ECC_BAD_ARG_E;
12274
13
    }
12275
12276
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12277
    #ifndef WOLF_CRYPTO_CB_FIND
12278
    if (key->devId != INVALID_DEVID)
12279
    #endif
12280
    {
12281
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12282
        if (!WC_VAR_OK(tmpKey)) {
12283
            return MEMORY_E;
12284
        }
12285
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12286
12287
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12288
        if (err != 0) {
12289
            WC_FREE_VAR(tmpKey, key->heap);
12290
            return err;
12291
        }
12292
12293
    #ifdef WOLFSSL_CUSTOM_CURVES
12294
        if (key->dp != NULL) {
12295
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
12296
            if (err != 0) {
12297
                wc_ecc_free(tmpKey);
12298
                WC_FREE_VAR(tmpKey, key->heap);
12299
                return err;
12300
            }
12301
        }
12302
    #endif
12303
12304
        /* Import into temp via software helper (no callback recursion) */
12305
        err = _ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted);
12306
        if (err == MP_OKAY) {
12307
            cbRet = wc_CryptoCb_SetKey(key->devId,
12308
                WC_SETKEY_ECC_PUB, key, tmpKey,
12309
                wc_ecc_size(tmpKey), NULL, 0, 0);
12310
        }
12311
12312
        wc_ecc_free(tmpKey);
12313
        WC_FREE_VAR(tmpKey, key->heap);
12314
12315
        if (err != MP_OKAY) {
12316
            return err;
12317
        }
12318
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12319
            return cbRet;
12320
        }
12321
    }
12322
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12323
12324
865
    return _ecc_import_x963_ex2(in, inLen, key, curve_id, untrusted);
12325
878
}
12326
12327
/* import public ECC key in ANSI X9.63 format */
12328
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
12329
                          int curve_id)
12330
878
{
12331
    /* treat as untrusted: validate the point is on the curve */
12332
878
    return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1);
12333
878
}
12334
12335
WOLFSSL_ABI
12336
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
12337
0
{
12338
0
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
12339
0
}
12340
#endif /* HAVE_ECC_KEY_IMPORT */
12341
12342
#ifdef HAVE_ECC_KEY_EXPORT
12343
12344
/* Software-only export of ecc key to component form.
12345
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
12346
static int _ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
12347
                          byte* qy, word32* qyLen, byte* d, word32* dLen,
12348
                          int encType, int dOrderSz)
12349
0
{
12350
0
    int err = 0;
12351
0
    word32 keySz;
12352
12353
0
    if (key == NULL) {
12354
0
        return BAD_FUNC_ARG;
12355
0
    }
12356
12357
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
12358
0
        return ECC_BAD_ARG_E;
12359
0
    }
12360
0
    keySz = (word32)key->dp->size;
12361
12362
    /* private key, d */
12363
0
    if (d != NULL) {
12364
0
        if (dLen == NULL ||
12365
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
12366
0
            return BAD_FUNC_ARG;
12367
12368
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12369
        defined(WOLFSSL_MICROCHIP_TA100)
12370
        /* Hardware cannot export private portion */
12371
        (void)dOrderSz;
12372
        return NOT_COMPILED_IN;
12373
    #else
12374
    #if defined(WOLFSSL_SECO_CAAM)
12375
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
12376
            /* Hardware cannot export private portion */
12377
            WOLFSSL_MSG("Can not export private key from HSM");
12378
            return NOT_COMPILED_IN;
12379
        }
12380
    #endif
12381
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12382
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
12383
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
12384
                *dLen = keySz + WC_CAAM_MAC_SZ;
12385
                return BUFFER_E;
12386
            }
12387
12388
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
12389
                encType);
12390
            ecc_put_k(key);
12391
            *dLen = keySz + WC_CAAM_MAC_SZ;
12392
        }
12393
        else if (encType == WC_TYPE_BLACK_KEY &&
12394
                key->blackKey != CAAM_BLACK_KEY_ECB &&
12395
                key->blackKey > 0) {
12396
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
12397
                *dLen = keySz + WC_CAAM_MAC_SZ;
12398
                return BUFFER_E;
12399
            }
12400
12401
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
12402
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
12403
                    return WC_HW_E;
12404
            }
12405
12406
            *dLen = keySz + WC_CAAM_MAC_SZ;
12407
        }
12408
        else
12409
    #endif
12410
0
        {
12411
0
            err = wc_export_int(ecc_get_k(key), d, dLen,
12412
0
                dOrderSz ? ecc_order_size(key->dp) : keySz, encType);
12413
0
            ecc_put_k(key);
12414
0
            if (err != MP_OKAY)
12415
0
                return err;
12416
0
        }
12417
0
    #endif
12418
0
    }
12419
12420
    /* public x component */
12421
0
    if (qx != NULL) {
12422
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
12423
0
            return BAD_FUNC_ARG;
12424
12425
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
12426
0
        if (err != MP_OKAY)
12427
0
            return err;
12428
0
    }
12429
12430
    /* public y component */
12431
0
    if (qy != NULL) {
12432
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
12433
0
            return BAD_FUNC_ARG;
12434
12435
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
12436
0
        if (err != MP_OKAY)
12437
0
            return err;
12438
0
    }
12439
12440
0
    return err;
12441
0
}
12442
12443
12444
/* Export with d at the size of the order when dOrderSz is set. */
12445
static int ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
12446
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType,
12447
                 int dOrderSz)
12448
0
{
12449
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12450
    int err;
12451
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12452
#endif
12453
12454
0
    if (key == NULL) {
12455
0
        return BAD_FUNC_ARG;
12456
0
    }
12457
12458
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12459
    #ifndef WOLF_CRYPTO_CB_FIND
12460
    if (key->devId != INVALID_DEVID)
12461
    #endif
12462
    {
12463
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12464
        if (!WC_VAR_OK(tmpKey)) {
12465
            return MEMORY_E;
12466
        }
12467
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12468
12469
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12470
        if (err != 0) {
12471
            WC_FREE_VAR(tmpKey, key->heap);
12472
            return err;
12473
        }
12474
12475
        err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
12476
                                     key, tmpKey);
12477
        if (err == 0) {
12478
            /* Call software helper (no callback recursion) */
12479
            err = _ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen,
12480
                                  encType, dOrderSz);
12481
        }
12482
12483
        wc_ecc_free(tmpKey);
12484
        WC_FREE_VAR(tmpKey, key->heap);
12485
12486
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12487
            return err;
12488
        }
12489
    }
12490
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
12491
12492
0
    return _ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType,
12493
0
        dOrderSz);
12494
0
}
12495
12496
/* export ecc key to component form, d is optional if only exporting public
12497
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
12498
 * return MP_OKAY on success */
12499
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
12500
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
12501
0
{
12502
0
    return ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType, 0);
12503
0
}
12504
12505
/* Export the private key only, with d at the size of the order when dOrderSz
12506
 * is set. */
12507
static int ecc_export_private(ecc_key* key, byte* out, word32* outLen,
12508
    int dOrderSz)
12509
0
{
12510
0
    int encType = WC_TYPE_UNSIGNED_BIN;
12511
12512
0
    if (key == NULL) {
12513
0
        return BAD_FUNC_ARG;
12514
0
    }
12515
12516
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12517
    /* check if black key in secure memory */
12518
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
12519
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
12520
        encType = WC_TYPE_BLACK_KEY;
12521
    }
12522
#endif
12523
12524
0
    return ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen, encType,
12525
0
        dOrderSz);
12526
0
}
12527
12528
/* export ecc private key only raw, outLen is in/out size as unsigned bin
12529
   return MP_OKAY on success */
12530
WOLFSSL_ABI
12531
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
12532
0
{
12533
0
    if (out == NULL || outLen == NULL) {
12534
0
        return BAD_FUNC_ARG;
12535
0
    }
12536
12537
0
    return ecc_export_private(key, out, outLen, 0);
12538
0
}
12539
12540
/* Export the private key zero-padded to the size of the order, as RFC 5915
12541
 * encodes it. A NULL out returns LENGTH_ONLY_E with the size needed. */
12542
int wc_ecc_export_private_order(ecc_key* key, byte* out, word32* outLen)
12543
0
{
12544
0
    if ((key == NULL) || (outLen == NULL)) {
12545
0
        return BAD_FUNC_ARG;
12546
0
    }
12547
12548
0
    if (out == NULL) {
12549
0
        if ((key->dp == NULL) || (wc_ecc_is_valid_idx(key->idx) == 0)) {
12550
0
            return ECC_BAD_ARG_E;
12551
0
        }
12552
    #if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12553
        if (key->devId == INVALID_DEVID)
12554
    #endif
12555
0
        {
12556
0
            if ((key->type != ECC_PRIVATEKEY) &&
12557
0
                    (key->type != ECC_PRIVATEKEY_ONLY)) {
12558
0
                return BAD_FUNC_ARG;
12559
0
            }
12560
0
        }
12561
0
        *outLen = ecc_order_size(key->dp);
12562
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12563
        if ((key->blackKey > 0) && (key->blackKey != CAAM_BLACK_KEY_ECB)) {
12564
            *outLen = (word32)key->dp->size + WC_CAAM_MAC_SZ;
12565
        }
12566
    #endif
12567
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
12568
0
    }
12569
12570
0
    return ecc_export_private(key, out, outLen, 1);
12571
0
}
12572
12573
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
12574
 * return MP_OKAY on success, negative on error */
12575
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
12576
                             byte* qy, word32* qyLen)
12577
0
{
12578
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
12579
0
        return BAD_FUNC_ARG;
12580
0
    }
12581
12582
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
12583
0
        WC_TYPE_UNSIGNED_BIN);
12584
0
}
12585
12586
/* export ecc key to raw elements including public (Qx,Qy) and
12587
 *   private (d) as unsigned bin
12588
 * return MP_OKAY on success, negative on error */
12589
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
12590
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
12591
0
{
12592
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
12593
0
        WC_TYPE_UNSIGNED_BIN);
12594
0
}
12595
12596
#endif /* HAVE_ECC_KEY_EXPORT */
12597
12598
#ifdef HAVE_ECC_KEY_IMPORT
12599
/* Check an imported private scalar is in [1, n-1] for the key's curve.
12600
 *
12601
 * Cheap by design - reads the order and compares, with no curve spec load or
12602
 * point arithmetic, so it runs on every import. The expensive public key
12603
 * consistency check stays behind WOLFSSL_VALIDATE_ECC_IMPORT.
12604
 *
12605
 * @param [in] key  ECC key with k and dp set.
12606
 * @return  0 when the scalar is in range.
12607
 * @return  ECC_PRIV_KEY_E when it is zero, negative or >= the order.
12608
 * @return  BAD_FUNC_ARG, MEMORY_E or a math error otherwise.
12609
 */
12610
static int ecc_check_privkey_range(ecc_key* key)
12611
0
{
12612
0
    int ret = 0;
12613
0
    mp_int* k;
12614
0
    WC_DECLARE_VAR(order, mp_int, 1, 0);
12615
12616
0
    if ((key == NULL) || (key->dp == NULL)) {
12617
0
        return BAD_FUNC_ARG;
12618
0
    }
12619
12620
    /* ecc_get_k() - not key->k - so this is correct on either side of
12621
     * ecc_blind_k_rng() under WOLFSSL_ECC_BLIND_K. */
12622
0
    k = ecc_get_k(key);
12623
12624
#ifdef WOLFSSL_SE050
12625
    /* A zero scalar is how a key held in the secure element looks to
12626
     * software: se050_ecc_create_key() fills in only the public part, so the
12627
     * DER it round-trips through carries a zero private value. Range
12628
     * checking still applies to a scalar that is actually present. */
12629
    if (mp_iszero(k)) {
12630
        ecc_put_k(key);
12631
        return 0;
12632
    }
12633
#endif
12634
12635
    /* SP 800-56Ar3, section 5.6.2.1.2 - private keys are in [1, n-1]. */
12636
0
    if (mp_iszero(k) || mp_isneg(k)) {
12637
0
        ecc_put_k(key);
12638
0
        return ECC_PRIV_KEY_E;
12639
0
    }
12640
12641
0
    WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
12642
0
        ret=MEMORY_E);
12643
12644
0
    if (ret == 0) {
12645
0
        ret = mp_init(order);
12646
0
    }
12647
0
    if (ret == 0) {
12648
0
        ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
12649
    #ifdef WOLFSSL_SM2
12650
        /* SM2 curve: private key must be less than order-1. */
12651
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
12652
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
12653
            ret = mp_sub_d(order, 1, order);
12654
        }
12655
    #endif
12656
0
        if ((ret == 0) && (mp_cmp(k, order) != MP_LT)) {
12657
0
            ret = ECC_PRIV_KEY_E;
12658
0
        }
12659
0
        mp_clear(order);
12660
0
    }
12661
0
    WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
12662
0
    ecc_put_k(key);
12663
12664
0
    return ret;
12665
0
}
12666
12667
/* Without a curve id, a private key whose size no curve has, but which is the
12668
 * order size of a curve one byte shorter, is taken as that curve's. */
12669
static int ecc_priv_curve_id(word32 privSz, int curve_id)
12670
0
{
12671
0
    int x;
12672
12673
0
    if (curve_id > ECC_CURVE_DEF) {
12674
0
        return curve_id;
12675
0
    }
12676
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
12677
0
        if ((word32)ecc_sets[x].size == privSz) {
12678
0
            return curve_id;
12679
0
        }
12680
0
    }
12681
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
12682
0
        if (((word32)ecc_sets[x].size + 1 == privSz) &&
12683
0
                (ecc_order_size(&ecc_sets[x]) == privSz)) {
12684
0
            return ecc_sets[x].id;
12685
0
        }
12686
0
    }
12687
0
    return curve_id;
12688
0
}
12689
12690
/* Software-only import of private key, public part optional.
12691
 * This internal helper avoids recursion when called from the SETKEY path. */
12692
static int _ecc_import_private_key_ex(const byte* priv, word32 privSz,
12693
                                      const byte* pub, word32 pubSz,
12694
                                      ecc_key* key, int curve_id)
12695
0
{
12696
0
    int ret;
12697
0
    if (key == NULL || priv == NULL) {
12698
0
        return BAD_FUNC_ARG;
12699
0
    }
12700
12701
    /* public optional, NULL if only importing private */
12702
0
    if (pub != NULL) {
12703
0
    #ifndef NO_ASN
12704
0
        word32 idx = 0;
12705
0
        ret = _ecc_import_x963_ex2(pub, pubSz, key, curve_id, 0);
12706
0
        if (ret < 0)
12707
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
12708
0
        key->type = ECC_PRIVATEKEY;
12709
    #else
12710
        (void)pubSz;
12711
        ret = NOT_COMPILED_IN;
12712
    #endif
12713
0
    }
12714
0
    else {
12715
        /* make sure required variables are reset */
12716
0
        wc_ecc_reset(key);
12717
12718
        /* set key size */
12719
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
12720
         *       on created keys or signatures */
12721
0
        ret = wc_ecc_set_curve(key, (int)privSz,
12722
0
            ecc_priv_curve_id(privSz, curve_id));
12723
0
        key->type = ECC_PRIVATEKEY_ONLY;
12724
0
    }
12725
12726
0
    if (ret != 0) {
12727
0
        ecc_forcezero_k(key);
12728
0
        key->type = 0;
12729
0
        return ret;
12730
0
    }
12731
12732
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12733
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
12734
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
12735
        int part = caamFindUnusedPartition();
12736
        if (part >= 0) {
12737
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
12738
            if (vaddr == 0) {
12739
                WOLFSSL_MSG("Unable to get partition");
12740
                return MEMORY_E;
12741
            }
12742
12743
            key->partNum  = part;
12744
            key->blackKey = (word32)vaddr;
12745
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
12746
                return WC_HW_E;
12747
12748
            if (pub != NULL) {
12749
                /* +1 to account for x963 compressed bit */
12750
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
12751
                    return WC_HW_E;
12752
                key->securePubKey = (word32)vaddr + privSz;
12753
            }
12754
        }
12755
        else {
12756
            WOLFSSL_MSG("Unable to find an unused partition");
12757
            return MEMORY_E;
12758
        }
12759
    #else
12760
        key->blackKey = CAAM_BLACK_KEY_CCM;
12761
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12762
    #ifdef WOLFSSL_ECC_BLIND_K
12763
        if (ret == MP_OKAY) {
12764
            ret = ecc_blind_k_rng(key, NULL);
12765
        }
12766
    #endif
12767
    #endif
12768
    }
12769
    else {
12770
        key->blackKey = 0;
12771
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12772
    #ifdef WOLFSSL_ECC_BLIND_K
12773
        if (ret == MP_OKAY) {
12774
            ret = ecc_blind_k_rng(key, NULL);
12775
        }
12776
    #endif
12777
12778
        /* If using AES-ECB encrypted black keys check here if key is valid,
12779
         * if not valid than assume is an encrypted key. A public key is needed
12780
         * for testing validity. */
12781
        if (key->devId == WOLFSSL_CAAM_DEVID && (
12782
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
12783
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
12784
            if ((pub != NULL) && (ret == MP_OKAY) &&
12785
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
12786
                key->blackKey = CAAM_BLACK_KEY_ECB;
12787
            }
12788
            else if ((pub == NULL) && (ret == MP_OKAY)) {
12789
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
12790
                key->blackKey = CAAM_BLACK_KEY_ECB;
12791
            }
12792
            else {
12793
                WOLFSSL_MSG("Importing key that is not a black key!");
12794
            }
12795
        }
12796
12797
        /* Plain text software keys can be checked when imported. */
12798
        if ((ret == MP_OKAY) && (key->blackKey == 0)) {
12799
            ret = ecc_check_privkey_range(key);
12800
        }
12801
    }
12802
#else
12803
12804
#ifdef WOLFSSL_ECC_BLIND_K
12805
    /* Drop any blind left over from a previous use of this key: the new
12806
     * scalar is read in unblinded and ecc_blind_k_rng() below installs a
12807
     * fresh one. Matches the x963 and raw import paths. */
12808
    mp_forcezero(key->kb);
12809
#endif
12810
0
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
12811
#ifdef HAVE_WOLF_BIGINT
12812
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
12813
                                                                 privSz) != 0) {
12814
        mp_clear(key->k);
12815
        ret = ASN_GETINT_E;
12816
    }
12817
#endif /* HAVE_WOLF_BIGINT */
12818
0
    if (ret == 0) {
12819
0
        ret = ecc_check_privkey_range(key);
12820
0
    }
12821
#ifdef WOLFSSL_ECC_BLIND_K
12822
    if (ret == 0) {
12823
        ret = ecc_blind_k_rng(key, NULL);
12824
    }
12825
#endif
12826
12827
0
#endif /* WOLFSSL_QNX_CAAM || WOLFSSL_IMXRT1170_CAAM */
12828
12829
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
12830
    if ((pub != NULL) && (ret == MP_OKAY))
12831
        /* public key needed to perform key validation */
12832
        ret = _ecc_validate_public_key(key, 1, 1);
12833
12834
#endif
12835
12836
0
    if (ret != 0) {
12837
        /* Rejected scalar must not stay in the key
12838
         * (ISO/IEC 19790:2012 7.9.7). */
12839
0
        ecc_forcezero_k(key);
12840
0
        key->type = (pub != NULL) ? ECC_PUBLICKEY : 0;
12841
0
    }
12842
12843
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12844
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
12845
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12846
    }
12847
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12848
    if (ret == 0) {
12849
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
12850
    }
12851
#endif
12852
12853
0
    return ret;
12854
0
}
12855
12856
/* import private key, public part optional if (pub) passed as NULL */
12857
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
12858
                                 const byte* pub, word32 pubSz, ecc_key* key,
12859
                                 int curve_id)
12860
0
{
12861
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12862
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12863
    int tmpErr = 0;
12864
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12865
#endif
12866
12867
0
    if (key == NULL || priv == NULL) {
12868
0
        return BAD_FUNC_ARG;
12869
0
    }
12870
12871
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12872
    #ifndef WOLF_CRYPTO_CB_FIND
12873
    if (key->devId != INVALID_DEVID)
12874
    #endif
12875
    {
12876
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12877
        if (!WC_VAR_OK(tmpKey)) {
12878
            return MEMORY_E;
12879
        }
12880
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12881
12882
        tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12883
        if (tmpErr != 0) {
12884
            WC_FREE_VAR(tmpKey, key->heap);
12885
            return tmpErr;
12886
        }
12887
12888
    #ifdef WOLFSSL_CUSTOM_CURVES
12889
        if (key->dp != NULL) {
12890
            tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp);
12891
            if (tmpErr != 0) {
12892
                wc_ecc_free(tmpKey);
12893
                WC_FREE_VAR(tmpKey, key->heap);
12894
                return tmpErr;
12895
            }
12896
        }
12897
    #endif
12898
12899
        /* Import into temp via software helper (no callback recursion) */
12900
        tmpErr = _ecc_import_private_key_ex(priv, privSz, pub, pubSz,
12901
            tmpKey, curve_id);
12902
        if (tmpErr == 0) {
12903
            cbRet = wc_CryptoCb_SetKey(key->devId,
12904
                WC_SETKEY_ECC_PRIV, key, tmpKey,
12905
                wc_ecc_size(tmpKey), NULL, 0, 0);
12906
        }
12907
12908
        /* wc_ecc_free calls mp_forcezero on private key components,
12909
         * so no separate ForceZero of the struct is needed here. */
12910
        wc_ecc_free(tmpKey);
12911
        WC_FREE_VAR(tmpKey, key->heap);
12912
12913
        if (tmpErr != 0) {
12914
            return tmpErr;
12915
        }
12916
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12917
            return cbRet;
12918
        }
12919
    }
12920
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12921
12922
0
    return _ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, curve_id);
12923
0
}
12924
12925
/* ecc private key import, public key in ANSI X9.63 format, private raw */
12926
WOLFSSL_ABI
12927
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
12928
                           word32 pubSz, ecc_key* key)
12929
0
{
12930
0
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
12931
0
                                                                ECC_CURVE_DEF);
12932
0
}
12933
#endif /* HAVE_ECC_KEY_IMPORT */
12934
12935
#ifndef NO_ASN
12936
/**
12937
   Convert ECC R,S to signature
12938
   r       R component of signature
12939
   s       S component of signature
12940
   out     DER-encoded ECDSA signature
12941
   outlen  [in/out] output buffer size, output signature size
12942
   return  MP_OKAY on success
12943
*/
12944
WOLFSSL_ABI
12945
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
12946
0
{
12947
0
    int err;
12948
#ifdef WOLFSSL_SMALL_STACK
12949
    mp_int* rtmp = NULL;
12950
    mp_int* stmp = NULL;
12951
#else
12952
0
    mp_int  rtmp[1];
12953
0
    mp_int  stmp[1];
12954
0
#endif
12955
12956
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
12957
0
        return ECC_BAD_ARG_E;
12958
12959
#ifdef WOLFSSL_SMALL_STACK
12960
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12961
    if (rtmp == NULL)
12962
        return MEMORY_E;
12963
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12964
    if (stmp == NULL) {
12965
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
12966
        return MEMORY_E;
12967
    }
12968
#endif
12969
12970
0
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
12971
0
    if (err != MP_OKAY) {
12972
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12973
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12974
0
        return err;
12975
0
    }
12976
12977
0
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
12978
0
    if (err == MP_OKAY)
12979
0
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
12980
12981
0
    if (err == MP_OKAY) {
12982
0
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
12983
0
            err = MP_ZERO_E;
12984
0
    }
12985
0
    if (err == MP_OKAY) {
12986
0
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
12987
0
            err = MP_READ_E;
12988
0
        }
12989
0
    }
12990
12991
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
12992
0
    if (err == MP_OKAY)
12993
0
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
12994
12995
0
    mp_clear(rtmp);
12996
0
    mp_clear(stmp);
12997
0
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12998
0
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12999
13000
0
    return err;
13001
0
}
13002
13003
/**
13004
   Convert ECC R,S raw unsigned bin to signature
13005
   r       R component of signature
13006
   rSz     R size
13007
   s       S component of signature
13008
   sSz     S size
13009
   out     DER-encoded ECDSA signature
13010
   outlen  [in/out] output buffer size, output signature size
13011
   return  MP_OKAY on success
13012
*/
13013
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
13014
    byte* out, word32* outlen)
13015
0
{
13016
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
13017
0
        return ECC_BAD_ARG_E;
13018
13019
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
13020
0
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
13021
0
}
13022
13023
/**
13024
   Convert ECC signature to R,S
13025
   sig     DER-encoded ECDSA signature
13026
   sigLen  length of signature in octets
13027
   r       R component of signature
13028
   rLen    [in/out] output "r" buffer size, output "r" size
13029
   s       S component of signature
13030
   sLen    [in/out] output "s" buffer size, output "s" size
13031
   return  MP_OKAY on success, negative on error
13032
*/
13033
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
13034
                     byte* s, word32* sLen)
13035
0
{
13036
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
13037
0
        return ECC_BAD_ARG_E;
13038
13039
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
13040
0
}
13041
#endif /* !NO_ASN */
13042
13043
#ifdef HAVE_ECC_KEY_IMPORT
13044
/* Software-only import of raw ECC key material.
13045
 * This internal helper avoids recursion when called from the SETKEY path. */
13046
static int _ecc_import_raw_private(ecc_key* key, const char* qx,
13047
          const char* qy, const char* d, int curve_id, int encType)
13048
0
{
13049
0
    int err = MP_OKAY;
13050
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
13051
    defined(WOLFSSL_MICROCHIP_TA100)
13052
    word32 keySz = 0;
13053
#endif
13054
13055
    /* if d is NULL, only import as public key using Qx,Qy */
13056
0
    if (key == NULL || qx == NULL || qy == NULL) {
13057
0
        return BAD_FUNC_ARG;
13058
0
    }
13059
13060
    /* make sure required variables are reset */
13061
0
    wc_ecc_reset(key);
13062
13063
    /* set curve type and index */
13064
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
13065
     *       on created keys or signatures */
13066
0
    err = wc_ecc_set_curve(key, 0, curve_id);
13067
0
    if (err != 0) {
13068
0
        return err;
13069
0
    }
13070
13071
    /* init key */
13072
#ifdef ALT_ECC_SIZE
13073
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
13074
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
13075
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
13076
    alt_fp_init(key->pubkey.x);
13077
    alt_fp_init(key->pubkey.y);
13078
    alt_fp_init(key->pubkey.z);
13079
    key->k = (mp_int*)key->ka;
13080
    alt_fp_init(key->k);
13081
#ifdef WOLFSSL_ECC_BLIND_K
13082
    key->kb = (mp_int*)key->kba;
13083
    key->ku = (mp_int*)key->kua;
13084
    alt_fp_init(key->kb);
13085
    alt_fp_init(key->ku);
13086
#endif
13087
#else
13088
0
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
13089
0
#ifndef WOLFSSL_ECC_BLIND_K
13090
0
                                                                      NULL, NULL
13091
#else
13092
                                                                key->kb, key->ku
13093
#endif
13094
0
                        );
13095
13096
0
    if (err != MP_OKAY)
13097
0
        return MEMORY_E;
13098
0
#endif
13099
#ifdef WOLFSSL_ECC_BLIND_K
13100
    mp_forcezero(key->kb);
13101
#endif
13102
13103
    /* read Qx */
13104
0
    if (err == MP_OKAY) {
13105
0
        if (encType == WC_TYPE_HEX_STR)
13106
0
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
13107
0
        else
13108
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
13109
0
                (word32)key->dp->size);
13110
13111
0
        if (mp_isneg(key->pubkey.x)) {
13112
0
            WOLFSSL_MSG("Invalid Qx");
13113
0
            err = BAD_FUNC_ARG;
13114
0
        }
13115
0
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
13116
0
            err = BAD_FUNC_ARG;
13117
0
        }
13118
0
    }
13119
13120
    /* read Qy */
13121
0
    if (err == MP_OKAY) {
13122
0
        if (encType == WC_TYPE_HEX_STR)
13123
0
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
13124
0
        else
13125
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
13126
0
                (word32)key->dp->size);
13127
13128
0
        if (mp_isneg(key->pubkey.y)) {
13129
0
            WOLFSSL_MSG("Invalid Qy");
13130
0
            err = BAD_FUNC_ARG;
13131
0
        }
13132
0
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
13133
0
            err = BAD_FUNC_ARG;
13134
0
        }
13135
0
    }
13136
13137
0
    if (err == MP_OKAY) {
13138
0
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
13139
0
            WOLFSSL_MSG("Invalid Qx and Qy");
13140
0
            err = ECC_INF_E;
13141
0
        }
13142
0
    }
13143
13144
0
    if (err == MP_OKAY)
13145
0
        err = mp_set(key->pubkey.z, 1);
13146
13147
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
13148
    defined(WOLFSSL_MICROCHIP_TA100)
13149
    /* For SECP256R1 only save raw public key for hardware */
13150
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
13151
        keySz = key->dp->size;
13152
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
13153
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
13154
        if (err == MP_OKAY)
13155
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
13156
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
13157
    }
13158
#elif defined(WOLFSSL_KCAPI_ECC)
13159
    if (err == MP_OKAY) {
13160
        word32 keySz = key->dp->size;
13161
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
13162
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
13163
        if (err == MP_OKAY) {
13164
            err = wc_export_int(key->pubkey.y,
13165
                &key->pubkey_raw[keySz], &keySz, keySz,
13166
                WC_TYPE_UNSIGNED_BIN);
13167
        }
13168
    }
13169
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
13170
    if (err == MP_OKAY) {
13171
        const word32 keySize = key->dp->size;
13172
        word32 bufSize = sizeof(key->keyRaw);
13173
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
13174
                            WC_TYPE_UNSIGNED_BIN);
13175
        if (err == MP_OKAY) {
13176
            const word32 offset = bufSize;
13177
            bufSize = sizeof(key->keyRaw) - offset;
13178
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
13179
                                keySize, WC_TYPE_UNSIGNED_BIN);
13180
        }
13181
        if (err == MP_OKAY) {
13182
            mp_reverse(key->keyRaw, keySize);
13183
            mp_reverse(&key->keyRaw[keySize], keySize);
13184
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
13185
                                           keySize * 2);
13186
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
13187
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
13188
                                              xil_curve_type[key->dp->id],
13189
                                              XIL_CAST_U64(key->keyRaw));
13190
            if (err) {
13191
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
13192
                err = WC_HW_E;
13193
            }
13194
#endif
13195
        }
13196
    }
13197
#endif
13198
13199
    /* import private key */
13200
0
    if (err == MP_OKAY) {
13201
0
        if (d != NULL) {
13202
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
13203
            defined(WOLFSSL_MICROCHIP_TA100)
13204
            /* Hardware doesn't support loading private key */
13205
            err = NOT_COMPILED_IN;
13206
13207
        #else
13208
0
            key->type = ECC_PRIVATEKEY;
13209
0
            if (encType == WC_TYPE_HEX_STR)
13210
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
13211
0
            else {
13212
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
13213
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
13214
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
13215
                    key->dp->size + WC_CAAM_MAC_SZ);
13216
                }
13217
                else
13218
            #endif /* WOLFSSL_QNX_CAAM */
13219
0
                {
13220
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
13221
0
                        (word32)key->dp->size);
13222
0
                }
13223
0
            }
13224
        #ifdef WOLFSSL_ECC_BLIND_K
13225
            if (err == 0) {
13226
                err = ecc_blind_k_rng(key, NULL);
13227
            }
13228
        #endif
13229
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
13230
            if (err == MP_OKAY) {
13231
                const word32 key_size = key->dp->size;
13232
                word32 buf_size = key_size;
13233
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
13234
                                    WC_TYPE_UNSIGNED_BIN);
13235
                mp_reverse(key->privKey, key_size);
13236
            }
13237
#endif
13238
13239
0
        #endif /* #else-case of custom HW-specific implementations */
13240
0
            if (err == MP_OKAY) {
13241
0
                if (mp_iszero(key->k) || mp_isneg(key->k)) {
13242
0
                    WOLFSSL_MSG("Invalid private key");
13243
0
                    err = BAD_FUNC_ARG;
13244
0
                }
13245
0
            }
13246
        #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
13247
            /* A black key holds an encrypted blob, not a scalar. */
13248
            if ((err == MP_OKAY) && (key->blackKey == 0))
13249
        #else
13250
0
            if (err == MP_OKAY)
13251
0
        #endif
13252
0
            {
13253
0
                err = ecc_check_privkey_range(key);
13254
0
            }
13255
0
        } else {
13256
0
            key->type = ECC_PUBLICKEY;
13257
0
        }
13258
0
    }
13259
13260
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
13261
    if (err == MP_OKAY) {
13262
        err = wc_ecc_check_key(key);
13263
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
13264
                                  mp_iszero(key->pubkey.y))) {
13265
            err = BAD_FUNC_ARG;
13266
        }
13267
    }
13268
#endif
13269
13270
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
13271
    if (err == MP_OKAY) {
13272
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
13273
    }
13274
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
13275
    if (err == MP_OKAY) {
13276
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
13277
    }
13278
#endif
13279
13280
0
    if (err != MP_OKAY) {
13281
0
        mp_clear(key->pubkey.x);
13282
0
        mp_clear(key->pubkey.y);
13283
0
        mp_clear(key->pubkey.z);
13284
0
        ecc_forcezero_k(key);
13285
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
13286
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
13287
#endif
13288
0
    }
13289
13290
0
    return err;
13291
0
}
13292
13293
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
13294
          const char* qy, const char* d, int curve_id, int encType)
13295
0
{
13296
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
13297
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
13298
    int setKeyType = WC_SETKEY_ECC_PRIV;
13299
    int err;
13300
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
13301
#endif
13302
13303
    /* if d is NULL, only import as public key using Qx,Qy */
13304
0
    if (key == NULL || qx == NULL || qy == NULL) {
13305
0
        return BAD_FUNC_ARG;
13306
0
    }
13307
13308
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
13309
    #ifndef WOLF_CRYPTO_CB_FIND
13310
    if (key->devId != INVALID_DEVID)
13311
    #endif
13312
    {
13313
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
13314
        if (!WC_VAR_OK(tmpKey)) {
13315
            return MEMORY_E;
13316
        }
13317
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
13318
13319
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
13320
        if (err != 0) {
13321
            WC_FREE_VAR(tmpKey, key->heap);
13322
            return err;
13323
        }
13324
13325
    #ifdef WOLFSSL_CUSTOM_CURVES
13326
        if (key->dp != NULL) {
13327
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
13328
            if (err != 0) {
13329
                wc_ecc_free(tmpKey);
13330
                WC_FREE_VAR(tmpKey, key->heap);
13331
                return err;
13332
            }
13333
        }
13334
    #endif
13335
13336
        /* Import into temp via software helper (no callback recursion) */
13337
        err = _ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType);
13338
        if (err == MP_OKAY) {
13339
            if (d == NULL) {
13340
                setKeyType = WC_SETKEY_ECC_PUB;
13341
            }
13342
            cbRet = wc_CryptoCb_SetKey(key->devId,
13343
                setKeyType, key, tmpKey,
13344
                wc_ecc_size(tmpKey), NULL, 0, 0);
13345
        }
13346
13347
        /* wc_ecc_free calls mp_forcezero on private key components,
13348
         * so no separate ForceZero of the struct is needed here. */
13349
        wc_ecc_free(tmpKey);
13350
        WC_FREE_VAR(tmpKey, key->heap);
13351
13352
        if (err != MP_OKAY) {
13353
            return err;
13354
        }
13355
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
13356
            return cbRet;
13357
        }
13358
    }
13359
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
13360
13361
0
    return _ecc_import_raw_private(key, qx, qy, d, curve_id, encType);
13362
0
}
13363
13364
/**
13365
   Import raw ECC key
13366
   key       The destination ecc_key structure
13367
   qx        x component of the public key, as ASCII hex string
13368
   qy        y component of the public key, as ASCII hex string
13369
   d         private key, as ASCII hex string, optional if importing public
13370
             key only
13371
   curve_id  The id of the curve.
13372
   @return    MP_OKAY on success
13373
*/
13374
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
13375
                   const char* d, int curve_id)
13376
0
{
13377
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
13378
0
        WC_TYPE_HEX_STR);
13379
0
}
13380
13381
/* Import x, y and optional private (d) as unsigned binary */
13382
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
13383
                   const byte* d, int curve_id)
13384
0
{
13385
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
13386
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
13387
0
}
13388
13389
/**
13390
   Import raw ECC key
13391
   key       The destination ecc_key structure
13392
   qx        x component of the public key, as ASCII hex string
13393
   qy        y component of the public key, as ASCII hex string
13394
   d         private key, as ASCII hex string, optional if importing public
13395
             key only
13396
   curveName ECC curve name, from ecc_sets[]
13397
   return    MP_OKAY on success
13398
*/
13399
WOLFSSL_ABI
13400
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
13401
                   const char* d, const char* curveName)
13402
0
{
13403
0
    int err, x;
13404
13405
    /* if d is NULL, only import as public key using Qx,Qy */
13406
0
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
13407
0
        return BAD_FUNC_ARG;
13408
0
    }
13409
13410
    /* set curve type and index */
13411
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
13412
0
        if (XSTRNCMP(ecc_sets[x].name, curveName,
13413
0
                     XSTRLEN(curveName)) == 0) {
13414
0
            break;
13415
0
        }
13416
0
    }
13417
13418
0
    if (ecc_sets[x].size == 0) {
13419
0
        WOLFSSL_MSG("ecc_set curve name not found");
13420
0
        err = ASN_PARSE_E;
13421
0
    } else {
13422
0
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
13423
0
            WC_TYPE_HEX_STR);
13424
0
    }
13425
13426
0
    return err;
13427
0
}
13428
#endif /* HAVE_ECC_KEY_IMPORT */
13429
13430
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
13431
/* public key size in octets */
13432
static int ecc_public_key_size(ecc_key* key, word32* sz)
13433
{
13434
    if (key == NULL || key->dp == NULL)
13435
        return BAD_FUNC_ARG;
13436
13437
    /* 'Uncompressed' | x | y */
13438
    *sz = 1 + 2 * (word32)key->dp->size;
13439
13440
    return 0;
13441
}
13442
#endif
13443
13444
/* key size in octets */
13445
WOLFSSL_ABI
13446
int wc_ecc_size(ecc_key* key)
13447
0
{
13448
0
    if (key == NULL) {
13449
0
        return 0;
13450
0
    }
13451
13452
#if defined(WOLF_CRYPTO_CB) && \
13453
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
13454
    if (key->devId != INVALID_DEVID) {
13455
        int ret;
13456
        int keySz = 0;
13457
13458
        ret = wc_CryptoCb_EccGetSize(key, &keySz);
13459
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
13460
            if (ret != 0) {
13461
                return 0;
13462
            }
13463
            return keySz;
13464
        }
13465
    }
13466
#endif
13467
13468
0
    if (key->dp == NULL) {
13469
0
        return 0;
13470
0
    }
13471
13472
0
    return key->dp->size;
13473
0
}
13474
13475
/* maximum signature size based on key size */
13476
WOLFSSL_ABI
13477
int wc_ecc_sig_size_calc(int sz)
13478
0
{
13479
0
    int maxSigSz = 0;
13480
13481
    /* calculate based on key bits */
13482
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
13483
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
13484
13485
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
13486
0
    if (maxSigSz < (128 + 2)) {
13487
0
        maxSigSz -= 1;
13488
0
    }
13489
13490
0
    return maxSigSz;
13491
0
}
13492
13493
/* maximum signature size based on actual key curve */
13494
WOLFSSL_ABI
13495
int wc_ecc_sig_size(const ecc_key* key)
13496
0
{
13497
0
    int maxSigSz;
13498
0
    int orderBits, keySz;
13499
13500
0
    if (key == NULL) {
13501
0
        return 0;
13502
0
    }
13503
13504
#if defined(WOLF_CRYPTO_CB) && \
13505
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
13506
    if (key->devId != INVALID_DEVID) {
13507
        int ret;
13508
        int cbKeySz = 0;
13509
13510
        ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
13511
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
13512
            if (ret != 0 || cbKeySz == 0) {
13513
                return 0;
13514
            }
13515
            return cbKeySz;
13516
        }
13517
    }
13518
#endif
13519
13520
0
    if (key->dp == NULL) {
13521
0
        return 0;
13522
0
    }
13523
13524
    /* the signature r and s will always be less than order */
13525
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
13526
        extra byte for r and s, so add 2 */
13527
0
    keySz = key->dp->size;
13528
0
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
13529
0
    if (orderBits > keySz * 8) {
13530
0
        keySz = (orderBits + 7) >> 3;
13531
0
    }
13532
    /* maximum possible signature header size is 7 bytes */
13533
0
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
13534
0
    if ((orderBits % 8) == 0) {
13535
        /* MSB can be set, so add 2 */
13536
0
        maxSigSz += ECC_MAX_PAD_SZ;
13537
0
    }
13538
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
13539
0
    if (maxSigSz < (128 + 2)) {
13540
0
        maxSigSz -= 1;
13541
0
    }
13542
13543
0
    return maxSigSz;
13544
0
}
13545
13546
13547
#ifdef FP_ECC
13548
13549
/* fixed point ECC cache */
13550
/* number of entries in the cache */
13551
#ifndef FP_ENTRIES
13552
    #define FP_ENTRIES 15
13553
#endif
13554
13555
/* number of bits in LUT */
13556
#ifndef FP_LUT
13557
    #define FP_LUT     8U
13558
#endif
13559
13560
#ifdef ECC_SHAMIR
13561
    /* Sharmir requires a bigger LUT, TAO */
13562
    #if (FP_LUT > 12) || (FP_LUT < 4)
13563
        #error FP_LUT must be between 4 and 12 inclusively
13564
    #endif
13565
#else
13566
    #if (FP_LUT > 12) || (FP_LUT < 2)
13567
        #error FP_LUT must be between 2 and 12 inclusively
13568
    #endif
13569
#endif
13570
13571
13572
#if !defined(WOLFSSL_SP_MATH)
13573
13574
/** Our FP cache */
13575
typedef struct {
13576
   ecc_point* g;               /* cached COPY of base point */
13577
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
13578
   int        LUT_set;         /* flag to determine if the LUT has been computed */
13579
   mp_int     mu;              /* copy of the montgomery constant */
13580
   int        lru_count;       /* amount of times this entry has been used */
13581
   int        lock;            /* flag to indicate cache eviction */
13582
                               /* permitted (0) or not (1) */
13583
} fp_cache_t;
13584
13585
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
13586
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
13587
13588
#ifndef HAVE_THREAD_LS
13589
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
13590
#ifndef WOLFSSL_MUTEX_INITIALIZER
13591
    /* Elects a single initializer for ecc_fp_lock. */
13592
    static wc_MutexOnceFlag initMutex = WOLFSSL_ATOMIC_INITIALIZER(0);
13593
#endif
13594
#endif /* HAVE_THREAD_LS */
13595
13596
/* simple table to help direct the generation of the LUT */
13597
static const struct {
13598
   int ham, terma, termb;
13599
} lut_orders[] = {
13600
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
13601
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
13602
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
13603
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
13604
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
13605
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
13606
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
13607
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
13608
#if FP_LUT > 6
13609
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
13610
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
13611
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
13612
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
13613
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
13614
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
13615
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
13616
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
13617
#if FP_LUT > 7
13618
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
13619
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
13620
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
13621
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
13622
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
13623
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
13624
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
13625
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
13626
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
13627
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
13628
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
13629
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
13630
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
13631
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
13632
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
13633
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
13634
#if FP_LUT > 8
13635
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
13636
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
13637
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
13638
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
13639
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
13640
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
13641
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
13642
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
13643
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
13644
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
13645
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
13646
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
13647
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
13648
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
13649
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
13650
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
13651
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
13652
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
13653
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
13654
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
13655
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
13656
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
13657
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
13658
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
13659
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
13660
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
13661
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
13662
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
13663
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
13664
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
13665
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
13666
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
13667
#if FP_LUT > 9
13668
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
13669
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
13670
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
13671
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
13672
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
13673
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
13674
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
13675
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
13676
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
13677
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
13678
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
13679
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
13680
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
13681
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
13682
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
13683
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
13684
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
13685
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
13686
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
13687
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
13688
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
13689
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
13690
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
13691
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
13692
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
13693
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
13694
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
13695
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
13696
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
13697
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
13698
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
13699
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
13700
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
13701
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
13702
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
13703
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
13704
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
13705
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
13706
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
13707
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
13708
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
13709
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
13710
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
13711
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
13712
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
13713
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
13714
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
13715
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
13716
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
13717
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
13718
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
13719
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
13720
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
13721
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
13722
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
13723
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
13724
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
13725
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
13726
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
13727
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
13728
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
13729
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
13730
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
13731
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
13732
#if FP_LUT > 10
13733
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
13734
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
13735
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
13736
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
13737
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
13738
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
13739
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
13740
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
13741
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
13742
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
13743
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
13744
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
13745
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
13746
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
13747
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
13748
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
13749
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
13750
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
13751
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
13752
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
13753
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
13754
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
13755
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
13756
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
13757
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
13758
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
13759
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
13760
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
13761
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
13762
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
13763
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
13764
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
13765
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
13766
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
13767
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
13768
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
13769
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
13770
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
13771
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
13772
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
13773
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
13774
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
13775
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
13776
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
13777
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
13778
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
13779
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
13780
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
13781
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
13782
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
13783
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
13784
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
13785
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
13786
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
13787
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
13788
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
13789
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
13790
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
13791
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
13792
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
13793
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
13794
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
13795
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
13796
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
13797
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
13798
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
13799
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
13800
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
13801
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
13802
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
13803
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
13804
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
13805
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
13806
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
13807
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
13808
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
13809
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
13810
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
13811
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
13812
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
13813
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
13814
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
13815
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
13816
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
13817
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
13818
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
13819
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
13820
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
13821
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
13822
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
13823
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
13824
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
13825
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
13826
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
13827
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
13828
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
13829
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
13830
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
13831
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
13832
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
13833
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
13834
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
13835
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
13836
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
13837
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
13838
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
13839
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
13840
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
13841
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
13842
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
13843
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
13844
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
13845
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
13846
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
13847
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
13848
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
13849
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
13850
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
13851
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
13852
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
13853
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
13854
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
13855
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
13856
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
13857
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
13858
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
13859
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
13860
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
13861
#if FP_LUT > 11
13862
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
13863
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
13864
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
13865
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
13866
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
13867
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
13868
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
13869
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
13870
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
13871
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
13872
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
13873
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
13874
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
13875
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
13876
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
13877
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
13878
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
13879
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
13880
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
13881
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
13882
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
13883
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
13884
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
13885
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
13886
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
13887
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
13888
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
13889
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
13890
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
13891
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
13892
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
13893
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
13894
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
13895
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
13896
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
13897
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
13898
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
13899
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
13900
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
13901
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
13902
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
13903
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
13904
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
13905
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
13906
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
13907
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
13908
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
13909
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
13910
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
13911
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
13912
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
13913
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
13914
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
13915
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
13916
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
13917
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
13918
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
13919
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
13920
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
13921
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
13922
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
13923
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
13924
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
13925
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
13926
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
13927
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
13928
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
13929
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
13930
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
13931
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
13932
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
13933
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
13934
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
13935
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
13936
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
13937
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
13938
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
13939
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
13940
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
13941
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
13942
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
13943
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
13944
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
13945
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
13946
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
13947
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
13948
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
13949
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
13950
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
13951
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
13952
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
13953
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
13954
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
13955
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
13956
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
13957
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
13958
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
13959
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
13960
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
13961
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
13962
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
13963
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
13964
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
13965
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
13966
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
13967
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
13968
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
13969
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
13970
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
13971
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
13972
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
13973
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
13974
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
13975
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
13976
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
13977
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
13978
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
13979
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
13980
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
13981
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
13982
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
13983
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
13984
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
13985
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
13986
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
13987
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
13988
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
13989
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
13990
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
13991
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
13992
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
13993
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
13994
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
13995
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
13996
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
13997
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
13998
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
13999
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
14000
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
14001
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
14002
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
14003
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
14004
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
14005
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
14006
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
14007
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
14008
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
14009
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
14010
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
14011
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
14012
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
14013
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
14014
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
14015
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
14016
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
14017
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
14018
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
14019
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
14020
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
14021
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
14022
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
14023
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
14024
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
14025
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
14026
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
14027
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
14028
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
14029
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
14030
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
14031
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
14032
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
14033
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
14034
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
14035
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
14036
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
14037
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
14038
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
14039
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
14040
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
14041
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
14042
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
14043
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
14044
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
14045
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
14046
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
14047
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
14048
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
14049
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
14050
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
14051
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
14052
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
14053
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
14054
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
14055
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
14056
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
14057
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
14058
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
14059
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
14060
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
14061
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
14062
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
14063
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
14064
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
14065
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
14066
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
14067
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
14068
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
14069
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
14070
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
14071
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
14072
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
14073
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
14074
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
14075
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
14076
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
14077
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
14078
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
14079
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
14080
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
14081
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
14082
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
14083
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
14084
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
14085
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
14086
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
14087
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
14088
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
14089
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
14090
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
14091
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
14092
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
14093
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
14094
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
14095
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
14096
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
14097
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
14098
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
14099
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
14100
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
14101
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
14102
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
14103
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
14104
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
14105
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
14106
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
14107
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
14108
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
14109
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
14110
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
14111
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
14112
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
14113
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
14114
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
14115
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
14116
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
14117
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
14118
#endif
14119
#endif
14120
#endif
14121
#endif
14122
#endif
14123
#endif
14124
};
14125
14126
14127
/* find a hole and free as required, return -1 if no hole found */
14128
static int find_hole(void)
14129
{
14130
#ifdef WOLFSSL_NO_MALLOC
14131
   return -1;
14132
#else
14133
   int      x, y, z;
14134
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
14135
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
14136
          z = x;
14137
          y = fp_cache[x].lru_count;
14138
       }
14139
   }
14140
14141
   /* decrease all */
14142
   for (x = 0; x < FP_ENTRIES; x++) {
14143
      if (fp_cache[x].lru_count > 3) {
14144
         --(fp_cache[x].lru_count);
14145
      }
14146
   }
14147
14148
   /* free entry z */
14149
   if (z >= 0 && fp_cache[z].g) {
14150
      mp_clear(&fp_cache[z].mu);
14151
      wc_ecc_del_point(fp_cache[z].g);
14152
      fp_cache[z].g  = NULL;
14153
      for (x = 0; x < (1<<FP_LUT); x++) {
14154
         wc_ecc_del_point(fp_cache[z].LUT[x]);
14155
         fp_cache[z].LUT[x] = NULL;
14156
      }
14157
      fp_cache[z].LUT_set = 0;
14158
      fp_cache[z].lru_count = 0;
14159
   }
14160
   return z;
14161
#endif /* !WOLFSSL_NO_MALLOC */
14162
}
14163
14164
/* determine if a base is already in the cache and if so, where */
14165
static int find_base(ecc_point* g)
14166
{
14167
   int x;
14168
   for (x = 0; x < FP_ENTRIES; x++) {
14169
      if (fp_cache[x].g != NULL &&
14170
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
14171
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
14172
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
14173
         break;
14174
      }
14175
   }
14176
   if (x == FP_ENTRIES) {
14177
      x = -1;
14178
   }
14179
   return x;
14180
}
14181
14182
/* add a new base to the cache */
14183
static int add_entry(int idx, ecc_point *g)
14184
{
14185
   unsigned x, y;
14186
14187
   /* allocate base and LUT */
14188
   fp_cache[idx].g = wc_ecc_new_point();
14189
   if (fp_cache[idx].g == NULL) {
14190
      return MP_MEM;
14191
   }
14192
14193
   /* copy x and y */
14194
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
14195
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
14196
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
14197
      wc_ecc_del_point(fp_cache[idx].g);
14198
      fp_cache[idx].g = NULL;
14199
      return MP_MEM;
14200
   }
14201
14202
   for (x = 0; x < (1U<<FP_LUT); x++) {
14203
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
14204
      if (fp_cache[idx].LUT[x] == NULL) {
14205
         for (y = 0; y < x; y++) {
14206
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
14207
            fp_cache[idx].LUT[y] = NULL;
14208
         }
14209
         wc_ecc_del_point(fp_cache[idx].g);
14210
         fp_cache[idx].g         = NULL;
14211
         fp_cache[idx].lru_count = 0;
14212
         return MP_MEM;
14213
      }
14214
   }
14215
14216
   fp_cache[idx].LUT_set   = 0;
14217
   fp_cache[idx].lru_count = 0;
14218
14219
   return MP_OKAY;
14220
}
14221
#endif
14222
14223
#if !defined(WOLFSSL_SP_MATH)
14224
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
14225
 *
14226
 * The algorithm builds patterns in increasing bit order by first making all
14227
 * single bit input patterns, then all two bit input patterns and so on
14228
 */
14229
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
14230
    mp_int* mu)
14231
{
14232
   int err;
14233
   unsigned x, y, bitlen, lut_gap;
14234
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
14235
   int infinity;
14236
14237
#ifdef WOLFSSL_SMALL_STACK
14238
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14239
       return MEMORY_E;
14240
#endif
14241
14242
   err = mp_init(tmp);
14243
   if (err != MP_OKAY) {
14244
       err = MP_MEM;
14245
       goto errout;
14246
   }
14247
14248
   /* sanity check to make sure lut_order table is of correct size,
14249
      should compile out to a NOP if true */
14250
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
14251
       err = BAD_FUNC_ARG;
14252
       goto errout;
14253
   }
14254
14255
   /* get bitlen and round up to next multiple of FP_LUT */
14256
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
14257
   x       = bitlen % FP_LUT;
14258
   if (x) {
14259
       bitlen += FP_LUT - x;
14260
   }
14261
   lut_gap = bitlen / FP_LUT;
14262
14263
   /* init the mu */
14264
   err = mp_init_copy(&fp_cache[idx].mu, mu);
14265
   if (err != MP_OKAY)
14266
       goto errout;
14267
14268
   /* copy base */
14269
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
14270
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
14271
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
14272
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
14273
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
14274
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
14275
       err = MP_MULMOD_E;
14276
       goto errout;
14277
   }
14278
14279
   /* make all single bit entries */
14280
   for (x = 1; x < FP_LUT; x++) {
14281
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
14282
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
14283
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
14284
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
14285
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
14286
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
14287
          err = MP_INIT_E;
14288
          goto errout;
14289
      } else {
14290
14291
         /* now double it bitlen/FP_LUT times */
14292
         for (y = 0; y < lut_gap; y++) {
14293
             if ((err = ecc_projective_dbl_point_safe(
14294
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
14295
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
14296
                                      a, modulus, mp)) != MP_OKAY) {
14297
                 goto errout;
14298
             }
14299
         }
14300
     }
14301
  }
14302
14303
   /* now make all entries in increase order of hamming weight */
14304
   for (x = 2; x <= FP_LUT; x++) {
14305
       if (err != MP_OKAY)
14306
           goto errout;
14307
       for (y = 0; y < (1UL<<FP_LUT); y++) {
14308
           if (lut_orders[y].ham != (int)x) continue;
14309
14310
           /* perform the add */
14311
           if ((err = ecc_projective_add_point_safe(
14312
                           fp_cache[idx].LUT[lut_orders[y].terma],
14313
                           fp_cache[idx].LUT[lut_orders[y].termb],
14314
                           fp_cache[idx].LUT[y], a, modulus, mp,
14315
                           &infinity)) != MP_OKAY) {
14316
               goto errout;
14317
           }
14318
       }
14319
   }
14320
14321
   /* now map all entries back to affine space to make point addition faster */
14322
   for (x = 1; x < (1UL<<FP_LUT); x++) {
14323
       if (err != MP_OKAY)
14324
           break;
14325
14326
       /* convert z to normal from montgomery */
14327
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
14328
14329
       /* invert it */
14330
       if (err == MP_OKAY)
14331
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
14332
                         fp_cache[idx].LUT[x]->z);
14333
14334
       if (err == MP_OKAY)
14335
         /* now square it */
14336
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
14337
14338
       if (err == MP_OKAY)
14339
         /* fix x */
14340
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
14341
                         fp_cache[idx].LUT[x]->x);
14342
14343
       if (err == MP_OKAY)
14344
         /* get 1/z^3 */
14345
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
14346
14347
       if (err == MP_OKAY)
14348
         /* fix y */
14349
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
14350
                         fp_cache[idx].LUT[x]->y);
14351
14352
       if (err == MP_OKAY)
14353
         /* free z */
14354
         mp_clear(fp_cache[idx].LUT[x]->z);
14355
   }
14356
14357
  errout:
14358
14359
   mp_clear(tmp);
14360
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14361
14362
   if (err == MP_OKAY) {
14363
       fp_cache[idx].LUT_set = 1;
14364
       return MP_OKAY;
14365
   }
14366
14367
   /* err cleanup */
14368
   for (y = 0; y < (1U<<FP_LUT); y++) {
14369
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
14370
      fp_cache[idx].LUT[y] = NULL;
14371
   }
14372
   wc_ecc_del_point(fp_cache[idx].g);
14373
   fp_cache[idx].g         = NULL;
14374
   fp_cache[idx].LUT_set   = 0;
14375
   fp_cache[idx].lru_count = 0;
14376
   mp_clear(&fp_cache[idx].mu);
14377
14378
   return err;
14379
}
14380
14381
/* perform a fixed point ECC mulmod */
14382
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
14383
                        mp_int* modulus, mp_digit mp, int map)
14384
{
14385
#ifdef WOLFCRYPT_HAVE_SAKKE
14386
    #define KB_SIZE 256
14387
#else
14388
    #define KB_SIZE 128
14389
#endif
14390
14391
#ifdef WOLFSSL_SMALL_STACK
14392
   unsigned char* kb = NULL;
14393
   mp_int*        tk = NULL;
14394
   mp_int*        order = NULL;
14395
#else
14396
   unsigned char kb[KB_SIZE];
14397
   mp_int        tk[1];
14398
   mp_int        order[1];
14399
#endif
14400
   int      x, err;
14401
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
14402
   int first;
14403
   int tk_zeroize = 0;
14404
14405
#ifdef WOLFSSL_SMALL_STACK
14406
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14407
   if (tk == NULL) {
14408
      err = MEMORY_E; goto done;
14409
   }
14410
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14411
   if (order == NULL) {
14412
      err = MEMORY_E; goto done;
14413
   }
14414
#endif
14415
14416
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
14417
       err = MP_INIT_E; goto done;
14418
   }
14419
14420
   if ((err = mp_copy(k, tk)) != MP_OKAY)
14421
       goto done;
14422
   tk_zeroize = 1;
14423
14424
#ifdef WOLFSSL_CHECK_MEM_ZERO
14425
   mp_memzero_add("accel_fp_mul tk", tk);
14426
#endif
14427
14428
   /* if it's smaller than modulus we fine */
14429
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
14430
      /* find order */
14431
       y = (unsigned)mp_unsigned_bin_size(modulus);
14432
      for (x = 0; ecc_sets[x].size; x++) {
14433
         if (y <= (unsigned)ecc_sets[x].size) break;
14434
      }
14435
14436
      /* back off if we are on the 521 bit curve */
14437
      if (y == 66) --x;
14438
14439
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14440
                                                MP_RADIX_HEX)) != MP_OKAY) {
14441
         goto done;
14442
      }
14443
14444
      /* k must be less than modulus */
14445
      if (mp_cmp(tk, order) != MP_LT) {
14446
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
14447
            goto done;
14448
         }
14449
      }
14450
   }
14451
14452
   /* get bitlen and round up to next multiple of FP_LUT */
14453
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
14454
   x       = bitlen % FP_LUT;
14455
   if (x) {
14456
      bitlen += FP_LUT - (unsigned)x;
14457
   }
14458
   lut_gap = bitlen / FP_LUT;
14459
14460
   /* get the k value */
14461
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
14462
      err = BUFFER_E; goto done;
14463
   }
14464
14465
   /* store k */
14466
#ifdef WOLFSSL_SMALL_STACK
14467
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14468
   if (kb == NULL) {
14469
      err = MEMORY_E; goto done;
14470
   }
14471
#endif
14472
14473
   XMEMSET(kb, 0, KB_SIZE);
14474
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
14475
   #ifdef WOLFSSL_CHECK_MEM_ZERO
14476
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
14477
   #endif
14478
      /* let's reverse kb so it's little endian */
14479
      x = 0;
14480
      y = (unsigned)mp_unsigned_bin_size(tk);
14481
      if (y > 0) {
14482
          y -= 1;
14483
      }
14484
14485
      while ((unsigned)x < y) {
14486
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
14487
         ++x; --y;
14488
      }
14489
14490
      /* at this point we can start, yipee */
14491
      first = 1;
14492
      for (x = (int)lut_gap-1; x >= 0; x--) {
14493
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
14494
             by x bits from the start */
14495
          bitpos = (unsigned)x;
14496
          for (y = z = 0; y < FP_LUT; y++) {
14497
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14498
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
14499
                                    the mult in each loop */
14500
          }
14501
14502
          /* double if not first */
14503
          if (!first) {
14504
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14505
                                                              mp)) != MP_OKAY) {
14506
                break;
14507
             }
14508
          }
14509
14510
          /* add if not first, otherwise copy */
14511
          if (!first && z) {
14512
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
14513
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
14514
                break;
14515
             }
14516
          } else if (z) {
14517
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
14518
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
14519
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
14520
                 err = MP_MEM;
14521
                 break;
14522
             }
14523
             first = 0;
14524
          }
14525
      }
14526
14527
      /* k reduced to 0 mod order, or the last add gave infinity */
14528
      if ((err == MP_OKAY) && (first == 1)) {
14529
         err = ecc_set_point_infinity(R);
14530
      }
14531
   }
14532
14533
   if (err == MP_OKAY) {
14534
      (void) z; /* Acknowledge the unused assignment */
14535
      ForceZero(kb, KB_SIZE);
14536
14537
      /* map R back from projective space */
14538
      if (map) {
14539
         err = ecc_map(R, modulus, mp);
14540
      } else {
14541
         err = MP_OKAY;
14542
      }
14543
   }
14544
14545
done:
14546
   /* cleanup */
14547
   mp_clear(order);
14548
   /* Ensure it was initialized. */
14549
   if (tk_zeroize) {
14550
       mp_forcezero(tk);
14551
   }
14552
14553
#ifdef WOLFSSL_SMALL_STACK
14554
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14555
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14556
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14557
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14558
   wc_MemZero_Check(kb, KB_SIZE);
14559
   mp_memzero_check(tk);
14560
#endif
14561
14562
#undef KB_SIZE
14563
14564
   return err;
14565
}
14566
#endif
14567
14568
#ifdef ECC_SHAMIR
14569
#if !defined(WOLFSSL_SP_MATH)
14570
/* perform a fixed point ECC mulmod */
14571
static int accel_fp_mul2add(int idx1, int idx2,
14572
                            mp_int* kA, mp_int* kB,
14573
                            ecc_point *R, mp_int* a,
14574
                            mp_int* modulus, mp_digit mp)
14575
{
14576
#define KB_SIZE 128
14577
14578
#ifdef WOLFSSL_SMALL_STACK
14579
   unsigned char* kb[2] = {NULL, NULL};
14580
   mp_int*        tka = NULL;
14581
   mp_int*        tkb = NULL;
14582
   mp_int*        order = NULL;
14583
#else
14584
   unsigned char kb[2][KB_SIZE];
14585
   mp_int        tka[1];
14586
   mp_int        tkb[1];
14587
   mp_int        order[1];
14588
#endif
14589
   int      x, err;
14590
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
14591
   int first;
14592
14593
#ifdef WOLFSSL_SMALL_STACK
14594
   /* each is zeroed on acquisition so the cleanup below no-ops if a later
14595
    * allocation fails and the init is skipped */
14596
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14597
   if (tka == NULL) {
14598
      err = MEMORY_E; goto done;
14599
   }
14600
   XMEMSET(tka, 0, sizeof(mp_int));
14601
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14602
   if (tkb == NULL) {
14603
      err = MEMORY_E; goto done;
14604
   }
14605
   XMEMSET(tkb, 0, sizeof(mp_int));
14606
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14607
   if (order == NULL) {
14608
      err = MEMORY_E; goto done;
14609
   }
14610
   XMEMSET(order, 0, sizeof(mp_int));
14611
#endif
14612
14613
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
14614
      err = MP_INIT_E; goto done;
14615
   }
14616
14617
   /* if it's smaller than modulus we fine */
14618
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
14619
      /* find order */
14620
      y = (unsigned)mp_unsigned_bin_size(modulus);
14621
      for (x = 0; ecc_sets[x].size; x++) {
14622
         if (y <= (unsigned)ecc_sets[x].size) break;
14623
      }
14624
14625
      /* back off if we are on the 521 bit curve */
14626
      if (y == 66) --x;
14627
14628
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14629
                                                MP_RADIX_HEX)) != MP_OKAY) {
14630
         goto done;
14631
      }
14632
14633
      /* kA must be less than modulus */
14634
      if (mp_cmp(kA, order) != MP_LT) {
14635
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
14636
            goto done;
14637
         }
14638
      } else {
14639
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14640
            goto done;
14641
         }
14642
      }
14643
   } else {
14644
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14645
         goto done;
14646
      }
14647
   }
14648
#ifdef WOLFSSL_CHECK_MEM_ZERO
14649
   mp_memzero_add("accel_fp_mul2add tka", tka);
14650
#endif
14651
14652
   /* if it's smaller than modulus we fine */
14653
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
14654
      /* find order */
14655
      y = (unsigned)mp_unsigned_bin_size(modulus);
14656
      for (x = 0; ecc_sets[x].size; x++) {
14657
         if (y <= (unsigned)ecc_sets[x].size) break;
14658
      }
14659
14660
      /* back off if we are on the 521 bit curve */
14661
      if (y == 66) --x;
14662
14663
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14664
                                                MP_RADIX_HEX)) != MP_OKAY) {
14665
         goto done;
14666
      }
14667
14668
      /* kB must be less than modulus */
14669
      if (mp_cmp(kB, order) != MP_LT) {
14670
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
14671
            goto done;
14672
         }
14673
      } else {
14674
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14675
            goto done;
14676
         }
14677
      }
14678
   } else {
14679
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14680
         goto done;
14681
      }
14682
   }
14683
#ifdef WOLFSSL_CHECK_MEM_ZERO
14684
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
14685
#endif
14686
14687
   /* get bitlen and round up to next multiple of FP_LUT */
14688
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
14689
   x       = bitlen % FP_LUT;
14690
   if (x) {
14691
      bitlen += FP_LUT - (unsigned)x;
14692
   }
14693
   lut_gap = bitlen / FP_LUT;
14694
14695
   /* get the k value */
14696
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
14697
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
14698
      err = BUFFER_E; goto done;
14699
   }
14700
14701
   /* store k */
14702
#ifdef WOLFSSL_SMALL_STACK
14703
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14704
   if (kb[0] == NULL) {
14705
      err = MEMORY_E; goto done;
14706
   }
14707
#endif
14708
14709
   XMEMSET(kb[0], 0, KB_SIZE);
14710
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
14711
      goto done;
14712
   }
14713
#ifdef WOLFSSL_CHECK_MEM_ZERO
14714
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
14715
#endif
14716
14717
   /* let's reverse kb so it's little endian */
14718
   x = 0;
14719
   y = (unsigned)mp_unsigned_bin_size(tka);
14720
   if (y > 0) {
14721
       y -= 1;
14722
   }
14723
   mp_clear(tka);
14724
   while ((unsigned)x < y) {
14725
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
14726
      ++x; --y;
14727
   }
14728
14729
   /* store b */
14730
#ifdef WOLFSSL_SMALL_STACK
14731
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14732
   if (kb[1] == NULL) {
14733
      err = MEMORY_E; goto done;
14734
   }
14735
#endif
14736
14737
   XMEMSET(kb[1], 0, KB_SIZE);
14738
#ifdef WOLFSSL_CHECK_MEM_ZERO
14739
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
14740
#endif
14741
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
14742
      x = 0;
14743
      y = (unsigned)mp_unsigned_bin_size(tkb);
14744
      if (y > 0) {
14745
          y -= 1;
14746
      }
14747
14748
      while ((unsigned)x < y) {
14749
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
14750
         ++x; --y;
14751
      }
14752
14753
      /* at this point we can start, yipee */
14754
      first = 1;
14755
      for (x = (int)lut_gap-1; x >= 0; x--) {
14756
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
14757
             offset by x bits from the start */
14758
          bitpos = (unsigned)x;
14759
          for (y = zA = zB = 0; y < FP_LUT; y++) {
14760
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14761
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14762
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
14763
                                      the mult in each loop */
14764
          }
14765
14766
          /* double if not first */
14767
          if (!first) {
14768
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14769
                                                              mp)) != MP_OKAY) {
14770
                break;
14771
             }
14772
14773
             /* add if not first, otherwise copy */
14774
             if (zA) {
14775
                if ((err = ecc_projective_add_point_safe(R,
14776
                                             fp_cache[idx1].LUT[zA], R, a,
14777
                                             modulus, mp, &first)) != MP_OKAY) {
14778
                   break;
14779
                }
14780
             }
14781
14782
             if (zB && first == 0) {
14783
                if ((err = ecc_projective_add_point_safe(R,
14784
                                             fp_cache[idx2].LUT[zB], R, a,
14785
                                             modulus, mp, &first)) != MP_OKAY) {
14786
                   break;
14787
                }
14788
             }
14789
             else if (zB) {
14790
                if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
14791
                    (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
14792
                    (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
14793
                    err = MP_MEM;
14794
                    break;
14795
                }
14796
                first = 0;
14797
             }
14798
          } else {
14799
             if (zA) {
14800
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
14801
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
14802
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
14803
                     err = MP_MEM;
14804
                     break;
14805
                 }
14806
                    first = 0;
14807
             }
14808
             if (zB && first == 0) {
14809
                if ((err = ecc_projective_add_point_safe(R,
14810
                                        fp_cache[idx2].LUT[zB], R, a,
14811
                                        modulus, mp, &first)) != MP_OKAY){
14812
                   break;
14813
                }
14814
             } else if (zB && first == 1) {
14815
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
14816
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
14817
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
14818
                     err = MP_MEM;
14819
                     break;
14820
                 }
14821
                    first = 0;
14822
             }
14823
          }
14824
      }
14825
14826
      /* kA and kB both reduced to 0 mod order, or the last add gave infinity */
14827
      if ((err == MP_OKAY) && (first == 1)) {
14828
         err = ecc_set_point_infinity(R);
14829
      }
14830
   }
14831
14832
done:
14833
   /* cleanup */
14834
   mp_forcezero(tkb);
14835
   mp_forcezero(tka);
14836
   mp_clear(order);
14837
14838
#ifdef WOLFSSL_SMALL_STACK
14839
   if (kb[0])
14840
#endif
14841
      ForceZero(kb[0], KB_SIZE);
14842
#ifdef WOLFSSL_SMALL_STACK
14843
   if (kb[1])
14844
#endif
14845
      ForceZero(kb[1], KB_SIZE);
14846
14847
#ifdef WOLFSSL_SMALL_STACK
14848
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14849
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14850
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14851
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14852
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14853
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14854
   wc_MemZero_Check(kb[1], KB_SIZE);
14855
   wc_MemZero_Check(kb[0], KB_SIZE);
14856
   mp_memzero_check(tkb);
14857
   mp_memzero_check(tka);
14858
#endif
14859
14860
#undef KB_SIZE
14861
14862
    if (err != MP_OKAY)
14863
        return err;
14864
14865
   return ecc_map(R, modulus, mp);
14866
}
14867
14868
14869
/** ECC Fixed Point mulmod global with heap hint used
14870
  Computes kA*A + kB*B = C using Shamir's Trick
14871
  A        First point to multiply
14872
  kA       What to multiple A by
14873
  B        Second point to multiply
14874
  kB       What to multiple B by
14875
  C        [out] Destination point (can overlap with A or B)
14876
  a        ECC curve parameter a
14877
  modulus  Modulus for curve
14878
  return MP_OKAY on success
14879
*/
14880
int ecc_mul2add(ecc_point* A, mp_int* kA,
14881
                ecc_point* B, mp_int* kB,
14882
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
14883
{
14884
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
14885
   mp_digit mp = 0;
14886
#ifdef WOLFSSL_SMALL_STACK
14887
   mp_int   *mu = NULL;
14888
#else
14889
   mp_int   mu[1];
14890
#endif
14891
14892
   if ((A == NULL) || (kA == NULL) || (B == NULL) || (kB == NULL) ||
14893
           (C == NULL) || (modulus == NULL)) {
14894
       return ECC_BAD_ARG_E;
14895
   }
14896
   if ((mp_isneg(kA) == MP_YES) || (mp_isneg(kB) == MP_YES)) {
14897
       return ECC_OUT_OF_RANGE_E;
14898
   }
14899
14900
#ifdef WOLFSSL_SMALL_STACK
14901
   mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14902
   if (mu == NULL)
14903
       return MP_MEM;
14904
#endif
14905
14906
   err = mp_init(mu);
14907
   if (err != MP_OKAY) {
14908
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14909
       return err;
14910
   }
14911
14912
#ifndef HAVE_THREAD_LS
14913
#ifndef WOLFSSL_MUTEX_INITIALIZER
14914
   /* extra sanity check if wolfCrypt_Init not called */
14915
   if (wc_local_InitMutexOnce(&ecc_fp_lock, &initMutex) != 0) {
14916
       mp_clear(mu);
14917
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14918
       return BAD_MUTEX_E;
14919
   }
14920
#endif
14921
14922
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14923
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14924
      return BAD_MUTEX_E;
14925
   }
14926
#endif /* HAVE_THREAD_LS */
14927
14928
      /* find point */
14929
      idx1 = find_base(A);
14930
14931
      /* no entry? */
14932
      if (idx1 == -1) {
14933
         /* find hole and add it */
14934
         if ((idx1 = find_hole()) >= 0) {
14935
            err = add_entry(idx1, A);
14936
         }
14937
      }
14938
      if (err == MP_OKAY && idx1 != -1 && fp_cache[idx1].lru_count < (INT_MAX-1)) {
14939
         /* increment LRU */
14940
         ++(fp_cache[idx1].lru_count);
14941
      }
14942
14943
      if (err == MP_OKAY) {
14944
        /* find point */
14945
        idx2 = find_base(B);
14946
14947
        /* no entry? */
14948
        if (idx2 == -1) {
14949
           /* find hole and add it */
14950
           if ((idx2 = find_hole()) >= 0)
14951
              err = add_entry(idx2, B);
14952
         }
14953
      }
14954
14955
      if (err == MP_OKAY && idx2 != -1 && fp_cache[idx2].lru_count < (INT_MAX-1)) {
14956
         /* increment LRU */
14957
         ++(fp_cache[idx2].lru_count);
14958
      }
14959
14960
      if (err == MP_OKAY) {
14961
        /* if it's >= 2 AND the LUT is not set build the LUT */
14962
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
14963
           /* compute mp */
14964
           err = mp_montgomery_setup(modulus, &mp);
14965
14966
           if (err == MP_OKAY) {
14967
             mpInit = 1;
14968
             err = mp_montgomery_calc_normalization(mu, modulus);
14969
           }
14970
14971
           if (err == MP_OKAY)
14972
             /* build the LUT */
14973
             err = build_lut(idx1, a, modulus, mp, mu);
14974
        }
14975
      }
14976
14977
      if (err == MP_OKAY) {
14978
        /* if it's >= 2 AND the LUT is not set build the LUT */
14979
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
14980
           if (mpInit == 0) {
14981
                /* compute mp */
14982
                err = mp_montgomery_setup(modulus, &mp);
14983
                if (err == MP_OKAY) {
14984
                    mpInit = 1;
14985
                    err = mp_montgomery_calc_normalization(mu, modulus);
14986
                }
14987
            }
14988
14989
            if (err == MP_OKAY)
14990
              /* build the LUT */
14991
              err = build_lut(idx2, a, modulus, mp, mu);
14992
        }
14993
      }
14994
14995
14996
      if (err == MP_OKAY) {
14997
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
14998
                                     fp_cache[idx2].LUT_set) {
14999
           if (mpInit == 0) {
15000
              /* compute mp */
15001
              err = mp_montgomery_setup(modulus, &mp);
15002
           }
15003
           if (err == MP_OKAY)
15004
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
15005
        } else {
15006
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
15007
        }
15008
      }
15009
15010
#ifndef HAVE_THREAD_LS
15011
    wc_UnLockMutex(&ecc_fp_lock);
15012
#endif /* HAVE_THREAD_LS */
15013
    mp_clear(mu);
15014
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15015
15016
    return err;
15017
}
15018
#endif
15019
#endif /* ECC_SHAMIR */
15020
15021
/** ECC Fixed Point mulmod global
15022
    k        The multiplicand
15023
    G        Base point to multiply
15024
    R        [out] Destination of product
15025
    a        ECC curve parameter a
15026
    modulus  The modulus for the curve
15027
    map      [boolean] If non-zero maps the point back to affine coordinates,
15028
             otherwise it's left in jacobian-montgomery form
15029
    return MP_OKAY if successful
15030
*/
15031
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
15032
    mp_int* modulus, int map, void* heap)
15033
{
15034
#if !defined(WOLFSSL_SP_MATH)
15035
   int   idx, err = MP_OKAY;
15036
   mp_digit mp = 0;
15037
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
15038
   int      mpSetup = 0;
15039
#ifndef HAVE_THREAD_LS
15040
   int got_ecc_fp_lock = 0;
15041
#endif
15042
15043
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
15044
       return ECC_BAD_ARG_E;
15045
   }
15046
15047
   /* k can't be negative or have more bits than modulus count plus 1 */
15048
   if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus) + 1)) {
15049
      return ECC_OUT_OF_RANGE_E;
15050
   }
15051
15052
   if (mp_iszero(k)) {
15053
      return ecc_set_point_infinity(R);
15054
   }
15055
15056
#ifdef WOLFSSL_SMALL_STACK
15057
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
15058
       return MP_MEM;
15059
#endif
15060
15061
   if (mp_init(mu) != MP_OKAY) {
15062
       err = MP_INIT_E;
15063
       goto out;
15064
   }
15065
15066
#ifndef HAVE_THREAD_LS
15067
#ifndef WOLFSSL_MUTEX_INITIALIZER
15068
   /* extra sanity check if wolfCrypt_Init not called */
15069
   if (wc_local_InitMutexOnce(&ecc_fp_lock, &initMutex) != 0) {
15070
      err = BAD_MUTEX_E;
15071
      goto out;
15072
   }
15073
#endif
15074
15075
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
15076
      err = BAD_MUTEX_E;
15077
      goto out;
15078
   }
15079
   got_ecc_fp_lock = 1;
15080
#endif /* HAVE_THREAD_LS */
15081
15082
      /* find point */
15083
      idx = find_base(G);
15084
15085
      /* no entry? */
15086
      if (idx == -1) {
15087
         /* find hole and add it */
15088
         idx = find_hole();
15089
15090
         if (idx >= 0)
15091
            err = add_entry(idx, G);
15092
      }
15093
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
15094
         /* increment LRU */
15095
         ++(fp_cache[idx].lru_count);
15096
      }
15097
15098
15099
      if (err == MP_OKAY) {
15100
        /* if it's 2 build the LUT, if it's higher just use the LUT */
15101
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
15102
           /* compute mp */
15103
           err = mp_montgomery_setup(modulus, &mp);
15104
15105
           if (err == MP_OKAY) {
15106
             /* compute mu */
15107
             mpSetup = 1;
15108
             err = mp_montgomery_calc_normalization(mu, modulus);
15109
           }
15110
15111
           if (err == MP_OKAY)
15112
             /* build the LUT */
15113
             err = build_lut(idx, a, modulus, mp, mu);
15114
        }
15115
      }
15116
15117
      if (err == MP_OKAY) {
15118
        if (idx >= 0 && fp_cache[idx].LUT_set) {
15119
           if (mpSetup == 0) {
15120
              /* compute mp */
15121
              err = mp_montgomery_setup(modulus, &mp);
15122
           }
15123
           if (err == MP_OKAY)
15124
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
15125
        } else {
15126
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
15127
        }
15128
      }
15129
15130
  out:
15131
15132
#ifndef HAVE_THREAD_LS
15133
    if (got_ecc_fp_lock)
15134
        wc_UnLockMutex(&ecc_fp_lock);
15135
#endif /* HAVE_THREAD_LS */
15136
    mp_clear(mu);
15137
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15138
15139
    return err;
15140
15141
#else /* WOLFSSL_SP_MATH */
15142
15143
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
15144
        return ECC_BAD_ARG_E;
15145
    }
15146
    if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus))) {
15147
        return ECC_OUT_OF_RANGE_E;
15148
    }
15149
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
15150
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
15151
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
15152
        return IS_POINT_E;
15153
    }
15154
15155
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
15156
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
15157
        int ret;
15158
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
15159
        return ret;
15160
    }
15161
#endif
15162
#ifndef WOLFSSL_SP_NO_256
15163
    if (mp_count_bits(modulus) == 256) {
15164
        int ret;
15165
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
15166
        return ret;
15167
    }
15168
#endif
15169
#ifdef WOLFSSL_SP_384
15170
    if (mp_count_bits(modulus) == 384) {
15171
        int ret;
15172
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
15173
        return ret;
15174
    }
15175
#endif
15176
#ifdef WOLFSSL_SP_521
15177
    if (mp_count_bits(modulus) == 521) {
15178
        int ret;
15179
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
15180
        return ret;
15181
    }
15182
#endif
15183
    return WC_KEY_SIZE_E;
15184
#endif /* WOLFSSL_SP_MATH */
15185
}
15186
15187
/** ECC Fixed Point mulmod global
15188
    k        The multiplicand
15189
    G        Base point to multiply
15190
    R        [out] Destination of product
15191
    a        ECC curve parameter a
15192
    modulus  The modulus for the curve
15193
    map      [boolean] If non-zero maps the point back to affine coordinates,
15194
             otherwise it's left in jacobian-montgomery form
15195
    return MP_OKAY if successful
15196
*/
15197
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
15198
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
15199
{
15200
#if !defined(WOLFSSL_SP_MATH)
15201
   int   idx, err = MP_OKAY;
15202
   mp_digit mp = 0;
15203
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
15204
   int      mpSetup = 0;
15205
#ifndef HAVE_THREAD_LS
15206
   int got_ecc_fp_lock = 0;
15207
#endif
15208
15209
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
15210
                                                                order == NULL) {
15211
       return ECC_BAD_ARG_E;
15212
   }
15213
15214
   /* k can't be negative or have more bits than order */
15215
   if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(order))) {
15216
      return ECC_OUT_OF_RANGE_E;
15217
   }
15218
15219
   if (mp_iszero(k)) {
15220
      return ecc_set_point_infinity(R);
15221
   }
15222
15223
#ifdef WOLFSSL_SMALL_STACK
15224
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
15225
       return MP_MEM;
15226
#endif
15227
15228
   if (mp_init(mu) != MP_OKAY) {
15229
       err = MP_INIT_E;
15230
       goto out;
15231
   }
15232
15233
#ifndef HAVE_THREAD_LS
15234
#ifndef WOLFSSL_MUTEX_INITIALIZER
15235
   /* extra sanity check if wolfCrypt_Init not called */
15236
   if (wc_local_InitMutexOnce(&ecc_fp_lock, &initMutex) != 0) {
15237
      err = BAD_MUTEX_E;
15238
      goto out;
15239
   }
15240
#endif
15241
15242
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
15243
      err = BAD_MUTEX_E;
15244
      goto out;
15245
   }
15246
   got_ecc_fp_lock = 1;
15247
#endif /* HAVE_THREAD_LS */
15248
15249
      /* find point */
15250
      idx = find_base(G);
15251
15252
      /* no entry? */
15253
      if (idx == -1) {
15254
         /* find hole and add it */
15255
         idx = find_hole();
15256
15257
         if (idx >= 0)
15258
            err = add_entry(idx, G);
15259
      }
15260
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
15261
         /* increment LRU */
15262
         ++(fp_cache[idx].lru_count);
15263
      }
15264
15265
15266
      if (err == MP_OKAY) {
15267
        /* if it's 2 build the LUT, if it's higher just use the LUT */
15268
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
15269
           /* compute mp */
15270
           err = mp_montgomery_setup(modulus, &mp);
15271
15272
           if (err == MP_OKAY) {
15273
             /* compute mu */
15274
             mpSetup = 1;
15275
             err = mp_montgomery_calc_normalization(mu, modulus);
15276
           }
15277
15278
           if (err == MP_OKAY)
15279
             /* build the LUT */
15280
             err = build_lut(idx, a, modulus, mp, mu);
15281
        }
15282
      }
15283
15284
      if (err == MP_OKAY) {
15285
        if (idx >= 0 && fp_cache[idx].LUT_set) {
15286
           if (mpSetup == 0) {
15287
              /* compute mp */
15288
              err = mp_montgomery_setup(modulus, &mp);
15289
           }
15290
           if (err == MP_OKAY)
15291
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
15292
        } else {
15293
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
15294
        }
15295
      }
15296
15297
  out:
15298
15299
#ifndef HAVE_THREAD_LS
15300
    if (got_ecc_fp_lock)
15301
        wc_UnLockMutex(&ecc_fp_lock);
15302
#endif /* HAVE_THREAD_LS */
15303
    mp_clear(mu);
15304
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15305
15306
    return err;
15307
15308
#else /* WOLFSSL_SP_MATH */
15309
15310
    (void)rng;
15311
15312
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
15313
                                                                order == NULL) {
15314
        return ECC_BAD_ARG_E;
15315
    }
15316
    if (mp_isneg(k) || (mp_count_bits(k) > mp_count_bits(modulus))) {
15317
        return ECC_OUT_OF_RANGE_E;
15318
    }
15319
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
15320
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
15321
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
15322
        return IS_POINT_E;
15323
    }
15324
15325
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
15326
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
15327
        int ret;
15328
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
15329
        return ret;
15330
    }
15331
#endif
15332
#ifndef WOLFSSL_SP_NO_256
15333
    if (mp_count_bits(modulus) == 256) {
15334
        int ret;
15335
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
15336
        return ret;
15337
    }
15338
#endif
15339
#ifdef WOLFSSL_SP_384
15340
    if (mp_count_bits(modulus) == 384) {
15341
        int ret;
15342
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
15343
        return ret;
15344
    }
15345
#endif
15346
#ifdef WOLFSSL_SP_521
15347
    if (mp_count_bits(modulus) == 521) {
15348
        int ret;
15349
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
15350
        return ret;
15351
    }
15352
#endif
15353
    return WC_KEY_SIZE_E;
15354
#endif /* WOLFSSL_SP_MATH */
15355
}
15356
15357
#if !defined(WOLFSSL_SP_MATH)
15358
/* helper function for freeing the cache ...
15359
   must be called with the cache mutex locked */
15360
static void wc_ecc_fp_free_cache(void)
15361
{
15362
   unsigned x, y;
15363
   for (x = 0; x < FP_ENTRIES; x++) {
15364
      if (fp_cache[x].g != NULL) {
15365
         for (y = 0; y < (1U<<FP_LUT); y++) {
15366
            wc_ecc_del_point(fp_cache[x].LUT[y]);
15367
            fp_cache[x].LUT[y] = NULL;
15368
         }
15369
         wc_ecc_del_point(fp_cache[x].g);
15370
         fp_cache[x].g         = NULL;
15371
         mp_clear(&fp_cache[x].mu);
15372
         fp_cache[x].LUT_set   = 0;
15373
         fp_cache[x].lru_count = 0;
15374
         fp_cache[x].lock = 0;
15375
      }
15376
   }
15377
}
15378
#endif
15379
15380
15381
/** Init the Fixed Point cache */
15382
void wc_ecc_fp_init(void)
15383
{
15384
#ifndef WOLFSSL_SP_MATH
15385
#ifndef HAVE_THREAD_LS
15386
#ifndef WOLFSSL_MUTEX_INITIALIZER
15387
   /* Losing the election is fine - the winner finishes the init. */
15388
   (void)wc_local_InitMutexOnce(&ecc_fp_lock, &initMutex);
15389
#endif
15390
#endif
15391
#endif
15392
}
15393
15394
15395
/** Free the Fixed Point cache */
15396
WOLFSSL_ABI
15397
void wc_ecc_fp_free(void)
15398
{
15399
#if !defined(WOLFSSL_SP_MATH)
15400
#ifndef HAVE_THREAD_LS
15401
#ifndef WOLFSSL_MUTEX_INITIALIZER
15402
   /* extra sanity check if wolfCrypt_Init not called */
15403
   if (wc_local_InitMutexOnce(&ecc_fp_lock, &initMutex) != 0)
15404
       return;
15405
#endif
15406
15407
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
15408
#endif /* HAVE_THREAD_LS */
15409
15410
       wc_ecc_fp_free_cache();
15411
15412
#ifndef HAVE_THREAD_LS
15413
       wc_UnLockMutex(&ecc_fp_lock);
15414
#ifndef WOLFSSL_MUTEX_INITIALIZER
15415
       wc_FreeMutex(&ecc_fp_lock);
15416
       WOLFSSL_ATOMIC_STORE(initMutex, 0);
15417
#endif
15418
   }
15419
#endif /* HAVE_THREAD_LS */
15420
#endif
15421
}
15422
15423
15424
#endif /* FP_ECC */
15425
15426
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
15427
878
{
15428
878
    int err = 0;
15429
15430
878
#ifdef ECC_TIMING_RESISTANT
15431
878
    if (key == NULL) {
15432
0
        err = BAD_FUNC_ARG;
15433
0
    }
15434
878
    else {
15435
878
        key->rng = rng;
15436
878
    }
15437
#else
15438
    (void)key;
15439
    (void)rng;
15440
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
15441
#endif
15442
15443
878
    return err;
15444
878
}
15445
15446
/* Companion to wc_ecc_set_rng(): detach the key's RNG association.
15447
 * Subsequent operations that require the key's RNG then fail with
15448
 * MISSING_RNG_E until a new one is set. */
15449
int wc_ecc_clear_rng(ecc_key* key)
15450
0
{
15451
0
    int err = 0;
15452
15453
0
#ifdef ECC_TIMING_RESISTANT
15454
0
    if (key == NULL) {
15455
0
        err = BAD_FUNC_ARG;
15456
0
    }
15457
0
    else {
15458
0
        key->rng = NULL;
15459
0
    }
15460
#else
15461
    (void)key;
15462
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
15463
#endif
15464
15465
0
    return err;
15466
0
}
15467
15468
#ifdef HAVE_ECC_ENCRYPT
15469
15470
15471
enum ecCliState {
15472
    ecCLI_INIT      = 1,
15473
    ecCLI_SALT_GET  = 2,
15474
    ecCLI_SALT_SET  = 3,
15475
    ecCLI_SENT_REQ  = 4,
15476
    ecCLI_RECV_RESP = 5,
15477
    ecCLI_BAD_STATE = 99
15478
};
15479
15480
enum ecSrvState {
15481
    ecSRV_INIT      = 1,
15482
    ecSRV_SALT_GET  = 2,
15483
    ecSRV_SALT_SET  = 3,
15484
    ecSRV_RECV_REQ  = 4,
15485
    ecSRV_SENT_RESP = 5,
15486
    ecSRV_BAD_STATE = 99
15487
};
15488
15489
15490
struct ecEncCtx {
15491
    byte* kdfSalt;         /* optional salt for kdf */
15492
    const byte* kdfInfo;   /* optional info for kdf */
15493
    const byte* macSalt;   /* optional salt for mac */
15494
    word32    kdfSaltSz;   /* size of kdfSalt */
15495
    word32    kdfInfoSz;   /* size of kdfInfo */
15496
    word32    macSaltSz;   /* size of macSalt */
15497
#ifdef WOLF_CRYPTO_CB
15498
    /* Device for ECIES. Not copied from the ECC key: unset means software,
15499
     * or the WOLF_CRYPTO_CB_FIND finder, even if the key has a device. */
15500
    int       devId;
15501
#endif
15502
    void*     heap;        /* heap hint for memory used */
15503
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
15504
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
15505
    byte      encAlgo;     /* which encryption type */
15506
    byte      kdfAlgo;     /* which key derivation function type */
15507
    byte      macAlgo;     /* which mac function type */
15508
    byte      protocol;    /* are we REQ_RESP client or server ? */
15509
    byte      cliSt;       /* protocol state, for sanity checks */
15510
    byte      srvSt;       /* protocol state, for sanity checks */
15511
    WC_RNG*   rng;
15512
};
15513
15514
/* optional set info, can be called before or after set_peer_salt */
15515
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
15516
{
15517
    if (ctx == NULL)
15518
        return BAD_FUNC_ARG;
15519
15520
    ctx->encAlgo = encAlgo;
15521
    ctx->kdfAlgo = kdfAlgo;
15522
    ctx->macAlgo = macAlgo;
15523
15524
    return 0;
15525
}
15526
15527
#ifdef WOLF_CRYPTO_CB
15528
/* Read back the parameters a caller configured on the context.  Intended for
15529
 * crypto-callback backends (e.g. a hardware ECIES engine) that must reproduce
15530
 * the algorithm, KDF salt and KDF info to run the operation off-device.  Only
15531
 * built when crypto callbacks are enabled, so default builds are unaffected. */
15532
int wc_ecc_ctx_get_algo(ecEncCtx* ctx, byte* encAlgo, byte* kdfAlgo,
15533
                        byte* macAlgo)
15534
{
15535
    if (ctx == NULL)
15536
        return BAD_FUNC_ARG;
15537
15538
    if (encAlgo != NULL)
15539
        *encAlgo = ctx->encAlgo;
15540
    if (kdfAlgo != NULL)
15541
        *kdfAlgo = ctx->kdfAlgo;
15542
    if (macAlgo != NULL)
15543
        *macAlgo = ctx->macAlgo;
15544
15545
    return 0;
15546
}
15547
15548
int wc_ecc_ctx_get_kdf_salt(ecEncCtx* ctx, const byte** salt, word32* sz)
15549
{
15550
    if (ctx == NULL || salt == NULL || sz == NULL)
15551
        return BAD_FUNC_ARG;
15552
15553
    *salt = ctx->kdfSalt;
15554
    *sz   = ctx->kdfSaltSz;
15555
15556
    return 0;
15557
}
15558
15559
int wc_ecc_ctx_get_info(ecEncCtx* ctx, const byte** info, word32* sz)
15560
{
15561
    if (ctx == NULL || info == NULL || sz == NULL)
15562
        return BAD_FUNC_ARG;
15563
15564
    *info = ctx->kdfInfo;
15565
    *sz   = ctx->kdfInfoSz;
15566
15567
    return 0;
15568
}
15569
15570
int wc_ecc_ctx_get_mac_salt(ecEncCtx* ctx, const byte** salt, word32* sz)
15571
{
15572
    if (ctx == NULL || salt == NULL || sz == NULL)
15573
        return BAD_FUNC_ARG;
15574
15575
    *salt = ctx->macSalt;
15576
    *sz   = ctx->macSaltSz;
15577
15578
    return 0;
15579
}
15580
15581
/* Read the client or server role, which picks which half of the derived key
15582
 * this message uses. */
15583
int wc_ecc_ctx_get_protocol(ecEncCtx* ctx, int* protocol)
15584
{
15585
    if (ctx == NULL || protocol == NULL)
15586
        return BAD_FUNC_ARG;
15587
15588
    *protocol = ctx->protocol;
15589
15590
    return 0;
15591
}
15592
15593
/* Read the RNG a caller set on the context, for backends that need one
15594
 * instead of standing up a DRBG of their own. */
15595
int wc_ecc_ctx_get_rng(ecEncCtx* ctx, WC_RNG** rng)
15596
{
15597
    if (ctx == NULL || rng == NULL)
15598
        return BAD_FUNC_ARG;
15599
15600
    *rng = ctx->rng;
15601
15602
    return 0;
15603
}
15604
15605
/* Pick the device that ECIES uses; it is never copied from the ECC key. Unset
15606
 * means software, or the WOLF_CRYPTO_CB_FIND finder. Kept across ctx reset. */
15607
int wc_ecc_ctx_set_dev_id(ecEncCtx* ctx, int devId)
15608
{
15609
    if (ctx == NULL)
15610
        return BAD_FUNC_ARG;
15611
15612
    ctx->devId = devId;
15613
15614
    return 0;
15615
}
15616
15617
/* Read back the device set above.  Callback code can use this to learn
15618
 * which device it was called for. */
15619
int wc_ecc_ctx_get_dev_id(ecEncCtx* ctx, int* devId)
15620
{
15621
    if (ctx == NULL || devId == NULL)
15622
        return BAD_FUNC_ARG;
15623
15624
    *devId = ctx->devId;
15625
15626
    return 0;
15627
}
15628
#endif /* WOLF_CRYPTO_CB */
15629
15630
15631
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
15632
{
15633
    if (ctx == NULL || ctx->protocol == 0)
15634
        return NULL;
15635
15636
    if (ctx->protocol == REQ_RESP_CLIENT) {
15637
        if (ctx->cliSt == ecCLI_INIT) {
15638
            ctx->cliSt =  ecCLI_SALT_GET;
15639
            return ctx->clientSalt;
15640
        }
15641
        else {
15642
            ctx->cliSt = ecCLI_BAD_STATE;
15643
            return NULL;
15644
        }
15645
    }
15646
    else if (ctx->protocol == REQ_RESP_SERVER) {
15647
        if (ctx->srvSt == ecSRV_INIT) {
15648
            ctx->srvSt =  ecSRV_SALT_GET;
15649
            return ctx->serverSalt;
15650
        }
15651
        else {
15652
            ctx->srvSt = ecSRV_BAD_STATE;
15653
            return NULL;
15654
        }
15655
    }
15656
15657
    return NULL;
15658
}
15659
15660
15661
/* optional set info, can be called before or after set_peer_salt */
15662
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
15663
{
15664
    if (ctx == NULL || info == 0 || sz < 0)
15665
        return BAD_FUNC_ARG;
15666
15667
    ctx->kdfInfo   = info;
15668
    ctx->kdfInfoSz = (word32)sz;
15669
15670
    return 0;
15671
}
15672
15673
15674
static const char* exchange_info = "Secure Message Exchange";
15675
15676
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
15677
{
15678
    byte tmp[EXCHANGE_SALT_SZ/2];
15679
    int  halfSz = EXCHANGE_SALT_SZ/2;
15680
15681
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15682
        return BAD_FUNC_ARG;
15683
15684
    if (ctx->protocol == REQ_RESP_CLIENT) {
15685
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
15686
        if (ctx->cliSt == ecCLI_SALT_GET)
15687
            ctx->cliSt =  ecCLI_SALT_SET;
15688
        else {
15689
            ctx->cliSt =  ecCLI_BAD_STATE;
15690
            return BAD_STATE_E;
15691
        }
15692
    }
15693
    else {
15694
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
15695
        if (ctx->srvSt == ecSRV_SALT_GET)
15696
            ctx->srvSt =  ecSRV_SALT_SET;
15697
        else {
15698
            ctx->srvSt =  ecSRV_BAD_STATE;
15699
            return BAD_STATE_E;
15700
        }
15701
    }
15702
15703
    /* mix half and half */
15704
    /* tmp stores 2nd half of client before overwrite */
15705
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
15706
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
15707
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
15708
15709
    ctx->kdfSalt   = ctx->clientSalt;
15710
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
15711
15712
    ctx->macSalt   = ctx->serverSalt;
15713
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
15714
15715
    if (ctx->kdfInfo == NULL) {
15716
        /* default info */
15717
        ctx->kdfInfo   = (const byte*)exchange_info;
15718
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
15719
    }
15720
15721
    return 0;
15722
}
15723
15724
/* Set the salt pointer into context.
15725
 *
15726
 * @param  [in, out]  ctx   ECIES context object.
15727
 * @param  [in]       salt  Salt to use with KDF.
15728
 * @param  [in]       sz    Length of salt in bytes.
15729
 * @return  0 on success.
15730
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15731
 */
15732
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15733
{
15734
    if (ctx == NULL || (salt == NULL && sz != 0))
15735
        return BAD_FUNC_ARG;
15736
15737
    /* truncate salt if exceeds max */
15738
    if (sz > EXCHANGE_SALT_SZ)
15739
        sz = EXCHANGE_SALT_SZ;
15740
15741
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
15742
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
15743
    if (ctx->protocol == REQ_RESP_CLIENT) {
15744
        ctx->cliSt = ecCLI_SALT_SET;
15745
        ctx->kdfSalt = ctx->clientSalt;
15746
    }
15747
    else if (ctx->protocol == REQ_RESP_SERVER) {
15748
        ctx->srvSt = ecSRV_SALT_SET;
15749
        ctx->kdfSalt = ctx->serverSalt;
15750
    }
15751
15752
    if (salt != NULL) {
15753
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
15754
    }
15755
    ctx->kdfSaltSz = sz;
15756
15757
    return 0;
15758
}
15759
15760
/* Set your own salt. By default we generate a random salt for ourselves.
15761
 * This allows overriding that after init or reset.
15762
 *
15763
 * @param  [in, out]  ctx   ECIES context object.
15764
 * @param  [in]       salt  Salt to use for ourselves
15765
 * @param  [in]       sz    Length of salt in bytes.
15766
 * @return  0 on success.
15767
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15768
 */
15769
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15770
{
15771
    byte* saltBuffer;
15772
15773
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15774
        return BAD_FUNC_ARG;
15775
15776
    if (sz > EXCHANGE_SALT_SZ)
15777
        sz = EXCHANGE_SALT_SZ;
15778
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
15779
        ctx->clientSalt :
15780
        ctx->serverSalt;
15781
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
15782
    XMEMCPY(saltBuffer, salt, sz);
15783
15784
    return 0;
15785
}
15786
15787
15788
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
15789
{
15790
    byte* saltBuffer;
15791
15792
    if (ctx == NULL || flags == 0)
15793
        return BAD_FUNC_ARG;
15794
15795
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
15796
15797
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
15798
}
15799
15800
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
15801
{
15802
    if (ctx) {
15803
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
15804
15805
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15806
        #ifdef WOLFSSL_AES_128
15807
            ctx->encAlgo  = ecAES_128_CBC;
15808
        #else
15809
            ctx->encAlgo  = ecAES_256_CBC;
15810
        #endif
15811
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15812
        #ifdef WOLFSSL_AES_256
15813
            ctx->encAlgo  = ecAES_256_CTR;
15814
        #else
15815
            ctx->encAlgo  = ecAES_128_CTR;
15816
        #endif
15817
    #elif !defined(NO_AES) && defined(HAVE_AESGCM) && \
15818
        (defined(WOLFSSL_ECIES_OLD) || defined(WOLFSSL_ECIES_GEN_IV) || \
15819
         defined(WOLFSSL_ECIES_STATIC_GCM_NONCE))
15820
        /* Only default to GCM when the configured IV mode permits it, so a
15821
         * GCM-only build cannot default to an algorithm that encrypt/decrypt
15822
         * would reject with NOT_COMPILED_IN. */
15823
        #ifdef WOLFSSL_AES_128
15824
            ctx->encAlgo  = ecAES_128_GCM;
15825
        #else
15826
            ctx->encAlgo  = ecAES_256_GCM;
15827
        #endif
15828
    #else
15829
        /* In a GCM-only build using the default IV mode, define
15830
         * WOLFSSL_ECIES_STATIC_GCM_NONCE to opt in to the fixed-nonce DEM. */
15831
        #error "No valid encryption algorithm for ECIES configured."
15832
    #endif
15833
        ctx->kdfAlgo  = ecHKDF_SHA256;
15834
        ctx->macAlgo  = ecHMAC_SHA256;
15835
        ctx->protocol = (byte)flags;
15836
        ctx->rng      = rng;
15837
    #ifdef WOLF_CRYPTO_CB
15838
        /* The XMEMSET above leaves this at 0, and 0 is a real devId.  Start
15839
         * in software; the caller picks a device with
15840
         * wc_ecc_ctx_set_dev_id(). */
15841
        ctx->devId    = INVALID_DEVID;
15842
    #endif
15843
15844
        if (flags == REQ_RESP_CLIENT)
15845
            ctx->cliSt = ecCLI_INIT;
15846
        if (flags == REQ_RESP_SERVER)
15847
            ctx->srvSt = ecSRV_INIT;
15848
    }
15849
}
15850
15851
15852
/* allow ecc context reset so user doesn't have to init/free for reuse */
15853
WOLFSSL_ABI
15854
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
15855
{
15856
    void* heap;
15857
#ifdef WOLF_CRYPTO_CB
15858
    int   devId;
15859
#endif
15860
15861
    if (ctx == NULL || rng == NULL)
15862
        return BAD_FUNC_ARG;
15863
15864
    /* ecc_ctx_init clears the whole context, so carry the heap hint over it.
15865
     * The context has to be freed to the heap it was allocated from.  Keep
15866
     * the device too: reset means "reuse this context", so it must stay. */
15867
    heap = ctx->heap;
15868
#ifdef WOLF_CRYPTO_CB
15869
    devId = ctx->devId;
15870
#endif
15871
    ecc_ctx_init(ctx, ctx->protocol, rng);
15872
    ctx->heap = heap;
15873
#ifdef WOLF_CRYPTO_CB
15874
    ctx->devId = devId;
15875
#endif
15876
15877
    return ecc_ctx_set_salt(ctx, ctx->protocol);
15878
}
15879
15880
15881
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
15882
{
15883
    int       ret = 0;
15884
    ecEncCtx* ctx;
15885
15886
    if (flags != REQ_RESP_SERVER && flags != REQ_RESP_CLIENT) {
15887
        WOLFSSL_MSG("Bad flag passed to wc_ecc_ctx_new_ex");
15888
        return NULL;
15889
    }
15890
15891
    ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap, DYNAMIC_TYPE_ECC);
15892
    if (ctx) {
15893
        ctx->protocol = (byte)flags;
15894
        ctx->heap     = heap;
15895
    #ifdef WOLF_CRYPTO_CB
15896
        /* wc_ecc_ctx_reset() below keeps devId across ecc_ctx_init(), so it
15897
         * needs a real value first.  This memory starts out uninitialized. */
15898
        ctx->devId    = INVALID_DEVID;
15899
    #endif
15900
    }
15901
15902
    ret = wc_ecc_ctx_reset(ctx, rng);
15903
    if (ret != 0) {
15904
        wc_ecc_ctx_free(ctx);
15905
        ctx = NULL;
15906
    }
15907
15908
    return ctx;
15909
}
15910
15911
15912
/* alloc/init and set defaults, return new Context  */
15913
WOLFSSL_ABI
15914
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
15915
{
15916
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
15917
}
15918
15919
15920
/* free any resources, clear any keys */
15921
WOLFSSL_ABI
15922
void wc_ecc_ctx_free(ecEncCtx* ctx)
15923
{
15924
    if (ctx) {
15925
        void* heap = ctx->heap;
15926
        ForceZero(ctx, sizeof(ecEncCtx));
15927
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
15928
        (void)heap;
15929
    }
15930
}
15931
15932
#if !defined(NO_AES) && defined(HAVE_AESGCM)
15933
/* Is the ECIES encryption algorithm an AES-GCM (AEAD) mode?  GCM replaces the
15934
 * AES + HMAC pair with a single authenticated-encryption pass. */
15935
static WC_INLINE int ecc_is_gcm(byte encAlgo)
15936
{
15937
    return (encAlgo == ecAES_128_GCM || encAlgo == ecAES_256_GCM);
15938
}
15939
#else
15940
/* Compile GCM branches out entirely when AES-GCM isn't available. */
15941
#define ecc_is_gcm(encAlgo) 0
15942
#endif
15943
15944
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
15945
                             int* keysLen, word32* digestSz, word32* blockSz)
15946
{
15947
    if (ctx) {
15948
        switch (ctx->encAlgo) {
15949
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15950
            case ecAES_128_CBC:
15951
                *encKeySz = KEY_SIZE_128;
15952
                *ivSz     = IV_SIZE_128;
15953
                *blockSz  = WC_AES_BLOCK_SIZE;
15954
                break;
15955
            case ecAES_256_CBC:
15956
                *encKeySz = KEY_SIZE_256;
15957
                *ivSz     = IV_SIZE_128;
15958
                *blockSz  = WC_AES_BLOCK_SIZE;
15959
                break;
15960
        #endif
15961
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15962
            case ecAES_128_CTR:
15963
                *encKeySz = KEY_SIZE_128;
15964
                *ivSz     = 12;
15965
                *blockSz  = 1;
15966
                break;
15967
            case ecAES_256_CTR:
15968
                *encKeySz = KEY_SIZE_256;
15969
                *ivSz     = 12;
15970
                *blockSz  = 1;
15971
                break;
15972
        #endif
15973
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
15974
            case ecAES_128_GCM:
15975
                *encKeySz = KEY_SIZE_128;
15976
                *ivSz     = GCM_NONCE_MID_SZ;
15977
                *blockSz  = 1;
15978
                break;
15979
            case ecAES_256_GCM:
15980
                *encKeySz = KEY_SIZE_256;
15981
                *ivSz     = GCM_NONCE_MID_SZ;
15982
                *blockSz  = 1;
15983
                break;
15984
        #endif
15985
            default:
15986
                return BAD_FUNC_ARG;
15987
        }
15988
15989
        if (ecc_is_gcm(ctx->encAlgo)) {
15990
            /* GCM is AEAD: the full block-sized tag replaces the HMAC digest,
15991
             * and no separate MAC algorithm/key is used. */
15992
            *digestSz = WC_AES_BLOCK_SIZE;
15993
        }
15994
        else {
15995
            switch (ctx->macAlgo) {
15996
                case ecHMAC_SHA256:
15997
                    *digestSz = WC_SHA256_DIGEST_SIZE;
15998
                    break;
15999
                default:
16000
                    return BAD_FUNC_ARG;
16001
            }
16002
        }
16003
    } else
16004
        return BAD_FUNC_ARG;
16005
16006
    if (ecc_is_gcm(ctx->encAlgo)) {
16007
        /* No MAC key.  The nonce follows the ECIES IV build mode, matching the
16008
         * CBC/CTR DEMs: derived from the KDF (OLD), a fresh random value
16009
         * (GEN_IV), or a fixed zero (default). */
16010
#ifdef WOLFSSL_ECIES_OLD
16011
        *keysLen = *encKeySz + *ivSz;   /* nonce is part of the KDF output */
16012
#else
16013
        *keysLen = *encKeySz;
16014
#endif
16015
    }
16016
    else {
16017
#ifdef WOLFSSL_ECIES_OLD
16018
        *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
16019
#else
16020
        *keysLen  = *encKeySz + (int)*digestSz;
16021
#endif
16022
    }
16023
16024
    return 0;
16025
}
16026
16027
/* Total ECIES output size for msgSz bytes of message: the ephemeral public
16028
 * key (not embedded in the OLD format), the IV/nonce when it is carried in
16029
 * the message (GEN_IV mode only), the ciphertext (same length as the padded
16030
 * plaintext), and the trailing HMAC digest or GCM tag.  Used both to
16031
 * bound-check the caller's output buffer and to report the final output
16032
 * size. */
16033
static word32 ecc_ecies_total_size(word32 pubKeySz, int ivSz, word32 msgSz,
16034
                                   word32 digestSz)
16035
{
16036
#ifdef WOLFSSL_ECIES_OLD
16037
    (void)pubKeySz;
16038
    (void)ivSz;
16039
    return msgSz + digestSz;
16040
#elif defined(WOLFSSL_ECIES_GEN_IV)
16041
    return pubKeySz + (word32)ivSz + msgSz + digestSz;
16042
#else
16043
    (void)ivSz;
16044
    return pubKeySz + msgSz + digestSz;
16045
#endif
16046
}
16047
16048
/* Validate and advance the single-use REQ/RESP protocol state for an encrypt.
16049
 * A no-op for the default (non REQ/RESP) protocol.  Returns BAD_STATE_E if the
16050
 * ctx is not in the state that permits an encrypt. */
16051
static int ecc_ctx_encrypt_advance(ecEncCtx* ctx)
16052
{
16053
    if (ctx == NULL)
16054
        return 0;
16055
    if (ctx->protocol == REQ_RESP_SERVER) {
16056
        if (ctx->srvSt != ecSRV_RECV_REQ)
16057
            return BAD_STATE_E;
16058
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
16059
    }
16060
    else if (ctx->protocol == REQ_RESP_CLIENT) {
16061
        if (ctx->cliSt != ecCLI_SALT_SET)
16062
            return BAD_STATE_E;
16063
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
16064
    }
16065
    return 0;
16066
}
16067
16068
/* Validate and advance the single-use REQ/RESP protocol state for a decrypt. */
16069
static int ecc_ctx_decrypt_advance(ecEncCtx* ctx)
16070
{
16071
    if (ctx == NULL)
16072
        return 0;
16073
    if (ctx->protocol == REQ_RESP_CLIENT) {
16074
        if (ctx->cliSt != ecCLI_SENT_REQ)
16075
            return BAD_STATE_E;
16076
        ctx->cliSt = ecCLI_BAD_STATE; /* we're done no more ops allowed */
16077
    }
16078
    else if (ctx->protocol == REQ_RESP_SERVER) {
16079
        if (ctx->srvSt != ecSRV_SALT_SET)
16080
            return BAD_STATE_E;
16081
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
16082
    }
16083
    return 0;
16084
}
16085
16086
16087
/* ecc encrypt with shared secret run through kdf
16088
   ctx holds non default algos and inputs
16089
   msgSz should be the right size for encAlgo, i.e., already padded
16090
   return 0 on success */
16091
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
16092
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
16093
{
16094
    int          ret = 0;
16095
    word32       blockSz = 0;
16096
#ifndef WOLFSSL_ECIES_OLD
16097
#ifndef WOLFSSL_ECIES_GEN_IV
16098
    byte         iv[ECC_MAX_IV_SIZE];
16099
#endif
16100
#endif
16101
    /* Not in the output in OLD mode; kept 0 for ecc_ecies_total_size(). */
16102
    word32       pubKeySz = 0;
16103
    word32       digestSz = 0;
16104
    ecEncCtx     localCtx;
16105
#ifdef WOLFSSL_SMALL_STACK
16106
    byte*        sharedSecret;
16107
    byte*        keys;
16108
#else
16109
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
16110
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
16111
#else
16112
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
16113
#endif
16114
    byte         keys[ECC_BUFSIZE];         /* max size */
16115
#endif
16116
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
16117
    word32       sharedSz = ECC_MAXSIZE;
16118
#else
16119
    /* 'Uncompressed' byte | public key x | public key y | secret */
16120
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
16121
#endif
16122
    int          keysLen = 0;
16123
    int          encKeySz = 0;
16124
    int          ivSz = 0;
16125
    int          offset = 0;         /* keys offset if doing msg exchange */
16126
    byte*        encKey = NULL;
16127
    byte*        encIv = NULL;
16128
    byte*        macKey = NULL;
16129
    /* Device for the ECIES callback and the KDF/AES/HMAC steps. It comes
16130
     * only from the context; unset means software, or the CB_FIND finder. */
16131
    int          eciesDevId = INVALID_DEVID;
16132
#ifdef ECC_TIMING_RESISTANT
16133
    int          lentRng = 0;      /* ctx->rng lent to privKey for this op */
16134
#endif
16135
16136
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
16137
                           outSz  == NULL)
16138
        return BAD_FUNC_ARG;
16139
16140
#ifdef WOLF_CRYPTO_CB
16141
    /* Read this before ctx is swapped for the local default below.  A NULL
16142
     * context has no device and stays INVALID_DEVID. */
16143
    if (ctx != NULL)
16144
        eciesDevId = ctx->devId;
16145
16146
    #ifndef WOLF_CRYPTO_CB_FIND
16147
    if (eciesDevId != INVALID_DEVID)
16148
    #endif
16149
    {
16150
        /* Snapshot single-use state so we can tell whether the callback handled
16151
         * it purely in hardware (state untouched) versus re-entered software
16152
         * (which advances the state itself, below). */
16153
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
16154
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
16155
        ret = wc_CryptoCb_EciesEncrypt(eciesDevId, privKey, pubKey, msg, msgSz,
16156
                                       out, outSz, ctx, compressed);
16157
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
16158
            /* Pure-hardware service left the state alone; enforce single-use
16159
             * here so the ctx can't be reused (nonce reuse for static-nonce
16160
             * GCM).  A re-entrant software callback already advanced it. */
16161
            if (ret == 0 && ctx != NULL &&
16162
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
16163
                ret = ecc_ctx_encrypt_advance(ctx);
16164
            return ret;
16165
        }
16166
        /* fall-through to software (ret is reassigned below) */
16167
    }
16168
#endif
16169
16170
    if (ctx == NULL) {  /* use defaults */
16171
        ecc_ctx_init(&localCtx, 0, NULL);
16172
        ctx = &localCtx;
16173
    }
16174
16175
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
16176
                            &blockSz);
16177
    if (ret != 0)
16178
        return ret;
16179
16180
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
16181
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
16182
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
16183
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
16184
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
16185
    if (ecc_is_gcm(ctx->encAlgo))
16186
        return NOT_COMPILED_IN;
16187
#endif
16188
16189
#ifndef WOLFSSL_ECIES_OLD
16190
    if (!compressed) {
16191
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
16192
    }
16193
    else {
16194
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
16195
    }
16196
#else
16197
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
16198
#endif
16199
16200
    if (ctx->protocol == REQ_RESP_SERVER) {
16201
        offset = keysLen;
16202
        keysLen *= 2;
16203
    }
16204
16205
    /* Validate and advance the single-use state (also covers a re-entrant
16206
     * software CryptoCb call; the hardware path handles it before dispatch). */
16207
    ret = ecc_ctx_encrypt_advance(ctx);
16208
    if (ret != 0)
16209
        return ret;
16210
16211
    if (keysLen > ECC_BUFSIZE) /* keys size */
16212
        return BUFFER_E;
16213
16214
    if ((msgSz % blockSz) != 0)
16215
        return BAD_PADDING_E;
16216
16217
    /* The nonce/IV is embedded in the output only in GEN_IV mode; OLD derives
16218
     * it from the KDF and default uses a fixed nonce (neither is sent). */
16219
    if (*outSz < ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz))
16220
        return BUFFER_E;
16221
16222
#ifdef ECC_TIMING_RESISTANT
16223
    if (ctx->rng != NULL && privKey->rng == NULL) {
16224
        /* Lend the ctx's RNG to the key for the duration of this operation
16225
         * only.  Restored to NULL before every subsequent return, so no
16226
         * borrowed pointer survives on the caller's key object after the
16227
         * call. */
16228
        privKey->rng = ctx->rng;
16229
        lentRng = 1;
16230
    }
16231
#endif
16232
16233
#ifndef WOLFSSL_ECIES_OLD
16234
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
16235
#ifdef ECC_TIMING_RESISTANT
16236
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
16237
#else
16238
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
16239
#endif
16240
        if (ret != 0) {
16241
        #ifdef ECC_TIMING_RESISTANT
16242
            if (lentRng)
16243
                privKey->rng = NULL;
16244
        #endif
16245
            return ret;
16246
        }
16247
    }
16248
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
16249
    if (ret != 0) {
16250
    #ifdef ECC_TIMING_RESISTANT
16251
        if (lentRng)
16252
            privKey->rng = NULL;
16253
    #endif
16254
        return ret;
16255
    }
16256
    out += pubKeySz;
16257
#endif
16258
16259
#ifdef WOLFSSL_SMALL_STACK
16260
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16261
    if (sharedSecret == NULL) {
16262
    #ifdef ECC_TIMING_RESISTANT
16263
        if (lentRng)
16264
            privKey->rng = NULL;
16265
    #endif
16266
        return MEMORY_E;
16267
    }
16268
16269
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16270
    if (keys == NULL) {
16271
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16272
    #ifdef ECC_TIMING_RESISTANT
16273
        if (lentRng)
16274
            privKey->rng = NULL;
16275
    #endif
16276
        return MEMORY_E;
16277
    }
16278
#endif
16279
16280
#ifdef WOLFSSL_ECIES_ISO18033
16281
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
16282
    sharedSz -= pubKeySz;
16283
#endif
16284
16285
    do {
16286
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
16287
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
16288
        if (ret != 0)
16289
            break;
16290
    #endif
16291
    #ifndef WOLFSSL_ECIES_ISO18033
16292
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
16293
    #else
16294
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
16295
                                                                     &sharedSz);
16296
    #endif
16297
    }
16298
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
16299
16300
    if (ret == 0) {
16301
    #ifdef WOLFSSL_ECIES_ISO18033
16302
        /* KDF data is encoded public key and secret. */
16303
        sharedSz += pubKeySz;
16304
    #endif
16305
        switch (ctx->kdfAlgo) {
16306
            /* Use the _ex form so the KDF runs on the context's device, like
16307
             * the cipher and MAC do.  wc_HKDF() would always use software.
16308
             * wc_X963_KDF() below takes no device, so it stays in software. */
16309
            case ecHKDF_SHA256 :
16310
                ret = wc_HKDF_ex(WC_SHA256, sharedSecret, sharedSz,
16311
                           ctx->kdfSalt, ctx->kdfSaltSz, ctx->kdfInfo,
16312
                           ctx->kdfInfoSz, keys, (word32)keysLen,
16313
                           privKey->heap, eciesDevId);
16314
                break;
16315
            case ecHKDF_SHA1 :
16316
                ret = wc_HKDF_ex(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
16317
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16318
                           keys, (word32)keysLen, privKey->heap, eciesDevId);
16319
                break;
16320
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
16321
            case ecKDF_X963_SHA1 :
16322
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16323
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16324
                break;
16325
            case ecKDF_X963_SHA256 :
16326
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16327
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16328
                break;
16329
            case ecKDF_SHA1 :
16330
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16331
                           NULL, 0, keys, (word32)keysLen);
16332
                break;
16333
            case ecKDF_SHA256 :
16334
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16335
                           NULL, 0, keys, (word32)keysLen);
16336
                break;
16337
#endif
16338
16339
16340
            default:
16341
                ret = BAD_FUNC_ARG;
16342
                break;
16343
        }
16344
    }
16345
16346
    if (ret == 0) {
16347
        if (ecc_is_gcm(ctx->encAlgo)) {
16348
            /* GCM nonce follows the ECIES IV build mode, matching CBC/CTR:
16349
             * OLD -> from the KDF output; GEN_IV -> fresh random, embedded;
16350
             * default -> fixed zero.  No MAC key. */
16351
            encKey = keys + offset;
16352
            macKey = NULL;
16353
#ifdef WOLFSSL_ECIES_OLD
16354
            encIv  = encKey + encKeySz;
16355
#elif defined(WOLFSSL_ECIES_GEN_IV)
16356
            {
16357
                WC_RNG* rng = (privKey->rng != NULL) ? privKey->rng : ctx->rng;
16358
                encIv  = out;
16359
                out   += ivSz;
16360
                if (rng == NULL)
16361
                    ret = MISSING_RNG_E;
16362
                else
16363
                    ret = wc_RNG_GenerateBlock(rng, encIv, (word32)ivSz);
16364
            }
16365
#else
16366
            XMEMSET(iv, 0, (size_t)ivSz);
16367
            encIv  = iv;
16368
#endif
16369
        }
16370
        else {
16371
    #ifdef WOLFSSL_ECIES_OLD
16372
            encKey = keys + offset;
16373
            encIv  = encKey + encKeySz;
16374
            macKey = encKey + encKeySz + ivSz;
16375
    #elif defined(WOLFSSL_ECIES_GEN_IV)
16376
            encKey = keys + offset;
16377
            encIv  = out;
16378
            out += ivSz;
16379
            macKey = encKey + encKeySz;
16380
            ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
16381
    #else
16382
            XMEMSET(iv, 0, (size_t)ivSz);
16383
            encKey = keys + offset;
16384
            encIv  = iv;
16385
            macKey = encKey + encKeySz;
16386
    #endif
16387
        }
16388
    }
16389
16390
    if (ret == 0) {
16391
       switch (ctx->encAlgo) {
16392
            case ecAES_128_CBC:
16393
            case ecAES_256_CBC:
16394
            {
16395
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
16396
            #ifdef WOLFSSL_SMALL_STACK
16397
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16398
                                          DYNAMIC_TYPE_AES);
16399
                if (aes == NULL) {
16400
                    ret = MEMORY_E;
16401
                    break;
16402
                }
16403
            #else
16404
                Aes aes[1];
16405
            #endif
16406
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16407
                if (ret == 0) {
16408
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
16409
                                                                AES_ENCRYPTION);
16410
                    if (ret == 0) {
16411
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
16412
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16413
                                                    defined(WC_ASYNC_ENABLE_AES)
16414
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16415
                                            WC_ASYNC_FLAG_NONE);
16416
                    #endif
16417
                    }
16418
                    wc_AesFree(aes);
16419
                }
16420
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16421
        #else
16422
                ret = NOT_COMPILED_IN;
16423
        #endif
16424
                break;
16425
            }
16426
            case ecAES_128_CTR:
16427
            case ecAES_256_CTR:
16428
            {
16429
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
16430
                byte ctr_iv[WC_AES_BLOCK_SIZE];
16431
            #ifndef WOLFSSL_SMALL_STACK
16432
                Aes aes[1];
16433
            #else
16434
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16435
                                            DYNAMIC_TYPE_AES);
16436
                if (aes == NULL) {
16437
                    ret = MEMORY_E;
16438
                    break;
16439
                }
16440
            #endif
16441
16442
                /* Include 4 byte counter starting at all zeros. */
16443
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
16444
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
16445
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
16446
16447
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16448
                if (ret == 0) {
16449
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
16450
                                                                AES_ENCRYPTION);
16451
                    if (ret == 0) {
16452
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
16453
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16454
                                                    defined(WC_ASYNC_ENABLE_AES)
16455
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16456
                                            WC_ASYNC_FLAG_NONE);
16457
                    #endif
16458
                    }
16459
                    wc_AesFree(aes);
16460
                }
16461
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16462
        #else
16463
                ret = NOT_COMPILED_IN;
16464
        #endif
16465
                break;
16466
            }
16467
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
16468
            case ecAES_128_GCM:
16469
            case ecAES_256_GCM:
16470
            {
16471
            #ifdef WOLFSSL_SMALL_STACK
16472
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16473
                                          DYNAMIC_TYPE_AES);
16474
                if (aes == NULL) {
16475
                    ret = MEMORY_E;
16476
                    break;
16477
                }
16478
            #else
16479
                Aes aes[1];
16480
            #endif
16481
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16482
                if (ret == 0) {
16483
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
16484
                    if (ret == 0) {
16485
                        /* tag is written directly after the ciphertext; the
16486
                         * mac salt (if any) is bound in as AAD, mirroring the
16487
                         * HMAC salt used by the CBC/CTR paths. */
16488
                        ret = wc_AesGcmEncrypt(aes, out, msg, msgSz,
16489
                                    encIv, (word32)ivSz,
16490
                                    out + msgSz, digestSz,
16491
                                    ctx->macSalt, ctx->macSaltSz);
16492
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16493
                                                    defined(WC_ASYNC_ENABLE_AES)
16494
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16495
                                            WC_ASYNC_FLAG_NONE);
16496
                    #endif
16497
                    }
16498
                    wc_AesFree(aes);
16499
                }
16500
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16501
                break;
16502
            }
16503
        #endif
16504
            default:
16505
                ret = BAD_FUNC_ARG;
16506
                break;
16507
        }
16508
    }
16509
16510
    if (ret == 0 && !ecc_is_gcm(ctx->encAlgo)) {
16511
        switch (ctx->macAlgo) {
16512
            case ecHMAC_SHA256:
16513
            {
16514
            #ifdef WOLFSSL_SMALL_STACK
16515
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
16516
                                             DYNAMIC_TYPE_HMAC);
16517
                if (hmac == NULL) {
16518
                    ret = MEMORY_E;
16519
                    break;
16520
                }
16521
            #else
16522
                Hmac hmac[1];
16523
            #endif
16524
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
16525
                if (ret == 0) {
16526
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
16527
                                                         WC_SHA256_DIGEST_SIZE);
16528
                    if (ret == 0) {
16529
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
16530
                        ret = wc_HmacUpdate(hmac, out, msgSz);
16531
                    #else
16532
                        /* IV is before encrypted message. */
16533
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
16534
                    #endif
16535
                    }
16536
                    if (ret == 0)
16537
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
16538
                    if (ret == 0)
16539
                        ret = wc_HmacFinal(hmac, out+msgSz);
16540
                    wc_HmacFree(hmac);
16541
                }
16542
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
16543
                break;
16544
            }
16545
16546
            default:
16547
                ret = BAD_FUNC_ARG;
16548
                break;
16549
        }
16550
    }
16551
16552
    if (ret == 0)
16553
        *outSz = ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz);
16554
16555
    ForceZero(sharedSecret, sharedSz);
16556
    ForceZero(keys, (word32)keysLen);
16557
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16558
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16559
16560
#ifdef ECC_TIMING_RESISTANT
16561
    if (lentRng)
16562
        privKey->rng = NULL;
16563
#endif
16564
16565
    return ret;
16566
}
16567
16568
/* ecc encrypt with shared secret run through kdf
16569
   ctx holds non default algos and inputs
16570
   msgSz should be the right size for encAlgo, i.e., already padded
16571
   return 0 on success */
16572
WOLFSSL_ABI
16573
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
16574
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
16575
{
16576
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
16577
}
16578
16579
/* ecc decrypt with shared secret run through kdf
16580
   ctx holds non default algos and inputs
16581
   return 0 on success */
16582
WOLFSSL_ABI
16583
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
16584
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
16585
{
16586
    int          ret = 0;
16587
    word32       blockSz = 0;
16588
#ifndef WOLFSSL_ECIES_OLD
16589
#ifndef WOLFSSL_ECIES_GEN_IV
16590
    byte         iv[ECC_MAX_IV_SIZE];
16591
#endif
16592
    word32       pubKeySz = 0;
16593
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
16594
#endif
16595
    word32       digestSz = 0;
16596
    ecEncCtx     localCtx;
16597
#ifdef WOLFSSL_SMALL_STACK
16598
    byte*        sharedSecret;
16599
    byte*        keys;
16600
#else
16601
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
16602
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
16603
#else
16604
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
16605
#endif
16606
    byte         keys[ECC_BUFSIZE];         /* max size */
16607
#endif
16608
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
16609
    word32       sharedSz = ECC_MAXSIZE;
16610
#else
16611
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
16612
#endif
16613
    int          keysLen = 0;
16614
    int          encKeySz = 0;
16615
    int          ivSz = 0;
16616
    int          offset = 0;       /* in case using msg exchange */
16617
    byte*        encKey = NULL;
16618
    const byte*  encIv = NULL;
16619
    byte*        macKey = NULL;
16620
    /* Device for the ECIES callback and the KDF/AES/HMAC steps. It comes
16621
     * only from the context; unset means software, or the CB_FIND finder. */
16622
    int          eciesDevId = INVALID_DEVID;
16623
#ifdef ECC_TIMING_RESISTANT
16624
    int          lentRng = 0;      /* ctx->rng lent to privKey for this op */
16625
#endif
16626
16627
16628
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
16629
        return BAD_FUNC_ARG;
16630
#ifdef WOLFSSL_ECIES_OLD
16631
    if (pubKey == NULL)
16632
        return BAD_FUNC_ARG;
16633
#endif
16634
16635
#ifdef WOLF_CRYPTO_CB
16636
    /* Read this before ctx is swapped for the local default below.  A NULL
16637
     * context has no device and stays INVALID_DEVID. */
16638
    if (ctx != NULL)
16639
        eciesDevId = ctx->devId;
16640
16641
    #ifndef WOLF_CRYPTO_CB_FIND
16642
    if (eciesDevId != INVALID_DEVID)
16643
    #endif
16644
    {
16645
        /* Snapshot single-use state so we can tell whether the callback handled
16646
         * it purely in hardware (state untouched) versus re-entered software
16647
         * (which advances the state itself, below). */
16648
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
16649
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
16650
        ret = wc_CryptoCb_EciesDecrypt(eciesDevId, privKey, pubKey, msg, msgSz,
16651
                                       out, outSz, ctx);
16652
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
16653
            /* Pure-hardware service left the state alone; enforce single-use
16654
             * here.  A re-entrant software callback already advanced it. */
16655
            if (ret == 0 && ctx != NULL &&
16656
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
16657
                ret = ecc_ctx_decrypt_advance(ctx);
16658
            return ret;
16659
        }
16660
        /* fall-through to software (ret is reassigned below) */
16661
    }
16662
#endif
16663
16664
    if (ctx == NULL) {  /* use defaults */
16665
        ecc_ctx_init(&localCtx, 0, NULL);
16666
        ctx = &localCtx;
16667
    }
16668
16669
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
16670
                            &blockSz);
16671
    if (ret != 0)
16672
        return ret;
16673
16674
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
16675
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
16676
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
16677
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
16678
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
16679
    if (ecc_is_gcm(ctx->encAlgo))
16680
        return NOT_COMPILED_IN;
16681
#endif
16682
16683
#ifndef WOLFSSL_ECIES_OLD
16684
    ret = ecc_public_key_size(privKey, &pubKeySz);
16685
    if (ret != 0)
16686
        return ret;
16687
#ifdef HAVE_COMP_KEY
16688
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
16689
        pubKeySz = (pubKeySz / 2) + 1;
16690
    }
16691
#endif /* HAVE_COMP_KEY */
16692
#endif /* WOLFSSL_ECIES_OLD */
16693
16694
    if (ctx->protocol == REQ_RESP_CLIENT) {
16695
        offset = keysLen;
16696
        keysLen *= 2;
16697
    }
16698
16699
    /* Validate and advance the single-use state (also covers a re-entrant
16700
     * software CryptoCb call; the hardware path handles it before dispatch). */
16701
    ret = ecc_ctx_decrypt_advance(ctx);
16702
    if (ret != 0)
16703
        return ret;
16704
16705
    if (keysLen > ECC_BUFSIZE) /* keys size */
16706
        return BUFFER_E;
16707
16708
    if (ecc_is_gcm(ctx->encAlgo)) {
16709
        /* GCM has a trailing tag (digestSz) and no block padding.  The nonce is
16710
         * only present in the input in GEN_IV mode. */
16711
#ifdef WOLFSSL_ECIES_OLD
16712
        if (msgSz < digestSz)
16713
            return BAD_FUNC_ARG;
16714
        if (*outSz < (msgSz - digestSz))
16715
            return BUFFER_E;
16716
#elif defined(WOLFSSL_ECIES_GEN_IV)
16717
        if (msgSz < pubKeySz + (word32)ivSz + digestSz)
16718
            return BAD_FUNC_ARG;
16719
        if (*outSz < (msgSz - (word32)ivSz - digestSz - pubKeySz))
16720
            return BUFFER_E;
16721
#else
16722
        if (msgSz < pubKeySz + digestSz)
16723
            return BAD_FUNC_ARG;
16724
        if (*outSz < (msgSz - digestSz - pubKeySz))
16725
            return BUFFER_E;
16726
#endif
16727
    }
16728
    else {
16729
#ifdef WOLFSSL_ECIES_OLD
16730
    if (((msgSz - digestSz) % blockSz) != 0)
16731
        return BAD_PADDING_E;
16732
16733
    if (*outSz < (msgSz - digestSz))
16734
        return BUFFER_E;
16735
#elif defined(WOLFSSL_ECIES_GEN_IV)
16736
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
16737
        return BAD_PADDING_E;
16738
16739
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
16740
        return BAD_FUNC_ARG;
16741
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
16742
        return BUFFER_E;
16743
#else
16744
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
16745
        return BAD_PADDING_E;
16746
16747
    if (msgSz < pubKeySz + blockSz + digestSz)
16748
        return BAD_FUNC_ARG;
16749
    if (*outSz < (msgSz - digestSz - pubKeySz))
16750
        return BUFFER_E;
16751
#endif
16752
    }
16753
16754
#ifdef ECC_TIMING_RESISTANT
16755
    if (ctx->rng != NULL && privKey->rng == NULL) {
16756
        /* Lend the ctx's RNG to the key for the duration of this operation
16757
         * only.  Restored to NULL before every subsequent return, so no
16758
         * borrowed pointer survives on the caller's key object after the
16759
         * call. */
16760
        privKey->rng = ctx->rng;
16761
        lentRng = 1;
16762
    }
16763
#endif
16764
16765
#ifdef WOLFSSL_SMALL_STACK
16766
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16767
    if (sharedSecret == NULL) {
16768
    #ifndef WOLFSSL_ECIES_OLD
16769
        if (pubKey == peerKey)
16770
            wc_ecc_free(peerKey);
16771
    #endif
16772
    #ifdef ECC_TIMING_RESISTANT
16773
        if (lentRng)
16774
            privKey->rng = NULL;
16775
    #endif
16776
        return MEMORY_E;
16777
    }
16778
16779
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16780
    if (keys == NULL) {
16781
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16782
    #ifndef WOLFSSL_ECIES_OLD
16783
        if (pubKey == peerKey)
16784
            wc_ecc_free(peerKey);
16785
    #endif
16786
    #ifdef ECC_TIMING_RESISTANT
16787
        if (lentRng)
16788
            privKey->rng = NULL;
16789
    #endif
16790
        return MEMORY_E;
16791
    }
16792
#endif
16793
16794
#ifndef WOLFSSL_ECIES_OLD
16795
    /* The ephemeral public key comes from the message; parse it into the
16796
     * local key object so a caller-supplied pubKey is left untouched. */
16797
    WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
16798
        DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
16799
    if (ret == 0) {
16800
        pubKey = peerKey;
16801
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
16802
    }
16803
    if (ret == 0) {
16804
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
16805
    }
16806
    if (ret == 0) {
16807
        /* Point is not MACed. */
16808
        msg += pubKeySz;
16809
        msgSz -= pubKeySz;
16810
    }
16811
#endif
16812
16813
    if (ret == 0) {
16814
    #ifdef WOLFSSL_ECIES_ISO18033
16815
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
16816
        sharedSz -= pubKeySz;
16817
    #endif
16818
16819
        do {
16820
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
16821
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
16822
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
16823
            if (ret != 0)
16824
                break;
16825
        #endif
16826
        #ifndef WOLFSSL_ECIES_ISO18033
16827
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
16828
                                                                    &sharedSz);
16829
        #else
16830
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
16831
                                                          pubKeySz, &sharedSz);
16832
        #endif
16833
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
16834
    }
16835
    if (ret == 0) {
16836
    #ifdef WOLFSSL_ECIES_ISO18033
16837
        /* KDF data is encoded public key and secret. */
16838
        sharedSz += pubKeySz;
16839
    #endif
16840
        switch (ctx->kdfAlgo) {
16841
            /* Use the _ex form so the KDF runs on the context's device, like
16842
             * the cipher and MAC do.  wc_HKDF() would always use software.
16843
             * wc_X963_KDF() below takes no device, so it stays in software. */
16844
            case ecHKDF_SHA256 :
16845
                ret = wc_HKDF_ex(WC_SHA256, sharedSecret, sharedSz,
16846
                           ctx->kdfSalt, ctx->kdfSaltSz, ctx->kdfInfo,
16847
                           ctx->kdfInfoSz, keys, (word32)keysLen,
16848
                           privKey->heap, eciesDevId);
16849
                break;
16850
            case ecHKDF_SHA1 :
16851
                ret = wc_HKDF_ex(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
16852
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16853
                           keys, (word32)keysLen, privKey->heap, eciesDevId);
16854
                break;
16855
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
16856
            case ecKDF_X963_SHA1 :
16857
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16858
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16859
                break;
16860
            case ecKDF_X963_SHA256 :
16861
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16862
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16863
                break;
16864
            case ecKDF_SHA1 :
16865
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16866
                           NULL, 0, keys, (word32)keysLen);
16867
                break;
16868
            case ecKDF_SHA256 :
16869
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16870
                           NULL, 0, keys, (word32)keysLen);
16871
                break;
16872
#endif
16873
16874
            default:
16875
                ret = BAD_FUNC_ARG;
16876
                break;
16877
         }
16878
    }
16879
16880
    if (ret == 0 && ecc_is_gcm(ctx->encAlgo)) {
16881
        /* GCM nonce follows the ECIES IV build mode (matching CBC/CTR); no MAC
16882
         * key and no separate HMAC verify (GCM authenticates on decrypt). */
16883
        encKey = keys + offset;
16884
        macKey = NULL;
16885
#ifdef WOLFSSL_ECIES_OLD
16886
        encIv  = encKey + encKeySz;
16887
#elif defined(WOLFSSL_ECIES_GEN_IV)
16888
        encIv  = msg;
16889
        msg   += ivSz;
16890
        msgSz -= (word32)ivSz;
16891
#else
16892
        XMEMSET(iv, 0, (size_t)ivSz);
16893
        encIv  = iv;
16894
#endif
16895
    }
16896
    else if (ret == 0) {
16897
    #ifdef WOLFSSL_ECIES_OLD
16898
        encKey = keys + offset;
16899
        encIv  = encKey + encKeySz;
16900
        macKey = encKey + encKeySz + ivSz;
16901
    #elif defined(WOLFSSL_ECIES_GEN_IV)
16902
        encKey = keys + offset;
16903
        encIv  = msg;
16904
        msg   += ivSz;
16905
        msgSz -= ivSz;
16906
        macKey = encKey + encKeySz;
16907
    #else
16908
        XMEMSET(iv, 0, (size_t)ivSz);
16909
        encKey = keys + offset;
16910
        encIv  = iv;
16911
        macKey = encKey + encKeySz;
16912
    #endif
16913
16914
        switch (ctx->macAlgo) {
16915
            case ecHMAC_SHA256:
16916
            {
16917
                byte verify[WC_SHA256_DIGEST_SIZE];
16918
            #ifdef WOLFSSL_SMALL_STACK
16919
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
16920
                                             DYNAMIC_TYPE_HMAC);
16921
                if (hmac == NULL) {
16922
                    ret = MEMORY_E;
16923
                    break;
16924
                }
16925
            #else
16926
                Hmac hmac[1];
16927
            #endif
16928
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
16929
                if (ret == 0) {
16930
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
16931
                                                         WC_SHA256_DIGEST_SIZE);
16932
                    if (ret == 0)
16933
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
16934
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
16935
                    #else
16936
                        /* IV is before encrypted message. */
16937
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
16938
                    #endif
16939
                    if (ret == 0)
16940
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
16941
16942
                    if (ret == 0)
16943
                        ret = wc_HmacFinal(hmac, verify);
16944
                    if ((ret == 0) && (ConstantCompare(verify, msg + msgSz - digestSz,
16945
                                                             (int)digestSz) != 0)) {
16946
                        ret = HASH_TYPE_E;
16947
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
16948
                    }
16949
16950
                    wc_HmacFree(hmac);
16951
                }
16952
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
16953
                break;
16954
            }
16955
16956
            default:
16957
                ret = BAD_FUNC_ARG;
16958
                break;
16959
        }
16960
    }
16961
16962
    if (ret == 0) {
16963
        switch (ctx->encAlgo) {
16964
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
16965
            case ecAES_128_CBC:
16966
            case ecAES_256_CBC:
16967
            {
16968
            #ifdef WOLFSSL_SMALL_STACK
16969
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16970
                                          DYNAMIC_TYPE_AES);
16971
                if (aes == NULL) {
16972
                    ret = MEMORY_E;
16973
                    break;
16974
                }
16975
            #else
16976
                Aes aes[1];
16977
            #endif
16978
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16979
                if (ret == 0) {
16980
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
16981
                                                                AES_DECRYPTION);
16982
                    if (ret == 0) {
16983
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
16984
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16985
                                                    defined(WC_ASYNC_ENABLE_AES)
16986
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16987
                                                            WC_ASYNC_FLAG_NONE);
16988
                    #endif
16989
                    }
16990
                    wc_AesFree(aes);
16991
                }
16992
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16993
                break;
16994
            }
16995
        #endif
16996
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
16997
            case ecAES_128_CTR:
16998
            case ecAES_256_CTR:
16999
            {
17000
            #ifdef WOLFSSL_SMALL_STACK
17001
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
17002
                                          DYNAMIC_TYPE_AES);
17003
                if (aes == NULL) {
17004
                    ret = MEMORY_E;
17005
                    break;
17006
                }
17007
             #else
17008
                Aes aes[1];
17009
             #endif
17010
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
17011
                if (ret == 0) {
17012
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
17013
                    /* Make a 16 byte IV from the bytes passed in. */
17014
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
17015
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
17016
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
17017
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
17018
                                                                AES_ENCRYPTION);
17019
                    if (ret == 0) {
17020
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
17021
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
17022
                                                    defined(WC_ASYNC_ENABLE_AES)
17023
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
17024
                                                            WC_ASYNC_FLAG_NONE);
17025
                    #endif
17026
                    }
17027
                    wc_AesFree(aes);
17028
                }
17029
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
17030
                break;
17031
            }
17032
        #endif
17033
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
17034
            case ecAES_128_GCM:
17035
            case ecAES_256_GCM:
17036
            {
17037
            #ifdef WOLFSSL_SMALL_STACK
17038
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
17039
                                          DYNAMIC_TYPE_AES);
17040
                if (aes == NULL) {
17041
                    ret = MEMORY_E;
17042
                    break;
17043
                }
17044
            #else
17045
                Aes aes[1];
17046
            #endif
17047
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
17048
                if (ret == 0) {
17049
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
17050
                    if (ret == 0) {
17051
                        /* tag trails the ciphertext; mac salt (if any) is the
17052
                         * AAD.  A tag mismatch returns AES_GCM_AUTH_E. */
17053
                        ret = wc_AesGcmDecrypt(aes, out, msg, msgSz - digestSz,
17054
                                    encIv, (word32)ivSz,
17055
                                    msg + msgSz - digestSz, digestSz,
17056
                                    ctx->macSalt, ctx->macSaltSz);
17057
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
17058
                                                    defined(WC_ASYNC_ENABLE_AES)
17059
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
17060
                                                            WC_ASYNC_FLAG_NONE);
17061
                    #endif
17062
                    }
17063
                    wc_AesFree(aes);
17064
                }
17065
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
17066
                break;
17067
            }
17068
        #endif
17069
            default:
17070
                ret = BAD_FUNC_ARG;
17071
                break;
17072
        }
17073
    }
17074
17075
    if (ret == 0)
17076
       *outSz = msgSz - digestSz;
17077
17078
#ifndef WOLFSSL_ECIES_OLD
17079
    if (pubKey == peerKey)
17080
        wc_ecc_free(peerKey);
17081
#endif
17082
    ForceZero(sharedSecret, sharedSz);
17083
    ForceZero(keys, (word32)keysLen);
17084
#ifdef WOLFSSL_SMALL_STACK
17085
#ifndef WOLFSSL_ECIES_OLD
17086
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
17087
#endif
17088
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
17089
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
17090
#endif
17091
17092
#ifdef ECC_TIMING_RESISTANT
17093
    if (lentRng)
17094
        privKey->rng = NULL;
17095
#endif
17096
17097
    return ret;
17098
}
17099
17100
17101
#endif /* HAVE_ECC_ENCRYPT */
17102
17103
17104
#ifdef HAVE_COMP_KEY
17105
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
17106
    !defined(WOLFSSL_MICROCHIP_TA100) && \
17107
    !defined(WOLFSSL_NO_ECC_SW)
17108
17109
#ifndef WOLFSSL_SP_MATH
17110
#if !defined(SQRTMOD_USE_MOD_EXP)
17111
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
17112
 */
17113
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
17114
{
17115
#ifdef WOLFSSL_SMALL_STACK
17116
    mp_int*  a1 = NULL;
17117
    mp_int*  n1 = NULL;
17118
#else
17119
    mp_int   a1[1], n1[1];
17120
#endif
17121
    int      res;
17122
    int      s = 1;
17123
    int      k;
17124
    mp_int*  t[2];
17125
    mp_int*  ts;
17126
    mp_digit residue;
17127
17128
    if (mp_isneg(a) == MP_YES) {
17129
        return MP_VAL;
17130
    }
17131
    if (mp_isneg(n) == MP_YES) {
17132
        return MP_VAL;
17133
    }
17134
    if (mp_iseven(n) == MP_YES) {
17135
        return MP_VAL;
17136
    }
17137
17138
#ifdef WOLFSSL_SMALL_STACK
17139
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
17140
    if (a1 == NULL) {
17141
        return MP_MEM;
17142
    }
17143
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
17144
    if (n1 == NULL) {
17145
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
17146
        return MP_MEM;
17147
    }
17148
#endif
17149
17150
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
17151
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
17152
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
17153
        return res;
17154
    }
17155
17156
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
17157
        goto done;
17158
    }
17159
17160
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
17161
        goto done;
17162
    }
17163
17164
    t[0] = a1;
17165
    t[1] = n1;
17166
17167
    /* Keep reducing until first number is 0. */
17168
    while (!mp_iszero(t[0])) {
17169
        /* Divide by 2 until odd. */
17170
        k = mp_cnt_lsb(t[0]);
17171
        if (k > 0) {
17172
            mp_rshb(t[0], k);
17173
17174
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
17175
             * Odd number of divides results in a negate.
17176
             */
17177
            residue = t[1]->dp[0] & 7;
17178
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
17179
                s = -s;
17180
            }
17181
        }
17182
17183
        /* Swap t[0] and t[1]. */
17184
        ts   = t[0];
17185
        t[0] = t[1];
17186
        t[1] = ts;
17187
17188
        /* Negate s if both numbers == 3 mod 4. */
17189
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
17190
             s = -s;
17191
        }
17192
17193
        /* Reduce first number modulo second. */
17194
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
17195
            res = mp_sub(t[0], t[1], t[0]);
17196
        }
17197
        else {
17198
            res = mp_mod(t[0], t[1], t[0]);
17199
        }
17200
        if (res != MP_OKAY) {
17201
            goto done;
17202
        }
17203
    }
17204
17205
    /* When the two numbers have divisors in common. */
17206
    if (!mp_isone(t[1])) {
17207
        s = 0;
17208
    }
17209
    *c = s;
17210
17211
done:
17212
17213
    /* cleanup */
17214
    mp_clear(n1);
17215
    mp_clear(a1);
17216
17217
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
17218
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
17219
17220
  return res;
17221
}
17222
#endif /* !SQRTMOD_USE_MOD_EXP */
17223
17224
17225
/* Solves the modular equation x^2 = n (mod p)
17226
 * where prime number is greater than 2 (odd prime).
17227
 * The result is returned in the third argument x
17228
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
17229
 */
17230
#if defined(SQRTMOD_USE_MOD_EXP)
17231
/* Temporaries of the single exponentiation square root: the p = 5 mod 8
17232
 * method needs one more. */
17233
#if defined(HAVE_ECC_KOBLITZ) || defined(WOLFSSL_CUSTOM_CURVES)
17234
    #define SQRTMOD_MOD_EXP_TMP_CNT 4
17235
#else
17236
    #define SQRTMOD_MOD_EXP_TMP_CNT 3
17237
#endif
17238
#endif
17239
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
17240
{
17241
#if defined(SQRTMOD_USE_MOD_EXP)
17242
  /* One modular exponentiation: n^((p+1)/4) for p = 3 mod 4 (HAC 3.36) and,
17243
   * only when a curve with such a prime can be present, Atkin's method for
17244
   * p = 5 mod 8. A prime that is 1 mod 8 has no single exponent square root
17245
   * and is refused. Three or four temporaries instead of the ten
17246
   * Tonelli-Shanks needs, which matters to callers on a small thread stack. */
17247
  int res;
17248
  mp_digit i;
17249
#ifdef WOLFSSL_SMALL_STACK
17250
  mp_int* t = (mp_int*)XMALLOC(SQRTMOD_MOD_EXP_TMP_CNT * sizeof(mp_int), NULL,
17251
                               DYNAMIC_TYPE_ECC_BUFFER);
17252
#else
17253
  mp_int t[SQRTMOD_MOD_EXP_TMP_CNT];
17254
#endif
17255
  mp_int* N;
17256
  mp_int* e;
17257
  mp_int* c;
17258
#if defined(HAVE_ECC_KOBLITZ) || defined(WOLFSSL_CUSTOM_CURVES)
17259
  mp_int* v;
17260
#endif
17261
17262
#ifdef WOLFSSL_SMALL_STACK
17263
  if (t == NULL) {
17264
      return MEMORY_E;
17265
  }
17266
#endif
17267
  N = &t[0];
17268
  e = &t[1];
17269
  c = &t[2];
17270
#if defined(HAVE_ECC_KOBLITZ) || defined(WOLFSSL_CUSTOM_CURVES)
17271
  v = &t[3];
17272
17273
  res = mp_init_multi(N, e, c, v, NULL, NULL);
17274
#else
17275
  res = mp_init_multi(N, e, c, NULL, NULL, NULL);
17276
#endif
17277
  if (res != MP_OKAY) {
17278
  #ifdef WOLFSSL_SMALL_STACK
17279
      XFREE(t, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17280
  #endif
17281
      return res;
17282
  }
17283
17284
  if (mp_iseven(prime)) {
17285
      res = MP_VAL;
17286
      goto out;
17287
  }
17288
  res = mp_mod_d(prime, 8, &i);
17289
  if (res == MP_OKAY && i == 1) {
17290
      res = MP_VAL;
17291
  }
17292
#if !defined(HAVE_ECC_KOBLITZ) && !defined(WOLFSSL_CUSTOM_CURVES)
17293
  /* secp224k1 is the only built-in curve with a prime that is 5 mod 8. */
17294
  if (res == MP_OKAY && i == 5) {
17295
      res = MP_VAL;
17296
  }
17297
#endif
17298
17299
  /* reduce n to less than prime */
17300
  if (res == MP_OKAY)
17301
      res = mp_mod(n, prime, N);
17302
  /* when N is zero, sqrt is zero */
17303
  if (res == MP_OKAY && mp_iszero(N)) {
17304
      mp_zero(ret);
17305
      goto out;
17306
  }
17307
17308
#if defined(HAVE_ECC_KOBLITZ) || defined(WOLFSSL_CUSTOM_CURVES)
17309
  /* prime mod 8 = 5: v = (2N)^((p-5)/8), i = 2N.v^2, ret = N.v.(i-1) */
17310
  if (res == MP_OKAY && i == 5) {
17311
      res = mp_addmod(N, N, prime, c);
17312
      if (res == MP_OKAY)
17313
          res = mp_sub_d(prime, 5, e);
17314
      if (res == MP_OKAY)
17315
          res = mp_div_2d(e, 3, e, NULL);
17316
      if (res == MP_OKAY)
17317
          res = mp_exptmod(c, e, prime, v);
17318
      if (res == MP_OKAY)
17319
          res = mp_sqrmod(v, prime, ret);
17320
      if (res == MP_OKAY)
17321
          res = mp_mulmod(ret, c, prime, ret);
17322
      if (res == MP_OKAY)
17323
          res = mp_sub_d(ret, 1, ret);
17324
      if (res == MP_OKAY)
17325
          res = mp_mulmod(ret, v, prime, ret);
17326
      if (res == MP_OKAY)
17327
          res = mp_mulmod(ret, N, prime, ret);
17328
  }
17329
  else
17330
#endif
17331
  /* prime mod 4 = 3: ret = N^((p+1)/4) */
17332
  if (res == MP_OKAY) {
17333
      res = mp_add_d(prime, 1, e);
17334
      if (res == MP_OKAY)
17335
          res = mp_div_2d(e, 2, e, NULL);
17336
      if (res == MP_OKAY)
17337
          res = mp_exptmod(N, e, prime, ret);
17338
  }
17339
17340
  /* Both formulas return a value for a non-residue too; only a value that
17341
   * squares back to N is a root. */
17342
  if (res == MP_OKAY)
17343
      res = mp_sqrmod(ret, prime, c);
17344
  if (res == MP_OKAY && mp_cmp(c, N) != MP_EQ) {
17345
      res = MP_VAL;
17346
  }
17347
17348
out:
17349
  mp_clear(N);
17350
  mp_clear(e);
17351
  mp_clear(c);
17352
#if defined(HAVE_ECC_KOBLITZ) || defined(WOLFSSL_CUSTOM_CURVES)
17353
  mp_clear(v);
17354
#endif
17355
#ifdef WOLFSSL_SMALL_STACK
17356
  XFREE(t, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17357
#endif
17358
17359
  return res;
17360
#else
17361
  int res, legendre, done = 0;
17362
  mp_digit i;
17363
#ifdef WOLFSSL_SMALL_STACK
17364
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17365
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17366
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17367
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17368
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17369
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17370
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17371
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17372
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17373
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
17374
#else
17375
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
17376
#endif
17377
17378
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
17379
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
17380
    res = MP_INIT_E;
17381
    goto out;
17382
  }
17383
17384
#ifdef WOLFSSL_SMALL_STACK
17385
  if ((t1 == NULL) ||
17386
      (C == NULL) ||
17387
      (Q == NULL) ||
17388
      (S == NULL) ||
17389
      (Z == NULL) ||
17390
      (M == NULL) ||
17391
      (T == NULL) ||
17392
      (R == NULL) ||
17393
      (N == NULL) ||
17394
      (two == NULL)) {
17395
    res = MP_MEM;
17396
    goto out;
17397
  }
17398
#endif
17399
17400
  /* first handle the simple cases n = 0 or n = 1 */
17401
  if (mp_cmp_d(n, 0) == MP_EQ) {
17402
    mp_zero(ret);
17403
    res = MP_OKAY;
17404
    goto out;
17405
  }
17406
  if (mp_cmp_d(n, 1) == MP_EQ) {
17407
    res = mp_set(ret, 1);
17408
    goto out;
17409
  }
17410
17411
  /* prime must be odd */
17412
  if (mp_cmp_d(prime, 2) == MP_EQ) {
17413
    res = MP_VAL;
17414
    goto out;
17415
  }
17416
17417
  /* reduce n to less than prime */
17418
  res = mp_mod(n, prime, N);
17419
  if (res != MP_OKAY) {
17420
    goto out;
17421
  }
17422
  /* when N is zero, sqrt is zero */
17423
  if (mp_iszero(N)) {
17424
    mp_set(ret, 0);
17425
    goto out;
17426
  }
17427
17428
  /* is quadratic non-residue mod prime */
17429
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
17430
    goto out;
17431
  }
17432
  if (legendre == -1) {
17433
    res = MP_VAL;
17434
    goto out;
17435
  }
17436
17437
  /* SPECIAL CASE: if prime mod 4 == 3
17438
   * compute directly: res = n^(prime+1)/4 mod prime
17439
   * Handbook of Applied Cryptography algorithm 3.36
17440
   */
17441
  res = mp_mod_d(prime, 4, &i);
17442
  if (res == MP_OKAY && i == 3) {
17443
    res = mp_add_d(prime, 1, t1);
17444
17445
    if (res == MP_OKAY)
17446
      res = mp_div_2(t1, t1);
17447
    if (res == MP_OKAY)
17448
      res = mp_div_2(t1, t1);
17449
    if (res == MP_OKAY)
17450
      res = mp_exptmod(N, t1, prime, ret);
17451
17452
    done = 1;
17453
  }
17454
17455
  /* NOW: TonelliShanks algorithm */
17456
  if (res == MP_OKAY && done == 0) {
17457
17458
    /* factor out powers of 2 from prime-1, defining Q and S
17459
    *                                      as: prime-1 = Q*2^S */
17460
    /* Q = prime - 1 */
17461
    res = mp_copy(prime, Q);
17462
    if (res == MP_OKAY)
17463
      res = mp_sub_d(Q, 1, Q);
17464
17465
    /* S = 0 */
17466
    if (res == MP_OKAY)
17467
      mp_zero(S);
17468
17469
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
17470
      /* Q = Q / 2 */
17471
      res = mp_div_2(Q, Q);
17472
17473
      /* S = S + 1 */
17474
      if (res == MP_OKAY)
17475
        res = mp_add_d(S, 1, S);
17476
    }
17477
17478
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
17479
    /* Z = 2 */
17480
    if (res == MP_OKAY)
17481
      res = mp_set_int(Z, 2);
17482
17483
    while (res == MP_OKAY) {
17484
      res = mp_jacobi(Z, prime, &legendre);
17485
      if (res == MP_OKAY && legendre == -1)
17486
        break;
17487
17488
#if defined(WOLFSSL_CUSTOM_CURVES)
17489
      /* P224R1 succeeds with a value of 11. */
17490
      if (mp_cmp_d(Z, 22) == MP_EQ) {
17491
        /* This is to clamp the loop in case 'prime' is not really prime */
17492
        res = MP_VAL;
17493
        break;
17494
      }
17495
#endif
17496
17497
      /* Z = Z + 1 */
17498
      if (res == MP_OKAY)
17499
        res = mp_add_d(Z, 1, Z);
17500
17501
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
17502
        /* This is to clamp the loop in case 'prime' is not really prime */
17503
        res = MP_VAL;
17504
        break;
17505
      }
17506
    }
17507
17508
    /* C = Z ^ Q mod prime */
17509
    if (res == MP_OKAY)
17510
      res = mp_exptmod(Z, Q, prime, C);
17511
17512
    /* t1 = (Q + 1) / 2 */
17513
    if (res == MP_OKAY)
17514
      res = mp_add_d(Q, 1, t1);
17515
    if (res == MP_OKAY)
17516
      res = mp_div_2(t1, t1);
17517
17518
    /* R = n ^ ((Q + 1) / 2) mod prime */
17519
    if (res == MP_OKAY)
17520
      res = mp_exptmod(N, t1, prime, R);
17521
17522
    /* T = n ^ Q mod prime */
17523
    if (res == MP_OKAY)
17524
      res = mp_exptmod(N, Q, prime, T);
17525
17526
    /* M = S */
17527
    if (res == MP_OKAY)
17528
      res = mp_copy(S, M);
17529
17530
    if (res == MP_OKAY)
17531
      res = mp_set_int(two, 2);
17532
17533
    while (res == MP_OKAY && done == 0) {
17534
      res = mp_copy(T, t1);
17535
17536
      /* reduce to 1 and count */
17537
      i = 0;
17538
      while (res == MP_OKAY) {
17539
        if (mp_cmp_d(t1, 1) == MP_EQ)
17540
            break;
17541
        res = mp_exptmod(t1, two, prime, t1);
17542
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
17543
          /* This is to clamp the loop in case 'prime' is not really prime */
17544
          res = MP_VAL;
17545
          break;
17546
        }
17547
        if (res == MP_OKAY)
17548
          i++;
17549
      }
17550
      if (res == MP_OKAY && i == 0) {
17551
        res = mp_copy(R, ret);
17552
        done = 1;
17553
      }
17554
17555
      if (done == 0) {
17556
        /* t1 = 2 ^ (M - i - 1) */
17557
        if (res == MP_OKAY)
17558
          res = mp_sub_d(M, i, t1);
17559
        if (res == MP_OKAY)
17560
          res = mp_sub_d(t1, 1, t1);
17561
        if (res == MP_OKAY)
17562
          res = mp_exptmod(two, t1, prime, t1);
17563
17564
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
17565
        if (res == MP_OKAY)
17566
          res = mp_exptmod(C, t1, prime, t1);
17567
17568
        /* C = (t1 * t1) mod prime */
17569
        if (res == MP_OKAY)
17570
          res = mp_sqrmod(t1, prime, C);
17571
17572
        /* R = (R * t1) mod prime */
17573
        if (res == MP_OKAY)
17574
          res = mp_mulmod(R, t1, prime, R);
17575
17576
        /* T = (T * C) mod prime */
17577
        if (res == MP_OKAY)
17578
          res = mp_mulmod(T, C, prime, T);
17579
17580
        /* M = i */
17581
        if (res == MP_OKAY)
17582
          res = mp_set(M, i);
17583
      }
17584
    }
17585
  }
17586
17587
  out:
17588
17589
#ifdef WOLFSSL_SMALL_STACK
17590
  if (t1) {
17591
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17592
      mp_clear(t1);
17593
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17594
  }
17595
  if (C) {
17596
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17597
      mp_clear(C);
17598
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17599
  }
17600
  if (Q) {
17601
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17602
      mp_clear(Q);
17603
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17604
  }
17605
  if (S) {
17606
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17607
      mp_clear(S);
17608
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17609
  }
17610
  if (Z) {
17611
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17612
      mp_clear(Z);
17613
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17614
  }
17615
  if (M) {
17616
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17617
      mp_clear(M);
17618
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17619
  }
17620
  if (T) {
17621
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17622
      mp_clear(T);
17623
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17624
  }
17625
  if (R) {
17626
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17627
      mp_clear(R);
17628
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17629
  }
17630
  if (N) {
17631
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17632
      mp_clear(N);
17633
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17634
  }
17635
  if (two) {
17636
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
17637
      mp_clear(two);
17638
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
17639
  }
17640
#else
17641
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
17642
    mp_clear(t1);
17643
    mp_clear(C);
17644
    mp_clear(Q);
17645
    mp_clear(S);
17646
    mp_clear(Z);
17647
    mp_clear(M);
17648
    mp_clear(T);
17649
    mp_clear(R);
17650
    mp_clear(N);
17651
    mp_clear(two);
17652
  }
17653
#endif
17654
17655
  return res;
17656
#endif
17657
}
17658
#endif /* !WOLFSSL_SP_MATH */
17659
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A */
17660
17661
#ifdef HAVE_ECC_KEY_EXPORT
17662
/* export public ECC key in ANSI X9.63 format compressed */
17663
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
17664
{
17665
   word32 numlen;
17666
   int    ret = MP_OKAY;
17667
17668
   if (key == NULL || outLen == NULL)
17669
       return BAD_FUNC_ARG;
17670
17671
   if (key->type == ECC_PRIVATEKEY_ONLY)
17672
       return ECC_PRIVATEONLY_E;
17673
17674
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
17675
       return ECC_BAD_ARG_E;
17676
   }
17677
17678
   numlen = (word32)key->dp->size;
17679
17680
   if (*outLen < (1 + numlen)) {
17681
      *outLen = 1 + numlen;
17682
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
17683
   }
17684
17685
   if (out == NULL)
17686
       return BAD_FUNC_ARG;
17687
17688
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
17689
       return ECC_BAD_ARG_E;
17690
17691
   /* store first byte */
17692
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
17693
17694
   /* pad and store x */
17695
   XMEMSET(out+1, 0, numlen);
17696
   ret = mp_to_unsigned_bin(
17697
       key->pubkey.x,
17698
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
17699
   *outLen = 1 + numlen;
17700
17701
   return ret;
17702
}
17703
#endif /* HAVE_ECC_KEY_EXPORT */
17704
#endif /* HAVE_COMP_KEY */
17705
17706
#ifdef HAVE_OID_ENCODING
17707
int wc_ecc_oid_cache_init(void)
17708
{
17709
    int ret = 0;
17710
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
17711
    ret = wc_local_InitMutexOnce(&ecc_oid_cache_lock, &eccOidLockInit);
17712
#endif
17713
    return ret;
17714
}
17715
17716
void wc_ecc_oid_cache_free(void)
17717
{
17718
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
17719
    wc_FreeMutex(&ecc_oid_cache_lock);
17720
    WOLFSSL_ATOMIC_STORE(eccOidLockInit, 0);
17721
#endif
17722
}
17723
#endif /* HAVE_OID_ENCODING */
17724
17725
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
17726
0
{
17727
0
    int x;
17728
0
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
17729
#ifdef HAVE_OID_ENCODING
17730
    oid_cache_t* o = NULL;
17731
#endif
17732
17733
0
    if (oidSum == 0) {
17734
0
        return BAD_FUNC_ARG;
17735
0
    }
17736
17737
#ifdef HAVE_OID_ENCODING
17738
    #ifndef WOLFSSL_MUTEX_INITIALIZER
17739
        /* extra sanity check if wolfCrypt_Init not called */
17740
        if (wc_local_InitMutexOnce(&ecc_oid_cache_lock,
17741
                &eccOidLockInit) != 0) {
17742
            return BAD_MUTEX_E;
17743
        }
17744
    #endif
17745
17746
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
17747
        return BAD_MUTEX_E;
17748
    }
17749
#endif
17750
17751
    /* find matching OID sum (based on encoded value) */
17752
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
17753
0
        if (ecc_sets[x].oidSum == oidSum) {
17754
        #ifdef HAVE_OID_ENCODING
17755
            /* check cache */
17756
            ret = 0;
17757
            o = &ecc_oid_cache[x];
17758
            if (o->oidSz == 0) {
17759
                o->oidSz = sizeof(o->oid);
17760
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
17761
                                                            o->oid, &o->oidSz);
17762
            }
17763
            if (oidSz) {
17764
                *oidSz = o->oidSz;
17765
            }
17766
            if (oid) {
17767
                *oid = o->oid;
17768
            }
17769
17770
            /* on success return curve id */
17771
            if (ret == 0) {
17772
                ret = ecc_sets[x].id;
17773
            }
17774
            break;
17775
        #else
17776
0
            if (oidSz) {
17777
0
                *oidSz = ecc_sets[x].oidSz;
17778
0
            }
17779
0
            if (oid) {
17780
0
                *oid = ecc_sets[x].oid;
17781
0
            }
17782
0
            ret = ecc_sets[x].id;
17783
0
            break;
17784
0
        #endif
17785
0
        }
17786
0
    }
17787
17788
#ifdef HAVE_OID_ENCODING
17789
    wc_UnLockMutex(&ecc_oid_cache_lock);
17790
#endif
17791
17792
0
    return ret;
17793
0
}
17794
17795
#ifdef WOLFSSL_CUSTOM_CURVES
17796
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
17797
{
17798
    if (key == NULL || dp == NULL) {
17799
        return BAD_FUNC_ARG;
17800
    }
17801
    /* Curve size must fit the fixed size buffers in the ECC code. */
17802
    if ((dp->size <= 0) || (dp->size > MAX_ECC_BYTES)) {
17803
        return ECC_BAD_ARG_E;
17804
    }
17805
17806
    key->idx = ECC_CUSTOM_IDX;
17807
    key->dp = dp;
17808
17809
    return 0;
17810
}
17811
#endif /* WOLFSSL_CUSTOM_CURVES */
17812
17813
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
17814
17815
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
17816
{
17817
    int i;
17818
17819
    /* in network byte order so start at end and work back */
17820
    for (i = 3; i >= 0; i--) {
17821
        if (++inOutCtr[i])  /* we're done unless we overflow */
17822
            return;
17823
    }
17824
}
17825
17826
/* ASN X9.63 Key Derivation Function (SEC1) */
17827
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
17828
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
17829
{
17830
    int ret;
17831
    word32 digestSz, copySz, remaining = outSz;
17832
    byte* outIdx;
17833
    byte  counter[4];
17834
    byte  tmp[WC_MAX_DIGEST_SIZE];
17835
17836
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
17837
17838
    if (secret == NULL || secretSz == 0 || out == NULL)
17839
        return BAD_FUNC_ARG;
17840
17841
    /* X9.63 allowed algos only */
17842
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
17843
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
17844
        type != WC_HASH_TYPE_SHA512)
17845
        return BAD_FUNC_ARG;
17846
17847
    ret = wc_HashGetDigestSize(type);
17848
    if (ret < 0)
17849
        return ret;
17850
    digestSz = (word32)ret;
17851
17852
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
17853
        return MEMORY_E);
17854
17855
    ret = wc_HashInit(hash, type);
17856
    if (ret != 0) {
17857
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17858
        return ret;
17859
    }
17860
17861
    outIdx = out;
17862
    XMEMSET(counter, 0, sizeof(counter));
17863
17864
    while (remaining > 0) {
17865
17866
        IncrementX963KdfCounter(counter);
17867
17868
        ret = wc_HashUpdate(hash, type, secret, secretSz);
17869
        if (ret != 0) {
17870
            break;
17871
        }
17872
17873
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
17874
        if (ret != 0) {
17875
            break;
17876
        }
17877
17878
        if (sinfo) {
17879
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
17880
            if (ret != 0) {
17881
                break;
17882
            }
17883
        }
17884
17885
        ret = wc_HashFinal(hash, type, tmp);
17886
        if (ret != 0) {
17887
            break;
17888
        }
17889
17890
        copySz = min(remaining, digestSz);
17891
        XMEMCPY(outIdx, tmp, copySz);
17892
17893
        remaining -= copySz;
17894
        outIdx += copySz;
17895
    }
17896
17897
    wc_HashFree(hash, type);
17898
17899
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17900
17901
    return ret;
17902
}
17903
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
17904
17905
#ifdef WOLFSSL_SE050
17906
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
17907
 * keyId is a word32, can be used for key IDs larger than an int.
17908
 *
17909
 * key    initialized ecc_key struct
17910
 * keyId  hardware key ID which stores ECC key
17911
 * flags  optional flags, currently unused
17912
 *
17913
 * Return 0 on success, negative on error */
17914
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
17915
{
17916
    (void)flags;
17917
17918
    if (key == NULL) {
17919
        return BAD_FUNC_ARG;
17920
    }
17921
17922
    return se050_ecc_use_key_id(key, keyId);
17923
}
17924
17925
/* Get hardware key ID associated with this ecc_key structure.
17926
 *
17927
 * key    initialized ecc_key struct
17928
 * keyId  [OUT] output for key ID associated with this structure
17929
 *
17930
 * Returns 0 on success, negative on error.
17931
 */
17932
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
17933
{
17934
    if (key == NULL || keyId == NULL) {
17935
        return BAD_FUNC_ARG;
17936
    }
17937
17938
    return se050_ecc_get_key_id(key, keyId);
17939
}
17940
#endif /* WOLFSSL_SE050 */
17941
17942
17943
#ifdef WC_ECC_NONBLOCK
17944
/* Enable ECC support for non-blocking operations */
17945
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
17946
{
17947
    if (key == NULL) {
17948
        return BAD_FUNC_ARG;
17949
    }
17950
    /* If a different context is already set, clear it before replacing.
17951
     * The caller is responsible for freeing any heap-allocated context. */
17952
    if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
17953
        XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
17954
    }
17955
    if (ctx != NULL) {
17956
        XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
17957
    }
17958
    key->nb_ctx = ctx;
17959
    return 0;
17960
}
17961
#endif /* WC_ECC_NONBLOCK */
17962
17963
#endif /* HAVE_ECC */