Ignore:
Timestamp:
Jun 22, 2021, 9:00:19 PM (3 years ago)
Author:
coas-nagasima
Message:

WolfSSLとAzure IoT SDKを更新

Location:
azure_iot_hub_f767zi/trunk/wolfssl-4.7.0
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/ecc.c

    r457 r464  
    4949 *                        Includes the curve "a" variable in calculation
    5050 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
    51  * ECC_CACHE_CURVE:     Enables cache of curve info to improve perofrmance
     51 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
    5252                                                                default: off
    5353 * FP_ECC:              ECC Fixed Point Cache                   default: off
     
    5757                        For the ECC curve paramaters `ecc_set_type` use fixed
    5858                        array for hex string
     59 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify.
     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
    5972 */
    6073
     
    7285 * ECC_USER_CURVES: Allows custom combination of key sizes below
    7386 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
     87 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
    7488 * HAVE_ECC112: 112 bit key
    7589 * HAVE_ECC128: 128 bit key
     
    142156#endif
    143157
    144 #ifdef WOLFSSL_SP_MATH
     158#if defined(WOLFSSL_PSOC6_CRYPTO)
     159    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
     160#endif
     161
     162#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
    145163    #define GEN_MEM_ERR MP_MEM
    146164#elif defined(USE_FAST_MATH)
     
    172190
    173191/* 256-bit curve on by default whether user curves or not */
    174 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
     192#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
    175193    #define ECC112
    176194#endif
    177 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
     195#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
    178196    #define ECC128
    179197#endif
    180 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
     198#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
    181199    #define ECC160
    182200#endif
    183 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
     201#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
    184202    #define ECC192
    185203#endif
    186 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
     204#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
    187205    #define ECC224
    188206#endif
    189 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
     207#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
    190208    #define ECC239
    191209#endif
    192 #if !defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)
     210#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
    193211    #define ECC256
    194212#endif
    195 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
     213#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
    196214    #define ECC320
    197215#endif
    198 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
     216#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
    199217    #define ECC384
    200218#endif
    201 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
     219#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
    202220    #define ECC512
    203221#endif
    204 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
     222#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
    205223    #define ECC521
    206224#endif
     
    9881006        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
    9891007        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
    990                 ecc_oid_secp256r1,                                                  /* oid/oidSz  */
     1008        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
    9911009        ecc_oid_secp256r1_sz,
    9921010        ECC_SECP256R1_OID,                                                  /* oid sum    */
     
    11611179
    11621180#if (defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)) && \
    1163     !defined(WOLFSSL_ATECC508A)
     1181    !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
    11641182static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
    11651183        mp_int* prime, mp_int* order);
     
    12581276#endif /* ECC_CACHE_CURVE */
    12591277
    1260 static void _wc_ecc_curve_free(ecc_curve_spec* curve)
     1278static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
     1279    byte mask)
     1280{
     1281    if (item) {
     1282    #ifdef HAVE_WOLF_BIGINT
     1283        wc_bigint_free(&item->raw);
     1284    #endif
     1285        mp_clear(item);
     1286    }
     1287    curve->load_mask &= ~mask;
     1288}
     1289static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
    12611290{
    12621291    if (curve == NULL) {
     
    12651294
    12661295    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
    1267         mp_clear(curve->prime);
     1296        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
    12681297    if (curve->load_mask & ECC_CURVE_FIELD_AF)
    1269         mp_clear(curve->Af);
     1298        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
    12701299#ifdef USE_ECC_B_PARAM
    12711300    if (curve->load_mask & ECC_CURVE_FIELD_BF)
    1272         mp_clear(curve->Bf);
     1301        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
    12731302#endif
    12741303    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
    1275         mp_clear(curve->order);
     1304        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
    12761305    if (curve->load_mask & ECC_CURVE_FIELD_GX)
    1277         mp_clear(curve->Gx);
     1306        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
    12781307    if (curve->load_mask & ECC_CURVE_FIELD_GY)
    1279         mp_clear(curve->Gy);
     1308        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
    12801309
    12811310    curve->load_mask = 0;
     
    12841313static void wc_ecc_curve_free(ecc_curve_spec* curve)
    12851314{
    1286     /* don't free cached curves */
    1287 #ifndef ECC_CACHE_CURVE
    1288     _wc_ecc_curve_free(curve);
    1289 #endif
    1290     (void)curve;
    1291 }
    1292 
    1293 static int wc_ecc_curve_load_item(const char* src, mp_int** dst,
    1294     ecc_curve_spec* curve, byte mask)
     1315    if (curve) {
     1316    #ifdef ECC_CACHE_CURVE
     1317        #ifdef WOLFSSL_CUSTOM_CURVES
     1318        /* only free custom curves (rest are globally cached) */
     1319        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
     1320            wc_ecc_curve_cache_free_spec(curve);
     1321            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
     1322        }
     1323        #endif
     1324    #else
     1325        wc_ecc_curve_cache_free_spec(curve);
     1326    #endif
     1327    }
     1328}
     1329
     1330static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
     1331    mp_int** dst, byte mask)
    12951332{
    12961333    int err;
     
    13221359    byte load_mask)
    13231360{
    1324     int ret = 0, x;
     1361    int ret = 0;
    13251362    ecc_curve_spec* curve;
    13261363    byte load_items = 0; /* mask of items to load */
     1364#ifdef ECC_CACHE_CURVE
     1365    int x;
     1366#endif
    13271367
    13281368    if (dp == NULL || pCurve == NULL)
     
    13421382
    13431383    /* make sure cache has been allocated */
    1344     if (ecc_curve_spec_cache[x] == NULL) {
    1345         ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(
    1346             sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
    1347         if (ecc_curve_spec_cache[x] == NULL) {
     1384    if (ecc_curve_spec_cache[x] == NULL
     1385    #ifdef WOLFSSL_CUSTOM_CURVES
     1386        || dp->id == ECC_CURVE_CUSTOM
     1387    #endif
     1388    ) {
     1389        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
     1390        if (curve == NULL) {
    13481391        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
    13491392            wc_UnLockMutex(&ecc_curve_cache_mutex);
     
    13511394            return MEMORY_E;
    13521395        }
    1353         XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));
    1354     }
    1355 
    1356     /* set curve pointer to cache */
    1357     *pCurve = ecc_curve_spec_cache[x];
    1358 
     1396        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
     1397
     1398        /* set curve pointer to cache */
     1399    #ifdef WOLFSSL_CUSTOM_CURVES
     1400        if (dp->id != ECC_CURVE_CUSTOM)
     1401    #endif
     1402        {
     1403            ecc_curve_spec_cache[x] = curve;
     1404        }
     1405    }
     1406    else {
     1407        curve = ecc_curve_spec_cache[x];
     1408    }
     1409    /* return new or cached curve */
     1410    *pCurve = curve;
     1411#else
     1412    curve = *pCurve;
    13591413#endif /* ECC_CACHE_CURVE */
    1360     curve = *pCurve;
    13611414
    13621415    /* make sure the curve is initialized */
     
    13821435
    13831436    /* load items */
    1384     x = 0;
    13851437    if (load_items & ECC_CURVE_FIELD_PRIME)
    1386         x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,
     1438        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
    13871439            ECC_CURVE_FIELD_PRIME);
    13881440    if (load_items & ECC_CURVE_FIELD_AF)
    1389         x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
     1441        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
    13901442            ECC_CURVE_FIELD_AF);
    13911443#ifdef USE_ECC_B_PARAM
    13921444    if (load_items & ECC_CURVE_FIELD_BF)
    1393         x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
     1445        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
    13941446            ECC_CURVE_FIELD_BF);
    13951447#endif
    13961448    if (load_items & ECC_CURVE_FIELD_ORDER)
    1397         x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
     1449        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
    13981450            ECC_CURVE_FIELD_ORDER);
    13991451    if (load_items & ECC_CURVE_FIELD_GX)
    1400         x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,
     1452        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
    14011453            ECC_CURVE_FIELD_GX);
    14021454    if (load_items & ECC_CURVE_FIELD_GY)
    1403         x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,
     1455        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
    14041456            ECC_CURVE_FIELD_GY);
    14051457
    14061458    /* check for error */
    1407     if (x != 0) {
     1459    if (ret != 0) {
    14081460        wc_ecc_curve_free(curve);
    14091461        ret = MP_READ_E;
     
    14341486    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
    14351487        if (ecc_curve_spec_cache[x]) {
    1436             _wc_ecc_curve_free(ecc_curve_spec_cache[x]);
     1488            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
    14371489            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
    14381490            ecc_curve_spec_cache[x] = NULL;
     
    15101562
    15111563
    1512 #ifndef WOLFSSL_ATECC508A
     1564#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
    15131565
    15141566#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
     
    15271579                             mp_int* a, mp_int* modulus, mp_digit mp)
    15281580{
    1529 #ifndef WOLFSSL_SP_MATH
     1581#if !defined(WOLFSSL_SP_MATH)
    15301582#ifdef WOLFSSL_SMALL_STACK
    15311583   mp_int* t1 = NULL;
     
    16121664
    16131665   /* should we dbl instead? */
    1614    if (err == MP_OKAY)
     1666   if (err == MP_OKAY) {
     1667#ifdef ECC_TIMING_RESISTANT
     1668       err = mp_submod_ct(modulus, Q->y, modulus, t1);
     1669#else
    16151670       err = mp_sub(modulus, Q->y, t1);
     1671#endif
     1672   }
    16161673   if (err == MP_OKAY) {
    16171674       if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
     
    17211778   /* Y = Y - T1 */
    17221779   if (err == MP_OKAY)
    1723        err = mp_sub(y, t1, y);
    1724    if (err == MP_OKAY) {
    1725        if (mp_isneg(y))
    1726            err = mp_add(y, modulus, y);
    1727    }
     1780       err = mp_submod_ct(y, t1, modulus, y);
    17281781   /* T1 = 2T1 */
    17291782   if (err == MP_OKAY)
    1730        err = mp_add(t1, t1, t1);
    1731    if (err == MP_OKAY) {
    1732        if (mp_cmp(t1, modulus) != MP_LT)
    1733            err = mp_sub(t1, modulus, t1);
    1734    }
     1783       err = mp_addmod_ct(t1, t1, modulus, t1);
    17351784   /* T1 = Y + T1 */
    17361785   if (err == MP_OKAY)
    1737        err = mp_add(t1, y, t1);
    1738    if (err == MP_OKAY) {
    1739        if (mp_cmp(t1, modulus) != MP_LT)
    1740            err = mp_sub(t1, modulus, t1);
    1741    }
     1786       err = mp_addmod_ct(t1, y, modulus, t1);
    17421787   /* X = X - T2 */
    17431788   if (err == MP_OKAY)
    1744        err = mp_sub(x, t2, x);
    1745    if (err == MP_OKAY) {
    1746        if (mp_isneg(x))
    1747            err = mp_add(x, modulus, x);
    1748    }
     1789       err = mp_submod_ct(x, t2, modulus, x);
    17491790   /* T2 = 2T2 */
    17501791   if (err == MP_OKAY)
    1751        err = mp_add(t2, t2, t2);
    1752    if (err == MP_OKAY) {
    1753        if (mp_cmp(t2, modulus) != MP_LT)
    1754            err = mp_sub(t2, modulus, t2);
    1755    }
     1792       err = mp_addmod_ct(t2, t2, modulus, t2);
    17561793   /* T2 = X + T2 */
    17571794   if (err == MP_OKAY)
    1758        err = mp_add(t2, x, t2);
    1759    if (err == MP_OKAY) {
    1760        if (mp_cmp(t2, modulus) != MP_LT)
    1761            err = mp_sub(t2, modulus, t2);
    1762    }
     1795       err = mp_addmod_ct(t2, x, modulus, t2);
    17631796
    17641797   if (err == MP_OKAY) {
     
    18091842   /* X = X - T2 */
    18101843   if (err == MP_OKAY)
    1811        err = mp_sub(x, t2, x);
    1812    if (err == MP_OKAY) {
    1813        if (mp_isneg(x))
    1814            err = mp_add(x, modulus, x);
    1815    }
     1844       err = mp_submod_ct(x, t2, modulus, x);
    18161845   /* T2 = T2 - X */
    18171846   if (err == MP_OKAY)
    1818        err = mp_sub(t2, x, t2);
    1819    if (err == MP_OKAY) {
    1820        if (mp_isneg(t2))
    1821            err = mp_add(t2, modulus, t2);
    1822    }
     1847       err = mp_submod_ct(t2, x, modulus, t2);
    18231848   /* T2 = T2 - X */
    18241849   if (err == MP_OKAY)
    1825        err = mp_sub(t2, x, t2);
    1826    if (err == MP_OKAY) {
    1827        if (mp_isneg(t2))
    1828            err = mp_add(t2, modulus, t2);
    1829    }
     1850       err = mp_submod_ct(t2, x, modulus, t2);
    18301851   /* T2 = T2 * Y */
    18311852   if (err == MP_OKAY)
     
    18361857   /* Y = T2 - T1 */
    18371858   if (err == MP_OKAY)
    1838        err = mp_sub(t2, t1, y);
    1839    if (err == MP_OKAY) {
    1840        if (mp_isneg(y))
    1841            err = mp_add(y, modulus, y);
    1842    }
     1859       err = mp_submod_ct(t2, t1, modulus, y);
    18431860   /* Y = Y/2 */
    1844    if (err == MP_OKAY) {
    1845        if (mp_isodd(y) == MP_YES)
    1846            err = mp_add(y, modulus, y);
    1847    }
    18481861   if (err == MP_OKAY)
    1849        err = mp_div_2(y, y);
     1862       err = mp_div_2_mod_ct(y, modulus, y);
    18501863
    18511864#ifdef ALT_ECC_SIZE
     
    19331946                                       mp_int* modulus, mp_digit mp)
    19341947{
    1935 #ifndef WOLFSSL_SP_MATH
     1948#if !defined(WOLFSSL_SP_MATH)
    19361949#ifdef WOLFSSL_SMALL_STACK
    19371950   mp_int* t1 = NULL;
     
    20642077   /* Z = 2Z */
    20652078   if (err == MP_OKAY)
    2066        err = mp_add(z, z, z);
    2067    if (err == MP_OKAY) {
    2068        if (mp_cmp(z, modulus) != MP_LT)
    2069            err = mp_sub(z, modulus, z);
    2070    }
     2079       err = mp_addmod_ct(z, z, modulus, z);
    20712080
    20722081   /* Determine if curve "a" should be used in calc */
     
    20762085      err = mp_submod(modulus, a, modulus, t2);
    20772086   }
    2078    if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
     2087   if (err == MP_OKAY && mp_iszero(t2)) {
     2088      /* T2 = X * X */
     2089      if (err == MP_OKAY)
     2090          err = mp_sqr(x, t2);
     2091      if (err == MP_OKAY)
     2092          err = mp_montgomery_reduce(t2, modulus, mp);
     2093      /* T1 = T2 + T1 */
     2094      if (err == MP_OKAY)
     2095          err = mp_addmod_ct(t2, t2, modulus, t1);
     2096      /* T1 = T2 + T1 */
     2097      if (err == MP_OKAY)
     2098          err = mp_addmod_ct(t1, t2, modulus, t1);
     2099   }
     2100   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
    20792101      /* use "a" in calc */
    20802102
     
    20942116      /* T1 = T2 + T1 */
    20952117      if (err == MP_OKAY)
    2096           err = mp_add(t1, t2, t1);
    2097       if (err == MP_OKAY) {
    2098          if (mp_cmp(t1, modulus) != MP_LT)
    2099             err = mp_sub(t1, modulus, t1);
    2100       }
     2118          err = mp_addmod_ct(t1, t2, modulus, t1);
    21012119      /* T1 = T2 + T1 */
    21022120      if (err == MP_OKAY)
    2103           err = mp_add(t1, t2, t1);
    2104       if (err == MP_OKAY) {
    2105           if (mp_cmp(t1, modulus) != MP_LT)
    2106               err = mp_sub(t1, modulus, t1);
    2107       }
     2121          err = mp_addmod_ct(t1, t2, modulus, t1);
    21082122      /* T1 = T2 + T1 */
    21092123      if (err == MP_OKAY)
    2110           err = mp_add(t1, t2, t1);
    2111       if (err == MP_OKAY) {
    2112          if (mp_cmp(t1, modulus) != MP_LT)
    2113             err = mp_sub(t1, modulus, t1);
    2114       }
     2124          err = mp_addmod_ct(t1, t2, modulus, t1);
    21152125   }
    21162126   else
     
    21222132      /* T2 = X - T1 */
    21232133      if (err == MP_OKAY)
    2124           err = mp_sub(x, t1, t2);
    2125       if (err == MP_OKAY) {
    2126           if (mp_isneg(t2))
    2127               err = mp_add(t2, modulus, t2);
    2128       }
     2134          err = mp_submod_ct(x, t1, modulus, t2);
    21292135      /* T1 = X + T1 */
    21302136      if (err == MP_OKAY)
    2131           err = mp_add(t1, x, t1);
    2132       if (err == MP_OKAY) {
    2133           if (mp_cmp(t1, modulus) != MP_LT)
    2134               err = mp_sub(t1, modulus, t1);
    2135       }
     2137          err = mp_addmod_ct(t1, x, modulus, t1);
    21362138      /* T2 = T1 * T2 */
    21372139      if (err == MP_OKAY)
     
    21422144      /* T1 = 2T2 */
    21432145      if (err == MP_OKAY)
    2144           err = mp_add(t2, t2, t1);
    2145       if (err == MP_OKAY) {
    2146           if (mp_cmp(t1, modulus) != MP_LT)
    2147               err = mp_sub(t1, modulus, t1);
    2148       }
     2146          err = mp_addmod_ct(t2, t2, modulus, t1);
    21492147      /* T1 = T1 + T2 */
    21502148      if (err == MP_OKAY)
    2151           err = mp_add(t1, t2, t1);
    2152       if (err == MP_OKAY) {
    2153           if (mp_cmp(t1, modulus) != MP_LT)
    2154               err = mp_sub(t1, modulus, t1);
    2155       }
     2149          err = mp_addmod_ct(t1, t2, modulus, t1);
    21562150   }
    21572151
    21582152   /* Y = 2Y */
    21592153   if (err == MP_OKAY)
    2160        err = mp_add(y, y, y);
    2161    if (err == MP_OKAY) {
    2162        if (mp_cmp(y, modulus) != MP_LT)
    2163            err = mp_sub(y, modulus, y);
    2164    }
     2154       err = mp_addmod_ct(y, y, modulus, y);
    21652155   /* Y = Y * Y */
    21662156   if (err == MP_OKAY)
     
    21762166
    21772167   /* T2 = T2/2 */
    2178    if (err == MP_OKAY) {
    2179        if (mp_isodd(t2) == MP_YES)
    2180            err = mp_add(t2, modulus, t2);
    2181    }
    21822168   if (err == MP_OKAY)
    2183        err = mp_div_2(t2, t2);
     2169       err = mp_div_2_mod_ct(t2, modulus, t2);
    21842170
    21852171   /* Y = Y * X */
     
    21972183   /* X = X - Y */
    21982184   if (err == MP_OKAY)
    2199        err = mp_sub(x, y, x);
    2200    if (err == MP_OKAY) {
    2201        if (mp_isneg(x))
    2202            err = mp_add(x, modulus, x);
    2203    }
     2185       err = mp_submod_ct(x, y, modulus, x);
    22042186   /* X = X - Y */
    22052187   if (err == MP_OKAY)
    2206        err = mp_sub(x, y, x);
    2207    if (err == MP_OKAY) {
    2208        if (mp_isneg(x))
    2209            err = mp_add(x, modulus, x);
    2210    }
     2188       err = mp_submod_ct(x, y, modulus, x);
    22112189
    22122190   /* Y = Y - X */
    22132191   if (err == MP_OKAY)
    2214        err = mp_sub(y, x, y);
    2215    if (err == MP_OKAY) {
    2216        if (mp_isneg(y))
    2217            err = mp_add(y, modulus, y);
    2218    }
     2192       err = mp_submod_ct(y, x, modulus, y);
    22192193   /* Y = Y * T1 */
    22202194   if (err == MP_OKAY)
     
    22252199   /* Y = Y - T2 */
    22262200   if (err == MP_OKAY)
    2227        err = mp_sub(y, t2, y);
    2228    if (err == MP_OKAY) {
    2229        if (mp_isneg(y))
    2230            err = mp_add(y, modulus, y);
    2231    }
     2201       err = mp_submod_ct(y, t2, modulus, y);
    22322202
    22332203#ifdef ALT_ECC_SIZE
     
    22922262int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
    22932263{
    2294 #ifndef WOLFSSL_SP_MATH
     2264#if !defined(WOLFSSL_SP_MATH)
    22952265#ifdef WOLFSSL_SMALL_STACK
    22962266   mp_int* t1 = NULL;
     
    24092379   /* get 1/z */
    24102380   if (err == MP_OKAY) {
    2411 #if defined(ECC_TIMING_RESISTANT) && defined(USE_FAST_MATH)
     2381#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
     2382                       defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
    24122383       if (ct) {
    24132384           err = mp_invmod_mont_ct(z, modulus, t1, mp);
     
    25082479#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA)
    25092480
    2510 #if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
     2481#if !defined(WOLFSSL_SP_MATH)
     2482
     2483#ifndef ECC_TIMING_RESISTANT
     2484
     2485/* size of sliding window, don't change this! */
     2486#define WINSIZE  4
     2487#define M_POINTS 8
     2488
     2489static int ecc_mulmod(mp_int* k, ecc_point* tG, ecc_point* R, ecc_point** M,
     2490    mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
     2491{
     2492   int      err = MP_OKAY;
     2493   int      i;
     2494   int      first = 1, bitbuf = 0, bitcpy = 0, j;
     2495   int      bitcnt = 0, mode = 0, digidx = 0;
     2496   mp_digit buf;
     2497   int      infinity;
     2498
     2499   (void)rng;
     2500
     2501   /* calc the M tab, which holds kG for k==8..15 */
     2502   /* M[0] == 8G */
     2503   if (err == MP_OKAY)
     2504       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
     2505   if (err == MP_OKAY)
     2506       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
     2507   if (err == MP_OKAY)
     2508       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
     2509
     2510   /* now find (8+k)G for k=1..7 */
     2511   if (err == MP_OKAY)
     2512       for (j = 9; j < 16; j++) {
     2513           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
     2514                                                        modulus, mp, &infinity);
     2515           if (err != MP_OKAY) break;
     2516       }
     2517
     2518   /* setup sliding window */
     2519   if (err == MP_OKAY) {
     2520       mode   = 0;
     2521       bitcnt = 1;
     2522       buf    = 0;
     2523       digidx = get_digit_count(k) - 1;
     2524       bitcpy = bitbuf = 0;
     2525       first  = 1;
     2526
     2527       /* perform ops */
     2528       for (;;) {
     2529           /* grab next digit as required */
     2530           if (--bitcnt == 0) {
     2531               if (digidx == -1) {
     2532                   break;
     2533               }
     2534               buf    = get_digit(k, digidx);
     2535               bitcnt = (int) DIGIT_BIT;
     2536               --digidx;
     2537           }
     2538
     2539           /* grab the next msb from the ltiplicand */
     2540           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
     2541           buf <<= 1;
     2542
     2543           /* skip leading zero bits */
     2544           if (mode == 0 && i == 0)
     2545               continue;
     2546
     2547           /* if the bit is zero and mode == 1 then we double */
     2548           if (mode == 1 && i == 0) {
     2549               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
     2550               if (err != MP_OKAY) break;
     2551               continue;
     2552           }
     2553
     2554           /* else we add it to the window */
     2555           bitbuf |= (i << (WINSIZE - ++bitcpy));
     2556           mode = 2;
     2557
     2558           if (bitcpy == WINSIZE) {
     2559               /* if this is the first window we do a simple copy */
     2560               if (first == 1) {
     2561                   /* R = kG [k = first window] */
     2562                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
     2563                   if (err != MP_OKAY) break;
     2564
     2565                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
     2566                   if (err != MP_OKAY) break;
     2567
     2568                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
     2569                   first = 0;
     2570               } else {
     2571                   /* normal window */
     2572                   /* ok window is filled so double as required and add  */
     2573                   /* double first */
     2574                   for (j = 0; j < WINSIZE; j++) {
     2575                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
     2576                                                                            mp);
     2577                       if (err != MP_OKAY) break;
     2578                   }
     2579                   if (err != MP_OKAY) break;  /* out of first for(;;) */
     2580
     2581                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
     2582                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
     2583                                                     a, modulus, mp, &infinity);
     2584               }
     2585               if (err != MP_OKAY) break;
     2586               /* empty window and reset */
     2587               bitcpy = bitbuf = 0;
     2588               mode = 1;
     2589           }
     2590       }
     2591   }
     2592
     2593   /* if bits remain then double/add */
     2594   if (err == MP_OKAY) {
     2595       if (mode == 2 && bitcpy > 0) {
     2596           /* double then add */
     2597           for (j = 0; j < bitcpy; j++) {
     2598               /* only double if we have had at least one add first */
     2599               if (first == 0) {
     2600                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
     2601                   if (err != MP_OKAY) break;
     2602               }
     2603
     2604               bitbuf <<= 1;
     2605               if ((bitbuf & (1 << WINSIZE)) != 0) {
     2606                   if (first == 1) {
     2607                       /* first add, so copy */
     2608                       err = mp_copy(tG->x, R->x);
     2609                       if (err != MP_OKAY) break;
     2610
     2611                       err = mp_copy(tG->y, R->y);
     2612                       if (err != MP_OKAY) break;
     2613
     2614                       err = mp_copy(tG->z, R->z);
     2615                       if (err != MP_OKAY) break;
     2616                       first = 0;
     2617                   } else {
     2618                       /* then add */
     2619                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
     2620                                                                 mp, &infinity);
     2621                       if (err != MP_OKAY) break;
     2622                   }
     2623               }
     2624           }
     2625       }
     2626   }
     2627
     2628   #undef WINSIZE
     2629
     2630   return err;
     2631}
     2632
     2633#else
     2634
     2635static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p,
     2636        mp_int* modulus, mp_digit mp, mp_int* tx, mp_int* ty)
     2637{
     2638    int err = MP_OKAY;
     2639#ifdef WOLFSSL_SMALL_STACK
     2640    mp_int*       mu = NULL;
     2641#else
     2642    mp_int        mu[1];
     2643#endif
     2644
     2645#ifdef WOLFSSL_SMALL_STACK
     2646    mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     2647    if (mu == NULL)
     2648        err = MEMORY_E;
     2649#endif
     2650
     2651    if (err == MP_OKAY)
     2652        err = mp_init(mu);
     2653    if (err == MP_OKAY)
     2654        err = mp_montgomery_calc_normalization(mu, modulus);
     2655    if (err == MP_OKAY)
     2656        err = wc_ecc_gen_k(rng, size, ty, modulus);
     2657    if (err == MP_OKAY)
     2658        err = mp_mulmod(ty, mu, modulus, ty);
     2659    if (err == MP_OKAY)
     2660        err = mp_mul(p->z, ty, p->z);
     2661    if (err == MP_OKAY)
     2662        err = mp_montgomery_reduce(p->z, modulus, mp);
     2663    if (err == MP_OKAY)
     2664        err = mp_sqr(ty, tx);
     2665    if (err == MP_OKAY)
     2666        err = mp_montgomery_reduce(tx, modulus, mp);
     2667    if (err == MP_OKAY)
     2668        err = mp_mul(ty, tx, ty);
     2669    if (err == MP_OKAY)
     2670        err = mp_montgomery_reduce(ty, modulus, mp);
     2671    if (err == MP_OKAY)
     2672        err = mp_mul(p->x, tx, p->x);
     2673    if (err == MP_OKAY)
     2674        err = mp_montgomery_reduce(p->x, modulus, mp);
     2675    if (err == MP_OKAY)
     2676        err = mp_mul(p->y, ty, p->y);
     2677    if (err == MP_OKAY)
     2678        err = mp_montgomery_reduce(p->y, modulus, mp);
     2679
     2680#ifdef WOLFSSL_SMALL_STACK
     2681    if (mu != NULL) {
     2682        mp_clear(mu);
     2683        XFREE(mu, NULL, DYNAMIC_TYPE_ECC);
     2684    }
     2685#else
     2686    mp_clear(mu);
     2687#endif
     2688
     2689    return err;
     2690}
     2691
     2692#define M_POINTS 3
     2693
     2694/* Joye double-add ladder.
     2695 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
     2696 * by Marc Joye (2007)
     2697 *
     2698 * Algorithm 1':
     2699 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
     2700 *   Output: Q = kP
     2701 *   1: R[0] = P; R[1] = P
     2702 *   2: for j = 1 to t-1 do
     2703 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
     2704 *   4: end for
     2705 *   5: b = k[0]; R[b] = R[b] - P
     2706 *   6: return R[0]
     2707 *
     2708 * Assumes: k < order.
     2709 */
     2710static int ecc_mulmod(mp_int* k, ecc_point* P, ecc_point* Q, ecc_point** R,
     2711    mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
     2712{
     2713    int      err = MP_OKAY;
     2714    int      bytes = (mp_count_bits(modulus) + 7) / 8;
     2715    int      i;
     2716    int      j = 1;
     2717    int      cnt = DIGIT_BIT;
     2718    int      t = 0;
     2719    mp_digit b;
     2720    mp_digit v = 0;
     2721#ifndef WC_NO_CACHE_RESISTANT
     2722    /* First bit always 1 (fix at end) and swap equals first bit */
     2723    int      swap = 1;
     2724#endif
     2725    int      infinity;
     2726
     2727    /* Step 1: R[0] = P; R[1] = P */
     2728    /* R[0] = P */
     2729    if (err == MP_OKAY)
     2730        err = mp_copy(P->x, R[0]->x);
     2731    if (err == MP_OKAY)
     2732        err = mp_copy(P->y, R[0]->y);
     2733    if (err == MP_OKAY)
     2734        err = mp_copy(P->z, R[0]->z);
     2735
     2736    /* R[1] = P */
     2737    if (err == MP_OKAY)
     2738        err = mp_copy(P->x, R[1]->x);
     2739    if (err == MP_OKAY)
     2740        err = mp_copy(P->y, R[1]->y);
     2741    if (err == MP_OKAY)
     2742        err = mp_copy(P->z, R[1]->z);
     2743
     2744    /* Randomize z ordinates to obfuscate timing. */
     2745    if ((err == MP_OKAY) && (rng != NULL))
     2746        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y);
     2747    if ((err == MP_OKAY) && (rng != NULL))
     2748        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y);
     2749
     2750    if (err == MP_OKAY) {
     2751        /* Order could be one greater than the size of the modulus. */
     2752        t = mp_count_bits(modulus) + 1;
     2753        v = k->dp[0] >> 1;
     2754        if (cnt > t) {
     2755            cnt = t;
     2756        }
     2757        err = mp_grow(k, modulus->used + 1);
     2758    }
     2759    /* Step 2: for j = 1 to t-1 do */
     2760    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
     2761        if (--cnt == 0) {
     2762            v = k->dp[j++];
     2763            cnt = DIGIT_BIT;
     2764        }
     2765
     2766        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
     2767        b = v & 1;
     2768        v >>= 1;
     2769#ifdef WC_NO_CACHE_RESISTANT
     2770        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
     2771        if (err == MP_OKAY) {
     2772            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
     2773                                                        modulus, mp, &infinity);
     2774        }
     2775#else
     2776        /* Swap R[0] and R[1] if other index is needed. */
     2777        swap ^= b;
     2778        if (err == MP_OKAY)
     2779            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
     2780        if (err == MP_OKAY)
     2781            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
     2782        if (err == MP_OKAY)
     2783            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
     2784        swap = (int)b;
     2785
     2786        if (err == MP_OKAY)
     2787            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
     2788        if (err == MP_OKAY) {
     2789            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
     2790                                                                 mp, &infinity);
     2791        }
     2792#endif /* WC_NO_CACHE_RESISTANT */
     2793    }
     2794    /* Step 4: end for */
     2795#ifndef WC_NO_CACHE_RESISTANT
     2796    /* Swap back if last bit is 0. */
     2797    swap ^= 1;
     2798    if (err == MP_OKAY)
     2799        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, swap);
     2800    if (err == MP_OKAY)
     2801        err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, swap);
     2802    if (err == MP_OKAY)
     2803        err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, swap);
     2804#endif
     2805
     2806    /* Step 5: b = k[0]; R[b] = R[b] - P */
     2807    /* R[2] = -P */
     2808    if (err == MP_OKAY)
     2809        err = mp_copy(P->x, R[2]->x);
     2810    if (err == MP_OKAY)
     2811        err = mp_sub(modulus, P->y, R[2]->y);
     2812    if (err == MP_OKAY)
     2813        err = mp_copy(P->z, R[2]->z);
     2814    /* Subtract point by adding negative. */
     2815    if (err == MP_OKAY) {
     2816        b = k->dp[0] & 1;
     2817#ifdef WC_NO_CACHE_RESISTANT
     2818        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
     2819                                                                     &infinity);
     2820#else
     2821        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
     2822        err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
     2823        if (err == MP_OKAY)
     2824            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
     2825        if (err == MP_OKAY)
     2826            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
     2827        if (err == MP_OKAY)
     2828            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
     2829                                                                 mp, &infinity);
     2830        /* Swap back if necessary. */
     2831        if (err == MP_OKAY)
     2832            err = mp_cond_swap_ct(R[0]->x, R[1]->x, modulus->used, (int)b);
     2833        if (err == MP_OKAY)
     2834            err = mp_cond_swap_ct(R[0]->y, R[1]->y, modulus->used, (int)b);
     2835        if (err == MP_OKAY)
     2836            err = mp_cond_swap_ct(R[0]->z, R[1]->z, modulus->used, (int)b);
     2837#endif
     2838    }
     2839
     2840    /* Step 6: return R[0] */
     2841    if (err == MP_OKAY)
     2842        err = mp_copy(R[0]->x, Q->x);
     2843    if (err == MP_OKAY)
     2844        err = mp_copy(R[0]->y, Q->y);
     2845    if (err == MP_OKAY)
     2846        err = mp_copy(R[0]->z, Q->z);
     2847
     2848    return err;
     2849}
     2850
     2851#endif
     2852
     2853/* Convert the point to montogmery form.
     2854 *
     2855 * @param  [in]   p        Point to convert.
     2856 * @param  [out]  r        Point in montgomery form.
     2857 * @param  [in]   modulus  Modulus of ordinates.
     2858 * @return  0 on success.
     2859 * @return  -ve on failure.
     2860 */
     2861static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
     2862                             void* heap)
     2863{
     2864   int err = MP_OKAY;
     2865#ifdef WOLFSSL_SMALL_STACK
     2866   mp_int*       mu = NULL;
     2867#else
     2868   mp_int        mu[1];
     2869#endif
     2870
     2871   (void)heap;
     2872
     2873#ifdef WOLFSSL_SMALL_STACK
     2874   mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2875   if (mu == NULL)
     2876       err = MEMORY_E;
     2877#endif
     2878   if (err == MP_OKAY)
     2879       err = mp_init(mu);
     2880   if (err == MP_OKAY) {
     2881       err = mp_montgomery_calc_normalization(mu, modulus);
     2882
     2883       if (err == MP_OKAY) {
     2884           if (mp_cmp_d(mu, 1) == MP_EQ) {
     2885               err = mp_copy(p->x, r->x);
     2886               if (err == MP_OKAY)
     2887                   err = mp_copy(p->y, r->y);
     2888               if (err == MP_OKAY)
     2889                   err = mp_copy(p->z, r->z);
     2890           }
     2891           else {
     2892               err = mp_mulmod(p->x, mu, modulus, r->x);
     2893               if (err == MP_OKAY)
     2894                   err = mp_mulmod(p->y, mu, modulus, r->y);
     2895               if (err == MP_OKAY)
     2896                   err = mp_mulmod(p->z, mu, modulus, r->z);
     2897           }
     2898       }
     2899
     2900       mp_clear(mu);
     2901   }
     2902#ifdef WOLFSSL_SMALL_STACK
     2903   if (mu != NULL)
     2904      XFREE(mu, heap, DYNAMIC_TYPE_ECC);
     2905#endif
     2906   return err;
     2907}
     2908
     2909#ifdef WOLFSSL_SMALL_STACK_CACHE
     2910static int ecc_key_tmp_init(ecc_key* key, void* heap)
     2911{
     2912   int err = MP_OKAY;
     2913
     2914   XMEMSET(key, 0, sizeof(*key));
     2915
     2916   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2917   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2918#ifdef ALT_ECC_SIZE
     2919   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2920   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2921   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
     2922#endif
     2923   if (key->t1 == NULL || key->t2 == NULL
     2924#ifdef ALT_ECC_SIZE
     2925      || key->x == NULL || key->y == NULL || key->z == NULL
     2926#endif
     2927   ) {
     2928       err = MEMORY_E;
     2929   }
     2930
     2931   return err;
     2932}
     2933
     2934static void ecc_key_tmp_final(ecc_key* key, void* heap)
     2935{
     2936    (void)heap;
     2937#ifdef ALT_ECC_SIZE
     2938   if (key->z != NULL)
     2939      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
     2940   if (key->y != NULL)
     2941      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
     2942   if (key->x != NULL)
     2943      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
     2944#endif
     2945   if (key->t2 != NULL)
     2946      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
     2947   if (key->t1 != NULL)
     2948      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
     2949}
     2950#endif /* WOLFSSL_SMALL_STACK_CACHE */
     2951#endif /* !WOLFSSL_SP_MATH */
     2952
     2953#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
    25112954/**
    25122955   Perform a point multiplication
     
    25212964*/
    25222965#ifdef FP_ECC
    2523 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
    2524                   mp_int* a, mp_int* modulus, int map,
    2525                   void* heap)
     2966static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
     2967                             mp_int* modulus, WC_RNG* rng, int map, void* heap)
    25262968#else
    2527 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
    2528                   mp_int* a, mp_int* modulus, int map,
    2529                   void* heap)
    2530 #endif
    2531 {
    2532 #ifndef WOLFSSL_SP_MATH
    2533 #ifndef ECC_TIMING_RESISTANT
    2534    /* size of sliding window, don't change this! */
    2535    #define WINSIZE  4
    2536    #define M_POINTS 8
    2537    int           first = 1, bitbuf = 0, bitcpy = 0, j;
    2538 #elif defined(WC_NO_CACHE_RESISTANT)
    2539    #define M_POINTS 4
     2969int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
     2970                     mp_int* modulus, int map, void* heap)
     2971#endif
     2972#if !defined(WOLFSSL_SP_MATH)
     2973{
     2974   ecc_point     *tG, *M[M_POINTS];
     2975   int           i, err;
     2976#ifdef WOLFSSL_SMALL_STACK_CACHE
     2977   ecc_key       *key = (ecc_key *)XMALLOC(sizeof *key, heap, DYNAMIC_TYPE_ECC);
     2978#endif
     2979   mp_digit      mp;
     2980
     2981   /* init variables */
     2982   tG = NULL;
     2983   XMEMSET(M, 0, sizeof(M));
     2984
     2985   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
     2986       err = ECC_BAD_ARG_E;
     2987       goto exit;
     2988   }
     2989
     2990#ifdef WOLFSSL_SMALL_STACK_CACHE
     2991   if (key == NULL) {
     2992       err = MP_MEM;
     2993       goto exit;
     2994   }
     2995   err = ecc_key_tmp_init(key, heap);
     2996   if (err != MP_OKAY)
     2997      goto exit;
     2998   R->key = key;
     2999#endif /* WOLFSSL_SMALL_STACK_CACHE */
     3000
     3001  /* alloc ram for window temps */
     3002  for (i = 0; i < M_POINTS; i++) {
     3003      M[i] = wc_ecc_new_point_h(heap);
     3004      if (M[i] == NULL) {
     3005         err = MEMORY_E;
     3006         goto exit;
     3007      }
     3008#ifdef WOLFSSL_SMALL_STACK_CACHE
     3009      M[i]->key = key;
     3010#endif
     3011  }
     3012
     3013   /* make a copy of G in case R==G */
     3014   tG = wc_ecc_new_point_h(heap);
     3015   if (tG == NULL) {
     3016       err = MEMORY_E;
     3017       goto exit;
     3018   }
     3019   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
     3020       goto exit;
     3021   }
     3022
     3023   /* init montgomery reduction */
     3024   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
     3025       goto exit;
     3026   }
     3027
     3028#ifdef FP_ECC
     3029   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
    25403030#else
    2541    #define M_POINTS 5
    2542 #endif
    2543 
     3031   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
     3032#endif
     3033   /* map R back from projective space */
     3034   if (err == MP_OKAY && map)
     3035       err = ecc_map(R, modulus, mp);
     3036
     3037exit:
     3038
     3039   /* done */
     3040   wc_ecc_del_point_h(tG, heap);
     3041   for (i = 0; i < M_POINTS; i++) {
     3042       wc_ecc_del_point_h(M[i], heap);
     3043   }
     3044#ifdef WOLFSSL_SMALL_STACK_CACHE
     3045   if (key) {
     3046       if (R)
     3047           R->key = NULL;
     3048       if (err == MP_OKAY)
     3049           ecc_key_tmp_final(key, heap);
     3050       XFREE(key, heap, DYNAMIC_TYPE_ECC);
     3051   }
     3052#endif /* WOLFSSL_SMALL_STACK_CACHE */
     3053
     3054   return err;
     3055}
     3056#else
     3057{
     3058   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
     3059       return ECC_BAD_ARG_E;
     3060   }
     3061
     3062   (void)a;
     3063
     3064#ifdef WOLFSSL_HAVE_SP_ECC
     3065#ifndef WOLFSSL_SP_NO_256
     3066   if (mp_count_bits(modulus) == 256) {
     3067       return sp_ecc_mulmod_256(k, G, R, map, heap);
     3068   }
     3069#endif
     3070#ifdef WOLFSSL_SP_384
     3071   if (mp_count_bits(modulus) == 384) {
     3072       return sp_ecc_mulmod_384(k, G, R, map, heap);
     3073   }
     3074#endif
     3075#else
     3076   (void)map;
     3077   (void)map;
     3078   (void)heap;
     3079#endif
     3080   return ECC_BAD_ARG_E;
     3081}
     3082#endif
     3083#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
     3084
     3085#ifndef FP_ECC
     3086/**
     3087   Perform a point multiplication
     3088   k    The scalar to multiply by
     3089   G    The base point
     3090   R    [out] Destination for kG
     3091   a    ECC curve parameter a
     3092   modulus  The modulus of the field the ECC curve is in
     3093   map      Boolean whether to map back to affine or not
     3094                (1==map, 0 == leave in projective)
     3095   return MP_OKAY on success
     3096*/
     3097int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
     3098                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
     3099                      void* heap)
     3100#if !defined(WOLFSSL_SP_MATH)
     3101{
    25443102   ecc_point     *tG, *M[M_POINTS];
    25453103   int           i, err;
     
    25473105   ecc_key       key;
    25483106#endif
    2549 #ifdef WOLFSSL_SMALL_STACK
    2550    mp_int*       mu = NULL;
    2551 #else
    2552    mp_int        mu[1];
    2553 #endif
    25543107   mp_digit      mp;
    2555    mp_digit      buf;
    2556    int           bitcnt = 0, mode = 0, digidx = 0;
     3108#ifdef ECC_TIMING_RESISTANT
     3109   mp_int t;
     3110#endif
    25573111
    25583112   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
    2559        return ECC_BAD_ARG_E;
     3113      return ECC_BAD_ARG_E;
    25603114   }
    25613115
     
    25633117   tG = NULL;
    25643118   XMEMSET(M, 0, sizeof(M));
    2565 #ifdef WOLFSSL_SMALL_STACK
    2566    mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2567    if (mu == NULL)
    2568        return MEMORY_E;
    2569 #endif
     3119
    25703120#ifdef WOLFSSL_SMALL_STACK_CACHE
    2571    key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2572    key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2573 #ifdef ALT_ECC_SIZE
    2574    key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2575    key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2576    key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
    2577 #endif
    2578    if (key.t1 == NULL || key.t2 == NULL
    2579 #ifdef ALT_ECC_SIZE
    2580       || key.x == NULL || key.y == NULL || key.z == NULL
    2581 #endif
    2582    ) {
    2583 #ifdef ALT_ECC_SIZE
    2584        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
    2585        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
    2586        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
    2587 #endif
    2588        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
    2589        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
    2590        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
    2591        return MEMORY_E;
    2592    }
     3121   err = ecc_key_tmp_init(&key, heap);
     3122   if (err != MP_OKAY)
     3123      goto exit;
     3124   R->key = &key;
    25933125#endif /* WOLFSSL_SMALL_STACK_CACHE */
    2594 
    2595    /* init montgomery reduction */
    2596    if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
    2597 #ifdef WOLFSSL_SMALL_STACK_CACHE
    2598 #ifdef ALT_ECC_SIZE
    2599        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
    2600        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
    2601        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
    2602 #endif
    2603        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
    2604        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
    2605 #endif /* WOLFSSL_SMALL_STACK_CACHE */
    2606 #ifdef WOLFSSL_SMALL_STACK
    2607        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
    2608 #endif
    2609        return err;
    2610    }
    2611 
    2612    if ((err = mp_init(mu)) != MP_OKAY) {
    2613 #ifdef WOLFSSL_SMALL_STACK_CACHE
    2614 #ifdef ALT_ECC_SIZE
    2615        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
    2616        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
    2617        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
    2618 #endif
    2619        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
    2620        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
    2621 #endif /* WOLFSSL_SMALL_STACK_CACHE */
    2622 #ifdef WOLFSSL_SMALL_STACK
    2623        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
    2624 #endif
    2625        return err;
    2626    }
    2627    if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {
    2628        mp_clear(mu);
    2629 #ifdef WOLFSSL_SMALL_STACK_CACHE
    2630 #ifdef ALT_ECC_SIZE
    2631        XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
    2632        XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
    2633        XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
    2634 #endif
    2635        XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
    2636        XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
    2637 #endif /* WOLFSSL_SMALL_STACK_CACHE */
    2638 #ifdef WOLFSSL_SMALL_STACK
    2639        XFREE(mu, heap, DYNAMIC_TYPE_ECC);
    2640 #endif
    2641        return err;
    2642    }
    26433126
    26443127  /* alloc ram for window temps */
     
    26463129      M[i] = wc_ecc_new_point_h(heap);
    26473130      if (M[i] == NULL) {
    2648          mp_clear(mu);
    2649          err = MEMORY_E; goto exit;
     3131         err = MEMORY_E;
     3132         goto exit;
    26503133      }
    26513134#ifdef WOLFSSL_SMALL_STACK_CACHE
     
    26563139   /* make a copy of G in case R==G */
    26573140   tG = wc_ecc_new_point_h(heap);
    2658    if (tG == NULL)
     3141   if (tG == NULL) {
    26593142       err = MEMORY_E;
    2660 
    2661    /* tG = G  and convert to montgomery */
     3143       goto exit;
     3144   }
     3145   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
     3146       goto exit;
     3147   }
     3148
     3149   /* init montgomery reduction */
     3150   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
     3151      goto exit;
     3152   }
     3153
     3154   /* k can't have more bits than order */
     3155   if (mp_count_bits(k) > mp_count_bits(order)) {
     3156      err = ECC_OUT_OF_RANGE_E;
     3157      goto exit;
     3158   }
     3159
     3160
     3161#ifdef ECC_TIMING_RESISTANT
     3162   if ((err = mp_init(&t)) != MP_OKAY)
     3163      goto exit;
     3164
     3165   if (err == MP_OKAY)
     3166      err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
     3167
     3168    /* Check for k == order - 1. Result will be 0 point which is not correct
     3169     * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
     3170     * (with constant time implementation)
     3171     */
     3172   if (err == MP_OKAY)
     3173      err = mp_sub_d(order, 1, &t);
    26623174   if (err == MP_OKAY) {
    2663        if (mp_cmp_d(mu, 1) == MP_EQ) {
    2664            err = mp_copy(G->x, tG->x);
    2665            if (err == MP_OKAY)
    2666                err = mp_copy(G->y, tG->y);
    2667            if (err == MP_OKAY)
    2668                err = mp_copy(G->z, tG->z);
    2669        } else {
    2670            err = mp_mulmod(G->x, mu, modulus, tG->x);
    2671            if (err == MP_OKAY)
    2672                err = mp_mulmod(G->y, mu, modulus, tG->y);
    2673            if (err == MP_OKAY)
    2674                err = mp_mulmod(G->z, mu, modulus, tG->z);
    2675        }
    2676    }
    2677 
    2678    /* done with mu */
    2679    mp_clear(mu);
    2680 
    2681 #ifdef WOLFSSL_SMALL_STACK_CACHE
    2682    R->key = &key;
    2683 #endif
    2684 #ifndef ECC_TIMING_RESISTANT
    2685 
    2686    /* calc the M tab, which holds kG for k==8..15 */
    2687    /* M[0] == 8G */
    2688    if (err == MP_OKAY)
    2689        err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);
    2690    if (err == MP_OKAY)
    2691        err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
    2692    if (err == MP_OKAY)
    2693        err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
    2694 
    2695    /* now find (8+k)G for k=1..7 */
    2696    if (err == MP_OKAY)
    2697        for (j = 9; j < 16; j++) {
    2698            err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus,
    2699                                                                             mp);
    2700            if (err != MP_OKAY) break;
    2701        }
    2702 
    2703    /* setup sliding window */
    2704    if (err == MP_OKAY) {
    2705        mode   = 0;
    2706        bitcnt = 1;
    2707        buf    = 0;
    2708        digidx = get_digit_count(k) - 1;
    2709        bitcpy = bitbuf = 0;
    2710        first  = 1;
    2711 
    2712        /* perform ops */
    2713        for (;;) {
    2714            /* grab next digit as required */
    2715            if (--bitcnt == 0) {
    2716                if (digidx == -1) {
    2717                    break;
    2718                }
    2719                buf    = get_digit(k, digidx);
    2720                bitcnt = (int) DIGIT_BIT;
    2721                --digidx;
    2722            }
    2723 
    2724            /* grab the next msb from the ltiplicand */
    2725            i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
    2726            buf <<= 1;
    2727 
    2728            /* skip leading zero bits */
    2729            if (mode == 0 && i == 0)
    2730                continue;
    2731 
    2732            /* if the bit is zero and mode == 1 then we double */
    2733            if (mode == 1 && i == 0) {
    2734                err = ecc_projective_dbl_point(R, R, a, modulus, mp);
    2735                if (err != MP_OKAY) break;
    2736                continue;
    2737            }
    2738 
    2739            /* else we add it to the window */
    2740            bitbuf |= (i << (WINSIZE - ++bitcpy));
    2741            mode = 2;
    2742 
    2743            if (bitcpy == WINSIZE) {
    2744                /* if this is the first window we do a simple copy */
    2745                if (first == 1) {
    2746                    /* R = kG [k = first window] */
    2747                    err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
    2748                    if (err != MP_OKAY) break;
    2749 
    2750                    err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
    2751                    if (err != MP_OKAY) break;
    2752 
    2753                    err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
    2754                    first = 0;
    2755                } else {
    2756                    /* normal window */
    2757                    /* ok window is filled so double as required and add  */
    2758                    /* double first */
    2759                    for (j = 0; j < WINSIZE; j++) {
    2760                        err = ecc_projective_dbl_point(R, R, a, modulus, mp);
    2761                        if (err != MP_OKAY) break;
    2762                    }
    2763                    if (err != MP_OKAY) break;  /* out of first for(;;) */
    2764 
    2765                    /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
    2766                    err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
    2767                                                                    modulus, mp);
    2768                }
    2769                if (err != MP_OKAY) break;
    2770                /* empty window and reset */
    2771                bitcpy = bitbuf = 0;
    2772                mode = 1;
    2773            }
    2774        }
    2775    }
    2776 
    2777    /* if bits remain then double/add */
    2778    if (err == MP_OKAY) {
    2779        if (mode == 2 && bitcpy > 0) {
    2780            /* double then add */
    2781            for (j = 0; j < bitcpy; j++) {
    2782                /* only double if we have had at least one add first */
    2783                if (first == 0) {
    2784                    err = ecc_projective_dbl_point(R, R, a, modulus, mp);
    2785                    if (err != MP_OKAY) break;
    2786                }
    2787 
    2788                bitbuf <<= 1;
    2789                if ((bitbuf & (1 << WINSIZE)) != 0) {
    2790                    if (first == 1) {
    2791                        /* first add, so copy */
    2792                        err = mp_copy(tG->x, R->x);
    2793                        if (err != MP_OKAY) break;
    2794 
    2795                        err = mp_copy(tG->y, R->y);
    2796                        if (err != MP_OKAY) break;
    2797 
    2798                        err = mp_copy(tG->z, R->z);
    2799                        if (err != MP_OKAY) break;
    2800                        first = 0;
    2801                    } else {
    2802                        /* then add */
    2803                        err = ecc_projective_add_point(R, tG, R, a, modulus, mp);
    2804                        if (err != MP_OKAY) break;
    2805                    }
    2806                }
    2807            }
    2808        }
    2809    }
    2810 
    2811    #undef WINSIZE
    2812 
    2813 #else /* ECC_TIMING_RESISTANT */
    2814 
    2815    /* calc the M tab */
    2816    /* M[0] == G */
    2817    if (err == MP_OKAY)
    2818        err = mp_copy(tG->x, M[0]->x);
    2819    if (err == MP_OKAY)
    2820        err = mp_copy(tG->y, M[0]->y);
    2821    if (err == MP_OKAY)
    2822        err = mp_copy(tG->z, M[0]->z);
    2823 
    2824    /* M[1] == 2G */
    2825    if (err == MP_OKAY)
    2826        err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);
    2827 #ifdef WC_NO_CACHE_RESISTANT
    2828    if (err == MP_OKAY)
    2829        err = wc_ecc_copy_point(M[0], M[2]);
     3175      int kIsMinusOne = (mp_cmp(k, &t) == MP_EQ);
     3176      err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
     3177      if (err == 0) {
     3178          err = mp_sub(modulus, tG->y, &t);
     3179      }
     3180      if (err == 0) {
     3181          err = mp_cond_copy(&t, kIsMinusOne, R->y);
     3182      }
     3183      if (err == 0) {
     3184          err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
     3185      }
     3186   }
     3187
     3188   mp_free(&t);
    28303189#else
    2831    if (err == MP_OKAY)
    2832        err = wc_ecc_copy_point(M[0], M[3]);
    2833    if (err == MP_OKAY)
    2834        err = wc_ecc_copy_point(M[1], M[4]);
    2835 #endif
    2836 
    2837    /* setup sliding window */
    2838    mode   = 0;
    2839    bitcnt = 1;
    2840    buf    = 0;
    2841    digidx = get_digit_count(modulus) - 1;
    2842    /* The order MAY be 1 bit longer than the modulus. */
    2843    digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1));
    2844 
    2845    /* perform ops */
    2846    if (err == MP_OKAY) {
    2847        for (;;) {
    2848            /* grab next digit as required */
    2849            if (--bitcnt == 0) {
    2850                if (digidx == -1) {
    2851                    break;
    2852                }
    2853                buf = get_digit(k, digidx);
    2854                bitcnt = (int)DIGIT_BIT;
    2855                --digidx;
    2856            }
    2857 
    2858            /* grab the next msb from the multiplicand */
    2859            i = (buf >> (DIGIT_BIT - 1)) & 1;
    2860            buf <<= 1;
    2861 
    2862 #ifdef WC_NO_CACHE_RESISTANT
    2863            if (mode == 0) {
    2864                /* timing resistant - dummy operations */
    2865                if (err == MP_OKAY)
    2866                    err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,
    2867                                                   mp);
    2868                if (err == MP_OKAY)
    2869                    err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
    2870            }
    2871            else {
    2872                if (err == MP_OKAY)
    2873                    err = ecc_projective_add_point(M[0], M[1], M[i^1], a,
    2874                                                   modulus, mp);
    2875                if (err == MP_OKAY)
    2876                    err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
    2877            }
    2878 #else
    2879            if (err == MP_OKAY)
    2880                err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, mp);
    2881            if (err == MP_OKAY)
    2882                err = mp_cond_copy(M[2]->x, i, M[0]->x);
    2883            if (err == MP_OKAY)
    2884                err = mp_cond_copy(M[2]->y, i, M[0]->y);
    2885            if (err == MP_OKAY)
    2886                err = mp_cond_copy(M[2]->z, i, M[0]->z);
    2887            if (err == MP_OKAY)
    2888                err = mp_cond_copy(M[2]->x, i ^ 1, M[1]->x);
    2889            if (err == MP_OKAY)
    2890                err = mp_cond_copy(M[2]->y, i ^ 1, M[1]->y);
    2891            if (err == MP_OKAY)
    2892                err = mp_cond_copy(M[2]->z, i ^ 1, M[1]->z);
    2893 
    2894            if (err == MP_OKAY)
    2895                err = mp_cond_copy(M[0]->x, i ^ 1, M[2]->x);
    2896            if (err == MP_OKAY)
    2897                err = mp_cond_copy(M[0]->y, i ^ 1, M[2]->y);
    2898            if (err == MP_OKAY)
    2899                err = mp_cond_copy(M[0]->z, i ^ 1, M[2]->z);
    2900            if (err == MP_OKAY)
    2901                err = mp_cond_copy(M[1]->x, i, M[2]->x);
    2902            if (err == MP_OKAY)
    2903                err = mp_cond_copy(M[1]->y, i, M[2]->y);
    2904            if (err == MP_OKAY)
    2905                err = mp_cond_copy(M[1]->z, i, M[2]->z);
    2906 
    2907            if (err == MP_OKAY)
    2908                err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
    2909            if (err == MP_OKAY)
    2910                err = mp_cond_copy(M[2]->x, i ^ 1, M[0]->x);
    2911            if (err == MP_OKAY)
    2912                err = mp_cond_copy(M[2]->y, i ^ 1, M[0]->y);
    2913            if (err == MP_OKAY)
    2914                err = mp_cond_copy(M[2]->z, i ^ 1, M[0]->z);
    2915            if (err == MP_OKAY)
    2916                err = mp_cond_copy(M[2]->x, i, M[1]->x);
    2917            if (err == MP_OKAY)
    2918                err = mp_cond_copy(M[2]->y, i, M[1]->y);
    2919            if (err == MP_OKAY)
    2920                err = mp_cond_copy(M[2]->z, i, M[1]->z);
    2921 
    2922            if (err == MP_OKAY)
    2923                err = mp_cond_copy(M[3]->x, (mode ^ 1) & i, M[0]->x);
    2924            if (err == MP_OKAY)
    2925                err = mp_cond_copy(M[3]->y, (mode ^ 1) & i, M[0]->y);
    2926            if (err == MP_OKAY)
    2927                err = mp_cond_copy(M[3]->z, (mode ^ 1) & i, M[0]->z);
    2928            if (err == MP_OKAY)
    2929                err = mp_cond_copy(M[4]->x, (mode ^ 1) & i, M[1]->x);
    2930            if (err == MP_OKAY)
    2931                err = mp_cond_copy(M[4]->y, (mode ^ 1) & i, M[1]->y);
    2932            if (err == MP_OKAY)
    2933                err = mp_cond_copy(M[4]->z, (mode ^ 1) & i, M[1]->z);
    2934 #endif /* WC_NO_CACHE_RESISTANT */
    2935 
    2936            if (err != MP_OKAY)
    2937                break;
    2938 
    2939            mode |= i;
    2940        } /* end for */
    2941    }
    2942 
    2943    /* copy result out */
    2944    if (err == MP_OKAY)
    2945        err = mp_copy(M[0]->x, R->x);
    2946    if (err == MP_OKAY)
    2947        err = mp_copy(M[0]->y, R->y);
    2948    if (err == MP_OKAY)
    2949        err = mp_copy(M[0]->z, R->z);
    2950 
    2951 #endif /* ECC_TIMING_RESISTANT */
    2952 
     3190   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
     3191
     3192   (void)order;
     3193#endif
    29533194   /* map R back from projective space */
    29543195   if (err == MP_OKAY && map)
    2955        err = ecc_map(R, modulus, mp);
     3196      err = ecc_map(R, modulus, mp);
    29563197
    29573198exit:
     
    29603201   wc_ecc_del_point_h(tG, heap);
    29613202   for (i = 0; i < M_POINTS; i++) {
    2962        wc_ecc_del_point_h(M[i], heap);
     3203      wc_ecc_del_point_h(M[i], heap);
    29633204   }
    29643205#ifdef WOLFSSL_SMALL_STACK_CACHE
    29653206   R->key = NULL;
    2966 #ifdef ALT_ECC_SIZE
    2967    XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
    2968    XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
    2969    XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
    2970 #endif
    2971    XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
    2972    XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
     3207   ecc_key_tmp_final(&key, heap);
    29733208#endif /* WOLFSSL_SMALL_STACK_CACHE */
    2974 #ifdef WOLFSSL_SMALL_STACK
    2975    XFREE(mu, heap, DYNAMIC_TYPE_ECC);
    2976 #endif
    29773209
    29783210   return err;
     3211}
    29793212#else
     3213{
    29803214   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
    29813215       return ECC_BAD_ARG_E;
     
    29833217
    29843218   (void)a;
    2985 
     3219   (void)order;
     3220   (void)rng;
     3221
     3222#ifdef WOLFSSL_HAVE_SP_ECC
    29863223#ifndef WOLFSSL_SP_NO_256
    29873224   if (mp_count_bits(modulus) == 256) {
     
    29943231   }
    29953232#endif
     3233#else
     3234   (void)map;
     3235   (void)heap;
     3236#endif
    29963237   return ECC_BAD_ARG_E;
    2997 #endif
    2998 }
    2999 
    3000 #endif /* !FP_ECC || !WOLFSSL_SP_MATH */
     3238}
     3239#endif /* !WOLFSSL_SP_MATH */
     3240#endif /* !FP_ECC */
    30013241
    30023242#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
     
    35353775{
    35363776   int err;
    3537 #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
     3777#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
     3778   !defined(WOLFSSL_ATECC608A)
    35383779   CRYS_ECDH_TempData_t tempBuff;
    35393780#endif
     
    35693810   }
    35703811
    3571 #ifdef WOLFSSL_ATECC508A
     3812#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    35723813   /* For SECP256R1 use hardware */
    35733814   if (private_key->dp->id == ECC_SECP256R1) {
     
    35913832        return err;
    35923833    }
    3593 
     3834#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     3835    err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
    35943836#else
    35953837   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
     
    36003842
    36013843
    3602 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     3844#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     3845    !defined(WOLFSSL_CRYPTOCELL)
    36033846
    36043847static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
    36053848                               byte* out, word32* outlen, ecc_curve_spec* curve)
    36063849{
    3607     int err;
    3608 #ifndef WOLFSSL_SP_MATH
     3850    int err = MP_OKAY;
     3851#if !defined(WOLFSSL_SP_MATH)
    36093852    ecc_point* result = NULL;
    36103853    word32 x = 0;
     
    36143857    mp_int k_lcl;
    36153858
     3859    WOLFSSL_ENTER("wc_ecc_shared_secret_gen_sync");
    36163860    /* if cofactor flag has been set */
    36173861    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
     
    36303874        }
    36313875    }
     3876#else
     3877    WOLFSSL_ENTER("wc_ecc_shared_secret_gen_sync");
    36323878#endif
    36333879
     
    36473893    else
    36483894#endif
    3649 #endif
    3650 #ifdef WOLFSSL_SP_MATH
     3895#else
     3896    (void)point;
     3897    (void)out;
     3898    (void)outlen;
     3899    (void)k;
     3900#endif
     3901#if defined(WOLFSSL_SP_MATH)
    36513902    {
    36523903        err = WC_KEY_SIZE_E;
     
    36683919        }
    36693920
    3670         /* Map in a separate call as this should be constant time */
    3671         err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 0,
    3672                                                              private_key->heap);
     3921#ifdef ECC_TIMING_RESISTANT
     3922        if (private_key->rng == NULL) {
     3923            err = MISSING_RNG_E;
     3924        }
     3925#endif
     3926
     3927        if (err == MP_OKAY) {
     3928            /* Map in a separate call as this should be constant time */
     3929#ifdef ECC_TIMING_RESISTANT
     3930            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
     3931                                              curve->order, private_key->rng, 0,
     3932                                              private_key->heap);
     3933#else
     3934            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
     3935                                      curve->order, NULL, 0, private_key->heap);
     3936#endif
     3937        }
    36733938        if (err == MP_OKAY) {
    36743939            err = mp_montgomery_setup(curve->prime, &mp);
     
    37003965#endif
    37013966
     3967    WOLFSSL_LEAVE("wc_ecc_shared_secret_gen_sync", err);
     3968
    37023969    return err;
    37033970}
     
    37113978
    37123979#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
    3713 #ifdef HAVE_CAVIUM_V
    3714     /* verify the curve is supported by hardware */
    3715     if (NitroxEccIsCurveSupported(private_key))
    3716 #endif
    3717     {
     3980    if (private_key->dp
     3981    #ifdef WOLFSSL_CUSTOM_CURVES
     3982        && private_key->dp->id != ECC_CURVE_CUSTOM
     3983    #endif
     3984    #ifdef HAVE_CAVIUM_V
     3985        /* verify the curve is supported by hardware */
     3986        && NitroxEccIsCurveSupported(private_key)
     3987    #endif
     3988    ) {
    37183989        word32 keySz = private_key->dp->size;
    37193990
     
    37704041{
    37714042    int err;
    3772     DECLARE_CURVE_SPECS(curve, 2);
     4043    DECLARE_CURVE_SPECS(curve, 3);
    37734044
    37744045    if (private_key == NULL || point == NULL || out == NULL ||
     
    37784049
    37794050    /* load curve info */
    3780     ALLOC_CURVE_SPECS(2);
     4051    ALLOC_CURVE_SPECS(3);
    37814052    err = wc_ecc_curve_load(private_key->dp, &curve,
    3782         (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
     4053        (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER));
    37834054    if (err != MP_OKAY) {
    37844055        FREE_CURVE_SPECS();
     
    38264097    if (private_key->type != ECC_PRIVATEKEY &&
    38274098            private_key->type != ECC_PRIVATEKEY_ONLY) {
     4099        WOLFSSL_MSG("ECC_BAD_ARG_E");
    38284100        return ECC_BAD_ARG_E;
    38294101    }
    38304102
    38314103    /* Verify domain params supplied */
    3832     if (wc_ecc_is_valid_idx(private_key->idx) == 0)
     4104    if (wc_ecc_is_valid_idx(private_key->idx) == 0) {
     4105        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
    38334106        return ECC_BAD_ARG_E;
     4107    }
    38344108
    38354109    switch(private_key->state) {
     
    38654139    } /* switch */
    38664140
     4141    WOLFSSL_LEAVE("wc_ecc_shared_secret_ex", err);
     4142
    38674143    /* if async pending then return and skip done cleanup below */
    38684144    if (err == WC_PENDING_E) {
     
    38824158#endif /* HAVE_ECC_DHE */
    38834159
    3884 
    3885 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     4160#ifdef USE_ECC_B_PARAM
     4161/* Checks if a point p lies on the curve with index curve_idx */
     4162int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
     4163{
     4164    int err;
     4165    DECLARE_CURVE_SPECS(curve, 3);
     4166
     4167    if (p == NULL)
     4168        return BAD_FUNC_ARG;
     4169
     4170    /* is the IDX valid ?  */
     4171    if (wc_ecc_is_valid_idx(curve_idx) != 1) {
     4172       return ECC_BAD_ARG_E;
     4173    }
     4174
     4175    ALLOC_CURVE_SPECS(3);
     4176    err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
     4177                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
     4178                                ECC_CURVE_FIELD_BF);
     4179    if (err == MP_OKAY) {
     4180        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
     4181    }
     4182
     4183    wc_ecc_curve_free(curve);
     4184    FREE_CURVE_SPECS();
     4185
     4186    return err;
     4187}
     4188#endif /* USE_ECC_B_PARAM */
     4189
     4190#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     4191    !defined(WOLFSSL_CRYPTOCELL)
    38864192/* return 1 if point is at infinity, 0 if not, < 0 on error */
    38874193int wc_ecc_point_is_at_infinity(ecc_point* p)
     
    38954201    return 0;
    38964202}
     4203#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
    38974204
    38984205/* generate random and ensure its greater than 0 and less than order */
     
    39384245#endif /* !WC_NO_RNG */
    39394246}
    3940 #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */
    39414247
    39424248static WC_INLINE void wc_ecc_reset(ecc_key* key)
     
    39454251    key->state = ECC_STATE_NONE;
    39464252}
    3947 
    39484253
    39494254/* create the public ECC key from a private key
     
    39604265 * returns MP_OKAY on success
    39614266 */
    3962 static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
    3963         ecc_point* pubOut)
     4267static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
     4268        ecc_point* pubOut, WC_RNG* rng)
    39644269{
    39654270    int err = MP_OKAY;
    3966 #ifndef WOLFSSL_ATECC508A
    3967 #ifndef WOLFSSL_SP_MATH
     4271#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) \
     4272  && !defined(WOLFSSL_SILABS_SE_ACCEL)
     4273#if !defined(WOLFSSL_SP_MATH)
    39684274    ecc_point* base = NULL;
    39694275#endif
     
    39724278#endif /* !WOLFSSL_ATECC508A */
    39734279
     4280    (void)rng;
     4281
    39744282    if (key == NULL) {
    39754283        return BAD_FUNC_ARG;
    39764284    }
    39774285
    3978 #ifndef WOLFSSL_ATECC508A
     4286#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) \
     4287  && !defined(WOLFSSL_SILABS_SE_ACCEL)
    39794288
    39804289    /* if ecc_point passed in then use it as output for public key point */
     
    39994308            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
    40004309        }
     4310    }
     4311
     4312    if ((err == MP_OKAY) && (mp_iszero(&key->k) || mp_isneg(&key->k) ||
     4313                                      (mp_cmp(&key->k, curve->order) != MP_LT)))
     4314    {
     4315        err = ECC_PRIV_KEY_E;
    40014316    }
    40024317
     
    40144329    }
    40154330
    4016 
    40174331    if (err != MP_OKAY) {
    40184332    }
     
    40324346#endif
    40334347#endif
    4034 #ifdef WOLFSSL_SP_MATH
     4348#if defined(WOLFSSL_SP_MATH)
    40354349        err = WC_KEY_SIZE_E;
    40364350#else
    40374351    {
    4038         mp_digit mp;
     4352        mp_digit mp = 0;
    40394353
    40404354        base = wc_ecc_new_point_h(key->heap);
     
    40474361            err = mp_copy(curve->Gy, base->y);
    40484362        if (err == MP_OKAY)
     4363            err = mp_montgomery_setup(curve->prime, &mp);
     4364        if (err == MP_OKAY)
    40494365            err = mp_set(base->z, 1);
    40504366
     
    40524368        if (err == MP_OKAY) {
    40534369            /* Map in a separate call as this should be constant time */
    4054             err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime,
    4055                                                                  0, key->heap);
     4370            err = wc_ecc_mulmod_ex2(&key->k, base, pub, curve->Af, curve->prime,
     4371                                               curve->order, rng, 0, key->heap);
    40564372            if (err == MP_MEM) {
    40574373               err = MEMORY_E;
    40584374            }
    4059         }
    4060         if (err == MP_OKAY) {
    4061             err = mp_montgomery_setup(curve->prime, &mp);
    40624375        }
    40634376        if (err == MP_OKAY) {
     
    40954408    (void)curveIn;
    40964409    err = NOT_COMPILED_IN;
    4097 #endif /* WOLFSSL_ATECC508A */
     4410#endif /* WOLFSSL_ATECC508A || WOLFSSL_SILABS_SE_ACCEL */
    40984411
    40994412    /* change key state if public part is cached */
     
    41194432    WOLFSSL_ENTER("wc_ecc_make_pub");
    41204433
    4121     return wc_ecc_make_pub_ex(key, NULL, pubOut);
    4122 }
    4123 
    4124 
    4125 WOLFSSL_ABI
    4126 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
    4127 {
     4434    return ecc_make_pub_ex(key, NULL, pubOut, NULL);
     4435}
     4436
     4437/* create the public ECC key from a private key - mask timing use random z
     4438 *
     4439 * key     an initialized private key to generate public part from
     4440 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
     4441 *         is cached in key instead.
     4442 *
     4443 *
     4444 * returns MP_OKAY on success
     4445 */
     4446int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
     4447{
     4448    WOLFSSL_ENTER("wc_ecc_make_pub");
     4449
     4450    return ecc_make_pub_ex(key, NULL, pubOut, rng);
     4451}
     4452
     4453
     4454int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
     4455                        int flags)
     4456{
     4457
    41284458    int err;
    4129 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
    4130 #ifndef WOLFSSL_SP_MATH
     4459#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     4460    !defined(WOLFSSL_CRYPTOCELL)
     4461#if !defined(WOLFSSL_SP_MATH)
    41314462    DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
    41324463#endif
    41334464#endif /* !WOLFSSL_ATECC508A */
    4134 #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
     4465#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
     4466    !defined(WOLFSSL_ATECC608A)
    41354467    const CRYS_ECPKI_Domain_t*  pDomain;
    41364468    CRYS_ECPKI_KG_TempData_t    tempBuff;
     
    41504482        return err;
    41514483    }
     4484
     4485    key->flags = flags;
    41524486
    41534487#ifdef WOLF_CRYPTO_CB
     
    41794513#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
    41804514
    4181 #ifdef WOLFSSL_ATECC508A
     4515#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    41824516   if (key->dp->id == ECC_SECP256R1) {
    41834517       key->type = ECC_PRIVATEKEY;
     
    42514585    }
    42524586
     4587#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     4588    return silabs_ecc_make_key(key, keysize);
    42534589#else
    42544590
     
    42754611
    42764612   { /* software key gen */
    4277 #ifdef WOLFSSL_SP_MATH
     4613#if defined(WOLFSSL_SP_MATH)
    42784614        err = WC_KEY_SIZE_E;
    42794615#else
     
    42944630        /* generate public key from k */
    42954631        if (err == MP_OKAY)
    4296             err = wc_ecc_make_pub_ex(key, curve, NULL);
     4632            err = ecc_make_pub_ex(key, curve, NULL, rng);
    42974633
    42984634        if (err == MP_OKAY)
     
    43274663}
    43284664
     4665WOLFSSL_ABI
     4666int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
     4667{
     4668    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
     4669}
     4670
    43294671#ifdef ECC_DUMP_OID
    43304672/* Optional dump of encoded OID for adding new curves */
     
    44524794#endif
    44534795
    4454 #ifdef WOLFSSL_ATECC508A
     4796#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    44554797    key->slot = ATECC_INVALID_SLOT;
    44564798#else
     
    44984840}
    44994841
    4500 #ifdef HAVE_PKCS11
     4842#ifdef WOLF_CRYPTO_CB
    45014843int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
    45024844                   int devId)
     
    45114853    if (ret == 0)
    45124854        ret = wc_ecc_init_ex(key, heap, devId);
    4513 
    45144855    if (ret == 0 && id != NULL && len != 0) {
    45154856        XMEMCPY(key->id, id, len);
    45164857        key->idLen = len;
     4858    }
     4859
     4860    return ret;
     4861}
     4862
     4863int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
     4864{
     4865    int ret = 0;
     4866    int labelLen = 0;
     4867
     4868    if (key == NULL || label == NULL)
     4869        ret = BAD_FUNC_ARG;
     4870    if (ret == 0) {
     4871        labelLen = (int)XSTRLEN(label);
     4872        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
     4873            ret = BUFFER_E;
     4874    }
     4875
     4876    if (ret == 0)
     4877        ret = wc_ecc_init_ex(key, heap, devId);
     4878    if (ret == 0) {
     4879        XMEMCPY(key->label, label, labelLen);
     4880        key->labelLen = labelLen;
    45174881    }
    45184882
     
    45544918#ifndef NO_ASN
    45554919
    4556 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || \
    4557     defined(WOLFSSL_CRYPTOCELL)
     4920
     4921#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
     4922    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
     4923    defined(WOLFSSL_SILABS_SE_ACCEL)
    45584924static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
    45594925    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
     
    45654931#endif
    45664932    {
    4567     #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
     4933    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
     4934        !defined(WOLFSSL_ATECC608A)
    45684935        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
    45694936        word32 raw_sig_size = *outlen;
     
    45724939    #endif
    45734940        word32 keysize = (word32)key->dp->size;
     4941    #ifdef PLUTON_CRYPTO_ECC
    45744942        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
     4943    #endif
    45754944
    45764945        /* Check args */
     
    45794948        }
    45804949
    4581     #if defined(WOLFSSL_ATECC508A)
    4582         key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
    4583         if (key->slot == ATECC_INVALID_SLOT) {
    4584             return ECC_BAD_ARG_E;
    4585         }
    4586 
     4950    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    45874951        /* Sign: Result is 32-bytes of R then 32-bytes of S */
    45884952        err = atmel_ecc_sign(key->slot, in, out);
     
    46044968            }
    46054969        }
     4970    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
     4971        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
     4972        if (err != 0) {
     4973               return WC_HW_E;
     4974        }
    46064975    #elif defined(WOLFSSL_CRYPTOCELL)
    4607 
     4976        /* truncate if hash is longer than key size */
     4977        if (msgLenInBytes > keysize) {
     4978            msgLenInBytes = keysize;
     4979        }
    46084980        hash_mode = cc310_hashModeECC(msgLenInBytes);
    46094981        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
    46104982            hash_mode = cc310_hashModeECC(keysize);
    46114983            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
    4612         }
    4613 
    4614         /* truncate if hash is longer than key size */
    4615         if (msgLenInBytes > keysize) {
    4616             msgLenInBytes = keysize;
     4984
    46174985        }
    46184986
     
    48005168
    48015169/* hardware crypto */
    4802 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL)
     5170#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
     5171    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
     5172  defined(WOLFSSL_SILABS_SE_ACCEL)
    48035173    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
    48045174#else
     
    48065176#endif
    48075177    if (err < 0) {
     5178        mp_clear(r);
     5179        mp_clear(s);
    48085180    #ifdef WOLFSSL_SMALL_STACK
    48095181        XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
     
    48365208    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
    48375209}
    4838 #elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     5210#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     5211      !defined(WOLFSSL_CRYPTOCELL)
    48395212/**
    48405213  Sign a message digest
     
    48505223{
    48515224   int    err = 0;
    4852 #ifndef WOLFSSL_SP_MATH
     5225#if !defined(WOLFSSL_SP_MATH)
    48535226   mp_int* e;
    48545227#if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
     
    48575230#endif
    48585231
    4859 #if defined(WOLFSSL_ECDSA_SET_K) || \
     5232#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
    48605233    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
    48615234    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
     
    48805253   }
    48815254
    4882 #ifdef WOLFSSL_SP_MATH
    4883 #ifndef WOLFSSL_SP_NO_256
    4884     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
    4885     #ifndef WOLFSSL_ECDSA_SET_K
    4886         return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap);
     5255#if defined(WOLFSSL_SP_MATH)
     5256    if (key->idx == ECC_CUSTOM_IDX ||
     5257            (ecc_sets[key->idx].id != ECC_SECP256R1 &&
     5258             ecc_sets[key->idx].id != ECC_SECP384R1)) {
     5259        return WC_KEY_SIZE_E;
     5260    }
     5261#endif
     5262
     5263#if (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
     5264                                                    defined(WOLFSSL_HAVE_SP_ECC)
     5265    if (key->idx != ECC_CUSTOM_IDX
     5266    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
     5267        && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC
     5268    #endif
     5269    ) {
     5270    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
     5271        mp_int* sign_k = key->sign_k;
    48875272    #else
    4888         return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
    4889                                                                      key->heap);
     5273        mp_int* sign_k = NULL;
    48905274    #endif
    4891     }
    4892 #endif
    4893 #ifdef WOLFSSL_SP_384
    4894     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
    4895     #ifndef WOLFSSL_ECDSA_SET_K
    4896         return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, key->heap);
    4897     #else
    4898         return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k,
    4899                                                                      key->heap);
     5275    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
     5276        /* perform blocking call to non-blocking function */
     5277        ecc_nb_ctx_t nb_ctx;
     5278        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
    49005279    #endif
    4901     }
    4902 #endif
    4903     return WC_KEY_SIZE_E;
     5280    #ifndef WOLFSSL_SP_NO_256
     5281        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
     5282        #ifdef WC_ECC_NONBLOCK
     5283            if (key->nb_ctx) {
     5284                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
     5285                    &key->k, r, s, sign_k, key->heap);
     5286            }
     5287            #ifdef WC_ECC_NONBLOCK_ONLY
     5288            do { /* perform blocking call to non-blocking function */
     5289                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
     5290                    &key->k, r, s, sign_k, key->heap);
     5291            } while (err == FP_WOULDBLOCK);
     5292            return err;
     5293            #endif
     5294        #endif /* WC_ECC_NONBLOCK */
     5295        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
     5296            return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, sign_k,
     5297                key->heap);
     5298        #endif
     5299        }
     5300    #endif
     5301    #ifdef WOLFSSL_SP_384
     5302        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
     5303        #ifdef WC_ECC_NONBLOCK
     5304            if (key->nb_ctx) {
     5305                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
     5306                    &key->k, r, s, sign_k, key->heap);
     5307            }
     5308            #ifdef WC_ECC_NONBLOCK_ONLY
     5309            do { /* perform blocking call to non-blocking function */
     5310                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
     5311                    &key->k, r, s, sign_k, key->heap);
     5312            } while (err == FP_WOULDBLOCK);
     5313            return err;
     5314            #endif
     5315        #endif /* WC_ECC_NONBLOCK */
     5316        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
     5317            return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, sign_k,
     5318                key->heap);
     5319        #endif
     5320        }
     5321    #endif
     5322    }
    49045323#else
    4905 #ifdef WOLFSSL_HAVE_SP_ECC
    4906     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
    4907     if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
    4908     #endif
    4909     {
    4910 #ifndef WOLFSSL_SP_NO_256
    4911         if (key->idx != ECC_CUSTOM_IDX &&
    4912                                        ecc_sets[key->idx].id == ECC_SECP256R1) {
    4913         #ifndef WOLFSSL_ECDSA_SET_K
    4914             return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL,
    4915                                                                      key->heap);
    4916         #else
    4917             return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
    4918                                                                      key->heap);
    4919         #endif
    4920         }
    4921 #endif
    4922 #ifdef WOLFSSL_SP_384
    4923         if (key->idx != ECC_CUSTOM_IDX &&
    4924                                        ecc_sets[key->idx].id == ECC_SECP384R1) {
    4925         #ifndef WOLFSSL_ECDSA_SET_K
    4926             return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL,
    4927                                                                      key->heap);
    4928         #else
    4929             return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k,
    4930                                                                      key->heap);
    4931         #endif
    4932         }
    4933 #endif
    4934     }
    4935 #endif /* WOLFSSL_HAVE_SP_ECC */
    4936 
     5324   (void)inlen;
     5325#endif
    49375326
    49385327#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
     
    49525341#endif
    49535342
     5343
     5344#if !defined(WOLFSSL_SP_MATH)
     5345
    49545346#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
    49555347   err = wc_ecc_alloc_mpint(key, &key->e);
     
    49775369
    49785370   /* load curve info */
    4979 #if defined(WOLFSSL_ECDSA_SET_K)
     5371#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
    49805372   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
    49815373   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
     
    51475539                    break;
    51485540               }
    5149        #ifdef WOLFSSL_ECDSA_SET_K
     5541       #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
    51505542               if (key->sign_k != NULL) {
    51515543                   if (loop_check > 1) {
     
    51545546                   }
    51555547
     5548                   /* use provided sign_k */
    51565549                   err = mp_copy(key->sign_k, &pubkey->k);
    51575550                   if (err != MP_OKAY) break;
    51585551
     5552                   /* free sign_k, so only used once */
    51595553                   mp_forcezero(key->sign_k);
    51605554                   mp_free(key->sign_k);
    51615555                   XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
    51625556                   key->sign_k = NULL;
    5163                    err = wc_ecc_make_pub_ex(pubkey, curve, NULL);
     5557           #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
     5558                   loop_check = 64;
     5559           #endif
     5560
     5561                   /* compute public key based on provided "k" */
     5562                   err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
    51645563               }
    51655564               else
     
    51755574               if (err != MP_OKAY) break;
    51765575
    5177                if (mp_iszero(r) == MP_YES) {
    5178                 #ifndef ALT_ECC_SIZE
    5179                    mp_clear(pubkey->pubkey.x);
    5180                    mp_clear(pubkey->pubkey.y);
    5181                    mp_clear(pubkey->pubkey.z);
    5182                 #endif
    5183                    mp_forcezero(&pubkey->k);
    5184                }
    5185                else {
     5576               if (mp_iszero(r) == MP_NO) {
     5577                   mp_int* ep = &pubkey->k;
     5578                   mp_int* kp = &pubkey->k;
     5579                   mp_int* x  = &key->k;
     5580
    51865581                   /* find s = (e + xr)/k
    51875582                             = b.(e/k.b + x.r/k.b) */
    51885583
    5189                    /* k = k.b */
    5190                    err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);
     5584                   /* k' = k.b */
     5585                   err = mp_mulmod(&pubkey->k, b, curve->order, kp);
    51915586                   if (err != MP_OKAY) break;
    51925587
    5193                    /* k = 1/k.b */
    5194                    err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);
     5588                   /* k' = 1/k.b
     5589                         = 1/k' */
     5590                   err = mp_invmod(kp, curve->order, kp);
    51955591                   if (err != MP_OKAY) break;
    51965592
    51975593                   /* s = x.r */
    5198                    err = mp_mulmod(&key->k, r, curve->order, s);
     5594                   err = mp_mulmod(x, r, curve->order, s);
    51995595                   if (err != MP_OKAY) break;
    52005596
    5201                    /* s = x.r/k.b */
    5202                    err = mp_mulmod(&pubkey->k, s, curve->order, s);
     5597                   /* s = x.r/k.b
     5598                        = k'.s */
     5599                   err = mp_mulmod(kp, s, curve->order, s);
    52035600                   if (err != MP_OKAY) break;
    52045601
    5205                    /* e = e/k.b */
    5206                    err = mp_mulmod(&pubkey->k, e, curve->order, e);
     5602                   /* e' = e/k.b
     5603                         = e.k' */
     5604                   err = mp_mulmod(kp, e, curve->order, ep);
    52075605                   if (err != MP_OKAY) break;
    52085606
    5209                    /* s = e/k.b + x.r/k.b
    5210                         = (e + x.r)/k.b */
    5211                    err = mp_add(e, s, s);
     5607                   /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
     5608                        = e' + s */
     5609                   err = mp_addmod_ct(ep, s, curve->order, s);
    52125610                   if (err != MP_OKAY) break;
    52135611
    5214                    /* s = b.(e + x.r)/k.b
    5215                         = (e + x.r)/k */
     5612                   /* s = b.(e + x.r)/k.b = (e + x.r)/k
     5613                        = b.s */
    52165614                   err = mp_mulmod(s, b, curve->order, s);
    52175615                   if (err != MP_OKAY) break;
    52185616
    5219                    /* s = (e + xr)/k */
    5220                    err = mp_mod(s, curve->order, s);
    5221                    if (err != MP_OKAY) break;
    5222 
    5223                    if (mp_iszero(s) == MP_NO)
     5617                   if (mp_iszero(s) == MP_NO) {
     5618                       /* sign successful */
    52245619                       break;
     5620                   }
    52255621                }
     5622            #ifndef ALT_ECC_SIZE
     5623                mp_clear(pubkey->pubkey.x);
     5624                mp_clear(pubkey->pubkey.y);
     5625                mp_clear(pubkey->pubkey.z);
     5626            #endif
     5627                mp_forcezero(&pubkey->k);
    52265628           }
    52275629           mp_clear(b);
    5228            mp_free(b);
    52295630       #ifdef WOLFSSL_SMALL_STACK
    52305631           XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
     
    52435644#endif
    52445645   FREE_CURVE_SPECS();
    5245 #endif /* WOLFSSL_SP_MATH */
     5646#endif /* !WOLFSSL_SP_MATH */
    52465647
    52475648   return err;
    52485649}
    52495650
    5250 #ifdef WOLFSSL_ECDSA_SET_K
     5651#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
    52515652int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
    52525653{
    5253     int ret = 0;
     5654    int ret;
     5655    DECLARE_CURVE_SPECS(curve, 1);
    52545656
    52555657    if (k == NULL || klen == 0 || key == NULL) {
    5256         ret = BAD_FUNC_ARG;
    5257     }
    5258 
    5259     if (ret == 0) {
    5260         if (key->sign_k == NULL) {
    5261             key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
    5262                                                               DYNAMIC_TYPE_ECC);
    5263             if (key->sign_k == NULL) {
    5264                 ret = MEMORY_E;
    5265             }
    5266         }
    5267     }
    5268 
    5269     if (ret == 0) {
    5270         ret = mp_init(key->sign_k);
    5271     }
     5658        return BAD_FUNC_ARG;
     5659    }
     5660
     5661    ALLOC_CURVE_SPECS(1);
     5662    ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
     5663    if (ret != 0) {
     5664        FREE_CURVE_SPECS();
     5665        return ret;
     5666    }
     5667
     5668    if (key->sign_k == NULL) {
     5669        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
     5670                                                            DYNAMIC_TYPE_ECC);
     5671        if (key->sign_k) {
     5672            ret = mp_init(key->sign_k);
     5673        }
     5674        else {
     5675            ret = MEMORY_E;
     5676        }
     5677    }
     5678
    52725679    if (ret == 0) {
    52735680        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
    52745681    }
    5275 
     5682    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
     5683        ret = MP_VAL;
     5684    }
     5685
     5686    wc_ecc_curve_free(curve);
     5687    FREE_CURVE_SPECS();
    52765688    return ret;
    52775689}
    5278 #endif /* WOLFSSL_ECDSA_SET_K */
    5279 #endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/
    5280 
    5281 #endif /* HAVE_ECC_SIGN */
     5690#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
     5691#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
     5692
     5693#endif /* !HAVE_ECC_SIGN */
    52825694
    52835695#ifdef WOLFSSL_CUSTOM_CURVES
     
    53165728    }
    53175729
    5318 #ifdef WOLFSSL_ECDSA_SET_K
     5730#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
    53195731    if (key->sign_k != NULL) {
    53205732        mp_forcezero(key->sign_k);
     
    53315743#endif
    53325744
    5333 #ifdef WOLFSSL_ATECC508A
     5745#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    53345746    atmel_ecc_free(key->slot);
    53355747    key->slot = ATECC_INVALID_SLOT;
     
    53505762}
    53515763
    5352 #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     5764#ifndef WOLFSSL_SP_MATH
     5765/* Handles add failure cases:
     5766 *
     5767 * Before add:
     5768 *   Case 1: A is infinity
     5769 *        -> Copy B into result.
     5770 *   Case 2: B is infinity
     5771 *        -> Copy A into result.
     5772 *   Case 3: x and z are the same in A and B (same x value in affine)
     5773 *     Case 3a: y values the same - same point
     5774 *           -> Double instead of add.
     5775 *     Case 3b: y values different - negative of the other when points on curve
     5776 *           -> Need to set result to infinity.
     5777 *
     5778 * After add:
     5779 *   Case 1: A and B are the same point (maybe different z)
     5780 *           (Result was: x == y == z == 0)
     5781 *        -> Need to double instead.
     5782 *
     5783 *   Case 2: A + B = <infinity> = 0.
     5784 *           (Result was: z == 0, x and/or y not 0)
     5785 *        -> Need to set result to infinity.
     5786 */
     5787int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
     5788    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
     5789{
     5790    int err;
     5791
     5792    if (mp_iszero(A->x) && mp_iszero(A->y)) {
     5793        /* A is infinity. */
     5794        err = wc_ecc_copy_point(B, R);
     5795    }
     5796    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
     5797        /* B is infinity. */
     5798        err = wc_ecc_copy_point(A, R);
     5799    }
     5800    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
     5801        /* x ordinattes the same. */
     5802        if (mp_cmp(A->y, B->y) == MP_EQ) {
     5803            /* A = B */
     5804            err = ecc_projective_dbl_point(B, R, a, modulus, mp);
     5805        }
     5806        else {
     5807            /* A = -B */
     5808            err = mp_set(R->x, 0);
     5809            if (err == MP_OKAY)
     5810                err = mp_set(R->y, 0);
     5811            if (err == MP_OKAY)
     5812                err = mp_set(R->z, 1);
     5813            if ((err == MP_OKAY) && (infinity != NULL))
     5814                *infinity = 1;
     5815        }
     5816    }
     5817    else {
     5818        err = ecc_projective_add_point(A, B, R, a, modulus, mp);
     5819        if ((err == MP_OKAY) && mp_iszero(R->z)) {
     5820            /* When all zero then should have done a double */
     5821            if (mp_iszero(R->x) && mp_iszero(R->y)) {
     5822                err = ecc_projective_dbl_point(B, R, a, modulus, mp);
     5823            }
     5824            /* When only Z zero then result is infinity */
     5825            else {
     5826                err = mp_set(R->x, 0);
     5827                if (err == MP_OKAY)
     5828                    err = mp_set(R->y, 0);
     5829                if (err == MP_OKAY)
     5830                    err = mp_set(R->z, 1);
     5831                if ((err == MP_OKAY) && (infinity != NULL))
     5832                    *infinity = 1;
     5833            }
     5834        }
     5835    }
     5836
     5837    return err;
     5838}
     5839
     5840/* Handles when P is the infinity point.
     5841 *
     5842 * Double infinity -> infinity.
     5843 * Otherwise do normal double - which can't lead to infinity as odd order.
     5844 */
     5845int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
     5846                                  mp_int* modulus, mp_digit mp)
     5847{
     5848    int err;
     5849
     5850    if (mp_iszero(P->x) && mp_iszero(P->y)) {
     5851        /* P is infinity. */
     5852        err = wc_ecc_copy_point(P, R);
     5853    }
     5854    else {
     5855        err = ecc_projective_dbl_point(P, R, a, modulus, mp);
     5856    }
     5857
     5858    return err;
     5859}
     5860#endif
     5861
     5862#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
     5863    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_CRYPTOCELL)
    53535864#ifdef ECC_SHAMIR
    53545865
     
    55316042  }
    55326043
    5533   if (err == MP_OKAY)
     6044  if (err == MP_OKAY) {
    55346045    /* precomp [i,0](A + B) table */
    5535     err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);
    5536 
    5537   if (err == MP_OKAY)
    5538     err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
    5539                                    a, modulus, mp);
    5540   if (err == MP_OKAY)
     6046    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
     6047  }
     6048  if (err == MP_OKAY) {
     6049    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
     6050                                                          a, modulus, mp, NULL);
     6051  }
     6052
     6053  if (err == MP_OKAY) {
    55416054    /* precomp [0,i](A + B) table */
    5542     err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);
    5543 
    5544   if (err == MP_OKAY)
    5545     err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
    5546                                    a, modulus, mp);
     6055    err = ecc_projective_dbl_point_safe(precomp[1<<2], precomp[2<<2], a,
     6056                                                                  modulus, mp);
     6057  }
     6058  if (err == MP_OKAY) {
     6059    err = ecc_projective_add_point_safe(precomp[1<<2], precomp[2<<2],
     6060                                           precomp[3<<2], a, modulus, mp, NULL);
     6061  }
    55476062
    55486063  if (err == MP_OKAY) {
     
    55516066      for (y = 1; y < 4; y++) {
    55526067        if (err == MP_OKAY) {
    5553           err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
    5554                                              precomp[x+(y<<2)], a, modulus, mp);
     6068          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
     6069                                                  precomp[x+(y<<2)], a, modulus,
     6070                                                  mp, NULL);
    55556071        }
    55566072      }
     
    55906106            /* double twice */
    55916107            if (err == MP_OKAY)
    5592                 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
     6108                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
    55936109            if (err == MP_OKAY)
    5594                 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
     6110                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
    55956111            else
    55966112                break;
     
    55996115        /* if not both zero */
    56006116        if ((nA != 0) || (nB != 0)) {
     6117            int i = nA + (nB<<2);
    56016118            if (first == 1) {
    56026119                /* if first, copy from table */
    56036120                first = 0;
    56046121                if (err == MP_OKAY)
    5605                     err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
     6122                    err = mp_copy(precomp[i]->x, C->x);
    56066123
    56076124                if (err == MP_OKAY)
    5608                     err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
     6125                    err = mp_copy(precomp[i]->y, C->y);
    56096126
    56106127                if (err == MP_OKAY)
    5611                     err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
     6128                    err = mp_copy(precomp[i]->z, C->z);
    56126129                else
    56136130                    break;
     
    56156132                /* if not first, add from table */
    56166133                if (err == MP_OKAY)
    5617                     err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
    5618                                                    a, modulus, mp);
     6134                    err = ecc_projective_add_point_safe(C, precomp[i],
     6135                                                        C, a, modulus, mp,
     6136                                                        &first);
    56196137                if (err != MP_OKAY)
    56206138                    break;
    5621                 if (mp_iszero(C->z)) {
    5622                     /* When all zero then should have done an add */
    5623                     if (mp_iszero(C->x) && mp_iszero(C->y)) {
    5624                         err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C,
    5625                                                        a, modulus, mp);
    5626                         if (err != MP_OKAY)
    5627                             break;
    5628                     }
    5629                     /* When only Z zero then result is infinity */
    5630                     else {
    5631                         err = mp_set(C->x, 0);
    5632                         if (err != MP_OKAY)
    5633                             break;
    5634                         err = mp_set(C->y, 0);
    5635                         if (err != MP_OKAY)
    5636                             break;
    5637                         err = mp_set(C->z, 1);
    5638                         if (err != MP_OKAY)
    5639                             break;
    5640                         first = 1;
    5641                     }
    5642                 }
    56436139            }
    56446140        }
     
    56776173
    56786174#endif /* ECC_SHAMIR */
    5679 #endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/
     6175#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
     6176        * !WOLFSSL_CRYPTOCEL */
    56806177
    56816178
     
    58216318#endif /* !NO_ASN */
    58226319
     6320static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
     6321{
     6322    int err;
     6323    DECLARE_CURVE_SPECS(curve, 1);
     6324
     6325    ALLOC_CURVE_SPECS(1);
     6326    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
     6327    if (err != 0) {
     6328        FREE_CURVE_SPECS();
     6329        return err;
     6330    }
     6331
     6332    if (mp_iszero(r) || mp_iszero(s)) {
     6333        err = MP_ZERO_E;
     6334    }
     6335    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
     6336        err = MP_VAL;
     6337    }
     6338    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
     6339        err = MP_VAL;
     6340    }
     6341
     6342    wc_ecc_curve_free(curve);
     6343    FREE_CURVE_SPECS();
     6344    return err;
     6345}
    58236346
    58246347/**
     
    58396362    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
    58406363}
     6364#elif defined(WOLFSSL_PSOC6_CRYPTO)
     6365{
     6366    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
     6367}
    58416368#else
    58426369{
    58436370   int           err;
    5844    word32        keySz;
    5845 #ifdef WOLFSSL_ATECC508A
     6371   word32        keySz = 0;
     6372#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    58466373   byte sigRS[ATECC_KEY_SIZE*2];
    58476374#elif defined(WOLFSSL_CRYPTOCELL)
     
    58506377   word32 msgLenInBytes = hashlen;
    58516378   CRYS_ECPKI_HASH_OpMode_t hash_mode;
     6379#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     6380   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
    58526381#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
    58536382   int          did_init = 0;
     
    58856414   }
    58866415
     6416   err = wc_ecc_check_r_s_range(key, r, s);
     6417   if (err != MP_OKAY) {
     6418      return err;
     6419   }
     6420
    58876421   keySz = key->dp->size;
    58886422
     
    59036437#endif
    59046438
    5905 #ifdef WOLFSSL_ATECC508A
     6439#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    59066440    /* Extract R and S */
    59076441    err = mp_to_unsigned_bin(r, &sigRS[0]);
     
    59326466   }
    59336467
     6468   /* truncate if hash is longer than key size */
     6469   if (msgLenInBytes > keySz) {
     6470       msgLenInBytes = keySz;
     6471   }
    59346472   hash_mode = cc310_hashModeECC(msgLenInBytes);
    59356473   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
    59366474       /* hash_mode = */ cc310_hashModeECC(keySz);
    59376475       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
    5938    }
    5939    /* truncate if hash is longer than key size */
    5940    if (msgLenInBytes > keySz) {
    5941        msgLenInBytes = keySz;
    59426476   }
    59436477
     
    59576491   /* valid signature if we get to this point */
    59586492   *res = 1;
     6493#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     6494   /* Extract R and S */
     6495
     6496   err = mp_to_unsigned_bin(r, &sigRS[0]);
     6497   if (err != MP_OKAY) {
     6498       return err;
     6499   }
     6500   err = mp_to_unsigned_bin(s, &sigRS[keySz]);
     6501   if (err != MP_OKAY) {
     6502       return err;
     6503   }
     6504
     6505   err = silabs_ecc_verify_hash(&sigRS[0], keySz*2,
     6506                                hash, hashlen,
     6507                                res, key);
     6508
    59596509#else
    59606510  /* checking if private key with no public part */
    59616511  if (key->type == ECC_PRIVATEKEY_ONLY) {
    59626512      WOLFSSL_MSG("Verify called with private key, generating public part");
    5963       err = wc_ecc_make_pub_ex(key, NULL, NULL);
     6513      err = ecc_make_pub_ex(key, NULL, NULL, NULL);
    59646514      if (err != MP_OKAY) {
    59656515           WOLFSSL_MSG("Unable to extract public key");
     
    59706520#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
    59716521  if (key->handle != -1) {
    5972       return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x, key->pubkey.y,
    5973                                           key->pubkey.z, r, s, res, key->heap);
     6522      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
     6523        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
    59746524  }
    59756525  if (wolfSSL_GetHandleCbSet() == 1) {
    5976       return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x, key->pubkey.y,
    5977                                           key->pubkey.z, r, s, res, key->heap);
     6526      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
     6527        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
    59786528  }
    59796529#endif
     6530
    59806531#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
    5981 #ifndef WOLFSSL_SP_NO_256
    5982   if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
    5983       return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
    5984                                            key->pubkey.z, r, s, res, key->heap);
    5985   }
    5986 #endif
    5987 #ifdef WOLFSSL_SP_384
    5988   if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
    5989       return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, key->pubkey.y,
    5990                                            key->pubkey.z, r, s, res, key->heap);
    5991   }
    5992 #endif
    5993   return WC_KEY_SIZE_E;
    5994 #else
    5995 #if defined WOLFSSL_HAVE_SP_ECC && !defined(FREESCALE_LTC_ECC)
     6532    if (key->idx == ECC_CUSTOM_IDX ||
     6533            (ecc_sets[key->idx].id != ECC_SECP256R1 &&
     6534             ecc_sets[key->idx].id != ECC_SECP384R1)) {
     6535        return WC_KEY_SIZE_E;
     6536    }
     6537#endif
     6538
     6539#if (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
     6540                                                    defined(WOLFSSL_HAVE_SP_ECC)
     6541    if (key->idx != ECC_CUSTOM_IDX
    59966542    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
    5997     if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
     6543        && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC
    59986544    #endif
    5999     {
    6000 #ifndef WOLFSSL_SP_NO_256
    6001         if (key->idx != ECC_CUSTOM_IDX &&
    6002                                        ecc_sets[key->idx].id == ECC_SECP256R1) {
    6003             return sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
    6004                                          key->pubkey.y, key->pubkey.z,r, s, res,
    6005                                          key->heap);
    6006         }
    6007 #endif /* WOLFSSL_SP_NO_256 */
    6008 #ifdef WOLFSSL_SP_384
    6009         if (key->idx != ECC_CUSTOM_IDX &&
    6010                                        ecc_sets[key->idx].id == ECC_SECP384R1) {
    6011             return sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
    6012                                          key->pubkey.y, key->pubkey.z,r, s, res,
    6013                                          key->heap);
    6014         }
    6015 #endif /* WOLFSSL_SP_384 */
    6016     }
    6017 #endif /* WOLFSSL_HAVE_SP_ECC */
    6018 
     6545    ) {
     6546    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
     6547        /* perform blocking call to non-blocking function */
     6548        ecc_nb_ctx_t nb_ctx;
     6549        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
     6550        err = NOT_COMPILED_IN; /* set default error */
     6551    #endif
     6552    #ifndef WOLFSSL_SP_NO_256
     6553        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
     6554        #ifdef WC_ECC_NONBLOCK
     6555            if (key->nb_ctx) {
     6556                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
     6557                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
     6558                    key->heap);
     6559            }
     6560            #ifdef WC_ECC_NONBLOCK_ONLY
     6561            do { /* perform blocking call to non-blocking function */
     6562                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
     6563                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
     6564                    key->heap);
     6565            } while (err == FP_WOULDBLOCK);
     6566            return err;
     6567            #endif
     6568        #endif /* WC_ECC_NONBLOCK */
     6569        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
     6570            return sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
     6571                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
     6572        #endif
     6573        }
     6574    #endif
     6575    #ifdef WOLFSSL_SP_384
     6576        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
     6577        #ifdef WC_ECC_NONBLOCK
     6578            if (key->nb_ctx) {
     6579                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
     6580                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
     6581                    key->heap);
     6582            }
     6583            #ifdef WC_ECC_NONBLOCK_ONLY
     6584            do { /* perform blocking call to non-blocking function */
     6585                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
     6586                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
     6587                    key->heap);
     6588            } while (err == FP_WOULDBLOCK);
     6589            return err;
     6590            #endif
     6591        #endif /* WC_ECC_NONBLOCK */
     6592        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
     6593            return sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
     6594                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
     6595        #endif
     6596        }
     6597    #endif
     6598    }
     6599#endif
     6600
     6601#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
    60196602   ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
    60206603
     
    60436626   /* read in the specs for this curve */
    60446627   err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
    6045 
    6046    /* check for zero */
    6047    if (err == MP_OKAY) {
    6048        if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
    6049            mp_cmp(r, curve->order) != MP_LT ||
    6050            mp_cmp(s, curve->order) != MP_LT) {
    6051            err = MP_ZERO_E;
    6052        }
    6053    }
    60546628
    60556629   /* read hash */
     
    61326706       if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
    61336707          err = MEMORY_E;
     6708       } else {
     6709           did_init = 1;
    61346710       }
    6135        did_init = 1;
    61366711   }
    61376712
     
    62006775            /* add them */
    62016776            if (err == MP_OKAY)
    6202                 err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
    6203                                                               curve->prime, mp);
    6204             if (err == MP_OKAY && mp_iszero(mG->z)) {
    6205                 /* When all zero then should have done an add */
    6206                 if (mp_iszero(mG->x) && mp_iszero(mG->y)) {
    6207                     err = ecc_projective_dbl_point(mQ, mG, curve->Af,
    6208                                                               curve->prime, mp);
    6209                 }
    6210                 /* When only Z zero then result is infinity */
    6211                 else {
    6212                     err = mp_set(mG->x, 0);
    6213                     if (err == MP_OKAY)
    6214                         err = mp_set(mG->y, 0);
    6215                     if (err == MP_OKAY)
    6216                         err = mp_set(mG->z, 1);
    6217                 }
    6218             }
     6777                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
     6778                                                        curve->prime, mp, NULL);
    62196779        }
    62206780        else {
     
    62736833   FREE_CURVE_SPECS();
    62746834
    6275 #endif /* WOLFSSL_SP_MATH */
     6835#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
    62766836#endif /* WOLFSSL_ATECC508A */
    62776837
     
    63576917#ifdef HAVE_COMP_KEY
    63586918    if (err == MP_OKAY && compressed == 1) {   /* build y */
    6359 #ifndef WOLFSSL_SP_MATH
    6360         int did_init = 0;
    6361         mp_int t1, t2;
    6362         DECLARE_CURVE_SPECS(curve, 3);
    6363 
    6364         ALLOC_CURVE_SPECS(3);
    6365 
    6366         if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
    6367             err = MEMORY_E;
    6368         else
    6369             did_init = 1;
    6370 
    6371         /* load curve info */
    6372         if (err == MP_OKAY)
    6373             err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
    6374                 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
    6375                     ECC_CURVE_FIELD_BF));
    6376 
    6377         /* compute x^3 */
    6378         if (err == MP_OKAY)
    6379             err = mp_sqr(point->x, &t1);
    6380         if (err == MP_OKAY)
    6381             err = mp_mulmod(&t1, point->x, curve->prime, &t1);
    6382 
    6383         /* compute x^3 + a*x */
    6384         if (err == MP_OKAY)
    6385             err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
    6386         if (err == MP_OKAY)
    6387             err = mp_add(&t1, &t2, &t1);
    6388 
    6389         /* compute x^3 + a*x + b */
    6390         if (err == MP_OKAY)
    6391             err = mp_add(&t1, curve->Bf, &t1);
    6392 
    6393         /* compute sqrt(x^3 + a*x + b) */
    6394         if (err == MP_OKAY)
    6395             err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
    6396 
    6397         /* adjust y */
    6398         if (err == MP_OKAY) {
    6399             if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
    6400                 (mp_isodd(&t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
    6401                 err = mp_mod(&t2, curve->prime, point->y);
    6402             }
    6403             else {
    6404                 err = mp_submod(curve->prime, &t2, curve->prime, point->y);
    6405             }
    6406         }
    6407 
    6408         if (did_init) {
    6409             mp_clear(&t2);
    6410             mp_clear(&t1);
    6411         }
    6412 
    6413         wc_ecc_curve_free(curve);
    6414         FREE_CURVE_SPECS();
    6415 #else
    6416     #ifndef WOLFSSL_SP_NO_256
     6919    #if defined(WOLFSSL_HAVE_SP_ECC)
     6920        #ifndef WOLFSSL_SP_NO_256
    64176921        if (curve_idx != ECC_CUSTOM_IDX &&
    64186922                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
     
    64206924        }
    64216925        else
    6422     #endif
    6423     #ifdef WOLFSSL_SP_384
     6926        #endif
     6927        #ifdef WOLFSSL_SP_384
    64246928        if (curve_idx != ECC_CUSTOM_IDX &&
    64256929                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
     
    64276931        }
    64286932        else
     6933        #endif
    64296934    #endif
     6935    #if !defined(WOLFSSL_SP_MATH)
     6936        {
     6937            int did_init = 0;
     6938            mp_int t1, t2;
     6939            DECLARE_CURVE_SPECS(curve, 3);
     6940
     6941            ALLOC_CURVE_SPECS(3);
     6942
     6943            if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
     6944                err = MEMORY_E;
     6945            else
     6946                did_init = 1;
     6947
     6948            /* load curve info */
     6949            if (err == MP_OKAY)
     6950                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
     6951                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
     6952                        ECC_CURVE_FIELD_BF));
     6953
     6954        #if defined(WOLFSSL_CUSTOM_CURVES) && \
     6955            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
     6956            /* validate prime is prime for custom curves */
     6957            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
     6958                int isPrime = MP_NO;
     6959                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
     6960                if (err == MP_OKAY && isPrime == MP_NO)
     6961                    err = MP_VAL;
     6962            }
     6963        #endif
     6964
     6965            /* compute x^3 */
     6966            if (err == MP_OKAY)
     6967                err = mp_sqr(point->x, &t1);
     6968            if (err == MP_OKAY)
     6969                err = mp_mulmod(&t1, point->x, curve->prime, &t1);
     6970
     6971            /* compute x^3 + a*x */
     6972            if (err == MP_OKAY)
     6973                err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
     6974            if (err == MP_OKAY)
     6975                err = mp_add(&t1, &t2, &t1);
     6976
     6977            /* compute x^3 + a*x + b */
     6978            if (err == MP_OKAY)
     6979                err = mp_add(&t1, curve->Bf, &t1);
     6980
     6981            /* compute sqrt(x^3 + a*x + b) */
     6982            if (err == MP_OKAY)
     6983                err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
     6984
     6985            /* adjust y */
     6986            if (err == MP_OKAY) {
     6987                if ((mp_isodd(&t2) == MP_YES &&
     6988                                            pointType == ECC_POINT_COMP_ODD) ||
     6989                    (mp_isodd(&t2) == MP_NO &&
     6990                                            pointType == ECC_POINT_COMP_EVEN)) {
     6991                    err = mp_mod(&t2, curve->prime, point->y);
     6992                }
     6993                else {
     6994                    err = mp_submod(curve->prime, &t2, curve->prime, point->y);
     6995                }
     6996            }
     6997
     6998            if (did_init) {
     6999                mp_clear(&t2);
     7000                mp_clear(&t1);
     7001            }
     7002
     7003            wc_ecc_curve_free(curve);
     7004            FREE_CURVE_SPECS();
     7005        }
     7006    #else
    64307007        {
    64317008            err = WC_KEY_SIZE_E;
    64327009        }
    6433 #endif
     7010    #endif
    64347011    }
    64357012#endif
     
    66337210       return ECC_PRIVATEONLY_E;
    66347211
    6635    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
    6636       return ECC_BAD_ARG_E;
    6637    }
     7212   if (key->type == 0 ||
     7213       wc_ecc_is_valid_idx(key->idx) == 0 ||
     7214       key->dp == NULL) {
     7215       return ECC_BAD_ARG_E;
     7216   }
     7217
    66387218   numlen = key->dp->size;
    66397219
     
    67037283
    67047284
    6705 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     7285#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     7286    !defined(WOLFSSL_CRYPTOCELL)
    67067287
    67077288/* is ecc point on curve described by dp ? */
    67087289int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
    67097290{
    6710 #ifndef WOLFSSL_SP_MATH
     7291#if !defined(WOLFSSL_SP_MATH)
    67117292   int err;
    67127293#ifdef WOLFSSL_SMALL_STACK
     
    67507331   /* compute y^2 - x^3 */
    67517332   if (err == MP_OKAY)
    6752        err = mp_sub(t1, t2, t1);
     7333       err = mp_submod(t1, t2, prime, t1);
    67537334
    67547335   /* Determine if curve "a" should be used in calc */
     
    67957376   if (err == MP_OKAY) {
    67967377       if (mp_cmp(t1, b) != MP_EQ) {
    6797           err = MP_VAL;
     7378          err = IS_POINT_E;
    67987379       } else {
    67997380          err = MP_OKAY;
     
    68137394   (void)b;
    68147395
     7396#ifdef WOLFSSL_HAVE_SP_ECC
    68157397#ifndef WOLFSSL_SP_NO_256
    68167398   if (mp_count_bits(prime) == 256) {
     
    68237405   }
    68247406#endif
     7407#else
     7408   (void)ecp;
     7409   (void)prime;
     7410#endif
    68257411   return WC_KEY_SIZE_E;
    68267412#endif
    68277413}
    68287414
    6829 #ifndef WOLFSSL_SP_MATH
     7415#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_VALIDATE_ECC_IMPORT)
    68307416/* validate privkey * generator == pubkey, 0 on success */
    68317417static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
     
    68347420    ecc_point* base = NULL;
    68357421    ecc_point* res  = NULL;
    6836     DECLARE_CURVE_SPECS(curve, 2);
     7422    DECLARE_CURVE_SPECS(curve, 3);
    68377423
    68387424    if (key == NULL)
    68397425        return BAD_FUNC_ARG;
    68407426
    6841     ALLOC_CURVE_SPECS(2);
     7427    ALLOC_CURVE_SPECS(3);
    68427428
    68437429    res = wc_ecc_new_point_h(key->heap);
     
    68707456        if (err == MP_OKAY) {
    68717457            /* load curve info */
    6872             err = wc_ecc_curve_load(key->dp, &curve,
    6873                                       (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
     7458            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
     7459                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
    68747460        }
    68757461
     
    68827468            err = mp_set(base->z, 1);
    68837469
     7470#ifdef ECC_TIMING_RESISTANT
    68847471        if (err == MP_OKAY)
    6885             err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);
     7472            err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
     7473                                                        key->rng, 1, key->heap);
     7474#else
     7475        if (err == MP_OKAY)
     7476            err = wc_ecc_mulmod_ex2(&key->k, base, res, a, prime, curve->order,
     7477                                                            NULL, 1, key->heap);
     7478#endif
    68867479    }
    68877480
     
    69037496    return err;
    69047497}
    6905 #endif
     7498#endif /* !WOLFSSL_SP_MATH || WOLFSSL_VALIDATE_ECC_IMPORT */
    69067499
    69077500#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
     
    69117504{
    69127505    int    err;
    6913 #ifndef WOLFSSL_ATECC508A
     7506#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A)
    69147507    DECLARE_CURVE_SPECS(curve, 2);
    69157508#endif
     
    69187511        return BAD_FUNC_ARG;
    69197512
    6920 #ifdef WOLFSSL_ATECC508A
     7513#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    69217514    /* Hardware based private key, so this operation is not supported */
    69227515    err = MP_OKAY; /* just report success */
    6923 
     7516#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     7517    /* Hardware based private key, so this operation is not supported */
     7518    err = MP_OKAY; /* just report success */
    69247519#else
    69257520    ALLOC_CURVE_SPECS(2);
     
    69737568#endif
    69747569#endif
    6975 #ifndef WOLFSSL_SP_MATH
     7570#if !defined(WOLFSSL_SP_MATH)
    69767571            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
    69777572        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
    69787573            err = ECC_INF_E;
    69797574#else
     7575        {
    69807576            (void)a;
    69817577            (void)prime;
    69827578
    69837579            err = WC_KEY_SIZE_E;
     7580        }
    69847581#endif
    69857582    }
     
    70227619int wc_ecc_check_key(ecc_key* key)
    70237620{
     7621#ifndef WOLFSSL_SP_MATH
    70247622    int    err;
    7025 #ifndef WOLFSSL_SP_MATH
    7026 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     7623#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     7624    !defined(WOLFSSL_CRYPTOCELL)
    70277625    mp_int* b = NULL;
    70287626#ifdef USE_ECC_B_PARAM
     
    70357633#endif /* USE_ECC_B_PARAM */
    70367634#endif /* WOLFSSL_ATECC508A */
     7635#endif /* !WOLFSSL_SP_MATH */
    70377636
    70387637    if (key == NULL)
    70397638        return BAD_FUNC_ARG;
    70407639
    7041 #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_CRYPTOCELL)
    7042 
    7043     err = 0; /* consider key check success on ATECC508A */
     7640#ifdef WOLFSSL_HAVE_SP_ECC
     7641#ifndef WOLFSSL_SP_NO_256
     7642    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
     7643        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
     7644            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
     7645    }
     7646#endif
     7647#ifdef WOLFSSL_SP_384
     7648    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
     7649        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
     7650            key->type == ECC_PRIVATEKEY ? &key->k : NULL, key->heap);
     7651    }
     7652#endif
     7653#endif
     7654
     7655#ifndef WOLFSSL_SP_MATH
     7656#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
     7657    defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL)
     7658
     7659    err = 0; /* consider key check success on ATECC508/608A */
    70447660
    70457661#else
     
    71137729                curve->order);
    71147730
     7731    /* SP 800-56Ar3, section 5.6.2.1.2 */
     7732    /* private keys must be in the range [1, n-1] */
     7733    if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
     7734                                    (mp_iszero(&key->k) || mp_isneg(&key->k) ||
     7735                                    (mp_cmp(&key->k, curve->order) != MP_LT))) {
     7736        err = ECC_PRIV_KEY_E;
     7737    }
     7738
    71157739    /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
    71167740    /* private * base generator must equal pubkey */
     
    71297753    FREE_CURVE_SPECS();
    71307754
     7755    return err;
    71317756#endif /* WOLFSSL_ATECC508A */
    71327757#else
    7133     if (key == NULL)
    7134         return BAD_FUNC_ARG;
    7135 
    7136     /* pubkey point cannot be at infinity */
    7137 #ifndef WOLFSSL_SP_NO_256
    7138     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
    7139         err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
    7140                                                                      key->heap);
    7141     }
    7142     else
    7143 #endif
    7144 #ifdef WOLFSSL_SP_384
    7145     if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
    7146         err = sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, &key->k,
    7147                                                                      key->heap);
    7148     }
    7149     else
    7150 #endif
    7151     {
    7152         err = WC_KEY_SIZE_E;
    7153     }
    7154 #endif
    7155 
    7156     return err;
     7758    return WC_KEY_SIZE_E;
     7759#endif /* !WOLFSSL_SP_MATH */
    71577760}
    71587761
     
    72157818    in += 1;
    72167819
    7217 #ifdef WOLFSSL_ATECC508A
     7820#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    72187821    /* For SECP256R1 only save raw public key for hardware */
    72197822    if (curve_id == ECC_SECP256R1 && inLen <= sizeof(key->pubkey_raw)) {
     
    72447847#ifdef HAVE_COMP_KEY
    72457848    if (err == MP_OKAY && compressed == 1) {   /* build y */
    7246 #ifndef WOLFSSL_SP_MATH
     7849#if !defined(WOLFSSL_SP_MATH)
    72477850        mp_int t1, t2;
    72487851        int did_init = 0;
     
    72617864                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
    72627865                 ECC_CURVE_FIELD_BF));
     7866
     7867    #if defined(WOLFSSL_CUSTOM_CURVES) && \
     7868        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
     7869        /* validate prime is prime for custom curves */
     7870        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
     7871            int isPrime = MP_NO;
     7872            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
     7873            if (err == MP_OKAY && isPrime == MP_NO)
     7874                err = MP_VAL;
     7875        }
     7876    #endif
    72637877
    72647878        /* compute x^3 */
     
    73347948        err = mp_set(key->pubkey.z, 1);
    73357949
     7950#ifdef WOLFSSL_SILABS_SE_ACCEL
     7951    err = silabs_ecc_import(key, keysize);
     7952#endif
     7953
    73367954#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
    73377955    if (err == MP_OKAY)
     
    73828000            return BAD_FUNC_ARG;
    73838001
    7384     #ifdef WOLFSSL_ATECC508A
     8002    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    73858003        /* Hardware cannot export private portion */
    73868004        return NOT_COMPILED_IN;
     
    74608078{
    74618079    int ret;
    7462 #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
     8080#ifdef WOLFSSL_CRYPTOCELL
    74638081    const CRYS_ECPKI_Domain_t* pDomain;
    74648082    CRYS_ECPKI_BUILD_TempData_t tempBuff;
     
    74768094        key->type = ECC_PRIVATEKEY;
    74778095    #else
     8096        (void)pubSz;
    74788097        ret = NOT_COMPILED_IN;
    74798098    #endif
     
    74918110        return ret;
    74928111
    7493 #ifdef WOLFSSL_ATECC508A
    7494     /* Hardware does not support loading private keys */
    7495     return NOT_COMPILED_IN;
    7496 #elif defined(WOLFSSL_CRYPTOCELL)
     8112#ifdef WOLFSSL_CRYPTOCELL
    74978113    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id));
    74988114
     
    75268142        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
    75278143    }
    7528 
     8144#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     8145    if (ret == MP_OKAY)
     8146        ret = mp_read_unsigned_bin(&key->k, priv, privSz);
     8147
     8148    if (ret == MP_OKAY) {
     8149        if (pub) {
     8150            ret = silabs_ecc_import(key, key->dp->size);
     8151        } else
     8152        {
     8153            ret = silabs_ecc_import_private(key, key->dp->size);
     8154        }
     8155    }
    75298156#else
    75308157
     
    75388165#endif /* HAVE_WOLF_BIGINT */
    75398166
    7540 
    7541 #endif /* WOLFSSL_ATECC508A */
     8167#endif /* WOLFSSL_CRYPTOCELL */
    75428168
    75438169#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
     
    76068232        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
    76078233
     8234    if (err == MP_OKAY) {
     8235        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
     8236            err = MP_ZERO_E;
     8237    }
     8238
    76088239    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
    76098240    if (err == MP_OKAY)
    76108241        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
    7611 
    7612     if (err == MP_OKAY) {
    7613         if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
    7614             err = MP_ZERO_E;
    7615     }
    76168242
    76178243    mp_clear(rtmp);
     
    76388264    byte* out, word32* outlen)
    76398265{
    7640     int err;
    7641 #ifdef WOLFSSL_SMALL_STACK
    7642     mp_int* rtmp = NULL;
    7643     mp_int* stmp = NULL;
    7644 #else
    7645     mp_int  rtmp[1];
    7646     mp_int  stmp[1];
    7647 #endif
    7648 
    76498266    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
    76508267        return ECC_BAD_ARG_E;
    76518268
    7652 #ifdef WOLFSSL_SMALL_STACK
    7653     rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
    7654     if (rtmp == NULL)
    7655         return MEMORY_E;
    7656     stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
    7657     if (stmp == NULL) {
    7658         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
    7659         return MEMORY_E;
    7660     }
    7661 #endif
    7662 
    7663     err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
    7664     if (err != MP_OKAY) {
    7665     #ifdef WOLFSSL_SMALL_STACK
    7666         XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
    7667         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
    7668     #endif
    7669         return err;
    7670     }
    7671 
    7672     err = mp_read_unsigned_bin(rtmp, r, rSz);
    7673     if (err == MP_OKAY)
    7674         err = mp_read_unsigned_bin(stmp, s, sSz);
    7675 
    76768269    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
    7677     if (err == MP_OKAY)
    7678         err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
    7679 
    7680     if (err == MP_OKAY) {
    7681         if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
    7682             err = MP_ZERO_E;
    7683     }
    7684 
    7685     mp_clear(rtmp);
    7686     mp_clear(stmp);
    7687 #ifdef WOLFSSL_SMALL_STACK
    7688     XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
    7689     XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
    7690 #endif
    7691 
    7692     return err;
     8270    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
    76938271}
    76948272
     
    77068284                     byte* s, word32* sLen)
    77078285{
    7708     int err;
    7709     int tmp_valid = 0;
    7710     word32 x = 0;
    7711 #ifdef WOLFSSL_SMALL_STACK
    7712     mp_int* rtmp = NULL;
    7713     mp_int* stmp = NULL;
    7714 #else
    7715     mp_int  rtmp[1];
    7716     mp_int  stmp[1];
    7717 #endif
    7718 
    77198286    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
    77208287        return ECC_BAD_ARG_E;
    77218288
    7722 #ifdef WOLFSSL_SMALL_STACK
    7723     rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
    7724     if (rtmp == NULL)
    7725         return MEMORY_E;
    7726     stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
    7727     if (stmp == NULL) {
    7728         XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
    7729         return MEMORY_E;
    7730     }
    7731 #endif
    7732 
    7733     err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);
    7734 
    7735     /* rtmp and stmp are initialized */
    7736     if (err == MP_OKAY) {
    7737         tmp_valid = 1;
    7738 
    7739         /* extract r */
    7740         x = mp_unsigned_bin_size(rtmp);
    7741         if (*rLen < x)
    7742             err = BUFFER_E;
    7743     }
    7744     if (err == MP_OKAY) {
    7745         *rLen = x;
    7746         err = mp_to_unsigned_bin(rtmp, r);
    7747     }
    7748 
    7749     /* extract s */
    7750     if (err == MP_OKAY) {
    7751         x = mp_unsigned_bin_size(stmp);
    7752         if (*sLen < x)
    7753             err = BUFFER_E;
    7754 
    7755         if (err == MP_OKAY) {
    7756             *sLen = x;
    7757             err = mp_to_unsigned_bin(stmp, s);
    7758         }
    7759     }
    7760 
    7761     if (tmp_valid) {
    7762         mp_clear(rtmp);
    7763         mp_clear(stmp);
    7764     }
    7765 #ifdef WOLFSSL_SMALL_STACK
    7766     XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
    7767     XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
    7768 #endif
    7769 
    7770     return err;
     8289    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
    77718290}
    77728291#endif /* !NO_ASN */
     
    77778296{
    77788297    int err = MP_OKAY;
    7779 #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A)
     8298#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
     8299    !defined(WOLFSSL_ATECC608A)
    77808300    const CRYS_ECPKI_Domain_t* pDomain;
    77818301    CRYS_ECPKI_BUILD_TempData_t tempBuff;
    77828302    byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
     8303#endif
     8304
     8305#if (defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) &&      \
     8306     !defined(WOLFSSL_ATECC608A))  ||                                   \
     8307  defined(WOLFSSL_SILABS_SE_ACCEL)
    77838308    word32 keySz = 0;
    77848309#endif
     8310
    77858311    /* if d is NULL, only import as public key using Qx,Qy */
    77868312    if (key == NULL || qx == NULL || qy == NULL) {
     
    78208346            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
    78218347                key->dp->size);
     8348
     8349        if (mp_iszero(key->pubkey.x)) {
     8350            WOLFSSL_MSG("Invalid Qx");
     8351            err = BAD_FUNC_ARG;
     8352        }
    78228353    }
    78238354
     
    78308361                key->dp->size);
    78318362
     8363        if (mp_iszero(key->pubkey.y)) {
     8364            WOLFSSL_MSG("Invalid Qy");
     8365            err = BAD_FUNC_ARG;
     8366        }
    78328367    }
    78338368
     
    78358370        err = mp_set(key->pubkey.z, 1);
    78368371
    7837 #ifdef WOLFSSL_ATECC508A
     8372#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    78388373    /* For SECP256R1 only save raw public key for hardware */
    78398374    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
    7840         word32 keySz = key->dp->size;
     8375        keySz = key->dp->size;
    78418376        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
    78428377            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
     
    78448379            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
    78458380                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
     8381    }
     8382#elif defined(WOLFSSL_SILABS_SE_ACCEL)
     8383    keySz = key->dp->size;
     8384    if (err == MP_OKAY) {
     8385        err = silabs_ecc_sig_to_rs(key, keySz);
    78468386    }
    78478387#elif defined(WOLFSSL_CRYPTOCELL)
     
    78778417    /* import private key */
    78788418    if (err == MP_OKAY) {
    7879         if (d != NULL && d[0] != '\0') {
    7880         #ifdef WOLFSSL_ATECC508A
     8419        if (d != NULL) {
     8420        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
    78818421            /* Hardware doesn't support loading private key */
    78828422            err = NOT_COMPILED_IN;
    78838423
     8424        #elif defined(WOLFSSL_SILABS_SE_ACCEL)
     8425            err = silabs_ecc_import_private_raw(key, keySz, d, encType);
     8426
    78848427        #elif defined(WOLFSSL_CRYPTOCELL)
    7885 
    78868428            key->type = ECC_PRIVATEKEY;
    78878429
     
    79188460                    key->dp->size);
    79198461        #endif /* WOLFSSL_ATECC508A */
     8462            if (mp_iszero(&key->k)) {
     8463                WOLFSSL_MSG("Invalid private key");
     8464                return BAD_FUNC_ARG;
     8465            }
    79208466        } else {
    79218467            key->type = ECC_PUBLICKEY;
     
    80878633
    80888634
    8089 #ifndef WOLFSSL_SP_MATH
     8635#if !defined(WOLFSSL_SP_MATH)
    80908636
    80918637/** Our FP cache */
     
    80938639   ecc_point* g;               /* cached COPY of base point */
    80948640   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
     8641   int        LUT_set;         /* flag to determine if the LUT has been computed */
    80958642   mp_int     mu;              /* copy of the montgomery constant */
    80968643   int        lru_count;       /* amount of times this entry has been used */
     
    86669213         fp_cache[z].LUT[x] = NULL;
    86679214      }
     9215      fp_cache[z].LUT_set = 0;
    86689216      fp_cache[z].lru_count = 0;
    86699217   }
     
    87239271   }
    87249272
     9273   fp_cache[idx].LUT_set   = 0;
    87259274   fp_cache[idx].lru_count = 0;
    87269275
     
    87299278#endif
    87309279
    8731 #ifndef WOLFSSL_SP_MATH
     9280#if !defined(WOLFSSL_SP_MATH)
    87329281/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
    87339282 *
     
    87419290   unsigned x, y, bitlen, lut_gap;
    87429291   mp_int tmp;
     9292   int infinity;
    87439293
    87449294   if (mp_init(&tmp) != MP_OKAY)
     
    87919341         /* now double it bitlen/FP_LUT times */
    87929342         for (y = 0; y < lut_gap; y++) {
    8793              if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
     9343             if ((err = ecc_projective_dbl_point_safe(fp_cache[idx].LUT[1<<x],
    87949344                            fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
    87959345                 break;
     
    88079357
    88089358           /* perform the add */
    8809            if ((err = ecc_projective_add_point(
     9359           if ((err = ecc_projective_add_point_safe(
    88109360                           fp_cache[idx].LUT[lut_orders[y].terma],
    88119361                           fp_cache[idx].LUT[lut_orders[y].termb],
    8812                            fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {
     9362                           fp_cache[idx].LUT[y], a, modulus, mp,
     9363                           &infinity)) != MP_OKAY) {
    88139364              break;
    88149365           }
     
    88549405   mp_clear(&tmp);
    88559406
    8856    if (err == MP_OKAY)
    8857      return MP_OKAY;
     9407   if (err == MP_OKAY) {
     9408       fp_cache[idx].LUT_set = 1;
     9409       return MP_OKAY;
     9410   }
    88589411
    88599412   /* err cleanup */
     
    88649417   wc_ecc_del_point(fp_cache[idx].g);
    88659418   fp_cache[idx].g         = NULL;
     9419   fp_cache[idx].LUT_set   = 0;
    88669420   fp_cache[idx].lru_count = 0;
    88679421   mp_clear(&fp_cache[idx].mu);
     
    88789432#ifdef WOLFSSL_SMALL_STACK
    88799433   unsigned char* kb = NULL;
     9434   mp_int*        tk = NULL;
     9435   mp_int*        order = NULL;
    88809436#else
    88819437   unsigned char kb[KB_SIZE];
     9438   mp_int        tk[1];
     9439   mp_int        order[1];
    88829440#endif
    88839441   int      x, err;
    8884    unsigned y, z = 0, bitlen, bitpos, lut_gap, first;
    8885    mp_int   tk, order;
    8886 
    8887    if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)
    8888        return MP_INIT_E;
     9442   unsigned y, z = 0, bitlen, bitpos, lut_gap;
     9443   int first;
     9444
     9445#ifdef WOLFSSL_SMALL_STACK
     9446   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     9447   if (tk == NULL) {
     9448      err = MEMORY_E; goto done;
     9449   }
     9450   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     9451   if (order == NULL) {
     9452      err = MEMORY_E; goto done;
     9453   }
     9454#endif
     9455
     9456   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
     9457       err = MP_INIT_E; goto done;
     9458   }
    88899459
    88909460   /* if it's smaller than modulus we fine */
     
    88999469      if (y == 66) --x;
    89009470
    8901       if ((err = mp_read_radix(&order, ecc_sets[x].order,
     9471      if ((err = mp_read_radix(order, ecc_sets[x].order,
    89029472                                                MP_RADIX_HEX)) != MP_OKAY) {
    89039473         goto done;
     
    89059475
    89069476      /* k must be less than modulus */
    8907       if (mp_cmp(k, &order) != MP_LT) {
    8908          if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
     9477      if (mp_cmp(k, order) != MP_LT) {
     9478         if ((err = mp_mod(k, order, tk)) != MP_OKAY) {
    89099479            goto done;
    89109480         }
    89119481      } else {
    8912          if ((err = mp_copy(k, &tk)) != MP_OKAY) {
     9482         if ((err = mp_copy(k, tk)) != MP_OKAY) {
    89139483            goto done;
    89149484         }
    89159485      }
    89169486   } else {
    8917       if ((err = mp_copy(k, &tk)) != MP_OKAY) {
     9487      if ((err = mp_copy(k, tk)) != MP_OKAY) {
    89189488         goto done;
    89199489      }
     
    89299499
    89309500   /* get the k value */
    8931    if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
     9501   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
    89329502      err = BUFFER_E; goto done;
    89339503   }
     
    89429512
    89439513   XMEMSET(kb, 0, KB_SIZE);
    8944    if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
     9514   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
    89459515      /* let's reverse kb so it's little endian */
    89469516      x = 0;
    8947       y = mp_unsigned_bin_size(&tk);
     9517      y = mp_unsigned_bin_size(tk);
    89489518      if (y > 0) {
    89499519          y -= 1;
     
    89699539          /* double if not first */
    89709540          if (!first) {
    8971              if ((err = ecc_projective_dbl_point(R, R, a, modulus,
     9541             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
    89729542                                                              mp)) != MP_OKAY) {
    89739543                break;
     
    89779547          /* add if not first, otherwise copy */
    89789548          if (!first && z) {
    8979              if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a,
    8980                                                      modulus, mp)) != MP_OKAY) {
     9549             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
     9550                                       R, a, modulus, mp, &first)) != MP_OKAY) {
    89819551                break;
    8982              }
    8983              if (mp_iszero(R->z)) {
    8984                  /* When all zero then should have done an add */
    8985                  if (mp_iszero(R->x) && mp_iszero(R->y)) {
    8986                      if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z],
    8987                                                R, a, modulus, mp)) != MP_OKAY) {
    8988                          break;
    8989                      }
    8990                  }
    8991                  /* When only Z zero then result is infinity */
    8992                  else {
    8993                     err = mp_set(R->x, 0);
    8994                     if (err != MP_OKAY) {
    8995                        break;
    8996                     }
    8997                     err = mp_set(R->y, 0);
    8998                     if (err != MP_OKAY) {
    8999                        break;
    9000                     }
    9001                     err = mp_copy(&fp_cache[idx].mu, R->z);
    9002                     if (err != MP_OKAY) {
    9003                        break;
    9004                     }
    9005                     first = 1;
    9006                  }
    90079552             }
    90089553          } else if (z) {
     
    90329577done:
    90339578   /* cleanup */
    9034    mp_clear(&order);
    9035    mp_clear(&tk);
     9579   mp_clear(order);
     9580   mp_clear(tk);
    90369581
    90379582#ifdef WOLFSSL_SMALL_STACK
    90389583   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9584   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9585   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
    90399586#endif
    90409587
     
    90469593
    90479594#ifdef ECC_SHAMIR
    9048 #ifndef WOLFSSL_SP_MATH
     9595#if !defined(WOLFSSL_SP_MATH)
    90499596/* perform a fixed point ECC mulmod */
    90509597static int accel_fp_mul2add(int idx1, int idx2,
     
    90579604#ifdef WOLFSSL_SMALL_STACK
    90589605   unsigned char* kb[2] = {NULL, NULL};
     9606   mp_int*        tka = NULL;
     9607   mp_int*        tkb = NULL;
     9608   mp_int*        order = NULL;
    90599609#else
    90609610   unsigned char kb[2][KB_SIZE];
     9611   mp_int        tka[1];
     9612   mp_int        tkb[1];
     9613   mp_int        order[1];
    90619614#endif
    90629615   int      x, err;
    9063    unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;
    9064    mp_int tka, tkb, order;
    9065 
    9066    if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)
    9067        return MP_INIT_E;
     9616   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
     9617   int first;
     9618
     9619#ifdef WOLFSSL_SMALL_STACK
     9620   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     9621   if (tka == NULL) {
     9622      err = MEMORY_E; goto done;
     9623   }
     9624   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     9625   if (tkb == NULL) {
     9626      err = MEMORY_E; goto done;
     9627   }
     9628   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
     9629   if (order == NULL) {
     9630      err = MEMORY_E; goto done;
     9631   }
     9632#endif
     9633
     9634   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
     9635      err = MP_INIT_E; goto done;
     9636   }
    90689637
    90699638   /* if it's smaller than modulus we fine */
     
    90789647      if (y == 66) --x;
    90799648
    9080       if ((err = mp_read_radix(&order, ecc_sets[x].order,
     9649      if ((err = mp_read_radix(order, ecc_sets[x].order,
    90819650                                                MP_RADIX_HEX)) != MP_OKAY) {
    90829651         goto done;
     
    90849653
    90859654      /* kA must be less than modulus */
    9086       if (mp_cmp(kA, &order) != MP_LT) {
    9087          if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
     9655      if (mp_cmp(kA, order) != MP_LT) {
     9656         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
    90889657            goto done;
    90899658         }
    90909659      } else {
    9091          if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
     9660         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
    90929661            goto done;
    90939662         }
    90949663      }
    90959664   } else {
    9096       if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
     9665      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
    90979666         goto done;
    90989667      }
     
    91109679      if (y == 66) --x;
    91119680
    9112       if ((err = mp_read_radix(&order, ecc_sets[x].order,
     9681      if ((err = mp_read_radix(order, ecc_sets[x].order,
    91139682                                                MP_RADIX_HEX)) != MP_OKAY) {
    91149683         goto done;
     
    91169685
    91179686      /* kB must be less than modulus */
    9118       if (mp_cmp(kB, &order) != MP_LT) {
    9119          if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
     9687      if (mp_cmp(kB, order) != MP_LT) {
     9688         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
    91209689            goto done;
    91219690         }
    91229691      } else {
    9123          if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
     9692         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
    91249693            goto done;
    91259694         }
    91269695      }
    91279696   } else {
    9128       if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
     9697      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
    91299698         goto done;
    91309699      }
     
    91409709
    91419710   /* get the k value */
    9142    if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
    9143        (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2))  ) {
     9711   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
     9712       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
    91449713      err = BUFFER_E; goto done;
    91459714   }
     
    91549723
    91559724   XMEMSET(kb[0], 0, KB_SIZE);
    9156    if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
     9725   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
    91579726      goto done;
    91589727   }
     
    91609729   /* let's reverse kb so it's little endian */
    91619730   x = 0;
    9162    y = mp_unsigned_bin_size(&tka);
     9731   y = mp_unsigned_bin_size(tka);
    91639732   if (y > 0) {
    91649733       y -= 1;
    91659734   }
    9166    mp_clear(&tka);
     9735   mp_clear(tka);
    91679736   while ((unsigned)x < y) {
    91689737      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
     
    91799748
    91809749   XMEMSET(kb[1], 0, KB_SIZE);
    9181    if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
     9750   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
    91829751      x = 0;
    9183       y = mp_unsigned_bin_size(&tkb);
     9752      y = mp_unsigned_bin_size(tkb);
    91849753      if (y > 0) {
    91859754          y -= 1;
     
    92069775          /* double if not first */
    92079776          if (!first) {
    9208              if ((err = ecc_projective_dbl_point(R, R, a, modulus,
     9777             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
    92099778                                                              mp)) != MP_OKAY) {
    92109779                break;
     
    92139782             /* add if not first, otherwise copy */
    92149783             if (zA) {
    9215                 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
    9216                                                R, a, modulus, mp)) != MP_OKAY) {
     9784                if ((err = ecc_projective_add_point_safe(R,
     9785                                             fp_cache[idx1].LUT[zA], R, a,
     9786                                             modulus, mp, &first)) != MP_OKAY) {
    92179787                   break;
    92189788                }
    9219                 if (mp_iszero(R->z)) {
    9220                     /* When all zero then should have done an add */
    9221                     if (mp_iszero(R->x) && mp_iszero(R->y)) {
    9222                         if ((err = ecc_projective_dbl_point(
    9223                                                   fp_cache[idx1].LUT[zA], R,
    9224                                                   a, modulus, mp)) != MP_OKAY) {
    9225                             break;
    9226                         }
    9227                     }
    9228                     /* When only Z zero then result is infinity */
    9229                     else {
    9230                        err = mp_set(R->x, 0);
    9231                        if (err != MP_OKAY) {
    9232                           break;
    9233                        }
    9234                        err = mp_set(R->y, 0);
    9235                        if (err != MP_OKAY) {
    9236                           break;
    9237                        }
    9238                        err = mp_copy(&fp_cache[idx1].mu, R->z);
    9239                        if (err != MP_OKAY) {
    9240                           break;
    9241                        }
    9242                        first = 1;
    9243                     }
    9244                 }
    92459789             }
    92469790
    92479791             if (zB) {
    9248                 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
    9249                                                R, a, modulus, mp)) != MP_OKAY) {
     9792                if ((err = ecc_projective_add_point_safe(R,
     9793                                             fp_cache[idx2].LUT[zB], R, a,
     9794                                             modulus, mp, &first)) != MP_OKAY) {
    92509795                   break;
    9251                 }
    9252                 if (mp_iszero(R->z)) {
    9253                     /* When all zero then should have done an add */
    9254                     if (mp_iszero(R->x) && mp_iszero(R->y)) {
    9255                         if ((err = ecc_projective_dbl_point(
    9256                                                   fp_cache[idx2].LUT[zB], R,
    9257                                                   a, modulus, mp)) != MP_OKAY) {
    9258                             break;
    9259                         }
    9260                     }
    9261                     /* When only Z zero then result is infinity */
    9262                     else {
    9263                        err = mp_set(R->x, 0);
    9264                        if (err != MP_OKAY) {
    9265                           break;
    9266                        }
    9267                        err = mp_set(R->y, 0);
    9268                        if (err != MP_OKAY) {
    9269                           break;
    9270                        }
    9271                        err = mp_copy(&fp_cache[idx2].mu, R->z);
    9272                        if (err != MP_OKAY) {
    9273                           break;
    9274                        }
    9275                        first = 1;
    9276                     }
    92779796                }
    92789797             }
     
    92899808             if (zB && first == 0) {
    92909809                if (zB) {
    9291                    if ((err = ecc_projective_add_point(R,
    9292                         fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
     9810                   if ((err = ecc_projective_add_point_safe(R,
     9811                                              fp_cache[idx2].LUT[zB], R, a,
     9812                                              modulus, mp, &first)) != MP_OKAY){
    92939813                      break;
    9294                    }
    9295                    if (mp_iszero(R->z)) {
    9296                        /* When all zero then should have done an add */
    9297                        if (mp_iszero(R->x) && mp_iszero(R->y)) {
    9298                            if ((err = ecc_projective_dbl_point(
    9299                                                   fp_cache[idx2].LUT[zB], R,
    9300                                                   a, modulus, mp)) != MP_OKAY) {
    9301                                break;
    9302                            }
    9303                        }
    9304                        /* When only Z zero then result is infinity */
    9305                        else {
    9306                           err = mp_set(R->x, 0);
    9307                           if (err != MP_OKAY) {
    9308                              break;
    9309                           }
    9310                           err = mp_set(R->y, 0);
    9311                           if (err != MP_OKAY) {
    9312                              break;
    9313                           }
    9314                           err = mp_copy(&fp_cache[idx2].mu, R->z);
    9315                           if (err != MP_OKAY) {
    9316                              break;
    9317                           }
    9318                           first = 1;
    9319                        }
    93209814                   }
    93219815                }
     
    93359829done:
    93369830   /* cleanup */
    9337    mp_clear(&tkb);
    9338    mp_clear(&tka);
    9339    mp_clear(&order);
     9831   mp_clear(tkb);
     9832   mp_clear(tka);
     9833   mp_clear(order);
    93409834
    93419835#ifdef WOLFSSL_SMALL_STACK
     
    93499843
    93509844#ifdef WOLFSSL_SMALL_STACK
     9845   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
    93519846   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
    9352    XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9847   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9848   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9849   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
    93539850#endif
    93549851
     
    93799876   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
    93809877   mp_digit mp;
    9381    mp_int   mu;
    9382 
    9383    err = mp_init(&mu);
    9384    if (err != MP_OKAY)
     9878#ifdef WOLFSSL_SMALL_STACK
     9879   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9880
     9881   if (mu == NULL)
     9882       return MP_MEM;
     9883#else
     9884   mp_int   mu[1];
     9885#endif
     9886
     9887   err = mp_init(mu);
     9888   if (err != MP_OKAY) {
     9889#ifdef WOLFSSL_SMALL_STACK
     9890       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9891#endif
    93859892       return err;
     9893   }
    93869894
    93879895#ifndef HAVE_THREAD_LS
    9388    if (initMutex == 0) {
     9896   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
    93899897        wc_InitMutex(&ecc_fp_lock);
    93909898        initMutex = 1;
    93919899   }
    9392    if (wc_LockMutex(&ecc_fp_lock) != 0)
     9900
     9901   if (wc_LockMutex(&ecc_fp_lock) != 0) {
     9902#ifdef WOLFSSL_SMALL_STACK
     9903       XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9904#endif
    93939905      return BAD_MUTEX_E;
     9906   }
    93949907#endif /* HAVE_THREAD_LS */
    93959908
     
    94279940
    94289941      if (err == MP_OKAY) {
    9429         /* if it's 2 build the LUT, if it's higher just use the LUT */
    9430         if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
     9942        /* if it's >= 2 AND the LUT is not set build the LUT */
     9943        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
    94319944           /* compute mp */
    94329945           err = mp_montgomery_setup(modulus, &mp);
     
    94349947           if (err == MP_OKAY) {
    94359948             mpInit = 1;
    9436              err = mp_montgomery_calc_normalization(&mu, modulus);
     9949             err = mp_montgomery_calc_normalization(mu, modulus);
    94379950           }
    94389951
    94399952           if (err == MP_OKAY)
    94409953             /* build the LUT */
    9441                err = build_lut(idx1, a, modulus, mp, &mu);
     9954             err = build_lut(idx1, a, modulus, mp, mu);
    94429955        }
    94439956      }
    94449957
    94459958      if (err == MP_OKAY) {
    9446         /* if it's 2 build the LUT, if it's higher just use the LUT */
    9447         if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
     9959        /* if it's >= 2 AND the LUT is not set build the LUT */
     9960        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
    94489961           if (mpInit == 0) {
    94499962                /* compute mp */
     
    94519964                if (err == MP_OKAY) {
    94529965                    mpInit = 1;
    9453                     err = mp_montgomery_calc_normalization(&mu, modulus);
     9966                    err = mp_montgomery_calc_normalization(mu, modulus);
    94549967                }
    94559968            }
    94569969
    94579970            if (err == MP_OKAY)
    9458             /* build the LUT */
    9459               err = build_lut(idx2, a, modulus, mp, &mu);
     9971              /* build the LUT */
     9972              err = build_lut(idx2, a, modulus, mp, mu);
    94609973        }
    94619974      }
     
    94639976
    94649977      if (err == MP_OKAY) {
    9465         if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
    9466                                      fp_cache[idx2].lru_count >= 2) {
     9978        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
     9979                                     fp_cache[idx2].LUT_set) {
    94679980           if (mpInit == 0) {
    94689981              /* compute mp */
     
    94799992    wc_UnLockMutex(&ecc_fp_lock);
    94809993#endif /* HAVE_THREAD_LS */
    9481     mp_clear(&mu);
     9994    mp_clear(mu);
     9995#ifdef WOLFSSL_SMALL_STACK
     9996    XFREE(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     9997#endif
    94829998
    94839999    return err;
     
    949910015    mp_int* modulus, int map, void* heap)
    950010016{
    9501 #ifndef WOLFSSL_SP_MATH
     10017#if !defined(WOLFSSL_SP_MATH)
    950210018   int   idx, err = MP_OKAY;
    950310019   mp_digit mp;
     
    951310029
    951410030#ifndef HAVE_THREAD_LS
    9515    if (initMutex == 0) {
     10031   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
    951610032        wc_InitMutex(&ecc_fp_lock);
    951710033        initMutex = 1;
     
    954110057      if (err == MP_OKAY) {
    954210058        /* if it's 2 build the LUT, if it's higher just use the LUT */
    9543         if (idx >= 0 && fp_cache[idx].lru_count == 2) {
     10059        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
    954410060           /* compute mp */
    954510061           err = mp_montgomery_setup(modulus, &mp);
     
    955810074
    955910075      if (err == MP_OKAY) {
    9560         if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
     10076        if (idx >= 0 && fp_cache[idx].LUT_set) {
    956110077           if (mpSetup == 0) {
    956210078              /* compute mp */
     
    956610082             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
    956710083        } else {
    9568            err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);
     10084           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
    956910085        }
    957010086     }
     
    959510111}
    959610112
    9597 #ifndef WOLFSSL_SP_MATH
     10113/** ECC Fixed Point mulmod global
     10114    k        The multiplicand
     10115    G        Base point to multiply
     10116    R        [out] Destination of product
     10117    a        ECC curve parameter a
     10118    modulus  The modulus for the curve
     10119    map      [boolean] If non-zero maps the point back to affine coordinates,
     10120             otherwise it's left in jacobian-montgomery form
     10121    return MP_OKAY if successful
     10122*/
     10123int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
     10124    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
     10125{
     10126#if !defined(WOLFSSL_SP_MATH)
     10127   int   idx, err = MP_OKAY;
     10128   mp_digit mp;
     10129   mp_int   mu;
     10130   int      mpSetup = 0;
     10131
     10132   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
     10133                                                                order == NULL) {
     10134       return ECC_BAD_ARG_E;
     10135   }
     10136
     10137   if (mp_init(&mu) != MP_OKAY)
     10138       return MP_INIT_E;
     10139
     10140   /* k can't have more bits than order */
     10141   if (mp_count_bits(k) > mp_count_bits(order)) {
     10142      return ECC_OUT_OF_RANGE_E;
     10143   }
     10144
     10145#ifndef HAVE_THREAD_LS
     10146   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
     10147        wc_InitMutex(&ecc_fp_lock);
     10148        initMutex = 1;
     10149   }
     10150
     10151   if (wc_LockMutex(&ecc_fp_lock) != 0)
     10152      return BAD_MUTEX_E;
     10153#endif /* HAVE_THREAD_LS */
     10154
     10155      /* find point */
     10156      idx = find_base(G);
     10157
     10158      /* no entry? */
     10159      if (idx == -1) {
     10160         /* find hole and add it */
     10161         idx = find_hole();
     10162
     10163         if (idx >= 0)
     10164            err = add_entry(idx, G);
     10165      }
     10166      if (err == MP_OKAY && idx >= 0) {
     10167         /* increment LRU */
     10168         ++(fp_cache[idx].lru_count);
     10169      }
     10170
     10171
     10172      if (err == MP_OKAY) {
     10173        /* if it's 2 build the LUT, if it's higher just use the LUT */
     10174        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
     10175           /* compute mp */
     10176           err = mp_montgomery_setup(modulus, &mp);
     10177
     10178           if (err == MP_OKAY) {
     10179             /* compute mu */
     10180             mpSetup = 1;
     10181             err = mp_montgomery_calc_normalization(&mu, modulus);
     10182           }
     10183
     10184           if (err == MP_OKAY)
     10185             /* build the LUT */
     10186             err = build_lut(idx, a, modulus, mp, &mu);
     10187        }
     10188      }
     10189
     10190      if (err == MP_OKAY) {
     10191        if (idx >= 0 && fp_cache[idx].LUT_set) {
     10192           if (mpSetup == 0) {
     10193              /* compute mp */
     10194              err = mp_montgomery_setup(modulus, &mp);
     10195           }
     10196           if (err == MP_OKAY)
     10197             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
     10198        } else {
     10199          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
     10200        }
     10201     }
     10202
     10203#ifndef HAVE_THREAD_LS
     10204    wc_UnLockMutex(&ecc_fp_lock);
     10205#endif /* HAVE_THREAD_LS */
     10206    mp_clear(&mu);
     10207
     10208    return err;
     10209#else
     10210    (void)rng;
     10211
     10212   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
     10213                                                                order == NULL) {
     10214        return ECC_BAD_ARG_E;
     10215    }
     10216
     10217#ifndef WOLFSSL_SP_NO_256
     10218    if (mp_count_bits(modulus) == 256) {
     10219        return sp_ecc_mulmod_256(k, G, R, map, heap);
     10220    }
     10221#endif
     10222#ifdef WOLFSSL_SP_384
     10223    if (mp_count_bits(modulus) == 384) {
     10224        return sp_ecc_mulmod_384(k, G, R, map, heap);
     10225    }
     10226#endif
     10227    return WC_KEY_SIZE_E;
     10228#endif
     10229}
     10230
     10231#if !defined(WOLFSSL_SP_MATH)
    959810232/* helper function for freeing the cache ...
    959910233   must be called with the cache mutex locked */
     
    961010244         fp_cache[x].g         = NULL;
    961110245         mp_clear(&fp_cache[x].mu);
     10246         fp_cache[x].LUT_set   = 0;
    961210247         fp_cache[x].lru_count = 0;
    961310248         fp_cache[x].lock = 0;
     
    961710252#endif
    961810253
    9619 /** Free the Fixed Point cache */
    9620 void wc_ecc_fp_free(void)
     10254
     10255/** Init the Fixed Point cache */
     10256void wc_ecc_fp_init(void)
    962110257{
    962210258#ifndef WOLFSSL_SP_MATH
     
    962610262        initMutex = 1;
    962710263   }
     10264#endif
     10265#endif
     10266}
     10267
     10268
     10269/** Free the Fixed Point cache */
     10270void wc_ecc_fp_free(void)
     10271{
     10272#if !defined(WOLFSSL_SP_MATH)
     10273#ifndef HAVE_THREAD_LS
     10274   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
     10275        wc_InitMutex(&ecc_fp_lock);
     10276        initMutex = 1;
     10277   }
    962810278
    962910279   if (wc_LockMutex(&ecc_fp_lock) == 0) {
     
    964310293
    964410294#endif /* FP_ECC */
     10295
     10296#ifdef ECC_TIMING_RESISTANT
     10297int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
     10298{
     10299    int err = 0;
     10300
     10301    if (key == NULL) {
     10302        err = BAD_FUNC_ARG;
     10303    }
     10304    else {
     10305        key->rng = rng;
     10306    }
     10307
     10308    return err;
     10309}
     10310#endif
    964510311
    964610312#ifdef HAVE_ECC_ENCRYPT
     
    968210348    byte      cliSt;       /* protocol state, for sanity checks */
    968310349    byte      srvSt;       /* protocol state, for sanity checks */
     10350    WC_RNG*   rng;
    968410351};
    968510352
     
    977910446
    978010447
    9781 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
     10448static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
    978210449{
    978310450    byte* saltBuffer = NULL;
    978410451
    9785     if (ctx == NULL || rng == NULL || flags == 0)
     10452    if (ctx == NULL || flags == 0)
    978610453        return BAD_FUNC_ARG;
    978710454
    978810455    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
    978910456
    9790     return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
    9791 }
    9792 
    9793 
    9794 static void ecc_ctx_init(ecEncCtx* ctx, int flags)
     10457    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
     10458}
     10459
     10460
     10461static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
    979510462{
    979610463    if (ctx) {
     
    980110468        ctx->macAlgo  = ecHMAC_SHA256;
    980210469        ctx->protocol = (byte)flags;
     10470        ctx->rng      = rng;
    980310471
    980410472        if (flags == REQ_RESP_CLIENT)
     
    981610484        return BAD_FUNC_ARG;
    981710485
    9818     ecc_ctx_init(ctx, ctx->protocol);
    9819     return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
     10486    ecc_ctx_init(ctx, ctx->protocol, rng);
     10487    return ecc_ctx_set_salt(ctx, ctx->protocol);
    982010488}
    982110489
     
    992110589
    992210590    if (ctx == NULL) {  /* use defaults */
    9923         ecc_ctx_init(&localCtx, 0);
     10591        ecc_ctx_init(&localCtx, 0, NULL);
    992410592        ctx = &localCtx;
    992510593    }
     
    995410622    if (*outSz < (msgSz + digestSz))
    995510623        return BUFFER_E;
     10624
     10625#ifdef ECC_TIMING_RESISTANT
     10626    if (ctx->rng != NULL && privKey->rng == NULL)
     10627        privKey->rng = ctx->rng;
     10628#endif
    995610629
    995710630#ifdef WOLFSSL_SMALL_STACK
     
    999710670           case ecAES_128_CBC:
    999810671               {
    9999                    Aes aes;
    10000                    ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
     10672#ifdef WOLFSSL_SMALL_STACK
     10673                   Aes *aes = (Aes *)XMALLOC(sizeof *aes, NULL,
     10674                                             DYNAMIC_TYPE_AES);
     10675                   if (aes == NULL) {
     10676                       ret = MEMORY_E;
     10677                       break;
     10678                   }
     10679#else
     10680                   Aes aes[1];
     10681#endif
     10682                   ret = wc_AesInit(aes, NULL, INVALID_DEVID);
    1000110683                   if (ret == 0) {
    10002                        ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
     10684                       ret = wc_AesSetKey(aes, encKey, KEY_SIZE_128, encIv,
    1000310685                                                                AES_ENCRYPTION);
    1000410686                       if (ret == 0) {
    10005                            ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
     10687                           ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
    1000610688                       #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
    10007                            ret = wc_AsyncWait(ret, &aes.asyncDev,
     10689                           ret = wc_AsyncWait(ret, &aes->asyncDev,
    1000810690                                              WC_ASYNC_FLAG_NONE);
    1000910691                       #endif
    1001010692                       }
    10011                        wc_AesFree(&aes);
     10693                       wc_AesFree(aes);
    1001210694                   }
     10695#ifdef WOLFSSL_SMALL_STACK
     10696                   XFREE(aes, NULL, DYNAMIC_TYPE_AES);
     10697#endif
    1001310698                   if (ret != 0)
    1001410699                      break;
     
    1002610711           case ecHMAC_SHA256:
    1002710712               {
    10028                    Hmac hmac;
    10029                    ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
     10713#ifdef WOLFSSL_SMALL_STACK
     10714                   Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, NULL,
     10715                                                DYNAMIC_TYPE_HMAC);
     10716                   if (hmac == NULL) {
     10717                       ret = MEMORY_E;
     10718                       break;
     10719                   }
     10720#else
     10721                   Hmac hmac[1];
     10722#endif
     10723                   ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
    1003010724                   if (ret == 0) {
    10031                        ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
     10725                       ret = wc_HmacSetKey(hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
    1003210726                       if (ret == 0)
    10033                            ret = wc_HmacUpdate(&hmac, out, msgSz);
     10727                           ret = wc_HmacUpdate(hmac, out, msgSz);
    1003410728                       if (ret == 0)
    10035                            ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
     10729                           ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
    1003610730                       if (ret == 0)
    10037                            ret = wc_HmacFinal(&hmac, out+msgSz);
    10038                        wc_HmacFree(&hmac);
     10731                           ret = wc_HmacFinal(hmac, out+msgSz);
     10732                       wc_HmacFree(hmac);
    1003910733                   }
     10734#ifdef WOLFSSL_SMALL_STACK
     10735                   XFREE(hmac, NULL, DYNAMIC_TYPE_HMAC);
     10736#endif
    1004010737               }
    1004110738               break;
     
    1009010787
    1009110788    if (ctx == NULL) {  /* use defaults */
    10092         ecc_ctx_init(&localCtx, 0);
     10789        ecc_ctx_init(&localCtx, 0, NULL);
    1009310790        ctx = &localCtx;
    1009410791    }
     
    1012310820    if (*outSz < (msgSz - digestSz))
    1012410821        return BUFFER_E;
     10822
     10823#ifdef ECC_TIMING_RESISTANT
     10824    if (ctx->rng != NULL && privKey->rng == NULL)
     10825        privKey->rng = ctx->rng;
     10826#endif
    1012510827
    1012610828#ifdef WOLFSSL_SMALL_STACK
     
    1016710869           {
    1016810870               byte verify[WC_SHA256_DIGEST_SIZE];
    10169                Hmac hmac;
    10170 
    10171                ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
     10871#ifdef WOLFSSL_SMALL_STACK
     10872               Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, NULL, DYNAMIC_TYPE_HMAC);
     10873               if (hmac == NULL) {
     10874                   ret = MEMORY_E;
     10875                   break;
     10876               }
     10877#else
     10878               Hmac hmac[1];
     10879#endif
     10880               ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
    1017210881               if (ret == 0) {
    10173                    ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
     10882                   ret = wc_HmacSetKey(hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
    1017410883                   if (ret == 0)
    10175                        ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
     10884                       ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
    1017610885                   if (ret == 0)
    10177                        ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
     10886                       ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
    1017810887                   if (ret == 0)
    10179                        ret = wc_HmacFinal(&hmac, verify);
     10888                       ret = wc_HmacFinal(hmac, verify);
    1018010889                   if (ret == 0) {
    1018110890                      if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
     
    1018310892                   }
    1018410893
    10185                    wc_HmacFree(&hmac);
     10894                   wc_HmacFree(hmac);
    1018610895               }
     10896#ifdef WOLFSSL_SMALL_STACK
     10897               XFREE(hmac, NULL, DYNAMIC_TYPE_HMAC);
     10898#endif
    1018710899               break;
    1018810900           }
     
    1019910911           case ecAES_128_CBC:
    1020010912               {
    10201                    Aes aes;
    10202                    ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
     10913#ifdef WOLFSSL_SMALL_STACK
     10914                   Aes *aes = (Aes *)XMALLOC(sizeof *aes, NULL,
     10915                                             DYNAMIC_TYPE_AES);
     10916                   if (aes == NULL) {
     10917                       ret = MEMORY_E;
     10918                       break;
     10919                   }
     10920#else
     10921                   Aes aes[1];
     10922#endif
     10923                   ret = wc_AesInit(aes, NULL, INVALID_DEVID);
     10924                   if (ret == 0) {
     10925                       ret = wc_AesSetKey(aes, encKey, KEY_SIZE_128, encIv,
    1020310926                                                                AES_DECRYPTION);
     10927                       if (ret == 0) {
     10928                           ret = wc_AesCbcDecrypt(aes, out, msg,
     10929                                                                msgSz-digestSz);
     10930                       #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
     10931                           ret = wc_AsyncWait(ret, &aes->asyncDev,
     10932                                                            WC_ASYNC_FLAG_NONE);
     10933                       #endif
     10934                       }
     10935                       wc_AesFree(aes);
     10936                   }
     10937#ifdef WOLFSSL_SMALL_STACK
     10938                   XFREE(aes, NULL, DYNAMIC_TYPE_AES);
     10939#endif
    1020410940                   if (ret != 0)
    10205                        break;
    10206                    ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
    10207                 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
    10208                    ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
    10209                 #endif
     10941                      break;
    1021010942               }
    1021110943               break;
     
    1023310965
    1023410966#ifdef HAVE_COMP_KEY
    10235 #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
     10967#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
     10968    !defined(WOLFSSL_CRYPTOCELL)
    1023610969
    1023710970#ifndef WOLFSSL_SP_MATH
    10238 int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
    10239 
    10240 int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
    10241 {
    10242   int      k, s, res;
    10243   int      r = 0; /* initialize to help static analysis out */
    10244   mp_digit residue;
    10245 
    10246   /* if a < 0 return MP_VAL */
    10247   if (mp_isneg(a) == MP_YES) {
    10248      return MP_VAL;
    10249   }
    10250 
    10251   /* if n <= 0 return MP_VAL */
    10252   if (mp_cmp_d(n, 0) != MP_GT) {
    10253      return MP_VAL;
    10254   }
    10255 
    10256   /* step 1. handle case of a == 0 */
    10257   if (mp_iszero (a) == MP_YES) {
    10258      /* special case of a == 0 and n == 1 */
    10259      if (mp_cmp_d (n, 1) == MP_EQ) {
    10260        *c = 1;
    10261      } else {
    10262        *c = 0;
    10263      }
    10264      return MP_OKAY;
    10265   }
    10266 
    10267   /* step 2.  if a == 1, return 1 */
    10268   if (mp_cmp_d (a, 1) == MP_EQ) {
    10269     *c = 1;
    10270     return MP_OKAY;
    10271   }
    10272 
    10273   /* default */
    10274   s = 0;
    10275 
    10276   /* divide out larger power of two */
    10277   k = mp_cnt_lsb(a);
    10278   res = mp_div_2d(a, k, a, NULL);
    10279 
    10280   if (res == MP_OKAY) {
    10281     /* step 4.  if e is even set s=1 */
    10282     if ((k & 1) == 0) {
    10283       s = 1;
    10284     } else {
    10285       /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
    10286       residue = n->dp[0] & 7;
    10287 
    10288       if (residue == 1 || residue == 7) {
    10289         s = 1;
    10290       } else if (residue == 3 || residue == 5) {
    10291         s = -1;
    10292       }
    10293     }
    10294 
    10295     /* step 5.  if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */
    10296     if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {
    10297       s = -s;
    10298     }
    10299   }
    10300 
    10301   if (res == MP_OKAY) {
    10302     /* if a == 1 we're done */
    10303     if (mp_cmp_d(a, 1) == MP_EQ) {
    10304       *c = s;
    10305     } else {
    10306       /* n1 = n mod a */
    10307       res = mp_mod (n, a, n);
    10308       if (res == MP_OKAY)
    10309         res = do_mp_jacobi(n, a, &r);
    10310 
    10311       if (res == MP_OKAY)
    10312         *c = s * r;
    10313     }
    10314   }
    10315 
    10316   return res;
    10317 }
    10318 
    10319 
    1032010971/* computes the jacobi c = (a | n) (or Legendre if n is prime)
    10321  * HAC pp. 73 Algorithm 2.149
    10322  * HAC is wrong here, as the special case of (0 | 1) is not
    10323  * handled correctly.
    1032410972 */
    1032510973int mp_jacobi(mp_int* a, mp_int* n, int* c)
     
    1032710975    mp_int   a1, n1;
    1032810976    int      res;
    10329 
    10330     /* step 3.  write a = a1 * 2**k  */
     10977    int      s = 1;
     10978    int      k;
     10979    mp_int*  t[2];
     10980    mp_int*  ts;
     10981    mp_digit residue;
     10982
     10983    if (mp_isneg(a) == MP_YES) {
     10984        return MP_VAL;
     10985    }
     10986    if (mp_isneg(n) == MP_YES) {
     10987        return MP_VAL;
     10988    }
     10989    if (mp_iseven(n) == MP_YES) {
     10990        return MP_VAL;
     10991    }
     10992
    1033110993    if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
    1033210994        return res;
    1033310995    }
    1033410996
    10335     if ((res = mp_copy(a, &a1)) != MP_OKAY) {
     10997    if ((res = mp_mod(a, n, &a1)) != MP_OKAY) {
    1033610998        goto done;
    1033710999    }
     
    1034111003    }
    1034211004
    10343     res = do_mp_jacobi(&a1, &n1, c);
     11005    t[0] = &a1;
     11006    t[1] = &n1;
     11007
     11008    /* Keep reducing until first number is 0. */
     11009    while (!mp_iszero(t[0])) {
     11010        /* Divide by 2 until odd. */
     11011        k = mp_cnt_lsb(t[0]);
     11012        if (k > 0) {
     11013            mp_rshb(t[0], k);
     11014
     11015            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
     11016             * Odd number of divides results in a negate.
     11017             */
     11018            residue = t[1]->dp[0] & 7;
     11019            if ((k & 1) && ((residue == 3) || (residue == 5))) {
     11020                s = -s;
     11021            }
     11022        }
     11023
     11024        /* Swap t[0] and t[1]. */
     11025        ts   = t[0];
     11026        t[0] = t[1];
     11027        t[1] = ts;
     11028
     11029        /* Negate s if both numbers == 3 mod 4. */
     11030        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
     11031             s = -s;
     11032        }
     11033
     11034        /* Reduce first number modulo second. */
     11035        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
     11036            res = mp_sub(t[0], t[1], t[0]);
     11037        }
     11038        else {
     11039            res = mp_mod(t[0], t[1], t[0]);
     11040        }
     11041        if (res != MP_OKAY) {
     11042            goto done;
     11043        }
     11044    }
     11045
     11046    /* When the two numbers have divisors in common. */
     11047    if (!mp_isone(t[1])) {
     11048        s = 0;
     11049    }
     11050    *c = s;
    1034411051
    1034511052done:
     
    1037711084#else
    1037811085  int res, legendre, done = 0;
    10379   mp_int t1, C, Q, S, Z, M, T, R, two;
    1038011086  mp_digit i;
     11087#ifdef WOLFSSL_SMALL_STACK
     11088  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11089  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11090  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11091  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11092  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11093  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11094  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11095  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11096  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11097#else
     11098  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], two[1];
     11099#endif
     11100
     11101  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
     11102      (mp_init_multi(T, R, two, NULL, NULL, NULL) != MP_OKAY)) {
     11103    res = MP_INIT_E;
     11104    goto out;
     11105  }
     11106
     11107#ifdef WOLFSSL_SMALL_STACK
     11108  if ((t1 == NULL) ||
     11109      (C == NULL) ||
     11110      (Q == NULL) ||
     11111      (S == NULL) ||
     11112      (Z == NULL) ||
     11113      (M == NULL) ||
     11114      (T == NULL) ||
     11115      (R == NULL) ||
     11116      (two == NULL)) {
     11117    res = MP_MEM;
     11118    goto out;
     11119  }
     11120#endif
    1038111121
    1038211122  /* first handle the simple cases n = 0 or n = 1 */
    1038311123  if (mp_cmp_d(n, 0) == MP_EQ) {
    1038411124    mp_zero(ret);
    10385     return MP_OKAY;
     11125    res = MP_OKAY;
     11126    goto out;
    1038611127  }
    1038711128  if (mp_cmp_d(n, 1) == MP_EQ) {
    10388     return mp_set(ret, 1);
     11129    res = mp_set(ret, 1);
     11130    goto out;
    1038911131  }
    1039011132
    1039111133  /* prime must be odd */
    1039211134  if (mp_cmp_d(prime, 2) == MP_EQ) {
    10393     return MP_VAL;
     11135    res = MP_VAL;
     11136    goto out;
    1039411137  }
    1039511138
    1039611139  /* is quadratic non-residue mod prime */
    1039711140  if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
    10398     return res;
     11141    goto out;
    1039911142  }
    1040011143  if (legendre == -1) {
    10401     return MP_VAL;
    10402   }
    10403 
    10404   if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
    10405     return res;
    10406 
    10407   if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
    10408                           != MP_OKAY) {
    10409     mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
    10410     mp_clear(&M);
    10411     return res;
     11144    res = MP_VAL;
     11145    goto out;
    1041211146  }
    1041311147
     
    1041811152  res = mp_mod_d(prime, 4, &i);
    1041911153  if (res == MP_OKAY && i == 3) {
    10420     res = mp_add_d(prime, 1, &t1);
     11154    res = mp_add_d(prime, 1, t1);
    1042111155
    1042211156    if (res == MP_OKAY)
    10423       res = mp_div_2(&t1, &t1);
     11157      res = mp_div_2(t1, t1);
    1042411158    if (res == MP_OKAY)
    10425       res = mp_div_2(&t1, &t1);
     11159      res = mp_div_2(t1, t1);
    1042611160    if (res == MP_OKAY)
    10427       res = mp_exptmod(n, &t1, prime, ret);
     11161      res = mp_exptmod(n, t1, prime, ret);
    1042811162
    1042911163    done = 1;
     
    1043611170    *                                      as: prime-1 = Q*2^S */
    1043711171    /* Q = prime - 1 */
    10438     res = mp_copy(prime, &Q);
     11172    res = mp_copy(prime, Q);
    1043911173    if (res == MP_OKAY)
    10440       res = mp_sub_d(&Q, 1, &Q);
     11174      res = mp_sub_d(Q, 1, Q);
    1044111175
    1044211176    /* S = 0 */
    1044311177    if (res == MP_OKAY)
    10444       mp_zero(&S);
    10445 
    10446     while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
     11178      mp_zero(S);
     11179
     11180    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
    1044711181      /* Q = Q / 2 */
    10448       res = mp_div_2(&Q, &Q);
     11182      res = mp_div_2(Q, Q);
    1044911183
    1045011184      /* S = S + 1 */
    1045111185      if (res == MP_OKAY)
    10452         res = mp_add_d(&S, 1, &S);
     11186        res = mp_add_d(S, 1, S);
    1045311187    }
    1045411188
     
    1045611190    /* Z = 2 */
    1045711191    if (res == MP_OKAY)
    10458       res = mp_set_int(&Z, 2);
     11192      res = mp_set_int(Z, 2);
    1045911193
    1046011194    while (res == MP_OKAY) {
    10461       res = mp_jacobi(&Z, prime, &legendre);
     11195      res = mp_jacobi(Z, prime, &legendre);
    1046211196      if (res == MP_OKAY && legendre == -1)
    1046311197        break;
     
    1046511199      /* Z = Z + 1 */
    1046611200      if (res == MP_OKAY)
    10467         res = mp_add_d(&Z, 1, &Z);
     11201        res = mp_add_d(Z, 1, Z);
    1046811202    }
    1046911203
    1047011204    /* C = Z ^ Q mod prime */
    1047111205    if (res == MP_OKAY)
    10472       res = mp_exptmod(&Z, &Q, prime, &C);
     11206      res = mp_exptmod(Z, Q, prime, C);
    1047311207
    1047411208    /* t1 = (Q + 1) / 2 */
    1047511209    if (res == MP_OKAY)
    10476       res = mp_add_d(&Q, 1, &t1);
     11210      res = mp_add_d(Q, 1, t1);
    1047711211    if (res == MP_OKAY)
    10478       res = mp_div_2(&t1, &t1);
     11212      res = mp_div_2(t1, t1);
    1047911213
    1048011214    /* R = n ^ ((Q + 1) / 2) mod prime */
    1048111215    if (res == MP_OKAY)
    10482       res = mp_exptmod(n, &t1, prime, &R);
     11216      res = mp_exptmod(n, t1, prime, R);
    1048311217
    1048411218    /* T = n ^ Q mod prime */
    1048511219    if (res == MP_OKAY)
    10486       res = mp_exptmod(n, &Q, prime, &T);
     11220      res = mp_exptmod(n, Q, prime, T);
    1048711221
    1048811222    /* M = S */
    1048911223    if (res == MP_OKAY)
    10490       res = mp_copy(&S, &M);
     11224      res = mp_copy(S, M);
    1049111225
    1049211226    if (res == MP_OKAY)
    10493       res = mp_set_int(&two, 2);
     11227      res = mp_set_int(two, 2);
    1049411228
    1049511229    while (res == MP_OKAY && done == 0) {
    10496       res = mp_copy(&T, &t1);
     11230      res = mp_copy(T, t1);
    1049711231
    1049811232      /* reduce to 1 and count */
    1049911233      i = 0;
    1050011234      while (res == MP_OKAY) {
    10501         if (mp_cmp_d(&t1, 1) == MP_EQ)
     11235        if (mp_cmp_d(t1, 1) == MP_EQ)
    1050211236            break;
    10503         res = mp_exptmod(&t1, &two, prime, &t1);
     11237        res = mp_exptmod(t1, two, prime, t1);
    1050411238        if (res == MP_OKAY)
    1050511239          i++;
    1050611240      }
    1050711241      if (res == MP_OKAY && i == 0) {
    10508         res = mp_copy(&R, ret);
     11242        res = mp_copy(R, ret);
    1050911243        done = 1;
    1051011244      }
     
    1051311247        /* t1 = 2 ^ (M - i - 1) */
    1051411248        if (res == MP_OKAY)
    10515           res = mp_sub_d(&M, i, &t1);
     11249          res = mp_sub_d(M, i, t1);
    1051611250        if (res == MP_OKAY)
    10517           res = mp_sub_d(&t1, 1, &t1);
     11251          res = mp_sub_d(t1, 1, t1);
    1051811252        if (res == MP_OKAY)
    10519           res = mp_exptmod(&two, &t1, prime, &t1);
     11253          res = mp_exptmod(two, t1, prime, t1);
    1052011254
    1052111255        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
    1052211256        if (res == MP_OKAY)
    10523           res = mp_exptmod(&C, &t1, prime, &t1);
     11257          res = mp_exptmod(C, t1, prime, t1);
    1052411258
    1052511259        /* C = (t1 * t1) mod prime */
    1052611260        if (res == MP_OKAY)
    10527           res = mp_sqrmod(&t1, prime, &C);
     11261          res = mp_sqrmod(t1, prime, C);
    1052811262
    1052911263        /* R = (R * t1) mod prime */
    1053011264        if (res == MP_OKAY)
    10531           res = mp_mulmod(&R, &t1, prime, &R);
     11265          res = mp_mulmod(R, t1, prime, R);
    1053211266
    1053311267        /* T = (T * C) mod prime */
    1053411268        if (res == MP_OKAY)
    10535           res = mp_mulmod(&T, &C, prime, &T);
     11269          res = mp_mulmod(T, C, prime, T);
    1053611270
    1053711271        /* M = i */
    1053811272        if (res == MP_OKAY)
    10539           res = mp_set(&M, i);
     11273          res = mp_set(M, i);
    1054011274      }
    1054111275    }
    1054211276  }
    1054311277
    10544   /* done */
    10545   mp_clear(&t1);
    10546   mp_clear(&C);
    10547   mp_clear(&Q);
    10548   mp_clear(&S);
    10549   mp_clear(&Z);
    10550   mp_clear(&M);
    10551   mp_clear(&T);
    10552   mp_clear(&R);
    10553   mp_clear(&two);
     11278  out:
     11279
     11280#ifdef WOLFSSL_SMALL_STACK
     11281  if (t1) {
     11282    if (res != MP_INIT_E)
     11283      mp_clear(t1);
     11284    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11285  }
     11286  if (C) {
     11287    if (res != MP_INIT_E)
     11288      mp_clear(C);
     11289    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11290  }
     11291  if (Q) {
     11292    if (res != MP_INIT_E)
     11293      mp_clear(Q);
     11294    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11295  }
     11296  if (S) {
     11297    if (res != MP_INIT_E)
     11298      mp_clear(S);
     11299    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11300  }
     11301  if (Z) {
     11302    if (res != MP_INIT_E)
     11303      mp_clear(Z);
     11304    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11305  }
     11306  if (M) {
     11307    if (res != MP_INIT_E)
     11308      mp_clear(M);
     11309    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11310  }
     11311  if (T) {
     11312    if (res != MP_INIT_E)
     11313      mp_clear(T);
     11314    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11315  }
     11316  if (R) {
     11317    if (res != MP_INIT_E)
     11318      mp_clear(R);
     11319    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11320  }
     11321  if (two) {
     11322    if (res != MP_INIT_E)
     11323      mp_clear(two);
     11324    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
     11325  }
     11326#else
     11327  if (res != MP_INIT_E) {
     11328    mp_clear(t1);
     11329    mp_clear(C);
     11330    mp_clear(Q);
     11331    mp_clear(S);
     11332    mp_clear(Z);
     11333    mp_clear(M);
     11334    mp_clear(T);
     11335    mp_clear(R);
     11336    mp_clear(two);
     11337  }
     11338#endif
    1055411339
    1055511340  return res;
     
    1056911354       return BAD_FUNC_ARG;
    1057011355
    10571    if (wc_ecc_is_valid_idx(key->idx) == 0) {
    10572       return ECC_BAD_ARG_E;
    10573    }
     11356   if (key->type == ECC_PRIVATEKEY_ONLY)
     11357       return ECC_PRIVATEONLY_E;
     11358
     11359   if (key->type == 0 ||
     11360       wc_ecc_is_valid_idx(key->idx) == 0 ||
     11361       key->dp == NULL) {
     11362       return ECC_BAD_ARG_E;
     11363   }
     11364
    1057411365   numlen = key->dp->size;
    1057511366
     
    1075911550#endif /* HAVE_X963_KDF */
    1076011551
     11552#ifdef WC_ECC_NONBLOCK
     11553/* Enable ECC support for non-blocking operations */
     11554int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
     11555{
     11556    if (key) {
     11557        if (ctx) {
     11558            XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
     11559        }
     11560        key->nb_ctx = ctx;
     11561    }
     11562    return 0;
     11563}
     11564#endif /* WC_ECC_NONBLOCK */
     11565
    1076111566#endif /* HAVE_ECC */
Note: See TracChangeset for help on using the changeset viewer.