Coverage Report

Created: 2026-08-14 06:23

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
#undef WOLFSSL_SMALL_STACK
29
#undef WOLFSSL_SMALL_STACK_CACHE
30
#endif
31
32
/*
33
Possible ECC enable options:
34
 * HAVE_ECC:            Overall control of ECC                  default: on
35
 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
36
 * HAVE_ECC_SIGN:       ECC sign                                default: on
37
 * HAVE_ECC_VERIFY:     ECC verify                              default: on
38
 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
39
 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
40
 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
41
 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
42
 * ECC_SHAMIR:          Enables Shamir calc method              default: on
43
 * HAVE_COMP_KEY:       Enables compressed key                  default: off
44
 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
45
 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
46
 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
47
 *                        Includes the curve "a" variable in calculation
48
 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
49
 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
50
 *                                                              default: off
51
 * FP_ECC:              ECC Fixed Point Cache                   default: off
52
 *                      FP cache is not supported for SECP160R1, SECP160R2,
53
 *                      SECP160K1 and SECP224K1. These do not work with scalars
54
 *                      that are the length of the order when the order is
55
 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
56
 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
57
 *                      For the ECC curve parameters `ecc_set_type` use fixed
58
 *                      array for hex string
59
 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify/keygen/secret.
60
 *                      Requires SP with WOLFSSL_SP_NONBLOCK
61
 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
62
 *                      normal blocking API's
63
 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
64
 *                      signing. If the value is invalid, a new random 'k' is
65
 *                      generated in the loop. (For testing)
66
 *                                                              default: off
67
 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
68
 *                      Enables the setting of the 'k' value to use during ECDSA
69
 *                      signing. If the value is invalid then an error is
70
 *                      returned rather than generating a new 'k'. (For testing)
71
 *                                                              default: off
72
 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
73
 *                      deterministic ECC signatures. The following function
74
 *                      can be used to set the deterministic signing flag in the
75
 *                      ecc key structure.
76
 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
77
 *                                                              default: off
78
 *
79
 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
80
 *                      hash directly instead of doing bits2octets(H(m)), when
81
 *                      the variant macro is used the bits2octets operation on
82
 *                      the hash is removed.
83
 *                                                              default: off
84
 *
85
 * WC_PROTECT_ENCRYPTED_MEM:
86
 *                      Enables implementations that protect data that is in
87
 *                      encrypted memory.
88
 *                                                              default: off
89
 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
90
 *                      Enables generation of scalar (private key and ECDSA
91
 *                      nonce) to be performed using reject sampling algorithm.
92
 *                      Use this when CPU state can be closely observed by
93
 *                      attacker.
94
 *                                                              default: off
95
 * WOLFSSL_ECC_BLIND_K
96
 *                      Blind the private key k by using a random mask.
97
 *                      The private key is never stored unprotected but an
98
 *                      unmasked copy is computed and stored each time it is
99
 *                      needed.
100
 *                                                              default: off
101
 * WOLFSSL_CHECK_VER_FAULTS
102
 *                      Sanity check on verification steps in case of faults.
103
 *                                                              default: off
104
 * ECC_TIMING_RESISTANT: Enables constant-time ECC operations   default: on
105
 *                      to prevent timing side-channel attacks.
106
 *                      Auto-enabled for FIPS and some embedded builds.
107
 * WC_NO_CACHE_RESISTANT: Disables cache-resistant operations   default: off
108
 *                      (conditional swaps) in ECC scalar multiply to
109
 *                      reduce overhead. Not recommended for secure use.
110
 * ALT_ECC_SIZE:        Uses alternate smaller fixed-size arrays default: off
111
 *                      for ECC points instead of full mp_int arrays,
112
 *                      reducing memory. Requires USE_FAST_MATH.
113
 * WOLFSSL_ECC_NO_SMALL_STACK: Disables WOLFSSL_SMALL_STACK     default: off
114
 *                      optimizations for ECC, using stack instead of heap.
115
 * HAVE_ECC_CHECK_PUBKEY_ORDER: Validates ECC public key order  default: on
116
 *                      during import. Auto-enabled unless
117
 *                      NO_ECC_CHECK_PUBKEY_ORDER is defined.
118
 * NO_ECC_CHECK_PUBKEY_ORDER: Disables public key order check   default: off
119
 *                      during ECC key import. Not recommended.
120
 * HAVE_ECC_MAKE_PUB:   Enables computing public key from       default: on
121
 *                      private key via wc_ecc_make_pub.
122
 * HAVE_ECC_VERIFY_HELPER: Enables ECC verify helper functions  default: on
123
 *                      Auto-enabled unless using hardware accelerators.
124
 * WOLFSSL_PUBLIC_ECC_ADD_DBL: Makes ecc_projective_add_point   default: off
125
 *                      and ecc_projective_dbl_point public APIs.
126
 * SQRTMOD_USE_MOD_EXP: Computes square root mod prime using    default: off
127
 *                      modular exponentiation instead of Jacobi method
128
 *                      for compressed key decompression.
129
 *
130
 * ECIES options:
131
 * WOLFSSL_ECIES_OLD:   Uses original wolfSSL ECIES format      default: off
132
 *                      (public key not in shared secret material).
133
 * WOLFSSL_ECIES_ISO18033: Uses ISO 18033 ECIES standard        default: off
134
 *                      (includes public key in shared secret).
135
 * WOLFSSL_ECIES_GEN_IV: Generates random IV for ECIES          default: off
136
 *                      encryption instead of deriving from KDF.
137
 * WOLFSSL_ECIES_STATIC_GCM_NONCE:                              default: off
138
 *                      Allows the AES-GCM DEM in the default IV mode, where the
139
 *                      GCM nonce is a fixed all-zero value that is not sent.
140
 *                      This is ONLY safe because ECIES derives a fresh key from
141
 *                      a fresh ephemeral key each message, so the (key, nonce)
142
 *                      pair never repeats.  Reusing the ephemeral key would
143
 *                      reuse both the key and the nonce - catastrophic for GCM.
144
 *                      Off by default: without this define, the GCM DEM returns
145
 *                      NOT_COMPILED_IN in the default IV mode so the fixed nonce
146
 *                      cannot be selected by accident.  Not needed with
147
 *                      WOLFSSL_ECIES_GEN_IV (random nonce) or WOLFSSL_ECIES_OLD
148
 *                      (KDF-derived nonce).
149
 *
150
 * Fixed Point Cache options (requires FP_ECC):
151
 * FP_ENTRIES:          Number of FP cache entries               default: 15
152
 * FP_LUT:              FP lookup table bit size (2-12). Larger  default: 8
153
 *                      values use more memory but faster verify.
154
 * FP_ECC_CONTROL:      Auto-selects cached FP ECC verify with  default: on
155
 *                      SP when WOLFSSL_HAVE_SP_ECC is available.
156
 *
157
 * SP Math ECC options:
158
 * WOLFSSL_HAVE_SP_ECC: Enables SP math optimizations for ECC   default: on
159
 *                      Provides significant performance improvement.
160
 * WOLFSSL_SP_NO_256:   Disables SP P-256 support               default: off
161
 * WOLFSSL_SP_384:      Enables SP P-384 support                default: off
162
 * WOLFSSL_SP_521:      Enables SP P-521 support                default: off
163
 * WOLFSSL_SP_1024:     Enables SP 1024-bit support for SAKKE   default: off
164
 * WOLFSSL_SP_SM2:      Enables SP SM2 curve support            default: off
165
 *                      Auto-enabled with WOLFSSL_SM2.
166
 *
167
 * Hardware/Offload options:
168
 * WOLFSSL_KCAPI_ECC:   Offload ECC to Linux Kernel Crypto API  default: off
169
 * WC_ASYNC_ENABLE_ECC: Enables async ECC with crypto callbacks default: off
170
 *                      Requires WOLFSSL_ASYNC_CRYPT.
171
 * WC_ASYNC_ENABLE_ECC_KEYGEN: Enables async ECC key gen        default: off
172
 * PLUTON_CRYPTO_ECC:   Uses ARM Pluton TEE for ECC operations  default: off
173
 * WOLFSSL_CAAM_BLACK_KEY_SM: Uses NXP CAAM secure memory for   default: off
174
 *                      encrypted black key storage.
175
 */
176
177
/*
178
ECC Curve Types:
179
 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
180
 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
181
 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
182
 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
183
 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
184
 * WOLFSSL_SM2          Enables SM2 curves                      default: off
185
 */
186
187
/*
188
ECC Curve Sizes:
189
 * ECC_USER_CURVES: Allows custom combination of key sizes below
190
 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
191
 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
192
 * HAVE_ECC112: 112 bit key
193
 * HAVE_ECC128: 128 bit key
194
 * HAVE_ECC160: 160 bit key
195
 * HAVE_ECC192: 192 bit key
196
 * HAVE_ECC224: 224 bit key
197
 * HAVE_ECC239: 239 bit key
198
 * NO_ECC256: Disables 256 bit key (on by default)
199
 * HAVE_ECC320: 320 bit key
200
 * HAVE_ECC384: 384 bit key
201
 * HAVE_ECC512: 512 bit key
202
 * HAVE_ECC521: 521 bit key
203
 */
204
205
206
#ifdef HAVE_ECC
207
208
/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
209
#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
210
    !defined(WOLFSSL_CUSTOM_CURVES)
211
    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
212
#endif
213
214
#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
215
    #ifdef USE_WINDOWS_API
216
        #pragma code_seg(".fipsA$f")
217
        #pragma const_seg(".fipsB$f")
218
    #endif
219
#endif
220
221
/* public ASN interface */
222
#include <wolfssl/wolfcrypt/asn_public.h>
223
224
#include <wolfssl/wolfcrypt/ecc.h>
225
#include <wolfssl/wolfcrypt/asn.h>
226
#include <wolfssl/wolfcrypt/hash.h>
227
228
#ifdef WOLFSSL_HAVE_SP_ECC
229
#include <wolfssl/wolfcrypt/sp.h>
230
#endif
231
232
#ifdef HAVE_ECC_ENCRYPT
233
    #include <wolfssl/wolfcrypt/kdf.h>
234
235
    /* For wc_AesGcmEncrypt() wrapper, if needed. */
236
    #include <wolfssl/wolfcrypt/wc_compat.h>
237
238
    #include <wolfssl/wolfcrypt/aes.h>
239
#endif
240
241
#ifdef WOLF_CRYPTO_CB
242
    #include <wolfssl/wolfcrypt/cryptocb.h>
243
#endif
244
245
#ifdef NO_INLINE
246
    #include <wolfssl/wolfcrypt/misc.h>
247
#else
248
    #define WOLFSSL_MISC_INCLUDED
249
    #include <wolfcrypt/src/misc.c>
250
#endif
251
252
#if FIPS_VERSION3_GE(6,0,0)
253
    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
254
                                                     { 0x1a2b3c4d, 0x00000005 };
255
    int wolfCrypt_FIPS_ECC_sanity(void)
256
    {
257
        return 0;
258
    }
259
#endif
260
261
#if defined(FREESCALE_LTC_ECC)
262
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
263
#endif
264
265
#if defined(WOLFSSL_STM32_PKA) || defined(WOLFSSL_STM32_CCB)
266
    /* CCB without PKA still needs stm32.h so its consistency #errors (e.g. CCB
267
     * requires DHUK + BARE/CUBEMX) are visible to this translation unit. */
268
    #include <wolfssl/wolfcrypt/port/st/stm32.h>
269
#endif
270
271
#if defined(WOLFSSL_PSOC6_CRYPTO)
272
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
273
#endif
274
275
#if defined(WOLFSSL_CAAM)
276
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
277
#endif
278
279
#if defined(WOLFSSL_KCAPI_ECC)
280
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
281
#endif
282
283
#ifdef WOLFSSL_SE050
284
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
285
#endif
286
287
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
288
    #include <xsecure_ellipticclient.h>
289
#endif
290
291
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
292
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
293
    #include <wolfssl/wolfcrypt/hmac.h>
294
#endif
295
296
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
297
    !defined(WOLFSSL_MICROCHIP_TA100) && \
298
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
299
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
300
    !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && \
301
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
302
    !defined(WOLFSSL_PSOC6_CRYPTO)
303
    /* STM32 sign-only (e.g. C5): the HW PKA cannot run the integrated ECDSA
304
     * verify (mode 0x26) correctly, so use the SW verify helper rather than the
305
     * HW-accelerator sigRS path. Note the helper's scalar multiplications still
306
     * run on the HW PKA generic-mul (stm32.c provides wc_ecc_mulmod_ex under
307
     * !WC_STM32_PKA_VERIFY_ONLY) -- the C5 issue is specifically the verify-mode
308
     * wrapper, not the point math, which is exercised and correct (the lead for
309
     * a future real HW verify). */
310
    #undef  HAVE_ECC_VERIFY_HELPER
311
    #define HAVE_ECC_VERIFY_HELPER
312
#endif
313
/* Compile in the software verify helper whenever SE050 hardware ECDSA verify is
314
 * bypassed:
315
 *  - WOLFSSL_SE050_NO_ECDSA_VERIFY disables SE050 ECDSA verify outright.
316
 *  - WOLFSSL_SE050_ONLY_KEY_ID verifies software keys (keyIdSet == 0) in
317
 *    wolfCrypt; the SE050 is used at runtime only for keys resident in HW. */
318
#if (defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) || \
319
     (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID))) && \
320
    defined(HAVE_ECC_VERIFY)
321
    #define HAVE_ECC_VERIFY_HELPER
322
#endif
323
324
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
325
        !defined(WOLFSSL_MICROCHIP_TA100) && \
326
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
327
    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB)
328
    #undef  HAVE_ECC_MAKE_PUB
329
    #define HAVE_ECC_MAKE_PUB
330
#endif
331
332
333
/* macro guard for ecc_check_pubkey_order functionality */
334
#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
335
     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
336
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
337
     !defined(WOLFSSL_MICROCHIP_TA100) && \
338
     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
339
     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
340
     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
341
342
    /* CAAM builds use public key validation as a means to check if an
343
     * imported private key is an encrypted black key or not */
344
    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
345
    #define HAVE_ECC_CHECK_PUBKEY_ORDER
346
#endif
347
348
#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
349
#define MAX_ECC_BITS_USE    SP_INT_BITS
350
#else
351
#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
352
#endif
353
354
#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
355
    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
356
357
#define ECC_KEY_MAX_BITS(key)                                       \
358
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
359
        ((unsigned)((key)->dp->size * 8)))
360
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
361
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
362
        ((unsigned)((key)->dp->size * 8)))
363
364
#else
365
366
/* Add one bit for cases when order is a bit greater than prime. */
367
#define ECC_KEY_MAX_BITS(key)                                       \
368
    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
369
        ((unsigned)((key)->dp->size * 8 + 1)))
370
#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
371
    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
372
        ((unsigned)((key)->dp->size * 8 + 1)))
373
374
#endif
375
376
#ifdef WOLFSSL_ECC_BLIND_K
377
mp_int* ecc_get_k(ecc_key* key)
378
{
379
    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
380
    return key->ku;
381
}
382
void ecc_blind_k(ecc_key* key, mp_int* b)
383
{
384
    mp_xor_ct(key->k, b, key->dp->size, key->k);
385
    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
386
}
387
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
388
{
389
    int ret = 0;
390
    WC_RNG local_rng;
391
392
#ifdef ECC_TIMING_RESISTANT
393
    if (rng == NULL) {
394
        rng = key->rng;
395
    }
396
#endif
397
    if (rng == NULL) {
398
        ret = wc_InitRng(&local_rng);
399
        if (ret == 0) {
400
            rng = &local_rng;
401
        }
402
    }
403
    if (ret == 0) {
404
        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
405
            sizeof(mp_digit), rng);
406
        if (ret == 0) {
407
            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
408
        }
409
    }
410
411
    if (rng == &local_rng) {
412
        wc_FreeRng(&local_rng);
413
    }
414
    return ret;
415
}
416
417
mp_int* wc_ecc_key_get_priv(ecc_key* key)
418
{
419
    return ecc_get_k(key);
420
}
421
#endif
422
423
/* forward declarations */
424
static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
425
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
426
#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
427
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
428
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
429
#endif
430
431
/* internal ECC states */
432
enum {
433
    ECC_STATE_NONE = 0,
434
435
    ECC_STATE_SHARED_SEC_GEN,
436
    ECC_STATE_SHARED_SEC_RES,
437
438
    ECC_STATE_SIGN_DO,
439
    ECC_STATE_SIGN_ENCODE,
440
441
    ECC_STATE_VERIFY_DECODE,
442
    ECC_STATE_VERIFY_DO,
443
    ECC_STATE_VERIFY_RES
444
};
445
446
447
/* map
448
   ptmul -> mulmod
449
*/
450
451
/* 256-bit curve on by default whether user curves or not */
452
#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
453
    #define ECC112
454
#endif
455
#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
456
    #define ECC128
457
#endif
458
#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
459
    #define ECC160
460
#endif
461
#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
462
    #define ECC192
463
#endif
464
#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
465
    #define ECC224
466
#endif
467
#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
468
    #define ECC239
469
#endif
470
#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
471
    #define ECC256
472
#endif
473
#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
474
    #define ECC320
475
#endif
476
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
477
    #define ECC384
478
#endif
479
#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
480
    #define ECC512
481
#endif
482
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
483
    #define ECC521
484
#endif
485
486
/* The encoded OID's for ECC curves */
487
#ifdef ECC112
488
    #ifndef NO_ECC_SECP
489
        #ifdef HAVE_OID_ENCODING
490
            #define CODED_SECP112R1    {1,3,132,0,6}
491
            #define CODED_SECP112R1_SZ 5
492
        #else
493
            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
494
            #define CODED_SECP112R1_SZ 5
495
        #endif
496
        #ifndef WOLFSSL_ECC_CURVE_STATIC
497
            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
498
        #else
499
            #define ecc_oid_secp112r1 CODED_SECP112R1
500
        #endif
501
        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
502
    #endif /* !NO_ECC_SECP */
503
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
504
        #ifdef HAVE_OID_ENCODING
505
            #define CODED_SECP112R2    {1,3,132,0,7}
506
            #define CODED_SECP112R2_SZ 5
507
        #else
508
            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
509
            #define CODED_SECP112R2_SZ 5
510
        #endif
511
        #ifndef WOLFSSL_ECC_CURVE_STATIC
512
            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
513
        #else
514
            #define ecc_oid_secp112r2 CODED_SECP112R2
515
        #endif
516
        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
517
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
518
#endif /* ECC112 */
519
#ifdef ECC128
520
    #ifndef NO_ECC_SECP
521
        #ifdef HAVE_OID_ENCODING
522
            #define CODED_SECP128R1    {1,3,132,0,28}
523
            #define CODED_SECP128R1_SZ 5
524
        #else
525
            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
526
            #define CODED_SECP128R1_SZ 5
527
        #endif
528
        #ifndef WOLFSSL_ECC_CURVE_STATIC
529
            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
530
        #else
531
            #define ecc_oid_secp128r1 CODED_SECP128R1
532
        #endif
533
        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
534
    #endif /* !NO_ECC_SECP */
535
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
536
        #ifdef HAVE_OID_ENCODING
537
            #define CODED_SECP128R2    {1,3,132,0,29}
538
            #define CODED_SECP128R2_SZ 5
539
        #else
540
            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
541
            #define CODED_SECP128R2_SZ 5
542
        #endif
543
        #ifndef WOLFSSL_ECC_CURVE_STATIC
544
            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
545
        #else
546
            #define ecc_oid_secp128r2 CODED_SECP128R2
547
        #endif
548
        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
549
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
550
#endif /* ECC128 */
551
#ifdef ECC160
552
#ifndef FP_ECC
553
    #ifndef NO_ECC_SECP
554
        #ifdef HAVE_OID_ENCODING
555
            #define CODED_SECP160R1    {1,3,132,0,8}
556
            #define CODED_SECP160R1_SZ 5
557
        #else
558
            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
559
            #define CODED_SECP160R1_SZ 5
560
        #endif
561
        #ifndef WOLFSSL_ECC_CURVE_STATIC
562
            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
563
        #else
564
            #define ecc_oid_secp160r1 CODED_SECP160R1
565
        #endif
566
        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
567
    #endif /* !NO_ECC_SECP */
568
    #ifdef HAVE_ECC_SECPR2
569
        #ifdef HAVE_OID_ENCODING
570
            #define CODED_SECP160R2    {1,3,132,0,30}
571
            #define CODED_SECP160R2_SZ 5
572
        #else
573
            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
574
            #define CODED_SECP160R2_SZ 5
575
        #endif
576
        #ifndef WOLFSSL_ECC_CURVE_STATIC
577
            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
578
        #else
579
            #define ecc_oid_secp160r2 CODED_SECP160R2
580
        #endif
581
        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
582
    #endif /* HAVE_ECC_SECPR2 */
583
    #ifdef HAVE_ECC_KOBLITZ
584
        #ifdef HAVE_OID_ENCODING
585
            #define CODED_SECP160K1    {1,3,132,0,9}
586
            #define CODED_SECP160K1_SZ 5
587
        #else
588
            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
589
            #define CODED_SECP160K1_SZ 5
590
        #endif
591
        #ifndef WOLFSSL_ECC_CURVE_STATIC
592
            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
593
        #else
594
            #define ecc_oid_secp160k1 CODED_SECP160K1
595
        #endif
596
        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
597
    #endif /* HAVE_ECC_KOBLITZ */
598
#endif /* !FP_ECC */
599
    #ifdef HAVE_ECC_BRAINPOOL
600
        #ifdef HAVE_OID_ENCODING
601
            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
602
            #define CODED_BRAINPOOLP160R1_SZ 10
603
        #else
604
            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
605
            #define CODED_BRAINPOOLP160R1_SZ 9
606
        #endif
607
        #ifndef WOLFSSL_ECC_CURVE_STATIC
608
            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
609
        #else
610
            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
611
        #endif
612
        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
613
    #endif /* HAVE_ECC_BRAINPOOL */
614
#endif /* ECC160 */
615
#ifdef ECC192
616
    #ifndef NO_ECC_SECP
617
        #ifdef HAVE_OID_ENCODING
618
            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
619
            #define CODED_SECP192R1_SZ 7
620
        #else
621
            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
622
            #define CODED_SECP192R1_SZ 8
623
        #endif
624
        #ifndef WOLFSSL_ECC_CURVE_STATIC
625
            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
626
        #else
627
            #define ecc_oid_secp192r1 CODED_SECP192R1
628
        #endif
629
        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
630
    #endif /* !NO_ECC_SECP */
631
    #ifdef HAVE_ECC_SECPR2
632
        #ifdef HAVE_OID_ENCODING
633
            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
634
            #define CODED_PRIME192V2_SZ 7
635
        #else
636
            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
637
            #define CODED_PRIME192V2_SZ 8
638
        #endif
639
        #ifndef WOLFSSL_ECC_CURVE_STATIC
640
            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
641
        #else
642
            #define ecc_oid_prime192v2 CODED_PRIME192V2
643
        #endif
644
        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
645
    #endif /* HAVE_ECC_SECPR2 */
646
    #ifdef HAVE_ECC_SECPR3
647
        #ifdef HAVE_OID_ENCODING
648
            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
649
            #define CODED_PRIME192V3_SZ 7
650
        #else
651
            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
652
            #define CODED_PRIME192V3_SZ 8
653
        #endif
654
        #ifndef WOLFSSL_ECC_CURVE_STATIC
655
            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
656
        #else
657
            #define ecc_oid_prime192v3 CODED_PRIME192V3
658
        #endif
659
        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
660
    #endif /* HAVE_ECC_SECPR3 */
661
    #ifdef HAVE_ECC_KOBLITZ
662
        #ifdef HAVE_OID_ENCODING
663
            #define CODED_SECP192K1    {1,3,132,0,31}
664
            #define CODED_SECP192K1_SZ 5
665
        #else
666
            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
667
            #define CODED_SECP192K1_SZ 5
668
        #endif
669
        #ifndef WOLFSSL_ECC_CURVE_STATIC
670
            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
671
        #else
672
            #define ecc_oid_secp192k1 CODED_SECP192K1
673
        #endif
674
        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
675
    #endif /* HAVE_ECC_KOBLITZ */
676
    #ifdef HAVE_ECC_BRAINPOOL
677
        #ifdef HAVE_OID_ENCODING
678
            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
679
            #define CODED_BRAINPOOLP192R1_SZ 10
680
        #else
681
            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
682
            #define CODED_BRAINPOOLP192R1_SZ 9
683
        #endif
684
        #ifndef WOLFSSL_ECC_CURVE_STATIC
685
            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
686
        #else
687
            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
688
        #endif
689
        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
690
    #endif /* HAVE_ECC_BRAINPOOL */
691
#endif /* ECC192 */
692
#ifdef ECC224
693
    #ifndef NO_ECC_SECP
694
        #ifdef HAVE_OID_ENCODING
695
            #define CODED_SECP224R1    {1,3,132,0,33}
696
            #define CODED_SECP224R1_SZ 5
697
        #else
698
            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
699
            #define CODED_SECP224R1_SZ 5
700
        #endif
701
        #ifndef WOLFSSL_ECC_CURVE_STATIC
702
            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
703
        #else
704
            #define ecc_oid_secp224r1 CODED_SECP224R1
705
        #endif
706
        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
707
    #endif /* !NO_ECC_SECP */
708
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
709
        #ifdef HAVE_OID_ENCODING
710
            #define CODED_SECP224K1    {1,3,132,0,32}
711
            #define CODED_SECP224K1_SZ 5
712
        #else
713
            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
714
            #define CODED_SECP224K1_SZ 5
715
        #endif
716
        #ifndef WOLFSSL_ECC_CURVE_STATIC
717
            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
718
        #else
719
            #define ecc_oid_secp224k1 CODED_SECP224K1
720
        #endif
721
        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
722
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
723
    #ifdef HAVE_ECC_BRAINPOOL
724
        #ifdef HAVE_OID_ENCODING
725
            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
726
            #define CODED_BRAINPOOLP224R1_SZ 10
727
        #else
728
            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
729
            #define CODED_BRAINPOOLP224R1_SZ 9
730
        #endif
731
        #ifndef WOLFSSL_ECC_CURVE_STATIC
732
            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
733
        #else
734
            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
735
        #endif
736
        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
737
    #endif /* HAVE_ECC_BRAINPOOL */
738
#endif /* ECC224 */
739
#ifdef ECC239
740
    #ifndef NO_ECC_SECP
741
        #ifdef HAVE_OID_ENCODING
742
            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
743
            #define CODED_PRIME239V1_SZ 7
744
        #else
745
            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
746
            #define CODED_PRIME239V1_SZ 8
747
        #endif
748
        #ifndef WOLFSSL_ECC_CURVE_STATIC
749
            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
750
        #else
751
            #define ecc_oid_prime239v1 CODED_PRIME239V1
752
        #endif
753
        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
754
    #endif /* !NO_ECC_SECP */
755
    #ifdef HAVE_ECC_SECPR2
756
        #ifdef HAVE_OID_ENCODING
757
            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
758
            #define CODED_PRIME239V2_SZ 7
759
        #else
760
            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
761
            #define CODED_PRIME239V2_SZ 8
762
        #endif
763
        #ifndef WOLFSSL_ECC_CURVE_STATIC
764
            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
765
        #else
766
            #define ecc_oid_prime239v2 CODED_PRIME239V2
767
        #endif
768
        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
769
    #endif /* HAVE_ECC_SECPR2 */
770
    #ifdef HAVE_ECC_SECPR3
771
        #ifdef HAVE_OID_ENCODING
772
            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
773
            #define CODED_PRIME239V3_SZ 7
774
        #else
775
            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
776
            #define CODED_PRIME239V3_SZ 8
777
        #endif
778
        #ifndef WOLFSSL_ECC_CURVE_STATIC
779
            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
780
        #else
781
            #define ecc_oid_prime239v3 CODED_PRIME239V3
782
        #endif
783
        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
784
    #endif /* HAVE_ECC_SECPR3 */
785
#endif /* ECC239 */
786
#ifdef ECC256
787
    #ifndef NO_ECC_SECP
788
        #ifdef HAVE_OID_ENCODING
789
            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
790
            #define CODED_SECP256R1_SZ 7
791
        #else
792
            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
793
            #define CODED_SECP256R1_SZ 8
794
        #endif
795
        #ifndef WOLFSSL_ECC_CURVE_STATIC
796
            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
797
        #else
798
            #define ecc_oid_secp256r1 CODED_SECP256R1
799
        #endif
800
        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
801
    #endif /* !NO_ECC_SECP */
802
    #ifdef HAVE_ECC_KOBLITZ
803
        #ifdef HAVE_OID_ENCODING
804
            #define CODED_SECP256K1    {1,3,132,0,10}
805
            #define CODED_SECP256K1_SZ 5
806
        #else
807
            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
808
            #define CODED_SECP256K1_SZ 5
809
        #endif
810
        #ifndef WOLFSSL_ECC_CURVE_STATIC
811
            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
812
        #else
813
            #define ecc_oid_secp256k1 CODED_SECP256K1
814
        #endif
815
        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
816
    #endif /* HAVE_ECC_KOBLITZ */
817
    #ifdef HAVE_ECC_BRAINPOOL
818
        #ifdef HAVE_OID_ENCODING
819
            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
820
            #define CODED_BRAINPOOLP256R1_SZ 10
821
        #else
822
            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
823
            #define CODED_BRAINPOOLP256R1_SZ 9
824
        #endif
825
        #ifndef WOLFSSL_ECC_CURVE_STATIC
826
            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
827
        #else
828
            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
829
        #endif
830
        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
831
    #endif /* HAVE_ECC_BRAINPOOL */
832
#endif /* ECC256 */
833
    #if defined(WOLFSSL_SM2)
834
        #ifdef HAVE_OID_ENCODING
835
            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
836
            #define CODED_SM2P256V1_SZ 6
837
        #else
838
            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
839
            #define CODED_SM2P256V1_SZ 8
840
        #endif
841
        #ifndef WOLFSSL_ECC_CURVE_STATIC
842
            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
843
        #else
844
            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
845
        #endif
846
        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
847
    #endif /* WOLFSSL_SM2 */
848
#ifdef ECC320
849
    #ifdef HAVE_ECC_BRAINPOOL
850
        #ifdef HAVE_OID_ENCODING
851
            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
852
            #define CODED_BRAINPOOLP320R1_SZ 10
853
        #else
854
            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
855
            #define CODED_BRAINPOOLP320R1_SZ 9
856
        #endif
857
        #ifndef WOLFSSL_ECC_CURVE_STATIC
858
            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
859
        #else
860
            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
861
        #endif
862
        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
863
    #endif /* HAVE_ECC_BRAINPOOL */
864
#endif /* ECC320 */
865
#ifdef ECC384
866
    #ifndef NO_ECC_SECP
867
        #ifdef HAVE_OID_ENCODING
868
            #define CODED_SECP384R1    {1,3,132,0,34}
869
            #define CODED_SECP384R1_SZ 5
870
        #else
871
            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
872
            #define CODED_SECP384R1_SZ 5
873
        #endif
874
        #ifndef WOLFSSL_ECC_CURVE_STATIC
875
            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
876
            #define CODED_SECP384R1_OID ecc_oid_secp384r1
877
        #else
878
            #define ecc_oid_secp384r1 CODED_SECP384R1
879
        #endif
880
        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
881
    #endif /* !NO_ECC_SECP */
882
    #ifdef HAVE_ECC_BRAINPOOL
883
        #ifdef HAVE_OID_ENCODING
884
            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
885
            #define CODED_BRAINPOOLP384R1_SZ 10
886
        #else
887
            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
888
            #define CODED_BRAINPOOLP384R1_SZ 9
889
        #endif
890
        #ifndef WOLFSSL_ECC_CURVE_STATIC
891
            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
892
        #else
893
            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
894
        #endif
895
        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
896
    #endif /* HAVE_ECC_BRAINPOOL */
897
#endif /* ECC384 */
898
#ifdef ECC512
899
    #ifdef HAVE_ECC_BRAINPOOL
900
        #ifdef HAVE_OID_ENCODING
901
            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
902
            #define CODED_BRAINPOOLP512R1_SZ 10
903
        #else
904
            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
905
            #define CODED_BRAINPOOLP512R1_SZ 9
906
        #endif
907
        #ifndef WOLFSSL_ECC_CURVE_STATIC
908
            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
909
        #else
910
            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
911
        #endif
912
        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
913
    #endif /* HAVE_ECC_BRAINPOOL */
914
#endif /* ECC512 */
915
#ifdef ECC521
916
    #ifndef NO_ECC_SECP
917
        #ifdef HAVE_OID_ENCODING
918
            #define CODED_SECP521R1     {1,3,132,0,35}
919
            #define CODED_SECP521R1_SZ 5
920
        #else
921
            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
922
            #define CODED_SECP521R1_SZ 5
923
        #endif
924
        #ifndef WOLFSSL_ECC_CURVE_STATIC
925
            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
926
        #else
927
            #define ecc_oid_secp521r1 CODED_SECP521R1
928
        #endif
929
        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
930
    #endif /* !NO_ECC_SECP */
931
#endif /* ECC521 */
932
933
934
/* This holds the key settings.
935
   ***MUST*** be organized by size from smallest to largest. */
936
937
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
938
    #undef ecc_sets
939
    #undef ecc_sets_count
940
#endif
941
942
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
943
static
944
#endif
945
const ecc_set_type ecc_sets[] = {
946
#ifdef ECC112
947
    #ifndef NO_ECC_SECP
948
    {
949
        14,                             /* size/bytes */
950
        ECC_SECP112R1,                  /* ID         */
951
        "SECP112R1",                    /* curve name */
952
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
953
        "DB7C2ABF62E35E668076BEAD2088", /* A          */
954
        "659EF8BA043916EEDE8911702B22", /* B          */
955
        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
956
        "9487239995A5EE76B55F9C2F098",  /* Gx         */
957
        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
958
        ecc_oid_secp112r1,              /* oid/oidSz  */
959
        ecc_oid_secp112r1_sz,
960
        ECC_SECP112R1_OID,              /* oid sum    */
961
        1,                              /* cofactor   */
962
    },
963
    #endif /* !NO_ECC_SECP */
964
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
965
    {
966
        14,                             /* size/bytes */
967
        ECC_SECP112R2,                  /* ID         */
968
        "SECP112R2",                    /* curve name */
969
        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
970
        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
971
        "51DEF1815DB5ED74FCC34C85D709", /* B          */
972
        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
973
        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
974
        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
975
        ecc_oid_secp112r2,              /* oid/oidSz  */
976
        ecc_oid_secp112r2_sz,
977
        ECC_SECP112R2_OID,              /* oid sum    */
978
        4,                              /* cofactor   */
979
    },
980
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
981
#endif /* ECC112 */
982
#ifdef ECC128
983
    #ifndef NO_ECC_SECP
984
    {
985
        16,                                 /* size/bytes */
986
        ECC_SECP128R1,                      /* ID         */
987
        "SECP128R1",                        /* curve name */
988
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
989
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
990
        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
991
        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
992
        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
993
        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
994
        ecc_oid_secp128r1,                  /* oid/oidSz  */
995
        ecc_oid_secp128r1_sz,
996
        ECC_SECP128R1_OID,                  /* oid sum    */
997
        1,                                  /* cofactor   */
998
    },
999
    #endif /* !NO_ECC_SECP */
1000
    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
1001
    {
1002
        16,                                 /* size/bytes */
1003
        ECC_SECP128R2,                      /* ID         */
1004
        "SECP128R2",                        /* curve name */
1005
        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1006
        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
1007
        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
1008
        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
1009
        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
1010
        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
1011
        ecc_oid_secp128r2,                  /* oid/oidSz  */
1012
        ecc_oid_secp128r2_sz,
1013
        ECC_SECP128R2_OID,                  /* oid sum    */
1014
        4,                                  /* cofactor   */
1015
    },
1016
    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
1017
#endif /* ECC128 */
1018
#ifdef ECC160
1019
#ifndef FP_ECC
1020
    #ifndef NO_ECC_SECP
1021
    {
1022
        20,                                         /* size/bytes */
1023
        ECC_SECP160R1,                              /* ID         */
1024
        "SECP160R1",                                /* curve name */
1025
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
1026
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
1027
        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
1028
        "100000000000000000001F4C8F927AED3CA752257",/* order      */
1029
        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
1030
        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
1031
        ecc_oid_secp160r1,                          /* oid/oidSz  */
1032
        ecc_oid_secp160r1_sz,
1033
        ECC_SECP160R1_OID,                          /* oid sum    */
1034
        1,                                          /* cofactor   */
1035
    },
1036
    #endif /* !NO_ECC_SECP */
1037
    #ifdef HAVE_ECC_SECPR2
1038
    {
1039
        20,                                         /* size/bytes */
1040
        ECC_SECP160R2,                              /* ID         */
1041
        "SECP160R2",                                /* curve name */
1042
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1043
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
1044
        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
1045
        "100000000000000000000351EE786A818F3A1A16B",/* order      */
1046
        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
1047
        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
1048
        ecc_oid_secp160r2,                          /* oid/oidSz  */
1049
        ecc_oid_secp160r2_sz,
1050
        ECC_SECP160R2_OID,                          /* oid sum    */
1051
        1,                                          /* cofactor   */
1052
    },
1053
    #endif /* HAVE_ECC_SECPR2 */
1054
    #ifdef HAVE_ECC_KOBLITZ
1055
    {
1056
        20,                                         /* size/bytes */
1057
        ECC_SECP160K1,                              /* ID         */
1058
        "SECP160K1",                                /* curve name */
1059
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
1060
        "0000000000000000000000000000000000000000", /* A          */
1061
        "0000000000000000000000000000000000000007", /* B          */
1062
        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
1063
        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
1064
        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
1065
        ecc_oid_secp160k1,                          /* oid/oidSz  */
1066
        ecc_oid_secp160k1_sz,
1067
        ECC_SECP160K1_OID,                          /* oid sum    */
1068
        1,                                          /* cofactor   */
1069
    },
1070
    #endif /* HAVE_ECC_KOBLITZ */
1071
#endif /* !FP_ECC */
1072
    #ifdef HAVE_ECC_BRAINPOOL
1073
    {
1074
        20,                                         /* size/bytes */
1075
        ECC_BRAINPOOLP160R1,                        /* ID         */
1076
        "BRAINPOOLP160R1",                          /* curve name */
1077
        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
1078
        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
1079
        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
1080
        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
1081
        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
1082
        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
1083
        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
1084
        ecc_oid_brainpoolp160r1_sz,
1085
        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
1086
        1,                                          /* cofactor   */
1087
    },
1088
    #endif /* HAVE_ECC_BRAINPOOL */
1089
#endif /* ECC160 */
1090
#ifdef ECC192
1091
    #ifndef NO_ECC_SECP
1092
    {
1093
        24,                                                 /* size/bytes */
1094
        ECC_SECP192R1,                                      /* ID         */
1095
        "SECP192R1",                                        /* curve name */
1096
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1097
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1098
        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
1099
        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
1100
        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
1101
        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
1102
        ecc_oid_secp192r1,                                  /* oid/oidSz  */
1103
        ecc_oid_secp192r1_sz,
1104
        ECC_SECP192R1_OID,                                  /* oid sum    */
1105
        1,                                                  /* cofactor   */
1106
    },
1107
    #endif /* !NO_ECC_SECP */
1108
    #ifdef HAVE_ECC_SECPR2
1109
    {
1110
        24,                                                 /* size/bytes */
1111
        ECC_PRIME192V2,                                     /* ID         */
1112
        "PRIME192V2",                                       /* curve name */
1113
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1114
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1115
        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
1116
        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
1117
        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
1118
        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
1119
        ecc_oid_prime192v2,                                 /* oid/oidSz  */
1120
        ecc_oid_prime192v2_sz,
1121
        ECC_PRIME192V2_OID,                                 /* oid sum    */
1122
        1,                                                  /* cofactor   */
1123
    },
1124
    #endif /* HAVE_ECC_SECPR2 */
1125
    #ifdef HAVE_ECC_SECPR3
1126
    {
1127
        24,                                                 /* size/bytes */
1128
        ECC_PRIME192V3,                                     /* ID         */
1129
        "PRIME192V3",                                       /* curve name */
1130
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
1131
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
1132
        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
1133
        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
1134
        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
1135
        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
1136
        ecc_oid_prime192v3,                                 /* oid/oidSz  */
1137
        ecc_oid_prime192v3_sz,
1138
        ECC_PRIME192V3_OID,                                 /* oid sum    */
1139
        1,                                                  /* cofactor   */
1140
    },
1141
    #endif /* HAVE_ECC_SECPR3 */
1142
    #ifdef HAVE_ECC_KOBLITZ
1143
    {
1144
        24,                                                 /* size/bytes */
1145
        ECC_SECP192K1,                                      /* ID         */
1146
        "SECP192K1",                                        /* curve name */
1147
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
1148
        "000000000000000000000000000000000000000000000000", /* A          */
1149
        "000000000000000000000000000000000000000000000003", /* B          */
1150
        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
1151
        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
1152
        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
1153
        ecc_oid_secp192k1,                                  /* oid/oidSz  */
1154
        ecc_oid_secp192k1_sz,
1155
        ECC_SECP192K1_OID,                                  /* oid sum    */
1156
        1,                                                  /* cofactor   */
1157
    },
1158
    #endif /* HAVE_ECC_KOBLITZ */
1159
    #ifdef HAVE_ECC_BRAINPOOL
1160
    {
1161
        24,                                                 /* size/bytes */
1162
        ECC_BRAINPOOLP192R1,                                /* ID         */
1163
        "BRAINPOOLP192R1",                                  /* curve name */
1164
        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
1165
        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
1166
        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
1167
        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
1168
        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
1169
        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
1170
        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
1171
        ecc_oid_brainpoolp192r1_sz,
1172
        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
1173
        1,                                                  /* cofactor   */
1174
    },
1175
    #endif /* HAVE_ECC_BRAINPOOL */
1176
#endif /* ECC192 */
1177
#ifdef ECC224
1178
    #ifndef NO_ECC_SECP
1179
    {
1180
        28,                                                         /* size/bytes */
1181
        ECC_SECP224R1,                                              /* ID         */
1182
        "SECP224R1",                                                /* curve name */
1183
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
1184
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
1185
        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
1186
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
1187
        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
1188
        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
1189
        ecc_oid_secp224r1,                                          /* oid/oidSz  */
1190
        ecc_oid_secp224r1_sz,
1191
        ECC_SECP224R1_OID,                                          /* oid sum    */
1192
        1,                                                          /* cofactor   */
1193
    },
1194
    #endif /* !NO_ECC_SECP */
1195
    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
1196
    {
1197
        28,                                                         /* size/bytes */
1198
        ECC_SECP224K1,                                              /* ID         */
1199
        "SECP224K1",                                                /* curve name */
1200
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
1201
        "00000000000000000000000000000000000000000000000000000000", /* A          */
1202
        "00000000000000000000000000000000000000000000000000000005", /* B          */
1203
        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
1204
        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
1205
        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
1206
        ecc_oid_secp224k1,                                          /* oid/oidSz  */
1207
        ecc_oid_secp224k1_sz,
1208
        ECC_SECP224K1_OID,                                          /* oid sum    */
1209
        1,                                                          /* cofactor   */
1210
    },
1211
    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
1212
    #ifdef HAVE_ECC_BRAINPOOL
1213
    {
1214
        28,                                                         /* size/bytes */
1215
        ECC_BRAINPOOLP224R1,                                        /* ID         */
1216
        "BRAINPOOLP224R1",                                          /* curve name */
1217
        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
1218
        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
1219
        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
1220
        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
1221
        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
1222
        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
1223
        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
1224
        ecc_oid_brainpoolp224r1_sz,
1225
        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
1226
        1,                                                          /* cofactor   */
1227
    },
1228
    #endif /* HAVE_ECC_BRAINPOOL */
1229
#endif /* ECC224 */
1230
#ifdef ECC239
1231
    #ifndef NO_ECC_SECP
1232
    {
1233
        30,                                                             /* size/bytes */
1234
        ECC_PRIME239V1,                                                 /* ID         */
1235
        "PRIME239V1",                                                   /* curve name */
1236
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1237
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1238
        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
1239
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
1240
        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
1241
        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
1242
        ecc_oid_prime239v1,                                             /* oid/oidSz  */
1243
        ecc_oid_prime239v1_sz,
1244
        ECC_PRIME239V1_OID,                                             /* oid sum    */
1245
        1,                                                              /* cofactor   */
1246
    },
1247
    #endif /* !NO_ECC_SECP */
1248
    #ifdef HAVE_ECC_SECPR2
1249
    {
1250
        30,                                                             /* size/bytes */
1251
        ECC_PRIME239V2,                                                 /* ID         */
1252
        "PRIME239V2",                                                   /* curve name */
1253
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1254
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1255
        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
1256
        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
1257
        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
1258
        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
1259
        ecc_oid_prime239v2,                                             /* oid/oidSz  */
1260
        ecc_oid_prime239v2_sz,
1261
        ECC_PRIME239V2_OID,                                             /* oid sum    */
1262
        1,                                                              /* cofactor   */
1263
    },
1264
    #endif /* HAVE_ECC_SECPR2 */
1265
    #ifdef HAVE_ECC_SECPR3
1266
    {
1267
        30,                                                             /* size/bytes */
1268
        ECC_PRIME239V3,                                                 /* ID         */
1269
        "PRIME239V3",                                                   /* curve name */
1270
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
1271
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
1272
        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
1273
        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
1274
        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
1275
        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
1276
        ecc_oid_prime239v3,                                             /* oid/oidSz  */
1277
        ecc_oid_prime239v3_sz,
1278
        ECC_PRIME239V3_OID,                                             /* oid sum    */
1279
        1,                                                              /* cofactor   */
1280
    },
1281
    #endif /* HAVE_ECC_SECPR3 */
1282
#endif /* ECC239 */
1283
#ifdef ECC256
1284
    #ifndef NO_ECC_SECP
1285
    {
1286
        32,                                                                 /* size/bytes */
1287
        ECC_SECP256R1,                                                      /* ID         */
1288
        "SECP256R1",                                                        /* curve name */
1289
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1290
        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1291
        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
1292
        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
1293
        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
1294
        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
1295
        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
1296
        ecc_oid_secp256r1_sz,
1297
        ECC_SECP256R1_OID,                                                  /* oid sum    */
1298
        1,                                                                  /* cofactor   */
1299
    },
1300
    #endif /* !NO_ECC_SECP */
1301
    #ifdef HAVE_ECC_KOBLITZ
1302
    {
1303
        32,                                                                 /* size/bytes */
1304
        ECC_SECP256K1,                                                      /* ID         */
1305
        "SECP256K1",                                                        /* curve name */
1306
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
1307
        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
1308
        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
1309
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
1310
        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
1311
        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
1312
        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
1313
        ecc_oid_secp256k1_sz,
1314
        ECC_SECP256K1_OID,                                                  /* oid sum    */
1315
        1,                                                                  /* cofactor   */
1316
    },
1317
    #endif /* HAVE_ECC_KOBLITZ */
1318
    #ifdef HAVE_ECC_BRAINPOOL
1319
    {
1320
        32,                                                                 /* size/bytes */
1321
        ECC_BRAINPOOLP256R1,                                                /* ID         */
1322
        "BRAINPOOLP256R1",                                                  /* curve name */
1323
        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
1324
        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
1325
        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
1326
        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
1327
        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
1328
        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
1329
        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
1330
        ecc_oid_brainpoolp256r1_sz,
1331
        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
1332
        1,                                                                  /* cofactor   */
1333
    },
1334
    #endif /* HAVE_ECC_BRAINPOOL */
1335
#endif /* ECC256 */
1336
    #if defined(WOLFSSL_SM2)
1337
    {
1338
        32,                                                     /* size/bytes */
1339
        ECC_SM2P256V1,                                          /* ID         */
1340
        "SM2P256V1",                                            /* curve name */
1341
1342
        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
1343
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
1344
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
1345
        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
1346
        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
1347
        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
1348
        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
1349
        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
1350
        ecc_oid_sm2p256v1_sz,
1351
        ECC_SM2P256V1_OID,                                      /* oid sum    */
1352
        1,                                                      /* cofactor   */
1353
    },
1354
    #endif /* WOLFSSL_SM2 */
1355
#ifdef ECC320
1356
    #ifdef HAVE_ECC_BRAINPOOL
1357
    {
1358
        40,                                                                                 /* size/bytes */
1359
        ECC_BRAINPOOLP320R1,                                                                /* ID         */
1360
        "BRAINPOOLP320R1",                                                                  /* curve name */
1361
        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
1362
        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
1363
        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
1364
        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
1365
        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
1366
        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
1367
        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
1368
        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
1369
        1,                                                                                  /* cofactor   */
1370
    },
1371
    #endif /* HAVE_ECC_BRAINPOOL */
1372
#endif /* ECC320 */
1373
#ifdef ECC384
1374
    #ifndef NO_ECC_SECP
1375
    {
1376
        48,                                                                                                 /* size/bytes */
1377
        ECC_SECP384R1,                                                                                      /* ID         */
1378
        "SECP384R1",                                                                                        /* curve name */
1379
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
1380
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
1381
        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
1382
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
1383
        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
1384
        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
1385
        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
1386
        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
1387
        1,                                                                                                  /* cofactor   */
1388
    },
1389
    #endif /* !NO_ECC_SECP */
1390
    #ifdef HAVE_ECC_BRAINPOOL
1391
    {
1392
        48,                                                                                                 /* size/bytes */
1393
        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
1394
        "BRAINPOOLP384R1",                                                                                  /* curve name */
1395
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
1396
        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
1397
        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
1398
        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
1399
        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
1400
        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
1401
        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
1402
        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
1403
        1,                                                                                                  /* cofactor   */
1404
    },
1405
    #endif /* HAVE_ECC_BRAINPOOL */
1406
#endif /* ECC384 */
1407
#ifdef ECC512
1408
    #ifdef HAVE_ECC_BRAINPOOL
1409
    {
1410
        64,                                                                                                                                 /* size/bytes */
1411
        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
1412
        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
1413
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
1414
        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
1415
        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
1416
        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
1417
        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
1418
        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
1419
        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
1420
        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
1421
        1,                                                                                                                                  /* cofactor   */
1422
    },
1423
    #endif /* HAVE_ECC_BRAINPOOL */
1424
#endif /* ECC512 */
1425
#ifdef ECC521
1426
    #ifndef NO_ECC_SECP
1427
    {
1428
        66,                                                                                                                                    /* size/bytes */
1429
        ECC_SECP521R1,                                                                                                                         /* ID         */
1430
        "SECP521R1",                                                                                                                           /* curve name */
1431
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
1432
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
1433
        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
1434
        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
1435
        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
1436
        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
1437
        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
1438
        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
1439
        1,                                                                                                                                     /* cofactor   */
1440
    },
1441
    #endif /* !NO_ECC_SECP */
1442
#endif /* ECC521 */
1443
#ifdef WOLFCRYPT_HAVE_SAKKE
1444
    {
1445
        128,
1446
        ECC_SAKKE_1,
1447
        "SAKKE1",
1448
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
1449
        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
1450
        "0",
1451
        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
1452
        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
1453
        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
1454
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1455
            NULL, 0,
1456
        #else
1457
            {0}, 0,
1458
        #endif
1459
        0,
1460
        4,
1461
    },
1462
#endif
1463
#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
1464
    /* place holder for custom curve index for cache */
1465
    {
1466
        1, /* non-zero */
1467
        ECC_CURVE_CUSTOM,
1468
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1469
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1470
        #else
1471
            {0},{0},{0},{0},{0},{0},{0},{0},
1472
        #endif
1473
        0, 0, 0
1474
    },
1475
#endif
1476
    {
1477
        0,
1478
        ECC_CURVE_INVALID,
1479
        #ifndef WOLFSSL_ECC_CURVE_STATIC
1480
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1481
        #else
1482
            {0},{0},{0},{0},{0},{0},{0},{0},
1483
        #endif
1484
        0, 0, 0
1485
    }
1486
};
1487
2.11k
#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
1488
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1489
static
1490
#endif
1491
const size_t ecc_sets_count = ECC_SET_COUNT - 1;
1492
1493
0
const ecc_set_type *wc_ecc_get_sets(void) {
1494
0
    return ecc_sets;
1495
0
}
1496
0
size_t wc_ecc_get_sets_count(void) {
1497
0
    return ecc_sets_count;
1498
0
}
1499
1500
#ifdef HAVE_OID_ENCODING
1501
    /* encoded OID cache */
1502
    typedef struct {
1503
        word32 oidSz;
1504
        byte oid[ECC_MAX_OID_LEN];
1505
    } oid_cache_t;
1506
    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
1507
1508
    static wolfSSL_Mutex ecc_oid_cache_lock
1509
        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
1510
#ifndef WOLFSSL_MUTEX_INITIALIZER
1511
    static volatile int eccOidLockInit = 0;
1512
#endif
1513
#endif /* HAVE_OID_ENCODING */
1514
1515
/* Forward declarations */
1516
#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
1517
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
1518
#endif
1519
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
1520
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
1521
    mp_int* prime, mp_int* order);
1522
#endif
1523
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
1524
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
1525
    !defined(WOLFSSL_KCAPI_ECC)
1526
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
1527
#endif
1528
1529
1530
#ifdef HAVE_COMP_KEY
1531
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
1532
    !defined(WOLFSSL_CRYPTOCELL)
1533
1534
#ifndef WOLFSSL_SP_MATH
1535
#if !defined(SQRTMOD_USE_MOD_EXP)
1536
static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1537
#endif
1538
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
1539
#endif
1540
#endif
1541
#endif
1542
1543
1544
/* Curve Specs */
1545
typedef struct ecc_curve_spec {
1546
    const ecc_set_type* dp;
1547
1548
    mp_int* prime;
1549
    mp_int* Af;
1550
    mp_int* Bf;
1551
    mp_int* order;
1552
    mp_int* Gx;
1553
    mp_int* Gy;
1554
1555
#ifdef ECC_CACHE_CURVE
1556
    mp_int prime_lcl;
1557
    mp_int Af_lcl;
1558
    mp_int Bf_lcl;
1559
    mp_int order_lcl;
1560
    mp_int Gx_lcl;
1561
    mp_int Gy_lcl;
1562
#else
1563
#ifdef WOLFSSL_SP_MATH_ALL
1564
    unsigned char* spec_ints;
1565
#else
1566
    mp_int* spec_ints;
1567
#endif
1568
    word32 spec_count;
1569
    word32 spec_use;
1570
#endif
1571
1572
    byte load_mask;
1573
} ecc_curve_spec;
1574
1575
    #define ECC_CURVE_FIELD_NONE    0x00
1576
5.27k
    #define ECC_CURVE_FIELD_PRIME   0x01
1577
5.27k
    #define ECC_CURVE_FIELD_AF      0x02
1578
5.27k
    #define ECC_CURVE_FIELD_BF      0x04
1579
2.11k
    #define ECC_CURVE_FIELD_ORDER   0x08
1580
2.11k
    #define ECC_CURVE_FIELD_GX      0x10
1581
2.11k
    #define ECC_CURVE_FIELD_GY      0x20
1582
0
    #define ECC_CURVE_FIELD_ALL     0x3F
1583
    #define ECC_CURVE_FIELD_COUNT   6
1584
1585
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
1586
static const u32 xil_curve_type[ECC_CURVE_MAX] = {
1587
        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
1588
        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
1589
};
1590
1591
static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
1592
{
1593
    word32 up, down;
1594
    up = 0;
1595
    down = len - 1;
1596
    while (up < len)
1597
        outbuf[up++] = inbuf[down--];
1598
}
1599
1600
static int xil_mpi_import(mp_int *mpi,
1601
                          const byte *inbuf,
1602
                          word32 len,
1603
                          void* heap)
1604
{
1605
    int err;
1606
#ifdef WOLFSSL_SMALL_STACK
1607
    byte* buf = NULL;
1608
#else
1609
    byte buf[MAX_ECC_BYTES];
1610
1611
    if (len > MAX_ECC_BYTES)
1612
        return BUFFER_E;
1613
#endif
1614
1615
    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
1616
        return MEMORY_E);
1617
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1618
    /* Register the stack buffer before it is filled so any future exit before
1619
     * the ForceZero is checked. XMEMSET makes it defined for registration. */
1620
    XMEMSET(buf, 0, len);
1621
    wc_MemZero_Add("xil_mpi_import buf", buf, len);
1622
#endif
1623
    buf_reverse(buf, inbuf, len);
1624
1625
    err = mp_read_unsigned_bin(mpi, buf, len);
1626
    ForceZero(buf, len);
1627
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1628
    wc_MemZero_Check(buf, len);
1629
#endif
1630
    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
1631
    return err;
1632
}
1633
#endif
1634
1635
#ifdef ECC_CACHE_CURVE
1636
    /* cache (mp_int) of the curve parameters */
1637
    #ifdef WOLFSSL_NO_MALLOC
1638
    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
1639
    #else
1640
    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
1641
    #endif
1642
    #ifndef SINGLE_THREADED
1643
        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
1644
    #endif
1645
1646
    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
1647
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1648
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1649
#elif defined(WOLFSSL_SMALL_STACK)
1650
#ifdef WOLFSSL_SP_MATH_ALL
1651
    #define DECLARE_CURVE_SPECS(intcount)                               \
1652
        unsigned char* spec_ints = NULL;                                \
1653
        ecc_curve_spec curve_lcl;                                       \
1654
        ecc_curve_spec* curve = &curve_lcl;                             \
1655
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1656
        curve->spec_count = intcount
1657
1658
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1659
    do {                                                                \
1660
        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
1661
            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
1662
            DYNAMIC_TYPE_ECC);                                          \
1663
        if (spec_ints == NULL)                                          \
1664
            (err) = MEMORY_E;                                           \
1665
        else {                                                          \
1666
            curve->spec_ints = spec_ints;                               \
1667
            (err) = MP_OKAY;                                            \
1668
        }                                                               \
1669
    } while (0)
1670
#else
1671
    #define DECLARE_CURVE_SPECS(intcount)                               \
1672
        mp_int* spec_ints = NULL;                                       \
1673
        ecc_curve_spec curve_lcl;                                       \
1674
        ecc_curve_spec* curve = &curve_lcl;                             \
1675
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1676
        curve->spec_count = intcount
1677
1678
    #define ALLOC_CURVE_SPECS(intcount, err)                            \
1679
    do {                                                                \
1680
        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
1681
                            DYNAMIC_TYPE_ECC);                          \
1682
        if (spec_ints == NULL)                                          \
1683
            (err) = MEMORY_E;                                           \
1684
        else {                                                          \
1685
            curve->spec_ints = spec_ints;                               \
1686
            (err) = MP_OKAY;                                            \
1687
        }                                                               \
1688
    } while (0)
1689
#endif
1690
    #define FREE_CURVE_SPECS()                                          \
1691
        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
1692
#else
1693
#ifdef WOLFSSL_SP_MATH_ALL
1694
    #define DECLARE_CURVE_SPECS(intcount)                               \
1695
1.05k
        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
1696
1.05k
            MAX_ECC_BITS_USE)) * (intcount)];                           \
1697
1.05k
        ecc_curve_spec curve_lcl;                                       \
1698
1.05k
        ecc_curve_spec* curve = &curve_lcl;                             \
1699
1.05k
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1700
1.05k
        curve->spec_ints = spec_ints;                                   \
1701
1.05k
        curve->spec_count = (intcount)
1702
#else
1703
    #define DECLARE_CURVE_SPECS(intcount)                               \
1704
        mp_int spec_ints[(intcount)];                                   \
1705
        ecc_curve_spec curve_lcl;                                       \
1706
        ecc_curve_spec* curve = &curve_lcl;                             \
1707
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
1708
        curve->spec_ints = spec_ints;                                   \
1709
        curve->spec_count = (intcount)
1710
#endif
1711
1.05k
    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
1712
1.05k
    #define FREE_CURVE_SPECS() WC_DO_NOTHING
1713
#endif /* ECC_CACHE_CURVE */
1714
1715
static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
1716
    byte mask)
1717
3.16k
{
1718
3.16k
    if (item) {
1719
    #ifdef HAVE_WOLF_BIGINT
1720
        wc_bigint_free(&item->raw);
1721
    #endif
1722
3.16k
        mp_clear(item);
1723
3.16k
    }
1724
3.16k
    curve->load_mask = (byte)(curve->load_mask & ~mask);
1725
3.16k
}
1726
static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
1727
1.05k
{
1728
1.05k
    if (curve == NULL) {
1729
0
        return;
1730
0
    }
1731
1732
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
1733
1.05k
        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
1734
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_AF)
1735
1.05k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
1736
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_BF)
1737
1.05k
        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
1738
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
1739
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
1740
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_GX)
1741
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
1742
1.05k
    if (curve->load_mask & ECC_CURVE_FIELD_GY)
1743
0
        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
1744
1745
1.05k
    curve->load_mask = 0;
1746
1.05k
}
1747
1748
static void wc_ecc_curve_free(ecc_curve_spec* curve)
1749
1.05k
{
1750
1.05k
    if (curve) {
1751
    #ifdef ECC_CACHE_CURVE
1752
        #ifdef WOLFSSL_CUSTOM_CURVES
1753
        /* only free custom curves (rest are globally cached) */
1754
        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
1755
            wc_ecc_curve_cache_free_spec(curve);
1756
            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
1757
        }
1758
        #endif
1759
    #else
1760
1.05k
        wc_ecc_curve_cache_free_spec(curve);
1761
1.05k
    #endif
1762
1.05k
    }
1763
1.05k
}
1764
1765
static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
1766
    mp_int** dst, byte mask)
1767
3.16k
{
1768
3.16k
    int err;
1769
1770
3.16k
#ifndef ECC_CACHE_CURVE
1771
    /* get mp_int from temp */
1772
3.16k
    if (curve->spec_use >= curve->spec_count) {
1773
0
        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
1774
0
        return ECC_BAD_ARG_E;
1775
0
    }
1776
3.16k
#ifdef WOLFSSL_SP_MATH_ALL
1777
3.16k
    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
1778
3.16k
        MAX_ECC_BITS_USE)) * curve->spec_use++);
1779
#else
1780
    *dst = &curve->spec_ints[curve->spec_use++];
1781
#endif
1782
3.16k
#endif
1783
1784
3.16k
#ifdef WOLFSSL_SP_MATH_ALL
1785
3.16k
    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
1786
#else
1787
    err = mp_init(*dst);
1788
#endif
1789
3.16k
    if (err == MP_OKAY) {
1790
3.16k
        curve->load_mask |= mask;
1791
1792
3.16k
        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
1793
1794
    #ifdef HAVE_WOLF_BIGINT
1795
        if (err == MP_OKAY)
1796
            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
1797
    #endif
1798
3.16k
    }
1799
3.16k
    return err;
1800
3.16k
}
1801
1802
static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
1803
    byte load_mask)
1804
1.05k
{
1805
1.05k
    int ret = 0;
1806
1.05k
    ecc_curve_spec* curve;
1807
1.05k
    byte load_items = 0; /* mask of items to load */
1808
#ifdef ECC_CACHE_CURVE
1809
    int x;
1810
#endif
1811
1812
1.05k
    if (dp == NULL || pCurve == NULL)
1813
0
        return BAD_FUNC_ARG;
1814
1815
#ifdef ECC_CACHE_CURVE
1816
    x = wc_ecc_get_curve_idx(dp->id);
1817
    if (x == ECC_CURVE_INVALID)
1818
        return ECC_BAD_ARG_E;
1819
1820
#if !defined(SINGLE_THREADED)
1821
    ret = wc_LockMutex(&ecc_curve_cache_mutex);
1822
    if (ret != 0) {
1823
        return ret;
1824
    }
1825
#endif
1826
1827
#ifdef WOLFSSL_NO_MALLOC
1828
    curve = &ecc_curve_spec_cache[x];
1829
#else
1830
    /* make sure cache has been allocated */
1831
    if (ecc_curve_spec_cache[x] == NULL
1832
    #ifdef WOLFSSL_CUSTOM_CURVES
1833
        || dp->id == ECC_CURVE_CUSTOM
1834
    #endif
1835
    ) {
1836
        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
1837
        if (curve == NULL) {
1838
        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1839
            wc_UnLockMutex(&ecc_curve_cache_mutex);
1840
        #endif
1841
            return MEMORY_E;
1842
        }
1843
        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
1844
1845
        /* set curve pointer to cache */
1846
    #ifdef WOLFSSL_CUSTOM_CURVES
1847
        if (dp->id != ECC_CURVE_CUSTOM)
1848
    #endif
1849
        {
1850
            ecc_curve_spec_cache[x] = curve;
1851
        }
1852
    }
1853
    else {
1854
        curve = ecc_curve_spec_cache[x];
1855
    }
1856
#endif /* WOLFSSL_NO_MALLOC */
1857
1858
    /* return new or cached curve */
1859
    *pCurve = curve;
1860
#else
1861
1.05k
    curve = *pCurve;
1862
1.05k
#endif /* ECC_CACHE_CURVE */
1863
1864
    /* make sure the curve is initialized */
1865
1.05k
    if (curve->dp != dp) {
1866
1.05k
        curve->load_mask = 0;
1867
1868
    #ifdef ECC_CACHE_CURVE
1869
        curve->prime = &curve->prime_lcl;
1870
        curve->Af = &curve->Af_lcl;
1871
        curve->Bf = &curve->Bf_lcl;
1872
        curve->order = &curve->order_lcl;
1873
        curve->Gx = &curve->Gx_lcl;
1874
        curve->Gy = &curve->Gy_lcl;
1875
    #endif
1876
1.05k
    }
1877
1.05k
    curve->dp = dp; /* set dp info */
1878
1879
    /* determine items to load */
1880
1.05k
    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
1881
1.05k
    curve->load_mask |= load_items;
1882
1883
    /* load items */
1884
1.05k
    if (load_items & ECC_CURVE_FIELD_PRIME)
1885
1.05k
        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
1886
1.05k
            ECC_CURVE_FIELD_PRIME);
1887
1.05k
    if (load_items & ECC_CURVE_FIELD_AF)
1888
1.05k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
1889
1.05k
            ECC_CURVE_FIELD_AF);
1890
1.05k
    if (load_items & ECC_CURVE_FIELD_BF)
1891
1.05k
        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
1892
1.05k
            ECC_CURVE_FIELD_BF);
1893
1.05k
    if (load_items & ECC_CURVE_FIELD_ORDER)
1894
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
1895
0
            ECC_CURVE_FIELD_ORDER);
1896
1.05k
    if (load_items & ECC_CURVE_FIELD_GX)
1897
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
1898
0
            ECC_CURVE_FIELD_GX);
1899
1.05k
    if (load_items & ECC_CURVE_FIELD_GY)
1900
0
        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
1901
0
            ECC_CURVE_FIELD_GY);
1902
1903
    /* check for error */
1904
1.05k
    if (ret != 0) {
1905
0
        wc_ecc_curve_free(curve);
1906
0
        ret = MP_READ_E;
1907
0
    }
1908
1909
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
1910
    wc_UnLockMutex(&ecc_curve_cache_mutex);
1911
#endif
1912
1913
1.05k
    return ret;
1914
1.05k
}
1915
1916
#ifdef ECC_CACHE_CURVE
1917
int wc_ecc_curve_cache_init(void)
1918
{
1919
    int ret = 0;
1920
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1921
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1922
    ret = wc_InitMutex(&ecc_curve_cache_mutex);
1923
#endif
1924
    return ret;
1925
}
1926
1927
void wc_ecc_curve_cache_free(void)
1928
{
1929
    int x;
1930
    /* free all ECC curve caches */
1931
    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
1932
    #ifdef WOLFSSL_NO_MALLOC
1933
        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
1934
        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
1935
    #else
1936
        if (ecc_curve_spec_cache[x]) {
1937
            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
1938
            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
1939
            ecc_curve_spec_cache[x] = NULL;
1940
        }
1941
    #endif /* WOLFSSL_NO_MALLOC */
1942
    }
1943
1944
#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
1945
        !defined(WOLFSSL_MUTEX_INITIALIZER)
1946
    wc_FreeMutex(&ecc_curve_cache_mutex);
1947
#endif
1948
}
1949
#endif /* ECC_CACHE_CURVE */
1950
1951
1952
/* Retrieve the curve name for the ECC curve id.
1953
 *
1954
 * curve_id  The id of the curve.
1955
 * returns the name stored from the curve if available, otherwise NULL.
1956
 */
1957
const char* wc_ecc_get_name(int curve_id)
1958
0
{
1959
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
1960
0
    if (curve_idx == ECC_CURVE_INVALID)
1961
0
        return NULL;
1962
0
    return ecc_sets[curve_idx].name;
1963
0
}
1964
1965
int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
1966
1.05k
{
1967
1.05k
    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
1968
0
        return BAD_FUNC_ARG;
1969
0
    }
1970
1971
1.05k
    if (keysize > ECC_MAXSIZE) {
1972
1
        return ECC_BAD_ARG_E;
1973
1
    }
1974
1975
    /* handle custom case */
1976
1.05k
    if (key->idx != ECC_CUSTOM_IDX) {
1977
1.05k
        int x;
1978
1979
        /* default values */
1980
1.05k
        key->idx = 0;
1981
1.05k
        key->dp = NULL;
1982
1983
        /* find ecc_set based on curve_id or key size */
1984
3.89k
        for (x = 0; ecc_sets[x].size != 0; x++) {
1985
3.89k
            if (curve_id > ECC_CURVE_DEF) {
1986
3.89k
                if (curve_id == ecc_sets[x].id)
1987
1.05k
                  break;
1988
3.89k
            }
1989
0
            else if (keysize <= ecc_sets[x].size) {
1990
0
                break;
1991
0
            }
1992
3.89k
        }
1993
1.05k
        if (ecc_sets[x].size == 0) {
1994
0
            WOLFSSL_MSG("ECC Curve not found");
1995
0
            return ECC_CURVE_OID_E;
1996
0
        }
1997
1998
1.05k
        key->idx = x;
1999
1.05k
        key->dp  = &ecc_sets[x];
2000
1.05k
    }
2001
2002
1.05k
    return 0;
2003
1.05k
}
2004
2005
2006
#ifdef ALT_ECC_SIZE
2007
static void alt_fp_init(mp_int* a)
2008
{
2009
    a->size = FP_SIZE_ECC;
2010
    mp_zero(a);
2011
}
2012
#endif /* ALT_ECC_SIZE */
2013
2014
2015
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
2016
    !defined(WOLFSSL_CRYPTOCELL) && \
2017
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
2018
      defined(WOLFSSL_IMXRT1170_CAAM))
2019
2020
#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
2021
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2022
                                     mp_int* modulus, mp_digit mp);
2023
2024
/**
2025
   Add two ECC points
2026
   P        The point to add
2027
   Q        The point to add
2028
   R        [out] The destination of the double
2029
   a        ECC curve parameter a
2030
   modulus  The modulus of the field the ECC curve is in
2031
   mp       The "b" value from montgomery_setup()
2032
   return   MP_OKAY on success
2033
*/
2034
static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2035
                                     mp_int* a, mp_int* modulus, mp_digit mp)
2036
0
{
2037
0
#if !defined(WOLFSSL_SP_MATH)
2038
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2039
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2040
#ifdef ALT_ECC_SIZE
2041
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2042
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2043
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2044
#endif
2045
0
   mp_int  *x, *y, *z;
2046
0
   int     err;
2047
2048
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2049
0
       return WC_KEY_SIZE_E;
2050
0
   }
2051
2052
   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
2053
0
   if (Q == R) {
2054
0
      ecc_point* tPt  = P;
2055
0
      P = Q;
2056
0
      Q = tPt;
2057
0
   }
2058
2059
#ifdef WOLFSSL_SMALL_STACK
2060
#ifdef WOLFSSL_SMALL_STACK_CACHE
2061
   if (R->key != NULL) {
2062
       t1 = R->key->t1;
2063
       t2 = R->key->t2;
2064
#ifdef ALT_ECC_SIZE
2065
       rx = R->key->x;
2066
       ry = R->key->y;
2067
       rz = R->key->z;
2068
#endif
2069
   }
2070
   else
2071
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2072
#endif /* WOLFSSL_SMALL_STACK */
2073
0
   {
2074
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2075
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2076
   #ifdef MP_INT_SIZE_CHECK_NULL
2077
      if (t1 == NULL || t2 == NULL) {
2078
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2079
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2080
         return MEMORY_E;
2081
      }
2082
   #endif
2083
#ifdef ALT_ECC_SIZE
2084
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2085
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2086
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2087
   #ifdef MP_INT_SIZE_CHECK_NULL
2088
      if (rx == NULL || ry == NULL || rz == NULL) {
2089
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2090
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2091
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2092
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2093
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2094
         return MEMORY_E;
2095
      }
2096
   #endif
2097
#endif
2098
0
   }
2099
2100
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2101
0
   if (err == MP_OKAY) {
2102
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2103
0
   }
2104
0
   if (err != MP_OKAY) {
2105
#ifdef WOLFSSL_SMALL_STACK
2106
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2107
      if (R->key == NULL)
2108
   #endif
2109
#endif
2110
0
      {
2111
      #ifdef ALT_ECC_SIZE
2112
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2113
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2114
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2115
      #endif
2116
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2117
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2118
0
      }
2119
0
      return err;
2120
0
   }
2121
2122
   /* should we dbl instead? */
2123
0
   if (err == MP_OKAY) {
2124
0
#ifdef ECC_TIMING_RESISTANT
2125
0
      err = mp_submod_ct(modulus, Q->y, modulus, t1);
2126
#else
2127
      err = mp_sub(modulus, Q->y, t1);
2128
#endif
2129
0
   }
2130
0
   if (err == MP_OKAY) {
2131
0
      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
2132
0
           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
2133
0
           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
2134
0
          mp_clear(t1);
2135
0
          mp_clear(t2);
2136
   #ifdef WOLFSSL_SMALL_STACK
2137
      #ifdef WOLFSSL_SMALL_STACK_CACHE
2138
         if (R->key == NULL)
2139
      #endif
2140
   #endif
2141
0
         {
2142
         #ifdef ALT_ECC_SIZE
2143
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2144
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2145
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2146
         #endif
2147
0
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2148
0
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2149
0
         }
2150
0
         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2151
0
      }
2152
0
   }
2153
2154
0
   if (err != MP_OKAY) {
2155
0
      goto done;
2156
0
   }
2157
2158
/* If use ALT_ECC_SIZE we need to use local stack variable since
2159
   ecc_point x,y,z is reduced size */
2160
#ifdef ALT_ECC_SIZE
2161
   /* Use local stack variable */
2162
   x = rx;
2163
   y = ry;
2164
   z = rz;
2165
2166
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2167
   if (err == MP_OKAY) {
2168
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2169
   }
2170
   if (err == MP_OKAY) {
2171
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2172
   }
2173
   if (err != MP_OKAY) {
2174
      goto done;
2175
   }
2176
#else
2177
   /* Use destination directly */
2178
0
   x = R->x;
2179
0
   y = R->y;
2180
0
   z = R->z;
2181
0
#endif
2182
2183
0
   if (err == MP_OKAY)
2184
0
       err = mp_copy(P->x, x);
2185
0
   if (err == MP_OKAY)
2186
0
       err = mp_copy(P->y, y);
2187
0
   if (err == MP_OKAY)
2188
0
       err = mp_copy(P->z, z);
2189
2190
   /* if Z is one then these are no-operations */
2191
0
   if (err == MP_OKAY) {
2192
0
       if (!mp_iszero(Q->z)) {
2193
           /* T1 = Z' * Z' */
2194
0
           err = mp_sqr(Q->z, t1);
2195
0
           if (err == MP_OKAY)
2196
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2197
2198
           /* X = X * T1 */
2199
0
           if (err == MP_OKAY)
2200
0
               err = mp_mul(t1, x, x);
2201
0
           if (err == MP_OKAY)
2202
0
               err = mp_montgomery_reduce(x, modulus, mp);
2203
2204
           /* T1 = Z' * T1 */
2205
0
           if (err == MP_OKAY)
2206
0
               err = mp_mul(Q->z, t1, t1);
2207
0
           if (err == MP_OKAY)
2208
0
               err = mp_montgomery_reduce(t1, modulus, mp);
2209
2210
           /* Y = Y * T1 */
2211
0
           if (err == MP_OKAY)
2212
0
               err = mp_mul(t1, y, y);
2213
0
           if (err == MP_OKAY)
2214
0
               err = mp_montgomery_reduce(y, modulus, mp);
2215
0
       }
2216
0
   }
2217
2218
   /* T1 = Z*Z */
2219
0
   if (err == MP_OKAY)
2220
0
       err = mp_sqr(z, t1);
2221
0
   if (err == MP_OKAY)
2222
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2223
2224
   /* T2 = X' * T1 */
2225
0
   if (err == MP_OKAY)
2226
0
       err = mp_mul(Q->x, t1, t2);
2227
0
   if (err == MP_OKAY)
2228
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2229
2230
   /* T1 = Z * T1 */
2231
0
   if (err == MP_OKAY)
2232
0
       err = mp_mul(z, t1, t1);
2233
0
   if (err == MP_OKAY)
2234
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2235
2236
   /* T1 = Y' * T1 */
2237
0
   if (err == MP_OKAY)
2238
0
       err = mp_mul(Q->y, t1, t1);
2239
0
   if (err == MP_OKAY)
2240
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2241
2242
   /* Y = Y - T1 */
2243
0
   if (err == MP_OKAY)
2244
0
       err = mp_submod_ct(y, t1, modulus, y);
2245
   /* T1 = 2T1 */
2246
0
   if (err == MP_OKAY)
2247
0
       err = mp_addmod_ct(t1, t1, modulus, t1);
2248
   /* T1 = Y + T1 */
2249
0
   if (err == MP_OKAY)
2250
0
       err = mp_addmod_ct(t1, y, modulus, t1);
2251
   /* X = X - T2 */
2252
0
   if (err == MP_OKAY)
2253
0
       err = mp_submod_ct(x, t2, modulus, x);
2254
   /* T2 = 2T2 */
2255
0
   if (err == MP_OKAY)
2256
0
       err = mp_addmod_ct(t2, t2, modulus, t2);
2257
   /* T2 = X + T2 */
2258
0
   if (err == MP_OKAY)
2259
0
       err = mp_addmod_ct(t2, x, modulus, t2);
2260
2261
0
   if (err == MP_OKAY) {
2262
0
       if (!mp_iszero(Q->z)) {
2263
           /* Z = Z * Z' */
2264
0
           err = mp_mul(z, Q->z, z);
2265
0
           if (err == MP_OKAY)
2266
0
               err = mp_montgomery_reduce(z, modulus, mp);
2267
0
       }
2268
0
   }
2269
2270
   /* Z = Z * X */
2271
0
   if (err == MP_OKAY)
2272
0
       err = mp_mul(z, x, z);
2273
0
   if (err == MP_OKAY)
2274
0
       err = mp_montgomery_reduce(z, modulus, mp);
2275
2276
   /* T1 = T1 * X  */
2277
0
   if (err == MP_OKAY)
2278
0
       err = mp_mul(t1, x, t1);
2279
0
   if (err == MP_OKAY)
2280
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2281
2282
   /* X = X * X */
2283
0
   if (err == MP_OKAY)
2284
0
       err = mp_sqr(x, x);
2285
0
   if (err == MP_OKAY)
2286
0
       err = mp_montgomery_reduce(x, modulus, mp);
2287
2288
   /* T2 = T2 * x */
2289
0
   if (err == MP_OKAY)
2290
0
       err = mp_mul(t2, x, t2);
2291
0
   if (err == MP_OKAY)
2292
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2293
2294
   /* T1 = T1 * X  */
2295
0
   if (err == MP_OKAY)
2296
0
       err = mp_mul(t1, x, t1);
2297
0
   if (err == MP_OKAY)
2298
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2299
2300
   /* X = Y*Y */
2301
0
   if (err == MP_OKAY)
2302
0
       err = mp_sqr(y, x);
2303
0
   if (err == MP_OKAY)
2304
0
       err = mp_montgomery_reduce(x, modulus, mp);
2305
2306
   /* X = X - T2 */
2307
0
   if (err == MP_OKAY)
2308
0
       err = mp_submod_ct(x, t2, modulus, x);
2309
   /* T2 = T2 - X */
2310
0
   if (err == MP_OKAY)
2311
0
       err = mp_submod_ct(t2, x, modulus, t2);
2312
   /* T2 = T2 - X */
2313
0
   if (err == MP_OKAY)
2314
0
       err = mp_submod_ct(t2, x, modulus, t2);
2315
   /* T2 = T2 * Y */
2316
0
   if (err == MP_OKAY)
2317
0
       err = mp_mul(t2, y, t2);
2318
0
   if (err == MP_OKAY)
2319
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2320
2321
   /* Y = T2 - T1 */
2322
0
   if (err == MP_OKAY)
2323
0
       err = mp_submod_ct(t2, t1, modulus, y);
2324
   /* Y = Y/2 */
2325
0
   if (err == MP_OKAY)
2326
0
       err = mp_div_2_mod_ct(y, modulus, y);
2327
2328
#ifdef ALT_ECC_SIZE
2329
   if (err == MP_OKAY)
2330
       err = mp_copy(x, R->x);
2331
   if (err == MP_OKAY)
2332
       err = mp_copy(y, R->y);
2333
   if (err == MP_OKAY)
2334
       err = mp_copy(z, R->z);
2335
#endif
2336
2337
0
done:
2338
2339
   /* clean up */
2340
0
   mp_clear(t1);
2341
0
   mp_clear(t2);
2342
#ifdef WOLFSSL_SMALL_STACK
2343
#ifdef WOLFSSL_SMALL_STACK_CACHE
2344
   if (R->key == NULL)
2345
#endif
2346
#endif
2347
0
   {
2348
   #ifdef ALT_ECC_SIZE
2349
      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2350
      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2351
      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2352
   #endif
2353
0
      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2354
0
      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2355
0
   }
2356
2357
0
   return err;
2358
#else
2359
    int modBits = mp_count_bits(modulus);
2360
2361
    (void)a;
2362
    (void)mp;
2363
2364
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2365
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2366
       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2367
                                            R->x, R->y, R->z);
2368
    }
2369
#endif
2370
#ifndef WOLFSSL_SP_NO_256
2371
    if (modBits == 256) {
2372
        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2373
                                         R->x, R->y, R->z);
2374
    }
2375
#endif
2376
#ifdef WOLFSSL_SP_384
2377
    if (modBits == 384) {
2378
        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2379
                                         R->x, R->y, R->z);
2380
    }
2381
#endif
2382
#ifdef WOLFSSL_SP_521
2383
    if (modBits == 521) {
2384
        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
2385
                                         R->x, R->y, R->z);
2386
    }
2387
#endif
2388
    return ECC_BAD_ARG_E;
2389
#endif
2390
0
}
2391
2392
int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
2393
                             mp_int* a, mp_int* modulus, mp_digit mp)
2394
0
{
2395
0
    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
2396
0
        return ECC_BAD_ARG_E;
2397
0
    }
2398
2399
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2400
0
        mp_cmp(P->y, modulus) != MP_LT ||
2401
0
        mp_cmp(P->z, modulus) != MP_LT ||
2402
0
        mp_cmp(Q->x, modulus) != MP_LT ||
2403
0
        mp_cmp(Q->y, modulus) != MP_LT ||
2404
0
        mp_cmp(Q->z, modulus) != MP_LT) {
2405
0
        return ECC_OUT_OF_RANGE_E;
2406
0
    }
2407
2408
0
    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
2409
0
}
2410
2411
/* ### Point doubling in Jacobian coordinate system ###
2412
 *
2413
 * let us have a curve:                 y^2 = x^3 + a*x + b
2414
 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
2415
 *
2416
 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
2417
 * Xr = M^2 - 2*S
2418
 * Yr = M * (S - Xr) - 8*T
2419
 * Zr = 2 * Yp * Zp
2420
 *
2421
 * M = 3 * Xp^2 + a*Zp^4
2422
 * T = Yp^4
2423
 * S = 4 * Xp * Yp^2
2424
 *
2425
 * SPECIAL CASE: when a == 3 we can compute M as
2426
 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
2427
 */
2428
2429
/**
2430
   Double an ECC point
2431
   P   The point to double
2432
   R   [out] The destination of the double
2433
   a   ECC curve parameter a
2434
   modulus  The modulus of the field the ECC curve is in
2435
   mp       The "b" value from montgomery_setup()
2436
   return   MP_OKAY on success
2437
*/
2438
static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2439
                                     mp_int* modulus, mp_digit mp)
2440
0
{
2441
0
#if !defined(WOLFSSL_SP_MATH)
2442
0
   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2443
0
   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2444
#ifdef ALT_ECC_SIZE
2445
   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2446
   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2447
   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2448
#endif
2449
0
   mp_int *x, *y, *z;
2450
0
   int    err;
2451
2452
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2453
0
       return WC_KEY_SIZE_E;
2454
0
   }
2455
2456
#ifdef WOLFSSL_SMALL_STACK
2457
#ifdef WOLFSSL_SMALL_STACK_CACHE
2458
   if (R->key != NULL) {
2459
       t1 = R->key->t1;
2460
       t2 = R->key->t2;
2461
   #ifdef ALT_ECC_SIZE
2462
       rx = R->key->x;
2463
       ry = R->key->y;
2464
       rz = R->key->z;
2465
   #endif
2466
   }
2467
   else
2468
#endif /* WOLFSSL_SMALL_STACK_CACHE */
2469
#endif
2470
0
   {
2471
0
      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2472
0
      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2473
   #ifdef MP_INT_SIZE_CHECK_NULL
2474
      if (t1 == NULL || t2 == NULL) {
2475
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2476
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2477
         return MEMORY_E;
2478
      }
2479
   #endif
2480
   #ifdef ALT_ECC_SIZE
2481
      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2482
      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2483
      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2484
   #ifdef MP_INT_SIZE_CHECK_NULL
2485
      if (rx == NULL || ry == NULL || rz == NULL) {
2486
          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2487
          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2488
          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2489
          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2490
          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2491
          return MEMORY_E;
2492
      }
2493
   #endif
2494
   #endif
2495
0
   }
2496
2497
0
   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2498
0
   if (err == MP_OKAY) {
2499
0
      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2500
0
   }
2501
0
   if (err != MP_OKAY) {
2502
#ifdef WOLFSSL_SMALL_STACK
2503
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2504
      if (R->key == NULL)
2505
   #endif
2506
#endif
2507
0
      {
2508
      #ifdef ALT_ECC_SIZE
2509
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2510
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2511
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2512
      #endif
2513
0
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2514
0
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2515
0
      }
2516
0
      return err;
2517
0
   }
2518
2519
/* If use ALT_ECC_SIZE we need to use local stack variable since
2520
   ecc_point x,y,z is reduced size */
2521
#ifdef ALT_ECC_SIZE
2522
   /* Use local stack variable */
2523
   x = rx;
2524
   y = ry;
2525
   z = rz;
2526
2527
   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2528
   if (err == MP_OKAY) {
2529
      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2530
   }
2531
   if (err == MP_OKAY) {
2532
      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2533
   }
2534
   if (err != MP_OKAY) {
2535
#ifdef WOLFSSL_SMALL_STACK
2536
   #ifdef WOLFSSL_SMALL_STACK_CACHE
2537
      if (R->key == NULL)
2538
   #endif
2539
#endif
2540
      {
2541
      #ifdef ALT_ECC_SIZE
2542
         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2543
         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2544
         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2545
      #endif
2546
         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2547
         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2548
      }
2549
      return err;
2550
   }
2551
#else
2552
   /* Use destination directly */
2553
0
   x = R->x;
2554
0
   y = R->y;
2555
0
   z = R->z;
2556
0
#endif
2557
2558
0
   if (err == MP_OKAY)
2559
0
       err = mp_copy(P->x, x);
2560
0
   if (err == MP_OKAY)
2561
0
       err = mp_copy(P->y, y);
2562
0
   if (err == MP_OKAY)
2563
0
       err = mp_copy(P->z, z);
2564
2565
   /* T1 = Z * Z */
2566
0
   if (err == MP_OKAY)
2567
0
       err = mp_sqr(z, t1);
2568
0
   if (err == MP_OKAY)
2569
0
       err = mp_montgomery_reduce(t1, modulus, mp);
2570
2571
   /* Z = Y * Z */
2572
0
   if (err == MP_OKAY)
2573
0
       err = mp_mul(z, y, z);
2574
0
   if (err == MP_OKAY)
2575
0
       err = mp_montgomery_reduce(z, modulus, mp);
2576
2577
   /* Z = 2Z */
2578
0
   if (err == MP_OKAY)
2579
0
       err = mp_addmod_ct(z, z, modulus, z);
2580
2581
   /* Determine if curve "a" should be used in calc */
2582
#ifdef WOLFSSL_CUSTOM_CURVES
2583
   if (err == MP_OKAY) {
2584
      /* Use a and prime to determine if a == 3 */
2585
      err = mp_submod(modulus, a, modulus, t2);
2586
   }
2587
   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
2588
      /* T2 = X * X */
2589
      err = mp_sqr(x, t2);
2590
      if (err == MP_OKAY)
2591
          err = mp_montgomery_reduce(t2, modulus, mp);
2592
      /* T1 = T2 + T1 */
2593
      if (err == MP_OKAY)
2594
          err = mp_addmod_ct(t2, t2, modulus, t1);
2595
      /* T1 = T2 + T1 */
2596
      if (err == MP_OKAY)
2597
          err = mp_addmod_ct(t1, t2, modulus, t1);
2598
   }
2599
   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
2600
      /* use "a" in calc */
2601
2602
      /* T2 = T1 * T1 */
2603
      err = mp_sqr(t1, t2);
2604
      if (err == MP_OKAY)
2605
          err = mp_montgomery_reduce(t2, modulus, mp);
2606
      /* T1 = T2 * a */
2607
      if (err == MP_OKAY)
2608
          err = mp_mulmod(t2, a, modulus, t1);
2609
      /* T2 = X * X */
2610
      if (err == MP_OKAY)
2611
          err = mp_sqr(x, t2);
2612
      if (err == MP_OKAY)
2613
          err = mp_montgomery_reduce(t2, modulus, mp);
2614
      /* T1 = T2 + T1 */
2615
      if (err == MP_OKAY)
2616
          err = mp_addmod_ct(t1, t2, modulus, t1);
2617
      /* T1 = T2 + T1 */
2618
      if (err == MP_OKAY)
2619
          err = mp_addmod_ct(t1, t2, modulus, t1);
2620
      /* T1 = T2 + T1 */
2621
      if (err == MP_OKAY)
2622
          err = mp_addmod_ct(t1, t2, modulus, t1);
2623
   }
2624
   else
2625
#endif /* WOLFSSL_CUSTOM_CURVES */
2626
0
   {
2627
      /* assumes "a" == 3 */
2628
0
      (void)a;
2629
2630
      /* T2 = X - T1 */
2631
0
      if (err == MP_OKAY)
2632
0
          err = mp_submod_ct(x, t1, modulus, t2);
2633
      /* T1 = X + T1 */
2634
0
      if (err == MP_OKAY)
2635
0
          err = mp_addmod_ct(t1, x, modulus, t1);
2636
      /* T2 = T1 * T2 */
2637
0
      if (err == MP_OKAY)
2638
0
          err = mp_mul(t1, t2, t2);
2639
0
      if (err == MP_OKAY)
2640
0
          err = mp_montgomery_reduce(t2, modulus, mp);
2641
2642
      /* T1 = 2T2 */
2643
0
      if (err == MP_OKAY)
2644
0
          err = mp_addmod_ct(t2, t2, modulus, t1);
2645
      /* T1 = T1 + T2 */
2646
0
      if (err == MP_OKAY)
2647
0
          err = mp_addmod_ct(t1, t2, modulus, t1);
2648
0
   }
2649
2650
   /* Y = 2Y */
2651
0
   if (err == MP_OKAY)
2652
0
       err = mp_addmod_ct(y, y, modulus, y);
2653
   /* Y = Y * Y */
2654
0
   if (err == MP_OKAY)
2655
0
       err = mp_sqr(y, y);
2656
0
   if (err == MP_OKAY)
2657
0
       err = mp_montgomery_reduce(y, modulus, mp);
2658
2659
   /* T2 = Y * Y */
2660
0
   if (err == MP_OKAY)
2661
0
       err = mp_sqr(y, t2);
2662
0
   if (err == MP_OKAY)
2663
0
       err = mp_montgomery_reduce(t2, modulus, mp);
2664
2665
   /* T2 = T2/2 */
2666
0
   if (err == MP_OKAY)
2667
0
       err = mp_div_2_mod_ct(t2, modulus, t2);
2668
2669
   /* Y = Y * X */
2670
0
   if (err == MP_OKAY)
2671
0
       err = mp_mul(y, x, y);
2672
0
   if (err == MP_OKAY)
2673
0
       err = mp_montgomery_reduce(y, modulus, mp);
2674
2675
   /* X = T1 * T1 */
2676
0
   if (err == MP_OKAY)
2677
0
       err = mp_sqr(t1, x);
2678
0
   if (err == MP_OKAY)
2679
0
       err = mp_montgomery_reduce(x, modulus, mp);
2680
2681
   /* X = X - Y */
2682
0
   if (err == MP_OKAY)
2683
0
       err = mp_submod_ct(x, y, modulus, x);
2684
   /* X = X - Y */
2685
0
   if (err == MP_OKAY)
2686
0
       err = mp_submod_ct(x, y, modulus, x);
2687
2688
   /* Y = Y - X */
2689
0
   if (err == MP_OKAY)
2690
0
       err = mp_submod_ct(y, x, modulus, y);
2691
   /* Y = Y * T1 */
2692
0
   if (err == MP_OKAY)
2693
0
       err = mp_mul(y, t1, y);
2694
0
   if (err == MP_OKAY)
2695
0
       err = mp_montgomery_reduce(y, modulus, mp);
2696
2697
   /* Y = Y - T2 */
2698
0
   if (err == MP_OKAY)
2699
0
       err = mp_submod_ct(y, t2, modulus, y);
2700
2701
#ifdef ALT_ECC_SIZE
2702
   if (err == MP_OKAY)
2703
       err = mp_copy(x, R->x);
2704
   if (err == MP_OKAY)
2705
       err = mp_copy(y, R->y);
2706
   if (err == MP_OKAY)
2707
       err = mp_copy(z, R->z);
2708
#endif
2709
2710
   /* clean up */
2711
0
   mp_clear(t1);
2712
0
   mp_clear(t2);
2713
2714
#ifdef WOLFSSL_SMALL_STACK
2715
#ifdef WOLFSSL_SMALL_STACK_CACHE
2716
   if (R->key == NULL)
2717
#endif
2718
#endif
2719
0
   {
2720
    #ifdef ALT_ECC_SIZE
2721
       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2722
       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2723
       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2724
    #endif
2725
0
       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2726
0
       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2727
0
    }
2728
2729
0
   return err;
2730
#else
2731
    int modBits = mp_count_bits(modulus);
2732
2733
    (void)a;
2734
    (void)mp;
2735
2736
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
2737
    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
2738
       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
2739
    }
2740
#endif
2741
#ifndef WOLFSSL_SP_NO_256
2742
    if (modBits == 256) {
2743
        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
2744
    }
2745
#endif
2746
#ifdef WOLFSSL_SP_384
2747
    if (modBits == 384) {
2748
        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
2749
    }
2750
#endif
2751
#ifdef WOLFSSL_SP_521
2752
    if (modBits == 521) {
2753
        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
2754
    }
2755
#endif
2756
    return ECC_BAD_ARG_E;
2757
#endif
2758
0
}
2759
2760
int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
2761
                             mp_int* modulus, mp_digit mp)
2762
0
{
2763
0
    if (P == NULL || R == NULL || modulus == NULL)
2764
0
        return ECC_BAD_ARG_E;
2765
2766
0
    if (mp_cmp(P->x, modulus) != MP_LT ||
2767
0
        mp_cmp(P->y, modulus) != MP_LT ||
2768
0
        mp_cmp(P->z, modulus) != MP_LT) {
2769
0
        return ECC_OUT_OF_RANGE_E;
2770
0
    }
2771
2772
0
    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
2773
0
}
2774
2775
#if !defined(FREESCALE_LTC_ECC) && \
2776
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY)) && \
2777
    !defined(WOLFSSL_CRYPTOCELL)
2778
2779
2780
/**
2781
  Map a projective Jacobian point back to affine space
2782
  P        [in/out] The point to map
2783
  modulus  The modulus of the field the ECC curve is in
2784
  mp       The "b" value from montgomery_setup()
2785
  ct       Operation should be constant time.
2786
  return   MP_OKAY on success
2787
*/
2788
int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
2789
0
{
2790
0
    int err = MP_OKAY;
2791
0
    (void)ct;
2792
2793
0
    if (P == NULL || modulus == NULL){
2794
0
        return ECC_BAD_ARG_E;
2795
0
    }
2796
0
    {
2797
0
        #if !defined(WOLFSSL_SP_MATH)
2798
0
        DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2799
0
        DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2800
        #ifdef ALT_ECC_SIZE
2801
        DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2802
        DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2803
        DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
2804
        #endif
2805
0
        mp_int *x, *y, *z;
2806
2807
0
        if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
2808
0
            return WC_KEY_SIZE_E;
2809
0
        }
2810
2811
        /* special case for point at infinity */
2812
0
        if (mp_cmp_d(P->z, 0) == MP_EQ) {
2813
0
            err = mp_set(P->x, 0);
2814
0
            if (err == MP_OKAY)
2815
0
                err = mp_set(P->y, 0);
2816
0
            if (err == MP_OKAY)
2817
0
                err = mp_set(P->z, 1);
2818
0
            return err;
2819
0
        }
2820
2821
        #ifdef WOLFSSL_SMALL_STACK
2822
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2823
        if (P->key != NULL) {
2824
            t1 = P->key->t1;
2825
            t2 = P->key->t2;
2826
        #ifdef ALT_ECC_SIZE
2827
            rx = P->key->x;
2828
            ry = P->key->y;
2829
            rz = P->key->z;
2830
        #endif
2831
        }
2832
        else
2833
        #endif /* WOLFSSL_SMALL_STACK_CACHE */
2834
        #endif
2835
0
        {
2836
0
            NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2837
0
            NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2838
        #ifdef MP_INT_SIZE_CHECK_NULL
2839
            if (t1 == NULL || t2 == NULL) {
2840
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2841
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2842
                return MEMORY_E;
2843
            }
2844
        #endif
2845
        #ifdef ALT_ECC_SIZE
2846
            NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2847
            NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2848
            NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
2849
        #ifdef MP_INT_SIZE_CHECK_NULL
2850
            if (rx == NULL || ry == NULL || rz == NULL) {
2851
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2852
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2853
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2854
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2855
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2856
                return MEMORY_E;
2857
            }
2858
        #endif
2859
        #endif
2860
0
        }
2861
2862
0
        err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
2863
0
        if (err == MP_OKAY) {
2864
0
            err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
2865
0
        }
2866
0
        if (err != MP_OKAY) {
2867
        #ifdef WOLFSSL_SMALL_STACK
2868
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2869
            if (P->key == NULL)
2870
        #endif
2871
        #endif
2872
0
            {
2873
            #ifdef ALT_ECC_SIZE
2874
                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2875
                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2876
                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2877
            #endif
2878
0
                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2879
0
                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2880
0
            }
2881
0
            return MEMORY_E;
2882
0
        }
2883
2884
        #ifdef ALT_ECC_SIZE
2885
        /* Use local stack variable */
2886
        x = rx;
2887
        y = ry;
2888
        z = rz;
2889
2890
        err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
2891
        if (err == MP_OKAY) {
2892
            err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
2893
        }
2894
        if (err == MP_OKAY) {
2895
            err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
2896
        }
2897
        if (err != MP_OKAY) {
2898
            goto done;
2899
        }
2900
2901
        if (err == MP_OKAY)
2902
            err = mp_copy(P->x, x);
2903
        if (err == MP_OKAY)
2904
            err = mp_copy(P->y, y);
2905
        if (err == MP_OKAY)
2906
            err = mp_copy(P->z, z);
2907
2908
        if (err != MP_OKAY) {
2909
            goto done;
2910
        }
2911
        #else
2912
        /* Use destination directly */
2913
0
        x = P->x;
2914
0
        y = P->y;
2915
0
        z = P->z;
2916
0
        #endif
2917
2918
        /* get 1/z */
2919
0
        if (err == MP_OKAY) {
2920
0
        #if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
2921
0
                        defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
2922
0
            if (ct) {
2923
0
                err = mp_invmod_mont_ct(z, modulus, t1, mp);
2924
0
                if (err == MP_OKAY)
2925
0
                    err = mp_montgomery_reduce(t1, modulus, mp);
2926
0
            }
2927
0
            else
2928
0
        #endif
2929
0
            {
2930
                /* first map z back to normal */
2931
0
                err = mp_montgomery_reduce(z, modulus, mp);
2932
0
                if (err == MP_OKAY)
2933
0
                    err = mp_invmod(z, modulus, t1);
2934
0
            }
2935
0
        }
2936
2937
        /* get 1/z^2 and 1/z^3 */
2938
0
        if (err == MP_OKAY)
2939
0
            err = mp_sqr(t1, t2);
2940
0
        if (err == MP_OKAY)
2941
0
            err = mp_mod(t2, modulus, t2);
2942
0
        if (err == MP_OKAY)
2943
0
            err = mp_mul(t1, t2, t1);
2944
0
        if (err == MP_OKAY)
2945
0
            err = mp_mod(t1, modulus, t1);
2946
2947
        /* multiply against x/y */
2948
0
        if (err == MP_OKAY)
2949
0
            err = mp_mul(x, t2, x);
2950
0
        if (err == MP_OKAY)
2951
0
            err = mp_montgomery_reduce(x, modulus, mp);
2952
0
        if (err == MP_OKAY)
2953
0
            err = mp_mul(y, t1, y);
2954
0
        if (err == MP_OKAY)
2955
0
            err = mp_montgomery_reduce(y, modulus, mp);
2956
2957
0
        if (err == MP_OKAY)
2958
0
            err = mp_set(z, 1);
2959
2960
        #ifdef ALT_ECC_SIZE
2961
        /* return result */
2962
        if (err == MP_OKAY)
2963
            err = mp_copy(x, P->x);
2964
        if (err == MP_OKAY)
2965
            err = mp_copy(y, P->y);
2966
        if (err == MP_OKAY)
2967
            err = mp_copy(z, P->z);
2968
2969
        done:
2970
        #endif
2971
2972
        /* clean up */
2973
0
        mp_clear(t1);
2974
0
        mp_clear(t2);
2975
2976
        #ifdef WOLFSSL_SMALL_STACK
2977
        #ifdef WOLFSSL_SMALL_STACK_CACHE
2978
        if (P->key == NULL)
2979
        #endif
2980
        #endif
2981
0
        {
2982
        #ifdef ALT_ECC_SIZE
2983
            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
2984
            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
2985
            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
2986
        #endif
2987
0
            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
2988
0
            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
2989
0
        }
2990
2991
0
        return err;
2992
        /* end !defined(WOLFSSL_SP_MATH) */
2993
2994
        #else
2995
        /* begin defined(WOLFSSL_SP_MATH) */
2996
        if (P == NULL || modulus == NULL)
2997
            return ECC_BAD_ARG_E;
2998
2999
        (void)mp;
3000
        (void)ct;
3001
3002
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3003
        if ((mp_count_bits(modulus) == 256) &&
3004
            (!mp_is_bit_set(modulus, 224))) {
3005
            err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
3006
        }
3007
        #elif !defined(WOLFSSL_SP_NO_256)
3008
        if (mp_count_bits(modulus) == 256) {
3009
            err = sp_ecc_map_256(P->x, P->y, P->z);
3010
        }
3011
        #elif defined(WOLFSSL_SP_384)
3012
        if (mp_count_bits(modulus) == 384) {
3013
            err = sp_ecc_map_384(P->x, P->y, P->z);
3014
        }
3015
        #elif defined(WOLFSSL_SP_521)
3016
        if (mp_count_bits(modulus) == 521) {
3017
            err = sp_ecc_map_521(P->x, P->y, P->z);
3018
        }
3019
        #else
3020
        err = ECC_BAD_ARG_E;
3021
        #endif
3022
3023
        WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
3024
    return err;
3025
#endif /* WOLFSSL_SP_MATH */
3026
0
    }
3027
0
}
3028
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
3029
3030
int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
3031
0
{
3032
0
    return ecc_map_ex(P, modulus, mp, 0);
3033
0
}
3034
#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
3035
3036
#if !defined(FREESCALE_LTC_ECC) && \
3037
    (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_VERIFY_ONLY)) && \
3038
    !defined(WOLFSSL_CRYPTOCELL)
3039
#if !defined(WOLFSSL_SP_MATH)
3040
3041
#ifndef ECC_TIMING_RESISTANT
3042
3043
/* size of sliding window, don't change this! */
3044
#define WINSIZE  4
3045
#define M_POINTS 8
3046
3047
static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
3048
    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3049
{
3050
   int      err = MP_OKAY;
3051
   int      i;
3052
   int      first = 1, bitbuf = 0, bitcpy = 0, j;
3053
   int      bitcnt = 0, mode = 0, digidx = 0;
3054
   mp_digit buf;
3055
   int      infinity;
3056
3057
   (void)rng;
3058
3059
   /* calc the M tab, which holds kG for k==8..15 */
3060
   /* M[0] == 8G */
3061
   if (err == MP_OKAY)
3062
       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
3063
   if (err == MP_OKAY)
3064
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3065
   if (err == MP_OKAY)
3066
       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
3067
3068
   /* now find (8+k)G for k=1..7 */
3069
   if (err == MP_OKAY)
3070
       for (j = 9; j < 16; j++) {
3071
           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
3072
                                                        modulus, mp, &infinity);
3073
           if (err != MP_OKAY) break;
3074
       }
3075
3076
   /* setup sliding window */
3077
   if (err == MP_OKAY) {
3078
       mode   = 0;
3079
       bitcnt = 1;
3080
       buf    = 0;
3081
       digidx = mp_get_digit_count(k) - 1;
3082
       bitcpy = bitbuf = 0;
3083
       first  = 1;
3084
3085
       /* perform ops */
3086
       for (;;) {
3087
           /* grab next digit as required */
3088
           if (--bitcnt == 0) {
3089
               if (digidx == -1) {
3090
                   break;
3091
               }
3092
               buf    = mp_get_digit(k, digidx);
3093
               bitcnt = (int) DIGIT_BIT;
3094
               --digidx;
3095
           }
3096
3097
           /* grab the next msb from the ltiplicand */
3098
           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3099
           buf <<= 1;
3100
3101
           /* skip leading zero bits */
3102
           if (mode == 0 && i == 0)
3103
               continue;
3104
3105
           /* if the bit is zero and mode == 1 then we double */
3106
           if (mode == 1 && i == 0) {
3107
               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3108
               if (err != MP_OKAY) break;
3109
               continue;
3110
           }
3111
3112
           /* else we add it to the window */
3113
           bitbuf |= (i << (WINSIZE - ++bitcpy));
3114
           mode = 2;
3115
3116
           if (bitcpy == WINSIZE) {
3117
               /* if this is the first window we do a simple copy */
3118
               if (first == 1) {
3119
                   /* R = kG [k = first window] */
3120
                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
3121
                   if (err != MP_OKAY) break;
3122
3123
                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
3124
                   if (err != MP_OKAY) break;
3125
3126
                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
3127
                   first = 0;
3128
               } else {
3129
                   /* normal window */
3130
                   /* ok window is filled so double as required and add  */
3131
                   /* double first */
3132
                   for (j = 0; j < WINSIZE; j++) {
3133
                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
3134
                                                                            mp);
3135
                       if (err != MP_OKAY) break;
3136
                   }
3137
                   if (err != MP_OKAY) break;  /* out of first for(;;) */
3138
3139
                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
3140
                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
3141
                                                     a, modulus, mp, &infinity);
3142
               }
3143
               if (err != MP_OKAY) break;
3144
               /* empty window and reset */
3145
               bitcpy = bitbuf = 0;
3146
               mode = 1;
3147
           }
3148
       }
3149
   }
3150
3151
   /* if bits remain then double/add */
3152
   if (err == MP_OKAY) {
3153
       if (mode == 2 && bitcpy > 0) {
3154
           /* double then add */
3155
           for (j = 0; j < bitcpy; j++) {
3156
               /* only double if we have had at least one add first */
3157
               if (first == 0) {
3158
                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
3159
                   if (err != MP_OKAY) break;
3160
               }
3161
3162
               bitbuf <<= 1;
3163
               if ((bitbuf & (1 << WINSIZE)) != 0) {
3164
                   if (first == 1) {
3165
                       /* first add, so copy */
3166
                       err = mp_copy(tG->x, R->x);
3167
                       if (err != MP_OKAY) break;
3168
3169
                       err = mp_copy(tG->y, R->y);
3170
                       if (err != MP_OKAY) break;
3171
3172
                       err = mp_copy(tG->z, R->z);
3173
                       if (err != MP_OKAY) break;
3174
                       first = 0;
3175
                   } else {
3176
                       /* then add */
3177
                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
3178
                                                                 mp, &infinity);
3179
                       if (err != MP_OKAY) break;
3180
                   }
3181
               }
3182
           }
3183
       }
3184
   }
3185
3186
   #undef WINSIZE
3187
3188
   return err;
3189
}
3190
3191
#else
3192
3193
static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
3194
    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
3195
0
{
3196
0
    int err = MP_OKAY;
3197
3198
0
    err = mp_montgomery_calc_normalization(mu, modulus);
3199
    /* Generate random value to multiply into p->z. */
3200
0
    if (err == MP_OKAY)
3201
0
        err = wc_ecc_gen_k(rng, size, ty, modulus);
3202
    /* Convert to montogmery form. */
3203
0
    if (err == MP_OKAY)
3204
0
        err = mp_mulmod(ty, mu, modulus, ty);
3205
    /* Multiply random value into p->z. */
3206
0
    if (err == MP_OKAY)
3207
0
        err = mp_mul(p->z, ty, p->z);
3208
0
    if (err == MP_OKAY)
3209
0
        err = mp_montgomery_reduce(p->z, modulus, mp);
3210
    /* Square random value for X (X' = X / Z^2). */
3211
0
    if (err == MP_OKAY)
3212
0
        err = mp_sqr(ty, tx);
3213
0
    if (err == MP_OKAY)
3214
0
        err = mp_montgomery_reduce(tx, modulus, mp);
3215
    /* Multiply square of random by random value for Y. */
3216
0
    if (err == MP_OKAY)
3217
0
        err = mp_mul(ty, tx, ty);
3218
0
    if (err == MP_OKAY)
3219
0
        err = mp_montgomery_reduce(ty, modulus, mp);
3220
    /* Multiply square into X. */
3221
0
    if (err == MP_OKAY)
3222
0
        err = mp_mul(p->x, tx, p->x);
3223
0
    if (err == MP_OKAY)
3224
0
        err = mp_montgomery_reduce(p->x, modulus, mp);
3225
    /* Multiply cube into Y (Y' = Y / Z^3). */
3226
0
    if (err == MP_OKAY)
3227
0
        err = mp_mul(p->y, ty, p->y);
3228
0
    if (err == MP_OKAY)
3229
0
        err = mp_montgomery_reduce(p->y, modulus, mp);
3230
3231
0
    return err;
3232
0
}
3233
3234
#ifndef WC_PROTECT_ENCRYPTED_MEM
3235
0
#define M_POINTS 3
3236
3237
/* Joye double-add ladder.
3238
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3239
 * by Marc Joye (2007)
3240
 *
3241
 * Algorithm 1':
3242
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3243
 *   Output: Q = kP
3244
 *   1: R[0] = P; R[1] = P
3245
 *   2: for j = 1 to t-1 do
3246
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3247
 *   4: end for
3248
 *   5: b = k[0]; R[b] = R[b] - P
3249
 *   6: return R[0]
3250
 *
3251
 * Assumes: k < order.
3252
 */
3253
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3254
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3255
0
{
3256
0
    int      err = MP_OKAY;
3257
0
    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
3258
0
    int      i;
3259
0
    int      j = 1;
3260
0
    int      cnt = DIGIT_BIT;
3261
0
    int      t = 0;
3262
0
    mp_digit b;
3263
0
    mp_digit v = 0;
3264
0
    mp_int*  kt = R[2]->x;
3265
0
#ifndef WC_NO_CACHE_RESISTANT
3266
    /* First bit always 1 (fix at end) and swap equals first bit */
3267
0
    int      swap = 1;
3268
0
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
3269
0
#endif
3270
0
    int      infinity;
3271
3272
0
#ifndef WC_NO_CACHE_RESISTANT
3273
0
    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
3274
0
    if (err == MP_OKAY)
3275
0
        err = mp_init(tmp);
3276
0
#endif
3277
3278
    /* Step 1: R[0] = P; R[1] = P */
3279
    /* R[0] = P */
3280
0
    if (err == MP_OKAY)
3281
0
        err = mp_copy(P->x, R[0]->x);
3282
0
    if (err == MP_OKAY)
3283
0
        err = mp_copy(P->y, R[0]->y);
3284
0
    if (err == MP_OKAY)
3285
0
        err = mp_copy(P->z, R[0]->z);
3286
3287
    /* R[1] = P */
3288
0
    if (err == MP_OKAY)
3289
0
        err = mp_copy(P->x, R[1]->x);
3290
0
    if (err == MP_OKAY)
3291
0
        err = mp_copy(P->y, R[1]->y);
3292
0
    if (err == MP_OKAY)
3293
0
        err = mp_copy(P->z, R[1]->z);
3294
3295
    /* Randomize z ordinates to obfuscate timing. */
3296
0
    if ((err == MP_OKAY) && (rng != NULL))
3297
0
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
3298
0
    if ((err == MP_OKAY) && (rng != NULL))
3299
0
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
3300
3301
0
    if (err == MP_OKAY) {
3302
        /* Order could be one greater than the size of the modulus. */
3303
0
        t = mp_count_bits(modulus) + 1;
3304
0
        v = k->dp[0] >> 1;
3305
0
        if (cnt > t) {
3306
0
            cnt = t;
3307
0
        }
3308
0
        err = mp_copy(k, kt);
3309
0
    }
3310
0
    if (err == MP_OKAY) {
3311
0
        err = mp_grow(kt, (int)modulus->used + 1);
3312
0
    }
3313
    /* Step 2: for j = 1 to t-1 do */
3314
0
    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
3315
0
        if (--cnt == 0) {
3316
0
            v = kt->dp[j++];
3317
0
            cnt = DIGIT_BIT;
3318
0
        }
3319
3320
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3321
0
        b = v & 1;
3322
0
        v >>= 1;
3323
#ifdef WC_NO_CACHE_RESISTANT
3324
        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
3325
        if (err == MP_OKAY) {
3326
            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
3327
                                                        modulus, mp, &infinity);
3328
        }
3329
#else
3330
        /* Swap R[0] and R[1] if other index is needed. */
3331
0
        swap ^= (int)b;
3332
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3333
0
            tmp);
3334
0
        if (err == MP_OKAY) {
3335
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3336
0
                tmp);
3337
0
        }
3338
0
        if (err == MP_OKAY) {
3339
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3340
0
                tmp);
3341
0
        }
3342
0
        swap = (int)b;
3343
3344
0
        if (err == MP_OKAY)
3345
0
            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
3346
0
        if (err == MP_OKAY) {
3347
0
            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
3348
0
                                                                 mp, &infinity);
3349
0
        }
3350
0
#endif /* WC_NO_CACHE_RESISTANT */
3351
0
    }
3352
    /* Step 4: end for */
3353
0
#ifndef WC_NO_CACHE_RESISTANT
3354
    /* Swap back if last bit is 0. */
3355
0
    swap ^= 1;
3356
0
    if (err == MP_OKAY) {
3357
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
3358
0
            tmp);
3359
0
    }
3360
0
    if (err == MP_OKAY) {
3361
0
        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
3362
0
            tmp);
3363
0
    }
3364
0
    if (err == MP_OKAY) {
3365
0
        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
3366
0
            tmp);
3367
0
    }
3368
0
#endif
3369
3370
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3371
    /* R[2] = -P */
3372
0
    if (err == MP_OKAY)
3373
0
        err = mp_copy(P->x, R[2]->x);
3374
0
    if (err == MP_OKAY)
3375
0
        err = mp_sub(modulus, P->y, R[2]->y);
3376
0
    if (err == MP_OKAY)
3377
0
        err = mp_copy(P->z, R[2]->z);
3378
    /* Subtract point by adding negative. */
3379
0
    if (err == MP_OKAY) {
3380
0
        b = k->dp[0] & 1;
3381
#ifdef WC_NO_CACHE_RESISTANT
3382
        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
3383
                                                                     &infinity);
3384
#else
3385
        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
3386
0
        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
3387
0
            tmp);
3388
0
        if (err == MP_OKAY) {
3389
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3390
0
                (int)b, tmp);
3391
0
        }
3392
0
        if (err == MP_OKAY) {
3393
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3394
0
                (int)b, tmp);
3395
0
        }
3396
0
        if (err == MP_OKAY)
3397
0
            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
3398
0
                                                                 mp, &infinity);
3399
        /* Swap back if necessary. */
3400
0
        if (err == MP_OKAY) {
3401
0
            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
3402
0
                (int)b, tmp);
3403
0
        }
3404
0
        if (err == MP_OKAY) {
3405
0
            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
3406
0
                (int)b, tmp);
3407
0
        }
3408
0
        if (err == MP_OKAY) {
3409
0
            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
3410
0
                (int)b, tmp);
3411
0
        }
3412
0
#endif
3413
0
    }
3414
3415
    /* Step 6: return R[0] */
3416
0
    if (err == MP_OKAY)
3417
0
        err = mp_copy(R[0]->x, Q->x);
3418
0
    if (err == MP_OKAY)
3419
0
        err = mp_copy(R[0]->y, Q->y);
3420
0
    if (err == MP_OKAY)
3421
0
        err = mp_copy(R[0]->z, Q->z);
3422
3423
#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
3424
    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
3425
#endif
3426
3427
0
    return err;
3428
0
}
3429
3430
#else
3431
/* Number of points to allocate for use during scalar multiplication. */
3432
#define M_POINTS        5
3433
/* Last of the points is used as a temporary during calculations. */
3434
#define TMP_IDX         M_POINTS - 1
3435
3436
static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
3437
    int digits, int m)
3438
{
3439
    int i;
3440
3441
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
3442
    /* Only using positive numbers in ECC operations. */
3443
    ra->sign = 0;
3444
    rb->sign = 0;
3445
#endif
3446
    /* Don't store 0 when mask is 0, it will be in a register. */
3447
    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
3448
    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
3449
    for (i = 0; i < digits; i++) {
3450
        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3451
                    a->dp[i];
3452
        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
3453
                    b->dp[i];
3454
    }
3455
}
3456
3457
static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
3458
    ecc_point* b, int digits, int m)
3459
{
3460
    /* Conditionally swap each ordinate. */
3461
    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
3462
    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
3463
    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
3464
}
3465
3466
/* Joye double-add ladder.
3467
 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
3468
 * by Marc Joye (2007)
3469
 *
3470
 * Algorithm 1':
3471
 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
3472
 *   Output: Q = kP
3473
 *   1: R[0] = P; R[1] = P
3474
 *   2: for j = 1 to t-1 do
3475
 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
3476
 *   4: end for
3477
 *   5: b = k[0]; R[b] = R[b] - P
3478
 *   6: return R[0]
3479
 *
3480
 * Assumes: k < order.
3481
 */
3482
static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
3483
    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
3484
{
3485
    int          err = MP_OKAY;
3486
    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
3487
    int          i;
3488
    int          j = 1;
3489
    int          cnt;
3490
    int          t = 0;
3491
    mp_int*      kt = R[TMP_IDX]->x;
3492
    /* First bit always 1 (fix at end) and swap equals first bit */
3493
    register int swap = 1;
3494
    /* Which pair of points has current value. R[0,1] or R[2,3] */
3495
    int          set = 0;
3496
    int          infinity;
3497
3498
    /* Step 1: R[0] = P; R[1] = P */
3499
    /* R[0] = P */
3500
    if (err == MP_OKAY)
3501
        err = mp_copy(P->x, R[0]->x);
3502
    if (err == MP_OKAY)
3503
        err = mp_copy(P->y, R[0]->y);
3504
    if (err == MP_OKAY)
3505
        err = mp_copy(P->z, R[0]->z);
3506
3507
    /* R[1] = P */
3508
    if (err == MP_OKAY)
3509
        err = mp_copy(P->x, R[1]->x);
3510
    if (err == MP_OKAY)
3511
        err = mp_copy(P->y, R[1]->y);
3512
    if (err == MP_OKAY)
3513
        err = mp_copy(P->z, R[1]->z);
3514
3515
    /* Randomize z ordinates to obfuscate timing. */
3516
    if ((err == MP_OKAY) && (rng != NULL))
3517
        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
3518
                           R[TMP_IDX]->y, kt);
3519
    if ((err == MP_OKAY) && (rng != NULL))
3520
        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
3521
                           R[TMP_IDX]->y, kt);
3522
3523
    if (err == MP_OKAY) {
3524
        /* Order could be one greater than the size of the modulus. */
3525
        t = mp_count_bits(modulus) + 1;
3526
        err = mp_copy(k, kt);
3527
    }
3528
    if (err == MP_OKAY) {
3529
        err = mp_grow(kt, modulus->used + 1);
3530
    }
3531
    /* Step 2: for j = 1 to t-1 do */
3532
    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
3533
        if (++cnt == DIGIT_BIT) {
3534
            j++;
3535
            cnt = 0;
3536
        }
3537
3538
        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
3539
        /* Swap R[0] and R[1] if other index is needed. */
3540
        /* Ensure 'swap' changes when shifted word is 0. */
3541
        swap += (kt->dp[j] >> cnt) + 2;
3542
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3543
                              R[set + 0], R[set + 1], modulus->used, swap);
3544
        /* Change to operate on set copied into. */
3545
        set = 2 - set;
3546
        /* Ensure 'swap' changes to a previously unseen value. */
3547
        swap += (kt->dp[j] >> cnt) + swap;
3548
3549
        /* R[0] = 2*R[0] */
3550
        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
3551
                                            mp);
3552
        if (err == MP_OKAY) {
3553
            /* R[0] = R[1] + R[0] */
3554
            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
3555
                                         R[set + 0], a, modulus, mp, &infinity);
3556
        }
3557
        /*  R[1]->z * 2 - same point. */
3558
        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
3559
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3560
        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
3561
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3562
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3563
        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
3564
    }
3565
    /* Step 4: end for */
3566
    /* Swap back if last bit is 0. */
3567
    /* Ensure 'swap' changes. */
3568
    swap += 1;
3569
    if (err == MP_OKAY) {
3570
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3571
                              R[set + 0], R[set + 1], modulus->used, swap);
3572
        set = 2 - set;
3573
    }
3574
3575
    /* Step 5: b = k[0]; R[b] = R[b] - P */
3576
    /* R[TMP_IDX] = -P */
3577
    if (err == MP_OKAY)
3578
        err = mp_copy(P->x, R[TMP_IDX]->x);
3579
    if (err == MP_OKAY)
3580
        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
3581
    if (err == MP_OKAY)
3582
        err = mp_copy(P->z, R[TMP_IDX]->z);
3583
    /* Subtract point by adding negative. */
3584
    if (err == MP_OKAY) {
3585
        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
3586
         * Last bit of k->dp[0] is being used to make decision to swap.
3587
         */
3588
        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3589
                              R[set + 0], R[set + 1], modulus->used,
3590
                              (int)k->dp[0]);
3591
        set = 2 - set;
3592
        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
3593
                                            a, modulus, mp, &infinity);
3594
        /* Swap back if necessary. */
3595
        if (err == MP_OKAY) {
3596
            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
3597
                                  R[set + 0], R[set + 1], modulus->used,
3598
                                  (int)k->dp[0]);
3599
            set = 2 - set;
3600
        }
3601
    }
3602
3603
    /* Step 6: return R[0] */
3604
    if (err == MP_OKAY)
3605
        err = mp_copy(R[set + 0]->x, Q->x);
3606
    if (err == MP_OKAY)
3607
        err = mp_copy(R[set + 0]->y, Q->y);
3608
    if (err == MP_OKAY)
3609
        err = mp_copy(R[set + 0]->z, Q->z);
3610
3611
    return err;
3612
}
3613
3614
#endif
3615
3616
#endif
3617
3618
/* Convert the point to montgomery form.
3619
 *
3620
 * @param  [in]   p        Point to convert.
3621
 * @param  [out]  r        Point in montgomery form.
3622
 * @param  [in]   modulus  Modulus of ordinates.
3623
 * @return  0 on success.
3624
 * @return  -ve on failure.
3625
 */
3626
static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
3627
                             void* heap)
3628
0
{
3629
0
   int err = MP_OKAY;
3630
3631
0
   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
3632
3633
0
   if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
3634
0
       return WC_KEY_SIZE_E;
3635
0
   }
3636
3637
0
   (void)heap;
3638
3639
0
   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
3640
#ifdef MP_INT_SIZE_CHECK_NULL
3641
   if (mu == NULL)
3642
       err = MEMORY_E;
3643
#endif
3644
0
   if (err == MP_OKAY)
3645
0
       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
3646
0
   if (err == MP_OKAY) {
3647
0
       err = mp_montgomery_calc_normalization(mu, modulus);
3648
3649
0
       if (err == MP_OKAY) {
3650
0
           if (mp_cmp_d(mu, 1) == MP_EQ) {
3651
0
               err = mp_copy(p->x, r->x);
3652
0
               if (err == MP_OKAY)
3653
0
                   err = mp_copy(p->y, r->y);
3654
0
               if (err == MP_OKAY)
3655
0
                   err = mp_copy(p->z, r->z);
3656
0
           }
3657
0
           else {
3658
0
               err = mp_mulmod(p->x, mu, modulus, r->x);
3659
0
               if (err == MP_OKAY)
3660
0
                   err = mp_mulmod(p->y, mu, modulus, r->y);
3661
0
               if (err == MP_OKAY)
3662
0
                   err = mp_mulmod(p->z, mu, modulus, r->z);
3663
0
           }
3664
0
       }
3665
3666
0
       mp_clear(mu);
3667
0
   }
3668
3669
0
   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
3670
0
   return err;
3671
0
}
3672
3673
#ifdef WOLFSSL_SMALL_STACK_CACHE
3674
static int ecc_key_tmp_init(ecc_key* key, void* heap)
3675
{
3676
   int err = MP_OKAY;
3677
3678
   (void)heap;
3679
3680
   if (key == NULL) {
3681
       return ECC_BAD_ARG_E;
3682
   }
3683
3684
   XMEMSET(key, 0, sizeof(*key));
3685
3686
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3687
   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3688
   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3689
#ifdef ALT_ECC_SIZE
3690
   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3691
   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3692
   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
3693
#endif
3694
   if (key->t1 == NULL || key->t2 == NULL
3695
#ifdef ALT_ECC_SIZE
3696
      || key->x == NULL || key->y == NULL || key->z == NULL
3697
#endif
3698
   ) {
3699
       err = MEMORY_E;
3700
   }
3701
   if (err == 0) {
3702
       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3703
   }
3704
   if (err == 0) {
3705
       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3706
   }
3707
#ifdef ALT_ECC_SIZE
3708
   if (err == 0) {
3709
       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3710
   }
3711
   if (err == 0) {
3712
       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3713
   }
3714
   if (err == 0) {
3715
       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
3716
   }
3717
#endif
3718
#else
3719
   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3720
   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3721
#ifdef ALT_ECC_SIZE
3722
   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3723
   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3724
   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
3725
#endif
3726
   if (key->t1 == NULL || key->t2 == NULL
3727
#ifdef ALT_ECC_SIZE
3728
      || key->x == NULL || key->y == NULL || key->z == NULL
3729
#endif
3730
   ) {
3731
       err = MEMORY_E;
3732
   }
3733
#endif
3734
3735
   return err;
3736
}
3737
3738
static void ecc_key_tmp_final(ecc_key* key, void* heap)
3739
{
3740
    (void)heap;
3741
3742
#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
3743
#ifdef ALT_ECC_SIZE
3744
   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
3745
   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
3746
   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
3747
#endif
3748
   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
3749
   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
3750
#else
3751
#ifdef ALT_ECC_SIZE
3752
   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
3753
   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
3754
   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
3755
#endif
3756
   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
3757
   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
3758
#endif
3759
}
3760
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3761
#endif /* !WOLFSSL_SP_MATH */
3762
3763
#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
3764
/**
3765
   Perform a point multiplication
3766
   k    The scalar to multiply by
3767
   G    The base point
3768
   R    [out] Destination for kG
3769
   a    ECC curve parameter a
3770
   modulus  The modulus of the field the ECC curve is in
3771
   map      Boolean whether to map back to affine or not
3772
                (1==map, 0 == leave in projective)
3773
   return MP_OKAY on success
3774
*/
3775
#ifdef FP_ECC
3776
static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
3777
                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
3778
                             void* heap)
3779
#else
3780
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
3781
                     mp_int* modulus, int map, void* heap)
3782
#endif
3783
#if !defined(WOLFSSL_SP_MATH)
3784
0
{
3785
0
   ecc_point     *tG, *M[M_POINTS];
3786
#ifdef WOLFSSL_NO_MALLOC
3787
   ecc_point     lcl_tG, lcl_M[M_POINTS];
3788
#endif
3789
0
   int           i, err;
3790
#ifdef WOLFSSL_SMALL_STACK_CACHE
3791
   ecc_key       *key = NULL;
3792
#endif
3793
0
   mp_digit      mp;
3794
3795
   /* init variables */
3796
0
   tG = NULL;
3797
0
   XMEMSET(M, 0, sizeof(M));
3798
3799
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3800
0
       err = ECC_BAD_ARG_E;
3801
0
       goto exit;
3802
0
   }
3803
3804
   /* k can't have more bits than modulus count plus 1 */
3805
0
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
3806
0
       err = ECC_OUT_OF_RANGE_E;
3807
0
       goto exit;
3808
0
   }
3809
3810
#ifdef WOLFSSL_SMALL_STACK_CACHE
3811
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
3812
   if (key == NULL) {
3813
       err = MP_MEM;
3814
       goto exit;
3815
   }
3816
   err = ecc_key_tmp_init(key, heap);
3817
   if (err != MP_OKAY)
3818
      goto exit;
3819
   R->key = key;
3820
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3821
3822
  /* alloc ram for window temps */
3823
0
  for (i = 0; i < M_POINTS; i++) {
3824
  #ifdef WOLFSSL_NO_MALLOC
3825
      M[i] = &lcl_M[i];
3826
  #endif
3827
0
      err = wc_ecc_new_point_ex(&M[i], heap);
3828
0
      if (err != MP_OKAY) {
3829
0
         goto exit;
3830
0
      }
3831
#ifdef WOLFSSL_SMALL_STACK_CACHE
3832
      M[i]->key = key;
3833
#endif
3834
0
  }
3835
3836
   /* make a copy of G in case R==G */
3837
#ifdef WOLFSSL_NO_MALLOC
3838
   tG = &lcl_tG;
3839
#endif
3840
0
   err = wc_ecc_new_point_ex(&tG, heap);
3841
0
   if (err != MP_OKAY) {
3842
0
       goto exit;
3843
0
   }
3844
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
3845
0
       goto exit;
3846
0
   }
3847
3848
   /* init montgomery reduction */
3849
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
3850
0
       goto exit;
3851
0
   }
3852
3853
#ifdef FP_ECC
3854
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
3855
#else
3856
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
3857
0
#endif
3858
   /* map R back from projective space */
3859
0
   if (err == MP_OKAY && map)
3860
0
       err = ecc_map(R, modulus, mp);
3861
3862
0
exit:
3863
3864
   /* done */
3865
0
   wc_ecc_del_point_ex(tG, heap);
3866
0
   for (i = 0; i < M_POINTS; i++) {
3867
0
       wc_ecc_del_point_ex(M[i], heap);
3868
0
   }
3869
3870
#ifdef WOLFSSL_SMALL_STACK_CACHE
3871
   if (key) {
3872
       if (R)
3873
           R->key = NULL;
3874
       ecc_key_tmp_final(key, heap);
3875
       XFREE(key, heap, DYNAMIC_TYPE_ECC);
3876
   }
3877
#endif /* WOLFSSL_SMALL_STACK_CACHE */
3878
3879
0
   return err;
3880
0
}
3881
#else
3882
{
3883
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
3884
       return ECC_BAD_ARG_E;
3885
   }
3886
3887
   (void)a;
3888
3889
   /* For supported curves the order is the same length in bits as the modulus.
3890
    * Can't have more than order bits for the scalar.
3891
    */
3892
   if (mp_count_bits(k) > mp_count_bits(modulus)) {
3893
       return ECC_OUT_OF_RANGE_E;
3894
   }
3895
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
3896
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
3897
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
3898
       return IS_POINT_E;
3899
   }
3900
3901
#ifdef WOLFSSL_HAVE_SP_ECC
3902
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
3903
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
3904
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
3905
   }
3906
#endif
3907
#ifndef WOLFSSL_SP_NO_256
3908
   if (mp_count_bits(modulus) == 256) {
3909
       return sp_ecc_mulmod_256(k, G, R, map, heap);
3910
   }
3911
#endif
3912
#ifdef WOLFSSL_SP_384
3913
   if (mp_count_bits(modulus) == 384) {
3914
       return sp_ecc_mulmod_384(k, G, R, map, heap);
3915
   }
3916
#endif
3917
#ifdef WOLFSSL_SP_521
3918
   if (mp_count_bits(modulus) == 521) {
3919
       return sp_ecc_mulmod_521(k, G, R, map, heap);
3920
   }
3921
#endif
3922
#else
3923
   (void)map;
3924
   (void)map;
3925
   (void)heap;
3926
#endif
3927
   return ECC_BAD_ARG_E;
3928
}
3929
#endif
3930
#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
3931
3932
#ifndef FP_ECC
3933
#if !defined(WOLFSSL_SP_MATH)
3934
#ifdef ECC_TIMING_RESISTANT
3935
static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
3936
   mp_int* modulus, mp_int* order)
3937
0
{
3938
0
    int err;
3939
0
    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
3940
3941
0
    if (MP_BITS_OVER_MAX(mp_bitsused(order), MAX_ECC_BITS_USE) ||
3942
0
            MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
3943
0
        return WC_KEY_SIZE_E;
3944
0
    }
3945
3946
0
    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
3947
#ifdef MP_INT_SIZE_CHECK_NULL
3948
    if (t == NULL) {
3949
        err = MEMORY_E;
3950
    }
3951
    else
3952
#endif
3953
0
    {
3954
0
        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
3955
0
    }
3956
0
    if (err == MP_OKAY) {
3957
        /* Check for k == order - 1. Result will be 0 point which is not correct
3958
         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
3959
         * (with constant time implementation)
3960
         */
3961
0
        err = mp_sub_d(order, 1, t);
3962
0
        if (err == MP_OKAY) {
3963
0
            int kIsMinusOne = (mp_cmp((const mp_int*)k, t) == MP_EQ);
3964
0
            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
3965
0
            if (err == MP_OKAY) {
3966
0
                err = mp_sub(modulus, tG->y, t);
3967
0
            }
3968
0
            if (err == MP_OKAY) {
3969
0
                err = mp_cond_copy(t, kIsMinusOne, R->y);
3970
0
            }
3971
0
            if (err == MP_OKAY) {
3972
0
                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
3973
0
            }
3974
0
        }
3975
3976
0
        mp_free(t);
3977
0
    }
3978
3979
0
    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
3980
0
    return err;
3981
0
}
3982
#endif /* ECC_TIMING_RESISTANT */
3983
#endif
3984
3985
/**
3986
   Perform a point multiplication
3987
   k    The scalar to multiply by
3988
   G    The base point
3989
   R    [out] Destination for kG
3990
   a    ECC curve parameter a
3991
   modulus  The modulus of the field the ECC curve is in
3992
   map      Boolean whether to map back to affine or not
3993
                (1==map, 0 == leave in projective)
3994
   return MP_OKAY on success
3995
*/
3996
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
3997
                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
3998
                      void* heap)
3999
#if !defined(WOLFSSL_SP_MATH)
4000
0
{
4001
0
   ecc_point     *tG, *M[M_POINTS];
4002
#ifdef WOLFSSL_NO_MALLOC
4003
   ecc_point     lcl_tG, lcl_M[M_POINTS];
4004
#endif
4005
0
   int           i, err;
4006
#ifdef WOLFSSL_SMALL_STACK_CACHE
4007
   ecc_key       *key = NULL;
4008
#endif
4009
0
   mp_digit      mp;
4010
4011
0
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4012
0
      return ECC_BAD_ARG_E;
4013
0
   }
4014
4015
#ifdef HAVE_ECC_CDH
4016
   if (mp_count_bits(modulus) > mp_count_bits(order)) {
4017
      if (mp_count_bits(k) > mp_count_bits(modulus)) {
4018
          return ECC_OUT_OF_RANGE_E;
4019
      }
4020
   }
4021
   else
4022
#endif
4023
   /* k can't have more bits than order */
4024
0
   if (mp_count_bits(k) > mp_count_bits(order)) {
4025
0
      WOLFSSL_MSG("Private key length is greater than order in bits.");
4026
0
      return ECC_OUT_OF_RANGE_E;
4027
0
   }
4028
4029
   /* init variables */
4030
0
   tG = NULL;
4031
0
   XMEMSET(M, 0, sizeof(M));
4032
4033
#ifdef WOLFSSL_SMALL_STACK_CACHE
4034
   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
4035
   if (key == NULL)
4036
       return MEMORY_E;
4037
   err = ecc_key_tmp_init(key, heap);
4038
   if (err != MP_OKAY)
4039
      goto exit;
4040
   R->key = key;
4041
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4042
4043
   /* alloc ram for window temps */
4044
0
   for (i = 0; i < M_POINTS; i++) {
4045
   #ifdef WOLFSSL_NO_MALLOC
4046
      M[i] = &lcl_M[i];
4047
   #endif
4048
0
      err = wc_ecc_new_point_ex(&M[i], heap);
4049
0
      if (err != MP_OKAY) {
4050
0
         goto exit;
4051
0
      }
4052
#ifdef WOLFSSL_SMALL_STACK_CACHE
4053
      M[i]->key = key;
4054
#endif
4055
0
  }
4056
4057
   /* make a copy of G in case R==G */
4058
#ifdef WOLFSSL_NO_MALLOC
4059
   tG = &lcl_tG;
4060
#endif
4061
0
   err = wc_ecc_new_point_ex(&tG, heap);
4062
0
   if (err != MP_OKAY) {
4063
0
       goto exit;
4064
0
   }
4065
0
   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
4066
0
       goto exit;
4067
0
   }
4068
4069
   /* init montgomery reduction */
4070
0
   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
4071
0
      goto exit;
4072
0
   }
4073
4074
0
   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
4075
0
#ifdef ECC_TIMING_RESISTANT
4076
0
   if (err == MP_OKAY) {
4077
0
       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
4078
0
   }
4079
#else
4080
   (void)order;
4081
#endif
4082
   /* map R back from projective space */
4083
0
   if (err == MP_OKAY && map)
4084
0
      err = ecc_map(R, modulus, mp);
4085
4086
0
exit:
4087
4088
   /* done */
4089
0
   wc_ecc_del_point_ex(tG, heap);
4090
0
   for (i = 0; i < M_POINTS; i++) {
4091
0
      wc_ecc_del_point_ex(M[i], heap);
4092
0
   }
4093
#ifdef WOLFSSL_SMALL_STACK_CACHE
4094
   R->key = NULL;
4095
   ecc_key_tmp_final(key, heap);
4096
   XFREE(key, heap, DYNAMIC_TYPE_ECC);
4097
#endif /* WOLFSSL_SMALL_STACK_CACHE */
4098
4099
0
   return err;
4100
0
}
4101
#else
4102
{
4103
   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
4104
       return ECC_BAD_ARG_E;
4105
   }
4106
   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
4107
       mp_count_bits(G->y) > mp_count_bits(modulus) ||
4108
       mp_count_bits(G->z) > mp_count_bits(modulus)) {
4109
       return IS_POINT_E;
4110
   }
4111
4112
   (void)a;
4113
   (void)order;
4114
   (void)rng;
4115
4116
#ifdef WOLFSSL_HAVE_SP_ECC
4117
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4118
   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
4119
       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
4120
   }
4121
#endif
4122
#ifndef WOLFSSL_SP_NO_256
4123
   if (mp_count_bits(modulus) == 256) {
4124
       return sp_ecc_mulmod_256(k, G, R, map, heap);
4125
   }
4126
#endif
4127
#ifdef WOLFSSL_SP_384
4128
   if (mp_count_bits(modulus) == 384) {
4129
       return sp_ecc_mulmod_384(k, G, R, map, heap);
4130
   }
4131
#endif
4132
#ifdef WOLFSSL_SP_521
4133
   if (mp_count_bits(modulus) == 521) {
4134
       return sp_ecc_mulmod_521(k, G, R, map, heap);
4135
   }
4136
#endif
4137
#else
4138
   (void)map;
4139
   (void)heap;
4140
#endif
4141
   return ECC_BAD_ARG_E;
4142
}
4143
#endif /* !WOLFSSL_SP_MATH */
4144
#endif /* !FP_ECC */
4145
4146
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
4147
4148
/** ECC Fixed Point mulmod global
4149
    k        The multiplicand
4150
    G        Base point to multiply
4151
    R        [out] Destination of product
4152
    a        ECC curve parameter a
4153
    modulus  The modulus for the curve
4154
    map      [boolean] If non-zero maps the point back to affine coordinates,
4155
             otherwise it's left in jacobian-montgomery form
4156
    return MP_OKAY if successful
4157
*/
4158
int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
4159
                  mp_int* modulus, int map)
4160
0
{
4161
0
    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
4162
0
        mp_zero(R->x);
4163
0
        mp_zero(R->y);
4164
0
        mp_set(R->z, 1);
4165
0
        return MP_OKAY;
4166
0
    }
4167
0
    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
4168
0
}
4169
4170
#endif
4171
4172
/**
4173
 * Allocate a new ECC point (if one not provided)
4174
 * use a heap hint when creating new ecc_point
4175
 * @return 0 on success
4176
 * @return BAD_FUNC_ARG for invalid arguments
4177
 * @return MEMORY_E on failure to allocate memory
4178
*/
4179
static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
4180
0
{
4181
0
   int err = MP_OKAY;
4182
0
   ecc_point* p;
4183
4184
0
   if (point == NULL) {
4185
0
       return BAD_FUNC_ARG;
4186
0
   }
4187
4188
0
   p = *point;
4189
0
   if (p == NULL) {
4190
0
      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
4191
0
   }
4192
0
   if (p == NULL) {
4193
0
      return MEMORY_E;
4194
0
   }
4195
0
   XMEMSET(p, 0, sizeof(ecc_point));
4196
4197
0
   if (*point == NULL)
4198
0
       p->isAllocated = 1;
4199
4200
0
#ifndef ALT_ECC_SIZE
4201
0
   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
4202
0
   if (err != MP_OKAY) {
4203
0
      WOLFSSL_MSG("mp_init_multi failed.");
4204
0
      if (p->isAllocated)
4205
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4206
0
      p = NULL;
4207
0
   }
4208
#else
4209
   p->x = (mp_int*)&p->xyz[0];
4210
   p->y = (mp_int*)&p->xyz[1];
4211
   p->z = (mp_int*)&p->xyz[2];
4212
   alt_fp_init(p->x);
4213
   alt_fp_init(p->y);
4214
   alt_fp_init(p->z);
4215
#endif
4216
4217
0
   *point = p;
4218
0
   (void)heap;
4219
0
   return err;
4220
0
} /* wc_ecc_new_point_ex */
4221
4222
ecc_point* wc_ecc_new_point_h(void* heap)
4223
0
{
4224
0
    ecc_point* p = NULL;
4225
0
    (void)wc_ecc_new_point_ex(&p, heap);
4226
0
    return p;
4227
0
}
4228
4229
ecc_point* wc_ecc_new_point(void)
4230
0
{
4231
0
   ecc_point* p = NULL;
4232
0
   (void)wc_ecc_new_point_ex(&p, NULL);
4233
0
   return p;
4234
0
}
4235
4236
/** Free an ECC point from memory
4237
  p   The point to free
4238
*/
4239
static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
4240
0
{
4241
0
   if (p != NULL) {
4242
0
      mp_clear(p->x);
4243
0
      mp_clear(p->y);
4244
0
      mp_clear(p->z);
4245
0
      if (p->isAllocated)
4246
0
          XFREE(p, heap, DYNAMIC_TYPE_ECC);
4247
0
   }
4248
0
   (void)heap;
4249
0
}
4250
void wc_ecc_del_point_h(ecc_point* p, void* heap)
4251
0
{
4252
0
   wc_ecc_del_point_ex(p, heap);
4253
0
}
4254
void wc_ecc_del_point(ecc_point* p)
4255
0
{
4256
0
    wc_ecc_del_point_ex(p, NULL);
4257
0
}
4258
4259
void wc_ecc_forcezero_point(ecc_point* p)
4260
0
{
4261
0
    if (p != NULL) {
4262
0
        mp_forcezero(p->x);
4263
0
        mp_forcezero(p->y);
4264
0
        mp_forcezero(p->z);
4265
0
    }
4266
0
}
4267
4268
4269
/** Copy the value of a point to an other one
4270
  p    The point to copy
4271
  r    The created point
4272
*/
4273
int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
4274
0
{
4275
0
    int ret;
4276
4277
    /* prevents null arguments */
4278
0
    if (p == NULL || r == NULL)
4279
0
        return ECC_BAD_ARG_E;
4280
4281
0
    ret = mp_copy(p->x, r->x);
4282
0
    if (ret != MP_OKAY)
4283
0
        return ret;
4284
0
    ret = mp_copy(p->y, r->y);
4285
0
    if (ret != MP_OKAY)
4286
0
        return ret;
4287
0
    ret = mp_copy(p->z, r->z);
4288
0
    if (ret != MP_OKAY)
4289
0
        return ret;
4290
4291
0
    return MP_OKAY;
4292
0
}
4293
4294
/** Compare the value of a point with an other one
4295
 a    The point to compare
4296
 b    The other point to compare
4297
4298
 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
4299
 */
4300
int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
4301
0
{
4302
0
    int ret;
4303
4304
    /* prevents null arguments */
4305
0
    if (a == NULL || b == NULL)
4306
0
        return BAD_FUNC_ARG;
4307
4308
0
    ret = mp_cmp(a->x, b->x);
4309
0
    if (ret != MP_EQ)
4310
0
        return ret;
4311
0
    ret = mp_cmp(a->y, b->y);
4312
0
    if (ret != MP_EQ)
4313
0
        return ret;
4314
0
    ret = mp_cmp(a->z, b->z);
4315
0
    if (ret != MP_EQ)
4316
0
        return ret;
4317
4318
0
    return MP_EQ;
4319
0
}
4320
4321
4322
/** Returns whether an ECC idx is valid or not
4323
  n      The idx number to check
4324
  return 1 if valid, 0 if not
4325
*/
4326
int wc_ecc_is_valid_idx(int n)
4327
1.05k
{
4328
1.05k
   int x;
4329
4330
1.05k
   if (n >= (int)ECC_SET_COUNT)
4331
0
       return 0;
4332
4333
6.33k
   for (x = 0; ecc_sets[x].size != 0; x++)
4334
5.27k
       ;
4335
   /* -1 is a valid index --- indicating that the domain params
4336
      were supplied by the user */
4337
1.05k
   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
4338
1.05k
      return 1;
4339
1.05k
   }
4340
4341
0
   return 0;
4342
1.05k
}
4343
4344
int wc_ecc_get_curve_idx(int curve_id)
4345
0
{
4346
0
    int curve_idx;
4347
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4348
0
        if (curve_id == ecc_sets[curve_idx].id)
4349
0
            break;
4350
0
    }
4351
0
    if (ecc_sets[curve_idx].size == 0) {
4352
0
        return ECC_CURVE_INVALID;
4353
0
    }
4354
0
    return curve_idx;
4355
0
}
4356
4357
int wc_ecc_get_curve_id(int curve_idx)
4358
0
{
4359
0
    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
4360
0
        return ecc_sets[curve_idx].id;
4361
0
    }
4362
0
    return ECC_CURVE_INVALID;
4363
0
}
4364
4365
/* Returns the curve size that corresponds to a given ecc_curve_id identifier
4366
 *
4367
 * id      curve id, from ecc_curve_id enum in ecc.h
4368
 * return  curve size, from ecc_sets[] on success, negative on error
4369
 */
4370
int wc_ecc_get_curve_size_from_id(int curve_id)
4371
0
{
4372
0
    int curve_idx = wc_ecc_get_curve_idx(curve_id);
4373
0
    if (curve_idx == ECC_CURVE_INVALID)
4374
0
        return ECC_BAD_ARG_E;
4375
0
    return ecc_sets[curve_idx].size;
4376
0
}
4377
4378
/* Returns the curve index that corresponds to a given curve name in
4379
 * ecc_sets[] of ecc.c
4380
 *
4381
 * name    curve name, from ecc_sets[].name in ecc.c
4382
 * return  curve index in ecc_sets[] on success, negative on error
4383
 */
4384
int wc_ecc_get_curve_idx_from_name(const char* curveName)
4385
0
{
4386
0
    int curve_idx;
4387
4388
0
    if (curveName == NULL)
4389
0
        return BAD_FUNC_ARG;
4390
4391
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4392
0
        if (
4393
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4394
0
            ecc_sets[curve_idx].name &&
4395
0
        #endif
4396
0
                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
4397
0
            break;
4398
0
        }
4399
0
    }
4400
0
    if (ecc_sets[curve_idx].size == 0) {
4401
0
        WOLFSSL_MSG("ecc_set curve name not found");
4402
0
        return ECC_CURVE_INVALID;
4403
0
    }
4404
0
    return curve_idx;
4405
0
}
4406
4407
/* Returns the curve size that corresponds to a given curve name,
4408
 * as listed in ecc_sets[] of ecc.c.
4409
 *
4410
 * name    curve name, from ecc_sets[].name in ecc.c
4411
 * return  curve size, from ecc_sets[] on success, negative on error
4412
 */
4413
int wc_ecc_get_curve_size_from_name(const char* curveName)
4414
0
{
4415
0
    int curve_idx;
4416
4417
0
    if (curveName == NULL)
4418
0
        return BAD_FUNC_ARG;
4419
4420
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4421
0
    if (curve_idx < 0)
4422
0
        return curve_idx;
4423
4424
0
    return ecc_sets[curve_idx].size;
4425
0
}
4426
4427
/* Returns the curve id that corresponds to a given curve name,
4428
 * as listed in ecc_sets[] of ecc.c.
4429
 *
4430
 * name   curve name, from ecc_sets[].name in ecc.c
4431
 * return curve id, from ecc_sets[] on success, negative on error
4432
 */
4433
int wc_ecc_get_curve_id_from_name(const char* curveName)
4434
0
{
4435
0
    int curve_idx;
4436
4437
0
    if (curveName == NULL)
4438
0
        return BAD_FUNC_ARG;
4439
4440
0
    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
4441
0
    if (curve_idx < 0)
4442
0
        return curve_idx;
4443
4444
0
    return ecc_sets[curve_idx].id;
4445
0
}
4446
4447
/* Compares a curve parameter (hex, from ecc_sets[]) to given input
4448
 * parameter for equality.
4449
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
4450
 * Returns MP_EQ on success, negative on error */
4451
static int wc_ecc_cmp_param(const char* curveParam,
4452
                            const byte* param, word32 paramSz, int encType)
4453
0
{
4454
0
    int err = MP_OKAY;
4455
#ifdef WOLFSSL_SMALL_STACK
4456
    mp_int* a = NULL;
4457
    mp_int* b = NULL;
4458
#else
4459
0
    mp_int  a[1], b[1];
4460
0
#endif
4461
4462
0
    if (param == NULL || curveParam == NULL)
4463
0
        return BAD_FUNC_ARG;
4464
4465
0
    if (encType == WC_TYPE_HEX_STR) {
4466
0
        if ((word32)XSTRLEN(curveParam) != paramSz)
4467
0
            return -1;
4468
0
        return (XSTRNCMP(curveParam, (const char*) param, paramSz) == 0)
4469
0
            ? 0 : -1;
4470
0
    }
4471
4472
#ifdef WOLFSSL_SMALL_STACK
4473
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4474
    if (a == NULL)
4475
        return MEMORY_E;
4476
    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
4477
    if (b == NULL) {
4478
        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
4479
        return MEMORY_E;
4480
    }
4481
#endif
4482
4483
0
    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
4484
0
        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4485
0
        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4486
0
        return err;
4487
0
    }
4488
4489
0
    if (err == MP_OKAY) {
4490
0
        err = mp_read_unsigned_bin(a, param, paramSz);
4491
0
    }
4492
0
    if (err == MP_OKAY)
4493
0
        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
4494
4495
0
    if (err == MP_OKAY) {
4496
0
        if (mp_cmp(a, b) != MP_EQ) {
4497
0
            err = -1;
4498
0
        } else {
4499
0
            err = MP_EQ;
4500
0
        }
4501
0
    }
4502
4503
0
    mp_clear(a);
4504
0
    mp_clear(b);
4505
0
    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
4506
0
    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
4507
4508
0
    return err;
4509
0
}
4510
4511
/* Returns the curve id in ecc_sets[] that corresponds to a given set of
4512
 * curve parameters.
4513
 *
4514
 * fieldSize  the field size in bits
4515
 * prime      prime of the finite field
4516
 * primeSz    size of prime in octets
4517
 * Af         first coefficient a of the curve
4518
 * AfSz       size of Af in octets
4519
 * Bf         second coefficient b of the curve
4520
 * BfSz       size of Bf in octets
4521
 * order      curve order
4522
 * orderSz    size of curve in octets
4523
 * Gx         affine x coordinate of base point
4524
 * GxSz       size of Gx in octets
4525
 * Gy         affine y coordinate of base point
4526
 * GySz       size of Gy in octets
4527
 * cofactor   curve cofactor
4528
 *
4529
 * return curve id, from ecc_sets[] on success, negative on error
4530
 */
4531
int wc_ecc_get_curve_id_from_params(int fieldSize,
4532
        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
4533
        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
4534
        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
4535
0
{
4536
0
    int idx;
4537
0
    int curveSz;
4538
4539
0
    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
4540
0
        Gx == NULL || Gy == NULL)
4541
0
        return BAD_FUNC_ARG;
4542
4543
0
    curveSz = (fieldSize + 1) >> 3;    /* round up */
4544
4545
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4546
0
        if (curveSz == ecc_sets[idx].size) {
4547
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
4548
0
                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4549
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
4550
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4551
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
4552
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4553
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
4554
0
                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4555
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
4556
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4557
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
4558
0
                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
4559
0
                (cofactor == ecc_sets[idx].cofactor)) {
4560
0
                    break;
4561
0
            }
4562
0
        }
4563
0
    }
4564
4565
0
    if (ecc_sets[idx].size == 0)
4566
0
        return ECC_CURVE_INVALID;
4567
4568
0
    return ecc_sets[idx].id;
4569
0
}
4570
4571
/* Returns the curve id in ecc_sets[] that corresponds
4572
 * to a given domain parameters pointer.
4573
 *
4574
 * dp   domain parameters pointer
4575
 *
4576
 * return curve id, from ecc_sets[] on success, negative on error
4577
 */
4578
int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
4579
0
{
4580
0
    int idx;
4581
4582
0
    if (dp == NULL
4583
0
    #ifndef WOLFSSL_ECC_CURVE_STATIC
4584
0
         || dp->prime == NULL ||  dp->Af == NULL ||
4585
0
        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
4586
0
    #endif
4587
0
    ) {
4588
0
        return BAD_FUNC_ARG;
4589
0
    }
4590
4591
0
    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
4592
0
        if (dp->size == ecc_sets[idx].size) {
4593
0
            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
4594
0
                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
4595
0
                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
4596
0
                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
4597
0
                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
4598
0
                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
4599
0
                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
4600
0
                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
4601
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
4602
0
                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
4603
0
                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
4604
0
                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
4605
0
                (dp->cofactor == ecc_sets[idx].cofactor)) {
4606
0
                    break;
4607
0
            }
4608
0
        }
4609
0
    }
4610
4611
0
    if (ecc_sets[idx].size == 0)
4612
0
        return ECC_CURVE_INVALID;
4613
4614
0
    return ecc_sets[idx].id;
4615
0
}
4616
4617
/* Returns the curve id that corresponds to a given OID,
4618
 * as listed in ecc_sets[] of ecc.c.
4619
 *
4620
 * oid   OID, from ecc_sets[].name in ecc.c
4621
 * len   OID len, from ecc_sets[].name in ecc.c
4622
 * return curve id, from ecc_sets[] on success, negative on error
4623
 */
4624
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
4625
0
{
4626
0
    int curve_idx;
4627
#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
4628
    int ret;
4629
    #ifdef HAVE_OID_DECODING
4630
    word16 decOid[MAX_OID_SZ/sizeof(word16)];
4631
    #else
4632
    byte  decOid[MAX_OID_SZ];
4633
    #endif
4634
    word32 decOidSz;
4635
#endif
4636
4637
0
    if (oid == NULL)
4638
0
        return BAD_FUNC_ARG;
4639
4640
#ifdef HAVE_OID_DECODING
4641
    decOidSz = (word32)sizeof(decOid);
4642
    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
4643
    if (ret != 0) {
4644
        return ret;
4645
    }
4646
#endif
4647
4648
0
    if (len == 0) {
4649
        /* SAKKE has zero oidSz and will otherwise match with len==0. */
4650
0
        WOLFSSL_MSG("zero oidSz");
4651
0
        return ECC_CURVE_INVALID;
4652
0
    }
4653
4654
0
    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
4655
    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4656
        decOidSz = (word32)sizeof(decOid);
4657
        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
4658
            decOid, &decOidSz);
4659
        if (ret != 0) {
4660
            continue;
4661
        }
4662
    #endif
4663
4664
0
        if (
4665
0
        #ifndef WOLFSSL_ECC_CURVE_STATIC
4666
0
            ecc_sets[curve_idx].oid &&
4667
0
        #endif
4668
        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
4669
            decOidSz == len &&
4670
                XMEMCMP(decOid, oid, len) == 0
4671
        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
4672
            /* We double because decOidSz is a count of word16 elements. */
4673
            ecc_sets[curve_idx].oidSz == decOidSz &&
4674
                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
4675
        #else
4676
0
            ecc_sets[curve_idx].oidSz == len &&
4677
0
                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
4678
0
        #endif
4679
0
        ) {
4680
0
            break;
4681
0
        }
4682
0
    }
4683
0
    if (ecc_sets[curve_idx].size == 0) {
4684
0
        WOLFSSL_MSG("ecc_set curve name not found");
4685
0
        return ECC_CURVE_INVALID;
4686
0
    }
4687
4688
0
    return ecc_sets[curve_idx].id;
4689
0
}
4690
4691
/* Get curve parameters using curve index */
4692
const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
4693
1.05k
{
4694
1.05k
    const ecc_set_type* ecc_set = NULL;
4695
4696
1.05k
    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
4697
1.05k
        ecc_set = &ecc_sets[curve_idx];
4698
1.05k
    }
4699
1.05k
    return ecc_set;
4700
1.05k
}
4701
4702
4703
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
4704
static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
4705
{
4706
   if (key == NULL || mp == NULL)
4707
      return BAD_FUNC_ARG;
4708
   if (*mp == NULL) {
4709
      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
4710
      if (*mp == NULL) {
4711
         return MEMORY_E;
4712
      }
4713
      XMEMSET(*mp, 0, sizeof(mp_int));
4714
   }
4715
   return 0;
4716
}
4717
static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
4718
{
4719
   if (key && mp && *mp) {
4720
      mp_clear(*mp);
4721
      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
4722
      *mp = NULL;
4723
   }
4724
}
4725
4726
static int wc_ecc_alloc_async(ecc_key* key)
4727
{
4728
    int err = wc_ecc_alloc_mpint(key, &key->r);
4729
    if (err == 0)
4730
        err = wc_ecc_alloc_mpint(key, &key->s);
4731
    return err;
4732
}
4733
4734
static void wc_ecc_free_async(ecc_key* key)
4735
{
4736
    wc_ecc_free_mpint(key, &key->r);
4737
    wc_ecc_free_mpint(key, &key->s);
4738
#ifdef HAVE_CAVIUM_V
4739
    wc_ecc_free_mpint(key, &key->e);
4740
    wc_ecc_free_mpint(key, &key->signK);
4741
#endif /* HAVE_CAVIUM_V */
4742
}
4743
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
4744
4745
4746
#ifdef HAVE_ECC_DHE
4747
/**
4748
  Create an ECC shared secret between two keys
4749
  private_key      The private ECC key (heap hint based off of private key)
4750
  public_key       The public key
4751
  out              [out] Destination of the shared secret
4752
                         Conforms to EC-DH from ANSI X9.63
4753
  outlen           [in/out] The max size and resulting size of the shared secret
4754
  return           MP_OKAY if successful
4755
*/
4756
WOLFSSL_ABI
4757
int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
4758
                      word32* outlen)
4759
0
{
4760
0
   int err = 0;
4761
0
   int privateKeyOk = 0;
4762
4763
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
4764
   !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
4765
   CRYS_ECDH_TempData_t tempBuff;
4766
#endif
4767
4768
0
   (void)err;
4769
0
   (void)privateKeyOk;
4770
4771
0
   if (private_key == NULL || public_key == NULL || out == NULL ||
4772
0
                                                            outlen == NULL) {
4773
0
       return BAD_FUNC_ARG;
4774
0
   }
4775
4776
#ifdef WOLF_CRYPTO_CB
4777
    #ifndef WOLF_CRYPTO_CB_FIND
4778
    if (private_key->devId != INVALID_DEVID)
4779
    #endif
4780
    {
4781
        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
4782
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4783
            return err;
4784
        /* fall-through when unavailable */
4785
    }
4786
#endif
4787
4788
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
4789
    return NO_VALID_DEVID;
4790
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
4791
   /* type valid? */
4792
0
   privateKeyOk = private_key->type == ECC_PRIVATEKEY ||
4793
0
                  private_key->type == ECC_PRIVATEKEY_ONLY;
4794
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
4795
      defined(WOLFSSL_SE050_ONLY_KEY_ID)
4796
   /* A SE050 key-id handle can represent a private key even though
4797
    * wc_ecc_use_key_id() only loads the public point into the ecc_key. */
4798
   if (private_key->keyIdSet)
4799
      privateKeyOk = 1;
4800
#endif
4801
0
   if (!privateKeyOk) {
4802
0
      return ECC_BAD_ARG_E;
4803
0
   }
4804
4805
   /* Verify domain params supplied */
4806
0
   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
4807
0
       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
4808
0
      return ECC_BAD_ARG_E;
4809
0
   }
4810
4811
   /* Verify curve id matches */
4812
0
   if (private_key->dp->id != public_key->dp->id) {
4813
0
      return ECC_BAD_ARG_E;
4814
0
   }
4815
4816
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
4817
    defined(WOLFSSL_MICROCHIP_TA100)
4818
   /* For SECP256R1 use hardware */
4819
   if (private_key->dp->id == ECC_SECP256R1 &&
4820
       private_key->slot != ATECC_INVALID_SLOT) {
4821
       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
4822
       *outlen = private_key->dp->size;
4823
   }
4824
   else {
4825
      err = NOT_COMPILED_IN;
4826
   }
4827
#elif defined(WOLFSSL_CRYPTOCELL)
4828
4829
    /* generate a secret*/
4830
    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
4831
                            &private_key->ctx.privKey,
4832
                            out,
4833
                            (uint32_t*)outlen,
4834
                            &tempBuff);
4835
4836
    if (err != SA_SILIB_RET_OK){
4837
        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
4838
        return err;
4839
    }
4840
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4841
   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
4842
#elif defined(WOLFSSL_KCAPI_ECC)
4843
   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
4844
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
4845
      defined(WOLFSSL_SE050_ONLY_KEY_ID)
4846
   /* SE050-resident private key uses hardware ECDH; a software private key
4847
    * (keyIdSet == 0) uses the wolfCrypt software implementation. */
4848
   if (private_key->keyIdSet)
4849
       err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4850
   else
4851
       err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out,
4852
                                     outlen);
4853
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE)
4854
   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
4855
#else
4856
0
   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
4857
0
#endif /* WOLFSSL_ATECC508A */
4858
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
4859
4860
0
   return err;
4861
0
}
4862
4863
4864
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
4865
    !defined(WOLFSSL_MICROCHIP_TA100) && \
4866
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
4867
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
4868
4869
int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
4870
                               byte* out, word32* outlen)
4871
0
{
4872
0
    int err = MP_OKAY;
4873
0
    mp_int* k = ecc_get_k(private_key);
4874
#ifdef WOLFSSL_SE050
4875
    /* A key-id handle holds no software private scalar - ECDH for such a key
4876
     * runs on the SE050 - so the identity this function computes from the
4877
     * all-zero scalar is not a shared secret and must not be rejected here. */
4878
    int checkInf = !private_key->keyIdSet;
4879
#else
4880
0
    int checkInf = 1;
4881
0
#endif
4882
#ifdef HAVE_ECC_CDH
4883
    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
4884
#endif
4885
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
4886
    defined(WC_ECC_NONBLOCK_ONLY)
4887
    ecc_nb_ctx_t nb_ctx;
4888
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
4889
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
4890
4891
#ifdef HAVE_ECC_CDH
4892
    /* if cofactor flag has been set */
4893
    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
4894
        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
4895
        /* only perform cofactor calc if not equal to 1 */
4896
        if (cofactor != 1) {
4897
#ifdef WOLFSSL_SMALL_STACK
4898
            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
4899
                return MEMORY_E;
4900
#endif
4901
            k = k_lcl;
4902
            if (mp_init(k) != MP_OKAY) {
4903
                err = MEMORY_E;
4904
                goto errout;
4905
            }
4906
            /* multiply cofactor times private key "k" */
4907
            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
4908
            if (err != MP_OKAY)
4909
                goto errout;
4910
        }
4911
    }
4912
#endif
4913
4914
#ifdef WOLFSSL_HAVE_SP_ECC
4915
4916
#ifndef WOLFSSL_SP_NO_256
4917
    if (private_key->idx != ECC_CUSTOM_IDX &&
4918
        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
4919
    #ifndef WC_ECC_NONBLOCK
4920
        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
4921
    #else
4922
        if (private_key->nb_ctx) {
4923
            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
4924
                                           point, out, outlen,
4925
                                           private_key->heap);
4926
        }
4927
        else {
4928
        #ifdef WC_ECC_NONBLOCK_ONLY
4929
            do { /* perform blocking call to non-blocking function */
4930
                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
4931
                                               outlen, private_key->heap);
4932
            } while (err == FP_WOULDBLOCK);
4933
        #else
4934
            err = sp_ecc_secret_gen_256(k, point, out, outlen,
4935
                                        private_key->heap);
4936
        #endif /* WC_ECC_NONBLOCK_ONLY */
4937
        }
4938
    #endif /* !WC_ECC_NONBLOCK */
4939
    }
4940
    else
4941
#endif /* ! WOLFSSL_SP_NO_256 */
4942
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
4943
    if (private_key->idx != ECC_CUSTOM_IDX &&
4944
                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
4945
        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
4946
                                                             private_key->heap);
4947
    }
4948
    else
4949
#endif
4950
#ifdef WOLFSSL_SP_384
4951
    if (private_key->idx != ECC_CUSTOM_IDX &&
4952
        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
4953
    #ifndef WC_ECC_NONBLOCK
4954
        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
4955
    #else
4956
        if (private_key->nb_ctx) {
4957
            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
4958
                                           point, out, outlen,
4959
                                           private_key->heap);
4960
        }
4961
        else {
4962
        #ifdef WC_ECC_NONBLOCK_ONLY
4963
            do { /* perform blocking call to non-blocking function */
4964
                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
4965
                                               outlen, private_key->heap);
4966
            } while (err == FP_WOULDBLOCK);
4967
        #else
4968
            err = sp_ecc_secret_gen_384(k, point, out, outlen,
4969
                                        private_key->heap);
4970
        #endif /* WC_ECC_NONBLOCK_ONLY */
4971
        }
4972
    #endif /* !WC_ECC_NONBLOCK */
4973
    }
4974
    else
4975
#endif /* WOLFSSL_SP_384 */
4976
#ifdef WOLFSSL_SP_521
4977
    if (private_key->idx != ECC_CUSTOM_IDX &&
4978
                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
4979
    #ifndef WC_ECC_NONBLOCK
4980
        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
4981
    #else
4982
        if (private_key->nb_ctx) {
4983
            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
4984
                                           point, out, outlen,
4985
                                           private_key->heap);
4986
        }
4987
        else {
4988
        #ifdef WC_ECC_NONBLOCK_ONLY
4989
            do { /* perform blocking call to non-blocking function */
4990
                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
4991
                                               outlen, private_key->heap);
4992
            } while (err == FP_WOULDBLOCK);
4993
        #else
4994
            err = sp_ecc_secret_gen_521(k, point, out, outlen,
4995
                                        private_key->heap);
4996
        #endif /* WC_ECC_NONBLOCK_ONLY */
4997
        }
4998
    #endif /* !WC_ECC_NONBLOCK */
4999
    }
5000
    else
5001
#endif /* WOLFSSL_SP_521 */
5002
#else
5003
0
    (void)point;
5004
0
    (void)out;
5005
0
    (void)outlen;
5006
0
    (void)k;
5007
0
#endif
5008
#if defined(WOLFSSL_SP_MATH)
5009
    {
5010
        (void)checkInf;
5011
        err = WC_KEY_SIZE_E;
5012
        goto errout;
5013
    }
5014
#else
5015
0
    {
5016
0
        ecc_point* result = NULL;
5017
        #ifdef WOLFSSL_NO_MALLOC
5018
        ecc_point  lcl_result;
5019
        #endif
5020
0
        int x = 0;
5021
0
        mp_digit mp = 0;
5022
0
        DECLARE_CURVE_SPECS(3);
5023
5024
        /* load curve info */
5025
0
        ALLOC_CURVE_SPECS(3, err);
5026
0
        if (err == MP_OKAY) {
5027
0
            err = wc_ecc_curve_load(private_key->dp, &curve,
5028
0
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5029
0
                 ECC_CURVE_FIELD_ORDER));
5030
0
        }
5031
5032
0
        if (err != MP_OKAY) {
5033
0
            FREE_CURVE_SPECS();
5034
0
            goto errout;
5035
0
        }
5036
5037
        /* make new point */
5038
    #ifdef WOLFSSL_NO_MALLOC
5039
        result = &lcl_result;
5040
    #endif
5041
0
        err = wc_ecc_new_point_ex(&result, private_key->heap);
5042
0
        if (err != MP_OKAY) {
5043
0
            wc_ecc_curve_free(curve);
5044
0
            FREE_CURVE_SPECS();
5045
0
            goto errout;
5046
0
        }
5047
5048
0
#ifdef ECC_TIMING_RESISTANT
5049
0
        if (private_key->rng == NULL) {
5050
0
            err = MISSING_RNG_E;
5051
0
        }
5052
0
#endif
5053
5054
0
        if (err == MP_OKAY) {
5055
            /* Map in a separate call as this should be constant time */
5056
0
#ifdef ECC_TIMING_RESISTANT
5057
0
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5058
0
                                              curve->order, private_key->rng, 0,
5059
0
                                              private_key->heap);
5060
#else
5061
            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
5062
                                      curve->order, NULL, 0, private_key->heap);
5063
#endif
5064
0
        }
5065
0
        if (err == MP_OKAY) {
5066
        #ifdef WOLFSSL_CHECK_MEM_ZERO
5067
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
5068
                result->x);
5069
            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
5070
                result->y);
5071
        #endif
5072
0
            err = mp_montgomery_setup(curve->prime, &mp);
5073
0
        }
5074
0
        if (err == MP_OKAY) {
5075
            /* Use constant time map if compiled in */
5076
0
            err = ecc_map_ex(result, curve->prime, mp, 1);
5077
0
        }
5078
0
        if (err == MP_OKAY) {
5079
            /* SP 800-56Ar3 5.7.1.2: the shared secret must not be the point at
5080
             * infinity. ecc_map_ex reports that case as x, y of zero with a
5081
             * success code, so check the point explicitly. */
5082
0
            if (checkInf && wc_ecc_point_is_at_infinity(result)) {
5083
0
                err = ECC_INF_E;
5084
0
            }
5085
0
        }
5086
0
        if (err == MP_OKAY) {
5087
0
            x = mp_unsigned_bin_size(curve->prime);
5088
0
            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
5089
0
                err = BUFFER_E;
5090
0
            }
5091
0
        }
5092
5093
0
        if (err == MP_OKAY) {
5094
0
            XMEMSET(out, 0, (size_t)x);
5095
0
            err = mp_to_unsigned_bin(result->x, out +
5096
0
                                     (x - mp_unsigned_bin_size(result->x)));
5097
0
        }
5098
0
        *outlen = (word32)x;
5099
5100
0
        mp_forcezero(result->x);
5101
0
        mp_forcezero(result->y);
5102
0
        wc_ecc_del_point_ex(result, private_key->heap);
5103
5104
0
        wc_ecc_curve_free(curve);
5105
0
        FREE_CURVE_SPECS();
5106
0
    }
5107
0
#endif
5108
5109
#ifdef WOLFSSL_HAVE_SP_ECC
5110
    if ((err == MP_OKAY) && checkInf) {
5111
        /* The single precision implementations above serialize the point at
5112
         * infinity as an all-zero x-coordinate and report success, so the
5113
         * identity has to be recognized from the output. SP 800-56Ar3 5.7.1.2
5114
         * requires an error and stop in that case. Accumulate over the whole
5115
         * buffer so the scan does not branch on the secret. */
5116
        word32 i;
5117
        byte   acc = 0;
5118
5119
        for (i = 0; i < *outlen; i++) {
5120
            acc |= out[i];
5121
        }
5122
        if (acc == 0) {
5123
            err = ECC_INF_E;
5124
        }
5125
    }
5126
#endif
5127
5128
0
  errout:
5129
5130
#ifdef HAVE_ECC_CDH
5131
    if (k == k_lcl)
5132
        mp_forcezero(k);
5133
    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
5134
#endif
5135
5136
0
    return err;
5137
0
}
5138
5139
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5140
static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
5141
            ecc_point* point, byte* out, word32 *outlen)
5142
{
5143
    int err = 0;
5144
5145
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5146
    DECLARE_CURVE_SPECS(3);
5147
5148
    /* load curve info */
5149
    ALLOC_CURVE_SPECS(3, err);
5150
    if (err == MP_OKAY) {
5151
        err = wc_ecc_curve_load(private_key->dp, &curve,
5152
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5153
             ECC_CURVE_FIELD_ORDER));
5154
    }
5155
5156
    if (err != MP_OKAY) {
5157
        FREE_CURVE_SPECS();
5158
        return err;
5159
    }
5160
5161
    if (private_key->dp
5162
    #ifdef WOLFSSL_CUSTOM_CURVES
5163
        && private_key->dp->id != ECC_CURVE_CUSTOM
5164
    #endif
5165
    #ifdef HAVE_CAVIUM_V
5166
        /* verify the curve is supported by hardware */
5167
        && NitroxEccIsCurveSupported(private_key)
5168
    #endif
5169
    ) {
5170
        word32 keySz = private_key->dp->size;
5171
5172
        /* sync public key x/y */
5173
        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
5174
            &ecc_get_k(private_key)->raw, keySz);
5175
        if (err == MP_OKAY)
5176
            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
5177
        if (err == MP_OKAY)
5178
            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
5179
    #ifdef HAVE_CAVIUM_V
5180
        /* allocate buffer for output */
5181
        if (err == MP_OKAY)
5182
            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
5183
        if (err == MP_OKAY)
5184
            err = wc_bigint_alloc(&private_key->e->raw,
5185
                NitroxEccGetSize(private_key)*2);
5186
        if (err == MP_OKAY)
5187
            err = NitroxEcdh(private_key,
5188
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5189
                private_key->e->raw.buf, &private_key->e->raw.len,
5190
                &curve->prime->raw);
5191
    #else
5192
        if (err == MP_OKAY)
5193
            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
5194
        if (err == MP_OKAY)
5195
            err = IntelQaEcdh(&private_key->asyncDev,
5196
                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
5197
                out, outlen,
5198
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5199
                private_key->dp->cofactor);
5200
    #endif
5201
    }
5202
    else
5203
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5204
    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
5205
        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
5206
        sw->eccSharedSec.private_key = private_key;
5207
        sw->eccSharedSec.public_point = point;
5208
        sw->eccSharedSec.out = out;
5209
        sw->eccSharedSec.outLen = outlen;
5210
        err = WC_PENDING_E;
5211
    }
5212
    else
5213
#endif
5214
    {
5215
        /* use sync in other cases */
5216
        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
5217
    }
5218
5219
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5220
        private_key->state++;
5221
    }
5222
5223
#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
5224
    wc_ecc_curve_free(curve);
5225
    FREE_CURVE_SPECS();
5226
#endif
5227
5228
    return err;
5229
}
5230
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5231
5232
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
5233
/**
5234
 Create an ECC shared secret between private key and public point
5235
 private_key      The private ECC key (heap hint based on private key)
5236
 point            The point to use (public key)
5237
 out              [out] Destination of the shared secret
5238
                        Conforms to EC-DH from ANSI X9.63
5239
 outlen           [in/out] The max size and resulting size of the shared secret
5240
 return           MP_OKAY if successful
5241
*/
5242
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5243
                            byte* out, word32 *outlen)
5244
0
{
5245
0
    int err;
5246
5247
0
    if (private_key == NULL || point == NULL || out == NULL ||
5248
0
                                                            outlen == NULL) {
5249
0
        return BAD_FUNC_ARG;
5250
0
    }
5251
5252
    /* type valid? */
5253
0
    if (private_key->type != ECC_PRIVATEKEY &&
5254
0
            private_key->type != ECC_PRIVATEKEY_ONLY) {
5255
0
        WOLFSSL_MSG("ECC_BAD_ARG_E");
5256
0
        return ECC_BAD_ARG_E;
5257
0
    }
5258
5259
    /* Verify domain params supplied */
5260
0
    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
5261
0
        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
5262
0
        return ECC_BAD_ARG_E;
5263
0
    }
5264
5265
0
    switch (private_key->state) {
5266
0
        case ECC_STATE_NONE:
5267
0
        case ECC_STATE_SHARED_SEC_GEN:
5268
0
            private_key->state = ECC_STATE_SHARED_SEC_GEN;
5269
5270
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5271
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5272
                err = wc_ecc_shared_secret_gen_async(private_key, point,
5273
                    out, outlen);
5274
            }
5275
            else
5276
        #endif
5277
0
            {
5278
0
                err = wc_ecc_shared_secret_gen_sync(private_key, point,
5279
0
                    out, outlen);
5280
0
            }
5281
0
            if (err < 0) {
5282
0
                break;
5283
0
            }
5284
0
            FALL_THROUGH;
5285
5286
0
        case ECC_STATE_SHARED_SEC_RES:
5287
0
            private_key->state = ECC_STATE_SHARED_SEC_RES;
5288
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5289
            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5290
            #ifdef HAVE_CAVIUM_V
5291
                /* verify the curve is supported by hardware */
5292
                if (NitroxEccIsCurveSupported(private_key)) {
5293
                    /* copy output */
5294
                    *outlen = private_key->dp->size;
5295
                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
5296
                }
5297
            #endif /* HAVE_CAVIUM_V */
5298
            }
5299
        #endif /* WOLFSSL_ASYNC_CRYPT */
5300
0
            err = 0;
5301
0
            break;
5302
5303
0
        default:
5304
0
            err = BAD_STATE_E;
5305
0
    } /* switch */
5306
5307
    /* if async pending then return and skip done cleanup below */
5308
0
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
5309
0
        return err;
5310
0
    }
5311
5312
    /* cleanup */
5313
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5314
    wc_ecc_free_async(private_key);
5315
#endif
5316
0
    private_key->state = ECC_STATE_NONE;
5317
5318
0
    return err;
5319
0
}
5320
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
5321
#elif defined(WOLFSSL_KCAPI_ECC)
5322
int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
5323
                            byte* out, word32 *outlen)
5324
{
5325
    int err;
5326
    WC_DECLARE_VAR(public_key, ecc_key, 1,
5327
                   private_key ? private_key->heap : NULL);
5328
5329
    WC_ALLOC_VAR_EX(public_key, ecc_key, 1, private_key->heap, DYNAMIC_TYPE_ECC,
5330
                    return MEMORY_E);
5331
5332
    err = wc_ecc_init_ex(public_key, private_key->heap, INVALID_DEVID);
5333
    if (err == MP_OKAY) {
5334
        #if FIPS_VERSION3_GE(6,0,0)
5335
        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5336
         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5337
         * keysize here when relying on default selection */
5338
        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
5339
            if (private_key->dp->size == 0 &&
5340
                (private_key->dp->id == ECC_SECP256R1 ||
5341
                private_key->dp->id == ECC_SECP224R1 ||
5342
                private_key->dp->id == ECC_SECP384R1 ||
5343
                private_key->dp->id == ECC_SECP521R1)) {
5344
                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
5345
                err = 0;
5346
            } else {
5347
                WOLFSSL_MSG("ECC curve too small for FIPS mode");
5348
                err = ECC_CURVE_OID_E;
5349
            }
5350
        }
5351
        if (err == 0) { /* FIPS specific check */
5352
        #endif
5353
        err = wc_ecc_set_curve(public_key, private_key->dp->size,
5354
                               private_key->dp->id);
5355
        if (err == MP_OKAY) {
5356
            err = mp_copy(point->x, public_key->pubkey.x);
5357
        }
5358
        #if FIPS_VERSION3_GE(6,0,0)
5359
        } /* end FIPS specific check */
5360
        #endif
5361
        if (err == MP_OKAY) {
5362
            err = mp_copy(point->y, public_key->pubkey.y);
5363
        }
5364
        if (err == MP_OKAY) {
5365
            err = wc_ecc_shared_secret(private_key, public_key, out, outlen);
5366
        }
5367
5368
        wc_ecc_free(public_key);
5369
    }
5370
5371
    WC_FREE_VAR_EX(public_key, private_key->heap, DYNAMIC_TYPE_ECC);
5372
    return err;
5373
}
5374
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
5375
#endif /* HAVE_ECC_DHE */
5376
5377
/* Checks if a point p lies on the curve with index curve_idx */
5378
int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
5379
1.05k
{
5380
1.05k
    int err = MP_OKAY;
5381
1.05k
    DECLARE_CURVE_SPECS(3);
5382
5383
1.05k
    if (p == NULL)
5384
0
        return BAD_FUNC_ARG;
5385
5386
    /* is the IDX valid ?  */
5387
1.05k
    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
5388
0
       return ECC_BAD_ARG_E;
5389
0
    }
5390
5391
1.05k
    ALLOC_CURVE_SPECS(3, err);
5392
1.05k
    if (err == MP_OKAY) {
5393
1.05k
        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
5394
1.05k
                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
5395
1.05k
                                ECC_CURVE_FIELD_BF);
5396
1.05k
    }
5397
5398
1.05k
    if (err == MP_OKAY) {
5399
1.05k
        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
5400
1.05k
    }
5401
5402
1.05k
    wc_ecc_curve_free(curve);
5403
1.05k
    FREE_CURVE_SPECS();
5404
5405
1.05k
    return err;
5406
1.05k
}
5407
5408
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
5409
    !defined(WOLFSSL_CRYPTOCELL) && \
5410
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
5411
      defined(WOLFSSL_IMXRT1170_CAAM))
5412
/* return 1 if point is at infinity, 0 if not, < 0 on error */
5413
int wc_ecc_point_is_at_infinity(ecc_point* p)
5414
1.05k
{
5415
1.05k
    if (p == NULL)
5416
0
        return BAD_FUNC_ARG;
5417
1.05k
    if (mp_iszero(p->x) && mp_iszero(p->y))
5418
2
        return 1;
5419
5420
1.05k
    return 0;
5421
1.05k
}
5422
#endif
5423
5424
/* generate random and ensure its greater than 0 and less than order */
5425
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
5426
0
{
5427
0
#ifndef WC_NO_RNG
5428
0
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
5429
0
    int err;
5430
0
    byte buf[ECC_MAXSIZE_GEN];
5431
5432
0
    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
5433
0
                                                                order == NULL) {
5434
0
        return BAD_FUNC_ARG;
5435
0
    }
5436
5437
    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
5438
    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
5439
0
    size += 8;
5440
5441
    /* make up random string */
5442
0
    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5443
#ifdef WOLFSSL_CHECK_MEM_ZERO
5444
    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5445
#endif
5446
5447
    /* load random buffer data into k */
5448
0
    if (err == 0)
5449
0
        err = mp_read_unsigned_bin(k, buf, (word32)size);
5450
5451
    /* the key should be smaller than the order of base point */
5452
0
    if (err == MP_OKAY) {
5453
0
        if (mp_cmp(k, order) != MP_LT) {
5454
0
            err = mp_mod(k, order, k);
5455
0
        }
5456
0
    }
5457
5458
    /* quick sanity check to make sure we're not dealing with a 0 key */
5459
0
    if (err == MP_OKAY) {
5460
0
        if (mp_iszero(k) == MP_YES)
5461
0
          err = MP_ZERO_E;
5462
0
    }
5463
5464
0
    ForceZero(buf, ECC_MAXSIZE_GEN);
5465
#ifdef WOLFSSL_CHECK_MEM_ZERO
5466
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5467
#endif
5468
5469
0
    return err;
5470
#else
5471
    int err;
5472
    byte buf[ECC_MAXSIZE_GEN];
5473
    int bits;
5474
5475
    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
5476
            (k == NULL) || (order == NULL)) {
5477
        return BAD_FUNC_ARG;
5478
    }
5479
5480
    /* Get actual bit count of order. */
5481
    bits = mp_count_bits(order);
5482
    size = (bits + 7) >> 3;
5483
5484
    /* generate number in range of order through rejection sampling. */
5485
    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
5486
    do {
5487
        /* A.2.2 step 3: make up random string */
5488
        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
5489
    #ifdef WOLFSSL_CHECK_MEM_ZERO
5490
        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
5491
    #endif
5492
        /* Generated multiple of 8 bits but now make it size of order. */
5493
        if ((bits & 0x7) > 0) {
5494
            buf[0] &= (1 << (bits & 0x7)) - 1;
5495
        }
5496
5497
        /* A.2.2 step 4: convert to integer. */
5498
        /* A.4.2 step 3: Convert the bit string to integer x. */
5499
        if (err == 0) {
5500
            err = mp_read_unsigned_bin(k, buf, (word32)size);
5501
        }
5502
5503
        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
5504
        if ((err == MP_OKAY) && !mp_iszero(k) &&
5505
                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
5506
            break;
5507
        }
5508
    }
5509
    while (err == MP_OKAY);
5510
5511
    ForceZero(buf, ECC_MAXSIZE_GEN);
5512
#ifdef WOLFSSL_CHECK_MEM_ZERO
5513
    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
5514
#endif
5515
5516
    return err;
5517
#endif
5518
#else
5519
    (void)rng;
5520
    (void)size;
5521
    (void)k;
5522
    (void)order;
5523
    return NOT_COMPILED_IN;
5524
#endif /* !WC_NO_RNG */
5525
0
}
5526
5527
static WC_INLINE void wc_ecc_reset(ecc_key* key)
5528
1.07k
{
5529
    /* make sure required key variables are reset */
5530
1.07k
    key->state = ECC_STATE_NONE;
5531
1.07k
}
5532
5533
5534
#if defined(HAVE_ECC_MAKE_PUB) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
5535
/* compute the public key Q = d*G in software.
5536
 *
5537
 * key    private key holding the scalar d, must be present and in range
5538
 * curve  [in]curve for key, cannot be NULL
5539
 * pub    [out]initialized ecc_point receiving the public key
5540
 * rng    optional RNG for a timing-resistant point multiply, may be NULL
5541
 *
5542
 * returns MP_OKAY on success
5543
 */
5544
static int ecc_make_pub_sw(ecc_key* key, ecc_curve_spec* curve,
5545
        ecc_point* pub, WC_RNG* rng)
5546
0
{
5547
0
    int err = MP_OKAY;
5548
5549
0
    (void)rng;
5550
5551
    /* The private scalar must be in range for the base-point multiply
5552
     * below. */
5553
0
    if (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
5554
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT)) {
5555
0
        err = ECC_PRIV_KEY_E;
5556
0
    }
5557
5558
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
5559
    defined(HAVE_INTEL_QA)
5560
    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5561
        word32 keySz = key->dp->size;
5562
        /* sync private key to raw */
5563
        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
5564
        if (err == MP_OKAY) {
5565
            err = IntelQaEccPointMul(&key->asyncDev,
5566
                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
5567
                &curve->Gx->raw, &curve->Gy->raw,
5568
                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
5569
                key->dp->cofactor);
5570
        }
5571
    }
5572
    else
5573
#endif
5574
0
    { /* BEGIN: Software Crypto */
5575
#ifdef WOLFSSL_HAVE_SP_ECC
5576
    /* Single-Precision Math (optimized for specific curves) */
5577
    if (err != MP_OKAY) {
5578
    }
5579
    else
5580
#ifndef WOLFSSL_SP_NO_256
5581
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
5582
        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
5583
    }
5584
    else
5585
#endif /* WOLFSSL_SP_NO_256 */
5586
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
5587
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
5588
        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
5589
    }
5590
    else
5591
#endif
5592
#ifdef WOLFSSL_SP_384
5593
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
5594
        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
5595
    }
5596
    else
5597
#endif
5598
#ifdef WOLFSSL_SP_521
5599
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
5600
        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
5601
    }
5602
    else
5603
#endif
5604
#endif /* WOLFSSL_HAVE_SP_ECC */
5605
5606
#if defined(WOLFSSL_SP_MATH)
5607
        err = WC_KEY_SIZE_E;
5608
#else
5609
0
    if (err == MP_OKAY) {
5610
        /* Multi-Precision Math: compute public curve */
5611
0
        mp_digit mp = 0;
5612
0
        ecc_point* base = NULL;
5613
    #ifdef WOLFSSL_NO_MALLOC
5614
        ecc_point  lcl_base;
5615
        base = &lcl_base;
5616
    #endif
5617
0
        err = wc_ecc_new_point_ex(&base, key->heap);
5618
5619
        /* read in the x/y for this key */
5620
0
        if (err == MP_OKAY)
5621
0
            err = mp_copy(curve->Gx, base->x);
5622
0
        if (err == MP_OKAY)
5623
0
            err = mp_copy(curve->Gy, base->y);
5624
0
        if (err == MP_OKAY)
5625
0
            err = mp_montgomery_setup(curve->prime, &mp);
5626
0
        if (err == MP_OKAY)
5627
0
            err = mp_set(base->z, 1);
5628
5629
        /* make the public key */
5630
0
        if (err == MP_OKAY) {
5631
            /* Map in a separate call as this should be constant time */
5632
0
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
5633
0
                                 curve->prime, curve->order, rng, 0, key->heap);
5634
0
            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
5635
0
               err = MEMORY_E;
5636
0
            }
5637
0
        }
5638
0
        if (err == MP_OKAY) {
5639
            /* Use constant time map if compiled in */
5640
0
            err = ecc_map_ex(pub, curve->prime, mp, 1);
5641
0
        }
5642
5643
0
        wc_ecc_del_point_ex(base, key->heap);
5644
0
    }
5645
0
#endif /* WOLFSSL_SP_MATH */
5646
0
    } /* END: Software Crypto */
5647
5648
0
    return err;
5649
0
}
5650
#endif /* HAVE_ECC_MAKE_PUB && !WOLF_CRYPTO_CB_ONLY_ECC */
5651
5652
/* create the public ECC key from a private key
5653
 *
5654
 * key     an initialized private key to generate public part from
5655
 * curve   [in]curve for key, cannot be NULL
5656
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5657
 *         is cached in key instead.
5658
 *
5659
 * Note this function is local to the file because of the argument type
5660
 *      ecc_curve_spec. Having this argument allows for not having to load the
5661
 *      curve type multiple times when generating a key with wc_ecc_make_key().
5662
 * For async the results are placed directly into pubOut, so this function
5663
 *      does not need to be called again
5664
 *
5665
 * returns MP_OKAY on success
5666
 */
5667
static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
5668
        ecc_point* pubOut, WC_RNG* rng)
5669
0
{
5670
0
    int err = MP_OKAY;
5671
0
#ifdef HAVE_ECC_MAKE_PUB
5672
0
    ecc_point* pub;
5673
0
    int doneInCb = 0;
5674
0
#endif /* HAVE_ECC_MAKE_PUB */
5675
5676
0
    (void)rng;
5677
5678
0
    if (key == NULL) {
5679
0
        return BAD_FUNC_ARG;
5680
0
    }
5681
5682
0
#ifdef HAVE_ECC_MAKE_PUB
5683
    /* if ecc_point passed in then use it as output for public key point */
5684
0
    if (pubOut != NULL) {
5685
0
        pub = pubOut;
5686
0
    }
5687
0
    else {
5688
        /* caching public key making it a ECC_PRIVATEKEY instead of
5689
           ECC_PRIVATEKEY_ONLY */
5690
0
        pub = &key->pubkey;
5691
0
        key->type = ECC_PRIVATEKEY_ONLY;
5692
0
    }
5693
5694
0
    if (err == MP_OKAY) {
5695
0
    #ifndef ALT_ECC_SIZE
5696
0
        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
5697
    #else
5698
        pub->x = (mp_int*)&pub->xyz[0];
5699
        pub->y = (mp_int*)&pub->xyz[1];
5700
        pub->z = (mp_int*)&pub->xyz[2];
5701
        alt_fp_init(pub->x);
5702
        alt_fp_init(pub->y);
5703
        alt_fp_init(pub->z);
5704
    #endif
5705
0
    }
5706
5707
#ifdef WOLF_CRYPTO_CB
5708
    /* offload Q = d*G to the device; fall through to software only when the
5709
     * device reports the operation unavailable.
5710
     *
5711
     * Under WOLF_CRYPTO_CB_FIND the devId gate is dropped so a find callback
5712
     * can route a key initialized with INVALID_DEVID. This helper is also
5713
     * shared by internal callers that compute a point from a transient scalar
5714
     * in key->k - the ECDSA software-sign nonce R = k*G (ecc_sign_hash_sw),
5715
     * keygen public-part derivation, and verify-time public-key recovery.
5716
     * Reaching the software signer means the device already declined to sign
5717
     * (the whole-sign offload wc_CryptoCb_EccSign ran first), so a find
5718
     * callback that hands this make-pub to a device notwithstanding the
5719
     * INVALID_DEVID is expected to likewise decline it. If it does not decline
5720
     * *and* the device ignores key->k (e.g. relying on an internal key
5721
     * representation), it returns d*G instead of the requested k*G and the
5722
     * resulting signature is wrong - but such a scenario is very unlikely. */
5723
    #ifndef WOLF_CRYPTO_CB_FIND
5724
    if ((err == MP_OKAY) && (key->devId != INVALID_DEVID))
5725
    #else
5726
    if (err == MP_OKAY)
5727
    #endif
5728
    {
5729
        err = wc_CryptoCb_EccMakePub(key, pub);
5730
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5731
            doneInCb = 1;
5732
        else
5733
            err = MP_OKAY; /* device declined the offload; fall back */
5734
    }
5735
#endif
5736
5737
0
    if ((err == MP_OKAY) && !doneInCb) {
5738
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5739
        /* software derivation is stripped and no device handled the op;
5740
         * fail closed */
5741
        (void)curve;
5742
        err = NO_VALID_DEVID;
5743
#else
5744
0
        err = ecc_make_pub_sw(key, curve, pub, rng);
5745
0
#endif
5746
0
    }
5747
5748
0
    if (err != MP_OKAY
5749
    #ifdef WOLFSSL_ASYNC_CRYPT
5750
        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
5751
    #endif
5752
0
    ) {
5753
        /* clean up if failed */
5754
0
    #ifndef ALT_ECC_SIZE
5755
0
        mp_clear(pub->x);
5756
0
        mp_clear(pub->y);
5757
0
        mp_clear(pub->z);
5758
0
    #endif
5759
0
    }
5760
5761
#else
5762
    /* Using hardware crypto, that does not support ecc_make_pub_ex */
5763
    (void)curve;
5764
    err = NOT_COMPILED_IN;
5765
#endif /* HAVE_ECC_MAKE_PUB */
5766
5767
    /* change key state if public part is cached */
5768
0
    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
5769
0
        key->type = ECC_PRIVATEKEY;
5770
0
    }
5771
5772
0
    return err;
5773
0
}
5774
5775
5776
/* create the public ECC key from a private key
5777
 *
5778
 * key     an initialized private key to generate public part from
5779
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5780
 *         is cached in key instead.
5781
 *
5782
 *
5783
 * returns MP_OKAY on success
5784
 */
5785
int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
5786
0
{
5787
0
    WOLFSSL_ENTER("wc_ecc_make_pub");
5788
5789
0
    return wc_ecc_make_pub_ex(key, pubOut, NULL);
5790
0
}
5791
5792
/* create the public ECC key from a private key - mask timing use random z
5793
 *
5794
 * key     an initialized private key to generate public part from
5795
 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
5796
 *         is cached in key instead.
5797
 *
5798
 *
5799
 * returns MP_OKAY on success
5800
 */
5801
int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
5802
0
{
5803
0
    int err = MP_OKAY;
5804
0
    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
5805
5806
0
    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
5807
5808
0
    if (key == NULL) {
5809
0
        return BAD_FUNC_ARG;
5810
0
    }
5811
5812
    /* load curve info */
5813
0
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
5814
0
    if (err == MP_OKAY) {
5815
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
5816
0
    }
5817
0
    if (err == MP_OKAY) {
5818
0
        err = ecc_make_pub_ex(key, curve, pubOut, rng);
5819
0
    }
5820
5821
0
    wc_ecc_curve_free(curve);
5822
0
    FREE_CURVE_SPECS();
5823
5824
0
    return err;
5825
0
}
5826
5827
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5828
    defined(WOLFSSL_MICROCHIP_TA100)
5829
/* Resolve the curve id to pass to the Microchip backend. Keep the curve
5830
 * distinction by id (not size): SECP256R1, SECP256K1 and BRAINPOOLP256R1 are
5831
 * all 32 bytes and must NOT be collapsed onto SECP256R1. */
5832
static WC_INLINE int microchip_curve_id_for_key(const ecc_key* key)
5833
{
5834
    if (key != NULL && key->dp != NULL) {
5835
        return key->dp->id;
5836
    }
5837
    return ECC_CURVE_DEF;
5838
}
5839
#endif
5840
5841
5842
static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
5843
        int curve_id, int flags)
5844
0
{
5845
0
    int err = 0;
5846
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
5847
    !defined(WOLFSSL_MICROCHIP_TA100) && \
5848
    !defined(WOLFSSL_ATECC608A)
5849
    const CRYS_ECPKI_Domain_t*  pDomain;
5850
    CRYS_ECPKI_KG_TempData_t    tempBuff;
5851
    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
5852
    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
5853
    word32 raw_size = 0;
5854
#endif
5855
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
5856
    defined(WC_ECC_NONBLOCK_ONLY)
5857
    ecc_nb_ctx_t nb_ctx;
5858
    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
5859
#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
5860
5861
0
    if (key == NULL || rng == NULL) {
5862
0
        return BAD_FUNC_ARG;
5863
0
    }
5864
5865
    /* make sure required variables are reset */
5866
0
    wc_ecc_reset(key);
5867
5868
    #if FIPS_VERSION3_GE(6,0,0)
5869
    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
5870
     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
5871
     * keysize here when relying on default selection */
5872
    if (keysize < WC_ECC_FIPS_GEN_MIN) {
5873
        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
5874
             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
5875
             curve_id == ECC_SECP521R1)) {
5876
            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
5877
            err = 0;
5878
        } else {
5879
            WOLFSSL_MSG("ECC curve too small for FIPS mode");
5880
            err = ECC_CURVE_OID_E;
5881
        }
5882
    }
5883
    if (err == 0) { /* FIPS specific check */
5884
    #endif
5885
0
    err = wc_ecc_set_curve(key, keysize, curve_id);
5886
0
    if (err != 0) {
5887
0
        return err;
5888
0
    }
5889
    #if FIPS_VERSION3_GE(6,0,0)
5890
    } /* end FIPS specific check */
5891
    #endif
5892
0
    key->flags = (byte)flags;
5893
5894
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
5895
    #ifndef WOLF_CRYPTO_CB_FIND
5896
    if (key->devId != INVALID_DEVID)
5897
    #endif
5898
    {
5899
        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
5900
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5901
            return err;
5902
        /* fall-through when unavailable */
5903
    }
5904
#endif
5905
5906
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
5907
    return NO_VALID_DEVID;
5908
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
5909
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
5910
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
5911
    #ifdef HAVE_CAVIUM
5912
        /* TODO: Not implemented */
5913
    #elif defined(HAVE_INTEL_QA)
5914
        /* Implemented in ecc_make_pub_ex for the pub calc */
5915
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5916
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
5917
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
5918
            sw->eccMake.rng = rng;
5919
            sw->eccMake.key = key;
5920
            sw->eccMake.size = keysize;
5921
            sw->eccMake.curve_id = curve_id;
5922
            return WC_PENDING_E;
5923
        }
5924
    #endif
5925
    }
5926
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
5927
5928
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
5929
    defined(WOLFSSL_MICROCHIP_TA100)
5930
#if defined(WOLFSSL_MICROCHIP_TA100)
5931
    /* TA100 supports multiple curves natively. */
5932
    if (key->dp->id == ECC_SECP256R1 ||
5933
        key->dp->id == ECC_SECP224R1 ||
5934
        key->dp->id == ECC_SECP384R1 ||
5935
        key->dp->id == ECC_SECP256K1 ||
5936
        key->dp->id == ECC_BRAINPOOLP256R1) {
5937
#else
5938
    /* ATECC508A/608A hardware only supports SECP256R1. */
5939
    if (key->dp->id == ECC_SECP256R1) {
5940
#endif
5941
       key->type = ECC_PRIVATEKEY;
5942
       if (key->slot == ATECC_INVALID_SLOT)
5943
           key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
5944
       err = atmel_ecc_create_key(key->slot, microchip_curve_id_for_key(key),
5945
           key->pubkey_raw);
5946
5947
       /* populate key->pubkey */
5948
       if (err == 0
5949
       #ifdef ALT_ECC_SIZE
5950
          && key->pubkey.x
5951
       #endif
5952
       ) {
5953
           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
5954
                                      (word32)key->dp->size);
5955
       }
5956
       if (err == 0
5957
       #ifdef ALT_ECC_SIZE
5958
          && key->pubkey.y
5959
       #endif
5960
       ) {
5961
           err = mp_read_unsigned_bin(key->pubkey.y,
5962
                                      key->pubkey_raw + key->dp->size,
5963
                                      (word32)key->dp->size);
5964
       }
5965
   }
5966
   else {
5967
      err = NOT_COMPILED_IN;
5968
   }
5969
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE) && \
5970
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
5971
    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
5972
    key->type = ECC_PRIVATEKEY;
5973
#elif defined(WOLFSSL_CRYPTOCELL)
5974
5975
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
5976
    raw_size = (word32)(key->dp->size)*2 + 1;
5977
5978
    /* generate first key pair */
5979
    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
5980
                                wc_rndGenVectFunc,
5981
                                pDomain,
5982
                                &key->ctx.privKey,
5983
                                &key->ctx.pubKey,
5984
                                &tempBuff,
5985
                                &fipsCtx);
5986
5987
    if (err != SA_SILIB_RET_OK){
5988
        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
5989
        return err;
5990
    }
5991
    key->type = ECC_PRIVATEKEY;
5992
5993
    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
5994
                                   CRYS_EC_PointUncompressed,
5995
                                   &ucompressed_key[0],
5996
                                   (uint32_t*)&raw_size);
5997
5998
    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
5999
        err = mp_read_unsigned_bin(key->pubkey.x,
6000
                                   &ucompressed_key[1], key->dp->size);
6001
        if (err == MP_OKAY) {
6002
            err = mp_read_unsigned_bin(key->pubkey.y,
6003
                            &ucompressed_key[1+key->dp->size],key->dp->size);
6004
        }
6005
    }
6006
    raw_size = key->dp->size;
6007
    if (err == MP_OKAY) {
6008
        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
6009
                                       ucompressed_key,
6010
                                       (uint32_t*)&raw_size);
6011
    }
6012
6013
    if (err == SA_SILIB_RET_OK) {
6014
        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
6015
#ifdef WOLFSSL_ECC_BLIND_K
6016
        if (err == MP_OKAY) {
6017
            err = ecc_blind_k_rng(key, rng);
6018
        }
6019
#endif
6020
    }
6021
6022
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
6023
    return silabs_ecc_make_key(key, keysize);
6024
#elif defined(WOLFSSL_KCAPI_ECC)
6025
6026
    err = KcapiEcc_MakeKey(key, keysize, curve_id);
6027
    (void)rng;
6028
6029
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6030
    if (xil_curve_type[key->dp->id] == 0)
6031
        return ECC_CURVE_OID_E;
6032
6033
    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
6034
    if (err)
6035
        return err;
6036
    /* Make sure that private key is max. 521 bits */
6037
    if (key->dp->size == 66)
6038
        key->privKey[65] &= 0x1U;
6039
6040
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
6041
6042
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6043
                                        2 * key->dp->size);
6044
6045
    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
6046
                                      xil_curve_type[key->dp->id],
6047
                                      XIL_CAST_U64(key->privKey),
6048
                                      XIL_CAST_U64(key->keyRaw));
6049
    if (err != XST_SUCCESS) {
6050
        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
6051
        err = WC_HW_E;
6052
    }
6053
6054
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
6055
                                        2 * key->dp->size);
6056
6057
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
6058
    if (err == 0)
6059
        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
6060
                                          xil_curve_type[key->dp->id],
6061
                                          XIL_CAST_U64(key->keyRaw));
6062
#endif
6063
6064
    if (err == 0)
6065
        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
6066
                             key->heap);
6067
    if (err == 0)
6068
        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
6069
                             key->dp->size, key->heap);
6070
    if (err == 0)
6071
        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
6072
                             key->heap);
6073
#ifdef WOLFSSL_ECC_BLIND_K
6074
    if (err == 0)
6075
        err = ecc_blind_k_rng(key, rng);
6076
#endif
6077
    if (err == 0)
6078
        err = mp_set(key->pubkey.z, 1);
6079
    if (err) {
6080
        key->privKey = NULL;
6081
        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
6082
        return err;
6083
    }
6084
6085
    key->type = ECC_PRIVATEKEY;
6086
6087
#else
6088
6089
#ifdef WOLFSSL_HAVE_SP_ECC
6090
6091
#ifndef WOLFSSL_SP_NO_256
6092
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
6093
    #ifndef WC_ECC_NONBLOCK
6094
        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6095
    #else
6096
        if (key->nb_ctx) {
6097
            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6098
                                         &key->pubkey, key->heap);
6099
        }
6100
        else {
6101
        #ifdef WC_ECC_NONBLOCK_ONLY
6102
            do { /* perform blocking call to non-blocking function */
6103
                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
6104
                                             &key->pubkey, key->heap);
6105
            } while (err == FP_WOULDBLOCK);
6106
        #else
6107
            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
6108
        #endif /* WC_ECC_NONBLOCK_ONLY */
6109
        }
6110
    #endif /* !WC_ECC_NONBLOCK */
6111
6112
        if (err == MP_OKAY) {
6113
            key->type = ECC_PRIVATEKEY;
6114
        }
6115
    }
6116
    else
6117
#endif /* !WOLFSSL_SP_NO_256 */
6118
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
6119
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
6120
        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
6121
        if (err == MP_OKAY) {
6122
            key->type = ECC_PRIVATEKEY;
6123
        }
6124
    }
6125
    else
6126
#endif
6127
#ifdef WOLFSSL_SP_384
6128
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
6129
    #ifndef WC_ECC_NONBLOCK
6130
        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6131
    #else
6132
        if (key->nb_ctx) {
6133
            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6134
                                         &key->pubkey, key->heap);
6135
        }
6136
        else {
6137
        #ifdef WC_ECC_NONBLOCK_ONLY
6138
            do { /* perform blocking call to non-blocking function */
6139
                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
6140
                                             &key->pubkey, key->heap);
6141
            } while (err == FP_WOULDBLOCK);
6142
        #else
6143
            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
6144
        #endif /* WC_ECC_NONBLOCK_ONLY */
6145
        }
6146
    #endif /* !WC_ECC_NONBLOCK */
6147
6148
        if (err == MP_OKAY) {
6149
            key->type = ECC_PRIVATEKEY;
6150
        }
6151
    }
6152
    else
6153
#endif /* WOLFSSL_SP_384 */
6154
#ifdef WOLFSSL_SP_521
6155
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
6156
    #ifndef WC_ECC_NONBLOCK
6157
        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6158
    #else
6159
        if (key->nb_ctx) {
6160
            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
6161
                                         &key->pubkey, key->heap);
6162
        }
6163
        else {
6164
        #ifdef WC_ECC_NONBLOCK_ONLY
6165
            do { /* perform blocking call to non-blocking function */
6166
                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
6167
                                             &key->pubkey, key->heap);
6168
            } while (err == FP_WOULDBLOCK);
6169
        #else
6170
            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
6171
        #endif /* WC_ECC_NONBLOCK_ONLY */
6172
        }
6173
    #endif /* !WC_ECC_NONBLOCK */
6174
6175
        if (err == MP_OKAY) {
6176
            key->type = ECC_PRIVATEKEY;
6177
        }
6178
    }
6179
    else
6180
#endif /* WOLFSSL_SP_521 */
6181
#endif /* WOLFSSL_HAVE_SP_ECC */
6182
6183
0
   { /* software key gen */
6184
#if defined(WOLFSSL_SP_MATH)
6185
        err = WC_KEY_SIZE_E;
6186
#else
6187
0
        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
6188
6189
        /* setup the key variables */
6190
0
#ifndef ALT_ECC_SIZE
6191
0
        err = mp_init(key->k);
6192
#else
6193
        err = 0;
6194
        key->k = (mp_int*)key->ka;
6195
        alt_fp_init(key->k);
6196
#endif
6197
6198
        /* load curve info */
6199
0
        if (err == MP_OKAY) {
6200
0
            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
6201
0
            if (err != MP_OKAY) {
6202
0
                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6203
0
            }
6204
0
        }
6205
6206
0
        if (err == MP_OKAY) {
6207
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
6208
0
            if (err != MP_OKAY) {
6209
0
                WOLFSSL_MSG("wc_ecc_curve_load failed");
6210
0
            }
6211
0
        }
6212
6213
        /* generate k */
6214
0
        if (err == MP_OKAY) {
6215
0
            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
6216
0
            if (err != MP_OKAY) {
6217
0
                WOLFSSL_MSG("wc_ecc_gen_k failed");
6218
0
            }
6219
0
        }
6220
6221
        /* generate public key from k */
6222
0
        if (err == MP_OKAY) {
6223
0
            err = ecc_make_pub_ex(key, curve, NULL, rng);
6224
0
            if (err != MP_OKAY) {
6225
0
                WOLFSSL_MSG("ecc_make_pub_ex failed");
6226
0
            }
6227
0
        }
6228
6229
0
        if (err == MP_OKAY
6230
        #ifdef WOLFSSL_ASYNC_CRYPT
6231
            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
6232
        #endif
6233
0
        ) {
6234
0
            key->type = ECC_PRIVATEKEY;
6235
0
        }
6236
0
        else {
6237
            /* cleanup these on failure case only */
6238
0
            mp_forcezero(key->k);
6239
0
        }
6240
6241
        /* cleanup allocations */
6242
0
        wc_ecc_curve_free(curve);
6243
0
        FREE_CURVE_SPECS();
6244
0
#endif /* WOLFSSL_SP_MATH */
6245
0
    }
6246
6247
#ifdef HAVE_WOLF_BIGINT
6248
    if (err == MP_OKAY)
6249
         err = wc_mp_to_bigint(key->k, &key->k->raw);
6250
    if (err == MP_OKAY)
6251
         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
6252
    if (err == MP_OKAY)
6253
         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
6254
    if (err == MP_OKAY)
6255
         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
6256
#endif
6257
6258
#ifdef WOLFSSL_ECC_BLIND_K
6259
    if (err == MP_OKAY)
6260
        err = ecc_blind_k_rng(key, rng);
6261
#endif
6262
6263
0
#endif /* HAVE_ECC_MAKE_PUB */
6264
6265
0
    return err;
6266
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
6267
0
}
6268
6269
6270
int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
6271
                        int flags)
6272
0
{
6273
0
    int err;
6274
6275
0
    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
6276
6277
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
6278
    !defined(WOLFSSL_KCAPI_ECC)
6279
    if (err == MP_OKAY) {
6280
        err = _ecc_validate_public_key(key, 0, 0);
6281
    }
6282
    if (err == MP_OKAY
6283
#if defined(WOLF_CRYPTO_CB)
6284
        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
6285
        && key->devId == INVALID_DEVID
6286
#endif
6287
        ) {
6288
        err = _ecc_pairwise_consistency_test(key, rng);
6289
    }
6290
    /* FIPS 140-3 IG 10.3.A (TE10.35.02): a key pair that fails post-
6291
     * generation validation or PCT must be rendered unusable so a caller
6292
     * that ignores the return value cannot use it. */
6293
    if (err != MP_OKAY) {
6294
        wc_ecc_free(key);
6295
    }
6296
#endif
6297
6298
0
    return err;
6299
0
}
6300
6301
WOLFSSL_ABI
6302
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
6303
0
{
6304
0
    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
6305
0
}
6306
6307
#ifdef ECC_DUMP_OID
6308
/* Optional dump of encoded OID for adding new curves */
6309
static int mOidDumpDone;
6310
static void wc_ecc_dump_oids(void)
6311
{
6312
    int x;
6313
6314
    if (mOidDumpDone) {
6315
        return;
6316
    }
6317
6318
    /* find matching OID sum (based on encoded value) */
6319
    for (x = 0; ecc_sets[x].size != 0; x++) {
6320
        int i;
6321
        byte* oid;
6322
        word32 oidSz, sum = 0;
6323
6324
        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
6325
6326
    #ifdef HAVE_OID_ENCODING
6327
        byte oidEnc[ECC_MAX_OID_LEN];
6328
6329
        oid = oidEnc;
6330
        oidSz = ECC_MAX_OID_LEN;
6331
6332
        printf("OID: ");
6333
        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
6334
            printf("%d.", ecc_sets[x].oid[i]);
6335
        }
6336
        printf("\n");
6337
6338
        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
6339
    #else
6340
        oid = (byte*)ecc_sets[x].oid;
6341
        oidSz = ecc_sets[x].oidSz;
6342
    #endif
6343
6344
        printf("OID Encoded: ");
6345
        for (i = 0; i < (int)oidSz; i++) {
6346
            printf("0x%02X,", oid[i]);
6347
        }
6348
        printf("\n");
6349
6350
        for (i = 0; i < (int)oidSz; i++) {
6351
            sum += oid[i];
6352
        }
6353
        printf("Sum: %u\n", sum);
6354
6355
        /* validate sum */
6356
        if (ecc_sets[x].oidSum != sum) {
6357
            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
6358
        }
6359
    }
6360
    mOidDumpDone = 1;
6361
}
6362
#endif /* ECC_DUMP_OID */
6363
6364
6365
WOLFSSL_ABI
6366
ecc_key* wc_ecc_key_new(void* heap)
6367
0
{
6368
0
    int devId = INVALID_DEVID;
6369
0
    ecc_key* key;
6370
6371
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6372
    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
6373
    devId = WOLFSSL_CAAM_DEVID;
6374
#endif
6375
0
    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
6376
0
    if (key) {
6377
0
        if (wc_ecc_init_ex(key, heap, devId) != 0) {
6378
0
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
6379
0
            key = NULL;
6380
0
        }
6381
0
    }
6382
6383
0
    return key;
6384
0
}
6385
6386
6387
WOLFSSL_ABI
6388
void wc_ecc_key_free(ecc_key* key)
6389
0
{
6390
0
    if (key) {
6391
0
        void* heap = key->heap;
6392
6393
0
        wc_ecc_free(key);
6394
0
        ForceZero(key, sizeof(ecc_key));
6395
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
6396
0
        (void)heap;
6397
0
    }
6398
0
}
6399
6400
6401
/**
6402
 Make a new ECC key
6403
 rng          An active RNG state
6404
 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
6405
 key          [out] Destination of the newly created key
6406
 return       MP_OKAY if successful,
6407
 upon error all allocated memory will be freed
6408
 */
6409
WOLFSSL_ABI
6410
int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
6411
0
{
6412
0
    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
6413
0
}
6414
6415
/* Setup dynamic pointers if using normal math for proper freeing */
6416
WOLFSSL_ABI
6417
int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
6418
2.18k
{
6419
2.18k
    int ret      = 0;
6420
6421
2.18k
    if (key == NULL) {
6422
0
        return BAD_FUNC_ARG;
6423
0
    }
6424
6425
#ifdef ECC_DUMP_OID
6426
    wc_ecc_dump_oids();
6427
#endif
6428
6429
2.18k
    XMEMSET(key, 0, sizeof(ecc_key));
6430
2.18k
    key->state = ECC_STATE_NONE;
6431
6432
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
6433
    key->devId = devId;
6434
#else
6435
2.18k
    (void)devId;
6436
2.18k
#endif
6437
6438
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6439
    defined(WOLFSSL_MICROCHIP_TA100)
6440
    key->slot = ATECC_INVALID_SLOT;
6441
#ifdef WOLFSSL_MICROCHIP_TA100
6442
    /* TA100 needs pubkey initialized to populate after genkey. With
6443
     * ALT_ECC_SIZE the x/y/z pointers must first be aimed at the inline
6444
     * xyz[] storage; mp_init_multi otherwise dereferences NULL. */
6445
#ifdef ALT_ECC_SIZE
6446
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6447
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6448
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6449
    alt_fp_init(key->pubkey.x);
6450
    alt_fp_init(key->pubkey.y);
6451
    alt_fp_init(key->pubkey.z);
6452
#else
6453
    ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
6454
                        NULL, NULL, NULL);
6455
    if (ret != MP_OKAY) {
6456
        return MEMORY_E;
6457
    }
6458
#endif
6459
#endif
6460
#else
6461
#if defined(WOLFSSL_KCAPI_ECC)
6462
    key->handle = NULL;
6463
#endif
6464
#ifdef ALT_ECC_SIZE
6465
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
6466
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
6467
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
6468
    alt_fp_init(key->pubkey.x);
6469
    alt_fp_init(key->pubkey.y);
6470
    alt_fp_init(key->pubkey.z);
6471
    key->k = (mp_int*)key->ka;
6472
    alt_fp_init(key->k);
6473
#ifdef WOLFSSL_ECC_BLIND_K
6474
    key->kb = (mp_int*)key->kba;
6475
    key->ku = (mp_int*)key->kia;
6476
    alt_fp_init(key->kb);
6477
    alt_fp_init(key->ku);
6478
#endif
6479
#else
6480
2.18k
    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
6481
2.18k
#ifndef WOLFSSL_ECC_BLIND_K
6482
2.18k
                                                                      NULL, NULL
6483
#else
6484
                                                                key->kb, key->ku
6485
#endif
6486
2.18k
                        );
6487
2.18k
    if (ret != MP_OKAY) {
6488
0
        return MEMORY_E;
6489
0
    }
6490
2.18k
#endif /* ALT_ECC_SIZE */
6491
#ifdef WOLFSSL_ECC_BLIND_K
6492
    mp_forcezero(key->kb);
6493
#endif
6494
2.18k
#endif /* WOLFSSL_ATECC508A */
6495
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
6496
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6497
     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
6498
     defined(WOLFSSL_NO_MALLOC)
6499
    ret = mp_init(key->sign_k);
6500
    if (ret != MP_OKAY) {
6501
        return MEMORY_E;
6502
    }
6503
#endif
6504
6505
#ifdef WOLFSSL_HEAP_TEST
6506
    (void)heap;
6507
    key->heap = (void*)WOLFSSL_HEAP_TEST;
6508
#else
6509
2.18k
    key->heap = heap;
6510
2.18k
#endif
6511
6512
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6513
    #ifdef WOLF_CRYPTO_CB
6514
    /* prefer crypto callback */
6515
    if (key->devId != INVALID_DEVID)
6516
    #endif
6517
    {
6518
        /* handle as async */
6519
        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
6520
                                                        key->heap, devId);
6521
    }
6522
    if (ret != 0)
6523
        return ret;
6524
#endif
6525
6526
#if defined(WOLFSSL_DSP)
6527
    key->handle = -1;
6528
#endif
6529
6530
#ifdef WOLFSSL_SE050
6531
    key->keyId = 0;
6532
    key->keyIdSet = 0;
6533
#endif
6534
6535
#ifdef WOLFSSL_CHECK_MEM_ZERO
6536
    mp_memzero_add("ECC k", key->k);
6537
#ifdef WOLFSSL_ECC_BLIND_K
6538
    mp_memzero_add("ECC kb", key->kb);
6539
    mp_memzero_add("ECC ku", key->ku);
6540
#endif
6541
#endif
6542
6543
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6544
    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
6545
6546
    if (wc_InitXsecure(&(key->xSec))) {
6547
        WOLFSSL_MSG("Can't initialize Xsecure");
6548
        return WC_HW_E;
6549
    }
6550
#endif
6551
6552
2.18k
    return ret;
6553
2.18k
}
6554
6555
WOLFSSL_ABI
6556
int wc_ecc_init(ecc_key* key)
6557
0
{
6558
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
6559
    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
6560
#else
6561
0
    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
6562
0
#endif
6563
0
}
6564
6565
#ifdef WOLF_PRIVATE_KEY_ID
6566
int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
6567
                   int devId)
6568
{
6569
    int ret = 0;
6570
#ifdef WOLFSSL_SE050
6571
    /* SE050 TLS users store a word32 at id, need to read it back */
6572
    word32 keyId = 0;
6573
#endif
6574
6575
    if (key == NULL)
6576
        ret = BAD_FUNC_ARG;
6577
    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
6578
        ret = BUFFER_E;
6579
    if (ret == 0)
6580
        ret = wc_ecc_init_ex(key, heap, devId);
6581
    if (ret == 0 && id != NULL && len != 0) {
6582
        XMEMCPY(key->id, id, (size_t)len);
6583
        key->idLen = len;
6584
    #ifdef WOLFSSL_SE050
6585
        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
6586
        if (len == (int)sizeof(word32)) {
6587
            keyId = readUnalignedWord32(key->id);
6588
            ret = wc_ecc_use_key_id(key, keyId, 0);
6589
        }
6590
    #endif
6591
    }
6592
6593
    return ret;
6594
}
6595
6596
int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
6597
{
6598
    int ret = 0;
6599
    int labelLen = 0;
6600
6601
    if (key == NULL || label == NULL)
6602
        ret = BAD_FUNC_ARG;
6603
    if (ret == 0) {
6604
        labelLen = (int)XSTRLEN(label);
6605
        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
6606
            ret = BUFFER_E;
6607
    }
6608
    if (ret == 0)
6609
        ret = wc_ecc_init_ex(key, heap, devId);
6610
    if (ret == 0) {
6611
        XMEMCPY(key->label, label, (size_t)labelLen);
6612
        key->labelLen = labelLen;
6613
    }
6614
6615
    return ret;
6616
}
6617
#endif /* WOLF_PRIVATE_KEY_ID */
6618
6619
int wc_ecc_set_flags(ecc_key* key, word32 flags)
6620
0
{
6621
0
    if (key == NULL) {
6622
0
        return BAD_FUNC_ARG;
6623
0
    }
6624
0
    key->flags |= flags;
6625
0
    return 0;
6626
0
}
6627
6628
6629
static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
6630
0
{
6631
0
    int err = MP_OKAY;
6632
0
    int orderBits;
6633
0
    DECLARE_CURVE_SPECS(1);
6634
6635
0
    ALLOC_CURVE_SPECS(1, err);
6636
0
    if (err == MP_OKAY) {
6637
0
        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
6638
0
    }
6639
6640
0
    if (err != 0) {
6641
0
       FREE_CURVE_SPECS();
6642
0
       return err;
6643
0
    }
6644
0
    orderBits = mp_count_bits(curve->order);
6645
6646
0
    wc_ecc_curve_free(curve);
6647
0
    FREE_CURVE_SPECS();
6648
0
    return orderBits;
6649
0
}
6650
6651
#ifdef HAVE_ECC_SIGN
6652
6653
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
6654
    defined(WOLFSSL_MICROCHIP_TA100) || \
6655
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
6656
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
6657
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6658
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
6659
    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
6660
    ecc_key* key)
6661
{
6662
    int err;
6663
#ifdef PLUTON_CRYPTO_ECC
6664
    if (key->devId != INVALID_DEVID) /* use hardware */
6665
#endif
6666
    {
6667
    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
6668
        !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
6669
        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
6670
        word32 raw_sig_size = *outlen;
6671
        word32 msgLenInBytes = inlen;
6672
        CRYS_ECPKI_HASH_OpMode_t hash_mode;
6673
    #endif
6674
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6675
#ifdef WOLFSSL_SMALL_STACK
6676
        byte* K = NULL;
6677
        byte* incopy = NULL;
6678
#else
6679
        byte K[MAX_ECC_BYTES] = {0};
6680
        byte incopy[MAX_ECC_BYTES] = {0};
6681
#endif
6682
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6683
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6684
        word32 Ksize;
6685
#endif
6686
#endif
6687
        word32 keysize = (word32)key->dp->size;
6688
    #ifdef PLUTON_CRYPTO_ECC
6689
        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
6690
    #endif
6691
6692
    #ifndef WOLFSSL_KCAPI_ECC
6693
        /* Check args */
6694
        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
6695
            return ECC_BAD_ARG_E;
6696
        }
6697
    #endif
6698
6699
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
6700
         defined(WOLFSSL_MICROCHIP_TA100)
6701
#if defined(WOLFSSL_MICROCHIP_TA100)
6702
        if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
6703
            (void)inlen;
6704
            /* Sign: Result is 32-bytes of R then 32-bytes of S */
6705
            err = atmel_ecc_sign(key->slot, in, out);
6706
        }
6707
        else {
6708
            /* Sign: Result is raw R||S */
6709
            err = atmel_ecc_sign_ex(key->slot, microchip_curve_id_for_key(key),
6710
                in, inlen, out);
6711
        }
6712
#else
6713
        (void)inlen;
6714
        /* Sign: Result is 32-bytes of R then 32-bytes of S */
6715
        err = atmel_ecc_sign(key->slot, in, out);
6716
#endif
6717
6718
        if (err != 0) {
6719
           return err;
6720
        }
6721
    #elif defined(PLUTON_CRYPTO_ECC)
6722
        {
6723
            /* if the input is larger than curve order, we must truncate */
6724
            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
6725
               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
6726
            }
6727
6728
            /* perform ECC sign */
6729
            word32 raw_sig_size = *outlen;
6730
            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
6731
            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
6732
               return BAD_COND_E;
6733
            }
6734
        }
6735
    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
6736
        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
6737
        if (err != 0) {
6738
               return WC_HW_E;
6739
        }
6740
    #elif defined(WOLFSSL_CRYPTOCELL)
6741
        /* truncate if hash is longer than key size */
6742
        if (msgLenInBytes > keysize) {
6743
            msgLenInBytes = keysize;
6744
        }
6745
        hash_mode = cc310_hashModeECC(msgLenInBytes);
6746
        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
6747
            (void)cc310_hashModeECC(keysize);
6748
            /* Ignoring returned value */
6749
            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
6750
6751
        }
6752
6753
        /* create signature from an input buffer using a private key*/
6754
        err = CRYS_ECDSA_Sign(&wc_rndState,
6755
                               wc_rndGenVectFunc,
6756
                               &sigCtxTemp,
6757
                               &key->ctx.privKey,
6758
                               hash_mode,
6759
                               (byte*)in,
6760
                               msgLenInBytes,
6761
                               out,
6762
                               (uint32_t*)&raw_sig_size);
6763
6764
        if (err != SA_SILIB_RET_OK){
6765
            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
6766
            return err;
6767
        }
6768
    #elif defined(WOLFSSL_KCAPI_ECC)
6769
        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
6770
        if (err != MP_OKAY) {
6771
            return err;
6772
        }
6773
        (void)rng;
6774
    #elif defined(WOLFSSL_SE050)
6775
        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
6776
        if (err != MP_OKAY) {
6777
            return err;
6778
        }
6779
        (void)rng;
6780
    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
6781
6782
#ifdef WOLFSSL_SMALL_STACK
6783
        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6784
        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
6785
        if (K == NULL || incopy == NULL) {
6786
            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6787
            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6788
            return MEMORY_E;
6789
        }
6790
#else
6791
        if (inlen > sizeof(incopy))
6792
            return ECC_BAD_ARG_E;
6793
#endif
6794
6795
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
6796
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
6797
        err = deterministic_sign_helper(in, inlen, key);
6798
        if (err)
6799
            return err;
6800
        Ksize = mp_unsigned_bin_size(key->sign_k);
6801
        if (Ksize > keysize) {
6802
            err = BUFFER_E;
6803
            goto error_out;
6804
        }
6805
        err = mp_to_unsigned_bin(key->sign_k, K);
6806
        if (err)
6807
            goto error_out;
6808
        mp_reverse(K, Ksize);
6809
#else
6810
        err = wc_RNG_GenerateBlock(rng, K, keysize);
6811
        if (err)
6812
            goto error_out;
6813
        /* Make sure that K is max. 521 bits */
6814
        if (keysize == 66)
6815
            K[65] &= 0x1;
6816
#endif
6817
        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
6818
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
6819
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
6820
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
6821
6822
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6823
6824
        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
6825
                                           xil_curve_type[key->dp->id],
6826
                                           XIL_CAST_U64(incopy), keysize,
6827
                                           XIL_CAST_U64(key->privKey),
6828
                                           XIL_CAST_U64(K),
6829
                                           XIL_CAST_U64(out));
6830
        if (err) {
6831
            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
6832
            err = WC_HW_E;
6833
        }
6834
6835
        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
6836
        mp_reverse(&out[0], keysize);
6837
        mp_reverse(&out[keysize], keysize);
6838
6839
error_out:
6840
        ForceZero(K, MAX_ECC_BYTES);
6841
        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
6842
        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
6843
        if (err) {
6844
            ForceZero(out, keysize * 2);
6845
            return err;
6846
        }
6847
    #endif /* HW-specific #if-#elif chain */
6848
6849
    #ifndef WOLFSSL_SE050
6850
        /* Load R and S, SE050 does this in port layer */
6851
        err = mp_read_unsigned_bin(r, &out[0], keysize);
6852
        if (err != MP_OKAY) {
6853
            return err;
6854
        }
6855
        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
6856
        if (err != MP_OKAY) {
6857
            return err;
6858
        }
6859
    #endif
6860
6861
        /* Check for zeros */
6862
        if (mp_iszero(r) || mp_iszero(s)) {
6863
            return MP_ZERO_E;
6864
        }
6865
    }
6866
#ifdef PLUTON_CRYPTO_ECC
6867
    else {
6868
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6869
    }
6870
#endif
6871
    (void)rng;
6872
6873
    return err;
6874
}
6875
#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
6876
6877
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
6878
static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
6879
    word32 *outlen, WC_RNG* rng, ecc_key* key)
6880
{
6881
    int err;
6882
    mp_int *r = NULL, *s = NULL;
6883
6884
    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
6885
                                                                rng == NULL) {
6886
        return ECC_BAD_ARG_E;
6887
    }
6888
6889
    err = wc_ecc_alloc_async(key);
6890
    if (err != 0) {
6891
        return err;
6892
    }
6893
    r = key->r;
6894
    s = key->s;
6895
6896
    switch (key->state) {
6897
        case ECC_STATE_NONE:
6898
        case ECC_STATE_SIGN_DO:
6899
            key->state = ECC_STATE_SIGN_DO;
6900
6901
            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
6902
                break;
6903
            }
6904
6905
            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
6906
            if (err < 0) {
6907
                break;
6908
            }
6909
6910
            FALL_THROUGH;
6911
6912
        case ECC_STATE_SIGN_ENCODE:
6913
            key->state = ECC_STATE_SIGN_ENCODE;
6914
6915
            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
6916
                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
6917
                    DECLARE_CURVE_SPECS(1);
6918
                    ALLOC_CURVE_SPECS(1, err);
6919
                    if (err != MP_OKAY) {
6920
                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
6921
                        break;
6922
                    }
6923
6924
                    /* get curve order */
6925
                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
6926
                #endif
6927
6928
                #ifdef HAVE_CAVIUM_V
6929
                    /* Nitrox requires r and s in sep buffer, so split it */
6930
                    NitroxEccRsSplit(key, &r->raw, &s->raw);
6931
                #endif
6932
                #ifndef WOLFSSL_ASYNC_CRYPT_SW
6933
                    /* only do this if not software, since it overwrites result */
6934
                    wc_bigint_to_mp(&r->raw, r);
6935
                    wc_bigint_to_mp(&s->raw, s);
6936
6937
                /* if using a curve with cofactor != 1 then reduce by mod order */
6938
                #ifdef HAVE_ECC_CDH
6939
                    /* if r is not less than order than reduce */
6940
                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
6941
                        err = mp_mod(r, curve->order, r);
6942
                    }
6943
                    wc_ecc_curve_free(curve);
6944
                    FREE_CURVE_SPECS();
6945
                #endif
6946
                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
6947
            }
6948
6949
            /* encoded with DSA header */
6950
            if (err == 0) {
6951
                err = StoreECC_DSA_Sig(out, outlen, r, s);
6952
            }
6953
6954
            /* done with R/S */
6955
            mp_clear(r);
6956
            mp_clear(s);
6957
            break;
6958
6959
        default:
6960
            err = BAD_STATE_E;
6961
            break;
6962
    }
6963
6964
    /* if async pending then return and skip done cleanup below */
6965
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
6966
        key->state++;
6967
        return err;
6968
    }
6969
6970
    /* cleanup */
6971
    wc_ecc_free_async(key);
6972
    key->state = ECC_STATE_NONE;
6973
6974
    return err;
6975
}
6976
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
6977
6978
/**
6979
 Sign a message digest
6980
 in        The message digest to sign
6981
 inlen     The length of the digest
6982
 out       [out] The destination for the signature
6983
 outlen    [in/out] The max size and resulting size of the signature
6984
 key       A private ECC key
6985
 return    MP_OKAY if successful
6986
 */
6987
WOLFSSL_ABI
6988
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
6989
                     WC_RNG* rng, ecc_key* key)
6990
0
{
6991
0
    int err;
6992
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
6993
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6994
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
6995
0
#endif
6996
#ifdef NO_ASN
6997
    word32 keySz;
6998
#endif
6999
7000
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7001
0
        return WC_KEY_SIZE_E;
7002
0
    }
7003
7004
0
    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
7005
0
        return ECC_BAD_ARG_E;
7006
0
    }
7007
0
    if ((inlen > WC_MAX_DIGEST_SIZE) ||
7008
0
        (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7009
0
    {
7010
0
        return BAD_LENGTH_E;
7011
0
    }
7012
7013
#ifdef WOLF_CRYPTO_CB
7014
    #ifndef WOLF_CRYPTO_CB_FIND
7015
    if (key->devId != INVALID_DEVID)
7016
    #endif
7017
    {
7018
        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
7019
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
7020
            return err;
7021
        /* fall-through when unavailable */
7022
    }
7023
#endif
7024
7025
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
7026
    (void)rng;
7027
    (void)inlen;
7028
    (void)s;
7029
    (void)r;
7030
    (void)err;
7031
    return NO_VALID_DEVID;
7032
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
7033
0
    if (rng == NULL) {
7034
0
        WOLFSSL_MSG("ECC sign RNG missing");
7035
0
        return ECC_BAD_ARG_E;
7036
0
    }
7037
7038
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7039
    /* handle async cases */
7040
    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
7041
#else
7042
7043
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7044
    #ifdef MP_INT_SIZE_CHECK_NULL
7045
    if (r == NULL)
7046
        return MEMORY_E;
7047
    #endif
7048
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7049
    #ifdef MP_INT_SIZE_CHECK_NULL
7050
    if (s == NULL) {
7051
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7052
        return MEMORY_E;
7053
    }
7054
    #endif
7055
7056
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7057
0
    if (err != 0) {
7058
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7059
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7060
0
        return err;
7061
0
    }
7062
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7063
0
    if (err != 0) {
7064
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7065
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7066
0
        return err;
7067
0
    }
7068
7069
/* hardware crypto */
7070
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID)
7071
    /* Route by key location: SE050-resident keys sign in hardware, software
7072
     * keys (keyIdSet == 0) sign with the wolfCrypt software implementation. */
7073
    if (key->keyIdSet)
7074
        err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7075
    else
7076
        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7077
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
7078
    defined(WOLFSSL_MICROCHIP_TA100) || \
7079
    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
7080
    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
7081
    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
7082
    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
7083
#else
7084
0
    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7085
0
#endif
7086
0
    if (err < 0) {
7087
0
        mp_clear(r);
7088
0
        mp_clear(s);
7089
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7090
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7091
0
        return err;
7092
0
    }
7093
7094
0
#ifndef NO_ASN
7095
    /* encoded with DSA header */
7096
0
    err = StoreECC_DSA_Sig(out, outlen, r, s);
7097
#else
7098
    /* No support for DSA ASN.1 header.
7099
     * Signature will be r+s directly. */
7100
    keySz = 0;
7101
    if (key->dp != NULL) {
7102
        keySz = (word32)key->dp->size;
7103
    }
7104
    if (keySz <= 0) {
7105
        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
7106
        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
7107
    }
7108
    *outlen = keySz * 2;
7109
7110
    /* Export signature into r,s */
7111
    mp_to_unsigned_bin_len(r, out, keySz);
7112
    mp_to_unsigned_bin_len(s, out + keySz, keySz);
7113
#endif /* !NO_ASN */
7114
7115
    /* cleanup */
7116
0
    mp_clear(r);
7117
0
    mp_clear(s);
7118
7119
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
7120
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
7121
0
#endif /* WOLFSSL_ASYNC_CRYPT */
7122
0
    return err;
7123
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
7124
0
}
7125
7126
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7127
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7128
/* returns MP_OKAY on success */
7129
static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
7130
{
7131
    int err = MP_OKAY;
7132
    DECLARE_CURVE_SPECS(1);
7133
    ALLOC_CURVE_SPECS(1, err);
7134
7135
    /* get curve order */
7136
    if (err == MP_OKAY) {
7137
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7138
    }
7139
7140
    if (err == MP_OKAY) {
7141
    #ifndef WOLFSSL_NO_MALLOC
7142
        /* if key->sign_k is NULL then create a buffer for the mp_int
7143
         * if not NULL then assume the user correctly set deterministic flag and
7144
         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
7145
        if (key->sign_k == NULL) {
7146
            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
7147
                                                            DYNAMIC_TYPE_ECC);
7148
            if (key->sign_k != NULL) {
7149
                err = mp_init(key->sign_k);
7150
                if (err != MP_OKAY) {
7151
                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7152
                    key->sign_k = NULL;
7153
                }
7154
            }
7155
        }
7156
        if (key->sign_k != NULL) {
7157
            if (wc_ecc_gen_deterministic_k(in, inlen,
7158
                        key->hashType, ecc_get_k(key), key->sign_k,
7159
                        curve->order, key->heap) != 0) {
7160
                mp_free(key->sign_k);
7161
                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7162
                key->sign_k = NULL;
7163
                err = ECC_PRIV_KEY_E;
7164
            }
7165
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7166
            else {
7167
                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
7168
            }
7169
        #endif
7170
        }
7171
        else {
7172
            err = MEMORY_E;
7173
        }
7174
    #else
7175
        key->sign_k_set = 0;
7176
        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
7177
                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
7178
            err = ECC_PRIV_KEY_E;
7179
        }
7180
        else {
7181
            key->sign_k_set = 1;
7182
        }
7183
    #endif
7184
    }
7185
7186
    wc_ecc_curve_free(curve);
7187
    FREE_CURVE_SPECS();
7188
    return err;
7189
}
7190
#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
7191
          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
7192
7193
/* WOLFSSL_STM32_PKA routes HW ECDSA sign/verify through the STM32 PKA
7194
 * (HAL_PKA_ECDSASign / Verify). Works under both the CubeMX-HAL path
7195
 * and the bare-metal direct-register path (WOLFSSL_STM32_BARE) -- the
7196
 * bare-metal driver implements the same HAL_PKA_ECDSA* surface.
7197
 *
7198
 * The non-FIPS input-validation checks (length range, all-zero digest
7199
 * rejection) live inside the SW body of wc_ecc_sign_hash_ex below.
7200
 * Since the STM32_PKA branch returns early without reaching them,
7201
 * mirror those checks here so HW + SW paths share the same input
7202
 * contract. Without this, an all-zero digest reaches the PKA IP and
7203
 * succeeds at the HW layer -- the wolfcrypt_test ECC sweep then fails
7204
 * at the post-call assertion that expected ECC_BAD_ARG_E for a zero
7205
 * digest. */
7206
/* The STM32H563 "light" PKA can verify but not sign (per ST: H563
7207
 * verify-only, H573 full). WC_STM32_PKA_VERIFY_ONLY routes sign to the
7208
 * software path (the #elif branch below) while verify stays on the HW PKA. */
7209
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_VERIFY_ONLY)
7210
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7211
                     ecc_key* key, mp_int *r, mp_int *s)
7212
{
7213
#ifndef WC_ALLOW_ECC_ZERO_HASH
7214
    byte hashIsZero = 0;
7215
    word32 zIdx;
7216
#endif
7217
7218
    if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7219
        return ECC_BAD_ARG_E;
7220
    }
7221
    if ((inlen > WC_MAX_DIGEST_SIZE) || (inlen < WC_MIN_DIGEST_SIZE)) {
7222
        return BAD_LENGTH_E;
7223
    }
7224
#ifndef WC_ALLOW_ECC_ZERO_HASH
7225
    /* reject all 0's hash */
7226
    for (zIdx = 0; zIdx < inlen; zIdx++)
7227
        hashIsZero |= in[zIdx];
7228
    if (hashIsZero == 0)
7229
        return ECC_BAD_ARG_E;
7230
#endif
7231
7232
    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
7233
}
7234
7235
#if defined(WOLFSSL_DHUK) && defined(WOLFSSL_STM32_BARE) && \
7236
    defined(WC_STM32_HAS_DHUK)
7237
/* Import a hardware-wrapped ECC private scalar + its derivation seed onto the
7238
 * ecc_key for the DHUK crypto-callback sign path. The scalar is AES-encrypted
7239
 * (offline or on-chip) with the device key that the SAES derives from the seed;
7240
 * at sign time it is decrypted into a short-lived buffer. The devId is NOT set
7241
 * here -- enable the device by setting devId at init
7242
 * (wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID)). See ecc.h for the contract. */
7243
int wc_ecc_import_wrapped_private(ecc_key* key, const byte* seed, word32 seedSz,
7244
                                  const byte* wrapped, word32 wrappedLen,
7245
                                  word32 plainLen)
7246
{
7247
    if (key == NULL || seed == NULL || wrapped == NULL) {
7248
        return BAD_FUNC_ARG;
7249
    }
7250
    /* Seed is the 256-bit DHUK derivation secret. */
7251
    if (seedSz != sizeof(key->dhuk_seed)) {
7252
        return BAD_FUNC_ARG;
7253
    }
7254
    /* Wrapped scalar blob must be a non-zero multiple of one AES block. */
7255
    if (wrappedLen == 0u || (wrappedLen % 16u) != 0u) {
7256
        return BAD_FUNC_ARG;
7257
    }
7258
    if (wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
7259
        return BAD_FUNC_ARG;
7260
    }
7261
    /* Plain length must fit inside the wrapped blob and be non-zero. */
7262
    if (plainLen == 0u || plainLen > wrappedLen) {
7263
        return BAD_FUNC_ARG;
7264
    }
7265
    /* Wrapped blob must be no larger than the plaintext padded up to a full
7266
     * AES block; a larger blob is malformed and would overrun the fixed-size
7267
     * unwrap buffer used during signing. */
7268
    if (wrappedLen > ((plainLen + 15u) & ~15u)) {
7269
        return BAD_FUNC_ARG;
7270
    }
7271
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
7272
    XMEMCPY(key->dhuk_seed, seed, seedSz);
7273
    key->dhuk_wrapped_priv_len = wrappedLen;
7274
    key->dhuk_plain_priv_len   = plainLen;
7275
    key->dhuk_seed_sz          = seedSz;
7276
#ifdef WOLFSSL_STM32_CCB
7277
    /* This is a DHUK seed-wrapped (non-CCB) scalar; clear any CCB blob
7278
     * routing left from a prior import so signing uses the DHUK path. */
7279
    key->dhuk_is_ccb = 0;
7280
#endif
7281
    return 0;
7282
}
7283
#endif /* WOLFSSL_DHUK && WOLFSSL_STM32_BARE && WC_STM32_HAS_DHUK */
7284
7285
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
7286
      !defined(WOLFSSL_MICROCHIP_TA100) && \
7287
      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
7288
#ifndef WOLFSSL_SP_MATH
7289
static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
7290
                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
7291
                            mp_int* s)
7292
0
{
7293
0
    int err = MP_OKAY;
7294
0
    int loop_check = 0;
7295
7296
0
    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
7297
7298
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
7299
0
        return WC_KEY_SIZE_E;
7300
0
    }
7301
7302
0
    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7303
#ifdef MP_INT_SIZE_CHECK_NULL
7304
    if (b == NULL)
7305
        err = MEMORY_E;
7306
#endif
7307
7308
0
    if (err == MP_OKAY) {
7309
0
        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
7310
0
    }
7311
7312
#ifdef WOLFSSL_CUSTOM_CURVES
7313
    /* if custom curve, apply params to pubkey */
7314
    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
7315
        err = wc_ecc_set_custom_curve(pubkey, key->dp);
7316
    }
7317
#endif
7318
7319
0
    if (err == MP_OKAY) {
7320
        /* Generate blinding value - non-zero value. */
7321
0
        do {
7322
0
            if (++loop_check > 64) {
7323
0
                 err = RNG_FAILURE_E;
7324
0
                 break;
7325
0
            }
7326
7327
0
            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
7328
0
        }
7329
0
        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
7330
0
        loop_check = 0;
7331
0
    }
7332
#ifdef WOLFSSL_CHECK_MEM_ZERO
7333
    if (err == MP_OKAY) {
7334
        mp_memzero_add("ecc_sign_hash_sw b", b);
7335
    }
7336
#endif
7337
7338
0
    for (; err == MP_OKAY;) {
7339
0
        if (++loop_check > 64) {
7340
0
             err = RNG_FAILURE_E;
7341
0
             break;
7342
0
        }
7343
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7344
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7345
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7346
#ifndef WOLFSSL_NO_MALLOC
7347
        if (key->sign_k != NULL)
7348
#else
7349
        if (key->sign_k_set)
7350
#endif
7351
        {
7352
            if (loop_check > 1) {
7353
               err = RNG_FAILURE_E;
7354
               break;
7355
            }
7356
7357
            /* use provided sign_k */
7358
            err = mp_copy(key->sign_k, pubkey->k);
7359
            if (err != MP_OKAY) break;
7360
7361
            /* free sign_k, so only used once */
7362
            mp_forcezero(key->sign_k);
7363
#ifndef WOLFSSL_NO_MALLOC
7364
            mp_free(key->sign_k);
7365
            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7366
            key->sign_k = NULL;
7367
#else
7368
            key->sign_k_set = 0;
7369
#endif
7370
    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
7371
            loop_check = 64;
7372
    #endif
7373
    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7374
        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7375
            if (key->deterministic == 1) {
7376
                /* sign_k generated earlier in function for SP calls.
7377
                 * Only go through the loop once and fail if error */
7378
                loop_check = 64;
7379
            }
7380
    #endif
7381
7382
            /* compute public key based on provided "k" */
7383
            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
7384
        }
7385
        else
7386
#endif
7387
0
        {
7388
0
            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
7389
0
                    WC_ECC_FLAG_NONE);
7390
0
        }
7391
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7392
        if (err == MP_OKAY) {
7393
            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
7394
        }
7395
    #endif
7396
    #ifdef WOLFSSL_ASYNC_CRYPT
7397
        /* for async do blocking wait here */
7398
        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
7399
    #endif
7400
0
        if (err != MP_OKAY) break;
7401
7402
        /* find r = x1 mod n */
7403
0
        err = mp_mod(pubkey->pubkey.x, curve->order, r);
7404
0
        if (err != MP_OKAY) break;
7405
7406
0
        if (mp_iszero(r) == MP_NO) {
7407
0
            mp_int* kp = ecc_get_k(pubkey);
7408
0
            mp_int* ep = kp;
7409
0
            mp_int* x  = ecc_get_k(key);
7410
7411
            /* Blind after getting. */
7412
0
            ecc_blind_k(key, b);
7413
7414
            /* find s = (e + xr)/k
7415
                      = b.(e/k.b + x.r/k.b) */
7416
7417
            /* k' = k.b */
7418
0
            err = mp_mulmod(kp, b, curve->order, kp);
7419
0
            if (err != MP_OKAY) break;
7420
7421
            /* k' = 1/k.b
7422
                  = 1/k' */
7423
0
            err = mp_invmod(kp, curve->order, kp);
7424
0
            if (err != MP_OKAY) break;
7425
7426
            /* s = x.r */
7427
0
            err = mp_mulmod(x, r, curve->order, s);
7428
0
            if (err != MP_OKAY) break;
7429
7430
            /* s = x.r/k.b
7431
                 = k'.s */
7432
0
            err = mp_mulmod(kp, s, curve->order, s);
7433
0
            if (err != MP_OKAY) break;
7434
7435
            /* e' = e/k.b
7436
                  = e.k' */
7437
0
            err = mp_mulmod(kp, e, curve->order, ep);
7438
0
            if (err != MP_OKAY) break;
7439
7440
            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
7441
                 = e' + s */
7442
0
            err = mp_addmod_ct(ep, s, curve->order, s);
7443
0
            if (err != MP_OKAY) break;
7444
7445
            /* s = b.(e + x.r)/k.b = (e + x.r)/k
7446
                 = b.s */
7447
0
            err = mp_mulmod(s, b, curve->order, s);
7448
0
            if (err != MP_OKAY) break;
7449
7450
0
            if (mp_iszero(s) == MP_NO) {
7451
                /* sign successful */
7452
0
                break;
7453
0
            }
7454
0
         }
7455
0
     #ifndef ALT_ECC_SIZE
7456
0
         mp_clear(pubkey->pubkey.x);
7457
0
         mp_clear(pubkey->pubkey.y);
7458
0
         mp_clear(pubkey->pubkey.z);
7459
0
     #endif
7460
0
         mp_forcezero(pubkey->k);
7461
7462
0
         err = WC_CHECK_FOR_INTR_SIGNALS();
7463
0
         if (err != 0)
7464
0
             break;
7465
0
         WC_RELAX_LONG_LOOP();
7466
0
    }
7467
0
    mp_forcezero(b);
7468
0
    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
7469
#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
7470
    mp_memzero_check(b);
7471
#endif
7472
7473
0
    return err;
7474
0
}
7475
#endif
7476
7477
#ifdef WOLFSSL_HAVE_SP_ECC
7478
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7479
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7480
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7481
/* SP only resets the logical length of k, leaving its digits in the backing
7482
 * store. Clear it the way the software path does. */
7483
static void ecc_sign_k_forcezero(ecc_key* key)
7484
{
7485
#ifndef WOLFSSL_NO_MALLOC
7486
    if (key->sign_k != NULL) {
7487
        mp_forcezero(key->sign_k);
7488
        mp_free(key->sign_k);
7489
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
7490
        key->sign_k = NULL;
7491
    }
7492
#else
7493
    if (key->sign_k_set) {
7494
        mp_forcezero(key->sign_k);
7495
        key->sign_k_set = 0;
7496
    }
7497
#endif
7498
}
7499
#endif
7500
7501
static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
7502
    ecc_key* key, mp_int *r, mp_int *s)
7503
{
7504
    if (key->idx != ECC_CUSTOM_IDX) {
7505
    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
7506
        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7507
           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7508
        mp_int* sign_k = key->sign_k;
7509
    #else
7510
        mp_int* sign_k = NULL;
7511
    #endif
7512
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
7513
        /* perform blocking call to non-blocking function */
7514
        ecc_nb_ctx_t nb_ctx;
7515
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
7516
    #endif
7517
    #ifndef WOLFSSL_SP_NO_256
7518
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
7519
        #ifdef WC_ECC_NONBLOCK
7520
            #ifdef WC_ECC_NONBLOCK_ONLY
7521
            int err;
7522
            #endif
7523
            if (key->nb_ctx) {
7524
                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7525
                    ecc_get_k(key), r, s, sign_k, key->heap);
7526
            }
7527
            #ifdef WC_ECC_NONBLOCK_ONLY
7528
            do { /* perform blocking call to non-blocking function */
7529
                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7530
                    ecc_get_k(key), r, s, sign_k, key->heap);
7531
            } while (err == FP_WOULDBLOCK);
7532
            return err;
7533
            #endif
7534
        #endif /* WC_ECC_NONBLOCK */
7535
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7536
            {
7537
                int ret;
7538
                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
7539
                                      sign_k, key->heap);
7540
                return ret;
7541
            }
7542
        #endif
7543
        }
7544
    #endif
7545
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
7546
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
7547
            int ret;
7548
            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
7549
                                      sign_k, key->heap);
7550
            return ret;
7551
        }
7552
    #endif
7553
    #ifdef WOLFSSL_SP_384
7554
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
7555
        #ifdef WC_ECC_NONBLOCK
7556
            #ifdef WC_ECC_NONBLOCK_ONLY
7557
            int err;
7558
            #endif
7559
            if (key->nb_ctx) {
7560
                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7561
                    ecc_get_k(key), r, s, sign_k, key->heap);
7562
            }
7563
            #ifdef WC_ECC_NONBLOCK_ONLY
7564
            do { /* perform blocking call to non-blocking function */
7565
                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7566
                    ecc_get_k(key), r, s, sign_k, key->heap);
7567
            } while (err == FP_WOULDBLOCK);
7568
            return err;
7569
            #endif
7570
        #endif /* WC_ECC_NONBLOCK */
7571
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7572
            {
7573
                int ret;
7574
                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
7575
                                      sign_k, key->heap);
7576
                return ret;
7577
            }
7578
        #endif
7579
        }
7580
    #endif
7581
    #ifdef WOLFSSL_SP_521
7582
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
7583
        #ifdef WC_ECC_NONBLOCK
7584
            #ifdef WC_ECC_NONBLOCK_ONLY
7585
            int err;
7586
            #endif
7587
            if (key->nb_ctx) {
7588
                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
7589
                    ecc_get_k(key), r, s, sign_k, key->heap);
7590
            }
7591
            #ifdef WC_ECC_NONBLOCK_ONLY
7592
            do { /* perform blocking call to non-blocking function */
7593
                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
7594
                    ecc_get_k(key), r, s, sign_k, key->heap);
7595
            } while (err == FP_WOULDBLOCK);
7596
            return err;
7597
            #endif
7598
        #endif /* WC_ECC_NONBLOCK */
7599
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
7600
            {
7601
                int ret;
7602
                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
7603
                                      sign_k, key->heap);
7604
                return ret;
7605
            }
7606
        #endif
7607
        }
7608
    #endif
7609
        (void)sign_k;
7610
    }
7611
7612
    /* SP doesn't support curve. */
7613
    return WC_KEY_SIZE_E;
7614
}
7615
#endif
7616
7617
/**
7618
  Sign a message digest
7619
  in        The message digest to sign
7620
  inlen     The length of the digest
7621
  key       A private ECC key
7622
  r         [out] The destination for r component of the signature
7623
  s         [out] The destination for s component of the signature
7624
  return    MP_OKAY if successful
7625
*/
7626
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
7627
                     ecc_key* key, mp_int *r, mp_int *s)
7628
0
{
7629
0
   int    err = 0;
7630
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
7631
0
   byte hashIsZero = 0;
7632
0
   word32 zIdx;
7633
0
#endif
7634
0
#if !defined(WOLFSSL_SP_MATH)
7635
0
   mp_int* e;
7636
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
7637
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
7638
0
#endif
7639
7640
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7641
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7642
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
7643
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7644
    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
7645
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
7646
#else
7647
0
   DECLARE_CURVE_SPECS(1);
7648
0
#endif
7649
0
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
7650
0
       return WC_KEY_SIZE_E;
7651
0
   }
7652
0
#endif /* !WOLFSSL_SP_MATH */
7653
7654
0
   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
7655
0
       return ECC_BAD_ARG_E;
7656
0
   }
7657
0
   if ((inlen > WC_MAX_DIGEST_SIZE) ||
7658
0
       (inlen < WC_MIN_DIGEST_SIZE_FOR_SIGN))
7659
0
   {
7660
0
       return BAD_LENGTH_E;
7661
0
   }
7662
7663
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
7664
   /* reject all 0's hash */
7665
0
   for (zIdx = 0; zIdx < inlen; zIdx++)
7666
0
       hashIsZero |= in[zIdx];
7667
0
   if (hashIsZero == 0)
7668
0
       return ECC_BAD_ARG_E;
7669
0
#endif
7670
7671
   /* is this a private key? */
7672
0
   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
7673
0
      return ECC_BAD_ARG_E;
7674
0
   }
7675
7676
   /* is the IDX valid ?  */
7677
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
7678
0
      return ECC_BAD_ARG_E;
7679
0
   }
7680
7681
#if defined(WOLFSSL_SP_MATH)
7682
    if (key->idx == ECC_CUSTOM_IDX || (1
7683
    #ifndef WOLFSSL_SP_NO_256
7684
         && ecc_sets[key->idx].id != ECC_SECP256R1
7685
    #endif
7686
    #ifdef WOLFSSL_SP_SM2
7687
         && ecc_sets[key->idx].id != ECC_SM2P256V1
7688
    #endif
7689
    #ifdef WOLFSSL_SP_384
7690
         && ecc_sets[key->idx].id != ECC_SECP384R1
7691
    #endif
7692
    #ifdef WOLFSSL_SP_521
7693
         && ecc_sets[key->idx].id != ECC_SECP521R1
7694
    #endif
7695
        )) {
7696
        return WC_KEY_SIZE_E;
7697
    }
7698
#endif
7699
7700
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7701
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7702
    /* generate deterministic 'k' value to be used either with SP or normal */
7703
    if (key->deterministic == 1) {
7704
        if (deterministic_sign_helper(in, inlen, key)) {
7705
            WOLFSSL_MSG("Error generating deterministic k to sign");
7706
            return ECC_PRIV_KEY_E;
7707
        }
7708
    }
7709
#endif
7710
7711
7712
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7713
    defined(WOLFSSL_ASYNC_CRYPT_SW)
7714
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7715
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
7716
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
7717
            sw->eccSign.in = in;
7718
            sw->eccSign.inSz = inlen;
7719
            sw->eccSign.rng = rng;
7720
            sw->eccSign.key = key;
7721
            sw->eccSign.r = r;
7722
            sw->eccSign.s = s;
7723
            return WC_PENDING_E;
7724
        }
7725
    }
7726
#endif
7727
7728
#if defined(WOLFSSL_HAVE_SP_ECC)
7729
   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
7730
   /* WC_KEY_SIZE_E only means SP left this curve to the software path below,
7731
    * which needs k and clears it itself. Every other result consumed k. */
7732
   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
7733
   #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7734
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7735
       defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7736
       #ifdef WC_ECC_NONBLOCK
7737
       /* An incomplete operation still needs k. */
7738
       if (err != FP_WOULDBLOCK)
7739
       #endif
7740
       {
7741
           ecc_sign_k_forcezero(key);
7742
       }
7743
   #endif
7744
       return err;
7745
   }
7746
#else
7747
0
   (void)inlen;
7748
0
#endif
7749
7750
0
#if !defined(WOLFSSL_SP_MATH)
7751
7752
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
7753
   err = wc_ecc_alloc_mpint(key, &key->e);
7754
   if (err != 0) {
7755
      return err;
7756
   }
7757
   e = key->e;
7758
#else
7759
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
7760
#ifdef MP_INT_SIZE_CHECK_NULL
7761
   if (e_lcl == NULL) {
7762
      return MEMORY_E;
7763
   }
7764
#endif
7765
0
   e = e_lcl;
7766
0
#endif
7767
7768
   /* get the hash and load it as a bignum into 'e' */
7769
   /* init the bignums */
7770
0
   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
7771
0
      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7772
0
      return err;
7773
0
   }
7774
7775
   /* load curve info */
7776
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
7777
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7778
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7779
    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7780
    if (err == MP_OKAY)
7781
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7782
#else
7783
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
7784
      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
7785
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
7786
        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
7787
        if (err == MP_OKAY)
7788
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7789
    }
7790
    else
7791
    #endif
7792
0
    {
7793
0
        ALLOC_CURVE_SPECS(1, err);
7794
0
        if (err == MP_OKAY)
7795
0
            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
7796
0
    }
7797
0
#endif
7798
7799
   /* load digest into e */
7800
0
   if (err == MP_OKAY) {
7801
       /* we may need to truncate if hash is longer than key size */
7802
0
       word32 orderBits = (word32)mp_count_bits(curve->order);
7803
7804
       /* truncate down to byte size, may be all that's needed */
7805
0
       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
7806
0
           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
7807
0
       err = mp_read_unsigned_bin(e, in, inlen);
7808
7809
       /* may still need bit truncation too */
7810
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
7811
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
7812
0
   }
7813
7814
   /* make up a key and export the public copy */
7815
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
7816
   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
7817
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
7818
   #ifdef HAVE_CAVIUM_V
7819
       if (NitroxEccIsCurveSupported(key))
7820
   #endif
7821
       {
7822
           word32 keySz = key->dp->size;
7823
           mp_int* k;
7824
       #ifdef HAVE_CAVIUM_V
7825
           err = wc_ecc_alloc_mpint(key, &key->signK);
7826
           if (err != 0)
7827
              return err;
7828
           k = key->signK;
7829
       #else
7830
           mp_int k_lcl;
7831
           k = &k_lcl;
7832
       #endif
7833
7834
           err = mp_init(k);
7835
7836
            /* make sure r and s are allocated */
7837
       #ifdef HAVE_CAVIUM_V
7838
           /* Nitrox V needs single buffer for R and S */
7839
           if (err == MP_OKAY)
7840
               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
7841
           /* Nitrox V only needs Prime and Order */
7842
           if (err == MP_OKAY)
7843
               err = wc_ecc_curve_load(key->dp, &curve,
7844
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
7845
       #else
7846
           if (err == MP_OKAY)
7847
               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
7848
           if (err == MP_OKAY)
7849
               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
7850
       #endif
7851
           if (err == MP_OKAY)
7852
               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
7853
7854
           /* load e and k */
7855
           if (err == MP_OKAY)
7856
               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
7857
           if (err == MP_OKAY)
7858
               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
7859
                  keySz);
7860
           if (err == MP_OKAY)
7861
               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
7862
           if (err == MP_OKAY)
7863
               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
7864
7865
       #ifdef HAVE_CAVIUM_V
7866
           if (err == MP_OKAY)
7867
               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
7868
                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
7869
                  &curve->order->raw);
7870
       #else
7871
           if (err == MP_OKAY)
7872
               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
7873
                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
7874
                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
7875
                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
7876
       #endif
7877
7878
       #ifndef HAVE_CAVIUM_V
7879
           mp_clear(e);
7880
           mp_forcezero(k);
7881
       #endif
7882
           wc_ecc_curve_free(curve);
7883
           FREE_CURVE_SPECS();
7884
7885
           return err;
7886
       }
7887
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
7888
   }
7889
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
7890
7891
0
   if (err == MP_OKAY) {
7892
0
       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
7893
7894
0
       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
7895
0
           err=MEMORY_E);
7896
0
       if (WC_VAR_OK(pubkey))
7897
0
       {
7898
       /* don't use async for key, since we don't support async return here */
7899
0
           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
7900
0
           if (err == MP_OKAY) {
7901
0
              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
7902
0
              wc_ecc_free(pubkey);
7903
0
              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
7904
0
           }
7905
0
       }
7906
0
   }
7907
7908
0
   mp_clear(e);
7909
0
   wc_ecc_curve_free(curve);
7910
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
7911
0
   FREE_CURVE_SPECS();
7912
0
#endif /* !WOLFSSL_SP_MATH */
7913
7914
0
   return err;
7915
0
}
7916
7917
#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
7918
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
7919
/* helper function to do HMAC operations
7920
 * returns 0 on success and updates "out" buffer
7921
 */
7922
static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
7923
        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
7924
        byte* out, enum wc_HashType hashType, void* heap)
7925
{
7926
    WC_DECLARE_VAR(hmac, Hmac, 1, heap);
7927
    int  ret, init;
7928
7929
    WC_ALLOC_VAR_EX(hmac, Hmac, 1, heap, DYNAMIC_TYPE_HMAC,
7930
                    return MEMORY_E);
7931
7932
    ret = init = wc_HmacInit(hmac, heap, INVALID_DEVID);
7933
    if (ret == 0)
7934
        ret = wc_HmacSetKey(hmac, (int)hashType, K, KSz);
7935
7936
    if (ret == 0)
7937
        ret = wc_HmacUpdate(hmac, V, VSz);
7938
7939
    if (ret == 0 && oct != NULL)
7940
        ret = wc_HmacUpdate(hmac, oct, 1);
7941
7942
    if (ret == 0)
7943
        ret = wc_HmacUpdate(hmac, x, xSz);
7944
7945
    if (ret == 0)
7946
        ret = wc_HmacUpdate(hmac, h1, h1Sz);
7947
7948
    if (ret == 0)
7949
        ret = wc_HmacFinal(hmac, out);
7950
7951
    if (init == 0)
7952
        wc_HmacFree(hmac);
7953
7954
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
7955
    return ret;
7956
}
7957
7958
7959
/* Generates a deterministic key based of the message using RFC6979
7960
 * @param  [in]   hash     Hash value to sign
7961
 * @param  [in]   hashSz   Size of 'hash' buffer passed in
7962
 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
7963
 *                WC_HASH_TYPE_SHA256
7964
 * @param  [in]   priv     Current ECC private key set
7965
 * @param  [out]  k        An initialized mp_int to set the k value generated in
7966
 * @param  [in]   order    ECC order parameter to use with generation
7967
 * @return  0 on success.
7968
 */
7969
int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
7970
        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
7971
        void* heap)
7972
{
7973
    int ret = 0;
7974
#ifndef WOLFSSL_SMALL_STACK
7975
    byte h1[MAX_ECC_BYTES];
7976
    byte V[WC_MAX_DIGEST_SIZE];
7977
    byte K[WC_MAX_DIGEST_SIZE];
7978
    byte x[MAX_ECC_BYTES];
7979
    mp_int z1[1];
7980
#else
7981
    byte *h1 = NULL;
7982
    byte *V  = NULL;
7983
    byte *K  = NULL;
7984
    byte *x  = NULL;
7985
    mp_int *z1 = NULL;
7986
#endif
7987
    word32 xSz, VSz, KSz, h1len, qLen;
7988
    byte intOct;
7989
    int qbits = 0;
7990
7991
    if (hash == NULL || k == NULL || order == NULL) {
7992
        return BAD_FUNC_ARG;
7993
    }
7994
7995
    if (hashSz > WC_MAX_DIGEST_SIZE) {
7996
        WOLFSSL_MSG("hash size was too large!");
7997
        return BAD_FUNC_ARG;
7998
    }
7999
8000
    /* if none is provided then detect has type based on hash size */
8001
    if (hashType == WC_HASH_TYPE_NONE) {
8002
        if (hashSz == 64) {
8003
            hashType = WC_HASH_TYPE_SHA512;
8004
        }
8005
        else if (hashSz == 48) {
8006
            hashType = WC_HASH_TYPE_SHA384;
8007
        }
8008
        else if (hashSz == 32) {
8009
            hashType = WC_HASH_TYPE_SHA256;
8010
        }
8011
        else {
8012
            return BAD_FUNC_ARG;
8013
        }
8014
    }
8015
8016
    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
8017
        WOLFSSL_MSG("private key larger than max expected!");
8018
        return BAD_FUNC_ARG;
8019
    }
8020
8021
#ifdef WOLFSSL_SMALL_STACK
8022
    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
8023
    if (h1 == NULL) {
8024
        ret = MEMORY_E;
8025
    }
8026
8027
    if (ret == 0) {
8028
        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8029
        if (V == NULL)
8030
            ret = MEMORY_E;
8031
    }
8032
8033
    if (ret == 0) {
8034
        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8035
        if (K == NULL)
8036
            ret = MEMORY_E;
8037
    }
8038
8039
    if (ret == 0) {
8040
        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8041
        if (x == NULL)
8042
            ret = MEMORY_E;
8043
    }
8044
8045
    if (ret == 0) {
8046
        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
8047
        if (z1 == NULL)
8048
            ret = MEMORY_E;
8049
    }
8050
8051
    /* bail out if any error has been hit at this point */
8052
    if (ret != 0) {
8053
        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8054
        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8055
        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8056
        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8057
        return ret;
8058
    }
8059
#endif
8060
8061
    VSz = KSz = hashSz;
8062
    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
8063
8064
    /* 3.2 b. Set V = 0x01 0x01 ... */
8065
    XMEMSET(V, 0x01, VSz);
8066
8067
    /* 3.2 c. Set K = 0x00 0x00 ... */
8068
    XMEMSET(K, 0x00, KSz);
8069
8070
#ifdef WOLFSSL_CHECK_MEM_ZERO
8071
    wc_MemZero_Add("wc_ecc_gen_deterministic_k K", K, KSz);
8072
    wc_MemZero_Add("wc_ecc_gen_deterministic_k V", V, VSz);
8073
#endif
8074
8075
    if (ret == 0) {
8076
        ret = mp_init(z1); /* always init z1 and free z1 */
8077
    }
8078
    if (ret == 0) {
8079
        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
8080
    }
8081
    if (ret == 0) {
8082
    #ifdef WOLFSSL_CHECK_MEM_ZERO
8083
        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
8084
    #endif
8085
        qbits = mp_count_bits(order);
8086
        if (qbits < 0)
8087
            ret = MP_VAL;
8088
    }
8089
8090
    if (ret == 0) {
8091
         /* hash truncate if too long */
8092
        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
8093
            /* calculate truncated hash size using bits rounded up byte */
8094
            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
8095
        }
8096
        ret = mp_read_unsigned_bin(z1, hash, hashSz);
8097
    }
8098
8099
    /* bits2octets on h1 */
8100
    if (ret == 0) {
8101
        XMEMSET(h1, 0, MAX_ECC_BYTES);
8102
8103
    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8104
        /* mod reduce by order using conditional subtract
8105
         * RFC6979 lists a variant that uses the hash directly instead of
8106
         * doing bits2octets(H(m)), when variant macro is used avoid this
8107
         * bits2octets operation */
8108
        if (mp_cmp(z1, order) == MP_GT) {
8109
            int z1Sz;
8110
8111
            mp_sub(z1, order, z1);
8112
            z1Sz = mp_unsigned_bin_size(z1);
8113
            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
8114
                ret = BUFFER_E;
8115
            }
8116
            else {
8117
                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8118
            }
8119
        }
8120
        else
8121
    #endif
8122
        {
8123
            /* use original hash and keep leading 0's */
8124
            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
8125
        }
8126
    }
8127
    mp_free(z1);
8128
8129
    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
8130
    if (ret == 0) {
8131
        intOct = 0x00;
8132
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
8133
                hashType, heap);
8134
    }
8135
8136
    /* 3.2 step e. V = HMAC_K(V) */
8137
    if (ret == 0) {
8138
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8139
                heap);
8140
    }
8141
8142
8143
    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
8144
    if (ret == 0) {
8145
        intOct = 0x01;
8146
        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
8147
                heap);
8148
    }
8149
8150
    /* 3.2 step g. V = HMAC_K(V) */
8151
    if (ret == 0) {
8152
        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
8153
                heap);
8154
    }
8155
8156
    /* 3.2 step h. loop through the next steps until a valid value is found */
8157
    if (ret == 0 ) {
8158
        int err;
8159
8160
        intOct = 0x00;
8161
        do {
8162
            xSz = 0; /* used as tLen */
8163
            err = 0; /* start as good until generated k is tested */
8164
8165
            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
8166
            while (xSz < qLen) {
8167
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8168
                        hashType, heap);
8169
                if (ret == 0) {
8170
                    int sz;
8171
8172
                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
8173
                    XMEMCPY(x + xSz, V, (size_t)sz);
8174
                    xSz += (word32)sz;
8175
                }
8176
                else {
8177
                    break; /* error case */
8178
                }
8179
            }
8180
8181
            if (ret == 0) {
8182
                mp_clear(k); /* 3.2 step h.1 clear T */
8183
                ret = mp_read_unsigned_bin(k, x, xSz);
8184
            }
8185
8186
            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
8187
                /* handle odd case where shift of 'k' is needed with RFC 6979
8188
                 *  k = bits2int(T) in section 3.2 h.3 */
8189
                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
8190
            }
8191
8192
            /* 3.2 step h.3 the key should be smaller than the order of base
8193
             * point */
8194
            if (ret == 0) {
8195
                if (mp_cmp(k, order) != MP_LT) {
8196
                    err = MP_VAL;
8197
                } else if (mp_iszero(k) == MP_YES) {
8198
                    /* no 0 key's */
8199
                    err = MP_ZERO_E;
8200
                }
8201
            }
8202
8203
            /* 3.2 step h.3 if there was a problem with 'k' generated then try
8204
             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
8205
            if (ret == 0 && err != 0) {
8206
                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
8207
                    hashType, heap);
8208
                if (ret == 0) {
8209
                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
8210
                    hashType, heap);
8211
                }
8212
            }
8213
        } while (ret == 0 && err != 0);
8214
    }
8215
8216
    ForceZero(x, MAX_ECC_BYTES);
8217
    ForceZero(K, WC_MAX_DIGEST_SIZE);
8218
    ForceZero(V, WC_MAX_DIGEST_SIZE);
8219
#ifdef WOLFSSL_SMALL_STACK
8220
    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
8221
    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
8222
    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
8223
    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
8224
    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
8225
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
8226
    wc_MemZero_Check(x, MAX_ECC_BYTES);
8227
    wc_MemZero_Check(K, WC_MAX_DIGEST_SIZE);
8228
    wc_MemZero_Check(V, WC_MAX_DIGEST_SIZE);
8229
#endif
8230
8231
    return ret;
8232
}
8233
8234
8235
/* Sets the deterministic flag for 'k' generation with sign.
8236
 * returns 0 on success
8237
 */
8238
int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
8239
                                enum wc_HashType hashType)
8240
{
8241
    if (key == NULL) {
8242
        return BAD_FUNC_ARG;
8243
    }
8244
8245
    key->deterministic = flag ? 1 : 0;
8246
    key->hashType = hashType;
8247
    return 0;
8248
}
8249
8250
int wc_ecc_set_deterministic(ecc_key* key, byte flag)
8251
{
8252
    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
8253
}
8254
8255
#endif /* end sign_ex and deterministic sign */
8256
8257
8258
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
8259
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
8260
{
8261
    int ret = MP_OKAY;
8262
    DECLARE_CURVE_SPECS(1);
8263
8264
    if (k == NULL || klen == 0 || key == NULL) {
8265
        return BAD_FUNC_ARG;
8266
    }
8267
8268
    ALLOC_CURVE_SPECS(1, ret);
8269
    if (ret == MP_OKAY) {
8270
        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
8271
    }
8272
8273
    if (ret != 0) {
8274
        FREE_CURVE_SPECS();
8275
        return ret;
8276
    }
8277
8278
#ifndef WOLFSSL_NO_MALLOC
8279
    if (key->sign_k == NULL) {
8280
        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
8281
                                                            DYNAMIC_TYPE_ECC);
8282
        if (key->sign_k) {
8283
            ret = mp_init(key->sign_k);
8284
        }
8285
        else {
8286
            ret = MEMORY_E;
8287
        }
8288
    }
8289
#endif
8290
8291
    if (ret == 0) {
8292
        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
8293
    }
8294
    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
8295
        ret = MP_VAL;
8296
    }
8297
#ifdef WOLFSSL_NO_MALLOC
8298
    if (ret == 0) {
8299
        key->sign_k_set = 1;
8300
    }
8301
#endif
8302
8303
    wc_ecc_curve_free(curve);
8304
    FREE_CURVE_SPECS();
8305
    return ret;
8306
}
8307
#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
8308
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
8309
8310
/* Guard must match the ecc.h prototype and the ccb_ / dhuk_ ecc_key struct
8311
 * members (both WOLFSSL_DHUK && WOLFSSL_STM32_CCB) -- the implementation must
8312
 * not be broader than the members it dereferences. */
8313
#if defined(WOLFSSL_DHUK) && defined(WOLFSSL_STM32_CCB)
8314
/* Load a previously provisioned device-protected ECDSA blob (wrapped scalar +
8315
 * AES-GCM iv/tag) and its public key onto the ecc_key. Sets the curve so the
8316
 * sign path can derive the parameters, and marks the key for the device
8317
 * crypto-callback. The caller enables the device with
8318
 * wc_ecc_init_ex(&key, heap, WC_DHUK_DEVID). Generic name -- the wrapping is
8319
 * the STM32 CCB, but the surface is not CCB-specific. */
8320
int wc_ecc_import_wrapped_private_ex(ecc_key* key, int curve_id,
8321
                           const byte* wrapped, word32 wrappedLen,
8322
                           const byte* iv, word32 ivLen,
8323
                           const byte* tag, word32 tagLen,
8324
                           const byte* pub, word32 pubLen)
8325
{
8326
    int modSz;
8327
    int ret;
8328
8329
    if (key == NULL || wrapped == NULL || iv == NULL || tag == NULL ||
8330
        pub == NULL) {
8331
        return BAD_FUNC_ARG;
8332
    }
8333
    /* Fixed 16-byte AES-GCM iv/tag -- validate explicitly (no over-read). */
8334
    if (ivLen != sizeof(key->ccb_iv) || tagLen != sizeof(key->ccb_tag)) {
8335
        return BAD_FUNC_ARG;
8336
    }
8337
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8338
    if (modSz <= 0) {
8339
        return BAD_FUNC_ARG;
8340
    }
8341
    if (wrappedLen == 0u || wrappedLen > sizeof(key->dhuk_wrapped_priv)) {
8342
        return BAD_FUNC_ARG;
8343
    }
8344
    if (pubLen != (word32)(2 * modSz)) {
8345
        return BAD_FUNC_ARG;
8346
    }
8347
    /* Import public key (qx||qy) + set the curve (key->dp). */
8348
    ret = wc_ecc_import_unsigned(key, pub, pub + modSz, NULL, curve_id);
8349
    if (ret != 0) {
8350
        return ret;
8351
    }
8352
    XMEMCPY(key->dhuk_wrapped_priv, wrapped, wrappedLen);
8353
    key->dhuk_wrapped_priv_len = wrappedLen;
8354
    XMEMCPY(key->ccb_iv,  iv,  sizeof(key->ccb_iv));
8355
    XMEMCPY(key->ccb_tag, tag, sizeof(key->ccb_tag));
8356
    key->dhuk_is_ccb = 1;
8357
    /* Clear any DHUK seed-import state left from a prior import; the CCB
8358
     * path keys off the wrapped blob + iv/tag, not the seed. */
8359
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8360
    key->dhuk_seed_sz        = 0;
8361
    key->dhuk_plain_priv_len = 0;
8362
    return 0;
8363
}
8364
8365
/* Crypto-callback keygen handler (WC_PK_TYPE_EC_KEYGEN). Provisions a fresh
8366
 * device-protected key: generate a scalar, have the CCB wrap it into a
8367
 * device-bound blob and derive its public key, and store both on the ecc_key
8368
 * (the scalar is zeroized and never leaves this call / the hardware). The
8369
 * scalar is generated in software with the supplied rng on a throwaway key with
8370
 * no devId (so no callback recursion). Returns CRYPTOCB_UNAVAILABLE for curves
8371
 * the CCB cannot wrap so keygen falls back to software. Not a public entry
8372
 * point -- reached via wc_ecc_make_key() on a WC_DHUK_DEVID key. */
8373
int wc_ecc_dev_make_key(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
8374
{
8375
#ifdef WOLFSSL_SMALL_STACK
8376
    ecc_key* tmp = NULL;             /* ecc_key is ~1-2KB -- heap it on the
8377
                                      * small-stack embedded targets this port
8378
                                      * runs on (repo convention). */
8379
#else
8380
    ecc_key  tmp[1];
8381
#endif
8382
#ifdef WOLFSSL_SMALL_STACK
8383
    /* d || pub || wrapped in one heap scratch buffer (~326 B) -- keep the
8384
     * fixed byte buffers off the stack too, like tmp above. */
8385
    byte*   scratch = NULL;
8386
    byte*   d;
8387
    byte*   pub;       /* qx || qy, contiguous */
8388
    byte*   wrapped;
8389
#else
8390
    byte    d[MAX_ECC_BYTES];
8391
    byte    pub[2 * MAX_ECC_BYTES];   /* qx || qy, contiguous */
8392
    byte    wrapped[96];
8393
#endif
8394
    byte    iv[16];
8395
    byte    tag[16];
8396
    word32  dLen;
8397
    word32  wrappedSz = 0;
8398
    int     modSz;
8399
    int     ret;
8400
    int     tmpInit = 0;
8401
8402
    (void)keysize;
8403
    if (rng == NULL || key == NULL) {
8404
        return BAD_FUNC_ARG;
8405
    }
8406
    /* wc_ecc_set_curve() ran before the callback, so key->dp is resolved even
8407
     * when curve_id came in as the default. */
8408
    if (curve_id <= 0 && key->dp != NULL) {
8409
        curve_id = key->dp->id;
8410
    }
8411
    modSz = wc_ecc_get_curve_size_from_id(curve_id);
8412
    if (modSz <= 0 || (word32)modSz > MAX_ECC_BYTES) {
8413
        return CRYPTOCB_UNAVAILABLE;   /* unsupported -> software keygen */
8414
    }
8415
8416
#ifdef WOLFSSL_SMALL_STACK
8417
    tmp = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
8418
    if (tmp == NULL) {
8419
        return MEMORY_E;
8420
    }
8421
    scratch = (byte*)XMALLOC((3 * MAX_ECC_BYTES) + 96, key->heap,
8422
                             DYNAMIC_TYPE_TMP_BUFFER);
8423
    if (scratch == NULL) {
8424
        XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8425
        return MEMORY_E;
8426
    }
8427
    d       = scratch;
8428
    pub     = scratch + MAX_ECC_BYTES;
8429
    wrapped = scratch + (3 * MAX_ECC_BYTES);
8430
#endif
8431
8432
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8433
    /* Register the stack private-key buffer before keygen/export so any exit
8434
     * before the ForceZero is checked. XMEMSET makes it defined. */
8435
    XMEMSET(d, 0, MAX_ECC_BYTES);
8436
    wc_MemZero_Add("wc_ecc_dev_make_key d", d, MAX_ECC_BYTES);
8437
#endif
8438
    ret = wc_ecc_init_ex(tmp, key->heap, INVALID_DEVID);
8439
    if (ret == 0) {
8440
        tmpInit = 1;
8441
        ret = wc_ecc_make_key_ex(rng, modSz, tmp, curve_id);
8442
    }
8443
    if (ret == 0) {
8444
        dLen = (word32)modSz;
8445
        ret = wc_ecc_export_private_only(tmp, d, &dLen);
8446
    }
8447
    if (ret == 0) {
8448
        ret = wc_Stm32_Ccb_EccMakeBlob(curve_id, d, dLen, iv, tag, wrapped,
8449
                                       &wrappedSz, pub, pub + modSz);
8450
        if (ret != 0) {
8451
            ret = CRYPTOCB_UNAVAILABLE;   /* curve not CCB-wrappable -> SW */
8452
        }
8453
    }
8454
    if (ret == 0) {
8455
        ret = wc_ecc_import_wrapped_private_ex(key, curve_id, wrapped, wrappedSz,
8456
                                     iv, (word32)sizeof(iv), tag,
8457
                                     (word32)sizeof(tag), pub,
8458
                                     (word32)(2 * modSz));
8459
    }
8460
8461
    ForceZero(d, MAX_ECC_BYTES);
8462
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
8463
    wc_MemZero_Check(d, MAX_ECC_BYTES);
8464
#endif
8465
    if (tmpInit) {
8466
        wc_ecc_free(tmp);
8467
    }
8468
#ifdef WOLFSSL_SMALL_STACK
8469
    XFREE(scratch, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
8470
    XFREE(tmp, key->heap, DYNAMIC_TYPE_ECC);
8471
#endif
8472
    return ret;
8473
}
8474
#endif /* WOLFSSL_DHUK && WOLFSSL_STM32_CCB */
8475
8476
#endif /* !HAVE_ECC_SIGN */
8477
8478
#ifdef WOLFSSL_CUSTOM_CURVES
8479
void wc_ecc_free_curve(ecc_set_type* curve, void* heap)
8480
{
8481
#ifndef WOLFSSL_ECC_CURVE_STATIC
8482
    if (curve->prime != NULL)
8483
        XFREE((void*)(wc_ptr_t)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
8484
    if (curve->Af != NULL)
8485
        XFREE((void*)(wc_ptr_t)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
8486
    if (curve->Bf != NULL)
8487
        XFREE((void*)(wc_ptr_t)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
8488
    if (curve->order != NULL)
8489
        XFREE((void*)(wc_ptr_t)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
8490
    if (curve->Gx != NULL)
8491
        XFREE((void*)(wc_ptr_t)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
8492
    if (curve->Gy != NULL)
8493
        XFREE((void*)(wc_ptr_t)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
8494
#endif
8495
8496
    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
8497
8498
    (void)heap;
8499
}
8500
#endif /* WOLFSSL_CUSTOM_CURVES */
8501
8502
/**
8503
  Free an ECC key from memory
8504
  key   The key you wish to free
8505
*/
8506
WOLFSSL_ABI
8507
int wc_ecc_free(ecc_key* key)
8508
2.18k
{
8509
2.18k
    if (key == NULL) {
8510
0
        return 0;
8511
0
    }
8512
8513
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
8514
    if (key->devId != INVALID_DEVID) {
8515
        /* Best-effort HSM resource release; errors are intentionally discarded
8516
         * so that software cleanup always runs and wc_ecc_free() retains its
8517
         * ABI guarantee of returning 0 on success. */
8518
        (void)wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
8519
                         WC_PK_TYPE_EC_KEYGEN, 0, key);
8520
        /* always continue to software cleanup */
8521
    }
8522
#endif
8523
8524
#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
8525
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
8526
    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
8527
#ifndef WOLFSSL_NO_MALLOC
8528
    if (key->sign_k != NULL)
8529
#endif
8530
    {
8531
        mp_forcezero(key->sign_k);
8532
        mp_free(key->sign_k);
8533
#ifndef WOLFSSL_NO_MALLOC
8534
        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
8535
        key->sign_k = NULL;
8536
#endif
8537
    }
8538
#endif
8539
8540
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
8541
    #ifdef WC_ASYNC_ENABLE_ECC
8542
    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
8543
    #endif
8544
    wc_ecc_free_async(key);
8545
#endif
8546
8547
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
8548
    /* free secure memory */
8549
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
8550
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
8551
       caamFreePart(key->partNum);
8552
    }
8553
#endif
8554
8555
#ifdef WOLFSSL_SE050
8556
#ifdef WOLFSSL_SE050_AUTO_ERASE
8557
    wc_se050_erase_object(key->keyId);
8558
#endif
8559
    se050_ecc_free_key(key);
8560
#endif
8561
8562
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
8563
    defined(WOLFSSL_MICROCHIP_TA100)
8564
    atmel_ecc_free(key->slot);
8565
    key->slot = ATECC_INVALID_SLOT;
8566
#endif /* WOLFSSL_ATECC508A */
8567
8568
#ifdef WOLFSSL_KCAPI_ECC
8569
    KcapiEcc_Free(key);
8570
#endif
8571
8572
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
8573
    key->privKey = NULL;
8574
    ForceZero(key->keyRaw, sizeof(key->keyRaw));
8575
    ForceZero(&key->xSec, sizeof(key->xSec));
8576
#endif
8577
8578
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
8579
    wc_MAXQ10XX_EccFree(key);
8580
#endif
8581
8582
#ifdef WOLFSSL_DHUK
8583
    /* Scrub the DHUK derivation seed and wrapped scalar (both secret). */
8584
    ForceZero(key->dhuk_seed, sizeof(key->dhuk_seed));
8585
    ForceZero(key->dhuk_wrapped_priv, sizeof(key->dhuk_wrapped_priv));
8586
    key->dhuk_seed_sz = 0;
8587
    key->dhuk_wrapped_priv_len = 0;
8588
    key->dhuk_plain_priv_len = 0;
8589
#endif
8590
8591
2.18k
    mp_clear(key->pubkey.x);
8592
2.18k
    mp_clear(key->pubkey.y);
8593
2.18k
    mp_clear(key->pubkey.z);
8594
8595
#ifdef ALT_ECC_SIZE
8596
    if (key->k)
8597
#endif
8598
2.18k
        mp_forcezero(key->k);
8599
#ifdef WOLFSSL_ECC_BLIND_K
8600
#ifdef ALT_ECC_SIZE
8601
    if (key->kb)
8602
#endif
8603
        mp_forcezero(key->kb);
8604
#ifdef ALT_ECC_SIZE
8605
    if (key->ku)
8606
#endif
8607
        mp_forcezero(key->ku);
8608
#endif
8609
8610
#ifdef WOLFSSL_CUSTOM_CURVES
8611
    if (key->deallocSet && key->dp != NULL) {
8612
        wc_ecc_free_curve((ecc_set_type *)(wc_ptr_t)key->dp, key->heap);
8613
        key->dp = NULL;
8614
    }
8615
#endif
8616
8617
#ifdef WOLFSSL_CHECK_MEM_ZERO
8618
    wc_MemZero_Check(key, sizeof(ecc_key));
8619
#endif
8620
8621
2.18k
    return 0;
8622
2.18k
}
8623
8624
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
8625
    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
8626
    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
8627
      defined(WOLFSSL_IMXRT1170_CAAM))
8628
/* Handles add failure cases:
8629
 *
8630
 * Before add:
8631
 *   Case 1: A is infinity
8632
 *        -> Copy B into result.
8633
 *   Case 2: B is infinity
8634
 *        -> Copy A into result.
8635
 *   Case 3: x and z are the same in A and B (same x value in affine)
8636
 *     Case 3a: y values the same - same point
8637
 *           -> Double instead of add.
8638
 *     Case 3b: y values different - negative of the other when points on curve
8639
 *           -> Need to set result to infinity.
8640
 *
8641
 * After add:
8642
 *   Case 1: A and B are the same point (maybe different z)
8643
 *           (Result was: x == y == z == 0)
8644
 *        -> Need to double instead.
8645
 *
8646
 *   Case 2: A + B = <infinity> = 0.
8647
 *           (Result was: z == 0, x and/or y not 0)
8648
 *        -> Need to set result to infinity.
8649
 */
8650
int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
8651
    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
8652
0
{
8653
0
    int err;
8654
8655
0
    if (mp_iszero(A->x) && mp_iszero(A->y)) {
8656
        /* A is infinity. */
8657
0
        err = wc_ecc_copy_point(B, R);
8658
0
    }
8659
0
    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
8660
        /* B is infinity. */
8661
0
        err = wc_ecc_copy_point(A, R);
8662
0
    }
8663
0
    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
8664
        /* x ordinattes the same. */
8665
0
        if (mp_cmp(A->y, B->y) == MP_EQ) {
8666
            /* A = B */
8667
0
            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8668
0
        }
8669
0
        else {
8670
            /* A = -B */
8671
0
            err = mp_set(R->x, 0);
8672
0
            if (err == MP_OKAY)
8673
0
                err = mp_set(R->y, 0);
8674
0
            if (err == MP_OKAY)
8675
0
                err = mp_set(R->z, 1);
8676
0
            if ((err == MP_OKAY) && (infinity != NULL))
8677
0
                *infinity = 1;
8678
0
        }
8679
0
    }
8680
0
    else {
8681
0
        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
8682
0
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8683
            /* When all zero then should have done a double */
8684
0
            if (mp_iszero(R->x) && mp_iszero(R->y)) {
8685
0
                if (mp_iszero(B->z)) {
8686
0
                    err = wc_ecc_copy_point(B, R);
8687
0
                    if (err == MP_OKAY) {
8688
0
                        err = mp_montgomery_calc_normalization(R->z, modulus);
8689
0
                    }
8690
0
                    if (err == MP_OKAY) {
8691
0
                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
8692
0
                    }
8693
0
                }
8694
0
                else {
8695
0
                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
8696
0
                }
8697
0
            }
8698
            /* When only Z zero then result is infinity */
8699
0
            else {
8700
0
                err = mp_set(R->x, 0);
8701
0
                if (err == MP_OKAY)
8702
0
                    err = mp_set(R->y, 0);
8703
0
                if (err == MP_OKAY)
8704
0
                    err = mp_set(R->z, 1);
8705
0
                if ((err == MP_OKAY) && (infinity != NULL))
8706
0
                    *infinity = 1;
8707
0
            }
8708
0
        }
8709
0
    }
8710
8711
0
    return err;
8712
0
}
8713
8714
/* Handles when P is the infinity point.
8715
 *
8716
 * Double infinity -> infinity.
8717
 * Otherwise do normal double - which can't lead to infinity as odd order.
8718
 */
8719
int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
8720
                                  mp_int* modulus, mp_digit mp)
8721
0
{
8722
0
    int err;
8723
8724
0
    if (mp_iszero(P->x) && mp_iszero(P->y)) {
8725
        /* P is infinity. */
8726
0
        err = wc_ecc_copy_point(P, R);
8727
0
    }
8728
0
    else {
8729
0
        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
8730
0
        if ((err == MP_OKAY) && mp_iszero(R->z)) {
8731
0
           err = mp_set(R->x, 0);
8732
0
           if (err == MP_OKAY)
8733
0
               err = mp_set(R->y, 0);
8734
0
           if (err == MP_OKAY)
8735
0
               err = mp_set(R->z, 1);
8736
0
        }
8737
0
    }
8738
8739
0
    return err;
8740
0
}
8741
#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
8742
          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
8743
          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
8744
            (WOLFSSL_IMXRT1170_CAAM))
8745
        */
8746
8747
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
8748
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
8749
    !defined(WOLFSSL_CRYPTOCELL) && \
8750
    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
8751
#ifdef ECC_SHAMIR
8752
8753
static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
8754
    ecc_point* Bm, mp_int* modulus, void* heap)
8755
0
{
8756
0
    int err = MP_OKAY;
8757
8758
0
    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
8759
8760
0
    if (MP_BITS_OVER_MAX(mp_bitsused(modulus), MAX_ECC_BITS_USE)) {
8761
0
        return WC_KEY_SIZE_E;
8762
0
    }
8763
8764
0
    (void)heap;
8765
8766
0
    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
8767
#ifdef MP_INT_SIZE_CHECK_NULL
8768
    if (mu == NULL)
8769
       err = MEMORY_E;
8770
#endif
8771
0
    if (err == MP_OKAY) {
8772
0
        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
8773
0
    }
8774
0
    if (err == MP_OKAY) {
8775
0
        err = mp_montgomery_calc_normalization(mu, modulus);
8776
8777
0
        if (err == MP_OKAY) {
8778
            /* copy ones ... */
8779
0
            err = mp_mulmod(A->x, mu, modulus, Am->x);
8780
0
        }
8781
8782
0
        if (err == MP_OKAY)
8783
0
            err = mp_mulmod(A->y, mu, modulus, Am->y);
8784
0
        if (err == MP_OKAY)
8785
0
            err = mp_mulmod(A->z, mu, modulus, Am->z);
8786
8787
0
        if (err == MP_OKAY)
8788
0
            err = mp_mulmod(B->x, mu, modulus, Bm->x);
8789
0
        if (err == MP_OKAY)
8790
0
            err = mp_mulmod(B->y, mu, modulus, Bm->y);
8791
0
        if (err == MP_OKAY)
8792
0
            err = mp_mulmod(B->z, mu, modulus, Bm->z);
8793
8794
        /* done with mu */
8795
0
        mp_clear(mu);
8796
0
    }
8797
8798
0
    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
8799
8800
0
    return err;
8801
0
}
8802
8803
/** Computes kA*A + kB*B = C using Shamir's Trick
8804
  A        First point to multiply
8805
  kA       What to multiple A by
8806
  B        Second point to multiply
8807
  kB       What to multiple B by
8808
  C        [out] Destination point (can overlap with A or B)
8809
  a        ECC curve parameter a
8810
  modulus  Modulus for curve
8811
  return MP_OKAY on success
8812
*/
8813
#ifdef FP_ECC
8814
static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
8815
                             ecc_point* B, mp_int* kB,
8816
                             ecc_point* C, mp_int* a, mp_int* modulus,
8817
                             void* heap)
8818
#else
8819
int ecc_mul2add(ecc_point* A, mp_int* kA,
8820
                    ecc_point* B, mp_int* kB,
8821
                    ecc_point* C, mp_int* a, mp_int* modulus,
8822
                    void* heap)
8823
#endif
8824
0
{
8825
#ifdef WOLFSSL_SMALL_STACK_CACHE
8826
  ecc_key        *key = NULL;
8827
#endif
8828
#ifdef WOLFSSL_SMALL_STACK
8829
  ecc_point**    precomp = NULL;
8830
#else
8831
0
  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
8832
  #ifdef WOLFSSL_NO_MALLOC
8833
  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
8834
  #endif
8835
0
#endif
8836
0
  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
8837
#ifdef WOLFSSL_NO_MALLOC
8838
  unsigned char tA[ECC_BUFSIZE];
8839
  unsigned char tB[ECC_BUFSIZE];
8840
#else
8841
0
  unsigned char* tA = NULL;
8842
0
  unsigned char* tB = NULL;
8843
0
#endif
8844
0
  int            err = MP_OKAY, first, x, y;
8845
0
  mp_digit       mp = 0;
8846
8847
  /* argchks */
8848
0
  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
8849
0
                                                         modulus == NULL) {
8850
0
     return ECC_BAD_ARG_E;
8851
0
  }
8852
8853
0
#ifndef WOLFSSL_NO_MALLOC
8854
  /* allocate memory */
8855
0
  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8856
0
  if (tA == NULL) {
8857
0
     return MP_MEM;
8858
0
  }
8859
0
  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
8860
0
  if (tB == NULL) {
8861
0
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8862
0
     return MP_MEM;
8863
0
  }
8864
0
#endif
8865
8866
#ifdef WOLFSSL_SMALL_STACK_CACHE
8867
  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
8868
  if (key == NULL) {
8869
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8870
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8871
     return MP_MEM;
8872
  }
8873
#endif
8874
#ifdef WOLFSSL_SMALL_STACK
8875
  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
8876
                                                       DYNAMIC_TYPE_ECC_BUFFER);
8877
  if (precomp == NULL) {
8878
     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8879
     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8880
  #ifdef WOLFSSL_SMALL_STACK_CACHE
8881
     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8882
  #endif
8883
     return MP_MEM;
8884
  }
8885
#endif
8886
#ifdef WOLFSSL_SMALL_STACK_CACHE
8887
  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8888
  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8889
#ifdef ALT_ECC_SIZE
8890
  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8891
  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8892
  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
8893
#endif
8894
8895
  if (key->t1 == NULL || key->t2 == NULL
8896
#ifdef ALT_ECC_SIZE
8897
     || key->x == NULL || key->y == NULL || key->z == NULL
8898
#endif
8899
  ) {
8900
#ifdef ALT_ECC_SIZE
8901
      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
8902
      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
8903
      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
8904
#endif
8905
      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
8906
      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
8907
      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
8908
      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
8909
      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
8910
      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
8911
      return MEMORY_E;
8912
  }
8913
  C->key = key;
8914
#endif /* WOLFSSL_SMALL_STACK_CACHE */
8915
8916
  /* init variables */
8917
0
  XMEMSET(tA, 0, ECC_BUFSIZE);
8918
0
  XMEMSET(tB, 0, ECC_BUFSIZE);
8919
0
#ifndef WOLFSSL_SMALL_STACK
8920
0
  XMEMSET(precomp, 0, sizeof(precomp));
8921
#else
8922
  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
8923
#endif
8924
#ifdef WOLFSSL_CHECK_MEM_ZERO
8925
  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
8926
  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
8927
#endif
8928
8929
  /* get sizes */
8930
0
  lenA = (unsigned int)mp_unsigned_bin_size(kA);
8931
0
  lenB = (unsigned int)mp_unsigned_bin_size(kB);
8932
0
  len  = MAX(lenA, lenB);
8933
8934
  /* sanity check */
8935
0
  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
8936
0
    err = BAD_FUNC_ARG;
8937
0
  }
8938
8939
0
  if (err == MP_OKAY) {
8940
    /* extract and justify kA */
8941
0
    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
8942
8943
    /* extract and justify kB */
8944
0
    if (err == MP_OKAY)
8945
0
        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
8946
8947
    /* allocate the table */
8948
0
    if (err == MP_OKAY) {
8949
0
        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
8950
        #ifdef WOLFSSL_NO_MALLOC
8951
            precomp[x] = &lcl_precomp[x];
8952
        #endif
8953
0
            err = wc_ecc_new_point_ex(&precomp[x], heap);
8954
0
            if (err != MP_OKAY)
8955
0
                break;
8956
        #ifdef WOLFSSL_SMALL_STACK_CACHE
8957
            precomp[x]->key = key;
8958
        #endif
8959
0
        }
8960
0
    }
8961
0
  }
8962
8963
0
  if (err == MP_OKAY)
8964
    /* init montgomery reduction */
8965
0
    err = mp_montgomery_setup(modulus, &mp);
8966
8967
0
  if (err == MP_OKAY) {
8968
0
    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
8969
0
  }
8970
8971
0
  if (err == MP_OKAY) {
8972
    /* precomp [i,0](A + B) table */
8973
0
    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
8974
0
  }
8975
0
  if (err == MP_OKAY) {
8976
0
    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
8977
0
                                                          a, modulus, mp, NULL);
8978
0
  }
8979
8980
0
  if (err == MP_OKAY) {
8981
    /* precomp [0,i](A + B) table */
8982
0
    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
8983
0
  }
8984
0
  if (err == MP_OKAY) {
8985
0
    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
8986
0
                                                             modulus, mp, NULL);
8987
0
  }
8988
8989
0
  if (err == MP_OKAY) {
8990
    /* precomp [i,j](A + B) table (i != 0, j != 0) */
8991
0
    for (x = 1; x < 4; x++) {
8992
0
      for (y = 1; y < 4; y++) {
8993
0
        if (err == MP_OKAY) {
8994
0
          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
8995
0
                                                  precomp[x+(y<<2)], a, modulus,
8996
0
                                                  mp, NULL);
8997
0
        }
8998
0
      }
8999
0
    }
9000
0
  }
9001
9002
0
  if (err == MP_OKAY) {
9003
0
    nibble  = 3;
9004
0
    first   = 1;
9005
0
    bitbufA = tA[0];
9006
0
    bitbufB = tB[0];
9007
9008
    /* for every byte of the multiplicands */
9009
0
    for (x = 0; x < (int)len || nibble != 3; ) {
9010
        /* grab a nibble */
9011
0
        if (++nibble == 4) {
9012
0
            if (x == (int)len) break;
9013
0
            bitbufA = tA[x];
9014
0
            bitbufB = tB[x];
9015
0
            nibble  = 0;
9016
0
            x++;
9017
0
        }
9018
9019
        /* extract two bits from both, shift/update */
9020
0
        nA = (bitbufA >> 6) & 0x03;
9021
0
        nB = (bitbufB >> 6) & 0x03;
9022
0
        bitbufA = (bitbufA << 2) & 0xFF;
9023
0
        bitbufB = (bitbufB << 2) & 0xFF;
9024
9025
        /* if both zero, if first, continue */
9026
0
        if ((nA == 0) && (nB == 0) && (first == 1)) {
9027
0
            continue;
9028
0
        }
9029
9030
        /* double twice, only if this isn't the first */
9031
0
        if (first == 0) {
9032
            /* double twice */
9033
0
            if (err == MP_OKAY)
9034
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9035
0
            if (err == MP_OKAY)
9036
0
                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
9037
0
            else
9038
0
                break;
9039
0
        }
9040
9041
        /* if not both zero */
9042
0
        if ((nA != 0) || (nB != 0)) {
9043
0
            unsigned int i = nA + (nB<<2);
9044
0
            if (first == 1) {
9045
                /* if first, copy from table */
9046
0
                first = 0;
9047
0
                if (err == MP_OKAY)
9048
0
                    err = mp_copy(precomp[i]->x, C->x);
9049
9050
0
                if (err == MP_OKAY)
9051
0
                    err = mp_copy(precomp[i]->y, C->y);
9052
9053
0
                if (err == MP_OKAY)
9054
0
                    err = mp_copy(precomp[i]->z, C->z);
9055
0
                else
9056
0
                    break;
9057
0
            } else {
9058
                /* if not first, add from table */
9059
0
                if (err == MP_OKAY)
9060
0
                    err = ecc_projective_add_point_safe(C, precomp[i],
9061
0
                                                        C, a, modulus, mp,
9062
0
                                                        &first);
9063
0
                if (err != MP_OKAY)
9064
0
                    break;
9065
0
            }
9066
0
        }
9067
0
    }
9068
0
  }
9069
9070
  /* reduce to affine */
9071
0
  if (err == MP_OKAY)
9072
0
    err = ecc_map(C, modulus, mp);
9073
9074
  /* clean up */
9075
0
  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
9076
0
     wc_ecc_del_point_ex(precomp[x], heap);
9077
0
  }
9078
9079
0
  ForceZero(tA, ECC_BUFSIZE);
9080
0
  ForceZero(tB, ECC_BUFSIZE);
9081
#ifdef WOLFSSL_SMALL_STACK_CACHE
9082
#ifdef ALT_ECC_SIZE
9083
  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
9084
  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
9085
  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
9086
#endif
9087
  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
9088
  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
9089
  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
9090
  C->key = NULL;
9091
#endif
9092
0
  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
9093
0
#ifndef WOLFSSL_NO_MALLOC
9094
0
  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
9095
0
  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
9096
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
9097
  wc_MemZero_Check(tB, ECC_BUFSIZE);
9098
  wc_MemZero_Check(tA, ECC_BUFSIZE);
9099
#endif
9100
0
  return err;
9101
0
}
9102
9103
#endif /* ECC_SHAMIR */
9104
#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
9105
        * !WOLFSSL_CRYPTOCEL */
9106
9107
9108
#ifdef HAVE_ECC_VERIFY
9109
/* verify
9110
 *
9111
 * w  = s^-1 mod n
9112
 * u1 = xw
9113
 * u2 = rw
9114
 * X = u1*G + u2*Q
9115
 * v = X_x1 mod n
9116
 * accept if v == r
9117
 */
9118
9119
/**
9120
 Verify an ECC signature
9121
 sig         The signature to verify
9122
 siglen      The length of the signature (octets)
9123
 hash        The hash (message digest) that was signed
9124
 hashlen     The length of the hash (octets)
9125
 res         Result of signature, 1==valid, 0==invalid
9126
 key         The corresponding public ECC key
9127
 return      MP_OKAY if successful (even if the signature is not valid)
9128
             Caller should check the *res value to determine if the signature
9129
             is valid or invalid. Other negative values are returned on error.
9130
 */
9131
WOLFSSL_ABI
9132
int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
9133
                       word32 hashlen, int* res, ecc_key* key)
9134
0
{
9135
0
    int err;
9136
9137
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9138
    mp_int *r = NULL, *s = NULL;
9139
#else
9140
0
    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9141
0
    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
9142
0
#endif
9143
#ifdef WOLFSSL_ASYNC_CRYPT
9144
    int isPrivateKeyOnly = 0;
9145
#endif
9146
#ifdef NO_ASN
9147
    word32 keySz;
9148
#endif
9149
9150
0
    if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE)) {
9151
0
        return WC_KEY_SIZE_E;
9152
0
    }
9153
9154
0
    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
9155
0
        return ECC_BAD_ARG_E;
9156
0
    }
9157
9158
    /* Check hash length */
9159
0
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
9160
0
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
9161
0
        return BAD_LENGTH_E;
9162
0
    }
9163
9164
#ifdef WOLF_CRYPTO_CB
9165
    #ifndef WOLF_CRYPTO_CB_FIND
9166
    if (key->devId != INVALID_DEVID)
9167
    #endif
9168
    {
9169
        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
9170
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
9171
            return err;
9172
        /* fall-through when unavailable */
9173
    }
9174
#endif
9175
9176
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
9177
    (void)siglen;
9178
    (void)hashlen;
9179
    (void)s;
9180
    (void)r;
9181
    (void)err;
9182
    return NO_VALID_DEVID;
9183
#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
9184
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9185
    err = wc_ecc_alloc_async(key);
9186
    if (err != 0)
9187
        return err;
9188
    r = key->r;
9189
    s = key->s;
9190
#else
9191
0
    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9192
0
        DYNAMIC_TYPE_ECC);
9193
    #ifdef MP_INT_SIZE_CHECK_NULL
9194
    if (r == NULL)
9195
        return MEMORY_E;
9196
    #endif
9197
0
    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
9198
0
        DYNAMIC_TYPE_ECC);
9199
    #ifdef MP_INT_SIZE_CHECK_NULL
9200
    if (s == NULL) {
9201
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9202
        return MEMORY_E;
9203
    }
9204
    #endif
9205
0
    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9206
0
    if (err != 0) {
9207
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9208
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9209
0
        return err;
9210
0
    }
9211
0
    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9212
0
    if (err != 0) {
9213
0
        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9214
0
        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9215
0
        return err;
9216
0
    }
9217
0
#endif /* WOLFSSL_ASYNC_CRYPT */
9218
9219
0
    switch (key->state) {
9220
0
        case ECC_STATE_NONE:
9221
0
        case ECC_STATE_VERIFY_DECODE:
9222
0
            key->state = ECC_STATE_VERIFY_DECODE;
9223
9224
            /* default to invalid signature */
9225
0
            *res = 0;
9226
9227
0
    #ifndef NO_ASN
9228
            /* Decode ASN.1 ECDSA signature. */
9229
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9230
            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
9231
             * If either of those don't allocate correctly, none of
9232
             * the rest of this function will execute, and everything
9233
             * gets cleaned up at the end. */
9234
            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
9235
        #else
9236
            /* r and s are initialized. */
9237
0
            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
9238
0
        #endif
9239
0
            if (err < 0) {
9240
0
                break;
9241
0
            }
9242
    #else
9243
            /* No support for DSA ASN.1 header.
9244
             * Signature must be r+s directly. */
9245
            keySz = 0;
9246
            if (key->dp != NULL) {
9247
                keySz = (word32)key->dp->size;
9248
            }
9249
            if (siglen != keySz * 2) {
9250
                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
9251
                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
9252
            }
9253
9254
            /* Import signature into r,s */
9255
            mp_init(r);
9256
            mp_init(s);
9257
            mp_read_unsigned_bin(r, sig, keySz);
9258
            mp_read_unsigned_bin(s, sig + keySz, keySz);
9259
    #endif /* !NO_ASN */
9260
0
            FALL_THROUGH;
9261
9262
0
        case ECC_STATE_VERIFY_DO:
9263
0
            key->state = ECC_STATE_VERIFY_DO;
9264
        #ifdef WOLFSSL_ASYNC_CRYPT
9265
            if (key->type == ECC_PRIVATEKEY_ONLY) {
9266
                isPrivateKeyOnly = 1;
9267
            }
9268
        #endif
9269
0
            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9270
9271
0
        #ifndef WOLFSSL_ASYNC_CRYPT
9272
            /* done with R/S */
9273
0
            mp_clear(r);
9274
0
            mp_clear(s);
9275
0
            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9276
0
            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9277
        #ifdef MP_INT_SIZE_CHECK_NULL
9278
            r = NULL;
9279
            s = NULL;
9280
        #endif
9281
0
        #endif
9282
9283
0
            if (err < 0) {
9284
0
                break;
9285
0
            }
9286
0
            FALL_THROUGH;
9287
9288
0
        case ECC_STATE_VERIFY_RES:
9289
0
            key->state = ECC_STATE_VERIFY_RES;
9290
0
            err = 0;
9291
0
            break;
9292
9293
0
        default:
9294
0
            err = BAD_STATE_E;
9295
0
    }
9296
9297
#ifdef WOLFSSL_ASYNC_CRYPT
9298
    /* if async pending then return and skip done cleanup below */
9299
    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
9300
        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
9301
            key->state++;
9302
        return err;
9303
    }
9304
#endif
9305
9306
    /* cleanup */
9307
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9308
    wc_ecc_free_async(key);
9309
#else
9310
0
    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
9311
0
    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
9312
0
#endif
9313
9314
    /* make sure required variables are reset */
9315
0
    wc_ecc_reset(key);
9316
0
    return err;
9317
0
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
9318
0
}
9319
9320
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
9321
9322
#if (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
9323
    !defined(WOLFSSL_PSOC6_CRYPTO) && \
9324
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
9325
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
9326
0
{
9327
0
    int err = MP_OKAY;
9328
0
    DECLARE_CURVE_SPECS(1);
9329
9330
0
    ALLOC_CURVE_SPECS(1, err);
9331
0
    if (err == MP_OKAY) {
9332
0
        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
9333
0
    }
9334
0
    if (err != 0) {
9335
0
        FREE_CURVE_SPECS();
9336
0
        return err;
9337
0
    }
9338
9339
0
    if (mp_iszero(r) || mp_iszero(s)) {
9340
0
        err = MP_ZERO_E;
9341
0
    }
9342
0
    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
9343
0
        err = MP_VAL;
9344
0
    }
9345
0
    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
9346
0
        err = MP_VAL;
9347
0
    }
9348
9349
0
    wc_ecc_curve_free(curve);
9350
0
    FREE_CURVE_SPECS();
9351
0
    return err;
9352
0
}
9353
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
9354
9355
#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP)
9356
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
9357
    word32 hashlen, int* res, ecc_key* key)
9358
0
{
9359
0
    (void)r;
9360
0
    (void)s;
9361
0
    (void)hash;
9362
0
    (void)hashlen;
9363
0
    (void)res;
9364
0
    (void)key;
9365
9366
#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
9367
  if (key->handle != -1) {
9368
      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
9369
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9370
  }
9371
  if (wolfSSL_GetHandleCbSet() == 1) {
9372
      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
9373
        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9374
  }
9375
#endif
9376
9377
#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
9378
    if (key->idx == ECC_CUSTOM_IDX || (1
9379
    #ifndef WOLFSSL_SP_NO_256
9380
         && ecc_sets[key->idx].id != ECC_SECP256R1
9381
    #endif
9382
    #ifdef WOLFSSL_SP_SM2
9383
         && ecc_sets[key->idx].id != ECC_SM2P256V1
9384
    #endif
9385
    #ifdef WOLFSSL_SP_384
9386
         && ecc_sets[key->idx].id != ECC_SECP384R1
9387
    #endif
9388
    #ifdef WOLFSSL_SP_521
9389
         && ecc_sets[key->idx].id != ECC_SECP521R1
9390
    #endif
9391
        )) {
9392
        return WC_KEY_SIZE_E;
9393
    }
9394
#endif
9395
9396
#if defined(WOLFSSL_HAVE_SP_ECC)
9397
    if (key->idx != ECC_CUSTOM_IDX) {
9398
    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
9399
        /* perform blocking call to non-blocking function */
9400
        ecc_nb_ctx_t nb_ctx;
9401
        int err;
9402
        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
9403
        err = NOT_COMPILED_IN; /* set default error */
9404
    #endif
9405
    #ifndef WOLFSSL_SP_NO_256
9406
        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
9407
        #ifdef WC_ECC_NONBLOCK
9408
            if (key->nb_ctx) {
9409
                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9410
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9411
                    key->heap);
9412
            }
9413
            #ifdef WC_ECC_NONBLOCK_ONLY
9414
            do { /* perform blocking call to non-blocking function */
9415
                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
9416
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9417
                    key->heap);
9418
            } while (err == FP_WOULDBLOCK);
9419
            return err;
9420
            #endif
9421
        #endif /* WC_ECC_NONBLOCK */
9422
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9423
            {
9424
                int ret;
9425
                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
9426
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9427
                return ret;
9428
            }
9429
        #endif
9430
        }
9431
    #endif
9432
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
9433
        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
9434
            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
9435
            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
9436
                key->pubkey.y, key->pubkey.z, r, s, res,
9437
                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
9438
                                          key->fpIdx, key->fpBuild, key->heap),
9439
                key->heap);
9440
            #endif
9441
            #if !defined(FP_ECC_CONTROL)
9442
            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
9443
                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9444
            #endif
9445
        }
9446
    #endif
9447
    #ifdef WOLFSSL_SP_384
9448
        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
9449
        #ifdef WC_ECC_NONBLOCK
9450
            if (key->nb_ctx) {
9451
                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9452
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9453
                    key->heap);
9454
            }
9455
            #ifdef WC_ECC_NONBLOCK_ONLY
9456
            do { /* perform blocking call to non-blocking function */
9457
                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
9458
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9459
                    key->heap);
9460
            } while (err == FP_WOULDBLOCK);
9461
            return err;
9462
            #endif
9463
        #endif /* WC_ECC_NONBLOCK */
9464
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9465
            {
9466
                int ret;
9467
                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
9468
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9469
                return ret;
9470
            }
9471
        #endif
9472
        }
9473
    #endif
9474
    #ifdef WOLFSSL_SP_521
9475
        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
9476
        #ifdef WC_ECC_NONBLOCK
9477
            if (key->nb_ctx) {
9478
                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
9479
                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
9480
                    key->heap);
9481
            }
9482
            #ifdef WC_ECC_NONBLOCK_ONLY
9483
            do { /* perform blocking call to non-blocking function */
9484
                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
9485
                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
9486
                    key->heap);
9487
            } while (err == FP_WOULDBLOCK);
9488
            return err;
9489
            #endif
9490
        #endif /* WC_ECC_NONBLOCK */
9491
        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
9492
            {
9493
                int ret;
9494
                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
9495
                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
9496
                return ret;
9497
            }
9498
        #endif
9499
        }
9500
    #endif
9501
    }
9502
#endif
9503
9504
0
    return NOT_COMPILED_IN;
9505
0
}
9506
9507
#if !defined(WOLFSSL_MICROCHIP) && \
9508
    (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC))
9509
static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
9510
    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
9511
0
{
9512
0
   int        err;
9513
0
   ecc_point* mG = NULL;
9514
0
   ecc_point* mQ = NULL;
9515
#ifdef WOLFSSL_NO_MALLOC
9516
   ecc_point  lcl_mG;
9517
   ecc_point  lcl_mQ;
9518
#endif
9519
9520
0
   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9521
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9522
0
   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
9523
0
#endif
9524
0
   mp_int*    e;
9525
0
   mp_int*    v = NULL;      /* Will be w. */
9526
#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
9527
   mp_int     u1tmp[1];
9528
   mp_int     u2tmp[1];
9529
#endif
9530
0
   mp_int*    u1 = NULL;     /* Will be e. */
9531
0
   mp_int*    u2 = NULL;     /* Will be w. */
9532
9533
0
   if (MP_BITS_OVER_MAX(ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE)) {
9534
0
       return WC_KEY_SIZE_E;
9535
0
   }
9536
9537
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
9538
   err = wc_ecc_alloc_mpint(key, &key->e);
9539
   if (err != 0) {
9540
      return err;
9541
   }
9542
   e = key->e;
9543
9544
   err = mp_init(e);
9545
#else
9546
0
   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
9547
#ifdef MP_INT_SIZE_CHECK_NULL
9548
   if (e_lcl == NULL) {
9549
       return MEMORY_E;
9550
   }
9551
#endif
9552
0
   e = e_lcl;
9553
9554
0
   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9555
0
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
9556
0
   if (err != MP_OKAY) {
9557
#ifdef WOLFSSL_SMALL_STACK
9558
   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9559
      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9560
   #endif
9561
#endif
9562
0
      return MEMORY_E;
9563
0
   }
9564
9565
   /* read hash */
9566
0
   if (err == MP_OKAY) {
9567
       /* we may need to truncate if hash is longer than key size */
9568
0
       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
9569
9570
       /* truncate down to byte size, may be all that's needed */
9571
0
       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9572
0
           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
9573
0
       err = mp_read_unsigned_bin(e, hash, hashlen);
9574
9575
       /* may still need bit truncation too */
9576
0
       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
9577
0
           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
9578
0
   }
9579
9580
   /* check for async hardware acceleration */
9581
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
9582
   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9583
   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
9584
   #ifdef HAVE_CAVIUM_V
9585
      if (NitroxEccIsCurveSupported(key))
9586
   #endif
9587
      {
9588
          word32 keySz = (word32)key->dp->size;
9589
          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
9590
          if (err == MP_OKAY)
9591
              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
9592
          if (err == MP_OKAY)
9593
              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
9594
          if (err == MP_OKAY)
9595
          #ifdef HAVE_CAVIUM_V
9596
              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
9597
                    &key->pubkey.y->raw, &r->raw, &s->raw,
9598
                    &curve->prime->raw, &curve->order->raw, res);
9599
          #else
9600
              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
9601
                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
9602
                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
9603
                    &curve->Gx->raw, &curve->Gy->raw, res);
9604
          #endif
9605
9606
      #ifndef HAVE_CAVIUM_V
9607
          mp_clear(e);
9608
      #endif
9609
9610
          return err;
9611
      }
9612
   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
9613
   }
9614
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
9615
9616
0
   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
9617
#ifdef MP_INT_SIZE_CHECK_NULL
9618
   if (w == NULL) {
9619
       err = MEMORY_E;
9620
   }
9621
#endif
9622
9623
0
   if (err == MP_OKAY) {
9624
#ifdef WOLFSSL_CHECK_VER_FAULTS
9625
    #ifndef WOLFSSL_NO_MALLOC
9626
        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9627
        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
9628
       if (u1 == NULL || u2 == NULL)
9629
            err = MEMORY_E;
9630
    #else
9631
        u1 = u1tmp;
9632
        u2 = u2tmp;
9633
    #endif
9634
       /* zeroed so the cleanup below no-ops if the init is skipped */
9635
       if (u1 != NULL)
9636
           XMEMSET(u1, 0, sizeof(mp_int));
9637
       if (u2 != NULL)
9638
           XMEMSET(u2, 0, sizeof(mp_int));
9639
#else
9640
0
       u1 = e;
9641
0
       u2 = w;
9642
0
#endif
9643
0
       v = w;
9644
0
   }
9645
0
   if (err == MP_OKAY) {
9646
0
       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9647
0
   }
9648
#ifdef WOLFSSL_CHECK_VER_FAULTS
9649
   if (err == MP_OKAY) {
9650
       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9651
   }
9652
   if (err == MP_OKAY) {
9653
       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
9654
   }
9655
#endif
9656
9657
   /* allocate points */
9658
0
   if (err == MP_OKAY) {
9659
   #ifdef WOLFSSL_NO_MALLOC
9660
       mG = &lcl_mG;
9661
   #endif
9662
0
       err = wc_ecc_new_point_ex(&mG, key->heap);
9663
0
   }
9664
0
   if (err == MP_OKAY) {
9665
   #ifdef WOLFSSL_NO_MALLOC
9666
       mQ = &lcl_mQ;
9667
   #endif
9668
0
       err = wc_ecc_new_point_ex(&mQ, key->heap);
9669
0
   }
9670
9671
   /*  w  = s^-1 mod n */
9672
0
   if (err == MP_OKAY)
9673
0
       err = mp_invmod(s, curve->order, w);
9674
9675
   /* u1 = ew */
9676
0
   if (err == MP_OKAY)
9677
0
       err = mp_mulmod(e, w, curve->order, u1);
9678
9679
#ifdef WOLFSSL_CHECK_VER_FAULTS
9680
    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
9681
        err = BAD_STATE_E;
9682
    }
9683
#endif
9684
9685
   /* u2 = rw */
9686
0
   if (err == MP_OKAY)
9687
0
       err = mp_mulmod(r, w, curve->order, u2);
9688
9689
#ifdef WOLFSSL_CHECK_VER_FAULTS
9690
    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
9691
        err = BAD_STATE_E;
9692
    }
9693
#endif
9694
9695
   /* find mG and mQ */
9696
0
   if (err == MP_OKAY)
9697
0
       err = mp_copy(curve->Gx, mG->x);
9698
0
   if (err == MP_OKAY)
9699
0
       err = mp_copy(curve->Gy, mG->y);
9700
0
   if (err == MP_OKAY)
9701
0
       err = mp_set(mG->z, 1);
9702
9703
0
   if (err == MP_OKAY)
9704
0
       err = mp_copy(key->pubkey.x, mQ->x);
9705
0
   if (err == MP_OKAY)
9706
0
       err = mp_copy(key->pubkey.y, mQ->y);
9707
0
   if (err == MP_OKAY)
9708
0
       err = mp_copy(key->pubkey.z, mQ->z);
9709
9710
#if defined(FREESCALE_LTC_ECC)
9711
   /* use PKHA to compute u1*mG + u2*mQ */
9712
   if (err == MP_OKAY)
9713
       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
9714
   if (err == MP_OKAY)
9715
       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
9716
   if (err == MP_OKAY)
9717
       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
9718
#else
9719
#ifndef ECC_SHAMIR
9720
    if (err == MP_OKAY)
9721
    {
9722
     #ifdef WOLFSSL_CHECK_VER_FAULTS
9723
        ecc_point mG1, mQ1;
9724
        wc_ecc_copy_point(mQ, &mQ1);
9725
        wc_ecc_copy_point(mG, &mG1);
9726
     #endif
9727
9728
        mp_digit mp = 0;
9729
9730
        if (!mp_iszero((MP_INT_SIZE*)u1)) {
9731
            /* compute u1*mG + u2*mQ = mG */
9732
            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
9733
                                                                     key->heap);
9734
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9735
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9736
                err = BAD_STATE_E;
9737
            }
9738
9739
            /* store new value for comparing with after add operation */
9740
           wc_ecc_copy_point(mG, &mG1);
9741
        #endif
9742
            if (err == MP_OKAY) {
9743
                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
9744
                                                                     key->heap);
9745
            }
9746
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9747
            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
9748
                err = BAD_STATE_E;
9749
            }
9750
        #endif
9751
9752
            /* find the montgomery mp */
9753
            if (err == MP_OKAY)
9754
                err = mp_montgomery_setup(curve->prime, &mp);
9755
9756
            /* add them - pass mG as A (first) not B (second): the safe-add
9757
             * recovery for a missed-double doubles B into R, which requires
9758
             * B and R to be different points. */
9759
            if (err == MP_OKAY)
9760
                err = ecc_projective_add_point_safe(mG, mQ, mG, curve->Af,
9761
                                                        curve->prime, mp, NULL);
9762
        #ifdef WOLFSSL_CHECK_VER_FAULTS
9763
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
9764
                err = BAD_STATE_E;
9765
            }
9766
            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
9767
                err = BAD_STATE_E;
9768
            }
9769
        #endif
9770
        }
9771
        else {
9772
            /* compute 0*mG + u2*mQ = mG */
9773
            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
9774
                                                                     key->heap);
9775
            /* find the montgomery mp */
9776
            if (err == MP_OKAY)
9777
                err = mp_montgomery_setup(curve->prime, &mp);
9778
        }
9779
9780
        /* reduce */
9781
        if (err == MP_OKAY)
9782
            err = ecc_map(mG, curve->prime, mp);
9783
    }
9784
#else
9785
    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
9786
0
    if (err == MP_OKAY) {
9787
0
        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
9788
0
                                                                     key->heap);
9789
0
    }
9790
0
#endif /* ECC_SHAMIR */
9791
0
#endif /* FREESCALE_LTC_ECC */
9792
9793
   /* v = X_x1 mod n */
9794
0
   if (err == MP_OKAY)
9795
0
       err = mp_mod(mG->x, curve->order, v);
9796
9797
   /* does v == r */
9798
0
   if (err == MP_OKAY) {
9799
0
       if (mp_cmp(v, r) == MP_EQ)
9800
0
           *res = 1;
9801
#ifdef WOLFSSL_CHECK_VER_FAULTS
9802
       /* redundant comparison as sanity check that first one happened */
9803
       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
9804
           *res = 0;
9805
#endif
9806
0
   }
9807
9808
   /* cleanup */
9809
0
   wc_ecc_del_point_ex(mG, key->heap);
9810
0
   wc_ecc_del_point_ex(mQ, key->heap);
9811
9812
0
   mp_clear(e);
9813
0
   mp_clear(w);
9814
0
   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
9815
#ifdef WOLFSSL_CHECK_VER_FAULTS
9816
   mp_clear(u1);
9817
   mp_clear(u2);
9818
#ifndef WOLFSSL_NO_MALLOC
9819
   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
9820
   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
9821
#endif
9822
#endif
9823
0
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
9824
0
   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
9825
0
#endif
9826
9827
0
   return err;
9828
0
}
9829
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
9830
#endif /* HAVE_ECC_VERIFY_HELPER */
9831
9832
/**
9833
   Verify an ECC signature
9834
   r           The signature R component to verify
9835
   s           The signature S component to verify
9836
   hash        The hash (message digest) that was signed
9837
   hashlen     The length of the hash (octets)
9838
   res         Result of signature, 1==valid, 0==invalid
9839
   key         The corresponding public ECC key
9840
   return      MP_OKAY if successful (even if the signature is not valid)
9841
               Caller should check the *res value to determine if the signature
9842
               is valid or invalid. Other negative values are returned on error.
9843
*/
9844
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
9845
                    word32 hashlen, int* res, ecc_key* key)
9846
0
{
9847
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_SIGN_ONLY)
9848
    /* HW ECDSA verify via STM32 PKA. Works under both the CubeMX-HAL
9849
     * and the bare-metal direct-register paths. (Under WC_STM32_PKA_SIGN_ONLY
9850
     * -- e.g. STM32C5 -- verify falls through to the software body below.)
9851
     * Mirror the non-FIPS
9852
     * input-validation from the SW body below (length range, all-zero
9853
     * digest rejection) so HW + SW share the same input contract. */
9854
#ifndef WC_ALLOW_ECC_ZERO_HASH
9855
    byte hashIsZero = 0;
9856
    word32 zIdx;
9857
#endif
9858
9859
    if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) {
9860
        return ECC_BAD_ARG_E;
9861
    }
9862
    if ((hashlen > WC_MAX_DIGEST_SIZE) || (hashlen < WC_MIN_DIGEST_SIZE)) {
9863
        return BAD_LENGTH_E;
9864
    }
9865
#ifndef WC_ALLOW_ECC_ZERO_HASH
9866
    /* reject all 0's hash */
9867
    for (zIdx = 0; zIdx < hashlen; zIdx++)
9868
        hashIsZero |= hash[zIdx];
9869
    if (hashIsZero == 0)
9870
        return ECC_BAD_ARG_E;
9871
#endif
9872
9873
    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9874
#elif defined(WOLFSSL_PSOC6_CRYPTO)
9875
    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
9876
#else
9877
0
   int           err;
9878
0
   word32        keySz = 0;
9879
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
9880
0
   byte hashIsZero = 0;
9881
0
   word32 zIdx;
9882
0
#endif
9883
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9884
   byte sigRS[ATECC_KEY_SIZE*2];
9885
#elif defined(WOLFSSL_MICROCHIP_TA100)
9886
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9887
#elif defined(WOLFSSL_CRYPTOCELL)
9888
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
9889
   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
9890
   word32 msgLenInBytes = hashlen;
9891
   CRYS_ECPKI_HASH_OpMode_t hash_mode;
9892
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
9893
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9894
#elif defined(WOLFSSL_KCAPI_ECC)
9895
   byte sigRS[MAX_ECC_BYTES*2];
9896
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
9897
   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
9898
   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
9899
#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) && \
9900
      !defined(WOLFSSL_SE050_ONLY_KEY_ID)
9901
#else
9902
   /* Software verify helper (also used for SE050 software keys under
9903
    * WOLFSSL_SE050_ONLY_KEY_ID) needs the curve specs. */
9904
0
   int curveLoaded = 0;
9905
0
   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
9906
0
#endif
9907
9908
0
   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
9909
0
       return ECC_BAD_ARG_E;
9910
9911
    /* Check hash length */
9912
0
    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
9913
0
        (hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
9914
0
        return BAD_LENGTH_E;
9915
0
    }
9916
9917
0
#ifndef WC_ALLOW_ECC_ZERO_HASH
9918
    /* reject all 0's hash */
9919
0
    for (zIdx = 0; zIdx < hashlen; zIdx++)
9920
0
        hashIsZero |= hash[zIdx];
9921
0
    if (hashIsZero == 0)
9922
0
        return ECC_BAD_ARG_E;
9923
0
#endif
9924
9925
   /* default to invalid signature */
9926
0
   *res = 0;
9927
9928
   /* is the IDX valid ?  */
9929
0
   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
9930
0
      return ECC_BAD_ARG_E;
9931
0
   }
9932
9933
0
   err = wc_ecc_check_r_s_range(key, r, s);
9934
0
   if (err != MP_OKAY) {
9935
0
      return err;
9936
0
   }
9937
9938
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_ONLY_KEY_ID) && \
9939
    !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY)
9940
   /* Key resident in the SE050: verify in hardware. Software keys fall through
9941
    * to the wolfCrypt verify helper below. */
9942
   if (key->keyIdSet) {
9943
       return se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
9944
   }
9945
#endif
9946
9947
0
   keySz = (word32)key->dp->size;
9948
9949
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
9950
    defined(WOLFSSL_ASYNC_CRYPT_SW)
9951
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
9952
        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
9953
            WC_ASYNC_SW* sw = &key->asyncDev.sw;
9954
            sw->eccVerify.r = r;
9955
            sw->eccVerify.s = s;
9956
            sw->eccVerify.hash = hash;
9957
            sw->eccVerify.hashlen = hashlen;
9958
            sw->eccVerify.stat = res;
9959
            sw->eccVerify.key = key;
9960
            return WC_PENDING_E;
9961
        }
9962
    }
9963
#endif
9964
9965
#ifndef HAVE_ECC_VERIFY_HELPER
9966
9967
#ifndef WOLFSSL_SE050
9968
    /* Extract R and S with front zero padding (if required),
9969
     * SE050 does this in port layer  */
9970
    XMEMSET(sigRS, 0, sizeof(sigRS));
9971
    err = mp_to_unsigned_bin(r, sigRS +
9972
                                (keySz - mp_unsigned_bin_size(r)));
9973
    if (err != MP_OKAY) {
9974
        return err;
9975
    }
9976
    err = mp_to_unsigned_bin(s, sigRS + keySz +
9977
                                (keySz - mp_unsigned_bin_size(s)));
9978
    if (err != MP_OKAY) {
9979
        return err;
9980
    }
9981
#endif /* WOLFSSL_SE050 */
9982
9983
#if defined(WOLFSSL_MICROCHIP_TA100)
9984
    if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
9985
        err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
9986
        if (err != 0) {
9987
            return err;
9988
        }
9989
        (void)hashlen;
9990
    }
9991
    else {
9992
        err = atmel_ecc_verify_ex(hash, hashlen, sigRS, key->pubkey_raw,
9993
            keySz * 2, microchip_curve_id_for_key(key), res);
9994
        if (err != 0) {
9995
           return err;
9996
        }
9997
    }
9998
#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
9999
    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
10000
    if (err != 0) {
10001
       return err;
10002
    }
10003
    (void)hashlen;
10004
#elif defined(WOLFSSL_CRYPTOCELL)
10005
10006
   /* truncate if hash is longer than key size */
10007
   if (msgLenInBytes > keySz) {
10008
       msgLenInBytes = keySz;
10009
   }
10010
   hash_mode = cc310_hashModeECC(msgLenInBytes);
10011
   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
10012
       /* hash_mode = */ cc310_hashModeECC(keySz);
10013
       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
10014
   }
10015
10016
   /* verify the signature using the public key */
10017
   err = CRYS_ECDSA_Verify(&sigCtxTemp,
10018
                           &key->ctx.pubKey,
10019
                           hash_mode,
10020
                           &sigRS[0],
10021
                           keySz*2,
10022
                           (byte*)hash,
10023
                           msgLenInBytes);
10024
10025
   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
10026
       /* signature verification reported invalid signature. */
10027
       *res = 0; /* Redundant, added for code clarity */
10028
       err = MP_OKAY;
10029
   }
10030
   else if (err != SA_SILIB_RET_OK) {
10031
       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
10032
       return err;
10033
   }
10034
   else {
10035
       /* valid signature. */
10036
       *res = 1;
10037
       err = MP_OKAY;
10038
   }
10039
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10040
   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
10041
                                hash, hashlen,
10042
                                res, key);
10043
#elif defined(WOLFSSL_KCAPI_ECC)
10044
    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
10045
    if (err == 0) {
10046
        *res = 1;
10047
    }
10048
#elif defined(WOLFSSL_SE050)
10049
    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
10050
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
10051
    if (hashlen > sizeof(hashcopy))
10052
        return ECC_BAD_ARG_E;
10053
    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
10054
    mp_reverse(sigRS, keySz);
10055
    mp_reverse(sigRS + keySz, keySz);
10056
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
10057
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
10058
    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
10059
10060
    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
10061
                                     xil_curve_type[key->dp->id],
10062
                                     XIL_CAST_U64(hashcopy), keySz,
10063
                                     XIL_CAST_U64(key->keyRaw),
10064
                                     XIL_CAST_U64(sigRS));
10065
10066
    if (err != XST_SUCCESS) {
10067
        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
10068
        err = WC_HW_E;
10069
    } else {
10070
        *res = 1;
10071
    }
10072
#endif
10073
10074
#else
10075
  /* checking if private key with no public part */
10076
0
  if (key->type == ECC_PRIVATEKEY_ONLY) {
10077
0
      WOLFSSL_MSG("Verify called with private key, generating public part");
10078
0
      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10079
0
      if (err != MP_OKAY) {
10080
0
          return err;
10081
0
      }
10082
0
      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10083
0
      if (err != MP_OKAY) {
10084
0
          FREE_CURVE_SPECS();
10085
0
          return err;
10086
0
      }
10087
0
      err = ecc_make_pub_ex(key, curve, NULL, NULL);
10088
0
      if (err != MP_OKAY) {
10089
0
           WOLFSSL_MSG("Unable to extract public key");
10090
0
           wc_ecc_curve_free(curve);
10091
0
           FREE_CURVE_SPECS();
10092
0
           return err;
10093
0
      }
10094
0
      curveLoaded = 1;
10095
0
  }
10096
10097
0
  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
10098
0
  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
10099
0
      if (curveLoaded) {
10100
0
           wc_ecc_curve_free(curve);
10101
0
           FREE_CURVE_SPECS();
10102
0
      }
10103
0
      return err;
10104
0
  }
10105
10106
0
#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
10107
0
   if (!curveLoaded) {
10108
0
       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
10109
0
       if (err != 0) {
10110
0
          return err;
10111
0
       }
10112
       /* read in the specs for this curve */
10113
0
       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
10114
0
       if (err != 0) {
10115
0
          FREE_CURVE_SPECS();
10116
0
          return err;
10117
0
       }
10118
0
   }
10119
10120
0
   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
10121
0
#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
10122
10123
0
   (void)curveLoaded;
10124
0
   wc_ecc_curve_free(curve);
10125
0
   FREE_CURVE_SPECS();
10126
0
#endif /* HAVE_ECC_VERIFY_HELPER */
10127
10128
0
   (void)keySz;
10129
0
   (void)hashlen;
10130
10131
0
   return err;
10132
0
#endif /* WOLFSSL_STM32_PKA */
10133
0
}
10134
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
10135
#endif /* HAVE_ECC_VERIFY */
10136
10137
#ifdef HAVE_ECC_KEY_IMPORT
10138
/* import point from der
10139
 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
10140
int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
10141
                               const int curve_idx, ecc_point* point,
10142
                               int shortKeySize)
10143
0
{
10144
0
    int err = 0;
10145
#ifdef HAVE_COMP_KEY
10146
    int compressed = 0;
10147
#endif
10148
0
    int keysize;
10149
0
    byte pointType;
10150
10151
0
#ifndef HAVE_COMP_KEY
10152
0
    (void)shortKeySize;
10153
0
#endif
10154
10155
0
    if (in == NULL || point == NULL || (curve_idx < 0) ||
10156
0
        (wc_ecc_is_valid_idx(curve_idx) == 0))
10157
0
        return ECC_BAD_ARG_E;
10158
10159
    /* must be odd */
10160
0
    if ((inLen & 1) == 0) {
10161
0
        return ECC_BAD_ARG_E;
10162
0
    }
10163
10164
    /* validate point format byte before any memory operations */
10165
0
    pointType = in[0];
10166
0
    if (pointType != ECC_POINT_UNCOMP &&
10167
0
            pointType != ECC_POINT_COMP_EVEN &&
10168
0
            pointType != ECC_POINT_COMP_ODD) {
10169
0
        return ASN_PARSE_E;
10170
0
    }
10171
10172
    /* clear if previously allocated */
10173
0
    mp_clear(point->x);
10174
0
    mp_clear(point->y);
10175
0
    mp_clear(point->z);
10176
10177
    /* init point */
10178
#ifdef ALT_ECC_SIZE
10179
    point->x = (mp_int*)&point->xyz[0];
10180
    point->y = (mp_int*)&point->xyz[1];
10181
    point->z = (mp_int*)&point->xyz[2];
10182
    alt_fp_init(point->x);
10183
    alt_fp_init(point->y);
10184
    alt_fp_init(point->z);
10185
#else
10186
0
    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
10187
10188
0
    if (err != MP_OKAY)
10189
0
        return MEMORY_E;
10190
0
#endif
10191
10192
    /* pointType already validated above; check for compressed format */
10193
0
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10194
#ifdef HAVE_COMP_KEY
10195
        compressed = 1;
10196
#else
10197
0
        err = NOT_COMPILED_IN;
10198
0
#endif
10199
0
    }
10200
10201
    /* adjust to skip first byte */
10202
0
    inLen -= 1;
10203
0
    in += 1;
10204
10205
    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
10206
     * is true */
10207
#ifdef HAVE_COMP_KEY
10208
    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
10209
#else
10210
0
    keysize = (int)(inLen>>1);
10211
0
#endif
10212
10213
    /* sanity check that x coordinate is expected size */
10214
0
    if (err == MP_OKAY) {
10215
0
        if (keysize != ecc_sets[curve_idx].size) {
10216
0
            err = ECC_BAD_ARG_E;
10217
0
        }
10218
0
    }
10219
10220
    /* read data */
10221
0
    if (err == MP_OKAY)
10222
0
        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
10223
10224
#ifdef HAVE_COMP_KEY
10225
    if (err == MP_OKAY && compressed == 1) {   /* build y */
10226
    #if defined(WOLFSSL_HAVE_SP_ECC)
10227
        #ifndef WOLFSSL_SP_NO_256
10228
        if (curve_idx != ECC_CUSTOM_IDX &&
10229
                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
10230
            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
10231
        }
10232
        else
10233
        #endif
10234
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10235
        if (curve_idx != ECC_CUSTOM_IDX &&
10236
                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
10237
            err = sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
10238
        }
10239
        else
10240
        #endif
10241
        #ifdef WOLFSSL_SP_384
10242
        if (curve_idx != ECC_CUSTOM_IDX &&
10243
                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
10244
            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
10245
        }
10246
        else
10247
        #endif
10248
        #ifdef WOLFSSL_SP_521
10249
        if (curve_idx != ECC_CUSTOM_IDX &&
10250
                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
10251
            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
10252
        }
10253
        else
10254
        #endif
10255
    #endif
10256
    #if !defined(WOLFSSL_SP_MATH)
10257
        {
10258
            int did_init = 0;
10259
        #ifdef WOLFSSL_SMALL_STACK
10260
            mp_int* t1 = NULL;
10261
            mp_int* t2 = NULL;
10262
        #else
10263
            mp_int t1[1], t2[1];
10264
        #endif
10265
            DECLARE_CURVE_SPECS(3);
10266
10267
            ALLOC_CURVE_SPECS(3, err);
10268
10269
        #ifdef WOLFSSL_SMALL_STACK
10270
            if (err == MP_OKAY) {
10271
                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10272
                                      DYNAMIC_TYPE_BIGINT);
10273
                if (t1 == NULL) {
10274
                    err = MEMORY_E;
10275
                }
10276
            }
10277
            if (err == MP_OKAY) {
10278
                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
10279
                                      DYNAMIC_TYPE_BIGINT);
10280
                if (t2 == NULL) {
10281
                    err = MEMORY_E;
10282
                }
10283
            }
10284
        #endif
10285
10286
            if (err == MP_OKAY) {
10287
                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
10288
                    err = MEMORY_E;
10289
                else
10290
                    did_init = 1;
10291
            }
10292
10293
            /* load curve info */
10294
            if (err == MP_OKAY)
10295
                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10296
                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
10297
                        ECC_CURVE_FIELD_BF));
10298
10299
        #if defined(WOLFSSL_CUSTOM_CURVES) && \
10300
            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
10301
            /* validate prime is prime for custom curves */
10302
            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
10303
                int isPrime = MP_NO;
10304
                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
10305
                if (err == MP_OKAY && isPrime == MP_NO)
10306
                    err = MP_VAL;
10307
            }
10308
        #endif
10309
10310
            /* compute x^3 */
10311
            if (err == MP_OKAY)
10312
                err = mp_sqr(point->x, t1);
10313
            if (err == MP_OKAY)
10314
                err = mp_mulmod(t1, point->x, curve->prime, t1);
10315
10316
            /* compute x^3 + a*x */
10317
            if (err == MP_OKAY)
10318
                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
10319
            if (err == MP_OKAY)
10320
                err = mp_add(t1, t2, t1);
10321
10322
            /* compute x^3 + a*x + b */
10323
            if (err == MP_OKAY)
10324
                err = mp_add(t1, curve->Bf, t1);
10325
10326
            /* compute sqrt(x^3 + a*x + b) */
10327
            if (err == MP_OKAY)
10328
                err = mp_sqrtmod_prime(t1, curve->prime, t2);
10329
10330
            /* adjust y */
10331
            if (err == MP_OKAY) {
10332
                if ((mp_isodd(t2) == MP_YES &&
10333
                                            pointType == ECC_POINT_COMP_ODD) ||
10334
                    (mp_isodd(t2) == MP_NO &&
10335
                                            pointType == ECC_POINT_COMP_EVEN)) {
10336
                    err = mp_mod(t2, curve->prime, point->y);
10337
                }
10338
                else {
10339
                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
10340
                }
10341
            }
10342
10343
            if (did_init) {
10344
                mp_clear(t2);
10345
                mp_clear(t1);
10346
            }
10347
10348
            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
10349
            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
10350
10351
            wc_ecc_curve_free(curve);
10352
            FREE_CURVE_SPECS();
10353
        }
10354
    #else
10355
        {
10356
            err = WC_KEY_SIZE_E;
10357
        }
10358
    #endif
10359
    }
10360
#endif
10361
10362
0
    if (err == MP_OKAY) {
10363
#ifdef HAVE_COMP_KEY
10364
        if (compressed == 0)
10365
#endif
10366
0
            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
10367
0
    }
10368
0
    if (err == MP_OKAY)
10369
0
        err = mp_set(point->z, 1);
10370
10371
0
    if (err != MP_OKAY) {
10372
0
        mp_clear(point->x);
10373
0
        mp_clear(point->y);
10374
0
        mp_clear(point->z);
10375
0
    }
10376
10377
0
    return err;
10378
0
}
10379
10380
/* function for backwards compatibility with previous implementations */
10381
int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
10382
                            ecc_point* point)
10383
0
{
10384
0
    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
10385
0
}
10386
#endif /* HAVE_ECC_KEY_IMPORT */
10387
10388
#ifdef HAVE_ECC_KEY_EXPORT
10389
/* export point to der */
10390
10391
int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
10392
                               word32* outLen, int compressed)
10393
0
{
10394
0
    if (compressed == 0)
10395
0
        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
10396
#ifdef HAVE_COMP_KEY
10397
    else
10398
        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
10399
#else
10400
0
    return NOT_COMPILED_IN;
10401
0
#endif
10402
0
}
10403
10404
int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
10405
                            word32* outLen)
10406
0
{
10407
0
    int    ret = MP_OKAY;
10408
0
    word32 numlen;
10409
0
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10410
10411
0
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10412
0
        return ECC_BAD_ARG_E;
10413
10414
0
    numlen = (word32)ecc_sets[curve_idx].size;
10415
10416
    /* return length needed only */
10417
0
    if (point != NULL && out == NULL && outLen != NULL) {
10418
0
        *outLen = 1 + 2*numlen;
10419
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10420
0
    }
10421
10422
0
    if (point == NULL || out == NULL || outLen == NULL)
10423
0
        return ECC_BAD_ARG_E;
10424
10425
0
    if (*outLen < (1 + 2*numlen)) {
10426
0
        *outLen = 1 + 2*numlen;
10427
0
        return BUFFER_E;
10428
0
    }
10429
10430
    /* Sanity check the ordinates' sizes. */
10431
0
    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
10432
0
        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
10433
0
        return ECC_BAD_ARG_E;
10434
0
    }
10435
10436
    /* store byte point type */
10437
0
    out[0] = ECC_POINT_UNCOMP;
10438
10439
0
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10440
0
        return MEMORY_E);
10441
10442
    /* pad and store x */
10443
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
10444
0
    ret = mp_to_unsigned_bin(point->x, buf +
10445
0
        (numlen - (word32)mp_unsigned_bin_size(point->x)));
10446
0
    if (ret != MP_OKAY)
10447
0
        goto done;
10448
0
    XMEMCPY(out+1, buf, numlen);
10449
10450
    /* pad and store y */
10451
0
    XMEMSET(buf, 0, ECC_BUFSIZE);
10452
0
    ret = mp_to_unsigned_bin(point->y, buf +
10453
0
        (numlen - (word32)mp_unsigned_bin_size(point->y)));
10454
0
    if (ret != MP_OKAY)
10455
0
        goto done;
10456
0
    XMEMCPY(out+1+numlen, buf, numlen);
10457
10458
0
    *outLen = 1 + 2*numlen;
10459
10460
0
done:
10461
0
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10462
10463
0
    return ret;
10464
0
}
10465
10466
10467
/* export point to der */
10468
#ifdef HAVE_COMP_KEY
10469
int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
10470
                                       byte* out, word32* outLen)
10471
{
10472
    int    ret = MP_OKAY;
10473
    word32 numlen;
10474
    word32 output_len;
10475
    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10476
10477
    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
10478
        return ECC_BAD_ARG_E;
10479
10480
    numlen = (word32)ecc_sets[curve_idx].size;
10481
    output_len = 1 + numlen; /* y point type + x */
10482
10483
    /* return length needed only */
10484
    if (point != NULL && out == NULL && outLen != NULL) {
10485
        *outLen = output_len;
10486
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10487
    }
10488
10489
    if (point == NULL || out == NULL || outLen == NULL)
10490
        return ECC_BAD_ARG_E;
10491
10492
10493
    if (*outLen < output_len) {
10494
        *outLen = output_len;
10495
        return BUFFER_E;
10496
    }
10497
10498
    /* Sanity check the ordinate's size. */
10499
    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
10500
        return ECC_BAD_ARG_E;
10501
    }
10502
10503
    /* store byte point type */
10504
    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
10505
                                            ECC_POINT_COMP_EVEN;
10506
10507
    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10508
        return MEMORY_E);
10509
10510
    /* pad and store x */
10511
    XMEMSET(buf, 0, ECC_BUFSIZE);
10512
    ret = mp_to_unsigned_bin(point->x, buf +
10513
                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
10514
    if (ret != MP_OKAY)
10515
        goto done;
10516
    XMEMCPY(out+1, buf, numlen);
10517
10518
    *outLen = output_len;
10519
10520
done:
10521
    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10522
10523
    return ret;
10524
}
10525
#endif /* HAVE_COMP_KEY */
10526
10527
/* Software-only export of public ECC key in ANSI X9.63 format.
10528
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
10529
static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10530
0
{
10531
0
   int    ret = MP_OKAY;
10532
0
   word32 numlen;
10533
0
   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10534
0
   word32 pubxlen, pubylen;
10535
10536
   /* return length needed only */
10537
0
   if (key != NULL && out == NULL && outLen != NULL) {
10538
      /* if key hasn't been setup assume max bytes for size estimation */
10539
0
      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10540
      /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10541
0
      *outLen = 1 + 2 * numlen;
10542
0
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10543
0
   }
10544
10545
0
   if (key == NULL || out == NULL || outLen == NULL) {
10546
0
      return ECC_BAD_ARG_E;
10547
0
   }
10548
10549
0
   if (key->type == ECC_PRIVATEKEY_ONLY) {
10550
0
       return ECC_PRIVATEONLY_E;
10551
0
   }
10552
10553
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10554
    /* check if public key in secure memory */
10555
    if (key->securePubKey > 0) {
10556
        int keySz = wc_ecc_size(key);
10557
10558
        /* store byte point type */
10559
        out[0] = ECC_POINT_UNCOMP;
10560
10561
        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
10562
            return WC_HW_E;
10563
10564
        *outLen = 1 + 2*keySz;
10565
        return MP_OKAY;
10566
    }
10567
#endif
10568
10569
0
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
10570
0
       return ECC_BAD_ARG_E;
10571
0
   }
10572
10573
0
   numlen = (word32)key->dp->size;
10574
10575
    /* verify room in out buffer */
10576
0
   if (*outLen < (1 + 2*numlen)) {
10577
0
      *outLen = 1 + 2*numlen;
10578
0
      return BUFFER_E;
10579
0
   }
10580
10581
   /* verify public key length is less than key size */
10582
0
   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
10583
0
   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
10584
0
   if ((pubxlen > numlen) || (pubylen > numlen)) {
10585
0
      WOLFSSL_MSG("Public key x/y invalid!");
10586
0
      return BUFFER_E;
10587
0
   }
10588
10589
   /* store byte point type */
10590
0
   out[0] = ECC_POINT_UNCOMP;
10591
10592
0
   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10593
0
       return MEMORY_E);
10594
10595
   /* pad and store x */
10596
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
10597
0
   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
10598
0
   if (ret != MP_OKAY)
10599
0
      goto done;
10600
0
   XMEMCPY(out+1, buf, numlen);
10601
10602
   /* pad and store y */
10603
0
   XMEMSET(buf, 0, ECC_BUFSIZE);
10604
0
   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
10605
0
   if (ret != MP_OKAY)
10606
0
      goto done;
10607
0
   XMEMCPY(out+1+numlen, buf, numlen);
10608
10609
0
   *outLen = 1 + 2*numlen;
10610
10611
0
done:
10612
0
   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10613
10614
0
   return ret;
10615
0
}
10616
10617
10618
/* export public ECC key in ANSI X9.63 format */
10619
WOLFSSL_ABI
10620
int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10621
0
{
10622
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10623
    int ret;
10624
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
10625
#endif
10626
10627
0
    if (key == NULL || outLen == NULL) {
10628
0
        return ECC_BAD_ARG_E;
10629
0
    }
10630
10631
    /* return length needed only */
10632
0
    if (out == NULL) {
10633
0
        word32 numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10634
        /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10635
0
        *outLen = 1 + 2 * numlen;
10636
0
        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10637
0
    }
10638
10639
0
    if (key->type == ECC_PRIVATEKEY_ONLY) {
10640
0
        return ECC_PRIVATEONLY_E;
10641
0
    }
10642
10643
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10644
    #ifndef WOLF_CRYPTO_CB_FIND
10645
    if (key->devId != INVALID_DEVID)
10646
    #endif
10647
    {
10648
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
10649
        if (!WC_VAR_OK(tmpKey)) {
10650
            return MEMORY_E;
10651
        }
10652
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
10653
10654
        ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
10655
        if (ret != 0) {
10656
            WC_FREE_VAR(tmpKey, key->heap);
10657
            return ret;
10658
        }
10659
10660
        ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
10661
                                     key, tmpKey);
10662
        if (ret == 0) {
10663
            /* Call software helper (no callback recursion) */
10664
            ret = _ecc_export_x963(tmpKey, out, outLen);
10665
        }
10666
10667
        wc_ecc_free(tmpKey);
10668
        WC_FREE_VAR(tmpKey, key->heap);
10669
10670
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
10671
            return ret;
10672
        }
10673
    }
10674
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
10675
10676
0
    return _ecc_export_x963(key, out, outLen);
10677
0
}
10678
10679
/* export public ECC key in ANSI X9.63 format, extended with
10680
 * compression option */
10681
WOLFSSL_ABI
10682
int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
10683
                          int compressed)
10684
0
{
10685
0
    if (compressed == 0) {
10686
0
        return wc_ecc_export_x963(key, out, outLen);
10687
0
    }
10688
#ifdef HAVE_COMP_KEY
10689
    else
10690
        return wc_ecc_export_x963_compressed(key, out, outLen);
10691
#else
10692
0
    return NOT_COMPILED_IN;
10693
0
#endif
10694
0
}
10695
#endif /* HAVE_ECC_KEY_EXPORT */
10696
10697
10698
/* is ecc point on curve described by dp ? */
10699
static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10700
1.04k
{
10701
1.04k
#if !defined(WOLFSSL_SP_MATH)
10702
1.04k
   int err;
10703
#ifdef WOLFSSL_SMALL_STACK
10704
   mp_int* t1;
10705
   mp_int* t2;
10706
#else
10707
1.04k
   mp_int  t1[1], t2[1];
10708
1.04k
#endif
10709
10710
#ifdef WOLFSSL_SMALL_STACK
10711
   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10712
   if (t1 == NULL)
10713
       return MEMORY_E;
10714
   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10715
   if (t2 == NULL) {
10716
       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
10717
       return MEMORY_E;
10718
   }
10719
#endif
10720
10721
1.04k
   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
10722
0
      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10723
0
      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10724
0
      return err;
10725
0
   }
10726
10727
   /* compute y^2 */
10728
1.04k
   if (err == MP_OKAY)
10729
1.04k
       err = mp_sqr(ecp->y, t1);
10730
10731
   /* compute x^3 */
10732
1.04k
   if (err == MP_OKAY)
10733
1.04k
       err = mp_sqr(ecp->x, t2);
10734
1.04k
   if (err == MP_OKAY)
10735
1.04k
       err = mp_mod(t2, prime, t2);
10736
1.04k
   if (err == MP_OKAY)
10737
1.04k
       err = mp_mul(ecp->x, t2, t2);
10738
10739
   /* compute y^2 - x^3 */
10740
1.04k
   if (err == MP_OKAY)
10741
1.04k
       err = mp_submod(t1, t2, prime, t1);
10742
10743
   /* Determine if curve "a" should be used in calc */
10744
#ifdef WOLFSSL_CUSTOM_CURVES
10745
   if (err == MP_OKAY) {
10746
      /* Use a and prime to determine if a == 3 */
10747
      err = mp_set(t2, 0);
10748
      if (err == MP_OKAY)
10749
          err = mp_submod(prime, a, prime, t2);
10750
   }
10751
   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
10752
      /* compute y^2 - x^3 + a*x */
10753
      if (err == MP_OKAY)
10754
          err = mp_mulmod(t2, ecp->x, prime, t2);
10755
      if (err == MP_OKAY)
10756
          err = mp_addmod(t1, t2, prime, t1);
10757
   }
10758
   else
10759
#endif /* WOLFSSL_CUSTOM_CURVES */
10760
1.04k
   {
10761
      /* assumes "a" == 3 */
10762
1.04k
      (void)a;
10763
10764
      /* compute y^2 - x^3 + 3x */
10765
1.04k
      if (err == MP_OKAY)
10766
1.04k
          err = mp_add(t1, ecp->x, t1);
10767
1.04k
      if (err == MP_OKAY)
10768
1.04k
          err = mp_add(t1, ecp->x, t1);
10769
1.04k
      if (err == MP_OKAY)
10770
1.04k
          err = mp_add(t1, ecp->x, t1);
10771
1.04k
      if (err == MP_OKAY)
10772
1.04k
          err = mp_mod(t1, prime, t1);
10773
1.04k
  }
10774
10775
   /* adjust range (0, prime) */
10776
1.04k
   while (err == MP_OKAY && mp_isneg(t1)) {
10777
0
      err = mp_add(t1, prime, t1);
10778
0
   }
10779
1.04k
   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
10780
0
      err = mp_sub(t1, prime, t1);
10781
0
   }
10782
10783
   /* compare to b */
10784
1.04k
   if (err == MP_OKAY) {
10785
1.04k
       if (mp_cmp(t1, b) != MP_EQ) {
10786
1.04k
          err = IS_POINT_E;
10787
1.04k
       } else {
10788
0
          err = MP_OKAY;
10789
0
       }
10790
1.04k
   }
10791
10792
1.04k
   mp_clear(t1);
10793
1.04k
   mp_clear(t2);
10794
10795
1.04k
   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10796
1.04k
   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10797
10798
1.04k
   return err;
10799
#else
10800
   (void)a;
10801
   (void)b;
10802
10803
#ifdef WOLFSSL_HAVE_SP_ECC
10804
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10805
   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10806
       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10807
   }
10808
#endif
10809
#ifndef WOLFSSL_SP_NO_256
10810
   if (mp_count_bits(prime) == 256) {
10811
       return sp_ecc_is_point_256(ecp->x, ecp->y);
10812
   }
10813
#endif
10814
#ifdef WOLFSSL_SP_384
10815
   if (mp_count_bits(prime) == 384) {
10816
       return sp_ecc_is_point_384(ecp->x, ecp->y);
10817
   }
10818
#endif
10819
#ifdef WOLFSSL_SP_521
10820
   if (mp_count_bits(prime) == 521) {
10821
       return sp_ecc_is_point_521(ecp->x, ecp->y);
10822
   }
10823
#endif
10824
#else
10825
   (void)ecp;
10826
   (void)prime;
10827
#endif
10828
   return WC_KEY_SIZE_E;
10829
#endif
10830
1.04k
}
10831
10832
int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10833
1.05k
{
10834
1.05k
    int err = MP_OKAY;
10835
10836
    /* Validate parameters. */
10837
1.05k
    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10838
0
        err = BAD_FUNC_ARG;
10839
0
    }
10840
10841
1.05k
    if (err == MP_OKAY) {
10842
        /* x must be in the range [0, p-1] */
10843
1.05k
        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10844
3
            err = ECC_OUT_OF_RANGE_E;
10845
3
        }
10846
1.05k
    }
10847
10848
1.05k
    if (err == MP_OKAY) {
10849
        /* y must be in the range [0, p-1] */
10850
1.05k
        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10851
3
            err = ECC_OUT_OF_RANGE_E;
10852
3
        }
10853
1.05k
    }
10854
10855
1.05k
    if (err == MP_OKAY) {
10856
        /* z must be one, that is point must be in affine form. */
10857
1.04k
        if (!mp_isone(ecp->z)) {
10858
0
            err = ECC_BAD_ARG_E;
10859
0
        }
10860
1.04k
    }
10861
10862
1.05k
    if (err == MP_OKAY) {
10863
        /* Check x and y are valid for curve equation. */
10864
1.04k
        err = _ecc_is_point(ecp, a, b, prime);
10865
1.04k
    }
10866
10867
1.05k
    return err;
10868
1.05k
}
10869
10870
#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
10871
10872
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10873
    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10874
    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10875
/* validate privkey * generator == pubkey, 0 on success */
10876
static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10877
{
10878
    int        err;
10879
    ecc_point* base = NULL;
10880
    ecc_point* res  = NULL;
10881
#ifdef WOLFSSL_NO_MALLOC
10882
    ecc_point lcl_base;
10883
    ecc_point lcl_res;
10884
#endif
10885
    DECLARE_CURVE_SPECS(3);
10886
10887
    if (key == NULL)
10888
        return BAD_FUNC_ARG;
10889
10890
    ALLOC_CURVE_SPECS(3, err);
10891
    if (err != MP_OKAY) {
10892
        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10893
        return err;
10894
    }
10895
10896
#ifdef WOLFSSL_NO_MALLOC
10897
    res = &lcl_res;
10898
#endif
10899
    err = wc_ecc_new_point_ex(&res, key->heap);
10900
10901
#ifdef WOLFSSL_HAVE_SP_ECC
10902
#ifndef WOLFSSL_SP_NO_256
10903
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10904
        if (err == MP_OKAY) {
10905
            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10906
        }
10907
    }
10908
    else
10909
#endif
10910
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10911
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10912
        if (err == MP_OKAY) {
10913
            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10914
        }
10915
    }
10916
    else
10917
#endif
10918
#ifdef WOLFSSL_SP_384
10919
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10920
        if (err == MP_OKAY) {
10921
            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10922
        }
10923
    }
10924
    else
10925
#endif
10926
#ifdef WOLFSSL_SP_521
10927
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10928
        if (err == MP_OKAY) {
10929
            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10930
        }
10931
    }
10932
    else
10933
#endif
10934
#endif
10935
    {
10936
        if (err == MP_OKAY) {
10937
        #ifdef WOLFSSL_NO_MALLOC
10938
            base = &lcl_base;
10939
        #endif
10940
            err = wc_ecc_new_point_ex(&base, key->heap);
10941
        }
10942
10943
        if (err == MP_OKAY) {
10944
            /* load curve info */
10945
            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10946
                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10947
        }
10948
10949
        /* set up base generator */
10950
        if (err == MP_OKAY)
10951
            err = mp_copy(curve->Gx, base->x);
10952
        if (err == MP_OKAY)
10953
            err = mp_copy(curve->Gy, base->y);
10954
        if (err == MP_OKAY)
10955
            err = mp_set(base->z, 1);
10956
10957
#ifdef WOLFSSL_KCAPI_ECC
10958
        if (err == MP_OKAY) {
10959
            word32 pubkey_sz = (word32)key->dp->size*2;
10960
            if (key->handle == NULL) {
10961
                /* if handle loaded, then pubkey_raw already populated */
10962
                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10963
            }
10964
            if (err == 0) {
10965
                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10966
                                           pubkey_sz/2);
10967
            }
10968
            if (err == MP_OKAY) {
10969
                err = mp_read_unsigned_bin(res->y,
10970
                                           key->pubkey_raw + pubkey_sz/2,
10971
                                           pubkey_sz/2);
10972
            }
10973
            if (err == MP_OKAY) {
10974
                err = mp_set(res->z, 1);
10975
            }
10976
        }
10977
        (void)a;
10978
        (void)prime;
10979
#else
10980
#ifdef ECC_TIMING_RESISTANT
10981
        if (err == MP_OKAY)
10982
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10983
                                          curve->order, key->rng, 1, key->heap);
10984
#else
10985
        if (err == MP_OKAY)
10986
            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10987
                                              curve->order, NULL, 1, key->heap);
10988
#endif
10989
#endif /* WOLFSSL_KCAPI_ECC */
10990
    }
10991
10992
    if (err == MP_OKAY) {
10993
        /* compare result to public key */
10994
        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10995
            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10996
            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10997
            /* didn't match */
10998
            err = ECC_PRIV_KEY_E;
10999
        }
11000
    }
11001
11002
    wc_ecc_curve_free(curve);
11003
    wc_ecc_del_point_ex(res, key->heap);
11004
    wc_ecc_del_point_ex(base, key->heap);
11005
    FREE_CURVE_SPECS();
11006
11007
    return err;
11008
}
11009
#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
11010
        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
11011
11012
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
11013
    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
11014
11015
/* check privkey generator helper, creates prime needed */
11016
static int ecc_check_privkey_gen_helper(ecc_key* key)
11017
{
11018
    int    err;
11019
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11020
    !defined(WOLFSSL_MICROCHIP_TA100)
11021
    DECLARE_CURVE_SPECS(2);
11022
#endif
11023
11024
    if (key == NULL)
11025
        return BAD_FUNC_ARG;
11026
11027
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11028
    defined(WOLFSSL_MICROCHIP_TA100)
11029
    /* Hardware based private key, so this operation is not supported */
11030
    err = MP_OKAY; /* just report success */
11031
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11032
    /* Hardware based private key, so this operation is not supported */
11033
    err = MP_OKAY; /* just report success */
11034
#elif defined(WOLFSSL_KCAPI_ECC)
11035
    /* Hardware based private key, so this operation is not supported */
11036
    err = MP_OKAY; /* just report success */
11037
#else
11038
    ALLOC_CURVE_SPECS(2, err);
11039
11040
    /* load curve info */
11041
    if (err == MP_OKAY)
11042
        err = wc_ecc_curve_load(key->dp, &curve,
11043
            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
11044
11045
    if (err == MP_OKAY)
11046
        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11047
11048
    wc_ecc_curve_free(curve);
11049
    FREE_CURVE_SPECS();
11050
11051
#endif /* WOLFSSL_ATECC508A */
11052
11053
    return err;
11054
}
11055
11056
/* Performs a Pairwise Consistency Test on an ECC key pair. */
11057
static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
11058
{
11059
    int err = 0;
11060
    word32 flags = key->flags;
11061
11062
    /* If flags not set default to cofactor and dec/sign */
11063
    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
11064
        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
11065
    }
11066
11067
    if (flags & WC_ECC_FLAG_COFACTOR) {
11068
        err = ecc_check_privkey_gen_helper(key);
11069
    }
11070
11071
    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
11072
#ifndef WOLFSSL_SMALL_STACK
11073
        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
11074
        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
11075
#else
11076
        byte* sig;
11077
#endif
11078
        byte* digest;
11079
        word32 sigLen, digestLen;
11080
        int dynRng = 0, res = 0;
11081
11082
        sigLen = (word32)wc_ecc_sig_size(key);
11083
        digestLen = WC_SHA256_DIGEST_SIZE;
11084
        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
11085
            DYNAMIC_TYPE_ECC, return MEMORY_E);
11086
        digest = sig + sigLen;
11087
11088
        if (rng == NULL) {
11089
            dynRng = 1;
11090
            rng = wc_rng_new(NULL, 0, key->heap);
11091
            if (rng == NULL) {
11092
                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11093
                return MEMORY_E;
11094
            }
11095
        }
11096
11097
        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
11098
11099
        if (!err)
11100
            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
11101
                    rng, key);
11102
        if (!err)
11103
            err = wc_ecc_verify_hash(sig, sigLen,
11104
                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
11105
11106
        if (res == 0)
11107
            err = ECC_PCT_E;
11108
11109
        if (dynRng) {
11110
            wc_rng_free(rng);
11111
        }
11112
        ForceZero(sig, sigLen + digestLen);
11113
        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
11114
    }
11115
    (void)rng;
11116
11117
    if (err != 0)
11118
        err = ECC_PCT_E;
11119
11120
    return err;
11121
}
11122
#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
11123
          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
11124
11125
#ifndef WOLFSSL_SP_MATH
11126
/* validate order * pubkey = point at infinity, 0 on success */
11127
static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
11128
        mp_int* prime, mp_int* order)
11129
0
{
11130
0
    ecc_point* inf = NULL;
11131
#ifdef WOLFSSL_NO_MALLOC
11132
    ecc_point  lcl_inf;
11133
#endif
11134
0
    int err;
11135
11136
0
    if (key == NULL)
11137
0
        return BAD_FUNC_ARG;
11138
0
   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
11139
0
       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
11140
0
       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
11141
0
       return IS_POINT_E;
11142
0
   }
11143
11144
#ifdef WOLFSSL_NO_MALLOC
11145
    inf = &lcl_inf;
11146
#endif
11147
0
    err = wc_ecc_new_point_ex(&inf, key->heap);
11148
0
    if (err == MP_OKAY) {
11149
#ifdef WOLFSSL_HAVE_SP_ECC
11150
#ifndef WOLFSSL_SP_NO_256
11151
        if (key->idx != ECC_CUSTOM_IDX &&
11152
                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
11153
            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
11154
        }
11155
        else
11156
#endif
11157
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11158
        if (key->idx != ECC_CUSTOM_IDX &&
11159
                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
11160
            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
11161
        }
11162
        else
11163
#endif
11164
#ifdef WOLFSSL_SP_384
11165
        if (key->idx != ECC_CUSTOM_IDX &&
11166
                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
11167
            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
11168
        }
11169
        else
11170
#endif
11171
#ifdef WOLFSSL_SP_521
11172
        if (key->idx != ECC_CUSTOM_IDX &&
11173
                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
11174
            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
11175
        }
11176
        else
11177
#endif
11178
#endif
11179
0
#if !defined(WOLFSSL_SP_MATH)
11180
0
            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
11181
0
        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
11182
0
            err = ECC_INF_E;
11183
#else
11184
        {
11185
            (void)a;
11186
            (void)prime;
11187
11188
            err = WC_KEY_SIZE_E;
11189
        }
11190
#endif
11191
0
    }
11192
11193
0
    wc_ecc_del_point_ex(inf, key->heap);
11194
11195
0
    return err;
11196
0
}
11197
#endif /* !WOLFSSL_SP_MATH */
11198
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11199
11200
11201
#ifdef OPENSSL_EXTRA
11202
int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
11203
{
11204
    int err = MP_OKAY;
11205
    DECLARE_CURVE_SPECS(2);
11206
11207
    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
11208
        return BAD_FUNC_ARG;
11209
11210
    ALLOC_CURVE_SPECS(2, err);
11211
11212
    if (err == MP_OKAY)
11213
        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
11214
                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
11215
    if (err == MP_OKAY)
11216
        err = mp_copy(curve->Gx, ecp->x);
11217
    if (err == MP_OKAY)
11218
        err = mp_copy(curve->Gy, ecp->y);
11219
    if (err == MP_OKAY)
11220
        err = mp_set(ecp->z, 1);
11221
11222
    wc_ecc_curve_free(curve);
11223
    FREE_CURVE_SPECS();
11224
11225
    return err;
11226
}
11227
#endif /* OPENSSL_EXTRA */
11228
11229
11230
/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
11231
 * ECC Full Public Key Validation Routine. If the parameter
11232
 * partial is set, then it follows section 5.6.2.3.4, the ECC
11233
 * Partial Public Key Validation Routine.
11234
 * If the parameter priv is set, add in a few extra
11235
 * checks on the bounds of the private key. */
11236
static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
11237
0
{
11238
0
    int err = MP_OKAY;
11239
0
#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
11240
0
    mp_int* b = NULL;
11241
0
    DECLARE_CURVE_SPECS(4);
11242
0
#endif
11243
11244
0
    if (key == NULL)
11245
0
        return BAD_FUNC_ARG;
11246
11247
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_CHECK_KEY) && \
11248
    !defined(WOLFSSL_CAAM)
11249
    /* Device-first: when a device is configured, let it validate the public
11250
     * key. Fall through to the software/HW path below only when the
11251
     * device reports the operation unavailable.
11252
     * CAAM is excluded: it relies on the software order-check below to detect
11253
     * whether an imported private key is an encrypted black key. */
11254
    #ifndef WOLF_CRYPTO_CB_FIND
11255
    if (key->devId != INVALID_DEVID)
11256
    #endif
11257
    {
11258
        err = wc_CryptoCb_EccCheckPubKey(key, !partial, priv);
11259
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
11260
            return err;
11261
        /* device declined; fall through. Every software/HW path below
11262
         * re-initializes err before reading it, so no reset is needed here. */
11263
    }
11264
#endif
11265
11266
#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
11267
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
11268
    /* Software validation is stripped; the device-first check above either
11269
     * handled the key or reported the op unavailable, so fail closed rather
11270
     * than accept an unvalidated key. */
11271
    err = NO_VALID_DEVID;
11272
#else
11273
    /* consider key check success on HW crypto
11274
     * ex: ATECC508/608A, CryptoCell and Silabs which validate the key
11275
     * internally
11276
     */
11277
    err = MP_OKAY;
11278
#endif
11279
11280
#else
11281
11282
#ifdef WOLFSSL_HAVE_SP_ECC
11283
#ifndef WOLFSSL_SP_NO_256
11284
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
11285
        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
11286
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11287
    }
11288
#endif
11289
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11290
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
11291
        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
11292
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11293
    }
11294
#endif
11295
#ifdef WOLFSSL_SP_384
11296
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
11297
        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
11298
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11299
    }
11300
#endif
11301
#ifdef WOLFSSL_SP_521
11302
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
11303
        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
11304
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11305
    }
11306
#endif
11307
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
11308
    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
11309
        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
11310
            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
11311
    }
11312
#endif
11313
#endif
11314
11315
0
#ifndef WOLFSSL_SP_MATH
11316
0
    ALLOC_CURVE_SPECS(4, err);
11317
11318
    #ifdef WOLFSSL_CAAM
11319
    /* keys can be black encrypted ones which can not be checked like plain text
11320
     * keys */
11321
    if (key->blackKey > 0) {
11322
        /* encrypted key was used */
11323
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11324
        FREE_CURVE_SPECS();
11325
        return 0;
11326
    }
11327
    #endif
11328
11329
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
11330
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
11331
    /* pubkey point cannot be at infinity */
11332
0
    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11333
0
        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
11334
0
        FREE_CURVE_SPECS();
11335
0
        return ECC_INF_E;
11336
0
    }
11337
11338
    /* load curve info */
11339
0
    if (err == MP_OKAY)
11340
0
        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
11341
0
            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER | ECC_CURVE_FIELD_BF));
11342
11343
0
    if (err == MP_OKAY)
11344
0
        b = curve->Bf;
11345
11346
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
11347
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
11348
    /* Qx must be in the range [0, p-1] */
11349
0
    if (err == MP_OKAY) {
11350
0
        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
11351
0
                mp_isneg(key->pubkey.x)) {
11352
0
            err = ECC_OUT_OF_RANGE_E;
11353
0
        }
11354
0
    }
11355
11356
    /* Qy must be in the range [0, p-1] */
11357
0
    if (err == MP_OKAY) {
11358
0
        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
11359
0
                mp_isneg(key->pubkey.y)) {
11360
0
            err = ECC_OUT_OF_RANGE_E;
11361
0
        }
11362
0
    }
11363
11364
    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
11365
    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
11366
    /* make sure point is actually on curve */
11367
0
    if (err == MP_OKAY)
11368
0
        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
11369
11370
0
    if (!partial) {
11371
        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
11372
        /* pubkey * order must be at infinity */
11373
0
        if (err == MP_OKAY)
11374
0
            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
11375
0
                    curve->prime, curve->order);
11376
0
    }
11377
11378
0
    if (priv) {
11379
        /* SP 800-56Ar3, section 5.6.2.1.2 */
11380
        /* private keys must be in the range [1, n-1] */
11381
0
        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
11382
0
            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
11383
0
            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
11384
        #ifdef WOLFSSL_KCAPI_ECC
11385
            && key->handle == NULL
11386
        #endif
11387
0
        ) {
11388
0
            err = ECC_PRIV_KEY_E;
11389
0
        }
11390
11391
    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
11392
        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
11393
        /* private * base generator must equal pubkey */
11394
        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
11395
            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
11396
    #endif
11397
0
    }
11398
11399
0
    wc_ecc_curve_free(curve);
11400
11401
0
    FREE_CURVE_SPECS();
11402
11403
#else
11404
    /* The single precision math curve is not available */
11405
    err = WC_KEY_SIZE_E;
11406
#endif /* !WOLFSSL_SP_MATH */
11407
0
#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
11408
11409
0
    (void)partial;
11410
0
    (void)priv;
11411
0
    return err;
11412
0
}
11413
11414
11415
/* perform sanity checks on ecc key validity, 0 on success */
11416
WOLFSSL_ABI
11417
int wc_ecc_check_key(ecc_key* key)
11418
0
{
11419
0
    int ret;
11420
    /* _ecc_validate_public_key is the single validation entry point: it is
11421
     * device-first (offloads to the crypto callback when a device is
11422
     * configured) and otherwise runs the software/HW checks, or fails closed
11423
     * under WOLF_CRYPTO_CB_ONLY_ECC. */
11424
0
    ret = _ecc_validate_public_key(key, 0, 1);
11425
0
    return ret;
11426
0
}
11427
11428
11429
#ifdef HAVE_ECC_KEY_IMPORT
11430
/* Software-only import of public ECC key in ANSI X9.63 format.
11431
 * This internal helper avoids recursion when called from the SETKEY path. */
11432
static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11433
                                int curve_id, int untrusted)
11434
1.07k
{
11435
1.07k
    int err = MP_OKAY;
11436
#ifdef HAVE_COMP_KEY
11437
    int compressed = 0;
11438
#endif
11439
1.07k
    int keysize = 0;
11440
1.07k
    byte pointType;
11441
#ifdef WOLFSSL_CRYPTOCELL
11442
    const CRYS_ECPKI_Domain_t* pDomain;
11443
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11444
#endif
11445
11446
1.07k
    if (in == NULL || key == NULL) {
11447
0
        return BAD_FUNC_ARG;
11448
0
    }
11449
11450
    /* must be odd */
11451
1.07k
    if ((inLen & 1) == 0) {
11452
0
        return ECC_BAD_ARG_E;
11453
0
    }
11454
11455
    /* make sure required variables are reset */
11456
1.07k
    wc_ecc_reset(key);
11457
11458
    /* init key */
11459
    #ifdef ALT_ECC_SIZE
11460
        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11461
        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11462
        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11463
        alt_fp_init(key->pubkey.x);
11464
        alt_fp_init(key->pubkey.y);
11465
        alt_fp_init(key->pubkey.z);
11466
        key->k = (mp_int*)key->ka;
11467
        alt_fp_init(key->k);
11468
    #ifdef WOLFSSL_ECC_BLIND_K
11469
        key->kb = (mp_int*)key->kba;
11470
        key->ku = (mp_int*)key->kua;
11471
        alt_fp_init(key->kb);
11472
        alt_fp_init(key->ku);
11473
    #endif
11474
    #else
11475
1.07k
        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
11476
1.07k
    #ifndef WOLFSSL_ECC_BLIND_K
11477
1.07k
                                                                      NULL, NULL
11478
    #else
11479
                                                                key->kb, key->ku
11480
    #endif
11481
1.07k
                            );
11482
11483
1.07k
        if (err != MP_OKAY)
11484
0
            return MEMORY_E;
11485
1.07k
    #endif
11486
#ifdef WOLFSSL_ECC_BLIND_K
11487
    mp_forcezero(key->kb);
11488
#endif
11489
11490
    /* check for point type (4, 2, or 3) */
11491
1.07k
    pointType = in[0];
11492
1.07k
    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
11493
19
                                         pointType != ECC_POINT_COMP_ODD) {
11494
18
        err = ASN_PARSE_E;
11495
18
    }
11496
11497
1.07k
    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
11498
    #ifdef HAVE_COMP_KEY
11499
        compressed = 1;
11500
    #else
11501
2
        err = NOT_COMPILED_IN;
11502
2
    #endif
11503
2
    }
11504
11505
    /* adjust to skip first byte */
11506
1.07k
    inLen -= 1;
11507
1.07k
    in += 1;
11508
11509
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11510
    defined(WOLFSSL_MICROCHIP_TA100)
11511
    /* For SECP256R1 only save raw public key for hardware */
11512
    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
11513
    #ifdef HAVE_COMP_KEY
11514
        if (!compressed)
11515
    #endif
11516
            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11517
    }
11518
#elif defined(WOLFSSL_KCAPI_ECC)
11519
    if (inLen <= (word32)sizeof(key->pubkey_raw))
11520
        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
11521
    else
11522
        err = BAD_FUNC_ARG;
11523
#endif
11524
11525
1.07k
    if (err == MP_OKAY) {
11526
    #ifdef HAVE_COMP_KEY
11527
        /* adjust inLen if compressed */
11528
        if (compressed) {
11529
            /* a compressed coordinate cannot exceed MAX_ECC_BYTES; bound it
11530
             * before doubling so inLen*2 + 1 cannot overflow word32. */
11531
            if (inLen > MAX_ECC_BYTES)
11532
                err = ECC_BAD_ARG_E;
11533
            else
11534
                inLen = inLen*2 + 1;  /* used uncompressed len */
11535
        }
11536
    #endif
11537
11538
        /* determine key size */
11539
1.05k
        if (err == MP_OKAY) {
11540
1.05k
            keysize = (int)(inLen>>1);
11541
            /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys,
11542
             *       only on created keys or signatures */
11543
1.05k
            err = wc_ecc_set_curve(key, keysize, curve_id);
11544
1.05k
            key->type = ECC_PUBLICKEY;
11545
1.05k
        }
11546
1.05k
    }
11547
11548
    /* read data */
11549
1.07k
    if (err == MP_OKAY)
11550
1.05k
        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
11551
11552
#ifdef HAVE_COMP_KEY
11553
    if (err == MP_OKAY && compressed == 1) {   /* build y */
11554
#if !defined(WOLFSSL_SP_MATH)
11555
    #ifdef WOLFSSL_SMALL_STACK
11556
        mp_int* t1 = NULL;
11557
        mp_int* t2 = NULL;
11558
    #else
11559
        mp_int t1[1], t2[1];
11560
    #endif
11561
        int did_init = 0;
11562
11563
        DECLARE_CURVE_SPECS(3);
11564
        ALLOC_CURVE_SPECS(3, err);
11565
11566
        #ifdef WOLFSSL_SMALL_STACK
11567
        if (err == MP_OKAY) {
11568
            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11569
            if (t1 == NULL) {
11570
                err = MEMORY_E;
11571
            }
11572
        }
11573
        if (err == MP_OKAY) {
11574
            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11575
            if (t2 == NULL) {
11576
                err = MEMORY_E;
11577
            }
11578
        }
11579
        #endif
11580
        if (err == MP_OKAY) {
11581
            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
11582
                err = MEMORY_E;
11583
            else
11584
                did_init = 1;
11585
        }
11586
11587
        /* load curve info */
11588
        if (err == MP_OKAY)
11589
            err = wc_ecc_curve_load(key->dp, &curve,
11590
                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
11591
                 ECC_CURVE_FIELD_BF));
11592
11593
    #if defined(WOLFSSL_CUSTOM_CURVES) && \
11594
        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
11595
        /* validate prime is prime for custom curves */
11596
        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
11597
            int isPrime = MP_NO;
11598
            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
11599
            if (err == MP_OKAY && isPrime == MP_NO)
11600
                err = MP_VAL;
11601
        }
11602
    #endif
11603
11604
        /* compute x^3 */
11605
        if (err == MP_OKAY)
11606
            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
11607
        if (err == MP_OKAY)
11608
            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
11609
11610
        /* compute x^3 + a*x */
11611
        if (err == MP_OKAY)
11612
            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
11613
        if (err == MP_OKAY)
11614
            err = mp_add(t1, t2, t1);
11615
11616
        /* compute x^3 + a*x + b */
11617
        if (err == MP_OKAY)
11618
            err = mp_add(t1, curve->Bf, t1);
11619
11620
        /* compute sqrt(x^3 + a*x + b) */
11621
        if (err == MP_OKAY)
11622
            err = mp_sqrtmod_prime(t1, curve->prime, t2);
11623
11624
        /* adjust y */
11625
        if (err == MP_OKAY) {
11626
            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
11627
                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
11628
                err = mp_mod(t2, curve->prime, t2);
11629
            }
11630
            else {
11631
                err = mp_submod(curve->prime, t2, curve->prime, t2);
11632
            }
11633
            if (err == MP_OKAY)
11634
                err = mp_copy(t2, key->pubkey.y);
11635
        }
11636
11637
        if (did_init) {
11638
            mp_clear(t2);
11639
            mp_clear(t1);
11640
        }
11641
        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
11642
        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
11643
11644
        wc_ecc_curve_free(curve);
11645
        FREE_CURVE_SPECS();
11646
#else
11647
    #ifndef WOLFSSL_SP_NO_256
11648
        if (key->dp->id == ECC_SECP256R1) {
11649
            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
11650
                key->pubkey.y);
11651
        }
11652
        else
11653
    #endif
11654
    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11655
        if (key->dp->id == ECC_SM2P256V1) {
11656
            err = sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
11657
        }
11658
        else
11659
    #endif
11660
    #ifdef WOLFSSL_SP_384
11661
        if (key->dp->id == ECC_SECP384R1) {
11662
            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
11663
                key->pubkey.y);
11664
        }
11665
        else
11666
    #endif
11667
    #ifdef WOLFSSL_SP_521
11668
        if (key->dp->id == ECC_SECP521R1) {
11669
            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
11670
                key->pubkey.y);
11671
        }
11672
        else
11673
    #endif
11674
        {
11675
            err = WC_KEY_SIZE_E;
11676
        }
11677
#endif
11678
    }
11679
#endif /* HAVE_COMP_KEY */
11680
11681
1.07k
    if (err == MP_OKAY) {
11682
    #ifdef HAVE_COMP_KEY
11683
        if (compressed == 0)
11684
    #endif
11685
1.05k
        {
11686
1.05k
            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
11687
1.05k
                (word32)keysize);
11688
1.05k
        }
11689
1.05k
    }
11690
1.07k
    if (err == MP_OKAY)
11691
1.05k
        err = mp_set(key->pubkey.z, 1);
11692
11693
#ifdef WOLFSSL_CRYPTOCELL
11694
    if (err == MP_OKAY) {
11695
        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11696
11697
        /* create public key from external key buffer */
11698
        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11699
                                               (byte*)in-1, /* re-adjust */
11700
                                               inLen+1,     /* original input */
11701
                                               &key->ctx.pubKey,
11702
                                               &tempBuff);
11703
11704
        if (err != SA_SILIB_RET_OK){
11705
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11706
        }
11707
    }
11708
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11709
    if (err == MP_OKAY)
11710
        err = silabs_ecc_import(key, keysize, 1, 0);
11711
#elif defined(WOLFSSL_SE050)
11712
    if (err == MP_OKAY) {
11713
        /* reset key ID, in case used before */
11714
        key->keyId = 0;
11715
        key->keyIdSet = 0;
11716
    }
11717
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11718
    #ifndef HAVE_COMP_KEY
11719
    if (err == MP_OKAY) {
11720
    #else
11721
    if (err == MP_OKAY && !compressed) {
11722
    #endif
11723
        buf_reverse(&key->keyRaw[0], &in[0], keysize);
11724
        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
11725
    }
11726
#endif
11727
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11728
    if (err == MP_OKAY)
11729
        err = wc_ecc_check_key(key);
11730
#endif
11731
1.07k
#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
11732
1.07k
     !defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
11733
1.07k
     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11734
1.07k
     !defined(WOLFSSL_CRYPTOCELL) && \
11735
1.07k
     (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
11736
1.07k
       defined(WOLFSSL_IMXRT1170_CAAM))
11737
1.07k
    if ((err == MP_OKAY) && untrusted) {
11738
        /* Reject point at infinity. */
11739
1.05k
        if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11740
2
            err = ECC_INF_E;
11741
2
        }
11742
        /* Verify the point lies on the curve (y^2 = x^3 + ax + b mod p) */
11743
1.05k
        if ((err == MP_OKAY) && (key->idx != ECC_CUSTOM_IDX)) {
11744
    #ifdef WOLFSSL_HAVE_SP_ECC
11745
        #ifndef WOLFSSL_SP_NO_256
11746
            if (ecc_sets[key->idx].id == ECC_SECP256R1) {
11747
                err = sp_ecc_is_point_256(key->pubkey.x, key->pubkey.y);
11748
            #if defined(WOLFSSL_SM2)
11749
                if (err != MP_OKAY && curve_id < 0) {
11750
                    /* Retry with SM2 curve when P-256 returns invalid.
11751
                     * Only when no explicit curve was requested (curve_id < 0).
11752
                     * Needed because SM2 keys can be mis-identified as
11753
                     * SECP256R1 during parsing. */
11754
                #if defined(WOLFSSL_SP_SM2)
11755
                    err = sp_ecc_is_point_sm2_256(key->pubkey.x,
11756
                                                  key->pubkey.y);
11757
                #else
11758
                    int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11759
                    if (sm2_idx != ECC_CURVE_INVALID)
11760
                        err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11761
                #endif
11762
                    if (err == MP_OKAY) {
11763
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11764
                                               ECC_SM2P256V1);
11765
                    }
11766
                }
11767
            #endif
11768
            }
11769
            else
11770
        #endif
11771
        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11772
            if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
11773
                err = sp_ecc_is_point_sm2_256(key->pubkey.x, key->pubkey.y);
11774
            }
11775
            else
11776
        #endif
11777
        #ifdef WOLFSSL_SP_384
11778
            if (ecc_sets[key->idx].id == ECC_SECP384R1) {
11779
                err = sp_ecc_is_point_384(key->pubkey.x, key->pubkey.y);
11780
            }
11781
            else
11782
        #endif
11783
        #ifdef WOLFSSL_SP_521
11784
            if (ecc_sets[key->idx].id == ECC_SECP521R1) {
11785
                err = sp_ecc_is_point_521(key->pubkey.x, key->pubkey.y);
11786
            }
11787
            else
11788
        #endif
11789
            {
11790
                err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11791
            }
11792
    #else
11793
1.05k
            err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11794
        #if defined(WOLFSSL_SM2)
11795
            if (err != MP_OKAY && curve_id < 0) {
11796
                /* Retry with SM2 curve when P-256 returns invalid.
11797
                 * Only when no explicit curve was requested (curve_id < 0).
11798
                 * Needed because SM2 keys can be mis-identified as
11799
                 * SECP256R1 during parsing. */
11800
                int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11801
                if (sm2_idx != ECC_CURVE_INVALID) {
11802
                    err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11803
                    if (err == MP_OKAY) {
11804
                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11805
                                               ECC_SM2P256V1);
11806
                    }
11807
                }
11808
            }
11809
        #endif
11810
1.05k
    #endif /* WOLFSSL_HAVE_SP_ECC */
11811
1.05k
        }
11812
1.05k
    }
11813
1.07k
#endif
11814
1.07k
    (void)untrusted;
11815
11816
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11817
    if (err == MP_OKAY) {
11818
        err = wc_MAXQ10XX_EccSetKey(key, keysize);
11819
    }
11820
#endif
11821
11822
1.07k
    if (err != MP_OKAY) {
11823
1.07k
        mp_clear(key->pubkey.x);
11824
1.07k
        mp_clear(key->pubkey.y);
11825
1.07k
        mp_clear(key->pubkey.z);
11826
1.07k
        mp_forcezero(key->k);
11827
1.07k
    }
11828
11829
1.07k
    return err;
11830
1.07k
}
11831
11832
/* import public ECC key in ANSI X9.63 format */
11833
int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11834
                           int curve_id, int untrusted)
11835
1.09k
{
11836
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11837
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
11838
    int err = 0;
11839
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11840
#endif
11841
11842
1.09k
    if (in == NULL || key == NULL) {
11843
0
        return BAD_FUNC_ARG;
11844
0
    }
11845
11846
    /* must be odd */
11847
1.09k
    if ((inLen & 1) == 0) {
11848
15
        return ECC_BAD_ARG_E;
11849
15
    }
11850
11851
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11852
    #ifndef WOLF_CRYPTO_CB_FIND
11853
    if (key->devId != INVALID_DEVID)
11854
    #endif
11855
    {
11856
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11857
        if (!WC_VAR_OK(tmpKey)) {
11858
            return MEMORY_E;
11859
        }
11860
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11861
11862
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11863
        if (err != 0) {
11864
            WC_FREE_VAR(tmpKey, key->heap);
11865
            return err;
11866
        }
11867
11868
    #ifdef WOLFSSL_CUSTOM_CURVES
11869
        if (key->dp != NULL) {
11870
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
11871
            if (err != 0) {
11872
                wc_ecc_free(tmpKey);
11873
                WC_FREE_VAR(tmpKey, key->heap);
11874
                return err;
11875
            }
11876
        }
11877
    #endif
11878
11879
        /* Import into temp via software helper (no callback recursion) */
11880
        err = _ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted);
11881
        if (err == MP_OKAY) {
11882
            cbRet = wc_CryptoCb_SetKey(key->devId,
11883
                WC_SETKEY_ECC_PUB, key, tmpKey,
11884
                wc_ecc_size(tmpKey), NULL, 0, 0);
11885
        }
11886
11887
        wc_ecc_free(tmpKey);
11888
        WC_FREE_VAR(tmpKey, key->heap);
11889
11890
        if (err != MP_OKAY) {
11891
            return err;
11892
        }
11893
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11894
            return cbRet;
11895
        }
11896
    }
11897
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
11898
11899
1.07k
    return _ecc_import_x963_ex2(in, inLen, key, curve_id, untrusted);
11900
1.09k
}
11901
11902
/* import public ECC key in ANSI X9.63 format */
11903
int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
11904
                          int curve_id)
11905
1.09k
{
11906
    /* treat as untrusted: validate the point is on the curve */
11907
1.09k
    return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1);
11908
1.09k
}
11909
11910
WOLFSSL_ABI
11911
int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
11912
0
{
11913
0
    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
11914
0
}
11915
#endif /* HAVE_ECC_KEY_IMPORT */
11916
11917
#ifdef HAVE_ECC_KEY_EXPORT
11918
11919
/* Software-only export of ecc key to component form.
11920
 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
11921
static int _ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
11922
                          byte* qy, word32* qyLen, byte* d, word32* dLen,
11923
                          int encType)
11924
0
{
11925
0
    int err = 0;
11926
0
    word32 keySz;
11927
11928
0
    if (key == NULL) {
11929
0
        return BAD_FUNC_ARG;
11930
0
    }
11931
11932
0
    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
11933
0
        return ECC_BAD_ARG_E;
11934
0
    }
11935
0
    keySz = (word32)key->dp->size;
11936
11937
    /* private key, d */
11938
0
    if (d != NULL) {
11939
0
        if (dLen == NULL ||
11940
0
            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
11941
0
            return BAD_FUNC_ARG;
11942
11943
    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11944
        defined(WOLFSSL_MICROCHIP_TA100)
11945
        /* Hardware cannot export private portion */
11946
        return NOT_COMPILED_IN;
11947
    #else
11948
    #if defined(WOLFSSL_SECO_CAAM)
11949
        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
11950
            /* Hardware cannot export private portion */
11951
            WOLFSSL_MSG("Can not export private key from HSM");
11952
            return NOT_COMPILED_IN;
11953
        }
11954
    #endif
11955
    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11956
        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11957
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11958
                *dLen = keySz + WC_CAAM_MAC_SZ;
11959
                return BUFFER_E;
11960
            }
11961
11962
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
11963
                encType);
11964
            *dLen = keySz + WC_CAAM_MAC_SZ;
11965
        }
11966
        else if (encType == WC_TYPE_BLACK_KEY &&
11967
                key->blackKey != CAAM_BLACK_KEY_ECB &&
11968
                key->blackKey > 0) {
11969
            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11970
                *dLen = keySz + WC_CAAM_MAC_SZ;
11971
                return BUFFER_E;
11972
            }
11973
11974
            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11975
                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11976
                    return WC_HW_E;
11977
            }
11978
11979
            *dLen = keySz + WC_CAAM_MAC_SZ;
11980
        }
11981
        else
11982
    #endif
11983
0
        {
11984
0
            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11985
0
            if (err != MP_OKAY)
11986
0
                return err;
11987
0
        }
11988
0
    #endif
11989
0
    }
11990
11991
    /* public x component */
11992
0
    if (qx != NULL) {
11993
0
        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11994
0
            return BAD_FUNC_ARG;
11995
11996
0
        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11997
0
        if (err != MP_OKAY)
11998
0
            return err;
11999
0
    }
12000
12001
    /* public y component */
12002
0
    if (qy != NULL) {
12003
0
        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
12004
0
            return BAD_FUNC_ARG;
12005
12006
0
        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
12007
0
        if (err != MP_OKAY)
12008
0
            return err;
12009
0
    }
12010
12011
0
    return err;
12012
0
}
12013
12014
12015
/* export ecc key to component form, d is optional if only exporting public
12016
 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
12017
 * return MP_OKAY on success */
12018
int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
12019
                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
12020
0
{
12021
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12022
    int err;
12023
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12024
#endif
12025
12026
0
    if (key == NULL) {
12027
0
        return BAD_FUNC_ARG;
12028
0
    }
12029
12030
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
12031
    #ifndef WOLF_CRYPTO_CB_FIND
12032
    if (key->devId != INVALID_DEVID)
12033
    #endif
12034
    {
12035
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12036
        if (!WC_VAR_OK(tmpKey)) {
12037
            return MEMORY_E;
12038
        }
12039
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12040
12041
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12042
        if (err != 0) {
12043
            WC_FREE_VAR(tmpKey, key->heap);
12044
            return err;
12045
        }
12046
12047
        err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
12048
                                     key, tmpKey);
12049
        if (err == 0) {
12050
            /* Call software helper (no callback recursion) */
12051
            err = _ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen,
12052
                                  encType);
12053
        }
12054
12055
        wc_ecc_free(tmpKey);
12056
        WC_FREE_VAR(tmpKey, key->heap);
12057
12058
        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12059
            return err;
12060
        }
12061
    }
12062
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
12063
12064
0
    return _ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType);
12065
0
}
12066
12067
/* export ecc private key only raw, outLen is in/out size as unsigned bin
12068
   return MP_OKAY on success */
12069
WOLFSSL_ABI
12070
int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
12071
0
{
12072
0
    if (out == NULL || outLen == NULL) {
12073
0
        return BAD_FUNC_ARG;
12074
0
    }
12075
12076
#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12077
    /* check if black key in secure memory */
12078
    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
12079
         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
12080
        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
12081
            WC_TYPE_BLACK_KEY);
12082
    }
12083
#endif
12084
12085
0
    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
12086
0
        WC_TYPE_UNSIGNED_BIN);
12087
0
}
12088
12089
/* export public key to raw elements including public (Qx,Qy) as unsigned bin
12090
 * return MP_OKAY on success, negative on error */
12091
int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
12092
                             byte* qy, word32* qyLen)
12093
0
{
12094
0
    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
12095
0
        return BAD_FUNC_ARG;
12096
0
    }
12097
12098
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
12099
0
        WC_TYPE_UNSIGNED_BIN);
12100
0
}
12101
12102
/* export ecc key to raw elements including public (Qx,Qy) and
12103
 *   private (d) as unsigned bin
12104
 * return MP_OKAY on success, negative on error */
12105
int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
12106
                              byte* qy, word32* qyLen, byte* d, word32* dLen)
12107
0
{
12108
0
    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
12109
0
        WC_TYPE_UNSIGNED_BIN);
12110
0
}
12111
12112
#endif /* HAVE_ECC_KEY_EXPORT */
12113
12114
#ifdef HAVE_ECC_KEY_IMPORT
12115
/* Software-only import of private key, public part optional.
12116
 * This internal helper avoids recursion when called from the SETKEY path. */
12117
static int _ecc_import_private_key_ex(const byte* priv, word32 privSz,
12118
                                      const byte* pub, word32 pubSz,
12119
                                      ecc_key* key, int curve_id)
12120
0
{
12121
0
    int ret;
12122
#ifdef WOLFSSL_CRYPTOCELL
12123
    const CRYS_ECPKI_Domain_t* pDomain;
12124
#endif
12125
12126
0
    if (key == NULL || priv == NULL) {
12127
0
        return BAD_FUNC_ARG;
12128
0
    }
12129
12130
    /* public optional, NULL if only importing private */
12131
0
    if (pub != NULL) {
12132
0
    #ifndef NO_ASN
12133
0
        word32 idx = 0;
12134
0
        ret = _ecc_import_x963_ex2(pub, pubSz, key, curve_id, 0);
12135
0
        if (ret < 0)
12136
0
            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
12137
0
        key->type = ECC_PRIVATEKEY;
12138
    #else
12139
        (void)pubSz;
12140
        ret = NOT_COMPILED_IN;
12141
    #endif
12142
0
    }
12143
0
    else {
12144
        /* make sure required variables are reset */
12145
0
        wc_ecc_reset(key);
12146
12147
        /* set key size */
12148
        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
12149
         *       on created keys or signatures */
12150
0
        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
12151
0
        key->type = ECC_PRIVATEKEY_ONLY;
12152
0
    }
12153
12154
0
    if (ret != 0)
12155
0
        return ret;
12156
12157
#ifdef WOLFSSL_CRYPTOCELL
12158
    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
12159
    /* import private key - priv checked for NULL at top */
12160
    if (priv[0] != '\0') {
12161
12162
        /* Create private key from external key buffer*/
12163
        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
12164
                                      priv,
12165
                                      privSz,
12166
                                      &key->ctx.privKey);
12167
12168
        if (ret != SA_SILIB_RET_OK) {
12169
            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
12170
            return ret;
12171
        }
12172
12173
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12174
    #ifdef WOLFSSL_ECC_BLIND_K
12175
        if (ret == MP_OKAY) {
12176
            err = ecc_blind_k_rng(key, NULL);
12177
        }
12178
    #endif
12179
    }
12180
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12181
    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
12182
    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
12183
        int part = caamFindUnusedPartition();
12184
        if (part >= 0) {
12185
            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
12186
            if (vaddr == 0) {
12187
                WOLFSSL_MSG("Unable to get partition");
12188
                return MEMORY_E;
12189
            }
12190
12191
            key->partNum  = part;
12192
            key->blackKey = (word32)vaddr;
12193
            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
12194
                return WC_HW_E;
12195
12196
            if (pub != NULL) {
12197
                /* +1 to account for x963 compressed bit */
12198
                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
12199
                    return WC_HW_E;
12200
                key->securePubKey = (word32)vaddr + privSz;
12201
            }
12202
        }
12203
        else {
12204
            WOLFSSL_MSG("Unable to find an unused partition");
12205
            return MEMORY_E;
12206
        }
12207
    #else
12208
        key->blackKey = CAAM_BLACK_KEY_CCM;
12209
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12210
    #ifdef WOLFSSL_ECC_BLIND_K
12211
        if (ret == MP_OKAY) {
12212
            err = ecc_blind_k_rng(key, NULL);
12213
        }
12214
    #endif
12215
    #endif
12216
    }
12217
    else {
12218
        key->blackKey = 0;
12219
        ret = mp_read_unsigned_bin(key->k, priv, privSz);
12220
    #ifdef WOLFSSL_ECC_BLIND_K
12221
        if (ret == MP_OKAY) {
12222
            err = ecc_blind_k_rng(key, NULL);
12223
        }
12224
    #endif
12225
12226
        /* If using AES-ECB encrypted black keys check here if key is valid,
12227
         * if not valid than assume is an encrypted key. A public key is needed
12228
         * for testing validity. */
12229
        if (key->devId == WOLFSSL_CAAM_DEVID && (
12230
            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
12231
            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
12232
            if ((pub != NULL) && (ret == MP_OKAY) &&
12233
                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
12234
                key->blackKey = CAAM_BLACK_KEY_ECB;
12235
            }
12236
            else if ((pub == NULL) && (ret == MP_OKAY)) {
12237
                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
12238
                key->blackKey = CAAM_BLACK_KEY_ECB;
12239
            }
12240
            else {
12241
                WOLFSSL_MSG("Importing key that is not a black key!");
12242
            }
12243
        }
12244
    }
12245
#else
12246
12247
0
    ret = mp_read_unsigned_bin(key->k, priv, privSz);
12248
#ifdef HAVE_WOLF_BIGINT
12249
    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
12250
                                                                 privSz) != 0) {
12251
        mp_clear(key->k);
12252
        ret = ASN_GETINT_E;
12253
    }
12254
#endif /* HAVE_WOLF_BIGINT */
12255
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12256
    if (ret == 0) {
12257
        WC_DECLARE_VAR(order, mp_int, 1, 0);
12258
12259
        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
12260
            ret=MEMORY_E);
12261
12262
        if (ret == 0) {
12263
            ret = mp_init(order);
12264
        }
12265
        if (ret == 0) {
12266
            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
12267
        }
12268
    #ifdef WOLFSSL_SM2
12269
        /* SM2 curve: private key must be less than order-1. */
12270
        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
12271
                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
12272
            ret = mp_sub_d(order, 1, order);
12273
        }
12274
    #endif
12275
        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
12276
            ret = ECC_PRIV_KEY_E;
12277
        }
12278
12279
        mp_clear(order);
12280
        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
12281
    }
12282
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
12283
#ifdef WOLFSSL_ECC_BLIND_K
12284
    if (ret == 0) {
12285
        ret = ecc_blind_k_rng(key, NULL);
12286
    }
12287
#endif
12288
12289
0
#endif /* WOLFSSL_CRYPTOCELL */
12290
12291
#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
12292
    if ((pub != NULL) && (ret == MP_OKAY))
12293
        /* public key needed to perform key validation */
12294
        ret = _ecc_validate_public_key(key, 1, 1);
12295
12296
#endif
12297
12298
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12299
    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
12300
        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12301
    }
12302
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12303
    if (ret == 0) {
12304
        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
12305
    }
12306
#endif
12307
12308
0
    return ret;
12309
0
}
12310
12311
/* import private key, public part optional if (pub) passed as NULL */
12312
int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
12313
                                 const byte* pub, word32 pubSz, ecc_key* key,
12314
                                 int curve_id)
12315
0
{
12316
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12317
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12318
    int tmpErr = 0;
12319
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12320
#endif
12321
12322
0
    if (key == NULL || priv == NULL) {
12323
0
        return BAD_FUNC_ARG;
12324
0
    }
12325
12326
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12327
    #ifndef WOLF_CRYPTO_CB_FIND
12328
    if (key->devId != INVALID_DEVID)
12329
    #endif
12330
    {
12331
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12332
        if (!WC_VAR_OK(tmpKey)) {
12333
            return MEMORY_E;
12334
        }
12335
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12336
12337
        tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12338
        if (tmpErr != 0) {
12339
            WC_FREE_VAR(tmpKey, key->heap);
12340
            return tmpErr;
12341
        }
12342
12343
    #ifdef WOLFSSL_CUSTOM_CURVES
12344
        if (key->dp != NULL) {
12345
            tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp);
12346
            if (tmpErr != 0) {
12347
                wc_ecc_free(tmpKey);
12348
                WC_FREE_VAR(tmpKey, key->heap);
12349
                return tmpErr;
12350
            }
12351
        }
12352
    #endif
12353
12354
        /* Import into temp via software helper (no callback recursion) */
12355
        tmpErr = _ecc_import_private_key_ex(priv, privSz, pub, pubSz,
12356
            tmpKey, curve_id);
12357
        if (tmpErr == 0) {
12358
            cbRet = wc_CryptoCb_SetKey(key->devId,
12359
                WC_SETKEY_ECC_PRIV, key, tmpKey,
12360
                wc_ecc_size(tmpKey), NULL, 0, 0);
12361
        }
12362
12363
        /* wc_ecc_free calls mp_forcezero on private key components,
12364
         * so no separate ForceZero of the struct is needed here. */
12365
        wc_ecc_free(tmpKey);
12366
        WC_FREE_VAR(tmpKey, key->heap);
12367
12368
        if (tmpErr != 0) {
12369
            return tmpErr;
12370
        }
12371
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12372
            return cbRet;
12373
        }
12374
    }
12375
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12376
12377
0
    return _ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, curve_id);
12378
0
}
12379
12380
/* ecc private key import, public key in ANSI X9.63 format, private raw */
12381
WOLFSSL_ABI
12382
int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
12383
                           word32 pubSz, ecc_key* key)
12384
0
{
12385
0
    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
12386
0
                                                                ECC_CURVE_DEF);
12387
0
}
12388
#endif /* HAVE_ECC_KEY_IMPORT */
12389
12390
#ifndef NO_ASN
12391
/**
12392
   Convert ECC R,S to signature
12393
   r       R component of signature
12394
   s       S component of signature
12395
   out     DER-encoded ECDSA signature
12396
   outlen  [in/out] output buffer size, output signature size
12397
   return  MP_OKAY on success
12398
*/
12399
WOLFSSL_ABI
12400
int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
12401
0
{
12402
0
    int err;
12403
#ifdef WOLFSSL_SMALL_STACK
12404
    mp_int* rtmp = NULL;
12405
    mp_int* stmp = NULL;
12406
#else
12407
0
    mp_int  rtmp[1];
12408
0
    mp_int  stmp[1];
12409
0
#endif
12410
12411
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
12412
0
        return ECC_BAD_ARG_E;
12413
12414
#ifdef WOLFSSL_SMALL_STACK
12415
    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12416
    if (rtmp == NULL)
12417
        return MEMORY_E;
12418
    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
12419
    if (stmp == NULL) {
12420
        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
12421
        return MEMORY_E;
12422
    }
12423
#endif
12424
12425
0
    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
12426
0
    if (err != MP_OKAY) {
12427
0
        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12428
0
        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12429
0
        return err;
12430
0
    }
12431
12432
0
    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
12433
0
    if (err == MP_OKAY)
12434
0
        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
12435
12436
0
    if (err == MP_OKAY) {
12437
0
        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
12438
0
            err = MP_ZERO_E;
12439
0
    }
12440
0
    if (err == MP_OKAY) {
12441
0
        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
12442
0
            err = MP_READ_E;
12443
0
        }
12444
0
    }
12445
12446
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
12447
0
    if (err == MP_OKAY)
12448
0
        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
12449
12450
0
    mp_clear(rtmp);
12451
0
    mp_clear(stmp);
12452
0
    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
12453
0
    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
12454
12455
0
    return err;
12456
0
}
12457
12458
/**
12459
   Convert ECC R,S raw unsigned bin to signature
12460
   r       R component of signature
12461
   rSz     R size
12462
   s       S component of signature
12463
   sSz     S size
12464
   out     DER-encoded ECDSA signature
12465
   outlen  [in/out] output buffer size, output signature size
12466
   return  MP_OKAY on success
12467
*/
12468
int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
12469
    byte* out, word32* outlen)
12470
0
{
12471
0
    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
12472
0
        return ECC_BAD_ARG_E;
12473
12474
    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
12475
0
    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
12476
0
}
12477
12478
/**
12479
   Convert ECC signature to R,S
12480
   sig     DER-encoded ECDSA signature
12481
   sigLen  length of signature in octets
12482
   r       R component of signature
12483
   rLen    [in/out] output "r" buffer size, output "r" size
12484
   s       S component of signature
12485
   sLen    [in/out] output "s" buffer size, output "s" size
12486
   return  MP_OKAY on success, negative on error
12487
*/
12488
int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
12489
                     byte* s, word32* sLen)
12490
0
{
12491
0
    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
12492
0
        return ECC_BAD_ARG_E;
12493
12494
0
    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
12495
0
}
12496
#endif /* !NO_ASN */
12497
12498
#ifdef HAVE_ECC_KEY_IMPORT
12499
/* Software-only import of raw ECC key material.
12500
 * This internal helper avoids recursion when called from the SETKEY path. */
12501
static int _ecc_import_raw_private(ecc_key* key, const char* qx,
12502
          const char* qy, const char* d, int curve_id, int encType)
12503
0
{
12504
0
    int err = MP_OKAY;
12505
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
12506
    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
12507
    const CRYS_ECPKI_Domain_t* pDomain;
12508
    CRYS_ECPKI_BUILD_TempData_t tempBuff;
12509
    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
12510
#endif
12511
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12512
    defined(WOLFSSL_MICROCHIP_TA100) || defined(WOLFSSL_CRYPTOCELL)
12513
    word32 keySz = 0;
12514
#endif
12515
12516
    /* if d is NULL, only import as public key using Qx,Qy */
12517
0
    if (key == NULL || qx == NULL || qy == NULL) {
12518
0
        return BAD_FUNC_ARG;
12519
0
    }
12520
12521
    /* make sure required variables are reset */
12522
0
    wc_ecc_reset(key);
12523
12524
    /* set curve type and index */
12525
    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
12526
     *       on created keys or signatures */
12527
0
    err = wc_ecc_set_curve(key, 0, curve_id);
12528
0
    if (err != 0) {
12529
0
        return err;
12530
0
    }
12531
12532
    /* init key */
12533
#ifdef ALT_ECC_SIZE
12534
    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
12535
    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
12536
    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
12537
    alt_fp_init(key->pubkey.x);
12538
    alt_fp_init(key->pubkey.y);
12539
    alt_fp_init(key->pubkey.z);
12540
    key->k = (mp_int*)key->ka;
12541
    alt_fp_init(key->k);
12542
#ifdef WOLFSSL_ECC_BLIND_K
12543
    key->kb = (mp_int*)key->kba;
12544
    key->ku = (mp_int*)key->kua;
12545
    alt_fp_init(key->kb);
12546
    alt_fp_init(key->ku);
12547
#endif
12548
#else
12549
0
    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
12550
0
#ifndef WOLFSSL_ECC_BLIND_K
12551
0
                                                                      NULL, NULL
12552
#else
12553
                                                                key->kb, key->ku
12554
#endif
12555
0
                        );
12556
12557
0
    if (err != MP_OKAY)
12558
0
        return MEMORY_E;
12559
0
#endif
12560
#ifdef WOLFSSL_ECC_BLIND_K
12561
    mp_forcezero(key->kb);
12562
#endif
12563
12564
    /* read Qx */
12565
0
    if (err == MP_OKAY) {
12566
0
        if (encType == WC_TYPE_HEX_STR)
12567
0
            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
12568
0
        else
12569
0
            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
12570
0
                (word32)key->dp->size);
12571
12572
0
        if (mp_isneg(key->pubkey.x)) {
12573
0
            WOLFSSL_MSG("Invalid Qx");
12574
0
            err = BAD_FUNC_ARG;
12575
0
        }
12576
0
        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
12577
0
            err = BAD_FUNC_ARG;
12578
0
        }
12579
0
    }
12580
12581
    /* read Qy */
12582
0
    if (err == MP_OKAY) {
12583
0
        if (encType == WC_TYPE_HEX_STR)
12584
0
            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
12585
0
        else
12586
0
            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
12587
0
                (word32)key->dp->size);
12588
12589
0
        if (mp_isneg(key->pubkey.y)) {
12590
0
            WOLFSSL_MSG("Invalid Qy");
12591
0
            err = BAD_FUNC_ARG;
12592
0
        }
12593
0
        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
12594
0
            err = BAD_FUNC_ARG;
12595
0
        }
12596
0
    }
12597
12598
0
    if (err == MP_OKAY) {
12599
0
        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
12600
0
            WOLFSSL_MSG("Invalid Qx and Qy");
12601
0
            err = ECC_INF_E;
12602
0
        }
12603
0
    }
12604
12605
0
    if (err == MP_OKAY)
12606
0
        err = mp_set(key->pubkey.z, 1);
12607
12608
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12609
    defined(WOLFSSL_MICROCHIP_TA100)
12610
    /* For SECP256R1 only save raw public key for hardware */
12611
    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
12612
        keySz = key->dp->size;
12613
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12614
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12615
        if (err == MP_OKAY)
12616
            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
12617
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12618
    }
12619
#elif defined(WOLFSSL_CRYPTOCELL)
12620
    if (err == MP_OKAY) {
12621
        keyRaw[0] = ECC_POINT_UNCOMP;
12622
        keySz = (word32)key->dp->size;
12623
        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
12624
            WC_TYPE_UNSIGNED_BIN);
12625
        if (err == MP_OKAY) {
12626
            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
12627
                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12628
        }
12629
12630
        if (err == MP_OKAY) {
12631
            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
12632
12633
            /* create public key from external key buffer */
12634
            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
12635
                                                   keyRaw,
12636
                                                   keySz*2 + 1,
12637
                                                   &key->ctx.pubKey,
12638
                                                   &tempBuff);
12639
        }
12640
12641
        if (err != SA_SILIB_RET_OK){
12642
            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
12643
            return err;
12644
        }
12645
    }
12646
#elif defined(WOLFSSL_KCAPI_ECC)
12647
    if (err == MP_OKAY) {
12648
        word32 keySz = key->dp->size;
12649
        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12650
            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12651
        if (err == MP_OKAY) {
12652
            err = wc_export_int(key->pubkey.y,
12653
                &key->pubkey_raw[keySz], &keySz, keySz,
12654
                WC_TYPE_UNSIGNED_BIN);
12655
        }
12656
    }
12657
#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12658
    if (err == MP_OKAY) {
12659
        const word32 keySize = key->dp->size;
12660
        word32 bufSize = sizeof(key->keyRaw);
12661
        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
12662
                            WC_TYPE_UNSIGNED_BIN);
12663
        if (err == MP_OKAY) {
12664
            const word32 offset = bufSize;
12665
            bufSize = sizeof(key->keyRaw) - offset;
12666
            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
12667
                                keySize, WC_TYPE_UNSIGNED_BIN);
12668
        }
12669
        if (err == MP_OKAY) {
12670
            mp_reverse(key->keyRaw, keySize);
12671
            mp_reverse(&key->keyRaw[keySize], keySize);
12672
            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
12673
                                           keySize * 2);
12674
#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
12675
            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
12676
                                              xil_curve_type[key->dp->id],
12677
                                              XIL_CAST_U64(key->keyRaw));
12678
            if (err) {
12679
                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
12680
                err = WC_HW_E;
12681
            }
12682
#endif
12683
        }
12684
    }
12685
#endif
12686
12687
    /* import private key */
12688
0
    if (err == MP_OKAY) {
12689
0
        if (d != NULL) {
12690
        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12691
            defined(WOLFSSL_MICROCHIP_TA100)
12692
            /* Hardware doesn't support loading private key */
12693
            err = NOT_COMPILED_IN;
12694
12695
        #elif defined(WOLFSSL_CRYPTOCELL)
12696
            key->type = ECC_PRIVATEKEY;
12697
12698
            if (encType == WC_TYPE_HEX_STR)
12699
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12700
            else
12701
                err = mp_read_unsigned_bin(key->k, (const byte*)d,
12702
                    key->dp->size);
12703
            if (err == MP_OKAY) {
12704
                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
12705
                    WC_TYPE_UNSIGNED_BIN);
12706
            }
12707
        #ifdef WOLFSSL_ECC_BLIND_K
12708
            if (err == 0) {
12709
                err = ecc_blind_k_rng(key, NULL);
12710
            }
12711
        #endif
12712
12713
            if (err == MP_OKAY) {
12714
                /* Create private key from external key buffer*/
12715
                err = CRYS_ECPKI_BuildPrivKey(pDomain,
12716
                                              keyRaw,
12717
                                              keySz,
12718
                                              &key->ctx.privKey);
12719
12720
                if (err != SA_SILIB_RET_OK){
12721
                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
12722
                    return err;
12723
                }
12724
            }
12725
12726
        #else
12727
0
            key->type = ECC_PRIVATEKEY;
12728
0
            if (encType == WC_TYPE_HEX_STR)
12729
0
                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12730
0
            else {
12731
            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12732
                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
12733
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12734
                    key->dp->size + WC_CAAM_MAC_SZ);
12735
                }
12736
                else
12737
            #endif /* WOLFSSL_QNX_CAAM */
12738
0
                {
12739
0
                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12740
0
                        (word32)key->dp->size);
12741
0
                }
12742
0
            }
12743
        #ifdef WOLFSSL_ECC_BLIND_K
12744
            if (err == 0) {
12745
                err = ecc_blind_k_rng(key, NULL);
12746
            }
12747
        #endif
12748
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12749
            if (err == MP_OKAY) {
12750
                const word32 key_size = key->dp->size;
12751
                word32 buf_size = key_size;
12752
                err = wc_export_int(key, key->privKey, &buf_size, key_size,
12753
                                    WC_TYPE_UNSIGNED_BIN);
12754
                mp_reverse(key->privKey, key_size);
12755
            }
12756
#endif
12757
12758
0
        #endif /* #else-case of custom HW-specific implementations */
12759
0
            if (err == MP_OKAY) {
12760
0
                if (mp_iszero(key->k) || mp_isneg(key->k)) {
12761
0
                    WOLFSSL_MSG("Invalid private key");
12762
0
                    err = BAD_FUNC_ARG;
12763
0
                }
12764
0
            }
12765
0
        } else {
12766
0
            key->type = ECC_PUBLICKEY;
12767
0
        }
12768
0
    }
12769
12770
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12771
    if (err == MP_OKAY) {
12772
        err = wc_ecc_check_key(key);
12773
        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
12774
                                  mp_iszero(key->pubkey.y))) {
12775
            err = BAD_FUNC_ARG;
12776
        }
12777
    }
12778
#endif
12779
12780
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12781
    if (err == MP_OKAY) {
12782
        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12783
    }
12784
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12785
    if (err == MP_OKAY) {
12786
        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
12787
    }
12788
#endif
12789
12790
0
    if (err != MP_OKAY) {
12791
0
        mp_clear(key->pubkey.x);
12792
0
        mp_clear(key->pubkey.y);
12793
0
        mp_clear(key->pubkey.z);
12794
0
        mp_forcezero(key->k);
12795
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12796
        ForceZero(key->keyRaw, sizeof(key->keyRaw));
12797
#endif
12798
0
    }
12799
12800
0
    return err;
12801
0
}
12802
12803
static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
12804
          const char* qy, const char* d, int curve_id, int encType)
12805
0
{
12806
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12807
    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12808
    int setKeyType = WC_SETKEY_ECC_PRIV;
12809
    int err;
12810
    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12811
#endif
12812
12813
    /* if d is NULL, only import as public key using Qx,Qy */
12814
0
    if (key == NULL || qx == NULL || qy == NULL) {
12815
0
        return BAD_FUNC_ARG;
12816
0
    }
12817
12818
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12819
    #ifndef WOLF_CRYPTO_CB_FIND
12820
    if (key->devId != INVALID_DEVID)
12821
    #endif
12822
    {
12823
        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12824
        if (!WC_VAR_OK(tmpKey)) {
12825
            return MEMORY_E;
12826
        }
12827
        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12828
12829
        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12830
        if (err != 0) {
12831
            WC_FREE_VAR(tmpKey, key->heap);
12832
            return err;
12833
        }
12834
12835
    #ifdef WOLFSSL_CUSTOM_CURVES
12836
        if (key->dp != NULL) {
12837
            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
12838
            if (err != 0) {
12839
                wc_ecc_free(tmpKey);
12840
                WC_FREE_VAR(tmpKey, key->heap);
12841
                return err;
12842
            }
12843
        }
12844
    #endif
12845
12846
        /* Import into temp via software helper (no callback recursion) */
12847
        err = _ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType);
12848
        if (err == MP_OKAY) {
12849
            if (d == NULL) {
12850
                setKeyType = WC_SETKEY_ECC_PUB;
12851
            }
12852
            cbRet = wc_CryptoCb_SetKey(key->devId,
12853
                setKeyType, key, tmpKey,
12854
                wc_ecc_size(tmpKey), NULL, 0, 0);
12855
        }
12856
12857
        /* wc_ecc_free calls mp_forcezero on private key components,
12858
         * so no separate ForceZero of the struct is needed here. */
12859
        wc_ecc_free(tmpKey);
12860
        WC_FREE_VAR(tmpKey, key->heap);
12861
12862
        if (err != MP_OKAY) {
12863
            return err;
12864
        }
12865
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12866
            return cbRet;
12867
        }
12868
    }
12869
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12870
12871
0
    return _ecc_import_raw_private(key, qx, qy, d, curve_id, encType);
12872
0
}
12873
12874
/**
12875
   Import raw ECC key
12876
   key       The destination ecc_key structure
12877
   qx        x component of the public key, as ASCII hex string
12878
   qy        y component of the public key, as ASCII hex string
12879
   d         private key, as ASCII hex string, optional if importing public
12880
             key only
12881
   curve_id  The id of the curve.
12882
   @return    MP_OKAY on success
12883
*/
12884
int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
12885
                   const char* d, int curve_id)
12886
0
{
12887
0
    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
12888
0
        WC_TYPE_HEX_STR);
12889
0
}
12890
12891
/* Import x, y and optional private (d) as unsigned binary */
12892
int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
12893
                   const byte* d, int curve_id)
12894
0
{
12895
0
    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
12896
0
        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
12897
0
}
12898
12899
/**
12900
   Import raw ECC key
12901
   key       The destination ecc_key structure
12902
   qx        x component of the public key, as ASCII hex string
12903
   qy        y component of the public key, as ASCII hex string
12904
   d         private key, as ASCII hex string, optional if importing public
12905
             key only
12906
   curveName ECC curve name, from ecc_sets[]
12907
   return    MP_OKAY on success
12908
*/
12909
WOLFSSL_ABI
12910
int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
12911
                   const char* d, const char* curveName)
12912
0
{
12913
0
    int err, x;
12914
12915
    /* if d is NULL, only import as public key using Qx,Qy */
12916
0
    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
12917
0
        return BAD_FUNC_ARG;
12918
0
    }
12919
12920
    /* set curve type and index */
12921
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
12922
0
        if (XSTRNCMP(ecc_sets[x].name, curveName,
12923
0
                     XSTRLEN(curveName)) == 0) {
12924
0
            break;
12925
0
        }
12926
0
    }
12927
12928
0
    if (ecc_sets[x].size == 0) {
12929
0
        WOLFSSL_MSG("ecc_set curve name not found");
12930
0
        err = ASN_PARSE_E;
12931
0
    } else {
12932
0
        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
12933
0
            WC_TYPE_HEX_STR);
12934
0
    }
12935
12936
0
    return err;
12937
0
}
12938
#endif /* HAVE_ECC_KEY_IMPORT */
12939
12940
#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
12941
/* public key size in octets */
12942
static int ecc_public_key_size(ecc_key* key, word32* sz)
12943
{
12944
    if (key == NULL || key->dp == NULL)
12945
        return BAD_FUNC_ARG;
12946
12947
    /* 'Uncompressed' | x | y */
12948
    *sz = 1 + 2 * (word32)key->dp->size;
12949
12950
    return 0;
12951
}
12952
#endif
12953
12954
/* key size in octets */
12955
WOLFSSL_ABI
12956
int wc_ecc_size(ecc_key* key)
12957
0
{
12958
0
    if (key == NULL) {
12959
0
        return 0;
12960
0
    }
12961
12962
#if defined(WOLF_CRYPTO_CB) && \
12963
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
12964
    if (key->devId != INVALID_DEVID) {
12965
        int ret;
12966
        int keySz = 0;
12967
12968
        ret = wc_CryptoCb_EccGetSize(key, &keySz);
12969
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12970
            if (ret != 0) {
12971
                return 0;
12972
            }
12973
            return keySz;
12974
        }
12975
    }
12976
#endif
12977
12978
0
    if (key->dp == NULL) {
12979
0
        return 0;
12980
0
    }
12981
12982
0
    return key->dp->size;
12983
0
}
12984
12985
/* maximum signature size based on key size */
12986
WOLFSSL_ABI
12987
int wc_ecc_sig_size_calc(int sz)
12988
0
{
12989
0
    int maxSigSz = 0;
12990
12991
    /* calculate based on key bits */
12992
    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
12993
0
    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
12994
12995
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
12996
0
    if (maxSigSz < (128 + 2)) {
12997
0
        maxSigSz -= 1;
12998
0
    }
12999
13000
0
    return maxSigSz;
13001
0
}
13002
13003
/* maximum signature size based on actual key curve */
13004
WOLFSSL_ABI
13005
int wc_ecc_sig_size(const ecc_key* key)
13006
0
{
13007
0
    int maxSigSz;
13008
0
    int orderBits, keySz;
13009
13010
0
    if (key == NULL) {
13011
0
        return 0;
13012
0
    }
13013
13014
#if defined(WOLF_CRYPTO_CB) && \
13015
    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
13016
    if (key->devId != INVALID_DEVID) {
13017
        int ret;
13018
        int cbKeySz = 0;
13019
13020
        ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
13021
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
13022
            if (ret != 0 || cbKeySz == 0) {
13023
                return 0;
13024
            }
13025
            return cbKeySz;
13026
        }
13027
    }
13028
#endif
13029
13030
0
    if (key->dp == NULL) {
13031
0
        return 0;
13032
0
    }
13033
13034
    /* the signature r and s will always be less than order */
13035
    /* if the order MSB (top bit of byte) is set then ASN encoding needs
13036
        extra byte for r and s, so add 2 */
13037
0
    keySz = key->dp->size;
13038
0
    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
13039
0
    if (orderBits > keySz * 8) {
13040
0
        keySz = (orderBits + 7) >> 3;
13041
0
    }
13042
    /* maximum possible signature header size is 7 bytes */
13043
0
    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
13044
0
    if ((orderBits % 8) == 0) {
13045
        /* MSB can be set, so add 2 */
13046
0
        maxSigSz += ECC_MAX_PAD_SZ;
13047
0
    }
13048
    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
13049
0
    if (maxSigSz < (128 + 2)) {
13050
0
        maxSigSz -= 1;
13051
0
    }
13052
13053
0
    return maxSigSz;
13054
0
}
13055
13056
13057
#ifdef FP_ECC
13058
13059
/* fixed point ECC cache */
13060
/* number of entries in the cache */
13061
#ifndef FP_ENTRIES
13062
    #define FP_ENTRIES 15
13063
#endif
13064
13065
/* number of bits in LUT */
13066
#ifndef FP_LUT
13067
    #define FP_LUT     8U
13068
#endif
13069
13070
#ifdef ECC_SHAMIR
13071
    /* Sharmir requires a bigger LUT, TAO */
13072
    #if (FP_LUT > 12) || (FP_LUT < 4)
13073
        #error FP_LUT must be between 4 and 12 inclusively
13074
    #endif
13075
#else
13076
    #if (FP_LUT > 12) || (FP_LUT < 2)
13077
        #error FP_LUT must be between 2 and 12 inclusively
13078
    #endif
13079
#endif
13080
13081
13082
#if !defined(WOLFSSL_SP_MATH)
13083
13084
/** Our FP cache */
13085
typedef struct {
13086
   ecc_point* g;               /* cached COPY of base point */
13087
   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
13088
   int        LUT_set;         /* flag to determine if the LUT has been computed */
13089
   mp_int     mu;              /* copy of the montgomery constant */
13090
   int        lru_count;       /* amount of times this entry has been used */
13091
   int        lock;            /* flag to indicate cache eviction */
13092
                               /* permitted (0) or not (1) */
13093
} fp_cache_t;
13094
13095
/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
13096
static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
13097
13098
#ifndef HAVE_THREAD_LS
13099
    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
13100
#ifndef WOLFSSL_MUTEX_INITIALIZER
13101
    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
13102
#endif
13103
#endif /* HAVE_THREAD_LS */
13104
13105
/* simple table to help direct the generation of the LUT */
13106
static const struct {
13107
   int ham, terma, termb;
13108
} lut_orders[] = {
13109
   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
13110
   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
13111
   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
13112
   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
13113
   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
13114
   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
13115
   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
13116
   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
13117
#if FP_LUT > 6
13118
   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
13119
   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
13120
   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
13121
   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
13122
   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
13123
   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
13124
   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
13125
   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
13126
#if FP_LUT > 7
13127
   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
13128
   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
13129
   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
13130
   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
13131
   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
13132
   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
13133
   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
13134
   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
13135
   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
13136
   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
13137
   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
13138
   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
13139
   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
13140
   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
13141
   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
13142
   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
13143
#if FP_LUT > 8
13144
   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
13145
   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
13146
   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
13147
   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
13148
   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
13149
   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
13150
   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
13151
   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
13152
   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
13153
   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
13154
   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
13155
   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
13156
   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
13157
   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
13158
   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
13159
   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
13160
   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
13161
   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
13162
   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
13163
   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
13164
   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
13165
   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
13166
   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
13167
   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
13168
   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
13169
   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
13170
   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
13171
   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
13172
   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
13173
   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
13174
   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
13175
   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
13176
#if FP_LUT > 9
13177
   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
13178
   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
13179
   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
13180
   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
13181
   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
13182
   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
13183
   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
13184
   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
13185
   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
13186
   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
13187
   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
13188
   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
13189
   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
13190
   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
13191
   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
13192
   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
13193
   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
13194
   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
13195
   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
13196
   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
13197
   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
13198
   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
13199
   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
13200
   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
13201
   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
13202
   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
13203
   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
13204
   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
13205
   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
13206
   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
13207
   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
13208
   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
13209
   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
13210
   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
13211
   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
13212
   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
13213
   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
13214
   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
13215
   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
13216
   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
13217
   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
13218
   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
13219
   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
13220
   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
13221
   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
13222
   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
13223
   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
13224
   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
13225
   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
13226
   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
13227
   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
13228
   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
13229
   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
13230
   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
13231
   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
13232
   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
13233
   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
13234
   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
13235
   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
13236
   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
13237
   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
13238
   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
13239
   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
13240
   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
13241
#if FP_LUT > 10
13242
   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
13243
   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
13244
   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
13245
   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
13246
   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
13247
   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
13248
   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
13249
   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
13250
   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
13251
   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
13252
   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
13253
   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
13254
   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
13255
   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
13256
   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
13257
   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
13258
   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
13259
   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
13260
   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
13261
   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
13262
   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
13263
   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
13264
   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
13265
   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
13266
   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
13267
   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
13268
   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
13269
   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
13270
   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
13271
   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
13272
   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
13273
   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
13274
   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
13275
   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
13276
   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
13277
   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
13278
   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
13279
   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
13280
   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
13281
   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
13282
   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
13283
   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
13284
   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
13285
   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
13286
   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
13287
   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
13288
   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
13289
   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
13290
   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
13291
   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
13292
   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
13293
   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
13294
   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
13295
   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
13296
   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
13297
   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
13298
   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
13299
   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
13300
   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
13301
   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
13302
   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
13303
   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
13304
   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
13305
   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
13306
   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
13307
   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
13308
   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
13309
   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
13310
   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
13311
   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
13312
   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
13313
   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
13314
   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
13315
   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
13316
   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
13317
   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
13318
   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
13319
   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
13320
   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
13321
   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
13322
   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
13323
   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
13324
   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
13325
   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
13326
   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
13327
   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
13328
   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
13329
   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
13330
   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
13331
   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
13332
   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
13333
   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
13334
   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
13335
   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
13336
   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
13337
   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
13338
   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
13339
   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
13340
   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
13341
   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
13342
   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
13343
   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
13344
   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
13345
   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
13346
   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
13347
   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
13348
   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
13349
   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
13350
   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
13351
   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
13352
   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
13353
   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
13354
   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
13355
   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
13356
   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
13357
   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
13358
   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
13359
   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
13360
   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
13361
   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
13362
   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
13363
   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
13364
   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
13365
   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
13366
   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
13367
   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
13368
   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
13369
   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
13370
#if FP_LUT > 11
13371
   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
13372
   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
13373
   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
13374
   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
13375
   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
13376
   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
13377
   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
13378
   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
13379
   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
13380
   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
13381
   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
13382
   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
13383
   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
13384
   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
13385
   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
13386
   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
13387
   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
13388
   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
13389
   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
13390
   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
13391
   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
13392
   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
13393
   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
13394
   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
13395
   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
13396
   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
13397
   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
13398
   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
13399
   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
13400
   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
13401
   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
13402
   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
13403
   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
13404
   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
13405
   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
13406
   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
13407
   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
13408
   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
13409
   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
13410
   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
13411
   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
13412
   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
13413
   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
13414
   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
13415
   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
13416
   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
13417
   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
13418
   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
13419
   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
13420
   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
13421
   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
13422
   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
13423
   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
13424
   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
13425
   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
13426
   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
13427
   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
13428
   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
13429
   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
13430
   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
13431
   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
13432
   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
13433
   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
13434
   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
13435
   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
13436
   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
13437
   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
13438
   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
13439
   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
13440
   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
13441
   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
13442
   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
13443
   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
13444
   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
13445
   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
13446
   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
13447
   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
13448
   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
13449
   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
13450
   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
13451
   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
13452
   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
13453
   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
13454
   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
13455
   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
13456
   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
13457
   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
13458
   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
13459
   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
13460
   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
13461
   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
13462
   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
13463
   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
13464
   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
13465
   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
13466
   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
13467
   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
13468
   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
13469
   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
13470
   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
13471
   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
13472
   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
13473
   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
13474
   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
13475
   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
13476
   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
13477
   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
13478
   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
13479
   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
13480
   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
13481
   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
13482
   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
13483
   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
13484
   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
13485
   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
13486
   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
13487
   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
13488
   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
13489
   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
13490
   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
13491
   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
13492
   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
13493
   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
13494
   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
13495
   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
13496
   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
13497
   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
13498
   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
13499
   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
13500
   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
13501
   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
13502
   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
13503
   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
13504
   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
13505
   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
13506
   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
13507
   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
13508
   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
13509
   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
13510
   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
13511
   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
13512
   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
13513
   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
13514
   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
13515
   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
13516
   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
13517
   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
13518
   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
13519
   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
13520
   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
13521
   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
13522
   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
13523
   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
13524
   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
13525
   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
13526
   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
13527
   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
13528
   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
13529
   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
13530
   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
13531
   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
13532
   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
13533
   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
13534
   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
13535
   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
13536
   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
13537
   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
13538
   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
13539
   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
13540
   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
13541
   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
13542
   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
13543
   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
13544
   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
13545
   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
13546
   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
13547
   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
13548
   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
13549
   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
13550
   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
13551
   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
13552
   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
13553
   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
13554
   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
13555
   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
13556
   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
13557
   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
13558
   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
13559
   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
13560
   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
13561
   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
13562
   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
13563
   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
13564
   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
13565
   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
13566
   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
13567
   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
13568
   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
13569
   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
13570
   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
13571
   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
13572
   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
13573
   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
13574
   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
13575
   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
13576
   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
13577
   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
13578
   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
13579
   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
13580
   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
13581
   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
13582
   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
13583
   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
13584
   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
13585
   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
13586
   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
13587
   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
13588
   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
13589
   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
13590
   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
13591
   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
13592
   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
13593
   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
13594
   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
13595
   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
13596
   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
13597
   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
13598
   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
13599
   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
13600
   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
13601
   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
13602
   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
13603
   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
13604
   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
13605
   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
13606
   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
13607
   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
13608
   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
13609
   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
13610
   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
13611
   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
13612
   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
13613
   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
13614
   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
13615
   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
13616
   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
13617
   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
13618
   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
13619
   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
13620
   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
13621
   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
13622
   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
13623
   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
13624
   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
13625
   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
13626
   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
13627
#endif
13628
#endif
13629
#endif
13630
#endif
13631
#endif
13632
#endif
13633
};
13634
13635
13636
/* find a hole and free as required, return -1 if no hole found */
13637
static int find_hole(void)
13638
{
13639
#ifdef WOLFSSL_NO_MALLOC
13640
   return -1;
13641
#else
13642
   int      x, y, z;
13643
   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
13644
       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
13645
          z = x;
13646
          y = fp_cache[x].lru_count;
13647
       }
13648
   }
13649
13650
   /* decrease all */
13651
   for (x = 0; x < FP_ENTRIES; x++) {
13652
      if (fp_cache[x].lru_count > 3) {
13653
         --(fp_cache[x].lru_count);
13654
      }
13655
   }
13656
13657
   /* free entry z */
13658
   if (z >= 0 && fp_cache[z].g) {
13659
      mp_clear(&fp_cache[z].mu);
13660
      wc_ecc_del_point(fp_cache[z].g);
13661
      fp_cache[z].g  = NULL;
13662
      for (x = 0; x < (1<<FP_LUT); x++) {
13663
         wc_ecc_del_point(fp_cache[z].LUT[x]);
13664
         fp_cache[z].LUT[x] = NULL;
13665
      }
13666
      fp_cache[z].LUT_set = 0;
13667
      fp_cache[z].lru_count = 0;
13668
   }
13669
   return z;
13670
#endif /* !WOLFSSL_NO_MALLOC */
13671
}
13672
13673
/* determine if a base is already in the cache and if so, where */
13674
static int find_base(ecc_point* g)
13675
{
13676
   int x;
13677
   for (x = 0; x < FP_ENTRIES; x++) {
13678
      if (fp_cache[x].g != NULL &&
13679
          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
13680
          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
13681
          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
13682
         break;
13683
      }
13684
   }
13685
   if (x == FP_ENTRIES) {
13686
      x = -1;
13687
   }
13688
   return x;
13689
}
13690
13691
/* add a new base to the cache */
13692
static int add_entry(int idx, ecc_point *g)
13693
{
13694
   unsigned x, y;
13695
13696
   /* allocate base and LUT */
13697
   fp_cache[idx].g = wc_ecc_new_point();
13698
   if (fp_cache[idx].g == NULL) {
13699
      return MP_MEM;
13700
   }
13701
13702
   /* copy x and y */
13703
   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
13704
       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
13705
       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
13706
      wc_ecc_del_point(fp_cache[idx].g);
13707
      fp_cache[idx].g = NULL;
13708
      return MP_MEM;
13709
   }
13710
13711
   for (x = 0; x < (1U<<FP_LUT); x++) {
13712
      fp_cache[idx].LUT[x] = wc_ecc_new_point();
13713
      if (fp_cache[idx].LUT[x] == NULL) {
13714
         for (y = 0; y < x; y++) {
13715
            wc_ecc_del_point(fp_cache[idx].LUT[y]);
13716
            fp_cache[idx].LUT[y] = NULL;
13717
         }
13718
         wc_ecc_del_point(fp_cache[idx].g);
13719
         fp_cache[idx].g         = NULL;
13720
         fp_cache[idx].lru_count = 0;
13721
         return MP_MEM;
13722
      }
13723
   }
13724
13725
   fp_cache[idx].LUT_set   = 0;
13726
   fp_cache[idx].lru_count = 0;
13727
13728
   return MP_OKAY;
13729
}
13730
#endif
13731
13732
#if !defined(WOLFSSL_SP_MATH)
13733
/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
13734
 *
13735
 * The algorithm builds patterns in increasing bit order by first making all
13736
 * single bit input patterns, then all two bit input patterns and so on
13737
 */
13738
static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
13739
    mp_int* mu)
13740
{
13741
   int err;
13742
   unsigned x, y, bitlen, lut_gap;
13743
   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
13744
   int infinity;
13745
13746
#ifdef WOLFSSL_SMALL_STACK
13747
   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13748
       return MEMORY_E;
13749
#endif
13750
13751
   err = mp_init(tmp);
13752
   if (err != MP_OKAY) {
13753
       err = MP_MEM;
13754
       goto errout;
13755
   }
13756
13757
   /* sanity check to make sure lut_order table is of correct size,
13758
      should compile out to a NOP if true */
13759
   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
13760
       err = BAD_FUNC_ARG;
13761
       goto errout;
13762
   }
13763
13764
   /* get bitlen and round up to next multiple of FP_LUT */
13765
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13766
   x       = bitlen % FP_LUT;
13767
   if (x) {
13768
       bitlen += FP_LUT - x;
13769
   }
13770
   lut_gap = bitlen / FP_LUT;
13771
13772
   /* init the mu */
13773
   err = mp_init_copy(&fp_cache[idx].mu, mu);
13774
   if (err != MP_OKAY)
13775
       goto errout;
13776
13777
   /* copy base */
13778
   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
13779
                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
13780
       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
13781
                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
13782
       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
13783
                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
13784
       err = MP_MULMOD_E;
13785
       goto errout;
13786
   }
13787
13788
   /* make all single bit entries */
13789
   for (x = 1; x < FP_LUT; x++) {
13790
      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
13791
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
13792
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
13793
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
13794
          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
13795
                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
13796
          err = MP_INIT_E;
13797
          goto errout;
13798
      } else {
13799
13800
         /* now double it bitlen/FP_LUT times */
13801
         for (y = 0; y < lut_gap; y++) {
13802
             if ((err = ecc_projective_dbl_point_safe(
13803
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13804
                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13805
                                      a, modulus, mp)) != MP_OKAY) {
13806
                 goto errout;
13807
             }
13808
         }
13809
     }
13810
  }
13811
13812
   /* now make all entries in increase order of hamming weight */
13813
   for (x = 2; x <= FP_LUT; x++) {
13814
       if (err != MP_OKAY)
13815
           goto errout;
13816
       for (y = 0; y < (1UL<<FP_LUT); y++) {
13817
           if (lut_orders[y].ham != (int)x) continue;
13818
13819
           /* perform the add */
13820
           if ((err = ecc_projective_add_point_safe(
13821
                           fp_cache[idx].LUT[lut_orders[y].terma],
13822
                           fp_cache[idx].LUT[lut_orders[y].termb],
13823
                           fp_cache[idx].LUT[y], a, modulus, mp,
13824
                           &infinity)) != MP_OKAY) {
13825
               goto errout;
13826
           }
13827
       }
13828
   }
13829
13830
   /* now map all entries back to affine space to make point addition faster */
13831
   for (x = 1; x < (1UL<<FP_LUT); x++) {
13832
       if (err != MP_OKAY)
13833
           break;
13834
13835
       /* convert z to normal from montgomery */
13836
       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
13837
13838
       /* invert it */
13839
       if (err == MP_OKAY)
13840
         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
13841
                         fp_cache[idx].LUT[x]->z);
13842
13843
       if (err == MP_OKAY)
13844
         /* now square it */
13845
         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
13846
13847
       if (err == MP_OKAY)
13848
         /* fix x */
13849
         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
13850
                         fp_cache[idx].LUT[x]->x);
13851
13852
       if (err == MP_OKAY)
13853
         /* get 1/z^3 */
13854
         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
13855
13856
       if (err == MP_OKAY)
13857
         /* fix y */
13858
         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
13859
                         fp_cache[idx].LUT[x]->y);
13860
13861
       if (err == MP_OKAY)
13862
         /* free z */
13863
         mp_clear(fp_cache[idx].LUT[x]->z);
13864
   }
13865
13866
  errout:
13867
13868
   mp_clear(tmp);
13869
   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13870
13871
   if (err == MP_OKAY) {
13872
       fp_cache[idx].LUT_set = 1;
13873
       return MP_OKAY;
13874
   }
13875
13876
   /* err cleanup */
13877
   for (y = 0; y < (1U<<FP_LUT); y++) {
13878
      wc_ecc_del_point(fp_cache[idx].LUT[y]);
13879
      fp_cache[idx].LUT[y] = NULL;
13880
   }
13881
   wc_ecc_del_point(fp_cache[idx].g);
13882
   fp_cache[idx].g         = NULL;
13883
   fp_cache[idx].LUT_set   = 0;
13884
   fp_cache[idx].lru_count = 0;
13885
   mp_clear(&fp_cache[idx].mu);
13886
13887
   return err;
13888
}
13889
13890
/* perform a fixed point ECC mulmod */
13891
static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
13892
                        mp_int* modulus, mp_digit mp, int map)
13893
{
13894
#ifdef WOLFCRYPT_HAVE_SAKKE
13895
    #define KB_SIZE 256
13896
#else
13897
    #define KB_SIZE 128
13898
#endif
13899
13900
#ifdef WOLFSSL_SMALL_STACK
13901
   unsigned char* kb = NULL;
13902
   mp_int*        tk = NULL;
13903
   mp_int*        order = NULL;
13904
#else
13905
   unsigned char kb[KB_SIZE];
13906
   mp_int        tk[1];
13907
   mp_int        order[1];
13908
#endif
13909
   int      x, err;
13910
   unsigned y, z = 0, bitlen, bitpos, lut_gap;
13911
   int first;
13912
   int tk_zeroize = 0;
13913
13914
#ifdef WOLFSSL_SMALL_STACK
13915
   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13916
   if (tk == NULL) {
13917
      err = MEMORY_E; goto done;
13918
   }
13919
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13920
   if (order == NULL) {
13921
      err = MEMORY_E; goto done;
13922
   }
13923
#endif
13924
13925
   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
13926
       err = MP_INIT_E; goto done;
13927
   }
13928
13929
   if ((err = mp_copy(k, tk)) != MP_OKAY)
13930
       goto done;
13931
   tk_zeroize = 1;
13932
13933
#ifdef WOLFSSL_CHECK_MEM_ZERO
13934
   mp_memzero_add("accel_fp_mul tk", tk);
13935
#endif
13936
13937
   /* if it's smaller than modulus we fine */
13938
   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
13939
      /* find order */
13940
       y = (unsigned)mp_unsigned_bin_size(modulus);
13941
      for (x = 0; ecc_sets[x].size; x++) {
13942
         if (y <= (unsigned)ecc_sets[x].size) break;
13943
      }
13944
13945
      /* back off if we are on the 521 bit curve */
13946
      if (y == 66) --x;
13947
13948
      if ((err = mp_read_radix(order, ecc_sets[x].order,
13949
                                                MP_RADIX_HEX)) != MP_OKAY) {
13950
         goto done;
13951
      }
13952
13953
      /* k must be less than modulus */
13954
      if (mp_cmp(tk, order) != MP_LT) {
13955
         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
13956
            goto done;
13957
         }
13958
      }
13959
   }
13960
13961
   /* get bitlen and round up to next multiple of FP_LUT */
13962
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13963
   x       = bitlen % FP_LUT;
13964
   if (x) {
13965
      bitlen += FP_LUT - (unsigned)x;
13966
   }
13967
   lut_gap = bitlen / FP_LUT;
13968
13969
   /* get the k value */
13970
   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
13971
      err = BUFFER_E; goto done;
13972
   }
13973
13974
   /* store k */
13975
#ifdef WOLFSSL_SMALL_STACK
13976
   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13977
   if (kb == NULL) {
13978
      err = MEMORY_E; goto done;
13979
   }
13980
#endif
13981
13982
   XMEMSET(kb, 0, KB_SIZE);
13983
   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
13984
   #ifdef WOLFSSL_CHECK_MEM_ZERO
13985
      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
13986
   #endif
13987
      /* let's reverse kb so it's little endian */
13988
      x = 0;
13989
      y = (unsigned)mp_unsigned_bin_size(tk);
13990
      if (y > 0) {
13991
          y -= 1;
13992
      }
13993
13994
      while ((unsigned)x < y) {
13995
         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
13996
         ++x; --y;
13997
      }
13998
13999
      /* at this point we can start, yipee */
14000
      first = 1;
14001
      for (x = (int)lut_gap-1; x >= 0; x--) {
14002
          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
14003
             by x bits from the start */
14004
          bitpos = (unsigned)x;
14005
          for (y = z = 0; y < FP_LUT; y++) {
14006
             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14007
             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
14008
                                    the mult in each loop */
14009
          }
14010
14011
          /* double if not first */
14012
          if (!first) {
14013
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14014
                                                              mp)) != MP_OKAY) {
14015
                break;
14016
             }
14017
          }
14018
14019
          /* add if not first, otherwise copy */
14020
          if (!first && z) {
14021
             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
14022
                                       R, a, modulus, mp, &first)) != MP_OKAY) {
14023
                break;
14024
             }
14025
          } else if (z) {
14026
             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
14027
                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
14028
                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
14029
                 err = MP_MEM;
14030
                 break;
14031
             }
14032
             first = 0;
14033
          }
14034
      }
14035
   }
14036
14037
   if (err == MP_OKAY) {
14038
      (void) z; /* Acknowledge the unused assignment */
14039
      ForceZero(kb, KB_SIZE);
14040
14041
      /* map R back from projective space */
14042
      if (map) {
14043
         err = ecc_map(R, modulus, mp);
14044
      } else {
14045
         err = MP_OKAY;
14046
      }
14047
   }
14048
14049
done:
14050
   /* cleanup */
14051
   mp_clear(order);
14052
   /* Ensure it was initialized. */
14053
   if (tk_zeroize) {
14054
       mp_forcezero(tk);
14055
   }
14056
14057
#ifdef WOLFSSL_SMALL_STACK
14058
   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14059
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14060
   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14061
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14062
   wc_MemZero_Check(kb, KB_SIZE);
14063
   mp_memzero_check(tk);
14064
#endif
14065
14066
#undef KB_SIZE
14067
14068
   return err;
14069
}
14070
#endif
14071
14072
#ifdef ECC_SHAMIR
14073
#if !defined(WOLFSSL_SP_MATH)
14074
/* perform a fixed point ECC mulmod */
14075
static int accel_fp_mul2add(int idx1, int idx2,
14076
                            mp_int* kA, mp_int* kB,
14077
                            ecc_point *R, mp_int* a,
14078
                            mp_int* modulus, mp_digit mp)
14079
{
14080
#define KB_SIZE 128
14081
14082
#ifdef WOLFSSL_SMALL_STACK
14083
   unsigned char* kb[2] = {NULL, NULL};
14084
   mp_int*        tka = NULL;
14085
   mp_int*        tkb = NULL;
14086
   mp_int*        order = NULL;
14087
#else
14088
   unsigned char kb[2][KB_SIZE];
14089
   mp_int        tka[1];
14090
   mp_int        tkb[1];
14091
   mp_int        order[1];
14092
#endif
14093
   int      x, err;
14094
   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
14095
   int first;
14096
14097
#ifdef WOLFSSL_SMALL_STACK
14098
   /* each is zeroed on acquisition so the cleanup below no-ops if a later
14099
    * allocation fails and the init is skipped */
14100
   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14101
   if (tka == NULL) {
14102
      err = MEMORY_E; goto done;
14103
   }
14104
   XMEMSET(tka, 0, sizeof(mp_int));
14105
   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14106
   if (tkb == NULL) {
14107
      err = MEMORY_E; goto done;
14108
   }
14109
   XMEMSET(tkb, 0, sizeof(mp_int));
14110
   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
14111
   if (order == NULL) {
14112
      err = MEMORY_E; goto done;
14113
   }
14114
   XMEMSET(order, 0, sizeof(mp_int));
14115
#endif
14116
14117
   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
14118
      err = MP_INIT_E; goto done;
14119
   }
14120
14121
   /* if it's smaller than modulus we fine */
14122
   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
14123
      /* find order */
14124
      y = (unsigned)mp_unsigned_bin_size(modulus);
14125
      for (x = 0; ecc_sets[x].size; x++) {
14126
         if (y <= (unsigned)ecc_sets[x].size) break;
14127
      }
14128
14129
      /* back off if we are on the 521 bit curve */
14130
      if (y == 66) --x;
14131
14132
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14133
                                                MP_RADIX_HEX)) != MP_OKAY) {
14134
         goto done;
14135
      }
14136
14137
      /* kA must be less than modulus */
14138
      if (mp_cmp(kA, order) != MP_LT) {
14139
         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
14140
            goto done;
14141
         }
14142
      } else {
14143
         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14144
            goto done;
14145
         }
14146
      }
14147
   } else {
14148
      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
14149
         goto done;
14150
      }
14151
   }
14152
#ifdef WOLFSSL_CHECK_MEM_ZERO
14153
   mp_memzero_add("accel_fp_mul2add tka", tka);
14154
#endif
14155
14156
   /* if it's smaller than modulus we fine */
14157
   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
14158
      /* find order */
14159
      y = (unsigned)mp_unsigned_bin_size(modulus);
14160
      for (x = 0; ecc_sets[x].size; x++) {
14161
         if (y <= (unsigned)ecc_sets[x].size) break;
14162
      }
14163
14164
      /* back off if we are on the 521 bit curve */
14165
      if (y == 66) --x;
14166
14167
      if ((err = mp_read_radix(order, ecc_sets[x].order,
14168
                                                MP_RADIX_HEX)) != MP_OKAY) {
14169
         goto done;
14170
      }
14171
14172
      /* kB must be less than modulus */
14173
      if (mp_cmp(kB, order) != MP_LT) {
14174
         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
14175
            goto done;
14176
         }
14177
      } else {
14178
         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14179
            goto done;
14180
         }
14181
      }
14182
   } else {
14183
      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
14184
         goto done;
14185
      }
14186
   }
14187
#ifdef WOLFSSL_CHECK_MEM_ZERO
14188
   mp_memzero_add("accel_fp_mul2add tkb", tkb);
14189
#endif
14190
14191
   /* get bitlen and round up to next multiple of FP_LUT */
14192
   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
14193
   x       = bitlen % FP_LUT;
14194
   if (x) {
14195
      bitlen += FP_LUT - (unsigned)x;
14196
   }
14197
   lut_gap = bitlen / FP_LUT;
14198
14199
   /* get the k value */
14200
   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
14201
       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
14202
      err = BUFFER_E; goto done;
14203
   }
14204
14205
   /* store k */
14206
#ifdef WOLFSSL_SMALL_STACK
14207
   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14208
   if (kb[0] == NULL) {
14209
      err = MEMORY_E; goto done;
14210
   }
14211
#endif
14212
14213
   XMEMSET(kb[0], 0, KB_SIZE);
14214
   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
14215
      goto done;
14216
   }
14217
#ifdef WOLFSSL_CHECK_MEM_ZERO
14218
   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
14219
#endif
14220
14221
   /* let's reverse kb so it's little endian */
14222
   x = 0;
14223
   y = (unsigned)mp_unsigned_bin_size(tka);
14224
   if (y > 0) {
14225
       y -= 1;
14226
   }
14227
   mp_clear(tka);
14228
   while ((unsigned)x < y) {
14229
      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
14230
      ++x; --y;
14231
   }
14232
14233
   /* store b */
14234
#ifdef WOLFSSL_SMALL_STACK
14235
   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14236
   if (kb[1] == NULL) {
14237
      err = MEMORY_E; goto done;
14238
   }
14239
#endif
14240
14241
   XMEMSET(kb[1], 0, KB_SIZE);
14242
#ifdef WOLFSSL_CHECK_MEM_ZERO
14243
   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
14244
#endif
14245
   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
14246
      x = 0;
14247
      y = (unsigned)mp_unsigned_bin_size(tkb);
14248
      if (y > 0) {
14249
          y -= 1;
14250
      }
14251
14252
      while ((unsigned)x < y) {
14253
         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
14254
         ++x; --y;
14255
      }
14256
14257
      /* at this point we can start, yipee */
14258
      first = 1;
14259
      for (x = (int)lut_gap-1; x >= 0; x--) {
14260
          /* extract FP_LUT bits from kb spread out by lut_gap bits and
14261
             offset by x bits from the start */
14262
          bitpos = (unsigned)x;
14263
          for (y = zA = zB = 0; y < FP_LUT; y++) {
14264
             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14265
             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
14266
             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
14267
                                      the mult in each loop */
14268
          }
14269
14270
          /* double if not first */
14271
          if (!first) {
14272
             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
14273
                                                              mp)) != MP_OKAY) {
14274
                break;
14275
             }
14276
14277
             /* add if not first, otherwise copy */
14278
             if (zA) {
14279
                if ((err = ecc_projective_add_point_safe(R,
14280
                                             fp_cache[idx1].LUT[zA], R, a,
14281
                                             modulus, mp, &first)) != MP_OKAY) {
14282
                   break;
14283
                }
14284
             }
14285
14286
             if (zB) {
14287
                if ((err = ecc_projective_add_point_safe(R,
14288
                                             fp_cache[idx2].LUT[zB], R, a,
14289
                                             modulus, mp, &first)) != MP_OKAY) {
14290
                   break;
14291
                }
14292
             }
14293
          } else {
14294
             if (zA) {
14295
                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
14296
                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
14297
                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
14298
                     err = MP_MEM;
14299
                     break;
14300
                 }
14301
                    first = 0;
14302
             }
14303
             if (zB && first == 0) {
14304
                if ((err = ecc_projective_add_point_safe(R,
14305
                                        fp_cache[idx2].LUT[zB], R, a,
14306
                                        modulus, mp, &first)) != MP_OKAY){
14307
                   break;
14308
                }
14309
             } else if (zB && first == 1) {
14310
                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
14311
                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
14312
                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
14313
                     err = MP_MEM;
14314
                     break;
14315
                 }
14316
                    first = 0;
14317
             }
14318
          }
14319
      }
14320
   }
14321
14322
done:
14323
   /* cleanup */
14324
   mp_forcezero(tkb);
14325
   mp_forcezero(tka);
14326
   mp_clear(order);
14327
14328
#ifdef WOLFSSL_SMALL_STACK
14329
   if (kb[0])
14330
#endif
14331
      ForceZero(kb[0], KB_SIZE);
14332
#ifdef WOLFSSL_SMALL_STACK
14333
   if (kb[1])
14334
#endif
14335
      ForceZero(kb[1], KB_SIZE);
14336
14337
#ifdef WOLFSSL_SMALL_STACK
14338
   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14339
   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
14340
   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14341
   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14342
   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14343
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
14344
   wc_MemZero_Check(kb[1], KB_SIZE);
14345
   wc_MemZero_Check(kb[0], KB_SIZE);
14346
   mp_memzero_check(tkb);
14347
   mp_memzero_check(tka);
14348
#endif
14349
14350
#undef KB_SIZE
14351
14352
    if (err != MP_OKAY)
14353
        return err;
14354
14355
   return ecc_map(R, modulus, mp);
14356
}
14357
14358
14359
/** ECC Fixed Point mulmod global with heap hint used
14360
  Computes kA*A + kB*B = C using Shamir's Trick
14361
  A        First point to multiply
14362
  kA       What to multiple A by
14363
  B        Second point to multiply
14364
  kB       What to multiple B by
14365
  C        [out] Destination point (can overlap with A or B)
14366
  a        ECC curve parameter a
14367
  modulus  Modulus for curve
14368
  return MP_OKAY on success
14369
*/
14370
int ecc_mul2add(ecc_point* A, mp_int* kA,
14371
                ecc_point* B, mp_int* kB,
14372
                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
14373
{
14374
   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
14375
   mp_digit mp = 0;
14376
#ifdef WOLFSSL_SMALL_STACK
14377
   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14378
14379
   if (mu == NULL)
14380
       return MP_MEM;
14381
#else
14382
   mp_int   mu[1];
14383
#endif
14384
14385
   err = mp_init(mu);
14386
   if (err != MP_OKAY) {
14387
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14388
       return err;
14389
   }
14390
14391
#ifndef HAVE_THREAD_LS
14392
#ifndef WOLFSSL_MUTEX_INITIALIZER
14393
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14394
        wc_InitMutex(&ecc_fp_lock);
14395
        initMutex = 1;
14396
   }
14397
#endif
14398
14399
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14400
       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14401
      return BAD_MUTEX_E;
14402
   }
14403
#endif /* HAVE_THREAD_LS */
14404
14405
      /* find point */
14406
      idx1 = find_base(A);
14407
14408
      /* no entry? */
14409
      if (idx1 == -1) {
14410
         /* find hole and add it */
14411
         if ((idx1 = find_hole()) >= 0) {
14412
            err = add_entry(idx1, A);
14413
         }
14414
      }
14415
      if (err == MP_OKAY && idx1 != -1 && fp_cache[idx1].lru_count < (INT_MAX-1)) {
14416
         /* increment LRU */
14417
         ++(fp_cache[idx1].lru_count);
14418
      }
14419
14420
      if (err == MP_OKAY) {
14421
        /* find point */
14422
        idx2 = find_base(B);
14423
14424
        /* no entry? */
14425
        if (idx2 == -1) {
14426
           /* find hole and add it */
14427
           if ((idx2 = find_hole()) >= 0)
14428
              err = add_entry(idx2, B);
14429
         }
14430
      }
14431
14432
      if (err == MP_OKAY && idx2 != -1 && fp_cache[idx2].lru_count < (INT_MAX-1)) {
14433
         /* increment LRU */
14434
         ++(fp_cache[idx2].lru_count);
14435
      }
14436
14437
      if (err == MP_OKAY) {
14438
        /* if it's >= 2 AND the LUT is not set build the LUT */
14439
        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
14440
           /* compute mp */
14441
           err = mp_montgomery_setup(modulus, &mp);
14442
14443
           if (err == MP_OKAY) {
14444
             mpInit = 1;
14445
             err = mp_montgomery_calc_normalization(mu, modulus);
14446
           }
14447
14448
           if (err == MP_OKAY)
14449
             /* build the LUT */
14450
             err = build_lut(idx1, a, modulus, mp, mu);
14451
        }
14452
      }
14453
14454
      if (err == MP_OKAY) {
14455
        /* if it's >= 2 AND the LUT is not set build the LUT */
14456
        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
14457
           if (mpInit == 0) {
14458
                /* compute mp */
14459
                err = mp_montgomery_setup(modulus, &mp);
14460
                if (err == MP_OKAY) {
14461
                    mpInit = 1;
14462
                    err = mp_montgomery_calc_normalization(mu, modulus);
14463
                }
14464
            }
14465
14466
            if (err == MP_OKAY)
14467
              /* build the LUT */
14468
              err = build_lut(idx2, a, modulus, mp, mu);
14469
        }
14470
      }
14471
14472
14473
      if (err == MP_OKAY) {
14474
        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
14475
                                     fp_cache[idx2].LUT_set) {
14476
           if (mpInit == 0) {
14477
              /* compute mp */
14478
              err = mp_montgomery_setup(modulus, &mp);
14479
           }
14480
           if (err == MP_OKAY)
14481
             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
14482
        } else {
14483
           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
14484
        }
14485
      }
14486
14487
#ifndef HAVE_THREAD_LS
14488
    wc_UnLockMutex(&ecc_fp_lock);
14489
#endif /* HAVE_THREAD_LS */
14490
    mp_clear(mu);
14491
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14492
14493
    return err;
14494
}
14495
#endif
14496
#endif /* ECC_SHAMIR */
14497
14498
/** ECC Fixed Point mulmod global
14499
    k        The multiplicand
14500
    G        Base point to multiply
14501
    R        [out] Destination of product
14502
    a        ECC curve parameter a
14503
    modulus  The modulus for the curve
14504
    map      [boolean] If non-zero maps the point back to affine coordinates,
14505
             otherwise it's left in jacobian-montgomery form
14506
    return MP_OKAY if successful
14507
*/
14508
int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
14509
    mp_int* modulus, int map, void* heap)
14510
{
14511
#if !defined(WOLFSSL_SP_MATH)
14512
   int   idx, err = MP_OKAY;
14513
   mp_digit mp = 0;
14514
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
14515
   int      mpSetup = 0;
14516
#ifndef HAVE_THREAD_LS
14517
   int got_ecc_fp_lock = 0;
14518
#endif
14519
14520
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
14521
       return ECC_BAD_ARG_E;
14522
   }
14523
14524
   /* k can't have more bits than modulus count plus 1 */
14525
   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
14526
      return ECC_OUT_OF_RANGE_E;
14527
   }
14528
14529
#ifdef WOLFSSL_SMALL_STACK
14530
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14531
       return MP_MEM;
14532
#endif
14533
14534
   if (mp_init(mu) != MP_OKAY) {
14535
       err = MP_INIT_E;
14536
       goto out;
14537
   }
14538
14539
#ifndef HAVE_THREAD_LS
14540
#ifndef WOLFSSL_MUTEX_INITIALIZER
14541
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14542
        wc_InitMutex(&ecc_fp_lock);
14543
        initMutex = 1;
14544
   }
14545
#endif
14546
14547
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14548
      err = BAD_MUTEX_E;
14549
      goto out;
14550
   }
14551
   got_ecc_fp_lock = 1;
14552
#endif /* HAVE_THREAD_LS */
14553
14554
      /* find point */
14555
      idx = find_base(G);
14556
14557
      /* no entry? */
14558
      if (idx == -1) {
14559
         /* find hole and add it */
14560
         idx = find_hole();
14561
14562
         if (idx >= 0)
14563
            err = add_entry(idx, G);
14564
      }
14565
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14566
         /* increment LRU */
14567
         ++(fp_cache[idx].lru_count);
14568
      }
14569
14570
14571
      if (err == MP_OKAY) {
14572
        /* if it's 2 build the LUT, if it's higher just use the LUT */
14573
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14574
           /* compute mp */
14575
           err = mp_montgomery_setup(modulus, &mp);
14576
14577
           if (err == MP_OKAY) {
14578
             /* compute mu */
14579
             mpSetup = 1;
14580
             err = mp_montgomery_calc_normalization(mu, modulus);
14581
           }
14582
14583
           if (err == MP_OKAY)
14584
             /* build the LUT */
14585
             err = build_lut(idx, a, modulus, mp, mu);
14586
        }
14587
      }
14588
14589
      if (err == MP_OKAY) {
14590
        if (idx >= 0 && fp_cache[idx].LUT_set) {
14591
           if (mpSetup == 0) {
14592
              /* compute mp */
14593
              err = mp_montgomery_setup(modulus, &mp);
14594
           }
14595
           if (err == MP_OKAY)
14596
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14597
        } else {
14598
           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
14599
        }
14600
      }
14601
14602
  out:
14603
14604
#ifndef HAVE_THREAD_LS
14605
    if (got_ecc_fp_lock)
14606
        wc_UnLockMutex(&ecc_fp_lock);
14607
#endif /* HAVE_THREAD_LS */
14608
    mp_clear(mu);
14609
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14610
14611
    return err;
14612
14613
#else /* WOLFSSL_SP_MATH */
14614
14615
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
14616
        return ECC_BAD_ARG_E;
14617
    }
14618
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14619
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14620
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14621
        return IS_POINT_E;
14622
    }
14623
14624
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14625
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14626
        int ret;
14627
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14628
        return ret;
14629
    }
14630
#endif
14631
#ifndef WOLFSSL_SP_NO_256
14632
    if (mp_count_bits(modulus) == 256) {
14633
        int ret;
14634
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14635
        return ret;
14636
    }
14637
#endif
14638
#ifdef WOLFSSL_SP_384
14639
    if (mp_count_bits(modulus) == 384) {
14640
        int ret;
14641
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14642
        return ret;
14643
    }
14644
#endif
14645
#ifdef WOLFSSL_SP_521
14646
    if (mp_count_bits(modulus) == 521) {
14647
        int ret;
14648
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14649
        return ret;
14650
    }
14651
#endif
14652
    return WC_KEY_SIZE_E;
14653
#endif /* WOLFSSL_SP_MATH */
14654
}
14655
14656
/** ECC Fixed Point mulmod global
14657
    k        The multiplicand
14658
    G        Base point to multiply
14659
    R        [out] Destination of product
14660
    a        ECC curve parameter a
14661
    modulus  The modulus for the curve
14662
    map      [boolean] If non-zero maps the point back to affine coordinates,
14663
             otherwise it's left in jacobian-montgomery form
14664
    return MP_OKAY if successful
14665
*/
14666
int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
14667
    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
14668
{
14669
#if !defined(WOLFSSL_SP_MATH)
14670
   int   idx, err = MP_OKAY;
14671
   mp_digit mp = 0;
14672
   WC_DECLARE_VAR(mu, mp_int, 1, 0);
14673
   int      mpSetup = 0;
14674
#ifndef HAVE_THREAD_LS
14675
   int got_ecc_fp_lock = 0;
14676
#endif
14677
14678
   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14679
                                                                order == NULL) {
14680
       return ECC_BAD_ARG_E;
14681
   }
14682
14683
   /* k can't have more bits than order */
14684
   if (mp_count_bits(k) > mp_count_bits(order)) {
14685
      return ECC_OUT_OF_RANGE_E;
14686
   }
14687
14688
#ifdef WOLFSSL_SMALL_STACK
14689
   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14690
       return MP_MEM;
14691
#endif
14692
14693
   if (mp_init(mu) != MP_OKAY) {
14694
       err = MP_INIT_E;
14695
       goto out;
14696
   }
14697
14698
#ifndef HAVE_THREAD_LS
14699
#ifndef WOLFSSL_MUTEX_INITIALIZER
14700
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14701
        wc_InitMutex(&ecc_fp_lock);
14702
        initMutex = 1;
14703
   }
14704
#endif
14705
14706
   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14707
      err = BAD_MUTEX_E;
14708
      goto out;
14709
   }
14710
   got_ecc_fp_lock = 1;
14711
#endif /* HAVE_THREAD_LS */
14712
14713
      /* find point */
14714
      idx = find_base(G);
14715
14716
      /* no entry? */
14717
      if (idx == -1) {
14718
         /* find hole and add it */
14719
         idx = find_hole();
14720
14721
         if (idx >= 0)
14722
            err = add_entry(idx, G);
14723
      }
14724
      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14725
         /* increment LRU */
14726
         ++(fp_cache[idx].lru_count);
14727
      }
14728
14729
14730
      if (err == MP_OKAY) {
14731
        /* if it's 2 build the LUT, if it's higher just use the LUT */
14732
        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14733
           /* compute mp */
14734
           err = mp_montgomery_setup(modulus, &mp);
14735
14736
           if (err == MP_OKAY) {
14737
             /* compute mu */
14738
             mpSetup = 1;
14739
             err = mp_montgomery_calc_normalization(mu, modulus);
14740
           }
14741
14742
           if (err == MP_OKAY)
14743
             /* build the LUT */
14744
             err = build_lut(idx, a, modulus, mp, mu);
14745
        }
14746
      }
14747
14748
      if (err == MP_OKAY) {
14749
        if (idx >= 0 && fp_cache[idx].LUT_set) {
14750
           if (mpSetup == 0) {
14751
              /* compute mp */
14752
              err = mp_montgomery_setup(modulus, &mp);
14753
           }
14754
           if (err == MP_OKAY)
14755
             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14756
        } else {
14757
          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
14758
        }
14759
      }
14760
14761
  out:
14762
14763
#ifndef HAVE_THREAD_LS
14764
    if (got_ecc_fp_lock)
14765
        wc_UnLockMutex(&ecc_fp_lock);
14766
#endif /* HAVE_THREAD_LS */
14767
    mp_clear(mu);
14768
    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14769
14770
    return err;
14771
14772
#else /* WOLFSSL_SP_MATH */
14773
14774
    (void)rng;
14775
14776
    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14777
                                                                order == NULL) {
14778
        return ECC_BAD_ARG_E;
14779
    }
14780
    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14781
        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14782
        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14783
        return IS_POINT_E;
14784
    }
14785
14786
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14787
    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14788
        int ret;
14789
        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14790
        return ret;
14791
    }
14792
#endif
14793
#ifndef WOLFSSL_SP_NO_256
14794
    if (mp_count_bits(modulus) == 256) {
14795
        int ret;
14796
        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14797
        return ret;
14798
    }
14799
#endif
14800
#ifdef WOLFSSL_SP_384
14801
    if (mp_count_bits(modulus) == 384) {
14802
        int ret;
14803
        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14804
        return ret;
14805
    }
14806
#endif
14807
#ifdef WOLFSSL_SP_521
14808
    if (mp_count_bits(modulus) == 521) {
14809
        int ret;
14810
        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14811
        return ret;
14812
    }
14813
#endif
14814
    return WC_KEY_SIZE_E;
14815
#endif /* WOLFSSL_SP_MATH */
14816
}
14817
14818
#if !defined(WOLFSSL_SP_MATH)
14819
/* helper function for freeing the cache ...
14820
   must be called with the cache mutex locked */
14821
static void wc_ecc_fp_free_cache(void)
14822
{
14823
   unsigned x, y;
14824
   for (x = 0; x < FP_ENTRIES; x++) {
14825
      if (fp_cache[x].g != NULL) {
14826
         for (y = 0; y < (1U<<FP_LUT); y++) {
14827
            wc_ecc_del_point(fp_cache[x].LUT[y]);
14828
            fp_cache[x].LUT[y] = NULL;
14829
         }
14830
         wc_ecc_del_point(fp_cache[x].g);
14831
         fp_cache[x].g         = NULL;
14832
         mp_clear(&fp_cache[x].mu);
14833
         fp_cache[x].LUT_set   = 0;
14834
         fp_cache[x].lru_count = 0;
14835
         fp_cache[x].lock = 0;
14836
      }
14837
   }
14838
}
14839
#endif
14840
14841
14842
/** Init the Fixed Point cache */
14843
void wc_ecc_fp_init(void)
14844
{
14845
#ifndef WOLFSSL_SP_MATH
14846
#ifndef HAVE_THREAD_LS
14847
#ifndef WOLFSSL_MUTEX_INITIALIZER
14848
   if (initMutex == 0) {
14849
        wc_InitMutex(&ecc_fp_lock);
14850
        initMutex = 1;
14851
   }
14852
#endif
14853
#endif
14854
#endif
14855
}
14856
14857
14858
/** Free the Fixed Point cache */
14859
WOLFSSL_ABI
14860
void wc_ecc_fp_free(void)
14861
{
14862
#if !defined(WOLFSSL_SP_MATH)
14863
#ifndef HAVE_THREAD_LS
14864
#ifndef WOLFSSL_MUTEX_INITIALIZER
14865
   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14866
        wc_InitMutex(&ecc_fp_lock);
14867
        initMutex = 1;
14868
   }
14869
#endif
14870
14871
   if (wc_LockMutex(&ecc_fp_lock) == 0) {
14872
#endif /* HAVE_THREAD_LS */
14873
14874
       wc_ecc_fp_free_cache();
14875
14876
#ifndef HAVE_THREAD_LS
14877
       wc_UnLockMutex(&ecc_fp_lock);
14878
#ifndef WOLFSSL_MUTEX_INITIALIZER
14879
       wc_FreeMutex(&ecc_fp_lock);
14880
       initMutex = 0;
14881
#endif
14882
   }
14883
#endif /* HAVE_THREAD_LS */
14884
#endif
14885
}
14886
14887
14888
#endif /* FP_ECC */
14889
14890
int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
14891
1.09k
{
14892
1.09k
    int err = 0;
14893
14894
1.09k
#ifdef ECC_TIMING_RESISTANT
14895
1.09k
    if (key == NULL) {
14896
0
        err = BAD_FUNC_ARG;
14897
0
    }
14898
1.09k
    else {
14899
1.09k
        key->rng = rng;
14900
1.09k
    }
14901
#else
14902
    (void)key;
14903
    (void)rng;
14904
    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
14905
#endif
14906
14907
1.09k
    return err;
14908
1.09k
}
14909
14910
#ifdef HAVE_ECC_ENCRYPT
14911
14912
14913
enum ecCliState {
14914
    ecCLI_INIT      = 1,
14915
    ecCLI_SALT_GET  = 2,
14916
    ecCLI_SALT_SET  = 3,
14917
    ecCLI_SENT_REQ  = 4,
14918
    ecCLI_RECV_RESP = 5,
14919
    ecCLI_BAD_STATE = 99
14920
};
14921
14922
enum ecSrvState {
14923
    ecSRV_INIT      = 1,
14924
    ecSRV_SALT_GET  = 2,
14925
    ecSRV_SALT_SET  = 3,
14926
    ecSRV_RECV_REQ  = 4,
14927
    ecSRV_SENT_RESP = 5,
14928
    ecSRV_BAD_STATE = 99
14929
};
14930
14931
14932
struct ecEncCtx {
14933
    byte* kdfSalt;         /* optional salt for kdf */
14934
    const byte* kdfInfo;   /* optional info for kdf */
14935
    const byte* macSalt;   /* optional salt for mac */
14936
    word32    kdfSaltSz;   /* size of kdfSalt */
14937
    word32    kdfInfoSz;   /* size of kdfInfo */
14938
    word32    macSaltSz;   /* size of macSalt */
14939
    void*     heap;        /* heap hint for memory used */
14940
    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14941
    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14942
    byte      encAlgo;     /* which encryption type */
14943
    byte      kdfAlgo;     /* which key derivation function type */
14944
    byte      macAlgo;     /* which mac function type */
14945
    byte      protocol;    /* are we REQ_RESP client or server ? */
14946
    byte      cliSt;       /* protocol state, for sanity checks */
14947
    byte      srvSt;       /* protocol state, for sanity checks */
14948
    WC_RNG*   rng;
14949
};
14950
14951
/* optional set info, can be called before or after set_peer_salt */
14952
int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
14953
{
14954
    if (ctx == NULL)
14955
        return BAD_FUNC_ARG;
14956
14957
    ctx->encAlgo = encAlgo;
14958
    ctx->kdfAlgo = kdfAlgo;
14959
    ctx->macAlgo = macAlgo;
14960
14961
    return 0;
14962
}
14963
14964
#ifdef WOLF_CRYPTO_CB
14965
/* Read back the parameters a caller configured on the context.  Intended for
14966
 * crypto-callback backends (e.g. a hardware ECIES engine) that must reproduce
14967
 * the algorithm, KDF salt and KDF info to run the operation off-device.  Only
14968
 * built when crypto callbacks are enabled, so default builds are unaffected. */
14969
int wc_ecc_ctx_get_algo(ecEncCtx* ctx, byte* encAlgo, byte* kdfAlgo,
14970
                        byte* macAlgo)
14971
{
14972
    if (ctx == NULL)
14973
        return BAD_FUNC_ARG;
14974
14975
    if (encAlgo != NULL)
14976
        *encAlgo = ctx->encAlgo;
14977
    if (kdfAlgo != NULL)
14978
        *kdfAlgo = ctx->kdfAlgo;
14979
    if (macAlgo != NULL)
14980
        *macAlgo = ctx->macAlgo;
14981
14982
    return 0;
14983
}
14984
14985
int wc_ecc_ctx_get_kdf_salt(ecEncCtx* ctx, const byte** salt, word32* sz)
14986
{
14987
    if (ctx == NULL || salt == NULL || sz == NULL)
14988
        return BAD_FUNC_ARG;
14989
14990
    *salt = ctx->kdfSalt;
14991
    *sz   = ctx->kdfSaltSz;
14992
14993
    return 0;
14994
}
14995
14996
int wc_ecc_ctx_get_info(ecEncCtx* ctx, const byte** info, word32* sz)
14997
{
14998
    if (ctx == NULL || info == NULL || sz == NULL)
14999
        return BAD_FUNC_ARG;
15000
15001
    *info = ctx->kdfInfo;
15002
    *sz   = ctx->kdfInfoSz;
15003
15004
    return 0;
15005
}
15006
#endif /* WOLF_CRYPTO_CB */
15007
15008
15009
const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
15010
{
15011
    if (ctx == NULL || ctx->protocol == 0)
15012
        return NULL;
15013
15014
    if (ctx->protocol == REQ_RESP_CLIENT) {
15015
        if (ctx->cliSt == ecCLI_INIT) {
15016
            ctx->cliSt =  ecCLI_SALT_GET;
15017
            return ctx->clientSalt;
15018
        }
15019
        else {
15020
            ctx->cliSt = ecCLI_BAD_STATE;
15021
            return NULL;
15022
        }
15023
    }
15024
    else if (ctx->protocol == REQ_RESP_SERVER) {
15025
        if (ctx->srvSt == ecSRV_INIT) {
15026
            ctx->srvSt =  ecSRV_SALT_GET;
15027
            return ctx->serverSalt;
15028
        }
15029
        else {
15030
            ctx->srvSt = ecSRV_BAD_STATE;
15031
            return NULL;
15032
        }
15033
    }
15034
15035
    return NULL;
15036
}
15037
15038
15039
/* optional set info, can be called before or after set_peer_salt */
15040
int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
15041
{
15042
    if (ctx == NULL || info == 0 || sz < 0)
15043
        return BAD_FUNC_ARG;
15044
15045
    ctx->kdfInfo   = info;
15046
    ctx->kdfInfoSz = (word32)sz;
15047
15048
    return 0;
15049
}
15050
15051
15052
static const char* exchange_info = "Secure Message Exchange";
15053
15054
int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
15055
{
15056
    byte tmp[EXCHANGE_SALT_SZ/2];
15057
    int  halfSz = EXCHANGE_SALT_SZ/2;
15058
15059
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15060
        return BAD_FUNC_ARG;
15061
15062
    if (ctx->protocol == REQ_RESP_CLIENT) {
15063
        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
15064
        if (ctx->cliSt == ecCLI_SALT_GET)
15065
            ctx->cliSt =  ecCLI_SALT_SET;
15066
        else {
15067
            ctx->cliSt =  ecCLI_BAD_STATE;
15068
            return BAD_STATE_E;
15069
        }
15070
    }
15071
    else {
15072
        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
15073
        if (ctx->srvSt == ecSRV_SALT_GET)
15074
            ctx->srvSt =  ecSRV_SALT_SET;
15075
        else {
15076
            ctx->srvSt =  ecSRV_BAD_STATE;
15077
            return BAD_STATE_E;
15078
        }
15079
    }
15080
15081
    /* mix half and half */
15082
    /* tmp stores 2nd half of client before overwrite */
15083
    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
15084
    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
15085
    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
15086
15087
    ctx->kdfSalt   = ctx->clientSalt;
15088
    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
15089
15090
    ctx->macSalt   = ctx->serverSalt;
15091
    ctx->macSaltSz = EXCHANGE_SALT_SZ;
15092
15093
    if (ctx->kdfInfo == NULL) {
15094
        /* default info */
15095
        ctx->kdfInfo   = (const byte*)exchange_info;
15096
        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
15097
    }
15098
15099
    return 0;
15100
}
15101
15102
/* Set the salt pointer into context.
15103
 *
15104
 * @param  [in, out]  ctx   ECIES context object.
15105
 * @param  [in]       salt  Salt to use with KDF.
15106
 * @param  [in]       sz    Length of salt in bytes.
15107
 * @return  0 on success.
15108
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15109
 */
15110
int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15111
{
15112
    if (ctx == NULL || (salt == NULL && sz != 0))
15113
        return BAD_FUNC_ARG;
15114
15115
    /* truncate salt if exceeds max */
15116
    if (sz > EXCHANGE_SALT_SZ)
15117
        sz = EXCHANGE_SALT_SZ;
15118
15119
    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
15120
     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
15121
    if (ctx->protocol == REQ_RESP_CLIENT) {
15122
        ctx->cliSt = ecCLI_SALT_SET;
15123
        ctx->kdfSalt = ctx->clientSalt;
15124
    }
15125
    else if (ctx->protocol == REQ_RESP_SERVER) {
15126
        ctx->srvSt = ecSRV_SALT_SET;
15127
        ctx->kdfSalt = ctx->serverSalt;
15128
    }
15129
15130
    if (salt != NULL) {
15131
        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
15132
    }
15133
    ctx->kdfSaltSz = sz;
15134
15135
    return 0;
15136
}
15137
15138
/* Set your own salt. By default we generate a random salt for ourselves.
15139
 * This allows overriding that after init or reset.
15140
 *
15141
 * @param  [in, out]  ctx   ECIES context object.
15142
 * @param  [in]       salt  Salt to use for ourselves
15143
 * @param  [in]       sz    Length of salt in bytes.
15144
 * @return  0 on success.
15145
 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
15146
 */
15147
int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
15148
{
15149
    byte* saltBuffer;
15150
15151
    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
15152
        return BAD_FUNC_ARG;
15153
15154
    if (sz > EXCHANGE_SALT_SZ)
15155
        sz = EXCHANGE_SALT_SZ;
15156
    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
15157
        ctx->clientSalt :
15158
        ctx->serverSalt;
15159
    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
15160
    XMEMCPY(saltBuffer, salt, sz);
15161
15162
    return 0;
15163
}
15164
15165
15166
static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
15167
{
15168
    byte* saltBuffer;
15169
15170
    if (ctx == NULL || flags == 0)
15171
        return BAD_FUNC_ARG;
15172
15173
    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
15174
15175
    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
15176
}
15177
15178
static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
15179
{
15180
    if (ctx) {
15181
        XMEMSET(ctx, 0, sizeof(ecEncCtx));
15182
15183
    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15184
        #ifdef WOLFSSL_AES_128
15185
            ctx->encAlgo  = ecAES_128_CBC;
15186
        #else
15187
            ctx->encAlgo  = ecAES_256_CBC;
15188
        #endif
15189
    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15190
        #ifdef WOLFSSL_AES_256
15191
            ctx->encAlgo  = ecAES_256_CTR;
15192
        #else
15193
            ctx->encAlgo  = ecAES_128_CTR;
15194
        #endif
15195
    #elif !defined(NO_AES) && defined(HAVE_AESGCM) && \
15196
        (defined(WOLFSSL_ECIES_OLD) || defined(WOLFSSL_ECIES_GEN_IV) || \
15197
         defined(WOLFSSL_ECIES_STATIC_GCM_NONCE))
15198
        /* Only default to GCM when the configured IV mode permits it, so a
15199
         * GCM-only build cannot default to an algorithm that encrypt/decrypt
15200
         * would reject with NOT_COMPILED_IN. */
15201
        #ifdef WOLFSSL_AES_128
15202
            ctx->encAlgo  = ecAES_128_GCM;
15203
        #else
15204
            ctx->encAlgo  = ecAES_256_GCM;
15205
        #endif
15206
    #else
15207
        /* In a GCM-only build using the default IV mode, define
15208
         * WOLFSSL_ECIES_STATIC_GCM_NONCE to opt in to the fixed-nonce DEM. */
15209
        #error "No valid encryption algorithm for ECIES configured."
15210
    #endif
15211
        ctx->kdfAlgo  = ecHKDF_SHA256;
15212
        ctx->macAlgo  = ecHMAC_SHA256;
15213
        ctx->protocol = (byte)flags;
15214
        ctx->rng      = rng;
15215
15216
        if (flags == REQ_RESP_CLIENT)
15217
            ctx->cliSt = ecCLI_INIT;
15218
        if (flags == REQ_RESP_SERVER)
15219
            ctx->srvSt = ecSRV_INIT;
15220
    }
15221
}
15222
15223
15224
/* allow ecc context reset so user doesn't have to init/free for reuse */
15225
WOLFSSL_ABI
15226
int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
15227
{
15228
    void* heap;
15229
15230
    if (ctx == NULL || rng == NULL)
15231
        return BAD_FUNC_ARG;
15232
15233
    /* ecc_ctx_init clears the whole context, so carry the heap hint over it.
15234
     * The context has to be freed to the heap it was allocated from. */
15235
    heap = ctx->heap;
15236
    ecc_ctx_init(ctx, ctx->protocol, rng);
15237
    ctx->heap = heap;
15238
15239
    return ecc_ctx_set_salt(ctx, ctx->protocol);
15240
}
15241
15242
15243
ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
15244
{
15245
    int       ret = 0;
15246
    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
15247
                                                              DYNAMIC_TYPE_ECC);
15248
15249
    if (ctx) {
15250
        ctx->protocol = (byte)flags;
15251
        ctx->heap     = heap;
15252
    }
15253
15254
    ret = wc_ecc_ctx_reset(ctx, rng);
15255
    if (ret != 0) {
15256
        wc_ecc_ctx_free(ctx);
15257
        ctx = NULL;
15258
    }
15259
15260
    return ctx;
15261
}
15262
15263
15264
/* alloc/init and set defaults, return new Context  */
15265
WOLFSSL_ABI
15266
ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
15267
{
15268
    return wc_ecc_ctx_new_ex(flags, rng, NULL);
15269
}
15270
15271
15272
/* free any resources, clear any keys */
15273
WOLFSSL_ABI
15274
void wc_ecc_ctx_free(ecEncCtx* ctx)
15275
{
15276
    if (ctx) {
15277
        void* heap = ctx->heap;
15278
        ForceZero(ctx, sizeof(ecEncCtx));
15279
        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
15280
        (void)heap;
15281
    }
15282
}
15283
15284
#if !defined(NO_AES) && defined(HAVE_AESGCM)
15285
/* Is the ECIES encryption algorithm an AES-GCM (AEAD) mode?  GCM replaces the
15286
 * AES + HMAC pair with a single authenticated-encryption pass. */
15287
static WC_INLINE int ecc_is_gcm(byte encAlgo)
15288
{
15289
    return (encAlgo == ecAES_128_GCM || encAlgo == ecAES_256_GCM);
15290
}
15291
#else
15292
/* Compile GCM branches out entirely when AES-GCM isn't available. */
15293
#define ecc_is_gcm(encAlgo) (0)
15294
#endif
15295
15296
static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
15297
                             int* keysLen, word32* digestSz, word32* blockSz)
15298
{
15299
    if (ctx) {
15300
        switch (ctx->encAlgo) {
15301
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15302
            case ecAES_128_CBC:
15303
                *encKeySz = KEY_SIZE_128;
15304
                *ivSz     = IV_SIZE_128;
15305
                *blockSz  = WC_AES_BLOCK_SIZE;
15306
                break;
15307
            case ecAES_256_CBC:
15308
                *encKeySz = KEY_SIZE_256;
15309
                *ivSz     = IV_SIZE_128;
15310
                *blockSz  = WC_AES_BLOCK_SIZE;
15311
                break;
15312
        #endif
15313
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15314
            case ecAES_128_CTR:
15315
                *encKeySz = KEY_SIZE_128;
15316
                *ivSz     = 12;
15317
                *blockSz  = 1;
15318
                break;
15319
            case ecAES_256_CTR:
15320
                *encKeySz = KEY_SIZE_256;
15321
                *ivSz     = 12;
15322
                *blockSz  = 1;
15323
                break;
15324
        #endif
15325
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
15326
            case ecAES_128_GCM:
15327
                *encKeySz = KEY_SIZE_128;
15328
                *ivSz     = GCM_NONCE_MID_SZ;
15329
                *blockSz  = 1;
15330
                break;
15331
            case ecAES_256_GCM:
15332
                *encKeySz = KEY_SIZE_256;
15333
                *ivSz     = GCM_NONCE_MID_SZ;
15334
                *blockSz  = 1;
15335
                break;
15336
        #endif
15337
            default:
15338
                return BAD_FUNC_ARG;
15339
        }
15340
15341
        if (ecc_is_gcm(ctx->encAlgo)) {
15342
            /* GCM is AEAD: the full block-sized tag replaces the HMAC digest,
15343
             * and no separate MAC algorithm/key is used. */
15344
            *digestSz = WC_AES_BLOCK_SIZE;
15345
        }
15346
        else {
15347
            switch (ctx->macAlgo) {
15348
                case ecHMAC_SHA256:
15349
                    *digestSz = WC_SHA256_DIGEST_SIZE;
15350
                    break;
15351
                default:
15352
                    return BAD_FUNC_ARG;
15353
            }
15354
        }
15355
    } else
15356
        return BAD_FUNC_ARG;
15357
15358
    if (ecc_is_gcm(ctx->encAlgo)) {
15359
        /* No MAC key.  The nonce follows the ECIES IV build mode, matching the
15360
         * CBC/CTR DEMs: derived from the KDF (OLD), a fresh random value
15361
         * (GEN_IV), or a fixed zero (default). */
15362
#ifdef WOLFSSL_ECIES_OLD
15363
        *keysLen = *encKeySz + *ivSz;   /* nonce is part of the KDF output */
15364
#else
15365
        *keysLen = *encKeySz;
15366
#endif
15367
    }
15368
    else {
15369
#ifdef WOLFSSL_ECIES_OLD
15370
        *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
15371
#else
15372
        *keysLen  = *encKeySz + (int)*digestSz;
15373
#endif
15374
    }
15375
15376
    return 0;
15377
}
15378
15379
/* Total ECIES output size for msgSz bytes of message: the ephemeral public
15380
 * key (not embedded in the OLD format), the IV/nonce when it is carried in
15381
 * the message (GEN_IV mode only), the ciphertext (same length as the padded
15382
 * plaintext), and the trailing HMAC digest or GCM tag.  Used both to
15383
 * bound-check the caller's output buffer and to report the final output
15384
 * size. */
15385
static word32 ecc_ecies_total_size(word32 pubKeySz, int ivSz, word32 msgSz,
15386
                                   word32 digestSz)
15387
{
15388
#ifdef WOLFSSL_ECIES_OLD
15389
    (void)pubKeySz;
15390
    (void)ivSz;
15391
    return msgSz + digestSz;
15392
#elif defined(WOLFSSL_ECIES_GEN_IV)
15393
    return pubKeySz + (word32)ivSz + msgSz + digestSz;
15394
#else
15395
    (void)ivSz;
15396
    return pubKeySz + msgSz + digestSz;
15397
#endif
15398
}
15399
15400
/* Validate and advance the single-use REQ/RESP protocol state for an encrypt.
15401
 * A no-op for the default (non REQ/RESP) protocol.  Returns BAD_STATE_E if the
15402
 * ctx is not in the state that permits an encrypt. */
15403
static int ecc_ctx_encrypt_advance(ecEncCtx* ctx)
15404
{
15405
    if (ctx == NULL)
15406
        return 0;
15407
    if (ctx->protocol == REQ_RESP_SERVER) {
15408
        if (ctx->srvSt != ecSRV_RECV_REQ)
15409
            return BAD_STATE_E;
15410
        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
15411
    }
15412
    else if (ctx->protocol == REQ_RESP_CLIENT) {
15413
        if (ctx->cliSt != ecCLI_SALT_SET)
15414
            return BAD_STATE_E;
15415
        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
15416
    }
15417
    return 0;
15418
}
15419
15420
/* Validate and advance the single-use REQ/RESP protocol state for a decrypt. */
15421
static int ecc_ctx_decrypt_advance(ecEncCtx* ctx)
15422
{
15423
    if (ctx == NULL)
15424
        return 0;
15425
    if (ctx->protocol == REQ_RESP_CLIENT) {
15426
        if (ctx->cliSt != ecCLI_SENT_REQ)
15427
            return BAD_STATE_E;
15428
        ctx->cliSt = ecCLI_BAD_STATE; /* we're done no more ops allowed */
15429
    }
15430
    else if (ctx->protocol == REQ_RESP_SERVER) {
15431
        if (ctx->srvSt != ecSRV_SALT_SET)
15432
            return BAD_STATE_E;
15433
        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
15434
    }
15435
    return 0;
15436
}
15437
15438
15439
/* ecc encrypt with shared secret run through kdf
15440
   ctx holds non default algos and inputs
15441
   msgSz should be the right size for encAlgo, i.e., already padded
15442
   return 0 on success */
15443
int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15444
    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
15445
{
15446
    int          ret = 0;
15447
    word32       blockSz = 0;
15448
#ifndef WOLFSSL_ECIES_OLD
15449
#ifndef WOLFSSL_ECIES_GEN_IV
15450
    byte         iv[ECC_MAX_IV_SIZE];
15451
#endif
15452
#endif
15453
    /* Not in the output in OLD mode; kept 0 for ecc_ecies_total_size(). */
15454
    word32       pubKeySz = 0;
15455
    word32       digestSz = 0;
15456
    ecEncCtx     localCtx;
15457
#ifdef WOLFSSL_SMALL_STACK
15458
    byte*        sharedSecret;
15459
    byte*        keys;
15460
#else
15461
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15462
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
15463
#else
15464
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
15465
#endif
15466
    byte         keys[ECC_BUFSIZE];         /* max size */
15467
#endif
15468
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15469
    word32       sharedSz = ECC_MAXSIZE;
15470
#else
15471
    /* 'Uncompressed' byte | public key x | public key y | secret */
15472
    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
15473
#endif
15474
    int          keysLen = 0;
15475
    int          encKeySz = 0;
15476
    int          ivSz = 0;
15477
    int          offset = 0;         /* keys offset if doing msg exchange */
15478
    byte*        encKey = NULL;
15479
    byte*        encIv = NULL;
15480
    byte*        macKey = NULL;
15481
    /* devId to hand the DEM AES/HMAC primitives; ecc_key only carries a devId
15482
     * field with PLUTON_CRYPTO_ECC or WOLF_CRYPTO_CB, so default to INVALID. */
15483
    int          eciesDevId = INVALID_DEVID;
15484
15485
    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
15486
                           outSz  == NULL)
15487
        return BAD_FUNC_ARG;
15488
15489
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
15490
    eciesDevId = privKey->devId;
15491
#endif
15492
15493
#ifdef WOLF_CRYPTO_CB
15494
    #ifndef WOLF_CRYPTO_CB_FIND
15495
    if (privKey->devId != INVALID_DEVID)
15496
    #endif
15497
    {
15498
        /* Snapshot single-use state so we can tell whether the callback handled
15499
         * it purely in hardware (state untouched) versus re-entered software
15500
         * (which advances the state itself, below). */
15501
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
15502
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
15503
        ret = wc_CryptoCb_EciesEncrypt(privKey, pubKey, msg, msgSz, out, outSz,
15504
                                       ctx, compressed);
15505
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
15506
            /* Pure-hardware service left the state alone; enforce single-use
15507
             * here so the ctx can't be reused (nonce reuse for static-nonce
15508
             * GCM).  A re-entrant software callback already advanced it. */
15509
            if (ret == 0 && ctx != NULL &&
15510
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
15511
                ret = ecc_ctx_encrypt_advance(ctx);
15512
            return ret;
15513
        }
15514
        /* fall-through to software (ret is reassigned below) */
15515
    }
15516
#endif
15517
15518
    if (ctx == NULL) {  /* use defaults */
15519
        ecc_ctx_init(&localCtx, 0, NULL);
15520
        ctx = &localCtx;
15521
    }
15522
15523
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
15524
                            &blockSz);
15525
    if (ret != 0)
15526
        return ret;
15527
15528
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
15529
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
15530
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
15531
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
15532
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
15533
    if (ecc_is_gcm(ctx->encAlgo))
15534
        return NOT_COMPILED_IN;
15535
#endif
15536
15537
#ifndef WOLFSSL_ECIES_OLD
15538
    if (!compressed) {
15539
        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
15540
    }
15541
    else {
15542
        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
15543
    }
15544
#else
15545
    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
15546
#endif
15547
15548
    if (ctx->protocol == REQ_RESP_SERVER) {
15549
        offset = keysLen;
15550
        keysLen *= 2;
15551
    }
15552
15553
    /* Validate and advance the single-use state (also covers a re-entrant
15554
     * software CryptoCb call; the hardware path handles it before dispatch). */
15555
    ret = ecc_ctx_encrypt_advance(ctx);
15556
    if (ret != 0)
15557
        return ret;
15558
15559
    if (keysLen > ECC_BUFSIZE) /* keys size */
15560
        return BUFFER_E;
15561
15562
    if ((msgSz % blockSz) != 0)
15563
        return BAD_PADDING_E;
15564
15565
    /* The nonce/IV is embedded in the output only in GEN_IV mode; OLD derives
15566
     * it from the KDF and default uses a fixed nonce (neither is sent). */
15567
    if (*outSz < ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz))
15568
        return BUFFER_E;
15569
15570
#ifdef ECC_TIMING_RESISTANT
15571
    if (ctx->rng != NULL && privKey->rng == NULL)
15572
        privKey->rng = ctx->rng;
15573
#endif
15574
15575
#ifndef WOLFSSL_ECIES_OLD
15576
    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
15577
#ifdef ECC_TIMING_RESISTANT
15578
        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
15579
#else
15580
        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
15581
#endif
15582
        if (ret != 0)
15583
            return ret;
15584
    }
15585
    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
15586
    if (ret != 0)
15587
        return ret;
15588
    out += pubKeySz;
15589
#endif
15590
15591
#ifdef WOLFSSL_SMALL_STACK
15592
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15593
    if (sharedSecret == NULL)
15594
        return MEMORY_E;
15595
15596
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15597
    if (keys == NULL) {
15598
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15599
        return MEMORY_E;
15600
    }
15601
#endif
15602
15603
#ifdef WOLFSSL_ECIES_ISO18033
15604
    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
15605
    sharedSz -= pubKeySz;
15606
#endif
15607
15608
    do {
15609
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
15610
        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
15611
        if (ret != 0)
15612
            break;
15613
    #endif
15614
    #ifndef WOLFSSL_ECIES_ISO18033
15615
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
15616
    #else
15617
        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
15618
                                                                     &sharedSz);
15619
    #endif
15620
    }
15621
    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
15622
15623
    if (ret == 0) {
15624
    #ifdef WOLFSSL_ECIES_ISO18033
15625
        /* KDF data is encoded public key and secret. */
15626
        sharedSz += pubKeySz;
15627
    #endif
15628
        switch (ctx->kdfAlgo) {
15629
            case ecHKDF_SHA256 :
15630
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
15631
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15632
                           keys, (word32)keysLen);
15633
                break;
15634
            case ecHKDF_SHA1 :
15635
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
15636
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15637
                           keys, (word32)keysLen);
15638
                break;
15639
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15640
            case ecKDF_X963_SHA1 :
15641
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15642
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15643
                break;
15644
            case ecKDF_X963_SHA256 :
15645
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15646
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15647
                break;
15648
            case ecKDF_SHA1 :
15649
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15650
                           NULL, 0, keys, (word32)keysLen);
15651
                break;
15652
            case ecKDF_SHA256 :
15653
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15654
                           NULL, 0, keys, (word32)keysLen);
15655
                break;
15656
#endif
15657
15658
15659
            default:
15660
                ret = BAD_FUNC_ARG;
15661
                break;
15662
        }
15663
    }
15664
15665
    if (ret == 0) {
15666
        if (ecc_is_gcm(ctx->encAlgo)) {
15667
            /* GCM nonce follows the ECIES IV build mode, matching CBC/CTR:
15668
             * OLD -> from the KDF output; GEN_IV -> fresh random, embedded;
15669
             * default -> fixed zero.  No MAC key. */
15670
            encKey = keys + offset;
15671
            macKey = NULL;
15672
#ifdef WOLFSSL_ECIES_OLD
15673
            encIv  = encKey + encKeySz;
15674
#elif defined(WOLFSSL_ECIES_GEN_IV)
15675
            {
15676
                WC_RNG* rng = (privKey->rng != NULL) ? privKey->rng : ctx->rng;
15677
                encIv  = out;
15678
                out   += ivSz;
15679
                if (rng == NULL)
15680
                    ret = MISSING_RNG_E;
15681
                else
15682
                    ret = wc_RNG_GenerateBlock(rng, encIv, (word32)ivSz);
15683
            }
15684
#else
15685
            XMEMSET(iv, 0, (size_t)ivSz);
15686
            encIv  = iv;
15687
#endif
15688
        }
15689
        else {
15690
    #ifdef WOLFSSL_ECIES_OLD
15691
            encKey = keys + offset;
15692
            encIv  = encKey + encKeySz;
15693
            macKey = encKey + encKeySz + ivSz;
15694
    #elif defined(WOLFSSL_ECIES_GEN_IV)
15695
            encKey = keys + offset;
15696
            encIv  = out;
15697
            out += ivSz;
15698
            macKey = encKey + encKeySz;
15699
            ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
15700
    #else
15701
            XMEMSET(iv, 0, (size_t)ivSz);
15702
            encKey = keys + offset;
15703
            encIv  = iv;
15704
            macKey = encKey + encKeySz;
15705
    #endif
15706
        }
15707
    }
15708
15709
    if (ret == 0) {
15710
       switch (ctx->encAlgo) {
15711
            case ecAES_128_CBC:
15712
            case ecAES_256_CBC:
15713
            {
15714
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15715
            #ifdef WOLFSSL_SMALL_STACK
15716
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15717
                                          DYNAMIC_TYPE_AES);
15718
                if (aes == NULL) {
15719
                    ret = MEMORY_E;
15720
                    break;
15721
                }
15722
            #else
15723
                Aes aes[1];
15724
            #endif
15725
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15726
                if (ret == 0) {
15727
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
15728
                                                                AES_ENCRYPTION);
15729
                    if (ret == 0) {
15730
                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
15731
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15732
                                                    defined(WC_ASYNC_ENABLE_AES)
15733
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15734
                                            WC_ASYNC_FLAG_NONE);
15735
                    #endif
15736
                    }
15737
                    wc_AesFree(aes);
15738
                }
15739
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15740
        #else
15741
                ret = NOT_COMPILED_IN;
15742
        #endif
15743
                break;
15744
            }
15745
            case ecAES_128_CTR:
15746
            case ecAES_256_CTR:
15747
            {
15748
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15749
                byte ctr_iv[WC_AES_BLOCK_SIZE];
15750
            #ifndef WOLFSSL_SMALL_STACK
15751
                Aes aes[1];
15752
            #else
15753
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15754
                                            DYNAMIC_TYPE_AES);
15755
                if (aes == NULL) {
15756
                    ret = MEMORY_E;
15757
                    break;
15758
                }
15759
            #endif
15760
15761
                /* Include 4 byte counter starting at all zeros. */
15762
                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
15763
                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
15764
                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
15765
15766
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15767
                if (ret == 0) {
15768
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
15769
                                                                AES_ENCRYPTION);
15770
                    if (ret == 0) {
15771
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
15772
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15773
                                                    defined(WC_ASYNC_ENABLE_AES)
15774
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15775
                                            WC_ASYNC_FLAG_NONE);
15776
                    #endif
15777
                    }
15778
                    wc_AesFree(aes);
15779
                }
15780
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15781
        #else
15782
                ret = NOT_COMPILED_IN;
15783
        #endif
15784
                break;
15785
            }
15786
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
15787
            case ecAES_128_GCM:
15788
            case ecAES_256_GCM:
15789
            {
15790
            #ifdef WOLFSSL_SMALL_STACK
15791
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15792
                                          DYNAMIC_TYPE_AES);
15793
                if (aes == NULL) {
15794
                    ret = MEMORY_E;
15795
                    break;
15796
                }
15797
            #else
15798
                Aes aes[1];
15799
            #endif
15800
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
15801
                if (ret == 0) {
15802
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
15803
                    if (ret == 0) {
15804
                        /* tag is written directly after the ciphertext; the
15805
                         * mac salt (if any) is bound in as AAD, mirroring the
15806
                         * HMAC salt used by the CBC/CTR paths. */
15807
                        ret = wc_AesGcmEncrypt(aes, out, msg, msgSz,
15808
                                    encIv, (word32)ivSz,
15809
                                    out + msgSz, digestSz,
15810
                                    ctx->macSalt, ctx->macSaltSz);
15811
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15812
                                                    defined(WC_ASYNC_ENABLE_AES)
15813
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15814
                                            WC_ASYNC_FLAG_NONE);
15815
                    #endif
15816
                    }
15817
                    wc_AesFree(aes);
15818
                }
15819
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15820
                break;
15821
            }
15822
        #endif
15823
            default:
15824
                ret = BAD_FUNC_ARG;
15825
                break;
15826
        }
15827
    }
15828
15829
    if (ret == 0 && !ecc_is_gcm(ctx->encAlgo)) {
15830
        switch (ctx->macAlgo) {
15831
            case ecHMAC_SHA256:
15832
            {
15833
            #ifdef WOLFSSL_SMALL_STACK
15834
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
15835
                                             DYNAMIC_TYPE_HMAC);
15836
                if (hmac == NULL) {
15837
                    ret = MEMORY_E;
15838
                    break;
15839
                }
15840
            #else
15841
                Hmac hmac[1];
15842
            #endif
15843
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
15844
                if (ret == 0) {
15845
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
15846
                                                         WC_SHA256_DIGEST_SIZE);
15847
                    if (ret == 0) {
15848
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
15849
                        ret = wc_HmacUpdate(hmac, out, msgSz);
15850
                    #else
15851
                        /* IV is before encrypted message. */
15852
                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
15853
                    #endif
15854
                    }
15855
                    if (ret == 0)
15856
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
15857
                    if (ret == 0)
15858
                        ret = wc_HmacFinal(hmac, out+msgSz);
15859
                    wc_HmacFree(hmac);
15860
                }
15861
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
15862
                break;
15863
            }
15864
15865
            default:
15866
                ret = BAD_FUNC_ARG;
15867
                break;
15868
        }
15869
    }
15870
15871
    if (ret == 0)
15872
        *outSz = ecc_ecies_total_size(pubKeySz, ivSz, msgSz, digestSz);
15873
15874
    ForceZero(sharedSecret, sharedSz);
15875
    ForceZero(keys, (word32)keysLen);
15876
    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15877
    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15878
15879
    return ret;
15880
}
15881
15882
/* ecc encrypt with shared secret run through kdf
15883
   ctx holds non default algos and inputs
15884
   msgSz should be the right size for encAlgo, i.e., already padded
15885
   return 0 on success */
15886
WOLFSSL_ABI
15887
int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15888
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15889
{
15890
    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
15891
}
15892
15893
/* ecc decrypt with shared secret run through kdf
15894
   ctx holds non default algos and inputs
15895
   return 0 on success */
15896
WOLFSSL_ABI
15897
int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15898
                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15899
{
15900
    int          ret = 0;
15901
    word32       blockSz = 0;
15902
#ifndef WOLFSSL_ECIES_OLD
15903
#ifndef WOLFSSL_ECIES_GEN_IV
15904
    byte         iv[ECC_MAX_IV_SIZE];
15905
#endif
15906
    word32       pubKeySz = 0;
15907
    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
15908
#endif
15909
    word32       digestSz = 0;
15910
    ecEncCtx     localCtx;
15911
#ifdef WOLFSSL_SMALL_STACK
15912
    byte*        sharedSecret;
15913
    byte*        keys;
15914
#else
15915
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15916
    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
15917
#else
15918
    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
15919
#endif
15920
    byte         keys[ECC_BUFSIZE];         /* max size */
15921
#endif
15922
#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15923
    word32       sharedSz = ECC_MAXSIZE;
15924
#else
15925
    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
15926
#endif
15927
    int          keysLen = 0;
15928
    int          encKeySz = 0;
15929
    int          ivSz = 0;
15930
    int          offset = 0;       /* in case using msg exchange */
15931
    byte*        encKey = NULL;
15932
    const byte*  encIv = NULL;
15933
    byte*        macKey = NULL;
15934
    /* devId to hand the DEM AES/HMAC primitives; ecc_key only carries a devId
15935
     * field with PLUTON_CRYPTO_ECC or WOLF_CRYPTO_CB, so default to INVALID. */
15936
    int          eciesDevId = INVALID_DEVID;
15937
15938
15939
    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
15940
        return BAD_FUNC_ARG;
15941
#ifdef WOLFSSL_ECIES_OLD
15942
    if (pubKey == NULL)
15943
        return BAD_FUNC_ARG;
15944
#endif
15945
15946
#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
15947
    eciesDevId = privKey->devId;
15948
#endif
15949
15950
#ifdef WOLF_CRYPTO_CB
15951
    #ifndef WOLF_CRYPTO_CB_FIND
15952
    if (privKey->devId != INVALID_DEVID)
15953
    #endif
15954
    {
15955
        /* Snapshot single-use state so we can tell whether the callback handled
15956
         * it purely in hardware (state untouched) versus re-entered software
15957
         * (which advances the state itself, below). */
15958
        byte cliStBefore = (ctx != NULL) ? ctx->cliSt : 0;
15959
        byte srvStBefore = (ctx != NULL) ? ctx->srvSt : 0;
15960
        ret = wc_CryptoCb_EciesDecrypt(privKey, pubKey, msg, msgSz, out, outSz,
15961
                                       ctx);
15962
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
15963
            /* Pure-hardware service left the state alone; enforce single-use
15964
             * here.  A re-entrant software callback already advanced it. */
15965
            if (ret == 0 && ctx != NULL &&
15966
                    ctx->cliSt == cliStBefore && ctx->srvSt == srvStBefore)
15967
                ret = ecc_ctx_decrypt_advance(ctx);
15968
            return ret;
15969
        }
15970
        /* fall-through to software (ret is reassigned below) */
15971
    }
15972
#endif
15973
15974
    if (ctx == NULL) {  /* use defaults */
15975
        ecc_ctx_init(&localCtx, 0, NULL);
15976
        ctx = &localCtx;
15977
    }
15978
15979
    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
15980
                            &blockSz);
15981
    if (ret != 0)
15982
        return ret;
15983
15984
#if !defined(WOLFSSL_ECIES_OLD) && !defined(WOLFSSL_ECIES_GEN_IV) && \
15985
    !defined(WOLFSSL_ECIES_STATIC_GCM_NONCE)
15986
    /* Default IV mode gives the GCM DEM a fixed (zero) nonce, which is only safe
15987
     * with a fresh ephemeral key per message.  Require explicit opt-in so it is
15988
     * never selected by accident; see WOLFSSL_ECIES_STATIC_GCM_NONCE. */
15989
    if (ecc_is_gcm(ctx->encAlgo))
15990
        return NOT_COMPILED_IN;
15991
#endif
15992
15993
#ifndef WOLFSSL_ECIES_OLD
15994
    ret = ecc_public_key_size(privKey, &pubKeySz);
15995
    if (ret != 0)
15996
        return ret;
15997
#ifdef HAVE_COMP_KEY
15998
    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
15999
        pubKeySz = (pubKeySz / 2) + 1;
16000
    }
16001
#endif /* HAVE_COMP_KEY */
16002
#endif /* WOLFSSL_ECIES_OLD */
16003
16004
    if (ctx->protocol == REQ_RESP_CLIENT) {
16005
        offset = keysLen;
16006
        keysLen *= 2;
16007
    }
16008
16009
    /* Validate and advance the single-use state (also covers a re-entrant
16010
     * software CryptoCb call; the hardware path handles it before dispatch). */
16011
    ret = ecc_ctx_decrypt_advance(ctx);
16012
    if (ret != 0)
16013
        return ret;
16014
16015
    if (keysLen > ECC_BUFSIZE) /* keys size */
16016
        return BUFFER_E;
16017
16018
    if (ecc_is_gcm(ctx->encAlgo)) {
16019
        /* GCM has a trailing tag (digestSz) and no block padding.  The nonce is
16020
         * only present in the input in GEN_IV mode. */
16021
#ifdef WOLFSSL_ECIES_OLD
16022
        if (msgSz < digestSz)
16023
            return BAD_FUNC_ARG;
16024
        if (*outSz < (msgSz - digestSz))
16025
            return BUFFER_E;
16026
#elif defined(WOLFSSL_ECIES_GEN_IV)
16027
        if (msgSz < pubKeySz + (word32)ivSz + digestSz)
16028
            return BAD_FUNC_ARG;
16029
        if (*outSz < (msgSz - (word32)ivSz - digestSz - pubKeySz))
16030
            return BUFFER_E;
16031
#else
16032
        if (msgSz < pubKeySz + digestSz)
16033
            return BAD_FUNC_ARG;
16034
        if (*outSz < (msgSz - digestSz - pubKeySz))
16035
            return BUFFER_E;
16036
#endif
16037
    }
16038
    else {
16039
#ifdef WOLFSSL_ECIES_OLD
16040
    if (((msgSz - digestSz) % blockSz) != 0)
16041
        return BAD_PADDING_E;
16042
16043
    if (*outSz < (msgSz - digestSz))
16044
        return BUFFER_E;
16045
#elif defined(WOLFSSL_ECIES_GEN_IV)
16046
    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
16047
        return BAD_PADDING_E;
16048
16049
    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
16050
        return BAD_FUNC_ARG;
16051
    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
16052
        return BUFFER_E;
16053
#else
16054
    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
16055
        return BAD_PADDING_E;
16056
16057
    if (msgSz < pubKeySz + blockSz + digestSz)
16058
        return BAD_FUNC_ARG;
16059
    if (*outSz < (msgSz - digestSz - pubKeySz))
16060
        return BUFFER_E;
16061
#endif
16062
    }
16063
16064
#ifdef ECC_TIMING_RESISTANT
16065
    if (ctx->rng != NULL && privKey->rng == NULL)
16066
        privKey->rng = ctx->rng;
16067
#endif
16068
16069
#ifdef WOLFSSL_SMALL_STACK
16070
    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16071
    if (sharedSecret == NULL) {
16072
    #ifndef WOLFSSL_ECIES_OLD
16073
        if (pubKey == peerKey)
16074
            wc_ecc_free(peerKey);
16075
    #endif
16076
        return MEMORY_E;
16077
    }
16078
16079
    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16080
    if (keys == NULL) {
16081
        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16082
    #ifndef WOLFSSL_ECIES_OLD
16083
        if (pubKey == peerKey)
16084
            wc_ecc_free(peerKey);
16085
    #endif
16086
        return MEMORY_E;
16087
    }
16088
#endif
16089
16090
#ifndef WOLFSSL_ECIES_OLD
16091
    if (pubKey == NULL) {
16092
        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
16093
            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
16094
        pubKey = peerKey;
16095
    }
16096
    else {
16097
        /* if a public key was passed in we should free it here before init
16098
         * and import */
16099
        wc_ecc_free(pubKey);
16100
    }
16101
    if (ret == 0) {
16102
        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
16103
    }
16104
    if (ret == 0) {
16105
        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
16106
    }
16107
    if (ret == 0) {
16108
        /* Point is not MACed. */
16109
        msg += pubKeySz;
16110
        msgSz -= pubKeySz;
16111
    }
16112
#endif
16113
16114
    if (ret == 0) {
16115
    #ifdef WOLFSSL_ECIES_ISO18033
16116
        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
16117
        sharedSz -= pubKeySz;
16118
    #endif
16119
16120
        do {
16121
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
16122
            ret = wc_AsyncWait(ret, &privKey->asyncDev,
16123
                                                     WC_ASYNC_FLAG_CALL_AGAIN);
16124
            if (ret != 0)
16125
                break;
16126
        #endif
16127
        #ifndef WOLFSSL_ECIES_ISO18033
16128
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
16129
                                                                    &sharedSz);
16130
        #else
16131
            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
16132
                                                          pubKeySz, &sharedSz);
16133
        #endif
16134
        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
16135
    }
16136
    if (ret == 0) {
16137
    #ifdef WOLFSSL_ECIES_ISO18033
16138
        /* KDF data is encoded public key and secret. */
16139
        sharedSz += pubKeySz;
16140
    #endif
16141
        switch (ctx->kdfAlgo) {
16142
            case ecHKDF_SHA256 :
16143
                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
16144
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16145
                           keys, (word32)keysLen);
16146
                break;
16147
            case ecHKDF_SHA1 :
16148
                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
16149
                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
16150
                           keys, (word32)keysLen);
16151
                break;
16152
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
16153
            case ecKDF_X963_SHA1 :
16154
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16155
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16156
                break;
16157
            case ecKDF_X963_SHA256 :
16158
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16159
                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
16160
                break;
16161
            case ecKDF_SHA1 :
16162
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
16163
                           NULL, 0, keys, (word32)keysLen);
16164
                break;
16165
            case ecKDF_SHA256 :
16166
                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
16167
                           NULL, 0, keys, (word32)keysLen);
16168
                break;
16169
#endif
16170
16171
            default:
16172
                ret = BAD_FUNC_ARG;
16173
                break;
16174
         }
16175
    }
16176
16177
    if (ret == 0 && ecc_is_gcm(ctx->encAlgo)) {
16178
        /* GCM nonce follows the ECIES IV build mode (matching CBC/CTR); no MAC
16179
         * key and no separate HMAC verify (GCM authenticates on decrypt). */
16180
        encKey = keys + offset;
16181
        macKey = NULL;
16182
#ifdef WOLFSSL_ECIES_OLD
16183
        encIv  = encKey + encKeySz;
16184
#elif defined(WOLFSSL_ECIES_GEN_IV)
16185
        encIv  = msg;
16186
        msg   += ivSz;
16187
        msgSz -= (word32)ivSz;
16188
#else
16189
        XMEMSET(iv, 0, (size_t)ivSz);
16190
        encIv  = iv;
16191
#endif
16192
    }
16193
    else if (ret == 0) {
16194
    #ifdef WOLFSSL_ECIES_OLD
16195
        encKey = keys + offset;
16196
        encIv  = encKey + encKeySz;
16197
        macKey = encKey + encKeySz + ivSz;
16198
    #elif defined(WOLFSSL_ECIES_GEN_IV)
16199
        encKey = keys + offset;
16200
        encIv  = msg;
16201
        msg   += ivSz;
16202
        msgSz -= ivSz;
16203
        macKey = encKey + encKeySz;
16204
    #else
16205
        XMEMSET(iv, 0, (size_t)ivSz);
16206
        encKey = keys + offset;
16207
        encIv  = iv;
16208
        macKey = encKey + encKeySz;
16209
    #endif
16210
16211
        switch (ctx->macAlgo) {
16212
            case ecHMAC_SHA256:
16213
            {
16214
                byte verify[WC_SHA256_DIGEST_SIZE];
16215
            #ifdef WOLFSSL_SMALL_STACK
16216
                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
16217
                                             DYNAMIC_TYPE_HMAC);
16218
                if (hmac == NULL) {
16219
                    ret = MEMORY_E;
16220
                    break;
16221
                }
16222
            #else
16223
                Hmac hmac[1];
16224
            #endif
16225
                ret = wc_HmacInit(hmac, privKey->heap, eciesDevId);
16226
                if (ret == 0) {
16227
                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
16228
                                                         WC_SHA256_DIGEST_SIZE);
16229
                    if (ret == 0)
16230
                    #if !defined(WOLFSSL_ECIES_GEN_IV)
16231
                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
16232
                    #else
16233
                        /* IV is before encrypted message. */
16234
                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
16235
                    #endif
16236
                    if (ret == 0)
16237
                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
16238
16239
                    if (ret == 0)
16240
                        ret = wc_HmacFinal(hmac, verify);
16241
                    if ((ret == 0) && (ConstantCompare(verify, msg + msgSz - digestSz,
16242
                                                             (int)digestSz) != 0)) {
16243
                        ret = HASH_TYPE_E;
16244
                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
16245
                    }
16246
16247
                    wc_HmacFree(hmac);
16248
                }
16249
                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
16250
                break;
16251
            }
16252
16253
            default:
16254
                ret = BAD_FUNC_ARG;
16255
                break;
16256
        }
16257
    }
16258
16259
    if (ret == 0) {
16260
        switch (ctx->encAlgo) {
16261
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
16262
            case ecAES_128_CBC:
16263
            case ecAES_256_CBC:
16264
            {
16265
            #ifdef WOLFSSL_SMALL_STACK
16266
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16267
                                          DYNAMIC_TYPE_AES);
16268
                if (aes == NULL) {
16269
                    ret = MEMORY_E;
16270
                    break;
16271
                }
16272
            #else
16273
                Aes aes[1];
16274
            #endif
16275
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16276
                if (ret == 0) {
16277
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
16278
                                                                AES_DECRYPTION);
16279
                    if (ret == 0) {
16280
                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
16281
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16282
                                                    defined(WC_ASYNC_ENABLE_AES)
16283
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16284
                                                            WC_ASYNC_FLAG_NONE);
16285
                    #endif
16286
                    }
16287
                    wc_AesFree(aes);
16288
                }
16289
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16290
                break;
16291
            }
16292
        #endif
16293
        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
16294
            case ecAES_128_CTR:
16295
            case ecAES_256_CTR:
16296
            {
16297
            #ifdef WOLFSSL_SMALL_STACK
16298
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16299
                                          DYNAMIC_TYPE_AES);
16300
                if (aes == NULL) {
16301
                    ret = MEMORY_E;
16302
                    break;
16303
                }
16304
             #else
16305
                Aes aes[1];
16306
             #endif
16307
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16308
                if (ret == 0) {
16309
                    byte ctr_iv[WC_AES_BLOCK_SIZE];
16310
                    /* Make a 16 byte IV from the bytes passed in. */
16311
                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
16312
                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
16313
                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
16314
                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
16315
                                                                AES_ENCRYPTION);
16316
                    if (ret == 0) {
16317
                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
16318
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16319
                                                    defined(WC_ASYNC_ENABLE_AES)
16320
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16321
                                                            WC_ASYNC_FLAG_NONE);
16322
                    #endif
16323
                    }
16324
                    wc_AesFree(aes);
16325
                }
16326
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16327
                break;
16328
            }
16329
        #endif
16330
        #if !defined(NO_AES) && defined(HAVE_AESGCM)
16331
            case ecAES_128_GCM:
16332
            case ecAES_256_GCM:
16333
            {
16334
            #ifdef WOLFSSL_SMALL_STACK
16335
                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
16336
                                          DYNAMIC_TYPE_AES);
16337
                if (aes == NULL) {
16338
                    ret = MEMORY_E;
16339
                    break;
16340
                }
16341
            #else
16342
                Aes aes[1];
16343
            #endif
16344
                ret = wc_AesInit(aes, privKey->heap, eciesDevId);
16345
                if (ret == 0) {
16346
                    ret = wc_AesGcmSetKey(aes, encKey, (word32)encKeySz);
16347
                    if (ret == 0) {
16348
                        /* tag trails the ciphertext; mac salt (if any) is the
16349
                         * AAD.  A tag mismatch returns AES_GCM_AUTH_E. */
16350
                        ret = wc_AesGcmDecrypt(aes, out, msg, msgSz - digestSz,
16351
                                    encIv, (word32)ivSz,
16352
                                    msg + msgSz - digestSz, digestSz,
16353
                                    ctx->macSalt, ctx->macSaltSz);
16354
                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
16355
                                                    defined(WC_ASYNC_ENABLE_AES)
16356
                        ret = wc_AsyncWait(ret, &aes->asyncDev,
16357
                                                            WC_ASYNC_FLAG_NONE);
16358
                    #endif
16359
                    }
16360
                    wc_AesFree(aes);
16361
                }
16362
                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
16363
                break;
16364
            }
16365
        #endif
16366
            default:
16367
                ret = BAD_FUNC_ARG;
16368
                break;
16369
        }
16370
    }
16371
16372
    if (ret == 0)
16373
       *outSz = msgSz - digestSz;
16374
16375
#ifndef WOLFSSL_ECIES_OLD
16376
    if (pubKey == peerKey)
16377
        wc_ecc_free(peerKey);
16378
#endif
16379
    ForceZero(sharedSecret, sharedSz);
16380
    ForceZero(keys, (word32)keysLen);
16381
#ifdef WOLFSSL_SMALL_STACK
16382
#ifndef WOLFSSL_ECIES_OLD
16383
    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16384
#endif
16385
    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16386
    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
16387
#endif
16388
16389
    return ret;
16390
}
16391
16392
16393
#endif /* HAVE_ECC_ENCRYPT */
16394
16395
16396
#ifdef HAVE_COMP_KEY
16397
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
16398
    !defined(WOLFSSL_MICROCHIP_TA100) && \
16399
    !defined(WOLFSSL_CRYPTOCELL)
16400
16401
#ifndef WOLFSSL_SP_MATH
16402
#if !defined(SQRTMOD_USE_MOD_EXP)
16403
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
16404
 */
16405
static int mp_jacobi(mp_int* a, mp_int* n, int* c)
16406
{
16407
#ifdef WOLFSSL_SMALL_STACK
16408
    mp_int*  a1 = NULL;
16409
    mp_int*  n1 = NULL;
16410
#else
16411
    mp_int   a1[1], n1[1];
16412
#endif
16413
    int      res;
16414
    int      s = 1;
16415
    int      k;
16416
    mp_int*  t[2];
16417
    mp_int*  ts;
16418
    mp_digit residue;
16419
16420
    if (mp_isneg(a) == MP_YES) {
16421
        return MP_VAL;
16422
    }
16423
    if (mp_isneg(n) == MP_YES) {
16424
        return MP_VAL;
16425
    }
16426
    if (mp_iseven(n) == MP_YES) {
16427
        return MP_VAL;
16428
    }
16429
16430
#ifdef WOLFSSL_SMALL_STACK
16431
    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
16432
    if (a1 == NULL) {
16433
        return MP_MEM;
16434
    }
16435
    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
16436
    if (n1 == NULL) {
16437
        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
16438
        return MP_MEM;
16439
    }
16440
#endif
16441
16442
    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
16443
        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
16444
        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
16445
        return res;
16446
    }
16447
16448
    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
16449
        goto done;
16450
    }
16451
16452
    if ((res = mp_copy(n, n1)) != MP_OKAY) {
16453
        goto done;
16454
    }
16455
16456
    t[0] = a1;
16457
    t[1] = n1;
16458
16459
    /* Keep reducing until first number is 0. */
16460
    while (!mp_iszero(t[0])) {
16461
        /* Divide by 2 until odd. */
16462
        k = mp_cnt_lsb(t[0]);
16463
        if (k > 0) {
16464
            mp_rshb(t[0], k);
16465
16466
            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
16467
             * Odd number of divides results in a negate.
16468
             */
16469
            residue = t[1]->dp[0] & 7;
16470
            if ((k & 1) && ((residue == 3) || (residue == 5))) {
16471
                s = -s;
16472
            }
16473
        }
16474
16475
        /* Swap t[0] and t[1]. */
16476
        ts   = t[0];
16477
        t[0] = t[1];
16478
        t[1] = ts;
16479
16480
        /* Negate s if both numbers == 3 mod 4. */
16481
        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
16482
             s = -s;
16483
        }
16484
16485
        /* Reduce first number modulo second. */
16486
        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
16487
            res = mp_sub(t[0], t[1], t[0]);
16488
        }
16489
        else {
16490
            res = mp_mod(t[0], t[1], t[0]);
16491
        }
16492
        if (res != MP_OKAY) {
16493
            goto done;
16494
        }
16495
    }
16496
16497
    /* When the two numbers have divisors in common. */
16498
    if (!mp_isone(t[1])) {
16499
        s = 0;
16500
    }
16501
    *c = s;
16502
16503
done:
16504
16505
    /* cleanup */
16506
    mp_clear(n1);
16507
    mp_clear(a1);
16508
16509
    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
16510
    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
16511
16512
  return res;
16513
}
16514
#endif /* !SQRTMOD_USE_MOD_EXP */
16515
16516
16517
/* Solves the modular equation x^2 = n (mod p)
16518
 * where prime number is greater than 2 (odd prime).
16519
 * The result is returned in the third argument x
16520
 * the function returns MP_OKAY on success, MP_VAL or another error on failure
16521
 */
16522
static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
16523
{
16524
#if defined(SQRTMOD_USE_MOD_EXP)
16525
  int res;
16526
  mp_digit i;
16527
  mp_int e;
16528
16529
  /* first handle the simple cases n = 0 or n = 1 */
16530
  if (mp_cmp_d(n, 0) == MP_EQ) {
16531
      mp_zero(ret);
16532
      return MP_OKAY;
16533
  }
16534
  if (mp_cmp_d(n, 1) == MP_EQ) {
16535
      return mp_set(ret, 1);
16536
  }
16537
16538
  if (mp_iseven(prime)) {
16539
      return MP_VAL;
16540
  }
16541
16542
  res = mp_init(&e);
16543
  if (res == MP_OKAY)
16544
      res = mp_mod_d(prime, 8, &i);
16545
  if (res == MP_OKAY && i == 1) {
16546
      return MP_VAL;
16547
  }
16548
  /* prime mod 8 = 5 */
16549
  else if (res == MP_OKAY && i == 5) {
16550
      res = mp_sub_d(prime, 1, &e);
16551
      if (res == MP_OKAY)
16552
          res = mp_div_2d(&e, 2, &e, NULL);
16553
  }
16554
  /* prime mod 4 = 3 */
16555
  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
16556
      res = mp_add_d(prime, 1, &e);
16557
      if (res == MP_OKAY)
16558
          res = mp_div_2d(&e, 2, &e, NULL);
16559
  }
16560
  if (res == MP_OKAY)
16561
      res = mp_exptmod(n, &e, prime, ret);
16562
16563
  mp_clear(&e);
16564
16565
  return res;
16566
#else
16567
  int res, legendre, done = 0;
16568
  mp_digit i;
16569
#ifdef WOLFSSL_SMALL_STACK
16570
  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16571
  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16572
  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16573
  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16574
  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16575
  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16576
  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16577
  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16578
  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16579
  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
16580
#else
16581
  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
16582
#endif
16583
16584
  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
16585
      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
16586
    res = MP_INIT_E;
16587
    goto out;
16588
  }
16589
16590
#ifdef WOLFSSL_SMALL_STACK
16591
  if ((t1 == NULL) ||
16592
      (C == NULL) ||
16593
      (Q == NULL) ||
16594
      (S == NULL) ||
16595
      (Z == NULL) ||
16596
      (M == NULL) ||
16597
      (T == NULL) ||
16598
      (R == NULL) ||
16599
      (N == NULL) ||
16600
      (two == NULL)) {
16601
    res = MP_MEM;
16602
    goto out;
16603
  }
16604
#endif
16605
16606
  /* first handle the simple cases n = 0 or n = 1 */
16607
  if (mp_cmp_d(n, 0) == MP_EQ) {
16608
    mp_zero(ret);
16609
    res = MP_OKAY;
16610
    goto out;
16611
  }
16612
  if (mp_cmp_d(n, 1) == MP_EQ) {
16613
    res = mp_set(ret, 1);
16614
    goto out;
16615
  }
16616
16617
  /* prime must be odd */
16618
  if (mp_cmp_d(prime, 2) == MP_EQ) {
16619
    res = MP_VAL;
16620
    goto out;
16621
  }
16622
16623
  /* reduce n to less than prime */
16624
  res = mp_mod(n, prime, N);
16625
  if (res != MP_OKAY) {
16626
    goto out;
16627
  }
16628
  /* when N is zero, sqrt is zero */
16629
  if (mp_iszero(N)) {
16630
    mp_set(ret, 0);
16631
    goto out;
16632
  }
16633
16634
  /* is quadratic non-residue mod prime */
16635
  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
16636
    goto out;
16637
  }
16638
  if (legendre == -1) {
16639
    res = MP_VAL;
16640
    goto out;
16641
  }
16642
16643
  /* SPECIAL CASE: if prime mod 4 == 3
16644
   * compute directly: res = n^(prime+1)/4 mod prime
16645
   * Handbook of Applied Cryptography algorithm 3.36
16646
   */
16647
  res = mp_mod_d(prime, 4, &i);
16648
  if (res == MP_OKAY && i == 3) {
16649
    res = mp_add_d(prime, 1, t1);
16650
16651
    if (res == MP_OKAY)
16652
      res = mp_div_2(t1, t1);
16653
    if (res == MP_OKAY)
16654
      res = mp_div_2(t1, t1);
16655
    if (res == MP_OKAY)
16656
      res = mp_exptmod(N, t1, prime, ret);
16657
16658
    done = 1;
16659
  }
16660
16661
  /* NOW: TonelliShanks algorithm */
16662
  if (res == MP_OKAY && done == 0) {
16663
16664
    /* factor out powers of 2 from prime-1, defining Q and S
16665
    *                                      as: prime-1 = Q*2^S */
16666
    /* Q = prime - 1 */
16667
    res = mp_copy(prime, Q);
16668
    if (res == MP_OKAY)
16669
      res = mp_sub_d(Q, 1, Q);
16670
16671
    /* S = 0 */
16672
    if (res == MP_OKAY)
16673
      mp_zero(S);
16674
16675
    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
16676
      /* Q = Q / 2 */
16677
      res = mp_div_2(Q, Q);
16678
16679
      /* S = S + 1 */
16680
      if (res == MP_OKAY)
16681
        res = mp_add_d(S, 1, S);
16682
    }
16683
16684
    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
16685
    /* Z = 2 */
16686
    if (res == MP_OKAY)
16687
      res = mp_set_int(Z, 2);
16688
16689
    while (res == MP_OKAY) {
16690
      res = mp_jacobi(Z, prime, &legendre);
16691
      if (res == MP_OKAY && legendre == -1)
16692
        break;
16693
16694
#if defined(WOLFSSL_CUSTOM_CURVES)
16695
      /* P224R1 succeeds with a value of 11. */
16696
      if (mp_cmp_d(Z, 22) == MP_EQ) {
16697
        /* This is to clamp the loop in case 'prime' is not really prime */
16698
        res = MP_VAL;
16699
        break;
16700
      }
16701
#endif
16702
16703
      /* Z = Z + 1 */
16704
      if (res == MP_OKAY)
16705
        res = mp_add_d(Z, 1, Z);
16706
16707
      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
16708
        /* This is to clamp the loop in case 'prime' is not really prime */
16709
        res = MP_VAL;
16710
        break;
16711
      }
16712
    }
16713
16714
    /* C = Z ^ Q mod prime */
16715
    if (res == MP_OKAY)
16716
      res = mp_exptmod(Z, Q, prime, C);
16717
16718
    /* t1 = (Q + 1) / 2 */
16719
    if (res == MP_OKAY)
16720
      res = mp_add_d(Q, 1, t1);
16721
    if (res == MP_OKAY)
16722
      res = mp_div_2(t1, t1);
16723
16724
    /* R = n ^ ((Q + 1) / 2) mod prime */
16725
    if (res == MP_OKAY)
16726
      res = mp_exptmod(N, t1, prime, R);
16727
16728
    /* T = n ^ Q mod prime */
16729
    if (res == MP_OKAY)
16730
      res = mp_exptmod(N, Q, prime, T);
16731
16732
    /* M = S */
16733
    if (res == MP_OKAY)
16734
      res = mp_copy(S, M);
16735
16736
    if (res == MP_OKAY)
16737
      res = mp_set_int(two, 2);
16738
16739
    while (res == MP_OKAY && done == 0) {
16740
      res = mp_copy(T, t1);
16741
16742
      /* reduce to 1 and count */
16743
      i = 0;
16744
      while (res == MP_OKAY) {
16745
        if (mp_cmp_d(t1, 1) == MP_EQ)
16746
            break;
16747
        res = mp_exptmod(t1, two, prime, t1);
16748
        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
16749
          /* This is to clamp the loop in case 'prime' is not really prime */
16750
          res = MP_VAL;
16751
          break;
16752
        }
16753
        if (res == MP_OKAY)
16754
          i++;
16755
      }
16756
      if (res == MP_OKAY && i == 0) {
16757
        res = mp_copy(R, ret);
16758
        done = 1;
16759
      }
16760
16761
      if (done == 0) {
16762
        /* t1 = 2 ^ (M - i - 1) */
16763
        if (res == MP_OKAY)
16764
          res = mp_sub_d(M, i, t1);
16765
        if (res == MP_OKAY)
16766
          res = mp_sub_d(t1, 1, t1);
16767
        if (res == MP_OKAY)
16768
          res = mp_exptmod(two, t1, prime, t1);
16769
16770
        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
16771
        if (res == MP_OKAY)
16772
          res = mp_exptmod(C, t1, prime, t1);
16773
16774
        /* C = (t1 * t1) mod prime */
16775
        if (res == MP_OKAY)
16776
          res = mp_sqrmod(t1, prime, C);
16777
16778
        /* R = (R * t1) mod prime */
16779
        if (res == MP_OKAY)
16780
          res = mp_mulmod(R, t1, prime, R);
16781
16782
        /* T = (T * C) mod prime */
16783
        if (res == MP_OKAY)
16784
          res = mp_mulmod(T, C, prime, T);
16785
16786
        /* M = i */
16787
        if (res == MP_OKAY)
16788
          res = mp_set(M, i);
16789
      }
16790
    }
16791
  }
16792
16793
  out:
16794
16795
#ifdef WOLFSSL_SMALL_STACK
16796
  if (t1) {
16797
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16798
      mp_clear(t1);
16799
    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16800
  }
16801
  if (C) {
16802
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16803
      mp_clear(C);
16804
    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16805
  }
16806
  if (Q) {
16807
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16808
      mp_clear(Q);
16809
    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16810
  }
16811
  if (S) {
16812
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16813
      mp_clear(S);
16814
    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16815
  }
16816
  if (Z) {
16817
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16818
      mp_clear(Z);
16819
    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16820
  }
16821
  if (M) {
16822
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16823
      mp_clear(M);
16824
    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16825
  }
16826
  if (T) {
16827
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16828
      mp_clear(T);
16829
    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16830
  }
16831
  if (R) {
16832
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16833
      mp_clear(R);
16834
    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16835
  }
16836
  if (N) {
16837
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16838
      mp_clear(N);
16839
    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16840
  }
16841
  if (two) {
16842
    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
16843
      mp_clear(two);
16844
    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
16845
  }
16846
#else
16847
  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
16848
    mp_clear(t1);
16849
    mp_clear(C);
16850
    mp_clear(Q);
16851
    mp_clear(S);
16852
    mp_clear(Z);
16853
    mp_clear(M);
16854
    mp_clear(T);
16855
    mp_clear(R);
16856
    mp_clear(N);
16857
    mp_clear(two);
16858
  }
16859
#endif
16860
16861
  return res;
16862
#endif
16863
}
16864
#endif /* !WOLFSSL_SP_MATH */
16865
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
16866
16867
#ifdef HAVE_ECC_KEY_EXPORT
16868
/* export public ECC key in ANSI X9.63 format compressed */
16869
static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
16870
{
16871
   word32 numlen;
16872
   int    ret = MP_OKAY;
16873
16874
   if (key == NULL || outLen == NULL)
16875
       return BAD_FUNC_ARG;
16876
16877
   if (key->type == ECC_PRIVATEKEY_ONLY)
16878
       return ECC_PRIVATEONLY_E;
16879
16880
   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
16881
       return ECC_BAD_ARG_E;
16882
   }
16883
16884
   numlen = (word32)key->dp->size;
16885
16886
   if (*outLen < (1 + numlen)) {
16887
      *outLen = 1 + numlen;
16888
      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
16889
   }
16890
16891
   if (out == NULL)
16892
       return BAD_FUNC_ARG;
16893
16894
   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
16895
       return ECC_BAD_ARG_E;
16896
16897
   /* store first byte */
16898
   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
16899
16900
   /* pad and store x */
16901
   XMEMSET(out+1, 0, numlen);
16902
   ret = mp_to_unsigned_bin(
16903
       key->pubkey.x,
16904
       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
16905
   *outLen = 1 + numlen;
16906
16907
   return ret;
16908
}
16909
#endif /* HAVE_ECC_KEY_EXPORT */
16910
#endif /* HAVE_COMP_KEY */
16911
16912
#ifdef HAVE_OID_ENCODING
16913
int wc_ecc_oid_cache_init(void)
16914
{
16915
    int ret = 0;
16916
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16917
    if (eccOidLockInit == 0) {
16918
        ret = wc_InitMutex(&ecc_oid_cache_lock);
16919
        if (ret == 0) {
16920
            eccOidLockInit = 1;
16921
        }
16922
    }
16923
#endif
16924
    return ret;
16925
}
16926
16927
void wc_ecc_oid_cache_free(void)
16928
{
16929
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16930
    wc_FreeMutex(&ecc_oid_cache_lock);
16931
    eccOidLockInit = 0;
16932
#endif
16933
}
16934
#endif /* HAVE_OID_ENCODING */
16935
16936
int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
16937
0
{
16938
0
    int x;
16939
0
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
16940
#ifdef HAVE_OID_ENCODING
16941
    oid_cache_t* o = NULL;
16942
#endif
16943
16944
0
    if (oidSum == 0) {
16945
0
        return BAD_FUNC_ARG;
16946
0
    }
16947
16948
#ifdef HAVE_OID_ENCODING
16949
    #ifndef WOLFSSL_MUTEX_INITIALIZER
16950
        /* extra sanity check if wolfCrypt_Init not called */
16951
        if (eccOidLockInit == 0) {
16952
            ret = wc_InitMutex(&ecc_oid_cache_lock);
16953
            if (ret != 0) {
16954
                return BAD_MUTEX_E;
16955
            }
16956
            eccOidLockInit = 1;
16957
        }
16958
    #endif
16959
16960
    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
16961
        return BAD_MUTEX_E;
16962
    }
16963
#endif
16964
16965
    /* find matching OID sum (based on encoded value) */
16966
0
    for (x = 0; ecc_sets[x].size != 0; x++) {
16967
0
        if (ecc_sets[x].oidSum == oidSum) {
16968
        #ifdef HAVE_OID_ENCODING
16969
            /* check cache */
16970
            ret = 0;
16971
            o = &ecc_oid_cache[x];
16972
            if (o->oidSz == 0) {
16973
                o->oidSz = sizeof(o->oid);
16974
                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
16975
                                                            o->oid, &o->oidSz);
16976
            }
16977
            if (oidSz) {
16978
                *oidSz = o->oidSz;
16979
            }
16980
            if (oid) {
16981
                *oid = o->oid;
16982
            }
16983
16984
            /* on success return curve id */
16985
            if (ret == 0) {
16986
                ret = ecc_sets[x].id;
16987
            }
16988
            break;
16989
        #else
16990
0
            if (oidSz) {
16991
0
                *oidSz = ecc_sets[x].oidSz;
16992
0
            }
16993
0
            if (oid) {
16994
0
                *oid = ecc_sets[x].oid;
16995
0
            }
16996
0
            ret = ecc_sets[x].id;
16997
0
            break;
16998
0
        #endif
16999
0
        }
17000
0
    }
17001
17002
#ifdef HAVE_OID_ENCODING
17003
    wc_UnLockMutex(&ecc_oid_cache_lock);
17004
#endif
17005
17006
0
    return ret;
17007
0
}
17008
17009
#ifdef WOLFSSL_CUSTOM_CURVES
17010
int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
17011
{
17012
    if (key == NULL || dp == NULL) {
17013
        return BAD_FUNC_ARG;
17014
    }
17015
17016
    key->idx = ECC_CUSTOM_IDX;
17017
    key->dp = dp;
17018
17019
    return 0;
17020
}
17021
#endif /* WOLFSSL_CUSTOM_CURVES */
17022
17023
#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
17024
17025
static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
17026
{
17027
    int i;
17028
17029
    /* in network byte order so start at end and work back */
17030
    for (i = 3; i >= 0; i--) {
17031
        if (++inOutCtr[i])  /* we're done unless we overflow */
17032
            return;
17033
    }
17034
}
17035
17036
/* ASN X9.63 Key Derivation Function (SEC1) */
17037
int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
17038
                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
17039
{
17040
    int ret;
17041
    word32 digestSz, copySz, remaining = outSz;
17042
    byte* outIdx;
17043
    byte  counter[4];
17044
    byte  tmp[WC_MAX_DIGEST_SIZE];
17045
17046
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
17047
17048
    if (secret == NULL || secretSz == 0 || out == NULL)
17049
        return BAD_FUNC_ARG;
17050
17051
    /* X9.63 allowed algos only */
17052
    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
17053
        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
17054
        type != WC_HASH_TYPE_SHA512)
17055
        return BAD_FUNC_ARG;
17056
17057
    ret = wc_HashGetDigestSize(type);
17058
    if (ret < 0)
17059
        return ret;
17060
    digestSz = (word32)ret;
17061
17062
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
17063
        return MEMORY_E);
17064
17065
    ret = wc_HashInit(hash, type);
17066
    if (ret != 0) {
17067
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17068
        return ret;
17069
    }
17070
17071
    outIdx = out;
17072
    XMEMSET(counter, 0, sizeof(counter));
17073
17074
    while (remaining > 0) {
17075
17076
        IncrementX963KdfCounter(counter);
17077
17078
        ret = wc_HashUpdate(hash, type, secret, secretSz);
17079
        if (ret != 0) {
17080
            break;
17081
        }
17082
17083
        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
17084
        if (ret != 0) {
17085
            break;
17086
        }
17087
17088
        if (sinfo) {
17089
            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
17090
            if (ret != 0) {
17091
                break;
17092
            }
17093
        }
17094
17095
        ret = wc_HashFinal(hash, type, tmp);
17096
        if (ret != 0) {
17097
            break;
17098
        }
17099
17100
        copySz = min(remaining, digestSz);
17101
        XMEMCPY(outIdx, tmp, copySz);
17102
17103
        remaining -= copySz;
17104
        outIdx += copySz;
17105
    }
17106
17107
    wc_HashFree(hash, type);
17108
17109
     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
17110
17111
    return ret;
17112
}
17113
#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
17114
17115
#ifdef WOLFSSL_SE050
17116
/* Use specified hardware key ID with ecc_key operations. Unlike devId,
17117
 * keyId is a word32, can be used for key IDs larger than an int.
17118
 *
17119
 * key    initialized ecc_key struct
17120
 * keyId  hardware key ID which stores ECC key
17121
 * flags  optional flags, currently unused
17122
 *
17123
 * Return 0 on success, negative on error */
17124
int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
17125
{
17126
    (void)flags;
17127
17128
    if (key == NULL) {
17129
        return BAD_FUNC_ARG;
17130
    }
17131
17132
    return se050_ecc_use_key_id(key, keyId);
17133
}
17134
17135
/* Get hardware key ID associated with this ecc_key structure.
17136
 *
17137
 * key    initialized ecc_key struct
17138
 * keyId  [OUT] output for key ID associated with this structure
17139
 *
17140
 * Returns 0 on success, negative on error.
17141
 */
17142
int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
17143
{
17144
    if (key == NULL || keyId == NULL) {
17145
        return BAD_FUNC_ARG;
17146
    }
17147
17148
    return se050_ecc_get_key_id(key, keyId);
17149
}
17150
#endif /* WOLFSSL_SE050 */
17151
17152
17153
#ifdef WC_ECC_NONBLOCK
17154
/* Enable ECC support for non-blocking operations */
17155
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
17156
{
17157
    if (key == NULL) {
17158
        return BAD_FUNC_ARG;
17159
    }
17160
    /* If a different context is already set, clear it before replacing.
17161
     * The caller is responsible for freeing any heap-allocated context. */
17162
    if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
17163
        XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
17164
    }
17165
    if (ctx != NULL) {
17166
        XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
17167
    }
17168
    key->nb_ctx = ctx;
17169
    return 0;
17170
}
17171
#endif /* WC_ECC_NONBLOCK */
17172
17173
#endif /* HAVE_ECC */