wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
wolfcrypt/src/ecc.c@17:a5f916481144, 2020-06-05 (annotated)
- Committer:
- wolfSSL
- Date:
- Fri Jun 05 00:11:07 2020 +0000
- Revision:
- 17:a5f916481144
- Parent:
- 16:8e0d178b1d1e
wolfSSL 4.4.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 15:117db924cf7c | 1 | /* ecc.c |
wolfSSL | 15:117db924cf7c | 2 | * |
wolfSSL | 16:8e0d178b1d1e | 3 | * Copyright (C) 2006-2020 wolfSSL Inc. |
wolfSSL | 15:117db924cf7c | 4 | * |
wolfSSL | 15:117db924cf7c | 5 | * This file is part of wolfSSL. |
wolfSSL | 15:117db924cf7c | 6 | * |
wolfSSL | 15:117db924cf7c | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 15:117db924cf7c | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 15:117db924cf7c | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 15:117db924cf7c | 10 | * (at your option) any later version. |
wolfSSL | 15:117db924cf7c | 11 | * |
wolfSSL | 15:117db924cf7c | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 15:117db924cf7c | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 15:117db924cf7c | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 15:117db924cf7c | 15 | * GNU General Public License for more details. |
wolfSSL | 15:117db924cf7c | 16 | * |
wolfSSL | 15:117db924cf7c | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 15:117db924cf7c | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 15:117db924cf7c | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 15:117db924cf7c | 20 | */ |
wolfSSL | 15:117db924cf7c | 21 | |
wolfSSL | 15:117db924cf7c | 22 | |
wolfSSL | 15:117db924cf7c | 23 | |
wolfSSL | 15:117db924cf7c | 24 | #ifdef HAVE_CONFIG_H |
wolfSSL | 15:117db924cf7c | 25 | #include <config.h> |
wolfSSL | 15:117db924cf7c | 26 | #endif |
wolfSSL | 15:117db924cf7c | 27 | |
wolfSSL | 15:117db924cf7c | 28 | /* in case user set HAVE_ECC there */ |
wolfSSL | 15:117db924cf7c | 29 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 15:117db924cf7c | 30 | |
wolfSSL | 16:8e0d178b1d1e | 31 | /* public ASN interface */ |
wolfSSL | 16:8e0d178b1d1e | 32 | #include <wolfssl/wolfcrypt/asn_public.h> |
wolfSSL | 16:8e0d178b1d1e | 33 | |
wolfSSL | 15:117db924cf7c | 34 | /* |
wolfSSL | 15:117db924cf7c | 35 | Possible ECC enable options: |
wolfSSL | 15:117db924cf7c | 36 | * HAVE_ECC: Overall control of ECC default: on |
wolfSSL | 15:117db924cf7c | 37 | * HAVE_ECC_ENCRYPT: ECC encrypt/decrypt w/AES and HKDF default: off |
wolfSSL | 15:117db924cf7c | 38 | * HAVE_ECC_SIGN: ECC sign default: on |
wolfSSL | 15:117db924cf7c | 39 | * HAVE_ECC_VERIFY: ECC verify default: on |
wolfSSL | 15:117db924cf7c | 40 | * HAVE_ECC_DHE: ECC build shared secret default: on |
wolfSSL | 15:117db924cf7c | 41 | * HAVE_ECC_CDH: ECC cofactor DH shared secret default: off |
wolfSSL | 15:117db924cf7c | 42 | * HAVE_ECC_KEY_IMPORT: ECC Key import default: on |
wolfSSL | 15:117db924cf7c | 43 | * HAVE_ECC_KEY_EXPORT: ECC Key export default: on |
wolfSSL | 15:117db924cf7c | 44 | * ECC_SHAMIR: Enables Shamir calc method default: on |
wolfSSL | 15:117db924cf7c | 45 | * HAVE_COMP_KEY: Enables compressed key default: off |
wolfSSL | 15:117db924cf7c | 46 | * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off |
wolfSSL | 15:117db924cf7c | 47 | * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen default: off |
wolfSSL | 15:117db924cf7c | 48 | * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off |
wolfSSL | 15:117db924cf7c | 49 | * Includes the curve "a" variable in calculation |
wolfSSL | 15:117db924cf7c | 50 | * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off |
wolfSSL | 15:117db924cf7c | 51 | * ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance |
wolfSSL | 15:117db924cf7c | 52 | default: off |
wolfSSL | 15:117db924cf7c | 53 | * FP_ECC: ECC Fixed Point Cache default: off |
wolfSSL | 15:117db924cf7c | 54 | * USE_ECC_B_PARAM: Enable ECC curve B param default: off |
wolfSSL | 15:117db924cf7c | 55 | (on for HAVE_COMP_KEY) |
wolfSSL | 16:8e0d178b1d1e | 56 | * WOLFSSL_ECC_CURVE_STATIC: default off (on for windows) |
wolfSSL | 16:8e0d178b1d1e | 57 | For the ECC curve paramaters `ecc_set_type` use fixed |
wolfSSL | 16:8e0d178b1d1e | 58 | array for hex string |
wolfSSL | 15:117db924cf7c | 59 | */ |
wolfSSL | 15:117db924cf7c | 60 | |
wolfSSL | 15:117db924cf7c | 61 | /* |
wolfSSL | 15:117db924cf7c | 62 | ECC Curve Types: |
wolfSSL | 15:117db924cf7c | 63 | * NO_ECC_SECP Disables SECP curves default: off (not defined) |
wolfSSL | 15:117db924cf7c | 64 | * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off |
wolfSSL | 15:117db924cf7c | 65 | * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off |
wolfSSL | 15:117db924cf7c | 66 | * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off |
wolfSSL | 15:117db924cf7c | 67 | * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off |
wolfSSL | 15:117db924cf7c | 68 | */ |
wolfSSL | 15:117db924cf7c | 69 | |
wolfSSL | 15:117db924cf7c | 70 | /* |
wolfSSL | 15:117db924cf7c | 71 | ECC Curve Sizes: |
wolfSSL | 15:117db924cf7c | 72 | * ECC_USER_CURVES: Allows custom combination of key sizes below |
wolfSSL | 15:117db924cf7c | 73 | * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined) |
wolfSSL | 15:117db924cf7c | 74 | * HAVE_ECC112: 112 bit key |
wolfSSL | 15:117db924cf7c | 75 | * HAVE_ECC128: 128 bit key |
wolfSSL | 15:117db924cf7c | 76 | * HAVE_ECC160: 160 bit key |
wolfSSL | 15:117db924cf7c | 77 | * HAVE_ECC192: 192 bit key |
wolfSSL | 15:117db924cf7c | 78 | * HAVE_ECC224: 224 bit key |
wolfSSL | 15:117db924cf7c | 79 | * HAVE_ECC239: 239 bit key |
wolfSSL | 15:117db924cf7c | 80 | * NO_ECC256: Disables 256 bit key (on by default) |
wolfSSL | 15:117db924cf7c | 81 | * HAVE_ECC320: 320 bit key |
wolfSSL | 15:117db924cf7c | 82 | * HAVE_ECC384: 384 bit key |
wolfSSL | 15:117db924cf7c | 83 | * HAVE_ECC512: 512 bit key |
wolfSSL | 15:117db924cf7c | 84 | * HAVE_ECC521: 521 bit key |
wolfSSL | 15:117db924cf7c | 85 | */ |
wolfSSL | 15:117db924cf7c | 86 | |
wolfSSL | 15:117db924cf7c | 87 | |
wolfSSL | 15:117db924cf7c | 88 | #ifdef HAVE_ECC |
wolfSSL | 15:117db924cf7c | 89 | |
wolfSSL | 15:117db924cf7c | 90 | /* Make sure custom curves is enabled for Brainpool or Koblitz curve types */ |
wolfSSL | 15:117db924cf7c | 91 | #if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\ |
wolfSSL | 15:117db924cf7c | 92 | !defined(WOLFSSL_CUSTOM_CURVES) |
wolfSSL | 15:117db924cf7c | 93 | #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 94 | #endif |
wolfSSL | 15:117db924cf7c | 95 | |
wolfSSL | 15:117db924cf7c | 96 | #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) |
wolfSSL | 15:117db924cf7c | 97 | /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ |
wolfSSL | 15:117db924cf7c | 98 | #define FIPS_NO_WRAPPERS |
wolfSSL | 15:117db924cf7c | 99 | |
wolfSSL | 15:117db924cf7c | 100 | #ifdef USE_WINDOWS_API |
wolfSSL | 15:117db924cf7c | 101 | #pragma code_seg(".fipsA$f") |
wolfSSL | 15:117db924cf7c | 102 | #pragma const_seg(".fipsB$f") |
wolfSSL | 15:117db924cf7c | 103 | #endif |
wolfSSL | 15:117db924cf7c | 104 | #endif |
wolfSSL | 15:117db924cf7c | 105 | |
wolfSSL | 15:117db924cf7c | 106 | #include <wolfssl/wolfcrypt/ecc.h> |
wolfSSL | 15:117db924cf7c | 107 | #include <wolfssl/wolfcrypt/asn.h> |
wolfSSL | 15:117db924cf7c | 108 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 15:117db924cf7c | 109 | #include <wolfssl/wolfcrypt/logging.h> |
wolfSSL | 15:117db924cf7c | 110 | #include <wolfssl/wolfcrypt/types.h> |
wolfSSL | 15:117db924cf7c | 111 | |
wolfSSL | 15:117db924cf7c | 112 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 113 | #include <wolfssl/wolfcrypt/sp.h> |
wolfSSL | 15:117db924cf7c | 114 | #endif |
wolfSSL | 15:117db924cf7c | 115 | |
wolfSSL | 15:117db924cf7c | 116 | #ifdef HAVE_ECC_ENCRYPT |
wolfSSL | 15:117db924cf7c | 117 | #include <wolfssl/wolfcrypt/hmac.h> |
wolfSSL | 15:117db924cf7c | 118 | #include <wolfssl/wolfcrypt/aes.h> |
wolfSSL | 15:117db924cf7c | 119 | #endif |
wolfSSL | 15:117db924cf7c | 120 | |
wolfSSL | 15:117db924cf7c | 121 | #ifdef HAVE_X963_KDF |
wolfSSL | 15:117db924cf7c | 122 | #include <wolfssl/wolfcrypt/hash.h> |
wolfSSL | 15:117db924cf7c | 123 | #endif |
wolfSSL | 15:117db924cf7c | 124 | |
wolfSSL | 16:8e0d178b1d1e | 125 | #ifdef WOLF_CRYPTO_CB |
wolfSSL | 16:8e0d178b1d1e | 126 | #include <wolfssl/wolfcrypt/cryptocb.h> |
wolfSSL | 15:117db924cf7c | 127 | #endif |
wolfSSL | 15:117db924cf7c | 128 | |
wolfSSL | 15:117db924cf7c | 129 | #ifdef NO_INLINE |
wolfSSL | 15:117db924cf7c | 130 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 15:117db924cf7c | 131 | #else |
wolfSSL | 15:117db924cf7c | 132 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 15:117db924cf7c | 133 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 15:117db924cf7c | 134 | #endif |
wolfSSL | 15:117db924cf7c | 135 | |
wolfSSL | 15:117db924cf7c | 136 | #if defined(FREESCALE_LTC_ECC) |
wolfSSL | 15:117db924cf7c | 137 | #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h> |
wolfSSL | 15:117db924cf7c | 138 | #endif |
wolfSSL | 15:117db924cf7c | 139 | |
wolfSSL | 16:8e0d178b1d1e | 140 | #if defined(WOLFSSL_STM32_PKA) |
wolfSSL | 16:8e0d178b1d1e | 141 | #include <wolfssl/wolfcrypt/port/st/stm32.h> |
wolfSSL | 16:8e0d178b1d1e | 142 | #endif |
wolfSSL | 16:8e0d178b1d1e | 143 | |
wolfSSL | 15:117db924cf7c | 144 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 145 | #define GEN_MEM_ERR MP_MEM |
wolfSSL | 15:117db924cf7c | 146 | #elif defined(USE_FAST_MATH) |
wolfSSL | 15:117db924cf7c | 147 | #define GEN_MEM_ERR FP_MEM |
wolfSSL | 15:117db924cf7c | 148 | #else |
wolfSSL | 15:117db924cf7c | 149 | #define GEN_MEM_ERR MP_MEM |
wolfSSL | 15:117db924cf7c | 150 | #endif |
wolfSSL | 15:117db924cf7c | 151 | |
wolfSSL | 15:117db924cf7c | 152 | |
wolfSSL | 15:117db924cf7c | 153 | /* internal ECC states */ |
wolfSSL | 15:117db924cf7c | 154 | enum { |
wolfSSL | 15:117db924cf7c | 155 | ECC_STATE_NONE = 0, |
wolfSSL | 15:117db924cf7c | 156 | |
wolfSSL | 15:117db924cf7c | 157 | ECC_STATE_SHARED_SEC_GEN, |
wolfSSL | 15:117db924cf7c | 158 | ECC_STATE_SHARED_SEC_RES, |
wolfSSL | 15:117db924cf7c | 159 | |
wolfSSL | 15:117db924cf7c | 160 | ECC_STATE_SIGN_DO, |
wolfSSL | 15:117db924cf7c | 161 | ECC_STATE_SIGN_ENCODE, |
wolfSSL | 15:117db924cf7c | 162 | |
wolfSSL | 15:117db924cf7c | 163 | ECC_STATE_VERIFY_DECODE, |
wolfSSL | 15:117db924cf7c | 164 | ECC_STATE_VERIFY_DO, |
wolfSSL | 15:117db924cf7c | 165 | ECC_STATE_VERIFY_RES, |
wolfSSL | 15:117db924cf7c | 166 | }; |
wolfSSL | 15:117db924cf7c | 167 | |
wolfSSL | 15:117db924cf7c | 168 | |
wolfSSL | 15:117db924cf7c | 169 | /* map |
wolfSSL | 15:117db924cf7c | 170 | ptmul -> mulmod |
wolfSSL | 15:117db924cf7c | 171 | */ |
wolfSSL | 15:117db924cf7c | 172 | |
wolfSSL | 15:117db924cf7c | 173 | /* 256-bit curve on by default whether user curves or not */ |
wolfSSL | 15:117db924cf7c | 174 | #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 175 | #define ECC112 |
wolfSSL | 15:117db924cf7c | 176 | #endif |
wolfSSL | 15:117db924cf7c | 177 | #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 178 | #define ECC128 |
wolfSSL | 15:117db924cf7c | 179 | #endif |
wolfSSL | 15:117db924cf7c | 180 | #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 181 | #define ECC160 |
wolfSSL | 15:117db924cf7c | 182 | #endif |
wolfSSL | 15:117db924cf7c | 183 | #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 184 | #define ECC192 |
wolfSSL | 15:117db924cf7c | 185 | #endif |
wolfSSL | 15:117db924cf7c | 186 | #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 187 | #define ECC224 |
wolfSSL | 15:117db924cf7c | 188 | #endif |
wolfSSL | 15:117db924cf7c | 189 | #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 190 | #define ECC239 |
wolfSSL | 15:117db924cf7c | 191 | #endif |
wolfSSL | 15:117db924cf7c | 192 | #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 193 | #define ECC256 |
wolfSSL | 15:117db924cf7c | 194 | #endif |
wolfSSL | 15:117db924cf7c | 195 | #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 196 | #define ECC320 |
wolfSSL | 15:117db924cf7c | 197 | #endif |
wolfSSL | 15:117db924cf7c | 198 | #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 199 | #define ECC384 |
wolfSSL | 15:117db924cf7c | 200 | #endif |
wolfSSL | 15:117db924cf7c | 201 | #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 202 | #define ECC512 |
wolfSSL | 15:117db924cf7c | 203 | #endif |
wolfSSL | 15:117db924cf7c | 204 | #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) |
wolfSSL | 15:117db924cf7c | 205 | #define ECC521 |
wolfSSL | 15:117db924cf7c | 206 | #endif |
wolfSSL | 15:117db924cf7c | 207 | |
wolfSSL | 15:117db924cf7c | 208 | /* The encoded OID's for ECC curves */ |
wolfSSL | 15:117db924cf7c | 209 | #ifdef ECC112 |
wolfSSL | 15:117db924cf7c | 210 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 211 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 212 | #define CODED_SECP112R1 {1,3,132,0,6} |
wolfSSL | 15:117db924cf7c | 213 | #define CODED_SECP112R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 214 | #else |
wolfSSL | 15:117db924cf7c | 215 | #define CODED_SECP112R1 {0x2B,0x81,0x04,0x00,0x06} |
wolfSSL | 15:117db924cf7c | 216 | #define CODED_SECP112R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 217 | #endif |
wolfSSL | 16:8e0d178b1d1e | 218 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 219 | static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1; |
wolfSSL | 15:117db924cf7c | 220 | #else |
wolfSSL | 15:117db924cf7c | 221 | #define ecc_oid_secp112r1 CODED_SECP112R1 |
wolfSSL | 15:117db924cf7c | 222 | #endif |
wolfSSL | 15:117db924cf7c | 223 | #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ |
wolfSSL | 15:117db924cf7c | 224 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 225 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 226 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 227 | #define CODED_SECP112R2 {1,3,132,0,7} |
wolfSSL | 15:117db924cf7c | 228 | #define CODED_SECP112R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 229 | #else |
wolfSSL | 15:117db924cf7c | 230 | #define CODED_SECP112R2 {0x2B,0x81,0x04,0x00,0x07} |
wolfSSL | 15:117db924cf7c | 231 | #define CODED_SECP112R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 232 | #endif |
wolfSSL | 16:8e0d178b1d1e | 233 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 234 | static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2; |
wolfSSL | 15:117db924cf7c | 235 | #else |
wolfSSL | 15:117db924cf7c | 236 | #define ecc_oid_secp112r2 CODED_SECP112R2 |
wolfSSL | 15:117db924cf7c | 237 | #endif |
wolfSSL | 15:117db924cf7c | 238 | #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ |
wolfSSL | 15:117db924cf7c | 239 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 240 | #endif /* ECC112 */ |
wolfSSL | 15:117db924cf7c | 241 | #ifdef ECC128 |
wolfSSL | 15:117db924cf7c | 242 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 243 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 244 | #define CODED_SECP128R1 {1,3,132,0,28} |
wolfSSL | 15:117db924cf7c | 245 | #define CODED_SECP128R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 246 | #else |
wolfSSL | 15:117db924cf7c | 247 | #define CODED_SECP128R1 {0x2B,0x81,0x04,0x00,0x1C} |
wolfSSL | 15:117db924cf7c | 248 | #define CODED_SECP128R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 249 | #endif |
wolfSSL | 16:8e0d178b1d1e | 250 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 251 | static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1; |
wolfSSL | 15:117db924cf7c | 252 | #else |
wolfSSL | 15:117db924cf7c | 253 | #define ecc_oid_secp128r1 CODED_SECP128R1 |
wolfSSL | 15:117db924cf7c | 254 | #endif |
wolfSSL | 15:117db924cf7c | 255 | #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ |
wolfSSL | 15:117db924cf7c | 256 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 257 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 258 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 259 | #define CODED_SECP128R2 {1,3,132,0,29} |
wolfSSL | 15:117db924cf7c | 260 | #define CODED_SECP128R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 261 | #else |
wolfSSL | 15:117db924cf7c | 262 | #define CODED_SECP128R2 {0x2B,0x81,0x04,0x00,0x1D} |
wolfSSL | 15:117db924cf7c | 263 | #define CODED_SECP128R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 264 | #endif |
wolfSSL | 16:8e0d178b1d1e | 265 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 266 | static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2; |
wolfSSL | 15:117db924cf7c | 267 | #else |
wolfSSL | 15:117db924cf7c | 268 | #define ecc_oid_secp128r2 CODED_SECP128R2 |
wolfSSL | 15:117db924cf7c | 269 | #endif |
wolfSSL | 15:117db924cf7c | 270 | #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ |
wolfSSL | 15:117db924cf7c | 271 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 272 | #endif /* ECC128 */ |
wolfSSL | 15:117db924cf7c | 273 | #ifdef ECC160 |
wolfSSL | 15:117db924cf7c | 274 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 275 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 276 | #define CODED_SECP160R1 {1,3,132,0,8} |
wolfSSL | 15:117db924cf7c | 277 | #define CODED_SECP160R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 278 | #else |
wolfSSL | 15:117db924cf7c | 279 | #define CODED_SECP160R1 {0x2B,0x81,0x04,0x00,0x08} |
wolfSSL | 15:117db924cf7c | 280 | #define CODED_SECP160R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 281 | #endif |
wolfSSL | 16:8e0d178b1d1e | 282 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 283 | static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1; |
wolfSSL | 15:117db924cf7c | 284 | #else |
wolfSSL | 15:117db924cf7c | 285 | #define ecc_oid_secp160r1 CODED_SECP160R1 |
wolfSSL | 15:117db924cf7c | 286 | #endif |
wolfSSL | 15:117db924cf7c | 287 | #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ |
wolfSSL | 15:117db924cf7c | 288 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 289 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 290 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 291 | #define CODED_SECP160R2 {1,3,132,0,30} |
wolfSSL | 16:8e0d178b1d1e | 292 | #define CODED_SECP160R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 293 | #else |
wolfSSL | 15:117db924cf7c | 294 | #define CODED_SECP160R2 {0x2B,0x81,0x04,0x00,0x1E} |
wolfSSL | 15:117db924cf7c | 295 | #define CODED_SECP160R2_SZ 5 |
wolfSSL | 15:117db924cf7c | 296 | #endif |
wolfSSL | 16:8e0d178b1d1e | 297 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 298 | static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2; |
wolfSSL | 15:117db924cf7c | 299 | #else |
wolfSSL | 15:117db924cf7c | 300 | #define ecc_oid_secp160r2 CODED_SECP160R2 |
wolfSSL | 15:117db924cf7c | 301 | #endif |
wolfSSL | 15:117db924cf7c | 302 | #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ |
wolfSSL | 15:117db924cf7c | 303 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 304 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 305 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 306 | #define CODED_SECP160K1 {1,3,132,0,9} |
wolfSSL | 15:117db924cf7c | 307 | #define CODED_SECP160K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 308 | #else |
wolfSSL | 15:117db924cf7c | 309 | #define CODED_SECP160K1 {0x2B,0x81,0x04,0x00,0x09} |
wolfSSL | 15:117db924cf7c | 310 | #define CODED_SECP160K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 311 | #endif |
wolfSSL | 16:8e0d178b1d1e | 312 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 313 | static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1; |
wolfSSL | 15:117db924cf7c | 314 | #else |
wolfSSL | 15:117db924cf7c | 315 | #define ecc_oid_secp160k1 CODED_SECP160K1 |
wolfSSL | 15:117db924cf7c | 316 | #endif |
wolfSSL | 15:117db924cf7c | 317 | #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ |
wolfSSL | 15:117db924cf7c | 318 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 319 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 320 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 321 | #define CODED_BRAINPOOLP160R1 {1,3,36,3,3,2,8,1,1,1} |
wolfSSL | 15:117db924cf7c | 322 | #define CODED_BRAINPOOLP160R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 323 | #else |
wolfSSL | 15:117db924cf7c | 324 | #define CODED_BRAINPOOLP160R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01} |
wolfSSL | 15:117db924cf7c | 325 | #define CODED_BRAINPOOLP160R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 326 | #endif |
wolfSSL | 16:8e0d178b1d1e | 327 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 328 | static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1; |
wolfSSL | 15:117db924cf7c | 329 | #else |
wolfSSL | 15:117db924cf7c | 330 | #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1 |
wolfSSL | 15:117db924cf7c | 331 | #endif |
wolfSSL | 15:117db924cf7c | 332 | #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ |
wolfSSL | 15:117db924cf7c | 333 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 334 | #endif /* ECC160 */ |
wolfSSL | 15:117db924cf7c | 335 | #ifdef ECC192 |
wolfSSL | 15:117db924cf7c | 336 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 337 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 338 | #define CODED_SECP192R1 {1,2,840,10045,3,1,1} |
wolfSSL | 15:117db924cf7c | 339 | #define CODED_SECP192R1_SZ 7 |
wolfSSL | 15:117db924cf7c | 340 | #else |
wolfSSL | 15:117db924cf7c | 341 | #define CODED_SECP192R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01} |
wolfSSL | 15:117db924cf7c | 342 | #define CODED_SECP192R1_SZ 8 |
wolfSSL | 15:117db924cf7c | 343 | #endif |
wolfSSL | 16:8e0d178b1d1e | 344 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 345 | static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1; |
wolfSSL | 15:117db924cf7c | 346 | #else |
wolfSSL | 15:117db924cf7c | 347 | #define ecc_oid_secp192r1 CODED_SECP192R1 |
wolfSSL | 15:117db924cf7c | 348 | #endif |
wolfSSL | 15:117db924cf7c | 349 | #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ |
wolfSSL | 15:117db924cf7c | 350 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 351 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 352 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 353 | #define CODED_PRIME192V2 {1,2,840,10045,3,1,2} |
wolfSSL | 15:117db924cf7c | 354 | #define CODED_PRIME192V2_SZ 7 |
wolfSSL | 15:117db924cf7c | 355 | #else |
wolfSSL | 15:117db924cf7c | 356 | #define CODED_PRIME192V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02} |
wolfSSL | 15:117db924cf7c | 357 | #define CODED_PRIME192V2_SZ 8 |
wolfSSL | 15:117db924cf7c | 358 | #endif |
wolfSSL | 16:8e0d178b1d1e | 359 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 360 | static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2; |
wolfSSL | 15:117db924cf7c | 361 | #else |
wolfSSL | 15:117db924cf7c | 362 | #define ecc_oid_prime192v2 CODED_PRIME192V2 |
wolfSSL | 15:117db924cf7c | 363 | #endif |
wolfSSL | 15:117db924cf7c | 364 | #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ |
wolfSSL | 15:117db924cf7c | 365 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 366 | #ifdef HAVE_ECC_SECPR3 |
wolfSSL | 15:117db924cf7c | 367 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 368 | #define CODED_PRIME192V3 {1,2,840,10045,3,1,3} |
wolfSSL | 15:117db924cf7c | 369 | #define CODED_PRIME192V3_SZ 7 |
wolfSSL | 15:117db924cf7c | 370 | #else |
wolfSSL | 15:117db924cf7c | 371 | #define CODED_PRIME192V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03} |
wolfSSL | 15:117db924cf7c | 372 | #define CODED_PRIME192V3_SZ 8 |
wolfSSL | 15:117db924cf7c | 373 | #endif |
wolfSSL | 16:8e0d178b1d1e | 374 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 375 | static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3; |
wolfSSL | 15:117db924cf7c | 376 | #else |
wolfSSL | 15:117db924cf7c | 377 | #define ecc_oid_prime192v3 CODED_PRIME192V3 |
wolfSSL | 15:117db924cf7c | 378 | #endif |
wolfSSL | 15:117db924cf7c | 379 | #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ |
wolfSSL | 15:117db924cf7c | 380 | #endif /* HAVE_ECC_SECPR3 */ |
wolfSSL | 15:117db924cf7c | 381 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 382 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 383 | #define CODED_SECP192K1 {1,3,132,0,31} |
wolfSSL | 15:117db924cf7c | 384 | #define CODED_SECP192K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 385 | #else |
wolfSSL | 15:117db924cf7c | 386 | #define CODED_SECP192K1 {0x2B,0x81,0x04,0x00,0x1F} |
wolfSSL | 15:117db924cf7c | 387 | #define CODED_SECP192K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 388 | #endif |
wolfSSL | 16:8e0d178b1d1e | 389 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 390 | static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1; |
wolfSSL | 15:117db924cf7c | 391 | #else |
wolfSSL | 15:117db924cf7c | 392 | #define ecc_oid_secp192k1 CODED_SECP192K1 |
wolfSSL | 15:117db924cf7c | 393 | #endif |
wolfSSL | 15:117db924cf7c | 394 | #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ |
wolfSSL | 15:117db924cf7c | 395 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 396 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 397 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 398 | #define CODED_BRAINPOOLP192R1 {1,3,36,3,3,2,8,1,1,3} |
wolfSSL | 15:117db924cf7c | 399 | #define CODED_BRAINPOOLP192R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 400 | #else |
wolfSSL | 15:117db924cf7c | 401 | #define CODED_BRAINPOOLP192R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03} |
wolfSSL | 15:117db924cf7c | 402 | #define CODED_BRAINPOOLP192R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 403 | #endif |
wolfSSL | 16:8e0d178b1d1e | 404 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 405 | static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1; |
wolfSSL | 15:117db924cf7c | 406 | #else |
wolfSSL | 15:117db924cf7c | 407 | #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1 |
wolfSSL | 15:117db924cf7c | 408 | #endif |
wolfSSL | 15:117db924cf7c | 409 | #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ |
wolfSSL | 15:117db924cf7c | 410 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 411 | #endif /* ECC192 */ |
wolfSSL | 15:117db924cf7c | 412 | #ifdef ECC224 |
wolfSSL | 15:117db924cf7c | 413 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 414 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 415 | #define CODED_SECP224R1 {1,3,132,0,33} |
wolfSSL | 15:117db924cf7c | 416 | #define CODED_SECP224R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 417 | #else |
wolfSSL | 15:117db924cf7c | 418 | #define CODED_SECP224R1 {0x2B,0x81,0x04,0x00,0x21} |
wolfSSL | 15:117db924cf7c | 419 | #define CODED_SECP224R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 420 | #endif |
wolfSSL | 16:8e0d178b1d1e | 421 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 422 | static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1; |
wolfSSL | 15:117db924cf7c | 423 | #else |
wolfSSL | 15:117db924cf7c | 424 | #define ecc_oid_secp224r1 CODED_SECP224R1 |
wolfSSL | 15:117db924cf7c | 425 | #endif |
wolfSSL | 15:117db924cf7c | 426 | #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ |
wolfSSL | 15:117db924cf7c | 427 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 428 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 429 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 430 | #define CODED_SECP224K1 {1,3,132,0,32} |
wolfSSL | 15:117db924cf7c | 431 | #define CODED_SECP224K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 432 | #else |
wolfSSL | 15:117db924cf7c | 433 | #define CODED_SECP224K1 {0x2B,0x81,0x04,0x00,0x20} |
wolfSSL | 15:117db924cf7c | 434 | #define CODED_SECP224K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 435 | #endif |
wolfSSL | 16:8e0d178b1d1e | 436 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 437 | static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1; |
wolfSSL | 15:117db924cf7c | 438 | #else |
wolfSSL | 15:117db924cf7c | 439 | #define ecc_oid_secp224k1 CODED_SECP224K1 |
wolfSSL | 15:117db924cf7c | 440 | #endif |
wolfSSL | 15:117db924cf7c | 441 | #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ |
wolfSSL | 15:117db924cf7c | 442 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 443 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 444 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 445 | #define CODED_BRAINPOOLP224R1 {1,3,36,3,3,2,8,1,1,5} |
wolfSSL | 15:117db924cf7c | 446 | #define CODED_BRAINPOOLP224R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 447 | #else |
wolfSSL | 15:117db924cf7c | 448 | #define CODED_BRAINPOOLP224R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05} |
wolfSSL | 15:117db924cf7c | 449 | #define CODED_BRAINPOOLP224R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 450 | #endif |
wolfSSL | 16:8e0d178b1d1e | 451 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 452 | static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1; |
wolfSSL | 15:117db924cf7c | 453 | #else |
wolfSSL | 15:117db924cf7c | 454 | #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1 |
wolfSSL | 15:117db924cf7c | 455 | #endif |
wolfSSL | 15:117db924cf7c | 456 | #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ |
wolfSSL | 15:117db924cf7c | 457 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 458 | #endif /* ECC224 */ |
wolfSSL | 15:117db924cf7c | 459 | #ifdef ECC239 |
wolfSSL | 15:117db924cf7c | 460 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 461 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 462 | #define CODED_PRIME239V1 {1,2,840,10045,3,1,4} |
wolfSSL | 15:117db924cf7c | 463 | #define CODED_PRIME239V1_SZ 7 |
wolfSSL | 15:117db924cf7c | 464 | #else |
wolfSSL | 15:117db924cf7c | 465 | #define CODED_PRIME239V1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04} |
wolfSSL | 15:117db924cf7c | 466 | #define CODED_PRIME239V1_SZ 8 |
wolfSSL | 15:117db924cf7c | 467 | #endif |
wolfSSL | 16:8e0d178b1d1e | 468 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 469 | static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1; |
wolfSSL | 15:117db924cf7c | 470 | #else |
wolfSSL | 15:117db924cf7c | 471 | #define ecc_oid_prime239v1 CODED_PRIME239V1 |
wolfSSL | 15:117db924cf7c | 472 | #endif |
wolfSSL | 15:117db924cf7c | 473 | #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ |
wolfSSL | 15:117db924cf7c | 474 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 475 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 476 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 477 | #define CODED_PRIME239V2 {1,2,840,10045,3,1,5} |
wolfSSL | 15:117db924cf7c | 478 | #define CODED_PRIME239V2_SZ 7 |
wolfSSL | 15:117db924cf7c | 479 | #else |
wolfSSL | 15:117db924cf7c | 480 | #define CODED_PRIME239V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05} |
wolfSSL | 15:117db924cf7c | 481 | #define CODED_PRIME239V2_SZ 8 |
wolfSSL | 15:117db924cf7c | 482 | #endif |
wolfSSL | 16:8e0d178b1d1e | 483 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 484 | static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2; |
wolfSSL | 15:117db924cf7c | 485 | #else |
wolfSSL | 15:117db924cf7c | 486 | #define ecc_oid_prime239v2 CODED_PRIME239V2 |
wolfSSL | 15:117db924cf7c | 487 | #endif |
wolfSSL | 15:117db924cf7c | 488 | #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ |
wolfSSL | 15:117db924cf7c | 489 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 490 | #ifdef HAVE_ECC_SECPR3 |
wolfSSL | 15:117db924cf7c | 491 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 492 | #define CODED_PRIME239V3 {1,2,840,10045,3,1,6} |
wolfSSL | 15:117db924cf7c | 493 | #define CODED_PRIME239V3_SZ 7 |
wolfSSL | 15:117db924cf7c | 494 | #else |
wolfSSL | 15:117db924cf7c | 495 | #define CODED_PRIME239V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06} |
wolfSSL | 15:117db924cf7c | 496 | #define CODED_PRIME239V3_SZ 8 |
wolfSSL | 15:117db924cf7c | 497 | #endif |
wolfSSL | 16:8e0d178b1d1e | 498 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 499 | static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3; |
wolfSSL | 15:117db924cf7c | 500 | #else |
wolfSSL | 15:117db924cf7c | 501 | #define ecc_oid_prime239v3 CODED_PRIME239V3 |
wolfSSL | 15:117db924cf7c | 502 | #endif |
wolfSSL | 15:117db924cf7c | 503 | #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ |
wolfSSL | 15:117db924cf7c | 504 | #endif /* HAVE_ECC_SECPR3 */ |
wolfSSL | 15:117db924cf7c | 505 | #endif /* ECC239 */ |
wolfSSL | 15:117db924cf7c | 506 | #ifdef ECC256 |
wolfSSL | 15:117db924cf7c | 507 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 508 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 509 | #define CODED_SECP256R1 {1,2,840,10045,3,1,7} |
wolfSSL | 15:117db924cf7c | 510 | #define CODED_SECP256R1_SZ 7 |
wolfSSL | 15:117db924cf7c | 511 | #else |
wolfSSL | 15:117db924cf7c | 512 | #define CODED_SECP256R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07} |
wolfSSL | 15:117db924cf7c | 513 | #define CODED_SECP256R1_SZ 8 |
wolfSSL | 15:117db924cf7c | 514 | #endif |
wolfSSL | 16:8e0d178b1d1e | 515 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 516 | static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1; |
wolfSSL | 15:117db924cf7c | 517 | #else |
wolfSSL | 15:117db924cf7c | 518 | #define ecc_oid_secp256r1 CODED_SECP256R1 |
wolfSSL | 15:117db924cf7c | 519 | #endif |
wolfSSL | 15:117db924cf7c | 520 | #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ |
wolfSSL | 15:117db924cf7c | 521 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 522 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 523 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 524 | #define CODED_SECP256K1 {1,3,132,0,10} |
wolfSSL | 15:117db924cf7c | 525 | #define CODED_SECP256K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 526 | #else |
wolfSSL | 15:117db924cf7c | 527 | #define CODED_SECP256K1 {0x2B,0x81,0x04,0x00,0x0A} |
wolfSSL | 15:117db924cf7c | 528 | #define CODED_SECP256K1_SZ 5 |
wolfSSL | 15:117db924cf7c | 529 | #endif |
wolfSSL | 16:8e0d178b1d1e | 530 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 531 | static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1; |
wolfSSL | 15:117db924cf7c | 532 | #else |
wolfSSL | 15:117db924cf7c | 533 | #define ecc_oid_secp256k1 CODED_SECP256K1 |
wolfSSL | 15:117db924cf7c | 534 | #endif |
wolfSSL | 15:117db924cf7c | 535 | #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ |
wolfSSL | 15:117db924cf7c | 536 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 537 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 538 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 539 | #define CODED_BRAINPOOLP256R1 {1,3,36,3,3,2,8,1,1,7} |
wolfSSL | 15:117db924cf7c | 540 | #define CODED_BRAINPOOLP256R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 541 | #else |
wolfSSL | 15:117db924cf7c | 542 | #define CODED_BRAINPOOLP256R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07} |
wolfSSL | 15:117db924cf7c | 543 | #define CODED_BRAINPOOLP256R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 544 | #endif |
wolfSSL | 16:8e0d178b1d1e | 545 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 546 | static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1; |
wolfSSL | 15:117db924cf7c | 547 | #else |
wolfSSL | 15:117db924cf7c | 548 | #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1 |
wolfSSL | 15:117db924cf7c | 549 | #endif |
wolfSSL | 15:117db924cf7c | 550 | #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ |
wolfSSL | 15:117db924cf7c | 551 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 552 | #endif /* ECC256 */ |
wolfSSL | 15:117db924cf7c | 553 | #ifdef ECC320 |
wolfSSL | 15:117db924cf7c | 554 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 555 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 556 | #define CODED_BRAINPOOLP320R1 {1,3,36,3,3,2,8,1,1,9} |
wolfSSL | 15:117db924cf7c | 557 | #define CODED_BRAINPOOLP320R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 558 | #else |
wolfSSL | 15:117db924cf7c | 559 | #define CODED_BRAINPOOLP320R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09} |
wolfSSL | 15:117db924cf7c | 560 | #define CODED_BRAINPOOLP320R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 561 | #endif |
wolfSSL | 16:8e0d178b1d1e | 562 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 563 | static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1; |
wolfSSL | 15:117db924cf7c | 564 | #else |
wolfSSL | 15:117db924cf7c | 565 | #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1 |
wolfSSL | 15:117db924cf7c | 566 | #endif |
wolfSSL | 15:117db924cf7c | 567 | #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ |
wolfSSL | 15:117db924cf7c | 568 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 569 | #endif /* ECC320 */ |
wolfSSL | 15:117db924cf7c | 570 | #ifdef ECC384 |
wolfSSL | 15:117db924cf7c | 571 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 572 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 573 | #define CODED_SECP384R1 {1,3,132,0,34} |
wolfSSL | 15:117db924cf7c | 574 | #define CODED_SECP384R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 575 | #else |
wolfSSL | 15:117db924cf7c | 576 | #define CODED_SECP384R1 {0x2B,0x81,0x04,0x00,0x22} |
wolfSSL | 15:117db924cf7c | 577 | #define CODED_SECP384R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 578 | #endif |
wolfSSL | 16:8e0d178b1d1e | 579 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 580 | static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1; |
wolfSSL | 15:117db924cf7c | 581 | #define CODED_SECP384R1_OID ecc_oid_secp384r1 |
wolfSSL | 15:117db924cf7c | 582 | #else |
wolfSSL | 15:117db924cf7c | 583 | #define ecc_oid_secp384r1 CODED_SECP384R1 |
wolfSSL | 15:117db924cf7c | 584 | #endif |
wolfSSL | 15:117db924cf7c | 585 | #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ |
wolfSSL | 15:117db924cf7c | 586 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 587 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 588 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 589 | #define CODED_BRAINPOOLP384R1 {1,3,36,3,3,2,8,1,1,11} |
wolfSSL | 15:117db924cf7c | 590 | #define CODED_BRAINPOOLP384R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 591 | #else |
wolfSSL | 15:117db924cf7c | 592 | #define CODED_BRAINPOOLP384R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B} |
wolfSSL | 15:117db924cf7c | 593 | #define CODED_BRAINPOOLP384R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 594 | #endif |
wolfSSL | 16:8e0d178b1d1e | 595 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 596 | static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1; |
wolfSSL | 15:117db924cf7c | 597 | #else |
wolfSSL | 15:117db924cf7c | 598 | #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1 |
wolfSSL | 15:117db924cf7c | 599 | #endif |
wolfSSL | 15:117db924cf7c | 600 | #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ |
wolfSSL | 15:117db924cf7c | 601 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 602 | #endif /* ECC384 */ |
wolfSSL | 15:117db924cf7c | 603 | #ifdef ECC512 |
wolfSSL | 15:117db924cf7c | 604 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 605 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 606 | #define CODED_BRAINPOOLP512R1 {1,3,36,3,3,2,8,1,1,13} |
wolfSSL | 15:117db924cf7c | 607 | #define CODED_BRAINPOOLP512R1_SZ 10 |
wolfSSL | 15:117db924cf7c | 608 | #else |
wolfSSL | 15:117db924cf7c | 609 | #define CODED_BRAINPOOLP512R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D} |
wolfSSL | 15:117db924cf7c | 610 | #define CODED_BRAINPOOLP512R1_SZ 9 |
wolfSSL | 15:117db924cf7c | 611 | #endif |
wolfSSL | 16:8e0d178b1d1e | 612 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 613 | static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1; |
wolfSSL | 15:117db924cf7c | 614 | #else |
wolfSSL | 15:117db924cf7c | 615 | #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1 |
wolfSSL | 15:117db924cf7c | 616 | #endif |
wolfSSL | 15:117db924cf7c | 617 | #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ |
wolfSSL | 15:117db924cf7c | 618 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 619 | #endif /* ECC512 */ |
wolfSSL | 15:117db924cf7c | 620 | #ifdef ECC521 |
wolfSSL | 15:117db924cf7c | 621 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 622 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 623 | #define CODED_SECP521R1 {1,3,132,0,35} |
wolfSSL | 15:117db924cf7c | 624 | #define CODED_SECP521R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 625 | #else |
wolfSSL | 15:117db924cf7c | 626 | #define CODED_SECP521R1 {0x2B,0x81,0x04,0x00,0x23} |
wolfSSL | 15:117db924cf7c | 627 | #define CODED_SECP521R1_SZ 5 |
wolfSSL | 15:117db924cf7c | 628 | #endif |
wolfSSL | 16:8e0d178b1d1e | 629 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 630 | static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1; |
wolfSSL | 15:117db924cf7c | 631 | #else |
wolfSSL | 15:117db924cf7c | 632 | #define ecc_oid_secp521r1 CODED_SECP521R1 |
wolfSSL | 15:117db924cf7c | 633 | #endif |
wolfSSL | 15:117db924cf7c | 634 | #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ |
wolfSSL | 15:117db924cf7c | 635 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 636 | #endif /* ECC521 */ |
wolfSSL | 15:117db924cf7c | 637 | |
wolfSSL | 15:117db924cf7c | 638 | |
wolfSSL | 15:117db924cf7c | 639 | /* This holds the key settings. |
wolfSSL | 15:117db924cf7c | 640 | ***MUST*** be organized by size from smallest to largest. */ |
wolfSSL | 15:117db924cf7c | 641 | |
wolfSSL | 15:117db924cf7c | 642 | const ecc_set_type ecc_sets[] = { |
wolfSSL | 15:117db924cf7c | 643 | #ifdef ECC112 |
wolfSSL | 15:117db924cf7c | 644 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 645 | { |
wolfSSL | 15:117db924cf7c | 646 | 14, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 647 | ECC_SECP112R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 648 | "SECP112R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 649 | "DB7C2ABF62E35E668076BEAD208B", /* prime */ |
wolfSSL | 15:117db924cf7c | 650 | "DB7C2ABF62E35E668076BEAD2088", /* A */ |
wolfSSL | 15:117db924cf7c | 651 | "659EF8BA043916EEDE8911702B22", /* B */ |
wolfSSL | 15:117db924cf7c | 652 | "DB7C2ABF62E35E7628DFAC6561C5", /* order */ |
wolfSSL | 15:117db924cf7c | 653 | "9487239995A5EE76B55F9C2F098", /* Gx */ |
wolfSSL | 15:117db924cf7c | 654 | "A89CE5AF8724C0A23E0E0FF77500", /* Gy */ |
wolfSSL | 15:117db924cf7c | 655 | ecc_oid_secp112r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 656 | ecc_oid_secp112r1_sz, |
wolfSSL | 15:117db924cf7c | 657 | ECC_SECP112R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 658 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 659 | }, |
wolfSSL | 15:117db924cf7c | 660 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 661 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 662 | { |
wolfSSL | 15:117db924cf7c | 663 | 14, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 664 | ECC_SECP112R2, /* ID */ |
wolfSSL | 15:117db924cf7c | 665 | "SECP112R2", /* curve name */ |
wolfSSL | 15:117db924cf7c | 666 | "DB7C2ABF62E35E668076BEAD208B", /* prime */ |
wolfSSL | 15:117db924cf7c | 667 | "6127C24C05F38A0AAAF65C0EF02C", /* A */ |
wolfSSL | 15:117db924cf7c | 668 | "51DEF1815DB5ED74FCC34C85D709", /* B */ |
wolfSSL | 15:117db924cf7c | 669 | "36DF0AAFD8B8D7597CA10520D04B", /* order */ |
wolfSSL | 15:117db924cf7c | 670 | "4BA30AB5E892B4E1649DD0928643", /* Gx */ |
wolfSSL | 15:117db924cf7c | 671 | "ADCD46F5882E3747DEF36E956E97", /* Gy */ |
wolfSSL | 15:117db924cf7c | 672 | ecc_oid_secp112r2, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 673 | ecc_oid_secp112r2_sz, |
wolfSSL | 15:117db924cf7c | 674 | ECC_SECP112R2_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 675 | 4, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 676 | }, |
wolfSSL | 15:117db924cf7c | 677 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 678 | #endif /* ECC112 */ |
wolfSSL | 15:117db924cf7c | 679 | #ifdef ECC128 |
wolfSSL | 15:117db924cf7c | 680 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 681 | { |
wolfSSL | 15:117db924cf7c | 682 | 16, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 683 | ECC_SECP128R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 684 | "SECP128R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 685 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 686 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 687 | "E87579C11079F43DD824993C2CEE5ED3", /* B */ |
wolfSSL | 15:117db924cf7c | 688 | "FFFFFFFE0000000075A30D1B9038A115", /* order */ |
wolfSSL | 15:117db924cf7c | 689 | "161FF7528B899B2D0C28607CA52C5B86", /* Gx */ |
wolfSSL | 15:117db924cf7c | 690 | "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */ |
wolfSSL | 15:117db924cf7c | 691 | ecc_oid_secp128r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 692 | ecc_oid_secp128r1_sz, |
wolfSSL | 15:117db924cf7c | 693 | ECC_SECP128R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 694 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 695 | }, |
wolfSSL | 15:117db924cf7c | 696 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 697 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 698 | { |
wolfSSL | 15:117db924cf7c | 699 | 16, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 700 | ECC_SECP128R2, /* ID */ |
wolfSSL | 15:117db924cf7c | 701 | "SECP128R2", /* curve name */ |
wolfSSL | 15:117db924cf7c | 702 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 703 | "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */ |
wolfSSL | 15:117db924cf7c | 704 | "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */ |
wolfSSL | 15:117db924cf7c | 705 | "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */ |
wolfSSL | 15:117db924cf7c | 706 | "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */ |
wolfSSL | 15:117db924cf7c | 707 | "27B6916A894D3AEE7106FE805FC34B44", /* Gy */ |
wolfSSL | 15:117db924cf7c | 708 | ecc_oid_secp128r2, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 709 | ecc_oid_secp128r2_sz, |
wolfSSL | 15:117db924cf7c | 710 | ECC_SECP128R2_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 711 | 4, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 712 | }, |
wolfSSL | 15:117db924cf7c | 713 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 714 | #endif /* ECC128 */ |
wolfSSL | 15:117db924cf7c | 715 | #ifdef ECC160 |
wolfSSL | 15:117db924cf7c | 716 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 717 | { |
wolfSSL | 15:117db924cf7c | 718 | 20, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 719 | ECC_SECP160R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 720 | "SECP160R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 721 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 722 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 723 | "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */ |
wolfSSL | 15:117db924cf7c | 724 | "100000000000000000001F4C8F927AED3CA752257",/* order */ |
wolfSSL | 15:117db924cf7c | 725 | "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */ |
wolfSSL | 15:117db924cf7c | 726 | "23A628553168947D59DCC912042351377AC5FB32", /* Gy */ |
wolfSSL | 15:117db924cf7c | 727 | ecc_oid_secp160r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 728 | ecc_oid_secp160r1_sz, |
wolfSSL | 15:117db924cf7c | 729 | ECC_SECP160R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 730 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 731 | }, |
wolfSSL | 15:117db924cf7c | 732 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 733 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 734 | { |
wolfSSL | 15:117db924cf7c | 735 | 20, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 736 | ECC_SECP160R2, /* ID */ |
wolfSSL | 15:117db924cf7c | 737 | "SECP160R2", /* curve name */ |
wolfSSL | 15:117db924cf7c | 738 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ |
wolfSSL | 15:117db924cf7c | 739 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */ |
wolfSSL | 15:117db924cf7c | 740 | "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */ |
wolfSSL | 15:117db924cf7c | 741 | "100000000000000000000351EE786A818F3A1A16B",/* order */ |
wolfSSL | 15:117db924cf7c | 742 | "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */ |
wolfSSL | 15:117db924cf7c | 743 | "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */ |
wolfSSL | 15:117db924cf7c | 744 | ecc_oid_secp160r2, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 745 | ecc_oid_secp160r2_sz, |
wolfSSL | 15:117db924cf7c | 746 | ECC_SECP160R2_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 747 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 748 | }, |
wolfSSL | 15:117db924cf7c | 749 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 750 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 751 | { |
wolfSSL | 15:117db924cf7c | 752 | 20, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 753 | ECC_SECP160K1, /* ID */ |
wolfSSL | 15:117db924cf7c | 754 | "SECP160K1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 755 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ |
wolfSSL | 15:117db924cf7c | 756 | "0000000000000000000000000000000000000000", /* A */ |
wolfSSL | 15:117db924cf7c | 757 | "0000000000000000000000000000000000000007", /* B */ |
wolfSSL | 15:117db924cf7c | 758 | "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */ |
wolfSSL | 15:117db924cf7c | 759 | "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */ |
wolfSSL | 15:117db924cf7c | 760 | "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */ |
wolfSSL | 15:117db924cf7c | 761 | ecc_oid_secp160k1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 762 | ecc_oid_secp160k1_sz, |
wolfSSL | 15:117db924cf7c | 763 | ECC_SECP160K1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 764 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 765 | }, |
wolfSSL | 15:117db924cf7c | 766 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 767 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 768 | { |
wolfSSL | 15:117db924cf7c | 769 | 20, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 770 | ECC_BRAINPOOLP160R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 771 | "BRAINPOOLP160R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 772 | "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */ |
wolfSSL | 15:117db924cf7c | 773 | "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */ |
wolfSSL | 15:117db924cf7c | 774 | "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */ |
wolfSSL | 15:117db924cf7c | 775 | "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */ |
wolfSSL | 15:117db924cf7c | 776 | "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */ |
wolfSSL | 15:117db924cf7c | 777 | "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */ |
wolfSSL | 15:117db924cf7c | 778 | ecc_oid_brainpoolp160r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 779 | ecc_oid_brainpoolp160r1_sz, |
wolfSSL | 15:117db924cf7c | 780 | ECC_BRAINPOOLP160R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 781 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 782 | }, |
wolfSSL | 15:117db924cf7c | 783 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 784 | #endif /* ECC160 */ |
wolfSSL | 15:117db924cf7c | 785 | #ifdef ECC192 |
wolfSSL | 15:117db924cf7c | 786 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 787 | { |
wolfSSL | 15:117db924cf7c | 788 | 24, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 789 | ECC_SECP192R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 790 | "SECP192R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 791 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 792 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 793 | "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B */ |
wolfSSL | 15:117db924cf7c | 794 | "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */ |
wolfSSL | 15:117db924cf7c | 795 | "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */ |
wolfSSL | 15:117db924cf7c | 796 | "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */ |
wolfSSL | 15:117db924cf7c | 797 | ecc_oid_secp192r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 798 | ecc_oid_secp192r1_sz, |
wolfSSL | 15:117db924cf7c | 799 | ECC_SECP192R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 800 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 801 | }, |
wolfSSL | 15:117db924cf7c | 802 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 803 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 804 | { |
wolfSSL | 15:117db924cf7c | 805 | 24, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 806 | ECC_PRIME192V2, /* ID */ |
wolfSSL | 15:117db924cf7c | 807 | "PRIME192V2", /* curve name */ |
wolfSSL | 15:117db924cf7c | 808 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 809 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 810 | "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */ |
wolfSSL | 15:117db924cf7c | 811 | "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */ |
wolfSSL | 15:117db924cf7c | 812 | "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */ |
wolfSSL | 15:117db924cf7c | 813 | "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */ |
wolfSSL | 15:117db924cf7c | 814 | ecc_oid_prime192v2, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 815 | ecc_oid_prime192v2_sz, |
wolfSSL | 15:117db924cf7c | 816 | ECC_PRIME192V2_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 817 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 818 | }, |
wolfSSL | 15:117db924cf7c | 819 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 820 | #ifdef HAVE_ECC_SECPR3 |
wolfSSL | 15:117db924cf7c | 821 | { |
wolfSSL | 15:117db924cf7c | 822 | 24, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 823 | ECC_PRIME192V3, /* ID */ |
wolfSSL | 15:117db924cf7c | 824 | "PRIME192V3", /* curve name */ |
wolfSSL | 15:117db924cf7c | 825 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 826 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 827 | "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */ |
wolfSSL | 15:117db924cf7c | 828 | "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */ |
wolfSSL | 15:117db924cf7c | 829 | "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */ |
wolfSSL | 15:117db924cf7c | 830 | "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */ |
wolfSSL | 15:117db924cf7c | 831 | ecc_oid_prime192v3, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 832 | ecc_oid_prime192v3_sz, |
wolfSSL | 15:117db924cf7c | 833 | ECC_PRIME192V3_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 834 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 835 | }, |
wolfSSL | 15:117db924cf7c | 836 | #endif /* HAVE_ECC_SECPR3 */ |
wolfSSL | 15:117db924cf7c | 837 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 838 | { |
wolfSSL | 15:117db924cf7c | 839 | 24, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 840 | ECC_SECP192K1, /* ID */ |
wolfSSL | 15:117db924cf7c | 841 | "SECP192K1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 842 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */ |
wolfSSL | 15:117db924cf7c | 843 | "000000000000000000000000000000000000000000000000", /* A */ |
wolfSSL | 15:117db924cf7c | 844 | "000000000000000000000000000000000000000000000003", /* B */ |
wolfSSL | 15:117db924cf7c | 845 | "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */ |
wolfSSL | 15:117db924cf7c | 846 | "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */ |
wolfSSL | 15:117db924cf7c | 847 | "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */ |
wolfSSL | 15:117db924cf7c | 848 | ecc_oid_secp192k1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 849 | ecc_oid_secp192k1_sz, |
wolfSSL | 15:117db924cf7c | 850 | ECC_SECP192K1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 851 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 852 | }, |
wolfSSL | 15:117db924cf7c | 853 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 854 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 855 | { |
wolfSSL | 15:117db924cf7c | 856 | 24, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 857 | ECC_BRAINPOOLP192R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 858 | "BRAINPOOLP192R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 859 | "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */ |
wolfSSL | 15:117db924cf7c | 860 | "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */ |
wolfSSL | 15:117db924cf7c | 861 | "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */ |
wolfSSL | 15:117db924cf7c | 862 | "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */ |
wolfSSL | 15:117db924cf7c | 863 | "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */ |
wolfSSL | 15:117db924cf7c | 864 | "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */ |
wolfSSL | 15:117db924cf7c | 865 | ecc_oid_brainpoolp192r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 866 | ecc_oid_brainpoolp192r1_sz, |
wolfSSL | 15:117db924cf7c | 867 | ECC_BRAINPOOLP192R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 868 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 869 | }, |
wolfSSL | 15:117db924cf7c | 870 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 871 | #endif /* ECC192 */ |
wolfSSL | 15:117db924cf7c | 872 | #ifdef ECC224 |
wolfSSL | 15:117db924cf7c | 873 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 874 | { |
wolfSSL | 15:117db924cf7c | 875 | 28, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 876 | ECC_SECP224R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 877 | "SECP224R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 878 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */ |
wolfSSL | 15:117db924cf7c | 879 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */ |
wolfSSL | 15:117db924cf7c | 880 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B */ |
wolfSSL | 15:117db924cf7c | 881 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ |
wolfSSL | 15:117db924cf7c | 882 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ |
wolfSSL | 15:117db924cf7c | 883 | "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ |
wolfSSL | 15:117db924cf7c | 884 | ecc_oid_secp224r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 885 | ecc_oid_secp224r1_sz, |
wolfSSL | 15:117db924cf7c | 886 | ECC_SECP224R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 887 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 888 | }, |
wolfSSL | 15:117db924cf7c | 889 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 890 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 891 | { |
wolfSSL | 15:117db924cf7c | 892 | 28, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 893 | ECC_SECP224K1, /* ID */ |
wolfSSL | 15:117db924cf7c | 894 | "SECP224K1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 895 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */ |
wolfSSL | 15:117db924cf7c | 896 | "00000000000000000000000000000000000000000000000000000000", /* A */ |
wolfSSL | 15:117db924cf7c | 897 | "00000000000000000000000000000000000000000000000000000005", /* B */ |
wolfSSL | 15:117db924cf7c | 898 | "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */ |
wolfSSL | 15:117db924cf7c | 899 | "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */ |
wolfSSL | 15:117db924cf7c | 900 | "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */ |
wolfSSL | 15:117db924cf7c | 901 | ecc_oid_secp224k1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 902 | ecc_oid_secp224k1_sz, |
wolfSSL | 15:117db924cf7c | 903 | ECC_SECP224K1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 904 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 905 | }, |
wolfSSL | 15:117db924cf7c | 906 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 907 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 908 | { |
wolfSSL | 15:117db924cf7c | 909 | 28, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 910 | ECC_BRAINPOOLP224R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 911 | "BRAINPOOLP224R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 912 | "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */ |
wolfSSL | 15:117db924cf7c | 913 | "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */ |
wolfSSL | 15:117db924cf7c | 914 | "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */ |
wolfSSL | 15:117db924cf7c | 915 | "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */ |
wolfSSL | 15:117db924cf7c | 916 | "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */ |
wolfSSL | 15:117db924cf7c | 917 | "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */ |
wolfSSL | 15:117db924cf7c | 918 | ecc_oid_brainpoolp224r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 919 | ecc_oid_brainpoolp224r1_sz, |
wolfSSL | 15:117db924cf7c | 920 | ECC_BRAINPOOLP224R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 921 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 922 | }, |
wolfSSL | 15:117db924cf7c | 923 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 924 | #endif /* ECC224 */ |
wolfSSL | 15:117db924cf7c | 925 | #ifdef ECC239 |
wolfSSL | 15:117db924cf7c | 926 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 927 | { |
wolfSSL | 15:117db924cf7c | 928 | 30, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 929 | ECC_PRIME239V1, /* ID */ |
wolfSSL | 15:117db924cf7c | 930 | "PRIME239V1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 931 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 932 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 933 | "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */ |
wolfSSL | 15:117db924cf7c | 934 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */ |
wolfSSL | 15:117db924cf7c | 935 | "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */ |
wolfSSL | 15:117db924cf7c | 936 | "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */ |
wolfSSL | 15:117db924cf7c | 937 | ecc_oid_prime239v1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 938 | ecc_oid_prime239v1_sz, |
wolfSSL | 15:117db924cf7c | 939 | ECC_PRIME239V1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 940 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 941 | }, |
wolfSSL | 15:117db924cf7c | 942 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 943 | #ifdef HAVE_ECC_SECPR2 |
wolfSSL | 15:117db924cf7c | 944 | { |
wolfSSL | 15:117db924cf7c | 945 | 30, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 946 | ECC_PRIME239V2, /* ID */ |
wolfSSL | 15:117db924cf7c | 947 | "PRIME239V2", /* curve name */ |
wolfSSL | 15:117db924cf7c | 948 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 949 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 950 | "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */ |
wolfSSL | 15:117db924cf7c | 951 | "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */ |
wolfSSL | 15:117db924cf7c | 952 | "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */ |
wolfSSL | 15:117db924cf7c | 953 | "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */ |
wolfSSL | 15:117db924cf7c | 954 | ecc_oid_prime239v2, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 955 | ecc_oid_prime239v2_sz, |
wolfSSL | 15:117db924cf7c | 956 | ECC_PRIME239V2_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 957 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 958 | }, |
wolfSSL | 15:117db924cf7c | 959 | #endif /* HAVE_ECC_SECPR2 */ |
wolfSSL | 15:117db924cf7c | 960 | #ifdef HAVE_ECC_SECPR3 |
wolfSSL | 15:117db924cf7c | 961 | { |
wolfSSL | 15:117db924cf7c | 962 | 30, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 963 | ECC_PRIME239V3, /* ID */ |
wolfSSL | 15:117db924cf7c | 964 | "PRIME239V3", /* curve name */ |
wolfSSL | 15:117db924cf7c | 965 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 966 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 967 | "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */ |
wolfSSL | 15:117db924cf7c | 968 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */ |
wolfSSL | 15:117db924cf7c | 969 | "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */ |
wolfSSL | 15:117db924cf7c | 970 | "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */ |
wolfSSL | 15:117db924cf7c | 971 | ecc_oid_prime239v3, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 972 | ecc_oid_prime239v3_sz, |
wolfSSL | 15:117db924cf7c | 973 | ECC_PRIME239V3_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 974 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 975 | }, |
wolfSSL | 15:117db924cf7c | 976 | #endif /* HAVE_ECC_SECPR3 */ |
wolfSSL | 15:117db924cf7c | 977 | #endif /* ECC239 */ |
wolfSSL | 15:117db924cf7c | 978 | #ifdef ECC256 |
wolfSSL | 15:117db924cf7c | 979 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 980 | { |
wolfSSL | 15:117db924cf7c | 981 | 32, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 982 | ECC_SECP256R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 983 | "SECP256R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 984 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 985 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 986 | "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B */ |
wolfSSL | 15:117db924cf7c | 987 | "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */ |
wolfSSL | 15:117db924cf7c | 988 | "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */ |
wolfSSL | 15:117db924cf7c | 989 | "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */ |
wolfSSL | 15:117db924cf7c | 990 | ecc_oid_secp256r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 991 | ecc_oid_secp256r1_sz, |
wolfSSL | 15:117db924cf7c | 992 | ECC_SECP256R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 993 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 994 | }, |
wolfSSL | 15:117db924cf7c | 995 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 996 | #ifdef HAVE_ECC_KOBLITZ |
wolfSSL | 15:117db924cf7c | 997 | { |
wolfSSL | 15:117db924cf7c | 998 | 32, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 999 | ECC_SECP256K1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1000 | "SECP256K1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1001 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */ |
wolfSSL | 15:117db924cf7c | 1002 | "0000000000000000000000000000000000000000000000000000000000000000", /* A */ |
wolfSSL | 15:117db924cf7c | 1003 | "0000000000000000000000000000000000000000000000000000000000000007", /* B */ |
wolfSSL | 15:117db924cf7c | 1004 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */ |
wolfSSL | 15:117db924cf7c | 1005 | "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1006 | "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1007 | ecc_oid_secp256k1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1008 | ecc_oid_secp256k1_sz, |
wolfSSL | 15:117db924cf7c | 1009 | ECC_SECP256K1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1010 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1011 | }, |
wolfSSL | 15:117db924cf7c | 1012 | #endif /* HAVE_ECC_KOBLITZ */ |
wolfSSL | 15:117db924cf7c | 1013 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 1014 | { |
wolfSSL | 15:117db924cf7c | 1015 | 32, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1016 | ECC_BRAINPOOLP256R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1017 | "BRAINPOOLP256R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1018 | "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */ |
wolfSSL | 15:117db924cf7c | 1019 | "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */ |
wolfSSL | 15:117db924cf7c | 1020 | "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */ |
wolfSSL | 15:117db924cf7c | 1021 | "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */ |
wolfSSL | 15:117db924cf7c | 1022 | "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1023 | "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1024 | ecc_oid_brainpoolp256r1, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1025 | ecc_oid_brainpoolp256r1_sz, |
wolfSSL | 15:117db924cf7c | 1026 | ECC_BRAINPOOLP256R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1027 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1028 | }, |
wolfSSL | 15:117db924cf7c | 1029 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 1030 | #endif /* ECC256 */ |
wolfSSL | 15:117db924cf7c | 1031 | #ifdef ECC320 |
wolfSSL | 15:117db924cf7c | 1032 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 1033 | { |
wolfSSL | 15:117db924cf7c | 1034 | 40, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1035 | ECC_BRAINPOOLP320R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1036 | "BRAINPOOLP320R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1037 | "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */ |
wolfSSL | 15:117db924cf7c | 1038 | "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */ |
wolfSSL | 15:117db924cf7c | 1039 | "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */ |
wolfSSL | 15:117db924cf7c | 1040 | "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */ |
wolfSSL | 15:117db924cf7c | 1041 | "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1042 | "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1043 | ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1044 | ECC_BRAINPOOLP320R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1045 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1046 | }, |
wolfSSL | 15:117db924cf7c | 1047 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 1048 | #endif /* ECC320 */ |
wolfSSL | 15:117db924cf7c | 1049 | #ifdef ECC384 |
wolfSSL | 15:117db924cf7c | 1050 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 1051 | { |
wolfSSL | 15:117db924cf7c | 1052 | 48, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1053 | ECC_SECP384R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1054 | "SECP384R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1055 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 1056 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 1057 | "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B */ |
wolfSSL | 15:117db924cf7c | 1058 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */ |
wolfSSL | 15:117db924cf7c | 1059 | "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1060 | "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1061 | ecc_oid_secp384r1, ecc_oid_secp384r1_sz, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1062 | ECC_SECP384R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1063 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1064 | }, |
wolfSSL | 15:117db924cf7c | 1065 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 1066 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 1067 | { |
wolfSSL | 15:117db924cf7c | 1068 | 48, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1069 | ECC_BRAINPOOLP384R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1070 | "BRAINPOOLP384R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1071 | "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */ |
wolfSSL | 15:117db924cf7c | 1072 | "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */ |
wolfSSL | 15:117db924cf7c | 1073 | "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */ |
wolfSSL | 15:117db924cf7c | 1074 | "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */ |
wolfSSL | 15:117db924cf7c | 1075 | "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1076 | "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1077 | ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1078 | ECC_BRAINPOOLP384R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1079 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1080 | }, |
wolfSSL | 15:117db924cf7c | 1081 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 1082 | #endif /* ECC384 */ |
wolfSSL | 15:117db924cf7c | 1083 | #ifdef ECC512 |
wolfSSL | 15:117db924cf7c | 1084 | #ifdef HAVE_ECC_BRAINPOOL |
wolfSSL | 15:117db924cf7c | 1085 | { |
wolfSSL | 15:117db924cf7c | 1086 | 64, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1087 | ECC_BRAINPOOLP512R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1088 | "BRAINPOOLP512R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1089 | "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */ |
wolfSSL | 15:117db924cf7c | 1090 | "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */ |
wolfSSL | 15:117db924cf7c | 1091 | "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */ |
wolfSSL | 15:117db924cf7c | 1092 | "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */ |
wolfSSL | 15:117db924cf7c | 1093 | "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1094 | "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1095 | ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1096 | ECC_BRAINPOOLP512R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1097 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1098 | }, |
wolfSSL | 15:117db924cf7c | 1099 | #endif /* HAVE_ECC_BRAINPOOL */ |
wolfSSL | 15:117db924cf7c | 1100 | #endif /* ECC512 */ |
wolfSSL | 15:117db924cf7c | 1101 | #ifdef ECC521 |
wolfSSL | 15:117db924cf7c | 1102 | #ifndef NO_ECC_SECP |
wolfSSL | 15:117db924cf7c | 1103 | { |
wolfSSL | 15:117db924cf7c | 1104 | 66, /* size/bytes */ |
wolfSSL | 15:117db924cf7c | 1105 | ECC_SECP521R1, /* ID */ |
wolfSSL | 15:117db924cf7c | 1106 | "SECP521R1", /* curve name */ |
wolfSSL | 15:117db924cf7c | 1107 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ |
wolfSSL | 15:117db924cf7c | 1108 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ |
wolfSSL | 15:117db924cf7c | 1109 | "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */ |
wolfSSL | 15:117db924cf7c | 1110 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */ |
wolfSSL | 15:117db924cf7c | 1111 | "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */ |
wolfSSL | 15:117db924cf7c | 1112 | "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */ |
wolfSSL | 15:117db924cf7c | 1113 | ecc_oid_secp521r1, ecc_oid_secp521r1_sz, /* oid/oidSz */ |
wolfSSL | 15:117db924cf7c | 1114 | ECC_SECP521R1_OID, /* oid sum */ |
wolfSSL | 15:117db924cf7c | 1115 | 1, /* cofactor */ |
wolfSSL | 15:117db924cf7c | 1116 | }, |
wolfSSL | 15:117db924cf7c | 1117 | #endif /* !NO_ECC_SECP */ |
wolfSSL | 15:117db924cf7c | 1118 | #endif /* ECC521 */ |
wolfSSL | 15:117db924cf7c | 1119 | #if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE) |
wolfSSL | 15:117db924cf7c | 1120 | /* place holder for custom curve index for cache */ |
wolfSSL | 15:117db924cf7c | 1121 | { |
wolfSSL | 15:117db924cf7c | 1122 | 1, /* non-zero */ |
wolfSSL | 15:117db924cf7c | 1123 | ECC_CURVE_CUSTOM, |
wolfSSL | 16:8e0d178b1d1e | 1124 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 1125 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
wolfSSL | 15:117db924cf7c | 1126 | #else |
wolfSSL | 16:8e0d178b1d1e | 1127 | {0},{0},{0},{0},{0},{0},{0},{0}, |
wolfSSL | 15:117db924cf7c | 1128 | #endif |
wolfSSL | 15:117db924cf7c | 1129 | 0, 0, 0 |
wolfSSL | 15:117db924cf7c | 1130 | }, |
wolfSSL | 15:117db924cf7c | 1131 | #endif |
wolfSSL | 15:117db924cf7c | 1132 | { |
wolfSSL | 16:8e0d178b1d1e | 1133 | 0, |
wolfSSL | 16:8e0d178b1d1e | 1134 | ECC_CURVE_INVALID, |
wolfSSL | 16:8e0d178b1d1e | 1135 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 1136 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
wolfSSL | 15:117db924cf7c | 1137 | #else |
wolfSSL | 16:8e0d178b1d1e | 1138 | {0},{0},{0},{0},{0},{0},{0},{0}, |
wolfSSL | 15:117db924cf7c | 1139 | #endif |
wolfSSL | 15:117db924cf7c | 1140 | 0, 0, 0 |
wolfSSL | 15:117db924cf7c | 1141 | } |
wolfSSL | 15:117db924cf7c | 1142 | }; |
wolfSSL | 15:117db924cf7c | 1143 | #define ECC_SET_COUNT (sizeof(ecc_sets)/sizeof(ecc_set_type)) |
wolfSSL | 16:8e0d178b1d1e | 1144 | const size_t ecc_sets_count = ECC_SET_COUNT - 1; |
wolfSSL | 15:117db924cf7c | 1145 | |
wolfSSL | 15:117db924cf7c | 1146 | |
wolfSSL | 15:117db924cf7c | 1147 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 1148 | /* encoded OID cache */ |
wolfSSL | 15:117db924cf7c | 1149 | typedef struct { |
wolfSSL | 15:117db924cf7c | 1150 | word32 oidSz; |
wolfSSL | 15:117db924cf7c | 1151 | byte oid[ECC_MAX_OID_LEN]; |
wolfSSL | 15:117db924cf7c | 1152 | } oid_cache_t; |
wolfSSL | 15:117db924cf7c | 1153 | static oid_cache_t ecc_oid_cache[ECC_SET_COUNT]; |
wolfSSL | 15:117db924cf7c | 1154 | #endif |
wolfSSL | 15:117db924cf7c | 1155 | |
wolfSSL | 15:117db924cf7c | 1156 | |
wolfSSL | 15:117db924cf7c | 1157 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 1158 | static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); |
wolfSSL | 15:117db924cf7c | 1159 | #endif |
wolfSSL | 15:117db924cf7c | 1160 | |
wolfSSL | 16:8e0d178b1d1e | 1161 | |
wolfSSL | 16:8e0d178b1d1e | 1162 | #if (defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)) && \ |
wolfSSL | 16:8e0d178b1d1e | 1163 | !defined(WOLFSSL_ATECC508A) |
wolfSSL | 15:117db924cf7c | 1164 | static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, |
wolfSSL | 15:117db924cf7c | 1165 | mp_int* prime, mp_int* order); |
wolfSSL | 15:117db924cf7c | 1166 | #endif |
wolfSSL | 15:117db924cf7c | 1167 | |
wolfSSL | 15:117db924cf7c | 1168 | int mp_jacobi(mp_int* a, mp_int* n, int* c); |
wolfSSL | 15:117db924cf7c | 1169 | int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); |
wolfSSL | 15:117db924cf7c | 1170 | |
wolfSSL | 15:117db924cf7c | 1171 | |
wolfSSL | 15:117db924cf7c | 1172 | /* Curve Specs */ |
wolfSSL | 15:117db924cf7c | 1173 | typedef struct ecc_curve_spec { |
wolfSSL | 15:117db924cf7c | 1174 | const ecc_set_type* dp; |
wolfSSL | 15:117db924cf7c | 1175 | |
wolfSSL | 15:117db924cf7c | 1176 | mp_int* prime; |
wolfSSL | 15:117db924cf7c | 1177 | mp_int* Af; |
wolfSSL | 15:117db924cf7c | 1178 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1179 | mp_int* Bf; |
wolfSSL | 15:117db924cf7c | 1180 | #endif |
wolfSSL | 15:117db924cf7c | 1181 | mp_int* order; |
wolfSSL | 15:117db924cf7c | 1182 | mp_int* Gx; |
wolfSSL | 15:117db924cf7c | 1183 | mp_int* Gy; |
wolfSSL | 15:117db924cf7c | 1184 | |
wolfSSL | 15:117db924cf7c | 1185 | #ifdef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1186 | mp_int prime_lcl; |
wolfSSL | 15:117db924cf7c | 1187 | mp_int Af_lcl; |
wolfSSL | 15:117db924cf7c | 1188 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1189 | mp_int Bf_lcl; |
wolfSSL | 15:117db924cf7c | 1190 | #endif |
wolfSSL | 15:117db924cf7c | 1191 | mp_int order_lcl; |
wolfSSL | 15:117db924cf7c | 1192 | mp_int Gx_lcl; |
wolfSSL | 15:117db924cf7c | 1193 | mp_int Gy_lcl; |
wolfSSL | 15:117db924cf7c | 1194 | #else |
wolfSSL | 15:117db924cf7c | 1195 | mp_int* spec_ints; |
wolfSSL | 15:117db924cf7c | 1196 | word32 spec_count; |
wolfSSL | 15:117db924cf7c | 1197 | word32 spec_use; |
wolfSSL | 15:117db924cf7c | 1198 | #endif |
wolfSSL | 15:117db924cf7c | 1199 | |
wolfSSL | 15:117db924cf7c | 1200 | byte load_mask; |
wolfSSL | 15:117db924cf7c | 1201 | } ecc_curve_spec; |
wolfSSL | 15:117db924cf7c | 1202 | |
wolfSSL | 15:117db924cf7c | 1203 | enum ecc_curve_load_mask { |
wolfSSL | 15:117db924cf7c | 1204 | ECC_CURVE_FIELD_NONE = 0x00, |
wolfSSL | 15:117db924cf7c | 1205 | ECC_CURVE_FIELD_PRIME = 0x01, |
wolfSSL | 15:117db924cf7c | 1206 | ECC_CURVE_FIELD_AF = 0x02, |
wolfSSL | 15:117db924cf7c | 1207 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1208 | ECC_CURVE_FIELD_BF = 0x04, |
wolfSSL | 15:117db924cf7c | 1209 | #endif |
wolfSSL | 15:117db924cf7c | 1210 | ECC_CURVE_FIELD_ORDER = 0x08, |
wolfSSL | 15:117db924cf7c | 1211 | ECC_CURVE_FIELD_GX = 0x10, |
wolfSSL | 15:117db924cf7c | 1212 | ECC_CURVE_FIELD_GY = 0x20, |
wolfSSL | 15:117db924cf7c | 1213 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1214 | ECC_CURVE_FIELD_ALL = 0x3F, |
wolfSSL | 15:117db924cf7c | 1215 | ECC_CURVE_FIELD_COUNT = 6, |
wolfSSL | 15:117db924cf7c | 1216 | #else |
wolfSSL | 15:117db924cf7c | 1217 | ECC_CURVE_FIELD_ALL = 0x3B, |
wolfSSL | 15:117db924cf7c | 1218 | ECC_CURVE_FIELD_COUNT = 5, |
wolfSSL | 15:117db924cf7c | 1219 | #endif |
wolfSSL | 15:117db924cf7c | 1220 | }; |
wolfSSL | 15:117db924cf7c | 1221 | |
wolfSSL | 15:117db924cf7c | 1222 | #ifdef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1223 | /* cache (mp_int) of the curve parameters */ |
wolfSSL | 15:117db924cf7c | 1224 | static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT]; |
wolfSSL | 15:117db924cf7c | 1225 | #ifndef SINGLE_THREADED |
wolfSSL | 15:117db924cf7c | 1226 | static wolfSSL_Mutex ecc_curve_cache_mutex; |
wolfSSL | 15:117db924cf7c | 1227 | #endif |
wolfSSL | 15:117db924cf7c | 1228 | |
wolfSSL | 15:117db924cf7c | 1229 | #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL |
wolfSSL | 15:117db924cf7c | 1230 | #define ALLOC_CURVE_SPECS(intcount) |
wolfSSL | 15:117db924cf7c | 1231 | #define FREE_CURVE_SPECS() |
wolfSSL | 15:117db924cf7c | 1232 | #elif defined(WOLFSSL_SMALL_STACK) |
wolfSSL | 15:117db924cf7c | 1233 | #define DECLARE_CURVE_SPECS(curve, intcount) \ |
wolfSSL | 15:117db924cf7c | 1234 | mp_int* spec_ints = NULL; \ |
wolfSSL | 15:117db924cf7c | 1235 | ecc_curve_spec curve_lcl; \ |
wolfSSL | 15:117db924cf7c | 1236 | ecc_curve_spec* curve = &curve_lcl; \ |
wolfSSL | 15:117db924cf7c | 1237 | XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \ |
wolfSSL | 15:117db924cf7c | 1238 | curve->spec_count = intcount |
wolfSSL | 15:117db924cf7c | 1239 | |
wolfSSL | 15:117db924cf7c | 1240 | #define ALLOC_CURVE_SPECS(intcount) \ |
wolfSSL | 15:117db924cf7c | 1241 | spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \ |
wolfSSL | 15:117db924cf7c | 1242 | DYNAMIC_TYPE_ECC); \ |
wolfSSL | 15:117db924cf7c | 1243 | if (spec_ints == NULL) \ |
wolfSSL | 15:117db924cf7c | 1244 | return MEMORY_E; \ |
wolfSSL | 15:117db924cf7c | 1245 | curve->spec_ints = spec_ints |
wolfSSL | 15:117db924cf7c | 1246 | #define FREE_CURVE_SPECS() \ |
wolfSSL | 15:117db924cf7c | 1247 | XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC) |
wolfSSL | 15:117db924cf7c | 1248 | #else |
wolfSSL | 15:117db924cf7c | 1249 | #define DECLARE_CURVE_SPECS(curve, intcount) \ |
wolfSSL | 15:117db924cf7c | 1250 | mp_int spec_ints[(intcount)]; \ |
wolfSSL | 15:117db924cf7c | 1251 | ecc_curve_spec curve_lcl; \ |
wolfSSL | 15:117db924cf7c | 1252 | ecc_curve_spec* curve = &curve_lcl; \ |
wolfSSL | 15:117db924cf7c | 1253 | XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \ |
wolfSSL | 15:117db924cf7c | 1254 | curve->spec_ints = spec_ints; \ |
wolfSSL | 15:117db924cf7c | 1255 | curve->spec_count = intcount |
wolfSSL | 15:117db924cf7c | 1256 | #define ALLOC_CURVE_SPECS(intcount) |
wolfSSL | 15:117db924cf7c | 1257 | #define FREE_CURVE_SPECS() |
wolfSSL | 15:117db924cf7c | 1258 | #endif /* ECC_CACHE_CURVE */ |
wolfSSL | 15:117db924cf7c | 1259 | |
wolfSSL | 15:117db924cf7c | 1260 | static void _wc_ecc_curve_free(ecc_curve_spec* curve) |
wolfSSL | 15:117db924cf7c | 1261 | { |
wolfSSL | 15:117db924cf7c | 1262 | if (curve == NULL) { |
wolfSSL | 15:117db924cf7c | 1263 | return; |
wolfSSL | 15:117db924cf7c | 1264 | } |
wolfSSL | 15:117db924cf7c | 1265 | |
wolfSSL | 15:117db924cf7c | 1266 | if (curve->load_mask & ECC_CURVE_FIELD_PRIME) |
wolfSSL | 15:117db924cf7c | 1267 | mp_clear(curve->prime); |
wolfSSL | 15:117db924cf7c | 1268 | if (curve->load_mask & ECC_CURVE_FIELD_AF) |
wolfSSL | 15:117db924cf7c | 1269 | mp_clear(curve->Af); |
wolfSSL | 15:117db924cf7c | 1270 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1271 | if (curve->load_mask & ECC_CURVE_FIELD_BF) |
wolfSSL | 15:117db924cf7c | 1272 | mp_clear(curve->Bf); |
wolfSSL | 15:117db924cf7c | 1273 | #endif |
wolfSSL | 15:117db924cf7c | 1274 | if (curve->load_mask & ECC_CURVE_FIELD_ORDER) |
wolfSSL | 15:117db924cf7c | 1275 | mp_clear(curve->order); |
wolfSSL | 15:117db924cf7c | 1276 | if (curve->load_mask & ECC_CURVE_FIELD_GX) |
wolfSSL | 15:117db924cf7c | 1277 | mp_clear(curve->Gx); |
wolfSSL | 15:117db924cf7c | 1278 | if (curve->load_mask & ECC_CURVE_FIELD_GY) |
wolfSSL | 15:117db924cf7c | 1279 | mp_clear(curve->Gy); |
wolfSSL | 15:117db924cf7c | 1280 | |
wolfSSL | 15:117db924cf7c | 1281 | curve->load_mask = 0; |
wolfSSL | 15:117db924cf7c | 1282 | } |
wolfSSL | 15:117db924cf7c | 1283 | |
wolfSSL | 15:117db924cf7c | 1284 | static void wc_ecc_curve_free(ecc_curve_spec* curve) |
wolfSSL | 15:117db924cf7c | 1285 | { |
wolfSSL | 15:117db924cf7c | 1286 | /* don't free cached curves */ |
wolfSSL | 15:117db924cf7c | 1287 | #ifndef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1288 | _wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 1289 | #endif |
wolfSSL | 15:117db924cf7c | 1290 | (void)curve; |
wolfSSL | 15:117db924cf7c | 1291 | } |
wolfSSL | 15:117db924cf7c | 1292 | |
wolfSSL | 15:117db924cf7c | 1293 | static int wc_ecc_curve_load_item(const char* src, mp_int** dst, |
wolfSSL | 15:117db924cf7c | 1294 | ecc_curve_spec* curve, byte mask) |
wolfSSL | 15:117db924cf7c | 1295 | { |
wolfSSL | 15:117db924cf7c | 1296 | int err; |
wolfSSL | 15:117db924cf7c | 1297 | |
wolfSSL | 15:117db924cf7c | 1298 | #ifndef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1299 | /* get mp_int from temp */ |
wolfSSL | 15:117db924cf7c | 1300 | if (curve->spec_use >= curve->spec_count) { |
wolfSSL | 15:117db924cf7c | 1301 | WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count"); |
wolfSSL | 15:117db924cf7c | 1302 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1303 | } |
wolfSSL | 15:117db924cf7c | 1304 | *dst = &curve->spec_ints[curve->spec_use++]; |
wolfSSL | 15:117db924cf7c | 1305 | #endif |
wolfSSL | 15:117db924cf7c | 1306 | |
wolfSSL | 15:117db924cf7c | 1307 | err = mp_init(*dst); |
wolfSSL | 15:117db924cf7c | 1308 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1309 | curve->load_mask |= mask; |
wolfSSL | 15:117db924cf7c | 1310 | |
wolfSSL | 15:117db924cf7c | 1311 | err = mp_read_radix(*dst, src, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 1312 | |
wolfSSL | 15:117db924cf7c | 1313 | #ifdef HAVE_WOLF_BIGINT |
wolfSSL | 15:117db924cf7c | 1314 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1315 | err = wc_mp_to_bigint(*dst, &(*dst)->raw); |
wolfSSL | 15:117db924cf7c | 1316 | #endif |
wolfSSL | 15:117db924cf7c | 1317 | } |
wolfSSL | 15:117db924cf7c | 1318 | return err; |
wolfSSL | 15:117db924cf7c | 1319 | } |
wolfSSL | 15:117db924cf7c | 1320 | |
wolfSSL | 15:117db924cf7c | 1321 | static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve, |
wolfSSL | 15:117db924cf7c | 1322 | byte load_mask) |
wolfSSL | 15:117db924cf7c | 1323 | { |
wolfSSL | 15:117db924cf7c | 1324 | int ret = 0, x; |
wolfSSL | 15:117db924cf7c | 1325 | ecc_curve_spec* curve; |
wolfSSL | 15:117db924cf7c | 1326 | byte load_items = 0; /* mask of items to load */ |
wolfSSL | 15:117db924cf7c | 1327 | |
wolfSSL | 15:117db924cf7c | 1328 | if (dp == NULL || pCurve == NULL) |
wolfSSL | 15:117db924cf7c | 1329 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1330 | |
wolfSSL | 15:117db924cf7c | 1331 | #ifdef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1332 | x = wc_ecc_get_curve_idx(dp->id); |
wolfSSL | 15:117db924cf7c | 1333 | if (x == ECC_CURVE_INVALID) |
wolfSSL | 15:117db924cf7c | 1334 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1335 | |
wolfSSL | 15:117db924cf7c | 1336 | #if !defined(SINGLE_THREADED) |
wolfSSL | 15:117db924cf7c | 1337 | ret = wc_LockMutex(&ecc_curve_cache_mutex); |
wolfSSL | 15:117db924cf7c | 1338 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 1339 | return ret; |
wolfSSL | 15:117db924cf7c | 1340 | } |
wolfSSL | 15:117db924cf7c | 1341 | #endif |
wolfSSL | 15:117db924cf7c | 1342 | |
wolfSSL | 15:117db924cf7c | 1343 | /* make sure cache has been allocated */ |
wolfSSL | 15:117db924cf7c | 1344 | if (ecc_curve_spec_cache[x] == NULL) { |
wolfSSL | 15:117db924cf7c | 1345 | ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC( |
wolfSSL | 15:117db924cf7c | 1346 | sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1347 | if (ecc_curve_spec_cache[x] == NULL) { |
wolfSSL | 15:117db924cf7c | 1348 | #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) |
wolfSSL | 15:117db924cf7c | 1349 | wc_UnLockMutex(&ecc_curve_cache_mutex); |
wolfSSL | 15:117db924cf7c | 1350 | #endif |
wolfSSL | 15:117db924cf7c | 1351 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1352 | } |
wolfSSL | 15:117db924cf7c | 1353 | XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec)); |
wolfSSL | 15:117db924cf7c | 1354 | } |
wolfSSL | 15:117db924cf7c | 1355 | |
wolfSSL | 15:117db924cf7c | 1356 | /* set curve pointer to cache */ |
wolfSSL | 15:117db924cf7c | 1357 | *pCurve = ecc_curve_spec_cache[x]; |
wolfSSL | 15:117db924cf7c | 1358 | |
wolfSSL | 15:117db924cf7c | 1359 | #endif /* ECC_CACHE_CURVE */ |
wolfSSL | 15:117db924cf7c | 1360 | curve = *pCurve; |
wolfSSL | 15:117db924cf7c | 1361 | |
wolfSSL | 15:117db924cf7c | 1362 | /* make sure the curve is initialized */ |
wolfSSL | 15:117db924cf7c | 1363 | if (curve->dp != dp) { |
wolfSSL | 15:117db924cf7c | 1364 | curve->load_mask = 0; |
wolfSSL | 15:117db924cf7c | 1365 | |
wolfSSL | 15:117db924cf7c | 1366 | #ifdef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1367 | curve->prime = &curve->prime_lcl; |
wolfSSL | 15:117db924cf7c | 1368 | curve->Af = &curve->Af_lcl; |
wolfSSL | 15:117db924cf7c | 1369 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1370 | curve->Bf = &curve->Bf_lcl; |
wolfSSL | 15:117db924cf7c | 1371 | #endif |
wolfSSL | 15:117db924cf7c | 1372 | curve->order = &curve->order_lcl; |
wolfSSL | 15:117db924cf7c | 1373 | curve->Gx = &curve->Gx_lcl; |
wolfSSL | 15:117db924cf7c | 1374 | curve->Gy = &curve->Gy_lcl; |
wolfSSL | 15:117db924cf7c | 1375 | #endif |
wolfSSL | 15:117db924cf7c | 1376 | } |
wolfSSL | 15:117db924cf7c | 1377 | curve->dp = dp; /* set dp info */ |
wolfSSL | 15:117db924cf7c | 1378 | |
wolfSSL | 15:117db924cf7c | 1379 | /* determine items to load */ |
wolfSSL | 15:117db924cf7c | 1380 | load_items = (((byte)~(word32)curve->load_mask) & load_mask); |
wolfSSL | 15:117db924cf7c | 1381 | curve->load_mask |= load_items; |
wolfSSL | 15:117db924cf7c | 1382 | |
wolfSSL | 15:117db924cf7c | 1383 | /* load items */ |
wolfSSL | 15:117db924cf7c | 1384 | x = 0; |
wolfSSL | 15:117db924cf7c | 1385 | if (load_items & ECC_CURVE_FIELD_PRIME) |
wolfSSL | 15:117db924cf7c | 1386 | x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve, |
wolfSSL | 15:117db924cf7c | 1387 | ECC_CURVE_FIELD_PRIME); |
wolfSSL | 15:117db924cf7c | 1388 | if (load_items & ECC_CURVE_FIELD_AF) |
wolfSSL | 15:117db924cf7c | 1389 | x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve, |
wolfSSL | 15:117db924cf7c | 1390 | ECC_CURVE_FIELD_AF); |
wolfSSL | 15:117db924cf7c | 1391 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 1392 | if (load_items & ECC_CURVE_FIELD_BF) |
wolfSSL | 15:117db924cf7c | 1393 | x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve, |
wolfSSL | 15:117db924cf7c | 1394 | ECC_CURVE_FIELD_BF); |
wolfSSL | 15:117db924cf7c | 1395 | #endif |
wolfSSL | 15:117db924cf7c | 1396 | if (load_items & ECC_CURVE_FIELD_ORDER) |
wolfSSL | 15:117db924cf7c | 1397 | x += wc_ecc_curve_load_item(dp->order, &curve->order, curve, |
wolfSSL | 15:117db924cf7c | 1398 | ECC_CURVE_FIELD_ORDER); |
wolfSSL | 15:117db924cf7c | 1399 | if (load_items & ECC_CURVE_FIELD_GX) |
wolfSSL | 15:117db924cf7c | 1400 | x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve, |
wolfSSL | 15:117db924cf7c | 1401 | ECC_CURVE_FIELD_GX); |
wolfSSL | 15:117db924cf7c | 1402 | if (load_items & ECC_CURVE_FIELD_GY) |
wolfSSL | 15:117db924cf7c | 1403 | x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve, |
wolfSSL | 15:117db924cf7c | 1404 | ECC_CURVE_FIELD_GY); |
wolfSSL | 15:117db924cf7c | 1405 | |
wolfSSL | 15:117db924cf7c | 1406 | /* check for error */ |
wolfSSL | 15:117db924cf7c | 1407 | if (x != 0) { |
wolfSSL | 15:117db924cf7c | 1408 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 1409 | ret = MP_READ_E; |
wolfSSL | 15:117db924cf7c | 1410 | } |
wolfSSL | 15:117db924cf7c | 1411 | |
wolfSSL | 15:117db924cf7c | 1412 | #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) |
wolfSSL | 15:117db924cf7c | 1413 | wc_UnLockMutex(&ecc_curve_cache_mutex); |
wolfSSL | 15:117db924cf7c | 1414 | #endif |
wolfSSL | 15:117db924cf7c | 1415 | |
wolfSSL | 15:117db924cf7c | 1416 | return ret; |
wolfSSL | 15:117db924cf7c | 1417 | } |
wolfSSL | 15:117db924cf7c | 1418 | |
wolfSSL | 15:117db924cf7c | 1419 | #ifdef ECC_CACHE_CURVE |
wolfSSL | 15:117db924cf7c | 1420 | int wc_ecc_curve_cache_init(void) |
wolfSSL | 15:117db924cf7c | 1421 | { |
wolfSSL | 15:117db924cf7c | 1422 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 1423 | #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) |
wolfSSL | 15:117db924cf7c | 1424 | ret = wc_InitMutex(&ecc_curve_cache_mutex); |
wolfSSL | 15:117db924cf7c | 1425 | #endif |
wolfSSL | 15:117db924cf7c | 1426 | return ret; |
wolfSSL | 15:117db924cf7c | 1427 | } |
wolfSSL | 15:117db924cf7c | 1428 | |
wolfSSL | 15:117db924cf7c | 1429 | void wc_ecc_curve_cache_free(void) |
wolfSSL | 15:117db924cf7c | 1430 | { |
wolfSSL | 15:117db924cf7c | 1431 | int x; |
wolfSSL | 15:117db924cf7c | 1432 | |
wolfSSL | 15:117db924cf7c | 1433 | /* free all ECC curve caches */ |
wolfSSL | 15:117db924cf7c | 1434 | for (x = 0; x < (int)ECC_SET_COUNT; x++) { |
wolfSSL | 15:117db924cf7c | 1435 | if (ecc_curve_spec_cache[x]) { |
wolfSSL | 15:117db924cf7c | 1436 | _wc_ecc_curve_free(ecc_curve_spec_cache[x]); |
wolfSSL | 15:117db924cf7c | 1437 | XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1438 | ecc_curve_spec_cache[x] = NULL; |
wolfSSL | 15:117db924cf7c | 1439 | } |
wolfSSL | 15:117db924cf7c | 1440 | } |
wolfSSL | 15:117db924cf7c | 1441 | |
wolfSSL | 15:117db924cf7c | 1442 | #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) |
wolfSSL | 15:117db924cf7c | 1443 | wc_FreeMutex(&ecc_curve_cache_mutex); |
wolfSSL | 15:117db924cf7c | 1444 | #endif |
wolfSSL | 15:117db924cf7c | 1445 | } |
wolfSSL | 15:117db924cf7c | 1446 | #endif /* ECC_CACHE_CURVE */ |
wolfSSL | 15:117db924cf7c | 1447 | |
wolfSSL | 15:117db924cf7c | 1448 | |
wolfSSL | 15:117db924cf7c | 1449 | /* Retrieve the curve name for the ECC curve id. |
wolfSSL | 15:117db924cf7c | 1450 | * |
wolfSSL | 15:117db924cf7c | 1451 | * curve_id The id of the curve. |
wolfSSL | 15:117db924cf7c | 1452 | * returns the name stored from the curve if available, otherwise NULL. |
wolfSSL | 15:117db924cf7c | 1453 | */ |
wolfSSL | 15:117db924cf7c | 1454 | const char* wc_ecc_get_name(int curve_id) |
wolfSSL | 15:117db924cf7c | 1455 | { |
wolfSSL | 15:117db924cf7c | 1456 | int curve_idx = wc_ecc_get_curve_idx(curve_id); |
wolfSSL | 15:117db924cf7c | 1457 | if (curve_idx == ECC_CURVE_INVALID) |
wolfSSL | 15:117db924cf7c | 1458 | return NULL; |
wolfSSL | 15:117db924cf7c | 1459 | return ecc_sets[curve_idx].name; |
wolfSSL | 15:117db924cf7c | 1460 | } |
wolfSSL | 15:117db924cf7c | 1461 | |
wolfSSL | 15:117db924cf7c | 1462 | int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) |
wolfSSL | 15:117db924cf7c | 1463 | { |
wolfSSL | 15:117db924cf7c | 1464 | if (keysize <= 0 && curve_id < 0) { |
wolfSSL | 15:117db924cf7c | 1465 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1466 | } |
wolfSSL | 15:117db924cf7c | 1467 | |
wolfSSL | 15:117db924cf7c | 1468 | if (keysize > ECC_MAXSIZE) { |
wolfSSL | 15:117db924cf7c | 1469 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1470 | } |
wolfSSL | 15:117db924cf7c | 1471 | |
wolfSSL | 15:117db924cf7c | 1472 | /* handle custom case */ |
wolfSSL | 15:117db924cf7c | 1473 | if (key->idx != ECC_CUSTOM_IDX) { |
wolfSSL | 15:117db924cf7c | 1474 | int x; |
wolfSSL | 15:117db924cf7c | 1475 | |
wolfSSL | 15:117db924cf7c | 1476 | /* default values */ |
wolfSSL | 15:117db924cf7c | 1477 | key->idx = 0; |
wolfSSL | 15:117db924cf7c | 1478 | key->dp = NULL; |
wolfSSL | 15:117db924cf7c | 1479 | |
wolfSSL | 15:117db924cf7c | 1480 | /* find ecc_set based on curve_id or key size */ |
wolfSSL | 15:117db924cf7c | 1481 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 15:117db924cf7c | 1482 | if (curve_id > ECC_CURVE_DEF) { |
wolfSSL | 15:117db924cf7c | 1483 | if (curve_id == ecc_sets[x].id) |
wolfSSL | 15:117db924cf7c | 1484 | break; |
wolfSSL | 15:117db924cf7c | 1485 | } |
wolfSSL | 15:117db924cf7c | 1486 | else if (keysize <= ecc_sets[x].size) { |
wolfSSL | 15:117db924cf7c | 1487 | break; |
wolfSSL | 15:117db924cf7c | 1488 | } |
wolfSSL | 15:117db924cf7c | 1489 | } |
wolfSSL | 15:117db924cf7c | 1490 | if (ecc_sets[x].size == 0) { |
wolfSSL | 15:117db924cf7c | 1491 | WOLFSSL_MSG("ECC Curve not found"); |
wolfSSL | 15:117db924cf7c | 1492 | return ECC_CURVE_OID_E; |
wolfSSL | 15:117db924cf7c | 1493 | } |
wolfSSL | 15:117db924cf7c | 1494 | |
wolfSSL | 15:117db924cf7c | 1495 | key->idx = x; |
wolfSSL | 15:117db924cf7c | 1496 | key->dp = &ecc_sets[x]; |
wolfSSL | 15:117db924cf7c | 1497 | } |
wolfSSL | 15:117db924cf7c | 1498 | |
wolfSSL | 15:117db924cf7c | 1499 | return 0; |
wolfSSL | 15:117db924cf7c | 1500 | } |
wolfSSL | 15:117db924cf7c | 1501 | |
wolfSSL | 15:117db924cf7c | 1502 | |
wolfSSL | 15:117db924cf7c | 1503 | #ifdef ALT_ECC_SIZE |
wolfSSL | 16:8e0d178b1d1e | 1504 | static void alt_fp_init(mp_int* a) |
wolfSSL | 15:117db924cf7c | 1505 | { |
wolfSSL | 15:117db924cf7c | 1506 | a->size = FP_SIZE_ECC; |
wolfSSL | 16:8e0d178b1d1e | 1507 | mp_zero(a); |
wolfSSL | 15:117db924cf7c | 1508 | } |
wolfSSL | 15:117db924cf7c | 1509 | #endif /* ALT_ECC_SIZE */ |
wolfSSL | 15:117db924cf7c | 1510 | |
wolfSSL | 15:117db924cf7c | 1511 | |
wolfSSL | 15:117db924cf7c | 1512 | #ifndef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 1513 | |
wolfSSL | 15:117db924cf7c | 1514 | #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL) |
wolfSSL | 15:117db924cf7c | 1515 | |
wolfSSL | 15:117db924cf7c | 1516 | /** |
wolfSSL | 15:117db924cf7c | 1517 | Add two ECC points |
wolfSSL | 15:117db924cf7c | 1518 | P The point to add |
wolfSSL | 15:117db924cf7c | 1519 | Q The point to add |
wolfSSL | 15:117db924cf7c | 1520 | R [out] The destination of the double |
wolfSSL | 15:117db924cf7c | 1521 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 1522 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 15:117db924cf7c | 1523 | mp The "b" value from montgomery_setup() |
wolfSSL | 15:117db924cf7c | 1524 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 1525 | */ |
wolfSSL | 15:117db924cf7c | 1526 | int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, |
wolfSSL | 15:117db924cf7c | 1527 | mp_int* a, mp_int* modulus, mp_digit mp) |
wolfSSL | 15:117db924cf7c | 1528 | { |
wolfSSL | 15:117db924cf7c | 1529 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 1530 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1531 | mp_int* t1 = NULL; |
wolfSSL | 15:117db924cf7c | 1532 | mp_int* t2 = NULL; |
wolfSSL | 15:117db924cf7c | 1533 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1534 | mp_int* rx = NULL; |
wolfSSL | 15:117db924cf7c | 1535 | mp_int* ry = NULL; |
wolfSSL | 15:117db924cf7c | 1536 | mp_int* rz = NULL; |
wolfSSL | 15:117db924cf7c | 1537 | #endif |
wolfSSL | 15:117db924cf7c | 1538 | #else |
wolfSSL | 15:117db924cf7c | 1539 | mp_int t1[1], t2[1]; |
wolfSSL | 15:117db924cf7c | 1540 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1541 | mp_int rx[1], ry[1], rz[1]; |
wolfSSL | 15:117db924cf7c | 1542 | #endif |
wolfSSL | 15:117db924cf7c | 1543 | #endif |
wolfSSL | 15:117db924cf7c | 1544 | mp_int *x, *y, *z; |
wolfSSL | 15:117db924cf7c | 1545 | int err; |
wolfSSL | 15:117db924cf7c | 1546 | |
wolfSSL | 15:117db924cf7c | 1547 | if (P == NULL || Q == NULL || R == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 1548 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1549 | } |
wolfSSL | 15:117db924cf7c | 1550 | |
wolfSSL | 15:117db924cf7c | 1551 | /* if Q == R then swap P and Q, so we don't require a local x,y,z */ |
wolfSSL | 15:117db924cf7c | 1552 | if (Q == R) { |
wolfSSL | 15:117db924cf7c | 1553 | ecc_point* tPt = P; |
wolfSSL | 15:117db924cf7c | 1554 | P = Q; |
wolfSSL | 15:117db924cf7c | 1555 | Q = tPt; |
wolfSSL | 15:117db924cf7c | 1556 | } |
wolfSSL | 15:117db924cf7c | 1557 | |
wolfSSL | 15:117db924cf7c | 1558 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1559 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1560 | if (R->key != NULL) { |
wolfSSL | 15:117db924cf7c | 1561 | t1 = R->key->t1; |
wolfSSL | 15:117db924cf7c | 1562 | t2 = R->key->t2; |
wolfSSL | 15:117db924cf7c | 1563 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1564 | rx = R->key->x; |
wolfSSL | 15:117db924cf7c | 1565 | ry = R->key->y; |
wolfSSL | 15:117db924cf7c | 1566 | rz = R->key->z; |
wolfSSL | 15:117db924cf7c | 1567 | #endif |
wolfSSL | 15:117db924cf7c | 1568 | } |
wolfSSL | 15:117db924cf7c | 1569 | else |
wolfSSL | 15:117db924cf7c | 1570 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 1571 | { |
wolfSSL | 15:117db924cf7c | 1572 | t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1573 | t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1574 | if (t1 == NULL || t2 == NULL) { |
wolfSSL | 15:117db924cf7c | 1575 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1576 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1577 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1578 | } |
wolfSSL | 15:117db924cf7c | 1579 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1580 | rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1581 | ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1582 | rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1583 | if (rx == NULL || ry == NULL || rz == NULL) { |
wolfSSL | 15:117db924cf7c | 1584 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1585 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1586 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1587 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1588 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1589 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1590 | } |
wolfSSL | 15:117db924cf7c | 1591 | #endif |
wolfSSL | 15:117db924cf7c | 1592 | } |
wolfSSL | 15:117db924cf7c | 1593 | #endif /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 1594 | |
wolfSSL | 15:117db924cf7c | 1595 | if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1596 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1597 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1598 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 1599 | #endif |
wolfSSL | 15:117db924cf7c | 1600 | { |
wolfSSL | 15:117db924cf7c | 1601 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1602 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1603 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1604 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1605 | #endif |
wolfSSL | 15:117db924cf7c | 1606 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1607 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1608 | } |
wolfSSL | 15:117db924cf7c | 1609 | #endif |
wolfSSL | 15:117db924cf7c | 1610 | return err; |
wolfSSL | 15:117db924cf7c | 1611 | } |
wolfSSL | 15:117db924cf7c | 1612 | |
wolfSSL | 15:117db924cf7c | 1613 | /* should we dbl instead? */ |
wolfSSL | 15:117db924cf7c | 1614 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1615 | err = mp_sub(modulus, Q->y, t1); |
wolfSSL | 15:117db924cf7c | 1616 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1617 | if ( (mp_cmp(P->x, Q->x) == MP_EQ) && |
wolfSSL | 15:117db924cf7c | 1618 | (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && |
wolfSSL | 15:117db924cf7c | 1619 | (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) { |
wolfSSL | 15:117db924cf7c | 1620 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 1621 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 1622 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1623 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1624 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 1625 | #endif |
wolfSSL | 15:117db924cf7c | 1626 | { |
wolfSSL | 15:117db924cf7c | 1627 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1628 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1629 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1630 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1631 | #endif |
wolfSSL | 15:117db924cf7c | 1632 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1633 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1634 | } |
wolfSSL | 15:117db924cf7c | 1635 | #endif |
wolfSSL | 15:117db924cf7c | 1636 | return ecc_projective_dbl_point(P, R, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1637 | } |
wolfSSL | 15:117db924cf7c | 1638 | } |
wolfSSL | 15:117db924cf7c | 1639 | |
wolfSSL | 15:117db924cf7c | 1640 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1641 | goto done; |
wolfSSL | 15:117db924cf7c | 1642 | } |
wolfSSL | 15:117db924cf7c | 1643 | |
wolfSSL | 15:117db924cf7c | 1644 | /* If use ALT_ECC_SIZE we need to use local stack variable since |
wolfSSL | 15:117db924cf7c | 1645 | ecc_point x,y,z is reduced size */ |
wolfSSL | 15:117db924cf7c | 1646 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1647 | /* Use local stack variable */ |
wolfSSL | 15:117db924cf7c | 1648 | x = rx; |
wolfSSL | 15:117db924cf7c | 1649 | y = ry; |
wolfSSL | 15:117db924cf7c | 1650 | z = rz; |
wolfSSL | 15:117db924cf7c | 1651 | |
wolfSSL | 15:117db924cf7c | 1652 | if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1653 | goto done; |
wolfSSL | 15:117db924cf7c | 1654 | } |
wolfSSL | 15:117db924cf7c | 1655 | #else |
wolfSSL | 15:117db924cf7c | 1656 | /* Use destination directly */ |
wolfSSL | 15:117db924cf7c | 1657 | x = R->x; |
wolfSSL | 15:117db924cf7c | 1658 | y = R->y; |
wolfSSL | 15:117db924cf7c | 1659 | z = R->z; |
wolfSSL | 15:117db924cf7c | 1660 | #endif |
wolfSSL | 15:117db924cf7c | 1661 | |
wolfSSL | 15:117db924cf7c | 1662 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1663 | err = mp_copy(P->x, x); |
wolfSSL | 15:117db924cf7c | 1664 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1665 | err = mp_copy(P->y, y); |
wolfSSL | 15:117db924cf7c | 1666 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1667 | err = mp_copy(P->z, z); |
wolfSSL | 15:117db924cf7c | 1668 | |
wolfSSL | 15:117db924cf7c | 1669 | /* if Z is one then these are no-operations */ |
wolfSSL | 15:117db924cf7c | 1670 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1671 | if (!mp_iszero(Q->z)) { |
wolfSSL | 15:117db924cf7c | 1672 | /* T1 = Z' * Z' */ |
wolfSSL | 15:117db924cf7c | 1673 | err = mp_sqr(Q->z, t1); |
wolfSSL | 15:117db924cf7c | 1674 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1675 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1676 | |
wolfSSL | 15:117db924cf7c | 1677 | /* X = X * T1 */ |
wolfSSL | 15:117db924cf7c | 1678 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1679 | err = mp_mul(t1, x, x); |
wolfSSL | 15:117db924cf7c | 1680 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1681 | err = mp_montgomery_reduce(x, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1682 | |
wolfSSL | 15:117db924cf7c | 1683 | /* T1 = Z' * T1 */ |
wolfSSL | 15:117db924cf7c | 1684 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1685 | err = mp_mul(Q->z, t1, t1); |
wolfSSL | 15:117db924cf7c | 1686 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1687 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1688 | |
wolfSSL | 15:117db924cf7c | 1689 | /* Y = Y * T1 */ |
wolfSSL | 15:117db924cf7c | 1690 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1691 | err = mp_mul(t1, y, y); |
wolfSSL | 15:117db924cf7c | 1692 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1693 | err = mp_montgomery_reduce(y, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1694 | } |
wolfSSL | 15:117db924cf7c | 1695 | } |
wolfSSL | 15:117db924cf7c | 1696 | |
wolfSSL | 15:117db924cf7c | 1697 | /* T1 = Z*Z */ |
wolfSSL | 15:117db924cf7c | 1698 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1699 | err = mp_sqr(z, t1); |
wolfSSL | 15:117db924cf7c | 1700 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1701 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1702 | |
wolfSSL | 15:117db924cf7c | 1703 | /* T2 = X' * T1 */ |
wolfSSL | 15:117db924cf7c | 1704 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1705 | err = mp_mul(Q->x, t1, t2); |
wolfSSL | 15:117db924cf7c | 1706 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1707 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1708 | |
wolfSSL | 15:117db924cf7c | 1709 | /* T1 = Z * T1 */ |
wolfSSL | 15:117db924cf7c | 1710 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1711 | err = mp_mul(z, t1, t1); |
wolfSSL | 15:117db924cf7c | 1712 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1713 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1714 | |
wolfSSL | 15:117db924cf7c | 1715 | /* T1 = Y' * T1 */ |
wolfSSL | 15:117db924cf7c | 1716 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1717 | err = mp_mul(Q->y, t1, t1); |
wolfSSL | 15:117db924cf7c | 1718 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1719 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1720 | |
wolfSSL | 15:117db924cf7c | 1721 | /* Y = Y - T1 */ |
wolfSSL | 15:117db924cf7c | 1722 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1723 | err = mp_sub(y, t1, y); |
wolfSSL | 15:117db924cf7c | 1724 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1725 | if (mp_isneg(y)) |
wolfSSL | 15:117db924cf7c | 1726 | err = mp_add(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 1727 | } |
wolfSSL | 15:117db924cf7c | 1728 | /* T1 = 2T1 */ |
wolfSSL | 15:117db924cf7c | 1729 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1730 | err = mp_add(t1, t1, t1); |
wolfSSL | 15:117db924cf7c | 1731 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1732 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 1733 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 1734 | } |
wolfSSL | 15:117db924cf7c | 1735 | /* T1 = Y + T1 */ |
wolfSSL | 15:117db924cf7c | 1736 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1737 | err = mp_add(t1, y, t1); |
wolfSSL | 15:117db924cf7c | 1738 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1739 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 1740 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 1741 | } |
wolfSSL | 15:117db924cf7c | 1742 | /* X = X - T2 */ |
wolfSSL | 15:117db924cf7c | 1743 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1744 | err = mp_sub(x, t2, x); |
wolfSSL | 15:117db924cf7c | 1745 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1746 | if (mp_isneg(x)) |
wolfSSL | 15:117db924cf7c | 1747 | err = mp_add(x, modulus, x); |
wolfSSL | 15:117db924cf7c | 1748 | } |
wolfSSL | 15:117db924cf7c | 1749 | /* T2 = 2T2 */ |
wolfSSL | 15:117db924cf7c | 1750 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1751 | err = mp_add(t2, t2, t2); |
wolfSSL | 15:117db924cf7c | 1752 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1753 | if (mp_cmp(t2, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 1754 | err = mp_sub(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 1755 | } |
wolfSSL | 15:117db924cf7c | 1756 | /* T2 = X + T2 */ |
wolfSSL | 15:117db924cf7c | 1757 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1758 | err = mp_add(t2, x, t2); |
wolfSSL | 15:117db924cf7c | 1759 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1760 | if (mp_cmp(t2, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 1761 | err = mp_sub(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 1762 | } |
wolfSSL | 15:117db924cf7c | 1763 | |
wolfSSL | 15:117db924cf7c | 1764 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1765 | if (!mp_iszero(Q->z)) { |
wolfSSL | 15:117db924cf7c | 1766 | /* Z = Z * Z' */ |
wolfSSL | 15:117db924cf7c | 1767 | err = mp_mul(z, Q->z, z); |
wolfSSL | 15:117db924cf7c | 1768 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1769 | err = mp_montgomery_reduce(z, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1770 | } |
wolfSSL | 15:117db924cf7c | 1771 | } |
wolfSSL | 15:117db924cf7c | 1772 | |
wolfSSL | 15:117db924cf7c | 1773 | /* Z = Z * X */ |
wolfSSL | 15:117db924cf7c | 1774 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1775 | err = mp_mul(z, x, z); |
wolfSSL | 15:117db924cf7c | 1776 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1777 | err = mp_montgomery_reduce(z, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1778 | |
wolfSSL | 15:117db924cf7c | 1779 | /* T1 = T1 * X */ |
wolfSSL | 15:117db924cf7c | 1780 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1781 | err = mp_mul(t1, x, t1); |
wolfSSL | 15:117db924cf7c | 1782 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1783 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1784 | |
wolfSSL | 15:117db924cf7c | 1785 | /* X = X * X */ |
wolfSSL | 15:117db924cf7c | 1786 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1787 | err = mp_sqr(x, x); |
wolfSSL | 15:117db924cf7c | 1788 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1789 | err = mp_montgomery_reduce(x, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1790 | |
wolfSSL | 15:117db924cf7c | 1791 | /* T2 = T2 * x */ |
wolfSSL | 15:117db924cf7c | 1792 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1793 | err = mp_mul(t2, x, t2); |
wolfSSL | 15:117db924cf7c | 1794 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1795 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1796 | |
wolfSSL | 15:117db924cf7c | 1797 | /* T1 = T1 * X */ |
wolfSSL | 15:117db924cf7c | 1798 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1799 | err = mp_mul(t1, x, t1); |
wolfSSL | 15:117db924cf7c | 1800 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1801 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1802 | |
wolfSSL | 15:117db924cf7c | 1803 | /* X = Y*Y */ |
wolfSSL | 15:117db924cf7c | 1804 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1805 | err = mp_sqr(y, x); |
wolfSSL | 15:117db924cf7c | 1806 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1807 | err = mp_montgomery_reduce(x, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1808 | |
wolfSSL | 15:117db924cf7c | 1809 | /* X = X - T2 */ |
wolfSSL | 15:117db924cf7c | 1810 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1811 | err = mp_sub(x, t2, x); |
wolfSSL | 15:117db924cf7c | 1812 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1813 | if (mp_isneg(x)) |
wolfSSL | 15:117db924cf7c | 1814 | err = mp_add(x, modulus, x); |
wolfSSL | 15:117db924cf7c | 1815 | } |
wolfSSL | 15:117db924cf7c | 1816 | /* T2 = T2 - X */ |
wolfSSL | 15:117db924cf7c | 1817 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1818 | err = mp_sub(t2, x, t2); |
wolfSSL | 15:117db924cf7c | 1819 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1820 | if (mp_isneg(t2)) |
wolfSSL | 15:117db924cf7c | 1821 | err = mp_add(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 1822 | } |
wolfSSL | 15:117db924cf7c | 1823 | /* T2 = T2 - X */ |
wolfSSL | 15:117db924cf7c | 1824 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1825 | err = mp_sub(t2, x, t2); |
wolfSSL | 15:117db924cf7c | 1826 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1827 | if (mp_isneg(t2)) |
wolfSSL | 15:117db924cf7c | 1828 | err = mp_add(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 1829 | } |
wolfSSL | 15:117db924cf7c | 1830 | /* T2 = T2 * Y */ |
wolfSSL | 15:117db924cf7c | 1831 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1832 | err = mp_mul(t2, y, t2); |
wolfSSL | 15:117db924cf7c | 1833 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1834 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 1835 | |
wolfSSL | 15:117db924cf7c | 1836 | /* Y = T2 - T1 */ |
wolfSSL | 15:117db924cf7c | 1837 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1838 | err = mp_sub(t2, t1, y); |
wolfSSL | 15:117db924cf7c | 1839 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1840 | if (mp_isneg(y)) |
wolfSSL | 15:117db924cf7c | 1841 | err = mp_add(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 1842 | } |
wolfSSL | 15:117db924cf7c | 1843 | /* Y = Y/2 */ |
wolfSSL | 15:117db924cf7c | 1844 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1845 | if (mp_isodd(y) == MP_YES) |
wolfSSL | 15:117db924cf7c | 1846 | err = mp_add(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 1847 | } |
wolfSSL | 15:117db924cf7c | 1848 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1849 | err = mp_div_2(y, y); |
wolfSSL | 15:117db924cf7c | 1850 | |
wolfSSL | 15:117db924cf7c | 1851 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1852 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1853 | err = mp_copy(x, R->x); |
wolfSSL | 15:117db924cf7c | 1854 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1855 | err = mp_copy(y, R->y); |
wolfSSL | 15:117db924cf7c | 1856 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1857 | err = mp_copy(z, R->z); |
wolfSSL | 15:117db924cf7c | 1858 | #endif |
wolfSSL | 15:117db924cf7c | 1859 | |
wolfSSL | 15:117db924cf7c | 1860 | done: |
wolfSSL | 15:117db924cf7c | 1861 | |
wolfSSL | 15:117db924cf7c | 1862 | /* clean up */ |
wolfSSL | 15:117db924cf7c | 1863 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 1864 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 1865 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1866 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1867 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 1868 | #endif |
wolfSSL | 15:117db924cf7c | 1869 | { |
wolfSSL | 15:117db924cf7c | 1870 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1871 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1872 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1873 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1874 | #endif |
wolfSSL | 15:117db924cf7c | 1875 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1876 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1877 | } |
wolfSSL | 15:117db924cf7c | 1878 | #endif |
wolfSSL | 15:117db924cf7c | 1879 | |
wolfSSL | 15:117db924cf7c | 1880 | return err; |
wolfSSL | 15:117db924cf7c | 1881 | #else |
wolfSSL | 15:117db924cf7c | 1882 | if (P == NULL || Q == NULL || R == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 1883 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1884 | } |
wolfSSL | 15:117db924cf7c | 1885 | |
wolfSSL | 15:117db924cf7c | 1886 | (void)a; |
wolfSSL | 15:117db924cf7c | 1887 | (void)mp; |
wolfSSL | 15:117db924cf7c | 1888 | |
wolfSSL | 16:8e0d178b1d1e | 1889 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 1890 | if (mp_count_bits(modulus) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 1891 | return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z, |
wolfSSL | 16:8e0d178b1d1e | 1892 | R->x, R->y, R->z); |
wolfSSL | 16:8e0d178b1d1e | 1893 | } |
wolfSSL | 16:8e0d178b1d1e | 1894 | #endif |
wolfSSL | 16:8e0d178b1d1e | 1895 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 1896 | if (mp_count_bits(modulus) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 1897 | return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z, |
wolfSSL | 16:8e0d178b1d1e | 1898 | R->x, R->y, R->z); |
wolfSSL | 16:8e0d178b1d1e | 1899 | } |
wolfSSL | 16:8e0d178b1d1e | 1900 | #endif |
wolfSSL | 16:8e0d178b1d1e | 1901 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1902 | #endif |
wolfSSL | 15:117db924cf7c | 1903 | } |
wolfSSL | 15:117db924cf7c | 1904 | |
wolfSSL | 15:117db924cf7c | 1905 | /* ### Point doubling in Jacobian coordinate system ### |
wolfSSL | 15:117db924cf7c | 1906 | * |
wolfSSL | 15:117db924cf7c | 1907 | * let us have a curve: y^2 = x^3 + a*x + b |
wolfSSL | 15:117db924cf7c | 1908 | * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6 |
wolfSSL | 15:117db924cf7c | 1909 | * |
wolfSSL | 15:117db924cf7c | 1910 | * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where: |
wolfSSL | 15:117db924cf7c | 1911 | * Xr = M^2 - 2*S |
wolfSSL | 15:117db924cf7c | 1912 | * Yr = M * (S - Xr) - 8*T |
wolfSSL | 15:117db924cf7c | 1913 | * Zr = 2 * Yp * Zp |
wolfSSL | 15:117db924cf7c | 1914 | * |
wolfSSL | 15:117db924cf7c | 1915 | * M = 3 * Xp^2 + a*Zp^4 |
wolfSSL | 15:117db924cf7c | 1916 | * T = Yp^4 |
wolfSSL | 15:117db924cf7c | 1917 | * S = 4 * Xp * Yp^2 |
wolfSSL | 15:117db924cf7c | 1918 | * |
wolfSSL | 15:117db924cf7c | 1919 | * SPECIAL CASE: when a == 3 we can compute M as |
wolfSSL | 15:117db924cf7c | 1920 | * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2) |
wolfSSL | 15:117db924cf7c | 1921 | */ |
wolfSSL | 15:117db924cf7c | 1922 | |
wolfSSL | 15:117db924cf7c | 1923 | /** |
wolfSSL | 15:117db924cf7c | 1924 | Double an ECC point |
wolfSSL | 15:117db924cf7c | 1925 | P The point to double |
wolfSSL | 15:117db924cf7c | 1926 | R [out] The destination of the double |
wolfSSL | 15:117db924cf7c | 1927 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 1928 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 15:117db924cf7c | 1929 | mp The "b" value from montgomery_setup() |
wolfSSL | 15:117db924cf7c | 1930 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 1931 | */ |
wolfSSL | 15:117db924cf7c | 1932 | int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, |
wolfSSL | 15:117db924cf7c | 1933 | mp_int* modulus, mp_digit mp) |
wolfSSL | 15:117db924cf7c | 1934 | { |
wolfSSL | 15:117db924cf7c | 1935 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 1936 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1937 | mp_int* t1 = NULL; |
wolfSSL | 15:117db924cf7c | 1938 | mp_int* t2 = NULL; |
wolfSSL | 15:117db924cf7c | 1939 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1940 | mp_int* rx = NULL; |
wolfSSL | 15:117db924cf7c | 1941 | mp_int* ry = NULL; |
wolfSSL | 15:117db924cf7c | 1942 | mp_int* rz = NULL; |
wolfSSL | 15:117db924cf7c | 1943 | #endif |
wolfSSL | 15:117db924cf7c | 1944 | #else |
wolfSSL | 15:117db924cf7c | 1945 | mp_int t1[1], t2[1]; |
wolfSSL | 15:117db924cf7c | 1946 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1947 | mp_int rx[1], ry[1], rz[1]; |
wolfSSL | 15:117db924cf7c | 1948 | #endif |
wolfSSL | 15:117db924cf7c | 1949 | #endif |
wolfSSL | 15:117db924cf7c | 1950 | mp_int *x, *y, *z; |
wolfSSL | 15:117db924cf7c | 1951 | int err; |
wolfSSL | 15:117db924cf7c | 1952 | |
wolfSSL | 15:117db924cf7c | 1953 | if (P == NULL || R == NULL || modulus == NULL) |
wolfSSL | 15:117db924cf7c | 1954 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 1955 | |
wolfSSL | 15:117db924cf7c | 1956 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1957 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1958 | if (R->key != NULL) { |
wolfSSL | 15:117db924cf7c | 1959 | t1 = R->key->t1; |
wolfSSL | 15:117db924cf7c | 1960 | t2 = R->key->t2; |
wolfSSL | 15:117db924cf7c | 1961 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1962 | rx = R->key->x; |
wolfSSL | 15:117db924cf7c | 1963 | ry = R->key->y; |
wolfSSL | 15:117db924cf7c | 1964 | rz = R->key->z; |
wolfSSL | 15:117db924cf7c | 1965 | #endif |
wolfSSL | 15:117db924cf7c | 1966 | } |
wolfSSL | 15:117db924cf7c | 1967 | else |
wolfSSL | 15:117db924cf7c | 1968 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 1969 | { |
wolfSSL | 15:117db924cf7c | 1970 | t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1971 | t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1972 | if (t1 == NULL || t2 == NULL) { |
wolfSSL | 15:117db924cf7c | 1973 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1974 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1975 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1976 | } |
wolfSSL | 15:117db924cf7c | 1977 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 1978 | rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1979 | ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1980 | rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1981 | if (rx == NULL || ry == NULL || rz == NULL) { |
wolfSSL | 15:117db924cf7c | 1982 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1983 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1984 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1985 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1986 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 1987 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1988 | } |
wolfSSL | 15:117db924cf7c | 1989 | #endif |
wolfSSL | 15:117db924cf7c | 1990 | } |
wolfSSL | 15:117db924cf7c | 1991 | #endif |
wolfSSL | 15:117db924cf7c | 1992 | |
wolfSSL | 15:117db924cf7c | 1993 | if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1994 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1995 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 1996 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 1997 | #endif |
wolfSSL | 15:117db924cf7c | 1998 | { |
wolfSSL | 15:117db924cf7c | 1999 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2000 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2001 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2002 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2003 | #endif |
wolfSSL | 15:117db924cf7c | 2004 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2005 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2006 | } |
wolfSSL | 15:117db924cf7c | 2007 | #endif |
wolfSSL | 15:117db924cf7c | 2008 | return err; |
wolfSSL | 15:117db924cf7c | 2009 | } |
wolfSSL | 15:117db924cf7c | 2010 | |
wolfSSL | 15:117db924cf7c | 2011 | /* If use ALT_ECC_SIZE we need to use local stack variable since |
wolfSSL | 15:117db924cf7c | 2012 | ecc_point x,y,z is reduced size */ |
wolfSSL | 15:117db924cf7c | 2013 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2014 | /* Use local stack variable */ |
wolfSSL | 15:117db924cf7c | 2015 | x = rx; |
wolfSSL | 15:117db924cf7c | 2016 | y = ry; |
wolfSSL | 15:117db924cf7c | 2017 | z = rz; |
wolfSSL | 15:117db924cf7c | 2018 | |
wolfSSL | 15:117db924cf7c | 2019 | if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2020 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 2021 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 2022 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2023 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2024 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 2025 | #endif |
wolfSSL | 15:117db924cf7c | 2026 | { |
wolfSSL | 15:117db924cf7c | 2027 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2028 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2029 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2030 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2031 | #endif |
wolfSSL | 15:117db924cf7c | 2032 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2033 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2034 | } |
wolfSSL | 15:117db924cf7c | 2035 | #endif |
wolfSSL | 15:117db924cf7c | 2036 | return err; |
wolfSSL | 15:117db924cf7c | 2037 | } |
wolfSSL | 15:117db924cf7c | 2038 | #else |
wolfSSL | 15:117db924cf7c | 2039 | /* Use destination directly */ |
wolfSSL | 15:117db924cf7c | 2040 | x = R->x; |
wolfSSL | 15:117db924cf7c | 2041 | y = R->y; |
wolfSSL | 15:117db924cf7c | 2042 | z = R->z; |
wolfSSL | 15:117db924cf7c | 2043 | #endif |
wolfSSL | 15:117db924cf7c | 2044 | |
wolfSSL | 15:117db924cf7c | 2045 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2046 | err = mp_copy(P->x, x); |
wolfSSL | 15:117db924cf7c | 2047 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2048 | err = mp_copy(P->y, y); |
wolfSSL | 15:117db924cf7c | 2049 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2050 | err = mp_copy(P->z, z); |
wolfSSL | 15:117db924cf7c | 2051 | |
wolfSSL | 15:117db924cf7c | 2052 | /* T1 = Z * Z */ |
wolfSSL | 15:117db924cf7c | 2053 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2054 | err = mp_sqr(z, t1); |
wolfSSL | 15:117db924cf7c | 2055 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2056 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2057 | |
wolfSSL | 15:117db924cf7c | 2058 | /* Z = Y * Z */ |
wolfSSL | 15:117db924cf7c | 2059 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2060 | err = mp_mul(z, y, z); |
wolfSSL | 15:117db924cf7c | 2061 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2062 | err = mp_montgomery_reduce(z, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2063 | |
wolfSSL | 15:117db924cf7c | 2064 | /* Z = 2Z */ |
wolfSSL | 15:117db924cf7c | 2065 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2066 | err = mp_add(z, z, z); |
wolfSSL | 15:117db924cf7c | 2067 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2068 | if (mp_cmp(z, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2069 | err = mp_sub(z, modulus, z); |
wolfSSL | 15:117db924cf7c | 2070 | } |
wolfSSL | 15:117db924cf7c | 2071 | |
wolfSSL | 15:117db924cf7c | 2072 | /* Determine if curve "a" should be used in calc */ |
wolfSSL | 15:117db924cf7c | 2073 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 2074 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2075 | /* Use a and prime to determine if a == 3 */ |
wolfSSL | 15:117db924cf7c | 2076 | err = mp_submod(modulus, a, modulus, t2); |
wolfSSL | 15:117db924cf7c | 2077 | } |
wolfSSL | 15:117db924cf7c | 2078 | if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) { |
wolfSSL | 15:117db924cf7c | 2079 | /* use "a" in calc */ |
wolfSSL | 15:117db924cf7c | 2080 | |
wolfSSL | 15:117db924cf7c | 2081 | /* T2 = T1 * T1 */ |
wolfSSL | 15:117db924cf7c | 2082 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2083 | err = mp_sqr(t1, t2); |
wolfSSL | 15:117db924cf7c | 2084 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2085 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2086 | /* T1 = T2 * a */ |
wolfSSL | 15:117db924cf7c | 2087 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2088 | err = mp_mulmod(t2, a, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2089 | /* T2 = X * X */ |
wolfSSL | 15:117db924cf7c | 2090 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2091 | err = mp_sqr(x, t2); |
wolfSSL | 15:117db924cf7c | 2092 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2093 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2094 | /* T1 = T2 + T1 */ |
wolfSSL | 15:117db924cf7c | 2095 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2096 | err = mp_add(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 2097 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2098 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2099 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2100 | } |
wolfSSL | 15:117db924cf7c | 2101 | /* T1 = T2 + T1 */ |
wolfSSL | 15:117db924cf7c | 2102 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2103 | err = mp_add(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 2104 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2105 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2106 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2107 | } |
wolfSSL | 15:117db924cf7c | 2108 | /* T1 = T2 + T1 */ |
wolfSSL | 15:117db924cf7c | 2109 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2110 | err = mp_add(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 2111 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2112 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2113 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2114 | } |
wolfSSL | 15:117db924cf7c | 2115 | } |
wolfSSL | 15:117db924cf7c | 2116 | else |
wolfSSL | 15:117db924cf7c | 2117 | #endif /* WOLFSSL_CUSTOM_CURVES */ |
wolfSSL | 15:117db924cf7c | 2118 | { |
wolfSSL | 15:117db924cf7c | 2119 | /* assumes "a" == 3 */ |
wolfSSL | 15:117db924cf7c | 2120 | (void)a; |
wolfSSL | 15:117db924cf7c | 2121 | |
wolfSSL | 15:117db924cf7c | 2122 | /* T2 = X - T1 */ |
wolfSSL | 15:117db924cf7c | 2123 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2124 | err = mp_sub(x, t1, t2); |
wolfSSL | 15:117db924cf7c | 2125 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2126 | if (mp_isneg(t2)) |
wolfSSL | 15:117db924cf7c | 2127 | err = mp_add(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 2128 | } |
wolfSSL | 15:117db924cf7c | 2129 | /* T1 = X + T1 */ |
wolfSSL | 15:117db924cf7c | 2130 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2131 | err = mp_add(t1, x, t1); |
wolfSSL | 15:117db924cf7c | 2132 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2133 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2134 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2135 | } |
wolfSSL | 15:117db924cf7c | 2136 | /* T2 = T1 * T2 */ |
wolfSSL | 15:117db924cf7c | 2137 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2138 | err = mp_mul(t1, t2, t2); |
wolfSSL | 15:117db924cf7c | 2139 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2140 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2141 | |
wolfSSL | 15:117db924cf7c | 2142 | /* T1 = 2T2 */ |
wolfSSL | 15:117db924cf7c | 2143 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2144 | err = mp_add(t2, t2, t1); |
wolfSSL | 15:117db924cf7c | 2145 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2146 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2147 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2148 | } |
wolfSSL | 15:117db924cf7c | 2149 | /* T1 = T1 + T2 */ |
wolfSSL | 15:117db924cf7c | 2150 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2151 | err = mp_add(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 2152 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2153 | if (mp_cmp(t1, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2154 | err = mp_sub(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2155 | } |
wolfSSL | 15:117db924cf7c | 2156 | } |
wolfSSL | 15:117db924cf7c | 2157 | |
wolfSSL | 15:117db924cf7c | 2158 | /* Y = 2Y */ |
wolfSSL | 15:117db924cf7c | 2159 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2160 | err = mp_add(y, y, y); |
wolfSSL | 15:117db924cf7c | 2161 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2162 | if (mp_cmp(y, modulus) != MP_LT) |
wolfSSL | 15:117db924cf7c | 2163 | err = mp_sub(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 2164 | } |
wolfSSL | 15:117db924cf7c | 2165 | /* Y = Y * Y */ |
wolfSSL | 15:117db924cf7c | 2166 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2167 | err = mp_sqr(y, y); |
wolfSSL | 15:117db924cf7c | 2168 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2169 | err = mp_montgomery_reduce(y, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2170 | |
wolfSSL | 15:117db924cf7c | 2171 | /* T2 = Y * Y */ |
wolfSSL | 15:117db924cf7c | 2172 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2173 | err = mp_sqr(y, t2); |
wolfSSL | 15:117db924cf7c | 2174 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2175 | err = mp_montgomery_reduce(t2, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2176 | |
wolfSSL | 15:117db924cf7c | 2177 | /* T2 = T2/2 */ |
wolfSSL | 15:117db924cf7c | 2178 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2179 | if (mp_isodd(t2) == MP_YES) |
wolfSSL | 15:117db924cf7c | 2180 | err = mp_add(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 2181 | } |
wolfSSL | 15:117db924cf7c | 2182 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2183 | err = mp_div_2(t2, t2); |
wolfSSL | 15:117db924cf7c | 2184 | |
wolfSSL | 15:117db924cf7c | 2185 | /* Y = Y * X */ |
wolfSSL | 15:117db924cf7c | 2186 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2187 | err = mp_mul(y, x, y); |
wolfSSL | 15:117db924cf7c | 2188 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2189 | err = mp_montgomery_reduce(y, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2190 | |
wolfSSL | 15:117db924cf7c | 2191 | /* X = T1 * T1 */ |
wolfSSL | 15:117db924cf7c | 2192 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2193 | err = mp_sqr(t1, x); |
wolfSSL | 15:117db924cf7c | 2194 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2195 | err = mp_montgomery_reduce(x, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2196 | |
wolfSSL | 15:117db924cf7c | 2197 | /* X = X - Y */ |
wolfSSL | 15:117db924cf7c | 2198 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2199 | err = mp_sub(x, y, x); |
wolfSSL | 15:117db924cf7c | 2200 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2201 | if (mp_isneg(x)) |
wolfSSL | 15:117db924cf7c | 2202 | err = mp_add(x, modulus, x); |
wolfSSL | 15:117db924cf7c | 2203 | } |
wolfSSL | 15:117db924cf7c | 2204 | /* X = X - Y */ |
wolfSSL | 15:117db924cf7c | 2205 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2206 | err = mp_sub(x, y, x); |
wolfSSL | 15:117db924cf7c | 2207 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2208 | if (mp_isneg(x)) |
wolfSSL | 15:117db924cf7c | 2209 | err = mp_add(x, modulus, x); |
wolfSSL | 15:117db924cf7c | 2210 | } |
wolfSSL | 15:117db924cf7c | 2211 | |
wolfSSL | 15:117db924cf7c | 2212 | /* Y = Y - X */ |
wolfSSL | 15:117db924cf7c | 2213 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2214 | err = mp_sub(y, x, y); |
wolfSSL | 15:117db924cf7c | 2215 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2216 | if (mp_isneg(y)) |
wolfSSL | 15:117db924cf7c | 2217 | err = mp_add(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 2218 | } |
wolfSSL | 15:117db924cf7c | 2219 | /* Y = Y * T1 */ |
wolfSSL | 15:117db924cf7c | 2220 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2221 | err = mp_mul(y, t1, y); |
wolfSSL | 15:117db924cf7c | 2222 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2223 | err = mp_montgomery_reduce(y, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2224 | |
wolfSSL | 15:117db924cf7c | 2225 | /* Y = Y - T2 */ |
wolfSSL | 15:117db924cf7c | 2226 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2227 | err = mp_sub(y, t2, y); |
wolfSSL | 15:117db924cf7c | 2228 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2229 | if (mp_isneg(y)) |
wolfSSL | 15:117db924cf7c | 2230 | err = mp_add(y, modulus, y); |
wolfSSL | 15:117db924cf7c | 2231 | } |
wolfSSL | 15:117db924cf7c | 2232 | |
wolfSSL | 15:117db924cf7c | 2233 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2234 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2235 | err = mp_copy(x, R->x); |
wolfSSL | 15:117db924cf7c | 2236 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2237 | err = mp_copy(y, R->y); |
wolfSSL | 15:117db924cf7c | 2238 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2239 | err = mp_copy(z, R->z); |
wolfSSL | 15:117db924cf7c | 2240 | #endif |
wolfSSL | 15:117db924cf7c | 2241 | |
wolfSSL | 15:117db924cf7c | 2242 | /* clean up */ |
wolfSSL | 15:117db924cf7c | 2243 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 2244 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 2245 | |
wolfSSL | 15:117db924cf7c | 2246 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2247 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2248 | if (R->key == NULL) |
wolfSSL | 15:117db924cf7c | 2249 | #endif |
wolfSSL | 15:117db924cf7c | 2250 | { |
wolfSSL | 15:117db924cf7c | 2251 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2252 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2253 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2254 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2255 | #endif |
wolfSSL | 15:117db924cf7c | 2256 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2257 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2258 | } |
wolfSSL | 15:117db924cf7c | 2259 | #endif |
wolfSSL | 15:117db924cf7c | 2260 | |
wolfSSL | 15:117db924cf7c | 2261 | return err; |
wolfSSL | 15:117db924cf7c | 2262 | #else |
wolfSSL | 15:117db924cf7c | 2263 | if (P == NULL || R == NULL || modulus == NULL) |
wolfSSL | 15:117db924cf7c | 2264 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2265 | |
wolfSSL | 15:117db924cf7c | 2266 | (void)a; |
wolfSSL | 15:117db924cf7c | 2267 | (void)mp; |
wolfSSL | 15:117db924cf7c | 2268 | |
wolfSSL | 16:8e0d178b1d1e | 2269 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 2270 | if (mp_count_bits(modulus) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 2271 | return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z); |
wolfSSL | 16:8e0d178b1d1e | 2272 | } |
wolfSSL | 16:8e0d178b1d1e | 2273 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2274 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 2275 | if (mp_count_bits(modulus) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 2276 | return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z); |
wolfSSL | 16:8e0d178b1d1e | 2277 | } |
wolfSSL | 16:8e0d178b1d1e | 2278 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2279 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2280 | #endif |
wolfSSL | 15:117db924cf7c | 2281 | } |
wolfSSL | 15:117db924cf7c | 2282 | |
wolfSSL | 15:117db924cf7c | 2283 | |
wolfSSL | 15:117db924cf7c | 2284 | /** |
wolfSSL | 16:8e0d178b1d1e | 2285 | Map a projective Jacobian point back to affine space |
wolfSSL | 15:117db924cf7c | 2286 | P [in/out] The point to map |
wolfSSL | 15:117db924cf7c | 2287 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 15:117db924cf7c | 2288 | mp The "b" value from montgomery_setup() |
wolfSSL | 16:8e0d178b1d1e | 2289 | ct Operation should be constant time. |
wolfSSL | 15:117db924cf7c | 2290 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 2291 | */ |
wolfSSL | 16:8e0d178b1d1e | 2292 | int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) |
wolfSSL | 15:117db924cf7c | 2293 | { |
wolfSSL | 15:117db924cf7c | 2294 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 2295 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2296 | mp_int* t1 = NULL; |
wolfSSL | 15:117db924cf7c | 2297 | mp_int* t2 = NULL; |
wolfSSL | 15:117db924cf7c | 2298 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2299 | mp_int* rx = NULL; |
wolfSSL | 15:117db924cf7c | 2300 | mp_int* ry = NULL; |
wolfSSL | 15:117db924cf7c | 2301 | mp_int* rz = NULL; |
wolfSSL | 15:117db924cf7c | 2302 | #endif |
wolfSSL | 15:117db924cf7c | 2303 | #else |
wolfSSL | 15:117db924cf7c | 2304 | mp_int t1[1], t2[1]; |
wolfSSL | 15:117db924cf7c | 2305 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2306 | mp_int rx[1], ry[1], rz[1]; |
wolfSSL | 15:117db924cf7c | 2307 | #endif |
wolfSSL | 15:117db924cf7c | 2308 | #endif /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 2309 | mp_int *x, *y, *z; |
wolfSSL | 15:117db924cf7c | 2310 | int err; |
wolfSSL | 15:117db924cf7c | 2311 | |
wolfSSL | 16:8e0d178b1d1e | 2312 | (void)ct; |
wolfSSL | 16:8e0d178b1d1e | 2313 | |
wolfSSL | 15:117db924cf7c | 2314 | if (P == NULL || modulus == NULL) |
wolfSSL | 15:117db924cf7c | 2315 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2316 | |
wolfSSL | 15:117db924cf7c | 2317 | /* special case for point at infinity */ |
wolfSSL | 15:117db924cf7c | 2318 | if (mp_cmp_d(P->z, 0) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 2319 | err = mp_set(P->x, 0); |
wolfSSL | 15:117db924cf7c | 2320 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2321 | err = mp_set(P->y, 0); |
wolfSSL | 15:117db924cf7c | 2322 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2323 | err = mp_set(P->z, 1); |
wolfSSL | 15:117db924cf7c | 2324 | return err; |
wolfSSL | 15:117db924cf7c | 2325 | } |
wolfSSL | 15:117db924cf7c | 2326 | |
wolfSSL | 15:117db924cf7c | 2327 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2328 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2329 | if (P->key != NULL) { |
wolfSSL | 15:117db924cf7c | 2330 | t1 = P->key->t1; |
wolfSSL | 15:117db924cf7c | 2331 | t2 = P->key->t2; |
wolfSSL | 15:117db924cf7c | 2332 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2333 | rx = P->key->x; |
wolfSSL | 15:117db924cf7c | 2334 | ry = P->key->y; |
wolfSSL | 15:117db924cf7c | 2335 | rz = P->key->z; |
wolfSSL | 15:117db924cf7c | 2336 | #endif |
wolfSSL | 15:117db924cf7c | 2337 | } |
wolfSSL | 15:117db924cf7c | 2338 | else |
wolfSSL | 15:117db924cf7c | 2339 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2340 | { |
wolfSSL | 15:117db924cf7c | 2341 | t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2342 | t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2343 | if (t1 == NULL || t2 == NULL) { |
wolfSSL | 15:117db924cf7c | 2344 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2345 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2346 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2347 | } |
wolfSSL | 15:117db924cf7c | 2348 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2349 | rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2350 | ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2351 | rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2352 | if (rx == NULL || ry == NULL || rz == NULL) { |
wolfSSL | 15:117db924cf7c | 2353 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2354 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2355 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2356 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2357 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2358 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2359 | } |
wolfSSL | 15:117db924cf7c | 2360 | #endif |
wolfSSL | 15:117db924cf7c | 2361 | } |
wolfSSL | 15:117db924cf7c | 2362 | #endif /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 2363 | |
wolfSSL | 15:117db924cf7c | 2364 | if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2365 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2366 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2367 | if (P->key == NULL) |
wolfSSL | 15:117db924cf7c | 2368 | #endif |
wolfSSL | 15:117db924cf7c | 2369 | { |
wolfSSL | 15:117db924cf7c | 2370 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2371 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2372 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2373 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2374 | #endif |
wolfSSL | 15:117db924cf7c | 2375 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2376 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2377 | } |
wolfSSL | 15:117db924cf7c | 2378 | #endif |
wolfSSL | 15:117db924cf7c | 2379 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2380 | } |
wolfSSL | 15:117db924cf7c | 2381 | |
wolfSSL | 15:117db924cf7c | 2382 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2383 | /* Use local stack variable */ |
wolfSSL | 15:117db924cf7c | 2384 | x = rx; |
wolfSSL | 15:117db924cf7c | 2385 | y = ry; |
wolfSSL | 15:117db924cf7c | 2386 | z = rz; |
wolfSSL | 15:117db924cf7c | 2387 | |
wolfSSL | 15:117db924cf7c | 2388 | if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2389 | goto done; |
wolfSSL | 15:117db924cf7c | 2390 | } |
wolfSSL | 15:117db924cf7c | 2391 | |
wolfSSL | 15:117db924cf7c | 2392 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2393 | err = mp_copy(P->x, x); |
wolfSSL | 15:117db924cf7c | 2394 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2395 | err = mp_copy(P->y, y); |
wolfSSL | 15:117db924cf7c | 2396 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2397 | err = mp_copy(P->z, z); |
wolfSSL | 15:117db924cf7c | 2398 | |
wolfSSL | 15:117db924cf7c | 2399 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2400 | goto done; |
wolfSSL | 15:117db924cf7c | 2401 | } |
wolfSSL | 15:117db924cf7c | 2402 | #else |
wolfSSL | 15:117db924cf7c | 2403 | /* Use destination directly */ |
wolfSSL | 15:117db924cf7c | 2404 | x = P->x; |
wolfSSL | 15:117db924cf7c | 2405 | y = P->y; |
wolfSSL | 15:117db924cf7c | 2406 | z = P->z; |
wolfSSL | 15:117db924cf7c | 2407 | #endif |
wolfSSL | 15:117db924cf7c | 2408 | |
wolfSSL | 15:117db924cf7c | 2409 | /* get 1/z */ |
wolfSSL | 16:8e0d178b1d1e | 2410 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 2411 | #if defined(ECC_TIMING_RESISTANT) && defined(USE_FAST_MATH) |
wolfSSL | 16:8e0d178b1d1e | 2412 | if (ct) { |
wolfSSL | 16:8e0d178b1d1e | 2413 | err = mp_invmod_mont_ct(z, modulus, t1, mp); |
wolfSSL | 16:8e0d178b1d1e | 2414 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2415 | err = mp_montgomery_reduce(t1, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2416 | } |
wolfSSL | 16:8e0d178b1d1e | 2417 | else |
wolfSSL | 16:8e0d178b1d1e | 2418 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2419 | { |
wolfSSL | 16:8e0d178b1d1e | 2420 | /* first map z back to normal */ |
wolfSSL | 16:8e0d178b1d1e | 2421 | err = mp_montgomery_reduce(z, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2422 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2423 | err = mp_invmod(z, modulus, t1); |
wolfSSL | 16:8e0d178b1d1e | 2424 | } |
wolfSSL | 16:8e0d178b1d1e | 2425 | } |
wolfSSL | 15:117db924cf7c | 2426 | |
wolfSSL | 15:117db924cf7c | 2427 | /* get 1/z^2 and 1/z^3 */ |
wolfSSL | 15:117db924cf7c | 2428 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2429 | err = mp_sqr(t1, t2); |
wolfSSL | 15:117db924cf7c | 2430 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2431 | err = mp_mod(t2, modulus, t2); |
wolfSSL | 15:117db924cf7c | 2432 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2433 | err = mp_mul(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 2434 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2435 | err = mp_mod(t1, modulus, t1); |
wolfSSL | 15:117db924cf7c | 2436 | |
wolfSSL | 15:117db924cf7c | 2437 | /* multiply against x/y */ |
wolfSSL | 15:117db924cf7c | 2438 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2439 | err = mp_mul(x, t2, x); |
wolfSSL | 15:117db924cf7c | 2440 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2441 | err = mp_montgomery_reduce(x, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2442 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2443 | err = mp_mul(y, t1, y); |
wolfSSL | 15:117db924cf7c | 2444 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2445 | err = mp_montgomery_reduce(y, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2446 | |
wolfSSL | 15:117db924cf7c | 2447 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2448 | err = mp_set(z, 1); |
wolfSSL | 15:117db924cf7c | 2449 | |
wolfSSL | 15:117db924cf7c | 2450 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2451 | /* return result */ |
wolfSSL | 15:117db924cf7c | 2452 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2453 | err = mp_copy(x, P->x); |
wolfSSL | 15:117db924cf7c | 2454 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2455 | err = mp_copy(y, P->y); |
wolfSSL | 15:117db924cf7c | 2456 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2457 | err = mp_copy(z, P->z); |
wolfSSL | 15:117db924cf7c | 2458 | |
wolfSSL | 15:117db924cf7c | 2459 | done: |
wolfSSL | 15:117db924cf7c | 2460 | #endif |
wolfSSL | 15:117db924cf7c | 2461 | |
wolfSSL | 15:117db924cf7c | 2462 | /* clean up */ |
wolfSSL | 15:117db924cf7c | 2463 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 2464 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 2465 | |
wolfSSL | 15:117db924cf7c | 2466 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2467 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2468 | if (P->key == NULL) |
wolfSSL | 15:117db924cf7c | 2469 | #endif |
wolfSSL | 15:117db924cf7c | 2470 | { |
wolfSSL | 15:117db924cf7c | 2471 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2472 | XFREE(rz, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2473 | XFREE(ry, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2474 | XFREE(rx, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2475 | #endif |
wolfSSL | 15:117db924cf7c | 2476 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2477 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2478 | } |
wolfSSL | 15:117db924cf7c | 2479 | #endif |
wolfSSL | 15:117db924cf7c | 2480 | |
wolfSSL | 15:117db924cf7c | 2481 | return err; |
wolfSSL | 15:117db924cf7c | 2482 | #else |
wolfSSL | 15:117db924cf7c | 2483 | if (P == NULL || modulus == NULL) |
wolfSSL | 15:117db924cf7c | 2484 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2485 | |
wolfSSL | 15:117db924cf7c | 2486 | (void)mp; |
wolfSSL | 15:117db924cf7c | 2487 | |
wolfSSL | 16:8e0d178b1d1e | 2488 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 2489 | if (mp_count_bits(modulus) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 2490 | return sp_ecc_map_256(P->x, P->y, P->z); |
wolfSSL | 16:8e0d178b1d1e | 2491 | } |
wolfSSL | 16:8e0d178b1d1e | 2492 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2493 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 2494 | if (mp_count_bits(modulus) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 2495 | return sp_ecc_map_384(P->x, P->y, P->z); |
wolfSSL | 16:8e0d178b1d1e | 2496 | } |
wolfSSL | 16:8e0d178b1d1e | 2497 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2498 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 2499 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2500 | } |
wolfSSL | 16:8e0d178b1d1e | 2501 | |
wolfSSL | 16:8e0d178b1d1e | 2502 | int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) |
wolfSSL | 16:8e0d178b1d1e | 2503 | { |
wolfSSL | 16:8e0d178b1d1e | 2504 | return ecc_map_ex(P, modulus, mp, 0); |
wolfSSL | 16:8e0d178b1d1e | 2505 | } |
wolfSSL | 15:117db924cf7c | 2506 | #endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */ |
wolfSSL | 15:117db924cf7c | 2507 | |
wolfSSL | 16:8e0d178b1d1e | 2508 | #if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) |
wolfSSL | 15:117db924cf7c | 2509 | |
wolfSSL | 15:117db924cf7c | 2510 | #if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH) |
wolfSSL | 15:117db924cf7c | 2511 | /** |
wolfSSL | 15:117db924cf7c | 2512 | Perform a point multiplication |
wolfSSL | 15:117db924cf7c | 2513 | k The scalar to multiply by |
wolfSSL | 15:117db924cf7c | 2514 | G The base point |
wolfSSL | 15:117db924cf7c | 2515 | R [out] Destination for kG |
wolfSSL | 15:117db924cf7c | 2516 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 2517 | modulus The modulus of the field the ECC curve is in |
wolfSSL | 15:117db924cf7c | 2518 | map Boolean whether to map back to affine or not |
wolfSSL | 15:117db924cf7c | 2519 | (1==map, 0 == leave in projective) |
wolfSSL | 15:117db924cf7c | 2520 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 2521 | */ |
wolfSSL | 15:117db924cf7c | 2522 | #ifdef FP_ECC |
wolfSSL | 15:117db924cf7c | 2523 | static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, |
wolfSSL | 15:117db924cf7c | 2524 | mp_int* a, mp_int* modulus, int map, |
wolfSSL | 15:117db924cf7c | 2525 | void* heap) |
wolfSSL | 15:117db924cf7c | 2526 | #else |
wolfSSL | 15:117db924cf7c | 2527 | int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, |
wolfSSL | 15:117db924cf7c | 2528 | mp_int* a, mp_int* modulus, int map, |
wolfSSL | 15:117db924cf7c | 2529 | void* heap) |
wolfSSL | 15:117db924cf7c | 2530 | #endif |
wolfSSL | 15:117db924cf7c | 2531 | { |
wolfSSL | 15:117db924cf7c | 2532 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 2533 | #ifndef ECC_TIMING_RESISTANT |
wolfSSL | 15:117db924cf7c | 2534 | /* size of sliding window, don't change this! */ |
wolfSSL | 15:117db924cf7c | 2535 | #define WINSIZE 4 |
wolfSSL | 15:117db924cf7c | 2536 | #define M_POINTS 8 |
wolfSSL | 15:117db924cf7c | 2537 | int first = 1, bitbuf = 0, bitcpy = 0, j; |
wolfSSL | 16:8e0d178b1d1e | 2538 | #elif defined(WC_NO_CACHE_RESISTANT) |
wolfSSL | 16:8e0d178b1d1e | 2539 | #define M_POINTS 4 |
wolfSSL | 15:117db924cf7c | 2540 | #else |
wolfSSL | 16:8e0d178b1d1e | 2541 | #define M_POINTS 5 |
wolfSSL | 15:117db924cf7c | 2542 | #endif |
wolfSSL | 15:117db924cf7c | 2543 | |
wolfSSL | 15:117db924cf7c | 2544 | ecc_point *tG, *M[M_POINTS]; |
wolfSSL | 15:117db924cf7c | 2545 | int i, err; |
wolfSSL | 16:8e0d178b1d1e | 2546 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 16:8e0d178b1d1e | 2547 | ecc_key key; |
wolfSSL | 16:8e0d178b1d1e | 2548 | #endif |
wolfSSL | 15:117db924cf7c | 2549 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2550 | mp_int* mu = NULL; |
wolfSSL | 15:117db924cf7c | 2551 | #else |
wolfSSL | 15:117db924cf7c | 2552 | mp_int mu[1]; |
wolfSSL | 15:117db924cf7c | 2553 | #endif |
wolfSSL | 15:117db924cf7c | 2554 | mp_digit mp; |
wolfSSL | 15:117db924cf7c | 2555 | mp_digit buf; |
wolfSSL | 15:117db924cf7c | 2556 | int bitcnt = 0, mode = 0, digidx = 0; |
wolfSSL | 15:117db924cf7c | 2557 | |
wolfSSL | 15:117db924cf7c | 2558 | if (k == NULL || G == NULL || R == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 2559 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2560 | } |
wolfSSL | 15:117db924cf7c | 2561 | |
wolfSSL | 15:117db924cf7c | 2562 | /* init variables */ |
wolfSSL | 15:117db924cf7c | 2563 | tG = NULL; |
wolfSSL | 15:117db924cf7c | 2564 | XMEMSET(M, 0, sizeof(M)); |
wolfSSL | 15:117db924cf7c | 2565 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2566 | mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2567 | if (mu == NULL) |
wolfSSL | 15:117db924cf7c | 2568 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2569 | #endif |
wolfSSL | 15:117db924cf7c | 2570 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2571 | key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2572 | key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2573 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2574 | key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2575 | key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2576 | key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2577 | #endif |
wolfSSL | 15:117db924cf7c | 2578 | if (key.t1 == NULL || key.t2 == NULL |
wolfSSL | 15:117db924cf7c | 2579 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2580 | || key.x == NULL || key.y == NULL || key.z == NULL |
wolfSSL | 15:117db924cf7c | 2581 | #endif |
wolfSSL | 15:117db924cf7c | 2582 | ) { |
wolfSSL | 15:117db924cf7c | 2583 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2584 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2585 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2586 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2587 | #endif |
wolfSSL | 15:117db924cf7c | 2588 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2589 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2590 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2591 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2592 | } |
wolfSSL | 15:117db924cf7c | 2593 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2594 | |
wolfSSL | 15:117db924cf7c | 2595 | /* init montgomery reduction */ |
wolfSSL | 15:117db924cf7c | 2596 | if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2597 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2598 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2599 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2600 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2601 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2602 | #endif |
wolfSSL | 15:117db924cf7c | 2603 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2604 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2605 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2606 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2607 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2608 | #endif |
wolfSSL | 15:117db924cf7c | 2609 | return err; |
wolfSSL | 15:117db924cf7c | 2610 | } |
wolfSSL | 15:117db924cf7c | 2611 | |
wolfSSL | 15:117db924cf7c | 2612 | if ((err = mp_init(mu)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2613 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2614 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2615 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2616 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2617 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2618 | #endif |
wolfSSL | 15:117db924cf7c | 2619 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2620 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2621 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2622 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2623 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2624 | #endif |
wolfSSL | 15:117db924cf7c | 2625 | return err; |
wolfSSL | 15:117db924cf7c | 2626 | } |
wolfSSL | 15:117db924cf7c | 2627 | if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2628 | mp_clear(mu); |
wolfSSL | 15:117db924cf7c | 2629 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2630 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2631 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2632 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2633 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2634 | #endif |
wolfSSL | 15:117db924cf7c | 2635 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2636 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2637 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2638 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2639 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2640 | #endif |
wolfSSL | 15:117db924cf7c | 2641 | return err; |
wolfSSL | 15:117db924cf7c | 2642 | } |
wolfSSL | 15:117db924cf7c | 2643 | |
wolfSSL | 15:117db924cf7c | 2644 | /* alloc ram for window temps */ |
wolfSSL | 15:117db924cf7c | 2645 | for (i = 0; i < M_POINTS; i++) { |
wolfSSL | 15:117db924cf7c | 2646 | M[i] = wc_ecc_new_point_h(heap); |
wolfSSL | 15:117db924cf7c | 2647 | if (M[i] == NULL) { |
wolfSSL | 15:117db924cf7c | 2648 | mp_clear(mu); |
wolfSSL | 15:117db924cf7c | 2649 | err = MEMORY_E; goto exit; |
wolfSSL | 15:117db924cf7c | 2650 | } |
wolfSSL | 15:117db924cf7c | 2651 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2652 | M[i]->key = &key; |
wolfSSL | 15:117db924cf7c | 2653 | #endif |
wolfSSL | 15:117db924cf7c | 2654 | } |
wolfSSL | 15:117db924cf7c | 2655 | |
wolfSSL | 15:117db924cf7c | 2656 | /* make a copy of G in case R==G */ |
wolfSSL | 15:117db924cf7c | 2657 | tG = wc_ecc_new_point_h(heap); |
wolfSSL | 15:117db924cf7c | 2658 | if (tG == NULL) |
wolfSSL | 15:117db924cf7c | 2659 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2660 | |
wolfSSL | 15:117db924cf7c | 2661 | /* tG = G and convert to montgomery */ |
wolfSSL | 15:117db924cf7c | 2662 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2663 | if (mp_cmp_d(mu, 1) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 2664 | err = mp_copy(G->x, tG->x); |
wolfSSL | 15:117db924cf7c | 2665 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2666 | err = mp_copy(G->y, tG->y); |
wolfSSL | 15:117db924cf7c | 2667 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2668 | err = mp_copy(G->z, tG->z); |
wolfSSL | 15:117db924cf7c | 2669 | } else { |
wolfSSL | 15:117db924cf7c | 2670 | err = mp_mulmod(G->x, mu, modulus, tG->x); |
wolfSSL | 15:117db924cf7c | 2671 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2672 | err = mp_mulmod(G->y, mu, modulus, tG->y); |
wolfSSL | 15:117db924cf7c | 2673 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2674 | err = mp_mulmod(G->z, mu, modulus, tG->z); |
wolfSSL | 15:117db924cf7c | 2675 | } |
wolfSSL | 15:117db924cf7c | 2676 | } |
wolfSSL | 15:117db924cf7c | 2677 | |
wolfSSL | 15:117db924cf7c | 2678 | /* done with mu */ |
wolfSSL | 15:117db924cf7c | 2679 | mp_clear(mu); |
wolfSSL | 15:117db924cf7c | 2680 | |
wolfSSL | 15:117db924cf7c | 2681 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2682 | R->key = &key; |
wolfSSL | 15:117db924cf7c | 2683 | #endif |
wolfSSL | 15:117db924cf7c | 2684 | #ifndef ECC_TIMING_RESISTANT |
wolfSSL | 15:117db924cf7c | 2685 | |
wolfSSL | 15:117db924cf7c | 2686 | /* calc the M tab, which holds kG for k==8..15 */ |
wolfSSL | 15:117db924cf7c | 2687 | /* M[0] == 8G */ |
wolfSSL | 15:117db924cf7c | 2688 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2689 | err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2690 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2691 | err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2692 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2693 | err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2694 | |
wolfSSL | 15:117db924cf7c | 2695 | /* now find (8+k)G for k=1..7 */ |
wolfSSL | 15:117db924cf7c | 2696 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2697 | for (j = 9; j < 16; j++) { |
wolfSSL | 16:8e0d178b1d1e | 2698 | err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus, |
wolfSSL | 16:8e0d178b1d1e | 2699 | mp); |
wolfSSL | 15:117db924cf7c | 2700 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2701 | } |
wolfSSL | 15:117db924cf7c | 2702 | |
wolfSSL | 15:117db924cf7c | 2703 | /* setup sliding window */ |
wolfSSL | 15:117db924cf7c | 2704 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2705 | mode = 0; |
wolfSSL | 15:117db924cf7c | 2706 | bitcnt = 1; |
wolfSSL | 15:117db924cf7c | 2707 | buf = 0; |
wolfSSL | 15:117db924cf7c | 2708 | digidx = get_digit_count(k) - 1; |
wolfSSL | 15:117db924cf7c | 2709 | bitcpy = bitbuf = 0; |
wolfSSL | 15:117db924cf7c | 2710 | first = 1; |
wolfSSL | 15:117db924cf7c | 2711 | |
wolfSSL | 15:117db924cf7c | 2712 | /* perform ops */ |
wolfSSL | 15:117db924cf7c | 2713 | for (;;) { |
wolfSSL | 15:117db924cf7c | 2714 | /* grab next digit as required */ |
wolfSSL | 15:117db924cf7c | 2715 | if (--bitcnt == 0) { |
wolfSSL | 15:117db924cf7c | 2716 | if (digidx == -1) { |
wolfSSL | 15:117db924cf7c | 2717 | break; |
wolfSSL | 15:117db924cf7c | 2718 | } |
wolfSSL | 15:117db924cf7c | 2719 | buf = get_digit(k, digidx); |
wolfSSL | 15:117db924cf7c | 2720 | bitcnt = (int) DIGIT_BIT; |
wolfSSL | 15:117db924cf7c | 2721 | --digidx; |
wolfSSL | 15:117db924cf7c | 2722 | } |
wolfSSL | 15:117db924cf7c | 2723 | |
wolfSSL | 15:117db924cf7c | 2724 | /* grab the next msb from the ltiplicand */ |
wolfSSL | 15:117db924cf7c | 2725 | i = (int)(buf >> (DIGIT_BIT - 1)) & 1; |
wolfSSL | 15:117db924cf7c | 2726 | buf <<= 1; |
wolfSSL | 15:117db924cf7c | 2727 | |
wolfSSL | 15:117db924cf7c | 2728 | /* skip leading zero bits */ |
wolfSSL | 15:117db924cf7c | 2729 | if (mode == 0 && i == 0) |
wolfSSL | 15:117db924cf7c | 2730 | continue; |
wolfSSL | 15:117db924cf7c | 2731 | |
wolfSSL | 15:117db924cf7c | 2732 | /* if the bit is zero and mode == 1 then we double */ |
wolfSSL | 15:117db924cf7c | 2733 | if (mode == 1 && i == 0) { |
wolfSSL | 15:117db924cf7c | 2734 | err = ecc_projective_dbl_point(R, R, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2735 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2736 | continue; |
wolfSSL | 15:117db924cf7c | 2737 | } |
wolfSSL | 15:117db924cf7c | 2738 | |
wolfSSL | 15:117db924cf7c | 2739 | /* else we add it to the window */ |
wolfSSL | 15:117db924cf7c | 2740 | bitbuf |= (i << (WINSIZE - ++bitcpy)); |
wolfSSL | 15:117db924cf7c | 2741 | mode = 2; |
wolfSSL | 15:117db924cf7c | 2742 | |
wolfSSL | 15:117db924cf7c | 2743 | if (bitcpy == WINSIZE) { |
wolfSSL | 15:117db924cf7c | 2744 | /* if this is the first window we do a simple copy */ |
wolfSSL | 15:117db924cf7c | 2745 | if (first == 1) { |
wolfSSL | 15:117db924cf7c | 2746 | /* R = kG [k = first window] */ |
wolfSSL | 15:117db924cf7c | 2747 | err = mp_copy(M[bitbuf-M_POINTS]->x, R->x); |
wolfSSL | 15:117db924cf7c | 2748 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2749 | |
wolfSSL | 15:117db924cf7c | 2750 | err = mp_copy(M[bitbuf-M_POINTS]->y, R->y); |
wolfSSL | 15:117db924cf7c | 2751 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2752 | |
wolfSSL | 15:117db924cf7c | 2753 | err = mp_copy(M[bitbuf-M_POINTS]->z, R->z); |
wolfSSL | 15:117db924cf7c | 2754 | first = 0; |
wolfSSL | 15:117db924cf7c | 2755 | } else { |
wolfSSL | 15:117db924cf7c | 2756 | /* normal window */ |
wolfSSL | 15:117db924cf7c | 2757 | /* ok window is filled so double as required and add */ |
wolfSSL | 15:117db924cf7c | 2758 | /* double first */ |
wolfSSL | 15:117db924cf7c | 2759 | for (j = 0; j < WINSIZE; j++) { |
wolfSSL | 15:117db924cf7c | 2760 | err = ecc_projective_dbl_point(R, R, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2761 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2762 | } |
wolfSSL | 15:117db924cf7c | 2763 | if (err != MP_OKAY) break; /* out of first for(;;) */ |
wolfSSL | 15:117db924cf7c | 2764 | |
wolfSSL | 15:117db924cf7c | 2765 | /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ |
wolfSSL | 15:117db924cf7c | 2766 | err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a, |
wolfSSL | 16:8e0d178b1d1e | 2767 | modulus, mp); |
wolfSSL | 15:117db924cf7c | 2768 | } |
wolfSSL | 15:117db924cf7c | 2769 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2770 | /* empty window and reset */ |
wolfSSL | 15:117db924cf7c | 2771 | bitcpy = bitbuf = 0; |
wolfSSL | 15:117db924cf7c | 2772 | mode = 1; |
wolfSSL | 15:117db924cf7c | 2773 | } |
wolfSSL | 15:117db924cf7c | 2774 | } |
wolfSSL | 15:117db924cf7c | 2775 | } |
wolfSSL | 15:117db924cf7c | 2776 | |
wolfSSL | 15:117db924cf7c | 2777 | /* if bits remain then double/add */ |
wolfSSL | 15:117db924cf7c | 2778 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2779 | if (mode == 2 && bitcpy > 0) { |
wolfSSL | 15:117db924cf7c | 2780 | /* double then add */ |
wolfSSL | 15:117db924cf7c | 2781 | for (j = 0; j < bitcpy; j++) { |
wolfSSL | 15:117db924cf7c | 2782 | /* only double if we have had at least one add first */ |
wolfSSL | 15:117db924cf7c | 2783 | if (first == 0) { |
wolfSSL | 15:117db924cf7c | 2784 | err = ecc_projective_dbl_point(R, R, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2785 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2786 | } |
wolfSSL | 15:117db924cf7c | 2787 | |
wolfSSL | 15:117db924cf7c | 2788 | bitbuf <<= 1; |
wolfSSL | 15:117db924cf7c | 2789 | if ((bitbuf & (1 << WINSIZE)) != 0) { |
wolfSSL | 15:117db924cf7c | 2790 | if (first == 1) { |
wolfSSL | 15:117db924cf7c | 2791 | /* first add, so copy */ |
wolfSSL | 15:117db924cf7c | 2792 | err = mp_copy(tG->x, R->x); |
wolfSSL | 15:117db924cf7c | 2793 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2794 | |
wolfSSL | 15:117db924cf7c | 2795 | err = mp_copy(tG->y, R->y); |
wolfSSL | 15:117db924cf7c | 2796 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2797 | |
wolfSSL | 15:117db924cf7c | 2798 | err = mp_copy(tG->z, R->z); |
wolfSSL | 15:117db924cf7c | 2799 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2800 | first = 0; |
wolfSSL | 15:117db924cf7c | 2801 | } else { |
wolfSSL | 15:117db924cf7c | 2802 | /* then add */ |
wolfSSL | 16:8e0d178b1d1e | 2803 | err = ecc_projective_add_point(R, tG, R, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2804 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 2805 | } |
wolfSSL | 15:117db924cf7c | 2806 | } |
wolfSSL | 15:117db924cf7c | 2807 | } |
wolfSSL | 15:117db924cf7c | 2808 | } |
wolfSSL | 15:117db924cf7c | 2809 | } |
wolfSSL | 15:117db924cf7c | 2810 | |
wolfSSL | 15:117db924cf7c | 2811 | #undef WINSIZE |
wolfSSL | 15:117db924cf7c | 2812 | |
wolfSSL | 15:117db924cf7c | 2813 | #else /* ECC_TIMING_RESISTANT */ |
wolfSSL | 15:117db924cf7c | 2814 | |
wolfSSL | 15:117db924cf7c | 2815 | /* calc the M tab */ |
wolfSSL | 15:117db924cf7c | 2816 | /* M[0] == G */ |
wolfSSL | 15:117db924cf7c | 2817 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2818 | err = mp_copy(tG->x, M[0]->x); |
wolfSSL | 15:117db924cf7c | 2819 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2820 | err = mp_copy(tG->y, M[0]->y); |
wolfSSL | 15:117db924cf7c | 2821 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2822 | err = mp_copy(tG->z, M[0]->z); |
wolfSSL | 15:117db924cf7c | 2823 | |
wolfSSL | 15:117db924cf7c | 2824 | /* M[1] == 2G */ |
wolfSSL | 15:117db924cf7c | 2825 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2826 | err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2827 | #ifdef WC_NO_CACHE_RESISTANT |
wolfSSL | 16:8e0d178b1d1e | 2828 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2829 | err = wc_ecc_copy_point(M[0], M[2]); |
wolfSSL | 16:8e0d178b1d1e | 2830 | #else |
wolfSSL | 16:8e0d178b1d1e | 2831 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2832 | err = wc_ecc_copy_point(M[0], M[3]); |
wolfSSL | 16:8e0d178b1d1e | 2833 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2834 | err = wc_ecc_copy_point(M[1], M[4]); |
wolfSSL | 16:8e0d178b1d1e | 2835 | #endif |
wolfSSL | 15:117db924cf7c | 2836 | |
wolfSSL | 15:117db924cf7c | 2837 | /* setup sliding window */ |
wolfSSL | 15:117db924cf7c | 2838 | mode = 0; |
wolfSSL | 15:117db924cf7c | 2839 | bitcnt = 1; |
wolfSSL | 15:117db924cf7c | 2840 | buf = 0; |
wolfSSL | 16:8e0d178b1d1e | 2841 | digidx = get_digit_count(modulus) - 1; |
wolfSSL | 16:8e0d178b1d1e | 2842 | /* The order MAY be 1 bit longer than the modulus. */ |
wolfSSL | 16:8e0d178b1d1e | 2843 | digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1)); |
wolfSSL | 15:117db924cf7c | 2844 | |
wolfSSL | 15:117db924cf7c | 2845 | /* perform ops */ |
wolfSSL | 15:117db924cf7c | 2846 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2847 | for (;;) { |
wolfSSL | 15:117db924cf7c | 2848 | /* grab next digit as required */ |
wolfSSL | 15:117db924cf7c | 2849 | if (--bitcnt == 0) { |
wolfSSL | 15:117db924cf7c | 2850 | if (digidx == -1) { |
wolfSSL | 15:117db924cf7c | 2851 | break; |
wolfSSL | 15:117db924cf7c | 2852 | } |
wolfSSL | 15:117db924cf7c | 2853 | buf = get_digit(k, digidx); |
wolfSSL | 15:117db924cf7c | 2854 | bitcnt = (int)DIGIT_BIT; |
wolfSSL | 15:117db924cf7c | 2855 | --digidx; |
wolfSSL | 15:117db924cf7c | 2856 | } |
wolfSSL | 15:117db924cf7c | 2857 | |
wolfSSL | 15:117db924cf7c | 2858 | /* grab the next msb from the multiplicand */ |
wolfSSL | 15:117db924cf7c | 2859 | i = (buf >> (DIGIT_BIT - 1)) & 1; |
wolfSSL | 15:117db924cf7c | 2860 | buf <<= 1; |
wolfSSL | 15:117db924cf7c | 2861 | |
wolfSSL | 16:8e0d178b1d1e | 2862 | #ifdef WC_NO_CACHE_RESISTANT |
wolfSSL | 16:8e0d178b1d1e | 2863 | if (mode == 0) { |
wolfSSL | 15:117db924cf7c | 2864 | /* timing resistant - dummy operations */ |
wolfSSL | 15:117db924cf7c | 2865 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2866 | err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus, |
wolfSSL | 15:117db924cf7c | 2867 | mp); |
wolfSSL | 15:117db924cf7c | 2868 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2869 | err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2870 | } |
wolfSSL | 16:8e0d178b1d1e | 2871 | else { |
wolfSSL | 15:117db924cf7c | 2872 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2873 | err = ecc_projective_add_point(M[0], M[1], M[i^1], a, |
wolfSSL | 16:8e0d178b1d1e | 2874 | modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2875 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2876 | err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2877 | } |
wolfSSL | 16:8e0d178b1d1e | 2878 | #else |
wolfSSL | 16:8e0d178b1d1e | 2879 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2880 | err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2881 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2882 | err = mp_cond_copy(M[2]->x, i, M[0]->x); |
wolfSSL | 16:8e0d178b1d1e | 2883 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2884 | err = mp_cond_copy(M[2]->y, i, M[0]->y); |
wolfSSL | 16:8e0d178b1d1e | 2885 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2886 | err = mp_cond_copy(M[2]->z, i, M[0]->z); |
wolfSSL | 16:8e0d178b1d1e | 2887 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2888 | err = mp_cond_copy(M[2]->x, i ^ 1, M[1]->x); |
wolfSSL | 16:8e0d178b1d1e | 2889 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2890 | err = mp_cond_copy(M[2]->y, i ^ 1, M[1]->y); |
wolfSSL | 16:8e0d178b1d1e | 2891 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2892 | err = mp_cond_copy(M[2]->z, i ^ 1, M[1]->z); |
wolfSSL | 15:117db924cf7c | 2893 | |
wolfSSL | 15:117db924cf7c | 2894 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2895 | err = mp_cond_copy(M[0]->x, i ^ 1, M[2]->x); |
wolfSSL | 15:117db924cf7c | 2896 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2897 | err = mp_cond_copy(M[0]->y, i ^ 1, M[2]->y); |
wolfSSL | 16:8e0d178b1d1e | 2898 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2899 | err = mp_cond_copy(M[0]->z, i ^ 1, M[2]->z); |
wolfSSL | 15:117db924cf7c | 2900 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2901 | err = mp_cond_copy(M[1]->x, i, M[2]->x); |
wolfSSL | 15:117db924cf7c | 2902 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2903 | err = mp_cond_copy(M[1]->y, i, M[2]->y); |
wolfSSL | 15:117db924cf7c | 2904 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2905 | err = mp_cond_copy(M[1]->z, i, M[2]->z); |
wolfSSL | 16:8e0d178b1d1e | 2906 | |
wolfSSL | 15:117db924cf7c | 2907 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2908 | err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 2909 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2910 | err = mp_cond_copy(M[2]->x, i ^ 1, M[0]->x); |
wolfSSL | 16:8e0d178b1d1e | 2911 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2912 | err = mp_cond_copy(M[2]->y, i ^ 1, M[0]->y); |
wolfSSL | 16:8e0d178b1d1e | 2913 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2914 | err = mp_cond_copy(M[2]->z, i ^ 1, M[0]->z); |
wolfSSL | 15:117db924cf7c | 2915 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2916 | err = mp_cond_copy(M[2]->x, i, M[1]->x); |
wolfSSL | 16:8e0d178b1d1e | 2917 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2918 | err = mp_cond_copy(M[2]->y, i, M[1]->y); |
wolfSSL | 16:8e0d178b1d1e | 2919 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2920 | err = mp_cond_copy(M[2]->z, i, M[1]->z); |
wolfSSL | 16:8e0d178b1d1e | 2921 | |
wolfSSL | 15:117db924cf7c | 2922 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2923 | err = mp_cond_copy(M[3]->x, (mode ^ 1) & i, M[0]->x); |
wolfSSL | 16:8e0d178b1d1e | 2924 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2925 | err = mp_cond_copy(M[3]->y, (mode ^ 1) & i, M[0]->y); |
wolfSSL | 16:8e0d178b1d1e | 2926 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2927 | err = mp_cond_copy(M[3]->z, (mode ^ 1) & i, M[0]->z); |
wolfSSL | 15:117db924cf7c | 2928 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2929 | err = mp_cond_copy(M[4]->x, (mode ^ 1) & i, M[1]->x); |
wolfSSL | 16:8e0d178b1d1e | 2930 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2931 | err = mp_cond_copy(M[4]->y, (mode ^ 1) & i, M[1]->y); |
wolfSSL | 16:8e0d178b1d1e | 2932 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 2933 | err = mp_cond_copy(M[4]->z, (mode ^ 1) & i, M[1]->z); |
wolfSSL | 16:8e0d178b1d1e | 2934 | #endif /* WC_NO_CACHE_RESISTANT */ |
wolfSSL | 16:8e0d178b1d1e | 2935 | |
wolfSSL | 15:117db924cf7c | 2936 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2937 | break; |
wolfSSL | 16:8e0d178b1d1e | 2938 | |
wolfSSL | 16:8e0d178b1d1e | 2939 | mode |= i; |
wolfSSL | 15:117db924cf7c | 2940 | } /* end for */ |
wolfSSL | 15:117db924cf7c | 2941 | } |
wolfSSL | 15:117db924cf7c | 2942 | |
wolfSSL | 15:117db924cf7c | 2943 | /* copy result out */ |
wolfSSL | 15:117db924cf7c | 2944 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2945 | err = mp_copy(M[0]->x, R->x); |
wolfSSL | 15:117db924cf7c | 2946 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2947 | err = mp_copy(M[0]->y, R->y); |
wolfSSL | 15:117db924cf7c | 2948 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2949 | err = mp_copy(M[0]->z, R->z); |
wolfSSL | 15:117db924cf7c | 2950 | |
wolfSSL | 15:117db924cf7c | 2951 | #endif /* ECC_TIMING_RESISTANT */ |
wolfSSL | 15:117db924cf7c | 2952 | |
wolfSSL | 15:117db924cf7c | 2953 | /* map R back from projective space */ |
wolfSSL | 15:117db924cf7c | 2954 | if (err == MP_OKAY && map) |
wolfSSL | 15:117db924cf7c | 2955 | err = ecc_map(R, modulus, mp); |
wolfSSL | 15:117db924cf7c | 2956 | |
wolfSSL | 15:117db924cf7c | 2957 | exit: |
wolfSSL | 15:117db924cf7c | 2958 | |
wolfSSL | 15:117db924cf7c | 2959 | /* done */ |
wolfSSL | 15:117db924cf7c | 2960 | wc_ecc_del_point_h(tG, heap); |
wolfSSL | 15:117db924cf7c | 2961 | for (i = 0; i < M_POINTS; i++) { |
wolfSSL | 15:117db924cf7c | 2962 | wc_ecc_del_point_h(M[i], heap); |
wolfSSL | 15:117db924cf7c | 2963 | } |
wolfSSL | 15:117db924cf7c | 2964 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 2965 | R->key = NULL; |
wolfSSL | 15:117db924cf7c | 2966 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 2967 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2968 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2969 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2970 | #endif |
wolfSSL | 15:117db924cf7c | 2971 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2972 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2973 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 2974 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 2975 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 2976 | #endif |
wolfSSL | 15:117db924cf7c | 2977 | |
wolfSSL | 15:117db924cf7c | 2978 | return err; |
wolfSSL | 15:117db924cf7c | 2979 | #else |
wolfSSL | 15:117db924cf7c | 2980 | if (k == NULL || G == NULL || R == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 2981 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2982 | } |
wolfSSL | 15:117db924cf7c | 2983 | |
wolfSSL | 15:117db924cf7c | 2984 | (void)a; |
wolfSSL | 15:117db924cf7c | 2985 | |
wolfSSL | 16:8e0d178b1d1e | 2986 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 2987 | if (mp_count_bits(modulus) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 2988 | return sp_ecc_mulmod_256(k, G, R, map, heap); |
wolfSSL | 16:8e0d178b1d1e | 2989 | } |
wolfSSL | 16:8e0d178b1d1e | 2990 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2991 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 2992 | if (mp_count_bits(modulus) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 2993 | return sp_ecc_mulmod_384(k, G, R, map, heap); |
wolfSSL | 16:8e0d178b1d1e | 2994 | } |
wolfSSL | 16:8e0d178b1d1e | 2995 | #endif |
wolfSSL | 16:8e0d178b1d1e | 2996 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 2997 | #endif |
wolfSSL | 15:117db924cf7c | 2998 | } |
wolfSSL | 15:117db924cf7c | 2999 | |
wolfSSL | 15:117db924cf7c | 3000 | #endif /* !FP_ECC || !WOLFSSL_SP_MATH */ |
wolfSSL | 15:117db924cf7c | 3001 | |
wolfSSL | 16:8e0d178b1d1e | 3002 | #endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */ |
wolfSSL | 15:117db924cf7c | 3003 | |
wolfSSL | 15:117db924cf7c | 3004 | /** ECC Fixed Point mulmod global |
wolfSSL | 15:117db924cf7c | 3005 | k The multiplicand |
wolfSSL | 15:117db924cf7c | 3006 | G Base point to multiply |
wolfSSL | 15:117db924cf7c | 3007 | R [out] Destination of product |
wolfSSL | 15:117db924cf7c | 3008 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 3009 | modulus The modulus for the curve |
wolfSSL | 16:8e0d178b1d1e | 3010 | map [boolean] If non-zero maps the point back to affine coordinates, |
wolfSSL | 15:117db924cf7c | 3011 | otherwise it's left in jacobian-montgomery form |
wolfSSL | 15:117db924cf7c | 3012 | return MP_OKAY if successful |
wolfSSL | 15:117db924cf7c | 3013 | */ |
wolfSSL | 15:117db924cf7c | 3014 | int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, |
wolfSSL | 15:117db924cf7c | 3015 | mp_int* modulus, int map) |
wolfSSL | 15:117db924cf7c | 3016 | { |
wolfSSL | 15:117db924cf7c | 3017 | return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL); |
wolfSSL | 15:117db924cf7c | 3018 | } |
wolfSSL | 15:117db924cf7c | 3019 | |
wolfSSL | 15:117db924cf7c | 3020 | #endif /* !WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 3021 | |
wolfSSL | 15:117db924cf7c | 3022 | /** |
wolfSSL | 15:117db924cf7c | 3023 | * use a heap hint when creating new ecc_point |
wolfSSL | 15:117db924cf7c | 3024 | * return an allocated point on success or NULL on failure |
wolfSSL | 15:117db924cf7c | 3025 | */ |
wolfSSL | 15:117db924cf7c | 3026 | ecc_point* wc_ecc_new_point_h(void* heap) |
wolfSSL | 15:117db924cf7c | 3027 | { |
wolfSSL | 15:117db924cf7c | 3028 | ecc_point* p; |
wolfSSL | 15:117db924cf7c | 3029 | |
wolfSSL | 15:117db924cf7c | 3030 | (void)heap; |
wolfSSL | 15:117db924cf7c | 3031 | |
wolfSSL | 15:117db924cf7c | 3032 | p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3033 | if (p == NULL) { |
wolfSSL | 15:117db924cf7c | 3034 | return NULL; |
wolfSSL | 15:117db924cf7c | 3035 | } |
wolfSSL | 15:117db924cf7c | 3036 | XMEMSET(p, 0, sizeof(ecc_point)); |
wolfSSL | 15:117db924cf7c | 3037 | |
wolfSSL | 15:117db924cf7c | 3038 | #ifndef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 3039 | if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3040 | XFREE(p, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3041 | return NULL; |
wolfSSL | 15:117db924cf7c | 3042 | } |
wolfSSL | 15:117db924cf7c | 3043 | #else |
wolfSSL | 15:117db924cf7c | 3044 | p->x = (mp_int*)&p->xyz[0]; |
wolfSSL | 15:117db924cf7c | 3045 | p->y = (mp_int*)&p->xyz[1]; |
wolfSSL | 15:117db924cf7c | 3046 | p->z = (mp_int*)&p->xyz[2]; |
wolfSSL | 15:117db924cf7c | 3047 | alt_fp_init(p->x); |
wolfSSL | 15:117db924cf7c | 3048 | alt_fp_init(p->y); |
wolfSSL | 15:117db924cf7c | 3049 | alt_fp_init(p->z); |
wolfSSL | 15:117db924cf7c | 3050 | #endif |
wolfSSL | 15:117db924cf7c | 3051 | |
wolfSSL | 15:117db924cf7c | 3052 | return p; |
wolfSSL | 15:117db924cf7c | 3053 | } |
wolfSSL | 15:117db924cf7c | 3054 | |
wolfSSL | 15:117db924cf7c | 3055 | |
wolfSSL | 15:117db924cf7c | 3056 | /** |
wolfSSL | 15:117db924cf7c | 3057 | Allocate a new ECC point |
wolfSSL | 15:117db924cf7c | 3058 | return A newly allocated point or NULL on error |
wolfSSL | 15:117db924cf7c | 3059 | */ |
wolfSSL | 15:117db924cf7c | 3060 | ecc_point* wc_ecc_new_point(void) |
wolfSSL | 15:117db924cf7c | 3061 | { |
wolfSSL | 15:117db924cf7c | 3062 | return wc_ecc_new_point_h(NULL); |
wolfSSL | 15:117db924cf7c | 3063 | } |
wolfSSL | 15:117db924cf7c | 3064 | |
wolfSSL | 15:117db924cf7c | 3065 | |
wolfSSL | 15:117db924cf7c | 3066 | void wc_ecc_del_point_h(ecc_point* p, void* heap) |
wolfSSL | 15:117db924cf7c | 3067 | { |
wolfSSL | 15:117db924cf7c | 3068 | /* prevents free'ing null arguments */ |
wolfSSL | 15:117db924cf7c | 3069 | if (p != NULL) { |
wolfSSL | 15:117db924cf7c | 3070 | mp_clear(p->x); |
wolfSSL | 15:117db924cf7c | 3071 | mp_clear(p->y); |
wolfSSL | 15:117db924cf7c | 3072 | mp_clear(p->z); |
wolfSSL | 15:117db924cf7c | 3073 | XFREE(p, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3074 | } |
wolfSSL | 15:117db924cf7c | 3075 | (void)heap; |
wolfSSL | 15:117db924cf7c | 3076 | } |
wolfSSL | 15:117db924cf7c | 3077 | |
wolfSSL | 15:117db924cf7c | 3078 | |
wolfSSL | 15:117db924cf7c | 3079 | /** Free an ECC point from memory |
wolfSSL | 15:117db924cf7c | 3080 | p The point to free |
wolfSSL | 15:117db924cf7c | 3081 | */ |
wolfSSL | 15:117db924cf7c | 3082 | void wc_ecc_del_point(ecc_point* p) |
wolfSSL | 15:117db924cf7c | 3083 | { |
wolfSSL | 15:117db924cf7c | 3084 | wc_ecc_del_point_h(p, NULL); |
wolfSSL | 15:117db924cf7c | 3085 | } |
wolfSSL | 15:117db924cf7c | 3086 | |
wolfSSL | 15:117db924cf7c | 3087 | |
wolfSSL | 15:117db924cf7c | 3088 | /** Copy the value of a point to an other one |
wolfSSL | 15:117db924cf7c | 3089 | p The point to copy |
wolfSSL | 15:117db924cf7c | 3090 | r The created point |
wolfSSL | 15:117db924cf7c | 3091 | */ |
wolfSSL | 15:117db924cf7c | 3092 | int wc_ecc_copy_point(ecc_point* p, ecc_point *r) |
wolfSSL | 15:117db924cf7c | 3093 | { |
wolfSSL | 15:117db924cf7c | 3094 | int ret; |
wolfSSL | 15:117db924cf7c | 3095 | |
wolfSSL | 15:117db924cf7c | 3096 | /* prevents null arguments */ |
wolfSSL | 15:117db924cf7c | 3097 | if (p == NULL || r == NULL) |
wolfSSL | 15:117db924cf7c | 3098 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3099 | |
wolfSSL | 15:117db924cf7c | 3100 | ret = mp_copy(p->x, r->x); |
wolfSSL | 15:117db924cf7c | 3101 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3102 | return ret; |
wolfSSL | 15:117db924cf7c | 3103 | ret = mp_copy(p->y, r->y); |
wolfSSL | 15:117db924cf7c | 3104 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3105 | return ret; |
wolfSSL | 15:117db924cf7c | 3106 | ret = mp_copy(p->z, r->z); |
wolfSSL | 15:117db924cf7c | 3107 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3108 | return ret; |
wolfSSL | 15:117db924cf7c | 3109 | |
wolfSSL | 15:117db924cf7c | 3110 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 3111 | } |
wolfSSL | 15:117db924cf7c | 3112 | |
wolfSSL | 15:117db924cf7c | 3113 | /** Compare the value of a point with an other one |
wolfSSL | 15:117db924cf7c | 3114 | a The point to compare |
wolfSSL | 15:117db924cf7c | 3115 | b The other point to compare |
wolfSSL | 15:117db924cf7c | 3116 | |
wolfSSL | 15:117db924cf7c | 3117 | return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error |
wolfSSL | 15:117db924cf7c | 3118 | */ |
wolfSSL | 15:117db924cf7c | 3119 | int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) |
wolfSSL | 15:117db924cf7c | 3120 | { |
wolfSSL | 15:117db924cf7c | 3121 | int ret; |
wolfSSL | 15:117db924cf7c | 3122 | |
wolfSSL | 15:117db924cf7c | 3123 | /* prevents null arguments */ |
wolfSSL | 15:117db924cf7c | 3124 | if (a == NULL || b == NULL) |
wolfSSL | 15:117db924cf7c | 3125 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3126 | |
wolfSSL | 15:117db924cf7c | 3127 | ret = mp_cmp(a->x, b->x); |
wolfSSL | 15:117db924cf7c | 3128 | if (ret != MP_EQ) |
wolfSSL | 15:117db924cf7c | 3129 | return ret; |
wolfSSL | 15:117db924cf7c | 3130 | ret = mp_cmp(a->y, b->y); |
wolfSSL | 15:117db924cf7c | 3131 | if (ret != MP_EQ) |
wolfSSL | 15:117db924cf7c | 3132 | return ret; |
wolfSSL | 15:117db924cf7c | 3133 | ret = mp_cmp(a->z, b->z); |
wolfSSL | 15:117db924cf7c | 3134 | if (ret != MP_EQ) |
wolfSSL | 15:117db924cf7c | 3135 | return ret; |
wolfSSL | 15:117db924cf7c | 3136 | |
wolfSSL | 15:117db924cf7c | 3137 | return MP_EQ; |
wolfSSL | 15:117db924cf7c | 3138 | } |
wolfSSL | 15:117db924cf7c | 3139 | |
wolfSSL | 15:117db924cf7c | 3140 | |
wolfSSL | 15:117db924cf7c | 3141 | /** Returns whether an ECC idx is valid or not |
wolfSSL | 15:117db924cf7c | 3142 | n The idx number to check |
wolfSSL | 15:117db924cf7c | 3143 | return 1 if valid, 0 if not |
wolfSSL | 15:117db924cf7c | 3144 | */ |
wolfSSL | 15:117db924cf7c | 3145 | int wc_ecc_is_valid_idx(int n) |
wolfSSL | 15:117db924cf7c | 3146 | { |
wolfSSL | 15:117db924cf7c | 3147 | int x; |
wolfSSL | 15:117db924cf7c | 3148 | |
wolfSSL | 15:117db924cf7c | 3149 | for (x = 0; ecc_sets[x].size != 0; x++) |
wolfSSL | 15:117db924cf7c | 3150 | ; |
wolfSSL | 15:117db924cf7c | 3151 | /* -1 is a valid index --- indicating that the domain params |
wolfSSL | 15:117db924cf7c | 3152 | were supplied by the user */ |
wolfSSL | 15:117db924cf7c | 3153 | if ((n >= ECC_CUSTOM_IDX) && (n < x)) { |
wolfSSL | 15:117db924cf7c | 3154 | return 1; |
wolfSSL | 15:117db924cf7c | 3155 | } |
wolfSSL | 15:117db924cf7c | 3156 | |
wolfSSL | 15:117db924cf7c | 3157 | return 0; |
wolfSSL | 15:117db924cf7c | 3158 | } |
wolfSSL | 15:117db924cf7c | 3159 | |
wolfSSL | 15:117db924cf7c | 3160 | int wc_ecc_get_curve_idx(int curve_id) |
wolfSSL | 15:117db924cf7c | 3161 | { |
wolfSSL | 15:117db924cf7c | 3162 | int curve_idx; |
wolfSSL | 15:117db924cf7c | 3163 | for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { |
wolfSSL | 15:117db924cf7c | 3164 | if (curve_id == ecc_sets[curve_idx].id) |
wolfSSL | 15:117db924cf7c | 3165 | break; |
wolfSSL | 15:117db924cf7c | 3166 | } |
wolfSSL | 15:117db924cf7c | 3167 | if (ecc_sets[curve_idx].size == 0) { |
wolfSSL | 15:117db924cf7c | 3168 | return ECC_CURVE_INVALID; |
wolfSSL | 15:117db924cf7c | 3169 | } |
wolfSSL | 15:117db924cf7c | 3170 | return curve_idx; |
wolfSSL | 15:117db924cf7c | 3171 | } |
wolfSSL | 15:117db924cf7c | 3172 | |
wolfSSL | 15:117db924cf7c | 3173 | int wc_ecc_get_curve_id(int curve_idx) |
wolfSSL | 15:117db924cf7c | 3174 | { |
wolfSSL | 15:117db924cf7c | 3175 | if (wc_ecc_is_valid_idx(curve_idx)) { |
wolfSSL | 15:117db924cf7c | 3176 | return ecc_sets[curve_idx].id; |
wolfSSL | 15:117db924cf7c | 3177 | } |
wolfSSL | 15:117db924cf7c | 3178 | return ECC_CURVE_INVALID; |
wolfSSL | 15:117db924cf7c | 3179 | } |
wolfSSL | 15:117db924cf7c | 3180 | |
wolfSSL | 15:117db924cf7c | 3181 | /* Returns the curve size that corresponds to a given ecc_curve_id identifier |
wolfSSL | 15:117db924cf7c | 3182 | * |
wolfSSL | 15:117db924cf7c | 3183 | * id curve id, from ecc_curve_id enum in ecc.h |
wolfSSL | 15:117db924cf7c | 3184 | * return curve size, from ecc_sets[] on success, negative on error |
wolfSSL | 15:117db924cf7c | 3185 | */ |
wolfSSL | 15:117db924cf7c | 3186 | int wc_ecc_get_curve_size_from_id(int curve_id) |
wolfSSL | 15:117db924cf7c | 3187 | { |
wolfSSL | 15:117db924cf7c | 3188 | int curve_idx = wc_ecc_get_curve_idx(curve_id); |
wolfSSL | 15:117db924cf7c | 3189 | if (curve_idx == ECC_CURVE_INVALID) |
wolfSSL | 15:117db924cf7c | 3190 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3191 | return ecc_sets[curve_idx].size; |
wolfSSL | 15:117db924cf7c | 3192 | } |
wolfSSL | 15:117db924cf7c | 3193 | |
wolfSSL | 15:117db924cf7c | 3194 | /* Returns the curve index that corresponds to a given curve name in |
wolfSSL | 15:117db924cf7c | 3195 | * ecc_sets[] of ecc.c |
wolfSSL | 15:117db924cf7c | 3196 | * |
wolfSSL | 15:117db924cf7c | 3197 | * name curve name, from ecc_sets[].name in ecc.c |
wolfSSL | 15:117db924cf7c | 3198 | * return curve index in ecc_sets[] on success, negative on error |
wolfSSL | 15:117db924cf7c | 3199 | */ |
wolfSSL | 15:117db924cf7c | 3200 | int wc_ecc_get_curve_idx_from_name(const char* curveName) |
wolfSSL | 15:117db924cf7c | 3201 | { |
wolfSSL | 15:117db924cf7c | 3202 | int curve_idx; |
wolfSSL | 15:117db924cf7c | 3203 | word32 len; |
wolfSSL | 15:117db924cf7c | 3204 | |
wolfSSL | 15:117db924cf7c | 3205 | if (curveName == NULL) |
wolfSSL | 15:117db924cf7c | 3206 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3207 | |
wolfSSL | 15:117db924cf7c | 3208 | len = (word32)XSTRLEN(curveName); |
wolfSSL | 15:117db924cf7c | 3209 | |
wolfSSL | 15:117db924cf7c | 3210 | for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { |
wolfSSL | 16:8e0d178b1d1e | 3211 | if ( |
wolfSSL | 16:8e0d178b1d1e | 3212 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 16:8e0d178b1d1e | 3213 | ecc_sets[curve_idx].name && |
wolfSSL | 16:8e0d178b1d1e | 3214 | #endif |
wolfSSL | 15:117db924cf7c | 3215 | XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) { |
wolfSSL | 15:117db924cf7c | 3216 | break; |
wolfSSL | 15:117db924cf7c | 3217 | } |
wolfSSL | 15:117db924cf7c | 3218 | } |
wolfSSL | 15:117db924cf7c | 3219 | if (ecc_sets[curve_idx].size == 0) { |
wolfSSL | 15:117db924cf7c | 3220 | WOLFSSL_MSG("ecc_set curve name not found"); |
wolfSSL | 15:117db924cf7c | 3221 | return ECC_CURVE_INVALID; |
wolfSSL | 15:117db924cf7c | 3222 | } |
wolfSSL | 15:117db924cf7c | 3223 | return curve_idx; |
wolfSSL | 15:117db924cf7c | 3224 | } |
wolfSSL | 15:117db924cf7c | 3225 | |
wolfSSL | 15:117db924cf7c | 3226 | /* Returns the curve size that corresponds to a given curve name, |
wolfSSL | 15:117db924cf7c | 3227 | * as listed in ecc_sets[] of ecc.c. |
wolfSSL | 15:117db924cf7c | 3228 | * |
wolfSSL | 15:117db924cf7c | 3229 | * name curve name, from ecc_sets[].name in ecc.c |
wolfSSL | 15:117db924cf7c | 3230 | * return curve size, from ecc_sets[] on success, negative on error |
wolfSSL | 15:117db924cf7c | 3231 | */ |
wolfSSL | 15:117db924cf7c | 3232 | int wc_ecc_get_curve_size_from_name(const char* curveName) |
wolfSSL | 15:117db924cf7c | 3233 | { |
wolfSSL | 15:117db924cf7c | 3234 | int curve_idx; |
wolfSSL | 15:117db924cf7c | 3235 | |
wolfSSL | 15:117db924cf7c | 3236 | if (curveName == NULL) |
wolfSSL | 15:117db924cf7c | 3237 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3238 | |
wolfSSL | 15:117db924cf7c | 3239 | curve_idx = wc_ecc_get_curve_idx_from_name(curveName); |
wolfSSL | 15:117db924cf7c | 3240 | if (curve_idx < 0) |
wolfSSL | 15:117db924cf7c | 3241 | return curve_idx; |
wolfSSL | 15:117db924cf7c | 3242 | |
wolfSSL | 15:117db924cf7c | 3243 | return ecc_sets[curve_idx].size; |
wolfSSL | 15:117db924cf7c | 3244 | } |
wolfSSL | 15:117db924cf7c | 3245 | |
wolfSSL | 15:117db924cf7c | 3246 | /* Returns the curve id that corresponds to a given curve name, |
wolfSSL | 15:117db924cf7c | 3247 | * as listed in ecc_sets[] of ecc.c. |
wolfSSL | 15:117db924cf7c | 3248 | * |
wolfSSL | 15:117db924cf7c | 3249 | * name curve name, from ecc_sets[].name in ecc.c |
wolfSSL | 15:117db924cf7c | 3250 | * return curve id, from ecc_sets[] on success, negative on error |
wolfSSL | 15:117db924cf7c | 3251 | */ |
wolfSSL | 15:117db924cf7c | 3252 | int wc_ecc_get_curve_id_from_name(const char* curveName) |
wolfSSL | 15:117db924cf7c | 3253 | { |
wolfSSL | 15:117db924cf7c | 3254 | int curve_idx; |
wolfSSL | 15:117db924cf7c | 3255 | |
wolfSSL | 15:117db924cf7c | 3256 | if (curveName == NULL) |
wolfSSL | 15:117db924cf7c | 3257 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3258 | |
wolfSSL | 15:117db924cf7c | 3259 | curve_idx = wc_ecc_get_curve_idx_from_name(curveName); |
wolfSSL | 15:117db924cf7c | 3260 | if (curve_idx < 0) |
wolfSSL | 15:117db924cf7c | 3261 | return curve_idx; |
wolfSSL | 15:117db924cf7c | 3262 | |
wolfSSL | 15:117db924cf7c | 3263 | return ecc_sets[curve_idx].id; |
wolfSSL | 15:117db924cf7c | 3264 | } |
wolfSSL | 15:117db924cf7c | 3265 | |
wolfSSL | 15:117db924cf7c | 3266 | /* Compares a curve parameter (hex, from ecc_sets[]) to given input |
wolfSSL | 16:8e0d178b1d1e | 3267 | * parameter for equality. |
wolfSSL | 16:8e0d178b1d1e | 3268 | * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR |
wolfSSL | 15:117db924cf7c | 3269 | * Returns MP_EQ on success, negative on error */ |
wolfSSL | 15:117db924cf7c | 3270 | static int wc_ecc_cmp_param(const char* curveParam, |
wolfSSL | 16:8e0d178b1d1e | 3271 | const byte* param, word32 paramSz, int encType) |
wolfSSL | 15:117db924cf7c | 3272 | { |
wolfSSL | 15:117db924cf7c | 3273 | int err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 3274 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 3275 | mp_int* a = NULL; |
wolfSSL | 15:117db924cf7c | 3276 | mp_int* b = NULL; |
wolfSSL | 15:117db924cf7c | 3277 | #else |
wolfSSL | 15:117db924cf7c | 3278 | mp_int a[1], b[1]; |
wolfSSL | 15:117db924cf7c | 3279 | #endif |
wolfSSL | 15:117db924cf7c | 3280 | |
wolfSSL | 15:117db924cf7c | 3281 | if (param == NULL || curveParam == NULL) |
wolfSSL | 15:117db924cf7c | 3282 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3283 | |
wolfSSL | 16:8e0d178b1d1e | 3284 | if (encType == WC_TYPE_HEX_STR) |
wolfSSL | 16:8e0d178b1d1e | 3285 | return XSTRNCMP(curveParam, (char*) param, paramSz); |
wolfSSL | 16:8e0d178b1d1e | 3286 | |
wolfSSL | 15:117db924cf7c | 3287 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 3288 | a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3289 | if (a == NULL) |
wolfSSL | 15:117db924cf7c | 3290 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 3291 | b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3292 | if (b == NULL) { |
wolfSSL | 15:117db924cf7c | 3293 | XFREE(a, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3294 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 3295 | } |
wolfSSL | 15:117db924cf7c | 3296 | #endif |
wolfSSL | 15:117db924cf7c | 3297 | |
wolfSSL | 16:8e0d178b1d1e | 3298 | if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 3299 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 3300 | XFREE(a, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 3301 | XFREE(b, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 3302 | #endif |
wolfSSL | 15:117db924cf7c | 3303 | return err; |
wolfSSL | 16:8e0d178b1d1e | 3304 | } |
wolfSSL | 16:8e0d178b1d1e | 3305 | |
wolfSSL | 16:8e0d178b1d1e | 3306 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3307 | err = mp_read_unsigned_bin(a, param, paramSz); |
wolfSSL | 16:8e0d178b1d1e | 3308 | } |
wolfSSL | 15:117db924cf7c | 3309 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3310 | err = mp_read_radix(b, curveParam, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 3311 | |
wolfSSL | 15:117db924cf7c | 3312 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3313 | if (mp_cmp(a, b) != MP_EQ) { |
wolfSSL | 15:117db924cf7c | 3314 | err = -1; |
wolfSSL | 15:117db924cf7c | 3315 | } else { |
wolfSSL | 15:117db924cf7c | 3316 | err = MP_EQ; |
wolfSSL | 15:117db924cf7c | 3317 | } |
wolfSSL | 15:117db924cf7c | 3318 | } |
wolfSSL | 15:117db924cf7c | 3319 | |
wolfSSL | 15:117db924cf7c | 3320 | mp_clear(a); |
wolfSSL | 15:117db924cf7c | 3321 | mp_clear(b); |
wolfSSL | 15:117db924cf7c | 3322 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 3323 | XFREE(b, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3324 | XFREE(a, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 3325 | #endif |
wolfSSL | 15:117db924cf7c | 3326 | |
wolfSSL | 15:117db924cf7c | 3327 | return err; |
wolfSSL | 15:117db924cf7c | 3328 | } |
wolfSSL | 15:117db924cf7c | 3329 | |
wolfSSL | 15:117db924cf7c | 3330 | /* Returns the curve id in ecc_sets[] that corresponds to a given set of |
wolfSSL | 15:117db924cf7c | 3331 | * curve parameters. |
wolfSSL | 15:117db924cf7c | 3332 | * |
wolfSSL | 15:117db924cf7c | 3333 | * fieldSize the field size in bits |
wolfSSL | 15:117db924cf7c | 3334 | * prime prime of the finite field |
wolfSSL | 15:117db924cf7c | 3335 | * primeSz size of prime in octets |
wolfSSL | 15:117db924cf7c | 3336 | * Af first coefficient a of the curve |
wolfSSL | 15:117db924cf7c | 3337 | * AfSz size of Af in octets |
wolfSSL | 15:117db924cf7c | 3338 | * Bf second coefficient b of the curve |
wolfSSL | 15:117db924cf7c | 3339 | * BfSz size of Bf in octets |
wolfSSL | 15:117db924cf7c | 3340 | * order curve order |
wolfSSL | 15:117db924cf7c | 3341 | * orderSz size of curve in octets |
wolfSSL | 15:117db924cf7c | 3342 | * Gx affine x coordinate of base point |
wolfSSL | 15:117db924cf7c | 3343 | * GxSz size of Gx in octets |
wolfSSL | 15:117db924cf7c | 3344 | * Gy affine y coordinate of base point |
wolfSSL | 15:117db924cf7c | 3345 | * GySz size of Gy in octets |
wolfSSL | 15:117db924cf7c | 3346 | * cofactor curve cofactor |
wolfSSL | 15:117db924cf7c | 3347 | * |
wolfSSL | 15:117db924cf7c | 3348 | * return curve id, from ecc_sets[] on success, negative on error |
wolfSSL | 15:117db924cf7c | 3349 | */ |
wolfSSL | 15:117db924cf7c | 3350 | int wc_ecc_get_curve_id_from_params(int fieldSize, |
wolfSSL | 15:117db924cf7c | 3351 | const byte* prime, word32 primeSz, const byte* Af, word32 AfSz, |
wolfSSL | 15:117db924cf7c | 3352 | const byte* Bf, word32 BfSz, const byte* order, word32 orderSz, |
wolfSSL | 15:117db924cf7c | 3353 | const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor) |
wolfSSL | 15:117db924cf7c | 3354 | { |
wolfSSL | 15:117db924cf7c | 3355 | int idx; |
wolfSSL | 15:117db924cf7c | 3356 | int curveSz; |
wolfSSL | 15:117db924cf7c | 3357 | |
wolfSSL | 15:117db924cf7c | 3358 | if (prime == NULL || Af == NULL || Bf == NULL || order == NULL || |
wolfSSL | 15:117db924cf7c | 3359 | Gx == NULL || Gy == NULL) |
wolfSSL | 15:117db924cf7c | 3360 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3361 | |
wolfSSL | 15:117db924cf7c | 3362 | curveSz = (fieldSize + 1) / 8; /* round up */ |
wolfSSL | 15:117db924cf7c | 3363 | |
wolfSSL | 15:117db924cf7c | 3364 | for (idx = 0; ecc_sets[idx].size != 0; idx++) { |
wolfSSL | 15:117db924cf7c | 3365 | if (curveSz == ecc_sets[idx].size) { |
wolfSSL | 15:117db924cf7c | 3366 | if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime, |
wolfSSL | 16:8e0d178b1d1e | 3367 | primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3368 | (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz, |
wolfSSL | 16:8e0d178b1d1e | 3369 | WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3370 | (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz, |
wolfSSL | 16:8e0d178b1d1e | 3371 | WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 15:117db924cf7c | 3372 | (wc_ecc_cmp_param(ecc_sets[idx].order, order, |
wolfSSL | 16:8e0d178b1d1e | 3373 | orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3374 | (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz, |
wolfSSL | 16:8e0d178b1d1e | 3375 | WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3376 | (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz, |
wolfSSL | 16:8e0d178b1d1e | 3377 | WC_TYPE_UNSIGNED_BIN) == MP_EQ) && |
wolfSSL | 15:117db924cf7c | 3378 | (cofactor == ecc_sets[idx].cofactor)) { |
wolfSSL | 15:117db924cf7c | 3379 | break; |
wolfSSL | 15:117db924cf7c | 3380 | } |
wolfSSL | 15:117db924cf7c | 3381 | } |
wolfSSL | 15:117db924cf7c | 3382 | } |
wolfSSL | 15:117db924cf7c | 3383 | |
wolfSSL | 15:117db924cf7c | 3384 | if (ecc_sets[idx].size == 0) |
wolfSSL | 15:117db924cf7c | 3385 | return ECC_CURVE_INVALID; |
wolfSSL | 15:117db924cf7c | 3386 | |
wolfSSL | 15:117db924cf7c | 3387 | return ecc_sets[idx].id; |
wolfSSL | 15:117db924cf7c | 3388 | } |
wolfSSL | 15:117db924cf7c | 3389 | |
wolfSSL | 16:8e0d178b1d1e | 3390 | /* Returns the curve id in ecc_sets[] that corresponds |
wolfSSL | 16:8e0d178b1d1e | 3391 | * to a given domain parameters pointer. |
wolfSSL | 16:8e0d178b1d1e | 3392 | * |
wolfSSL | 16:8e0d178b1d1e | 3393 | * dp domain parameters pointer |
wolfSSL | 16:8e0d178b1d1e | 3394 | * |
wolfSSL | 16:8e0d178b1d1e | 3395 | * return curve id, from ecc_sets[] on success, negative on error |
wolfSSL | 16:8e0d178b1d1e | 3396 | */ |
wolfSSL | 16:8e0d178b1d1e | 3397 | int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp) |
wolfSSL | 16:8e0d178b1d1e | 3398 | { |
wolfSSL | 16:8e0d178b1d1e | 3399 | int idx; |
wolfSSL | 16:8e0d178b1d1e | 3400 | |
wolfSSL | 16:8e0d178b1d1e | 3401 | if (dp == NULL |
wolfSSL | 16:8e0d178b1d1e | 3402 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 16:8e0d178b1d1e | 3403 | || dp->prime == NULL || dp->Af == NULL || |
wolfSSL | 16:8e0d178b1d1e | 3404 | dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL |
wolfSSL | 16:8e0d178b1d1e | 3405 | #endif |
wolfSSL | 16:8e0d178b1d1e | 3406 | ) { |
wolfSSL | 16:8e0d178b1d1e | 3407 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 3408 | } |
wolfSSL | 16:8e0d178b1d1e | 3409 | |
wolfSSL | 16:8e0d178b1d1e | 3410 | for (idx = 0; ecc_sets[idx].size != 0; idx++) { |
wolfSSL | 16:8e0d178b1d1e | 3411 | if (dp->size == ecc_sets[idx].size) { |
wolfSSL | 16:8e0d178b1d1e | 3412 | if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime, |
wolfSSL | 16:8e0d178b1d1e | 3413 | (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3414 | (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af, |
wolfSSL | 16:8e0d178b1d1e | 3415 | (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3416 | (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf, |
wolfSSL | 16:8e0d178b1d1e | 3417 | (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3418 | (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order, |
wolfSSL | 16:8e0d178b1d1e | 3419 | (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3420 | (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx, |
wolfSSL | 16:8e0d178b1d1e | 3421 | (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3422 | (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy, |
wolfSSL | 16:8e0d178b1d1e | 3423 | (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) && |
wolfSSL | 16:8e0d178b1d1e | 3424 | (dp->cofactor == ecc_sets[idx].cofactor)) { |
wolfSSL | 16:8e0d178b1d1e | 3425 | break; |
wolfSSL | 16:8e0d178b1d1e | 3426 | } |
wolfSSL | 16:8e0d178b1d1e | 3427 | } |
wolfSSL | 16:8e0d178b1d1e | 3428 | } |
wolfSSL | 16:8e0d178b1d1e | 3429 | |
wolfSSL | 16:8e0d178b1d1e | 3430 | if (ecc_sets[idx].size == 0) |
wolfSSL | 16:8e0d178b1d1e | 3431 | return ECC_CURVE_INVALID; |
wolfSSL | 16:8e0d178b1d1e | 3432 | |
wolfSSL | 16:8e0d178b1d1e | 3433 | return ecc_sets[idx].id; |
wolfSSL | 16:8e0d178b1d1e | 3434 | } |
wolfSSL | 16:8e0d178b1d1e | 3435 | |
wolfSSL | 16:8e0d178b1d1e | 3436 | /* Returns the curve id that corresponds to a given OID, |
wolfSSL | 16:8e0d178b1d1e | 3437 | * as listed in ecc_sets[] of ecc.c. |
wolfSSL | 16:8e0d178b1d1e | 3438 | * |
wolfSSL | 16:8e0d178b1d1e | 3439 | * oid OID, from ecc_sets[].name in ecc.c |
wolfSSL | 16:8e0d178b1d1e | 3440 | * len OID len, from ecc_sets[].name in ecc.c |
wolfSSL | 16:8e0d178b1d1e | 3441 | * return curve id, from ecc_sets[] on success, negative on error |
wolfSSL | 16:8e0d178b1d1e | 3442 | */ |
wolfSSL | 16:8e0d178b1d1e | 3443 | int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len) |
wolfSSL | 16:8e0d178b1d1e | 3444 | { |
wolfSSL | 16:8e0d178b1d1e | 3445 | int curve_idx; |
wolfSSL | 16:8e0d178b1d1e | 3446 | |
wolfSSL | 16:8e0d178b1d1e | 3447 | if (oid == NULL) |
wolfSSL | 16:8e0d178b1d1e | 3448 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 3449 | |
wolfSSL | 16:8e0d178b1d1e | 3450 | for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { |
wolfSSL | 16:8e0d178b1d1e | 3451 | if ( |
wolfSSL | 16:8e0d178b1d1e | 3452 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 16:8e0d178b1d1e | 3453 | ecc_sets[curve_idx].oid && |
wolfSSL | 16:8e0d178b1d1e | 3454 | #endif |
wolfSSL | 16:8e0d178b1d1e | 3455 | ecc_sets[curve_idx].oidSz == len && |
wolfSSL | 16:8e0d178b1d1e | 3456 | XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0) { |
wolfSSL | 16:8e0d178b1d1e | 3457 | break; |
wolfSSL | 16:8e0d178b1d1e | 3458 | } |
wolfSSL | 16:8e0d178b1d1e | 3459 | } |
wolfSSL | 16:8e0d178b1d1e | 3460 | if (ecc_sets[curve_idx].size == 0) { |
wolfSSL | 16:8e0d178b1d1e | 3461 | WOLFSSL_MSG("ecc_set curve name not found"); |
wolfSSL | 16:8e0d178b1d1e | 3462 | return ECC_CURVE_INVALID; |
wolfSSL | 16:8e0d178b1d1e | 3463 | } |
wolfSSL | 16:8e0d178b1d1e | 3464 | |
wolfSSL | 16:8e0d178b1d1e | 3465 | return ecc_sets[curve_idx].id; |
wolfSSL | 16:8e0d178b1d1e | 3466 | } |
wolfSSL | 16:8e0d178b1d1e | 3467 | |
wolfSSL | 16:8e0d178b1d1e | 3468 | /* Get curve parameters using curve index */ |
wolfSSL | 16:8e0d178b1d1e | 3469 | const ecc_set_type* wc_ecc_get_curve_params(int curve_idx) |
wolfSSL | 16:8e0d178b1d1e | 3470 | { |
wolfSSL | 16:8e0d178b1d1e | 3471 | const ecc_set_type* ecc_set = NULL; |
wolfSSL | 16:8e0d178b1d1e | 3472 | |
wolfSSL | 16:8e0d178b1d1e | 3473 | if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) { |
wolfSSL | 16:8e0d178b1d1e | 3474 | ecc_set = &ecc_sets[curve_idx]; |
wolfSSL | 16:8e0d178b1d1e | 3475 | } |
wolfSSL | 16:8e0d178b1d1e | 3476 | return ecc_set; |
wolfSSL | 16:8e0d178b1d1e | 3477 | } |
wolfSSL | 16:8e0d178b1d1e | 3478 | |
wolfSSL | 16:8e0d178b1d1e | 3479 | |
wolfSSL | 16:8e0d178b1d1e | 3480 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 3481 | static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp) |
wolfSSL | 15:117db924cf7c | 3482 | { |
wolfSSL | 15:117db924cf7c | 3483 | if (key == NULL || mp == NULL) |
wolfSSL | 15:117db924cf7c | 3484 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3485 | if (*mp == NULL) { |
wolfSSL | 15:117db924cf7c | 3486 | *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); |
wolfSSL | 15:117db924cf7c | 3487 | if (*mp == NULL) { |
wolfSSL | 15:117db924cf7c | 3488 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 3489 | } |
wolfSSL | 15:117db924cf7c | 3490 | XMEMSET(*mp, 0, sizeof(mp_int)); |
wolfSSL | 15:117db924cf7c | 3491 | } |
wolfSSL | 15:117db924cf7c | 3492 | return 0; |
wolfSSL | 15:117db924cf7c | 3493 | } |
wolfSSL | 15:117db924cf7c | 3494 | static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp) |
wolfSSL | 15:117db924cf7c | 3495 | { |
wolfSSL | 15:117db924cf7c | 3496 | if (key && mp && *mp) { |
wolfSSL | 15:117db924cf7c | 3497 | mp_clear(*mp); |
wolfSSL | 15:117db924cf7c | 3498 | XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT); |
wolfSSL | 15:117db924cf7c | 3499 | *mp = NULL; |
wolfSSL | 15:117db924cf7c | 3500 | } |
wolfSSL | 15:117db924cf7c | 3501 | } |
wolfSSL | 15:117db924cf7c | 3502 | |
wolfSSL | 15:117db924cf7c | 3503 | static int wc_ecc_alloc_async(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 3504 | { |
wolfSSL | 15:117db924cf7c | 3505 | int err = wc_ecc_alloc_mpint(key, &key->r); |
wolfSSL | 15:117db924cf7c | 3506 | if (err == 0) |
wolfSSL | 15:117db924cf7c | 3507 | err = wc_ecc_alloc_mpint(key, &key->s); |
wolfSSL | 15:117db924cf7c | 3508 | return err; |
wolfSSL | 15:117db924cf7c | 3509 | } |
wolfSSL | 15:117db924cf7c | 3510 | |
wolfSSL | 15:117db924cf7c | 3511 | static void wc_ecc_free_async(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 3512 | { |
wolfSSL | 15:117db924cf7c | 3513 | wc_ecc_free_mpint(key, &key->r); |
wolfSSL | 15:117db924cf7c | 3514 | wc_ecc_free_mpint(key, &key->s); |
wolfSSL | 15:117db924cf7c | 3515 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 3516 | wc_ecc_free_mpint(key, &key->e); |
wolfSSL | 15:117db924cf7c | 3517 | wc_ecc_free_mpint(key, &key->signK); |
wolfSSL | 15:117db924cf7c | 3518 | #endif /* HAVE_CAVIUM_V */ |
wolfSSL | 15:117db924cf7c | 3519 | } |
wolfSSL | 16:8e0d178b1d1e | 3520 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 15:117db924cf7c | 3521 | |
wolfSSL | 15:117db924cf7c | 3522 | |
wolfSSL | 15:117db924cf7c | 3523 | #ifdef HAVE_ECC_DHE |
wolfSSL | 15:117db924cf7c | 3524 | /** |
wolfSSL | 15:117db924cf7c | 3525 | Create an ECC shared secret between two keys |
wolfSSL | 15:117db924cf7c | 3526 | private_key The private ECC key (heap hint based off of private key) |
wolfSSL | 15:117db924cf7c | 3527 | public_key The public key |
wolfSSL | 15:117db924cf7c | 3528 | out [out] Destination of the shared secret |
wolfSSL | 15:117db924cf7c | 3529 | Conforms to EC-DH from ANSI X9.63 |
wolfSSL | 15:117db924cf7c | 3530 | outlen [in/out] The max size and resulting size of the shared secret |
wolfSSL | 15:117db924cf7c | 3531 | return MP_OKAY if successful |
wolfSSL | 15:117db924cf7c | 3532 | */ |
wolfSSL | 15:117db924cf7c | 3533 | int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, |
wolfSSL | 15:117db924cf7c | 3534 | word32* outlen) |
wolfSSL | 15:117db924cf7c | 3535 | { |
wolfSSL | 15:117db924cf7c | 3536 | int err; |
wolfSSL | 16:8e0d178b1d1e | 3537 | #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 3538 | CRYS_ECDH_TempData_t tempBuff; |
wolfSSL | 16:8e0d178b1d1e | 3539 | #endif |
wolfSSL | 15:117db924cf7c | 3540 | if (private_key == NULL || public_key == NULL || out == NULL || |
wolfSSL | 15:117db924cf7c | 3541 | outlen == NULL) { |
wolfSSL | 15:117db924cf7c | 3542 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3543 | } |
wolfSSL | 15:117db924cf7c | 3544 | |
wolfSSL | 16:8e0d178b1d1e | 3545 | #ifdef WOLF_CRYPTO_CB |
wolfSSL | 15:117db924cf7c | 3546 | if (private_key->devId != INVALID_DEVID) { |
wolfSSL | 16:8e0d178b1d1e | 3547 | err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen); |
wolfSSL | 16:8e0d178b1d1e | 3548 | if (err != CRYPTOCB_UNAVAILABLE) |
wolfSSL | 15:117db924cf7c | 3549 | return err; |
wolfSSL | 16:8e0d178b1d1e | 3550 | /* fall-through when unavailable */ |
wolfSSL | 15:117db924cf7c | 3551 | } |
wolfSSL | 15:117db924cf7c | 3552 | #endif |
wolfSSL | 15:117db924cf7c | 3553 | |
wolfSSL | 15:117db924cf7c | 3554 | /* type valid? */ |
wolfSSL | 15:117db924cf7c | 3555 | if (private_key->type != ECC_PRIVATEKEY && |
wolfSSL | 15:117db924cf7c | 3556 | private_key->type != ECC_PRIVATEKEY_ONLY) { |
wolfSSL | 15:117db924cf7c | 3557 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3558 | } |
wolfSSL | 15:117db924cf7c | 3559 | |
wolfSSL | 15:117db924cf7c | 3560 | /* Verify domain params supplied */ |
wolfSSL | 15:117db924cf7c | 3561 | if (wc_ecc_is_valid_idx(private_key->idx) == 0 || |
wolfSSL | 15:117db924cf7c | 3562 | wc_ecc_is_valid_idx(public_key->idx) == 0) { |
wolfSSL | 15:117db924cf7c | 3563 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3564 | } |
wolfSSL | 15:117db924cf7c | 3565 | |
wolfSSL | 15:117db924cf7c | 3566 | /* Verify curve id matches */ |
wolfSSL | 15:117db924cf7c | 3567 | if (private_key->dp->id != public_key->dp->id) { |
wolfSSL | 15:117db924cf7c | 3568 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3569 | } |
wolfSSL | 15:117db924cf7c | 3570 | |
wolfSSL | 15:117db924cf7c | 3571 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 3572 | /* For SECP256R1 use hardware */ |
wolfSSL | 16:8e0d178b1d1e | 3573 | if (private_key->dp->id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 3574 | err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out); |
wolfSSL | 16:8e0d178b1d1e | 3575 | *outlen = private_key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 3576 | } |
wolfSSL | 16:8e0d178b1d1e | 3577 | else { |
wolfSSL | 16:8e0d178b1d1e | 3578 | err = NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 3579 | } |
wolfSSL | 16:8e0d178b1d1e | 3580 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 3581 | |
wolfSSL | 16:8e0d178b1d1e | 3582 | /* generate a secret*/ |
wolfSSL | 16:8e0d178b1d1e | 3583 | err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 3584 | &private_key->ctx.privKey, |
wolfSSL | 16:8e0d178b1d1e | 3585 | out, |
wolfSSL | 16:8e0d178b1d1e | 3586 | outlen, |
wolfSSL | 16:8e0d178b1d1e | 3587 | &tempBuff); |
wolfSSL | 16:8e0d178b1d1e | 3588 | |
wolfSSL | 16:8e0d178b1d1e | 3589 | if (err != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 3590 | WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed"); |
wolfSSL | 16:8e0d178b1d1e | 3591 | return err; |
wolfSSL | 16:8e0d178b1d1e | 3592 | } |
wolfSSL | 16:8e0d178b1d1e | 3593 | |
wolfSSL | 15:117db924cf7c | 3594 | #else |
wolfSSL | 15:117db924cf7c | 3595 | err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen); |
wolfSSL | 15:117db924cf7c | 3596 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 3597 | |
wolfSSL | 15:117db924cf7c | 3598 | return err; |
wolfSSL | 15:117db924cf7c | 3599 | } |
wolfSSL | 15:117db924cf7c | 3600 | |
wolfSSL | 15:117db924cf7c | 3601 | |
wolfSSL | 16:8e0d178b1d1e | 3602 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 3603 | |
wolfSSL | 15:117db924cf7c | 3604 | static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, |
wolfSSL | 15:117db924cf7c | 3605 | byte* out, word32* outlen, ecc_curve_spec* curve) |
wolfSSL | 15:117db924cf7c | 3606 | { |
wolfSSL | 15:117db924cf7c | 3607 | int err; |
wolfSSL | 15:117db924cf7c | 3608 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 3609 | ecc_point* result = NULL; |
wolfSSL | 15:117db924cf7c | 3610 | word32 x = 0; |
wolfSSL | 15:117db924cf7c | 3611 | #endif |
wolfSSL | 15:117db924cf7c | 3612 | mp_int* k = &private_key->k; |
wolfSSL | 15:117db924cf7c | 3613 | #ifdef HAVE_ECC_CDH |
wolfSSL | 15:117db924cf7c | 3614 | mp_int k_lcl; |
wolfSSL | 15:117db924cf7c | 3615 | |
wolfSSL | 15:117db924cf7c | 3616 | /* if cofactor flag has been set */ |
wolfSSL | 15:117db924cf7c | 3617 | if (private_key->flags & WC_ECC_FLAG_COFACTOR) { |
wolfSSL | 15:117db924cf7c | 3618 | mp_digit cofactor = (mp_digit)private_key->dp->cofactor; |
wolfSSL | 15:117db924cf7c | 3619 | /* only perform cofactor calc if not equal to 1 */ |
wolfSSL | 15:117db924cf7c | 3620 | if (cofactor != 1) { |
wolfSSL | 15:117db924cf7c | 3621 | k = &k_lcl; |
wolfSSL | 15:117db924cf7c | 3622 | if (mp_init(k) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3623 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 3624 | /* multiply cofactor times private key "k" */ |
wolfSSL | 15:117db924cf7c | 3625 | err = mp_mul_d(&private_key->k, cofactor, k); |
wolfSSL | 15:117db924cf7c | 3626 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3627 | mp_clear(k); |
wolfSSL | 15:117db924cf7c | 3628 | return err; |
wolfSSL | 15:117db924cf7c | 3629 | } |
wolfSSL | 15:117db924cf7c | 3630 | } |
wolfSSL | 15:117db924cf7c | 3631 | } |
wolfSSL | 15:117db924cf7c | 3632 | #endif |
wolfSSL | 15:117db924cf7c | 3633 | |
wolfSSL | 15:117db924cf7c | 3634 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 3635 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 3636 | if (private_key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 15:117db924cf7c | 3637 | ecc_sets[private_key->idx].id == ECC_SECP256R1) { |
wolfSSL | 15:117db924cf7c | 3638 | err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap); |
wolfSSL | 15:117db924cf7c | 3639 | } |
wolfSSL | 15:117db924cf7c | 3640 | else |
wolfSSL | 15:117db924cf7c | 3641 | #endif |
wolfSSL | 16:8e0d178b1d1e | 3642 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 3643 | if (private_key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 3644 | ecc_sets[private_key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 3645 | err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap); |
wolfSSL | 16:8e0d178b1d1e | 3646 | } |
wolfSSL | 16:8e0d178b1d1e | 3647 | else |
wolfSSL | 16:8e0d178b1d1e | 3648 | #endif |
wolfSSL | 15:117db924cf7c | 3649 | #endif |
wolfSSL | 15:117db924cf7c | 3650 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 3651 | { |
wolfSSL | 15:117db924cf7c | 3652 | err = WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 3653 | |
wolfSSL | 15:117db924cf7c | 3654 | (void)curve; |
wolfSSL | 15:117db924cf7c | 3655 | } |
wolfSSL | 15:117db924cf7c | 3656 | #else |
wolfSSL | 15:117db924cf7c | 3657 | { |
wolfSSL | 16:8e0d178b1d1e | 3658 | mp_digit mp = 0; |
wolfSSL | 16:8e0d178b1d1e | 3659 | |
wolfSSL | 15:117db924cf7c | 3660 | /* make new point */ |
wolfSSL | 15:117db924cf7c | 3661 | result = wc_ecc_new_point_h(private_key->heap); |
wolfSSL | 15:117db924cf7c | 3662 | if (result == NULL) { |
wolfSSL | 15:117db924cf7c | 3663 | #ifdef HAVE_ECC_CDH |
wolfSSL | 15:117db924cf7c | 3664 | if (k == &k_lcl) |
wolfSSL | 15:117db924cf7c | 3665 | mp_clear(k); |
wolfSSL | 15:117db924cf7c | 3666 | #endif |
wolfSSL | 15:117db924cf7c | 3667 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 3668 | } |
wolfSSL | 15:117db924cf7c | 3669 | |
wolfSSL | 16:8e0d178b1d1e | 3670 | /* Map in a separate call as this should be constant time */ |
wolfSSL | 16:8e0d178b1d1e | 3671 | err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 0, |
wolfSSL | 15:117db924cf7c | 3672 | private_key->heap); |
wolfSSL | 15:117db924cf7c | 3673 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 3674 | err = mp_montgomery_setup(curve->prime, &mp); |
wolfSSL | 16:8e0d178b1d1e | 3675 | } |
wolfSSL | 16:8e0d178b1d1e | 3676 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 3677 | /* Use constant time map if compiled in */ |
wolfSSL | 16:8e0d178b1d1e | 3678 | err = ecc_map_ex(result, curve->prime, mp, 1); |
wolfSSL | 16:8e0d178b1d1e | 3679 | } |
wolfSSL | 16:8e0d178b1d1e | 3680 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3681 | x = mp_unsigned_bin_size(curve->prime); |
wolfSSL | 16:8e0d178b1d1e | 3682 | if (*outlen < x || (int)x < mp_unsigned_bin_size(result->x)) { |
wolfSSL | 15:117db924cf7c | 3683 | err = BUFFER_E; |
wolfSSL | 15:117db924cf7c | 3684 | } |
wolfSSL | 15:117db924cf7c | 3685 | } |
wolfSSL | 15:117db924cf7c | 3686 | |
wolfSSL | 15:117db924cf7c | 3687 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3688 | XMEMSET(out, 0, x); |
wolfSSL | 15:117db924cf7c | 3689 | err = mp_to_unsigned_bin(result->x,out + |
wolfSSL | 15:117db924cf7c | 3690 | (x - mp_unsigned_bin_size(result->x))); |
wolfSSL | 15:117db924cf7c | 3691 | } |
wolfSSL | 15:117db924cf7c | 3692 | *outlen = x; |
wolfSSL | 15:117db924cf7c | 3693 | |
wolfSSL | 15:117db924cf7c | 3694 | wc_ecc_del_point_h(result, private_key->heap); |
wolfSSL | 15:117db924cf7c | 3695 | } |
wolfSSL | 15:117db924cf7c | 3696 | #endif |
wolfSSL | 15:117db924cf7c | 3697 | #ifdef HAVE_ECC_CDH |
wolfSSL | 15:117db924cf7c | 3698 | if (k == &k_lcl) |
wolfSSL | 15:117db924cf7c | 3699 | mp_clear(k); |
wolfSSL | 15:117db924cf7c | 3700 | #endif |
wolfSSL | 15:117db924cf7c | 3701 | |
wolfSSL | 15:117db924cf7c | 3702 | return err; |
wolfSSL | 15:117db924cf7c | 3703 | } |
wolfSSL | 15:117db924cf7c | 3704 | |
wolfSSL | 15:117db924cf7c | 3705 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 3706 | static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, |
wolfSSL | 15:117db924cf7c | 3707 | ecc_point* point, byte* out, word32 *outlen, |
wolfSSL | 15:117db924cf7c | 3708 | ecc_curve_spec* curve) |
wolfSSL | 15:117db924cf7c | 3709 | { |
wolfSSL | 15:117db924cf7c | 3710 | int err; |
wolfSSL | 15:117db924cf7c | 3711 | |
wolfSSL | 15:117db924cf7c | 3712 | #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 3713 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 3714 | /* verify the curve is supported by hardware */ |
wolfSSL | 15:117db924cf7c | 3715 | if (NitroxEccIsCurveSupported(private_key)) |
wolfSSL | 15:117db924cf7c | 3716 | #endif |
wolfSSL | 15:117db924cf7c | 3717 | { |
wolfSSL | 15:117db924cf7c | 3718 | word32 keySz = private_key->dp->size; |
wolfSSL | 15:117db924cf7c | 3719 | |
wolfSSL | 15:117db924cf7c | 3720 | /* sync public key x/y */ |
wolfSSL | 15:117db924cf7c | 3721 | err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz); |
wolfSSL | 15:117db924cf7c | 3722 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3723 | err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz); |
wolfSSL | 15:117db924cf7c | 3724 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3725 | err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz); |
wolfSSL | 15:117db924cf7c | 3726 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 3727 | /* allocate buffer for output */ |
wolfSSL | 15:117db924cf7c | 3728 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3729 | err = wc_ecc_alloc_mpint(private_key, &private_key->e); |
wolfSSL | 15:117db924cf7c | 3730 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3731 | err = wc_bigint_alloc(&private_key->e->raw, |
wolfSSL | 15:117db924cf7c | 3732 | NitroxEccGetSize(private_key)*2); |
wolfSSL | 15:117db924cf7c | 3733 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3734 | err = NitroxEcdh(private_key, |
wolfSSL | 15:117db924cf7c | 3735 | &private_key->k.raw, &point->x->raw, &point->y->raw, |
wolfSSL | 15:117db924cf7c | 3736 | private_key->e->raw.buf, &private_key->e->raw.len, |
wolfSSL | 15:117db924cf7c | 3737 | &curve->prime->raw); |
wolfSSL | 15:117db924cf7c | 3738 | #else |
wolfSSL | 15:117db924cf7c | 3739 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3740 | err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF); |
wolfSSL | 15:117db924cf7c | 3741 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3742 | err = IntelQaEcdh(&private_key->asyncDev, |
wolfSSL | 15:117db924cf7c | 3743 | &private_key->k.raw, &point->x->raw, &point->y->raw, |
wolfSSL | 15:117db924cf7c | 3744 | out, outlen, |
wolfSSL | 15:117db924cf7c | 3745 | &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw, |
wolfSSL | 15:117db924cf7c | 3746 | private_key->dp->cofactor); |
wolfSSL | 15:117db924cf7c | 3747 | #endif |
wolfSSL | 15:117db924cf7c | 3748 | return err; |
wolfSSL | 15:117db924cf7c | 3749 | } |
wolfSSL | 15:117db924cf7c | 3750 | #elif defined(WOLFSSL_ASYNC_CRYPT_TEST) |
wolfSSL | 15:117db924cf7c | 3751 | if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) { |
wolfSSL | 15:117db924cf7c | 3752 | WC_ASYNC_TEST* testDev = &private_key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 3753 | testDev->eccSharedSec.private_key = private_key; |
wolfSSL | 15:117db924cf7c | 3754 | testDev->eccSharedSec.public_point = point; |
wolfSSL | 15:117db924cf7c | 3755 | testDev->eccSharedSec.out = out; |
wolfSSL | 15:117db924cf7c | 3756 | testDev->eccSharedSec.outLen = outlen; |
wolfSSL | 15:117db924cf7c | 3757 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 3758 | } |
wolfSSL | 15:117db924cf7c | 3759 | #endif |
wolfSSL | 15:117db924cf7c | 3760 | |
wolfSSL | 15:117db924cf7c | 3761 | /* use sync in other cases */ |
wolfSSL | 15:117db924cf7c | 3762 | err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); |
wolfSSL | 15:117db924cf7c | 3763 | |
wolfSSL | 15:117db924cf7c | 3764 | return err; |
wolfSSL | 15:117db924cf7c | 3765 | } |
wolfSSL | 16:8e0d178b1d1e | 3766 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 15:117db924cf7c | 3767 | |
wolfSSL | 15:117db924cf7c | 3768 | int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point, |
wolfSSL | 15:117db924cf7c | 3769 | byte* out, word32 *outlen) |
wolfSSL | 15:117db924cf7c | 3770 | { |
wolfSSL | 15:117db924cf7c | 3771 | int err; |
wolfSSL | 15:117db924cf7c | 3772 | DECLARE_CURVE_SPECS(curve, 2); |
wolfSSL | 15:117db924cf7c | 3773 | |
wolfSSL | 15:117db924cf7c | 3774 | if (private_key == NULL || point == NULL || out == NULL || |
wolfSSL | 15:117db924cf7c | 3775 | outlen == NULL) { |
wolfSSL | 15:117db924cf7c | 3776 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3777 | } |
wolfSSL | 15:117db924cf7c | 3778 | |
wolfSSL | 16:8e0d178b1d1e | 3779 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 3780 | ALLOC_CURVE_SPECS(2); |
wolfSSL | 15:117db924cf7c | 3781 | err = wc_ecc_curve_load(private_key->dp, &curve, |
wolfSSL | 15:117db924cf7c | 3782 | (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); |
wolfSSL | 15:117db924cf7c | 3783 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3784 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 3785 | return err; |
wolfSSL | 15:117db924cf7c | 3786 | } |
wolfSSL | 15:117db924cf7c | 3787 | |
wolfSSL | 15:117db924cf7c | 3788 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 3789 | if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 3790 | err = wc_ecc_shared_secret_gen_async(private_key, point, |
wolfSSL | 15:117db924cf7c | 3791 | out, outlen, curve); |
wolfSSL | 15:117db924cf7c | 3792 | } |
wolfSSL | 15:117db924cf7c | 3793 | else |
wolfSSL | 15:117db924cf7c | 3794 | #endif |
wolfSSL | 15:117db924cf7c | 3795 | { |
wolfSSL | 15:117db924cf7c | 3796 | err = wc_ecc_shared_secret_gen_sync(private_key, point, |
wolfSSL | 15:117db924cf7c | 3797 | out, outlen, curve); |
wolfSSL | 15:117db924cf7c | 3798 | } |
wolfSSL | 15:117db924cf7c | 3799 | |
wolfSSL | 15:117db924cf7c | 3800 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 3801 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 3802 | |
wolfSSL | 15:117db924cf7c | 3803 | return err; |
wolfSSL | 15:117db924cf7c | 3804 | } |
wolfSSL | 15:117db924cf7c | 3805 | |
wolfSSL | 15:117db924cf7c | 3806 | /** |
wolfSSL | 15:117db924cf7c | 3807 | Create an ECC shared secret between private key and public point |
wolfSSL | 15:117db924cf7c | 3808 | private_key The private ECC key (heap hint based on private key) |
wolfSSL | 15:117db924cf7c | 3809 | point The point to use (public key) |
wolfSSL | 15:117db924cf7c | 3810 | out [out] Destination of the shared secret |
wolfSSL | 15:117db924cf7c | 3811 | Conforms to EC-DH from ANSI X9.63 |
wolfSSL | 15:117db924cf7c | 3812 | outlen [in/out] The max size and resulting size of the shared secret |
wolfSSL | 15:117db924cf7c | 3813 | return MP_OKAY if successful |
wolfSSL | 15:117db924cf7c | 3814 | */ |
wolfSSL | 15:117db924cf7c | 3815 | int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, |
wolfSSL | 15:117db924cf7c | 3816 | byte* out, word32 *outlen) |
wolfSSL | 15:117db924cf7c | 3817 | { |
wolfSSL | 15:117db924cf7c | 3818 | int err; |
wolfSSL | 15:117db924cf7c | 3819 | |
wolfSSL | 15:117db924cf7c | 3820 | if (private_key == NULL || point == NULL || out == NULL || |
wolfSSL | 15:117db924cf7c | 3821 | outlen == NULL) { |
wolfSSL | 15:117db924cf7c | 3822 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3823 | } |
wolfSSL | 15:117db924cf7c | 3824 | |
wolfSSL | 15:117db924cf7c | 3825 | /* type valid? */ |
wolfSSL | 15:117db924cf7c | 3826 | if (private_key->type != ECC_PRIVATEKEY && |
wolfSSL | 15:117db924cf7c | 3827 | private_key->type != ECC_PRIVATEKEY_ONLY) { |
wolfSSL | 15:117db924cf7c | 3828 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3829 | } |
wolfSSL | 15:117db924cf7c | 3830 | |
wolfSSL | 15:117db924cf7c | 3831 | /* Verify domain params supplied */ |
wolfSSL | 15:117db924cf7c | 3832 | if (wc_ecc_is_valid_idx(private_key->idx) == 0) |
wolfSSL | 15:117db924cf7c | 3833 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 3834 | |
wolfSSL | 15:117db924cf7c | 3835 | switch(private_key->state) { |
wolfSSL | 15:117db924cf7c | 3836 | case ECC_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 3837 | case ECC_STATE_SHARED_SEC_GEN: |
wolfSSL | 15:117db924cf7c | 3838 | private_key->state = ECC_STATE_SHARED_SEC_GEN; |
wolfSSL | 15:117db924cf7c | 3839 | |
wolfSSL | 15:117db924cf7c | 3840 | err = wc_ecc_shared_secret_gen(private_key, point, out, outlen); |
wolfSSL | 15:117db924cf7c | 3841 | if (err < 0) { |
wolfSSL | 15:117db924cf7c | 3842 | break; |
wolfSSL | 15:117db924cf7c | 3843 | } |
wolfSSL | 15:117db924cf7c | 3844 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 3845 | |
wolfSSL | 15:117db924cf7c | 3846 | case ECC_STATE_SHARED_SEC_RES: |
wolfSSL | 15:117db924cf7c | 3847 | private_key->state = ECC_STATE_SHARED_SEC_RES; |
wolfSSL | 15:117db924cf7c | 3848 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 3849 | if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 3850 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 3851 | /* verify the curve is supported by hardware */ |
wolfSSL | 15:117db924cf7c | 3852 | if (NitroxEccIsCurveSupported(private_key)) { |
wolfSSL | 15:117db924cf7c | 3853 | /* copy output */ |
wolfSSL | 15:117db924cf7c | 3854 | *outlen = private_key->dp->size; |
wolfSSL | 15:117db924cf7c | 3855 | XMEMCPY(out, private_key->e->raw.buf, *outlen); |
wolfSSL | 15:117db924cf7c | 3856 | } |
wolfSSL | 15:117db924cf7c | 3857 | #endif /* HAVE_CAVIUM_V */ |
wolfSSL | 15:117db924cf7c | 3858 | } |
wolfSSL | 15:117db924cf7c | 3859 | #endif /* WOLFSSL_ASYNC_CRYPT */ |
wolfSSL | 15:117db924cf7c | 3860 | err = 0; |
wolfSSL | 15:117db924cf7c | 3861 | break; |
wolfSSL | 15:117db924cf7c | 3862 | |
wolfSSL | 15:117db924cf7c | 3863 | default: |
wolfSSL | 15:117db924cf7c | 3864 | err = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 3865 | } /* switch */ |
wolfSSL | 15:117db924cf7c | 3866 | |
wolfSSL | 15:117db924cf7c | 3867 | /* if async pending then return and skip done cleanup below */ |
wolfSSL | 15:117db924cf7c | 3868 | if (err == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 3869 | private_key->state++; |
wolfSSL | 15:117db924cf7c | 3870 | return err; |
wolfSSL | 15:117db924cf7c | 3871 | } |
wolfSSL | 15:117db924cf7c | 3872 | |
wolfSSL | 15:117db924cf7c | 3873 | /* cleanup */ |
wolfSSL | 16:8e0d178b1d1e | 3874 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 3875 | wc_ecc_free_async(private_key); |
wolfSSL | 15:117db924cf7c | 3876 | #endif |
wolfSSL | 15:117db924cf7c | 3877 | private_key->state = ECC_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 3878 | |
wolfSSL | 15:117db924cf7c | 3879 | return err; |
wolfSSL | 15:117db924cf7c | 3880 | } |
wolfSSL | 16:8e0d178b1d1e | 3881 | #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */ |
wolfSSL | 15:117db924cf7c | 3882 | #endif /* HAVE_ECC_DHE */ |
wolfSSL | 15:117db924cf7c | 3883 | |
wolfSSL | 15:117db924cf7c | 3884 | |
wolfSSL | 16:8e0d178b1d1e | 3885 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 3886 | /* return 1 if point is at infinity, 0 if not, < 0 on error */ |
wolfSSL | 15:117db924cf7c | 3887 | int wc_ecc_point_is_at_infinity(ecc_point* p) |
wolfSSL | 15:117db924cf7c | 3888 | { |
wolfSSL | 15:117db924cf7c | 3889 | if (p == NULL) |
wolfSSL | 15:117db924cf7c | 3890 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3891 | |
wolfSSL | 15:117db924cf7c | 3892 | if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0) |
wolfSSL | 15:117db924cf7c | 3893 | return 1; |
wolfSSL | 15:117db924cf7c | 3894 | |
wolfSSL | 15:117db924cf7c | 3895 | return 0; |
wolfSSL | 15:117db924cf7c | 3896 | } |
wolfSSL | 15:117db924cf7c | 3897 | |
wolfSSL | 15:117db924cf7c | 3898 | /* generate random and ensure its greater than 0 and less than order */ |
wolfSSL | 16:8e0d178b1d1e | 3899 | int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) |
wolfSSL | 16:8e0d178b1d1e | 3900 | { |
wolfSSL | 16:8e0d178b1d1e | 3901 | #ifndef WC_NO_RNG |
wolfSSL | 15:117db924cf7c | 3902 | int err; |
wolfSSL | 16:8e0d178b1d1e | 3903 | byte buf[ECC_MAXSIZE_GEN]; |
wolfSSL | 15:117db924cf7c | 3904 | |
wolfSSL | 15:117db924cf7c | 3905 | /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ |
wolfSSL | 15:117db924cf7c | 3906 | /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ |
wolfSSL | 15:117db924cf7c | 3907 | size += 8; |
wolfSSL | 15:117db924cf7c | 3908 | |
wolfSSL | 15:117db924cf7c | 3909 | /* make up random string */ |
wolfSSL | 15:117db924cf7c | 3910 | err = wc_RNG_GenerateBlock(rng, buf, size); |
wolfSSL | 15:117db924cf7c | 3911 | |
wolfSSL | 15:117db924cf7c | 3912 | /* load random buffer data into k */ |
wolfSSL | 15:117db924cf7c | 3913 | if (err == 0) |
wolfSSL | 15:117db924cf7c | 3914 | err = mp_read_unsigned_bin(k, (byte*)buf, size); |
wolfSSL | 15:117db924cf7c | 3915 | |
wolfSSL | 15:117db924cf7c | 3916 | /* the key should be smaller than the order of base point */ |
wolfSSL | 15:117db924cf7c | 3917 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3918 | if (mp_cmp(k, order) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 3919 | err = mp_mod(k, order, k); |
wolfSSL | 15:117db924cf7c | 3920 | } |
wolfSSL | 15:117db924cf7c | 3921 | } |
wolfSSL | 15:117db924cf7c | 3922 | |
wolfSSL | 15:117db924cf7c | 3923 | /* quick sanity check to make sure we're not dealing with a 0 key */ |
wolfSSL | 15:117db924cf7c | 3924 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 3925 | if (mp_iszero(k) == MP_YES) |
wolfSSL | 15:117db924cf7c | 3926 | err = MP_ZERO_E; |
wolfSSL | 15:117db924cf7c | 3927 | } |
wolfSSL | 15:117db924cf7c | 3928 | |
wolfSSL | 15:117db924cf7c | 3929 | ForceZero(buf, ECC_MAXSIZE); |
wolfSSL | 15:117db924cf7c | 3930 | |
wolfSSL | 15:117db924cf7c | 3931 | return err; |
wolfSSL | 16:8e0d178b1d1e | 3932 | #else |
wolfSSL | 16:8e0d178b1d1e | 3933 | (void)rng; |
wolfSSL | 16:8e0d178b1d1e | 3934 | (void)size; |
wolfSSL | 16:8e0d178b1d1e | 3935 | (void)k; |
wolfSSL | 16:8e0d178b1d1e | 3936 | (void)order; |
wolfSSL | 16:8e0d178b1d1e | 3937 | return NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 3938 | #endif /* !WC_NO_RNG */ |
wolfSSL | 16:8e0d178b1d1e | 3939 | } |
wolfSSL | 16:8e0d178b1d1e | 3940 | #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */ |
wolfSSL | 15:117db924cf7c | 3941 | |
wolfSSL | 15:117db924cf7c | 3942 | static WC_INLINE void wc_ecc_reset(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 3943 | { |
wolfSSL | 15:117db924cf7c | 3944 | /* make sure required key variables are reset */ |
wolfSSL | 15:117db924cf7c | 3945 | key->state = ECC_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 3946 | } |
wolfSSL | 15:117db924cf7c | 3947 | |
wolfSSL | 15:117db924cf7c | 3948 | |
wolfSSL | 15:117db924cf7c | 3949 | /* create the public ECC key from a private key |
wolfSSL | 15:117db924cf7c | 3950 | * |
wolfSSL | 15:117db924cf7c | 3951 | * key an initialized private key to generate public part from |
wolfSSL | 15:117db924cf7c | 3952 | * curveIn [in]curve for key, can be NULL |
wolfSSL | 15:117db924cf7c | 3953 | * pubOut [out]ecc_point holding the public key, if NULL then public key part |
wolfSSL | 15:117db924cf7c | 3954 | * is cached in key instead. |
wolfSSL | 15:117db924cf7c | 3955 | * |
wolfSSL | 15:117db924cf7c | 3956 | * Note this function is local to the file because of the argument type |
wolfSSL | 15:117db924cf7c | 3957 | * ecc_curve_spec. Having this argument allows for not having to load the |
wolfSSL | 15:117db924cf7c | 3958 | * curve type multiple times when generating a key with wc_ecc_make_key(). |
wolfSSL | 15:117db924cf7c | 3959 | * |
wolfSSL | 15:117db924cf7c | 3960 | * returns MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 3961 | */ |
wolfSSL | 15:117db924cf7c | 3962 | static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, |
wolfSSL | 15:117db924cf7c | 3963 | ecc_point* pubOut) |
wolfSSL | 15:117db924cf7c | 3964 | { |
wolfSSL | 15:117db924cf7c | 3965 | int err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 3966 | #ifndef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 3967 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 3968 | ecc_point* base = NULL; |
wolfSSL | 15:117db924cf7c | 3969 | #endif |
wolfSSL | 15:117db924cf7c | 3970 | ecc_point* pub; |
wolfSSL | 15:117db924cf7c | 3971 | DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); |
wolfSSL | 16:8e0d178b1d1e | 3972 | #endif /* !WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 3973 | |
wolfSSL | 15:117db924cf7c | 3974 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 3975 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3976 | } |
wolfSSL | 15:117db924cf7c | 3977 | |
wolfSSL | 15:117db924cf7c | 3978 | #ifndef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 3979 | |
wolfSSL | 15:117db924cf7c | 3980 | /* if ecc_point passed in then use it as output for public key point */ |
wolfSSL | 15:117db924cf7c | 3981 | if (pubOut != NULL) { |
wolfSSL | 15:117db924cf7c | 3982 | pub = pubOut; |
wolfSSL | 15:117db924cf7c | 3983 | } |
wolfSSL | 15:117db924cf7c | 3984 | else { |
wolfSSL | 15:117db924cf7c | 3985 | /* caching public key making it a ECC_PRIVATEKEY instead of |
wolfSSL | 15:117db924cf7c | 3986 | ECC_PRIVATEKEY_ONLY */ |
wolfSSL | 15:117db924cf7c | 3987 | pub = &key->pubkey; |
wolfSSL | 15:117db924cf7c | 3988 | key->type = ECC_PRIVATEKEY_ONLY; |
wolfSSL | 15:117db924cf7c | 3989 | } |
wolfSSL | 15:117db924cf7c | 3990 | |
wolfSSL | 15:117db924cf7c | 3991 | /* avoid loading the curve unless it is not passed in */ |
wolfSSL | 15:117db924cf7c | 3992 | if (curveIn != NULL) { |
wolfSSL | 15:117db924cf7c | 3993 | curve = curveIn; |
wolfSSL | 15:117db924cf7c | 3994 | } |
wolfSSL | 15:117db924cf7c | 3995 | else { |
wolfSSL | 15:117db924cf7c | 3996 | /* load curve info */ |
wolfSSL | 16:8e0d178b1d1e | 3997 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 3998 | ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); |
wolfSSL | 15:117db924cf7c | 3999 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 16:8e0d178b1d1e | 4000 | } |
wolfSSL | 15:117db924cf7c | 4001 | } |
wolfSSL | 15:117db924cf7c | 4002 | |
wolfSSL | 15:117db924cf7c | 4003 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4004 | #ifndef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 4005 | err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 4006 | #else |
wolfSSL | 15:117db924cf7c | 4007 | pub->x = (mp_int*)&pub->xyz[0]; |
wolfSSL | 15:117db924cf7c | 4008 | pub->y = (mp_int*)&pub->xyz[1]; |
wolfSSL | 15:117db924cf7c | 4009 | pub->z = (mp_int*)&pub->xyz[2]; |
wolfSSL | 15:117db924cf7c | 4010 | alt_fp_init(pub->x); |
wolfSSL | 15:117db924cf7c | 4011 | alt_fp_init(pub->y); |
wolfSSL | 15:117db924cf7c | 4012 | alt_fp_init(pub->z); |
wolfSSL | 15:117db924cf7c | 4013 | #endif |
wolfSSL | 15:117db924cf7c | 4014 | } |
wolfSSL | 15:117db924cf7c | 4015 | |
wolfSSL | 15:117db924cf7c | 4016 | |
wolfSSL | 16:8e0d178b1d1e | 4017 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4018 | } |
wolfSSL | 16:8e0d178b1d1e | 4019 | else |
wolfSSL | 15:117db924cf7c | 4020 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 4021 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 4022 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 4023 | err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4024 | } |
wolfSSL | 16:8e0d178b1d1e | 4025 | else |
wolfSSL | 16:8e0d178b1d1e | 4026 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4027 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 4028 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 4029 | err = sp_ecc_mulmod_base_384(&key->k, pub, 1, key->heap); |
wolfSSL | 15:117db924cf7c | 4030 | } |
wolfSSL | 15:117db924cf7c | 4031 | else |
wolfSSL | 15:117db924cf7c | 4032 | #endif |
wolfSSL | 15:117db924cf7c | 4033 | #endif |
wolfSSL | 15:117db924cf7c | 4034 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 4035 | err = WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 4036 | #else |
wolfSSL | 15:117db924cf7c | 4037 | { |
wolfSSL | 16:8e0d178b1d1e | 4038 | mp_digit mp; |
wolfSSL | 16:8e0d178b1d1e | 4039 | |
wolfSSL | 16:8e0d178b1d1e | 4040 | base = wc_ecc_new_point_h(key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4041 | if (base == NULL) |
wolfSSL | 16:8e0d178b1d1e | 4042 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 4043 | /* read in the x/y for this key */ |
wolfSSL | 15:117db924cf7c | 4044 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4045 | err = mp_copy(curve->Gx, base->x); |
wolfSSL | 15:117db924cf7c | 4046 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4047 | err = mp_copy(curve->Gy, base->y); |
wolfSSL | 15:117db924cf7c | 4048 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4049 | err = mp_set(base->z, 1); |
wolfSSL | 15:117db924cf7c | 4050 | |
wolfSSL | 15:117db924cf7c | 4051 | /* make the public key */ |
wolfSSL | 15:117db924cf7c | 4052 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4053 | /* Map in a separate call as this should be constant time */ |
wolfSSL | 15:117db924cf7c | 4054 | err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime, |
wolfSSL | 16:8e0d178b1d1e | 4055 | 0, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4056 | if (err == MP_MEM) { |
wolfSSL | 16:8e0d178b1d1e | 4057 | err = MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 4058 | } |
wolfSSL | 16:8e0d178b1d1e | 4059 | } |
wolfSSL | 16:8e0d178b1d1e | 4060 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4061 | err = mp_montgomery_setup(curve->prime, &mp); |
wolfSSL | 16:8e0d178b1d1e | 4062 | } |
wolfSSL | 16:8e0d178b1d1e | 4063 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4064 | /* Use constant time map if compiled in */ |
wolfSSL | 16:8e0d178b1d1e | 4065 | err = ecc_map_ex(pub, curve->prime, mp, 1); |
wolfSSL | 15:117db924cf7c | 4066 | } |
wolfSSL | 15:117db924cf7c | 4067 | |
wolfSSL | 15:117db924cf7c | 4068 | wc_ecc_del_point_h(base, key->heap); |
wolfSSL | 15:117db924cf7c | 4069 | } |
wolfSSL | 15:117db924cf7c | 4070 | #endif |
wolfSSL | 15:117db924cf7c | 4071 | |
wolfSSL | 15:117db924cf7c | 4072 | #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN |
wolfSSL | 15:117db924cf7c | 4073 | /* validate the public key, order * pubkey = point at infinity */ |
wolfSSL | 15:117db924cf7c | 4074 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4075 | err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime, |
wolfSSL | 15:117db924cf7c | 4076 | curve->order); |
wolfSSL | 15:117db924cf7c | 4077 | #endif /* WOLFSSL_VALIDATE_KEYGEN */ |
wolfSSL | 15:117db924cf7c | 4078 | |
wolfSSL | 15:117db924cf7c | 4079 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4080 | /* clean up if failed */ |
wolfSSL | 15:117db924cf7c | 4081 | #ifndef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 4082 | mp_clear(pub->x); |
wolfSSL | 15:117db924cf7c | 4083 | mp_clear(pub->y); |
wolfSSL | 15:117db924cf7c | 4084 | mp_clear(pub->z); |
wolfSSL | 15:117db924cf7c | 4085 | #endif |
wolfSSL | 15:117db924cf7c | 4086 | } |
wolfSSL | 15:117db924cf7c | 4087 | |
wolfSSL | 15:117db924cf7c | 4088 | /* free up local curve */ |
wolfSSL | 15:117db924cf7c | 4089 | if (curveIn == NULL) { |
wolfSSL | 15:117db924cf7c | 4090 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 4091 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 4092 | } |
wolfSSL | 15:117db924cf7c | 4093 | |
wolfSSL | 15:117db924cf7c | 4094 | #else |
wolfSSL | 15:117db924cf7c | 4095 | (void)curveIn; |
wolfSSL | 16:8e0d178b1d1e | 4096 | err = NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 4097 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 4098 | |
wolfSSL | 15:117db924cf7c | 4099 | /* change key state if public part is cached */ |
wolfSSL | 15:117db924cf7c | 4100 | if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) { |
wolfSSL | 15:117db924cf7c | 4101 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 15:117db924cf7c | 4102 | } |
wolfSSL | 15:117db924cf7c | 4103 | |
wolfSSL | 15:117db924cf7c | 4104 | return err; |
wolfSSL | 15:117db924cf7c | 4105 | } |
wolfSSL | 15:117db924cf7c | 4106 | |
wolfSSL | 15:117db924cf7c | 4107 | |
wolfSSL | 15:117db924cf7c | 4108 | /* create the public ECC key from a private key |
wolfSSL | 15:117db924cf7c | 4109 | * |
wolfSSL | 15:117db924cf7c | 4110 | * key an initialized private key to generate public part from |
wolfSSL | 15:117db924cf7c | 4111 | * pubOut [out]ecc_point holding the public key, if NULL then public key part |
wolfSSL | 15:117db924cf7c | 4112 | * is cached in key instead. |
wolfSSL | 15:117db924cf7c | 4113 | * |
wolfSSL | 15:117db924cf7c | 4114 | * |
wolfSSL | 15:117db924cf7c | 4115 | * returns MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 4116 | */ |
wolfSSL | 15:117db924cf7c | 4117 | int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut) |
wolfSSL | 15:117db924cf7c | 4118 | { |
wolfSSL | 15:117db924cf7c | 4119 | WOLFSSL_ENTER("wc_ecc_make_pub"); |
wolfSSL | 15:117db924cf7c | 4120 | |
wolfSSL | 15:117db924cf7c | 4121 | return wc_ecc_make_pub_ex(key, NULL, pubOut); |
wolfSSL | 15:117db924cf7c | 4122 | } |
wolfSSL | 15:117db924cf7c | 4123 | |
wolfSSL | 15:117db924cf7c | 4124 | |
wolfSSL | 16:8e0d178b1d1e | 4125 | WOLFSSL_ABI |
wolfSSL | 15:117db924cf7c | 4126 | int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) |
wolfSSL | 15:117db924cf7c | 4127 | { |
wolfSSL | 16:8e0d178b1d1e | 4128 | int err; |
wolfSSL | 16:8e0d178b1d1e | 4129 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 4130 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 4131 | DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); |
wolfSSL | 15:117db924cf7c | 4132 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4133 | #endif /* !WOLFSSL_ATECC508A */ |
wolfSSL | 16:8e0d178b1d1e | 4134 | #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 4135 | const CRYS_ECPKI_Domain_t* pDomain; |
wolfSSL | 16:8e0d178b1d1e | 4136 | CRYS_ECPKI_KG_TempData_t tempBuff; |
wolfSSL | 16:8e0d178b1d1e | 4137 | CRYS_ECPKI_KG_FipsContext_t fipsCtx; |
wolfSSL | 16:8e0d178b1d1e | 4138 | byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; |
wolfSSL | 16:8e0d178b1d1e | 4139 | word32 raw_size = 0; |
wolfSSL | 16:8e0d178b1d1e | 4140 | #endif |
wolfSSL | 15:117db924cf7c | 4141 | if (key == NULL || rng == NULL) { |
wolfSSL | 15:117db924cf7c | 4142 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 4143 | } |
wolfSSL | 15:117db924cf7c | 4144 | |
wolfSSL | 15:117db924cf7c | 4145 | /* make sure required variables are reset */ |
wolfSSL | 15:117db924cf7c | 4146 | wc_ecc_reset(key); |
wolfSSL | 15:117db924cf7c | 4147 | |
wolfSSL | 15:117db924cf7c | 4148 | err = wc_ecc_set_curve(key, keysize, curve_id); |
wolfSSL | 15:117db924cf7c | 4149 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 4150 | return err; |
wolfSSL | 15:117db924cf7c | 4151 | } |
wolfSSL | 15:117db924cf7c | 4152 | |
wolfSSL | 16:8e0d178b1d1e | 4153 | #ifdef WOLF_CRYPTO_CB |
wolfSSL | 16:8e0d178b1d1e | 4154 | if (key->devId != INVALID_DEVID) { |
wolfSSL | 16:8e0d178b1d1e | 4155 | err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id); |
wolfSSL | 16:8e0d178b1d1e | 4156 | if (err != CRYPTOCB_UNAVAILABLE) |
wolfSSL | 16:8e0d178b1d1e | 4157 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4158 | /* fall-through when unavailable */ |
wolfSSL | 16:8e0d178b1d1e | 4159 | } |
wolfSSL | 16:8e0d178b1d1e | 4160 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4161 | |
wolfSSL | 15:117db924cf7c | 4162 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 4163 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 4164 | #ifdef HAVE_CAVIUM |
wolfSSL | 15:117db924cf7c | 4165 | /* TODO: Not implemented */ |
wolfSSL | 15:117db924cf7c | 4166 | #elif defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 4167 | /* TODO: Not implemented */ |
wolfSSL | 15:117db924cf7c | 4168 | #else |
wolfSSL | 15:117db924cf7c | 4169 | if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) { |
wolfSSL | 15:117db924cf7c | 4170 | WC_ASYNC_TEST* testDev = &key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 4171 | testDev->eccMake.rng = rng; |
wolfSSL | 15:117db924cf7c | 4172 | testDev->eccMake.key = key; |
wolfSSL | 15:117db924cf7c | 4173 | testDev->eccMake.size = keysize; |
wolfSSL | 15:117db924cf7c | 4174 | testDev->eccMake.curve_id = curve_id; |
wolfSSL | 15:117db924cf7c | 4175 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 4176 | } |
wolfSSL | 15:117db924cf7c | 4177 | #endif |
wolfSSL | 15:117db924cf7c | 4178 | } |
wolfSSL | 16:8e0d178b1d1e | 4179 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 15:117db924cf7c | 4180 | |
wolfSSL | 15:117db924cf7c | 4181 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 4182 | if (key->dp->id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 4183 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 4184 | key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE); |
wolfSSL | 16:8e0d178b1d1e | 4185 | err = atmel_ecc_create_key(key->slot, key->pubkey_raw); |
wolfSSL | 16:8e0d178b1d1e | 4186 | |
wolfSSL | 16:8e0d178b1d1e | 4187 | /* populate key->pubkey */ |
wolfSSL | 16:8e0d178b1d1e | 4188 | if (err == 0 |
wolfSSL | 16:8e0d178b1d1e | 4189 | #ifdef ALT_ECC_SIZE |
wolfSSL | 16:8e0d178b1d1e | 4190 | && key->pubkey.x |
wolfSSL | 16:8e0d178b1d1e | 4191 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4192 | ) { |
wolfSSL | 16:8e0d178b1d1e | 4193 | err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw, |
wolfSSL | 16:8e0d178b1d1e | 4194 | ECC_MAX_CRYPTO_HW_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 4195 | } |
wolfSSL | 16:8e0d178b1d1e | 4196 | if (err == 0 |
wolfSSL | 16:8e0d178b1d1e | 4197 | #ifdef ALT_ECC_SIZE |
wolfSSL | 16:8e0d178b1d1e | 4198 | && key->pubkey.y |
wolfSSL | 16:8e0d178b1d1e | 4199 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4200 | ) { |
wolfSSL | 16:8e0d178b1d1e | 4201 | err = mp_read_unsigned_bin(key->pubkey.y, |
wolfSSL | 16:8e0d178b1d1e | 4202 | key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE, |
wolfSSL | 16:8e0d178b1d1e | 4203 | ECC_MAX_CRYPTO_HW_SIZE); |
wolfSSL | 16:8e0d178b1d1e | 4204 | } |
wolfSSL | 16:8e0d178b1d1e | 4205 | } |
wolfSSL | 16:8e0d178b1d1e | 4206 | else { |
wolfSSL | 16:8e0d178b1d1e | 4207 | err = NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 4208 | } |
wolfSSL | 16:8e0d178b1d1e | 4209 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 4210 | |
wolfSSL | 16:8e0d178b1d1e | 4211 | pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id)); |
wolfSSL | 16:8e0d178b1d1e | 4212 | raw_size = (word32)(key->dp->size)*2 + 1; |
wolfSSL | 16:8e0d178b1d1e | 4213 | |
wolfSSL | 16:8e0d178b1d1e | 4214 | /* generate first key pair */ |
wolfSSL | 16:8e0d178b1d1e | 4215 | err = CRYS_ECPKI_GenKeyPair(&wc_rndState, |
wolfSSL | 16:8e0d178b1d1e | 4216 | wc_rndGenVectFunc, |
wolfSSL | 16:8e0d178b1d1e | 4217 | pDomain, |
wolfSSL | 16:8e0d178b1d1e | 4218 | &key->ctx.privKey, |
wolfSSL | 16:8e0d178b1d1e | 4219 | &key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 4220 | &tempBuff, |
wolfSSL | 16:8e0d178b1d1e | 4221 | &fipsCtx); |
wolfSSL | 16:8e0d178b1d1e | 4222 | |
wolfSSL | 16:8e0d178b1d1e | 4223 | if (err != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 4224 | WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed"); |
wolfSSL | 16:8e0d178b1d1e | 4225 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4226 | } |
wolfSSL | 16:8e0d178b1d1e | 4227 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 4228 | |
wolfSSL | 16:8e0d178b1d1e | 4229 | err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 4230 | CRYS_EC_PointUncompressed, |
wolfSSL | 16:8e0d178b1d1e | 4231 | &ucompressed_key[0], |
wolfSSL | 16:8e0d178b1d1e | 4232 | &raw_size); |
wolfSSL | 16:8e0d178b1d1e | 4233 | |
wolfSSL | 16:8e0d178b1d1e | 4234 | if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) { |
wolfSSL | 16:8e0d178b1d1e | 4235 | err = mp_read_unsigned_bin(key->pubkey.x, |
wolfSSL | 16:8e0d178b1d1e | 4236 | &ucompressed_key[1], key->dp->size); |
wolfSSL | 16:8e0d178b1d1e | 4237 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4238 | err = mp_read_unsigned_bin(key->pubkey.y, |
wolfSSL | 16:8e0d178b1d1e | 4239 | &ucompressed_key[1+key->dp->size],key->dp->size); |
wolfSSL | 16:8e0d178b1d1e | 4240 | } |
wolfSSL | 16:8e0d178b1d1e | 4241 | } |
wolfSSL | 16:8e0d178b1d1e | 4242 | raw_size = key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 4243 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4244 | err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey, |
wolfSSL | 16:8e0d178b1d1e | 4245 | ucompressed_key, |
wolfSSL | 16:8e0d178b1d1e | 4246 | &raw_size); |
wolfSSL | 16:8e0d178b1d1e | 4247 | } |
wolfSSL | 16:8e0d178b1d1e | 4248 | |
wolfSSL | 16:8e0d178b1d1e | 4249 | if (err == SA_SILIB_RET_OK) { |
wolfSSL | 16:8e0d178b1d1e | 4250 | err = mp_read_unsigned_bin(&key->k, ucompressed_key, raw_size); |
wolfSSL | 16:8e0d178b1d1e | 4251 | } |
wolfSSL | 16:8e0d178b1d1e | 4252 | |
wolfSSL | 15:117db924cf7c | 4253 | #else |
wolfSSL | 15:117db924cf7c | 4254 | |
wolfSSL | 15:117db924cf7c | 4255 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 4256 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 4257 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 15:117db924cf7c | 4258 | err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4259 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4260 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 4261 | } |
wolfSSL | 15:117db924cf7c | 4262 | } |
wolfSSL | 15:117db924cf7c | 4263 | else |
wolfSSL | 15:117db924cf7c | 4264 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4265 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 4266 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 4267 | err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4268 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4269 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 4270 | } |
wolfSSL | 16:8e0d178b1d1e | 4271 | } |
wolfSSL | 16:8e0d178b1d1e | 4272 | else |
wolfSSL | 16:8e0d178b1d1e | 4273 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4274 | #endif /* WOLFSSL_HAVE_SP_ECC */ |
wolfSSL | 16:8e0d178b1d1e | 4275 | |
wolfSSL | 16:8e0d178b1d1e | 4276 | { /* software key gen */ |
wolfSSL | 15:117db924cf7c | 4277 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 4278 | err = WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 4279 | #else |
wolfSSL | 15:117db924cf7c | 4280 | |
wolfSSL | 15:117db924cf7c | 4281 | /* setup the key variables */ |
wolfSSL | 15:117db924cf7c | 4282 | err = mp_init(&key->k); |
wolfSSL | 15:117db924cf7c | 4283 | |
wolfSSL | 15:117db924cf7c | 4284 | /* load curve info */ |
wolfSSL | 16:8e0d178b1d1e | 4285 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4286 | ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); |
wolfSSL | 15:117db924cf7c | 4287 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 16:8e0d178b1d1e | 4288 | } |
wolfSSL | 15:117db924cf7c | 4289 | |
wolfSSL | 15:117db924cf7c | 4290 | /* generate k */ |
wolfSSL | 15:117db924cf7c | 4291 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4292 | err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order); |
wolfSSL | 15:117db924cf7c | 4293 | |
wolfSSL | 15:117db924cf7c | 4294 | /* generate public key from k */ |
wolfSSL | 15:117db924cf7c | 4295 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4296 | err = wc_ecc_make_pub_ex(key, curve, NULL); |
wolfSSL | 15:117db924cf7c | 4297 | |
wolfSSL | 15:117db924cf7c | 4298 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 4299 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 15:117db924cf7c | 4300 | |
wolfSSL | 15:117db924cf7c | 4301 | /* cleanup these on failure case only */ |
wolfSSL | 15:117db924cf7c | 4302 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4303 | /* clean up */ |
wolfSSL | 15:117db924cf7c | 4304 | mp_forcezero(&key->k); |
wolfSSL | 15:117db924cf7c | 4305 | } |
wolfSSL | 15:117db924cf7c | 4306 | |
wolfSSL | 15:117db924cf7c | 4307 | /* cleanup allocations */ |
wolfSSL | 15:117db924cf7c | 4308 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 4309 | FREE_CURVE_SPECS(); |
wolfSSL | 16:8e0d178b1d1e | 4310 | #endif /* WOLFSSL_SP_MATH */ |
wolfSSL | 16:8e0d178b1d1e | 4311 | } |
wolfSSL | 16:8e0d178b1d1e | 4312 | |
wolfSSL | 16:8e0d178b1d1e | 4313 | #ifdef HAVE_WOLF_BIGINT |
wolfSSL | 16:8e0d178b1d1e | 4314 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 4315 | err = wc_mp_to_bigint(&key->k, &key->k.raw); |
wolfSSL | 16:8e0d178b1d1e | 4316 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 4317 | err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw); |
wolfSSL | 16:8e0d178b1d1e | 4318 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 4319 | err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw); |
wolfSSL | 16:8e0d178b1d1e | 4320 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 4321 | err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw); |
wolfSSL | 15:117db924cf7c | 4322 | #endif |
wolfSSL | 15:117db924cf7c | 4323 | |
wolfSSL | 15:117db924cf7c | 4324 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 4325 | |
wolfSSL | 15:117db924cf7c | 4326 | return err; |
wolfSSL | 15:117db924cf7c | 4327 | } |
wolfSSL | 15:117db924cf7c | 4328 | |
wolfSSL | 15:117db924cf7c | 4329 | #ifdef ECC_DUMP_OID |
wolfSSL | 15:117db924cf7c | 4330 | /* Optional dump of encoded OID for adding new curves */ |
wolfSSL | 15:117db924cf7c | 4331 | static int mOidDumpDone; |
wolfSSL | 15:117db924cf7c | 4332 | static void wc_ecc_dump_oids(void) |
wolfSSL | 15:117db924cf7c | 4333 | { |
wolfSSL | 15:117db924cf7c | 4334 | int x; |
wolfSSL | 15:117db924cf7c | 4335 | |
wolfSSL | 15:117db924cf7c | 4336 | if (mOidDumpDone) { |
wolfSSL | 15:117db924cf7c | 4337 | return; |
wolfSSL | 15:117db924cf7c | 4338 | } |
wolfSSL | 15:117db924cf7c | 4339 | |
wolfSSL | 15:117db924cf7c | 4340 | /* find matching OID sum (based on encoded value) */ |
wolfSSL | 15:117db924cf7c | 4341 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 15:117db924cf7c | 4342 | int i; |
wolfSSL | 15:117db924cf7c | 4343 | byte* oid; |
wolfSSL | 15:117db924cf7c | 4344 | word32 oidSz, sum = 0; |
wolfSSL | 15:117db924cf7c | 4345 | |
wolfSSL | 15:117db924cf7c | 4346 | printf("ECC %s (%d):\n", ecc_sets[x].name, x); |
wolfSSL | 15:117db924cf7c | 4347 | |
wolfSSL | 15:117db924cf7c | 4348 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 15:117db924cf7c | 4349 | byte oidEnc[ECC_MAX_OID_LEN]; |
wolfSSL | 15:117db924cf7c | 4350 | |
wolfSSL | 15:117db924cf7c | 4351 | oid = oidEnc; |
wolfSSL | 15:117db924cf7c | 4352 | oidSz = ECC_MAX_OID_LEN; |
wolfSSL | 15:117db924cf7c | 4353 | |
wolfSSL | 15:117db924cf7c | 4354 | printf("OID: "); |
wolfSSL | 15:117db924cf7c | 4355 | for (i = 0; i < (int)ecc_sets[x].oidSz; i++) { |
wolfSSL | 15:117db924cf7c | 4356 | printf("%d.", ecc_sets[x].oid[i]); |
wolfSSL | 15:117db924cf7c | 4357 | } |
wolfSSL | 15:117db924cf7c | 4358 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 4359 | |
wolfSSL | 15:117db924cf7c | 4360 | EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz); |
wolfSSL | 15:117db924cf7c | 4361 | #else |
wolfSSL | 15:117db924cf7c | 4362 | oid = (byte*)ecc_sets[x].oid; |
wolfSSL | 15:117db924cf7c | 4363 | oidSz = ecc_sets[x].oidSz; |
wolfSSL | 15:117db924cf7c | 4364 | #endif |
wolfSSL | 15:117db924cf7c | 4365 | |
wolfSSL | 15:117db924cf7c | 4366 | printf("OID Encoded: "); |
wolfSSL | 15:117db924cf7c | 4367 | for (i = 0; i < (int)oidSz; i++) { |
wolfSSL | 15:117db924cf7c | 4368 | printf("0x%02X,", oid[i]); |
wolfSSL | 15:117db924cf7c | 4369 | } |
wolfSSL | 15:117db924cf7c | 4370 | printf("\n"); |
wolfSSL | 15:117db924cf7c | 4371 | |
wolfSSL | 15:117db924cf7c | 4372 | for (i = 0; i < (int)oidSz; i++) { |
wolfSSL | 15:117db924cf7c | 4373 | sum += oid[i]; |
wolfSSL | 15:117db924cf7c | 4374 | } |
wolfSSL | 15:117db924cf7c | 4375 | printf("Sum: %d\n", sum); |
wolfSSL | 15:117db924cf7c | 4376 | |
wolfSSL | 15:117db924cf7c | 4377 | /* validate sum */ |
wolfSSL | 15:117db924cf7c | 4378 | if (ecc_sets[x].oidSum != sum) { |
wolfSSL | 15:117db924cf7c | 4379 | printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum); |
wolfSSL | 15:117db924cf7c | 4380 | } |
wolfSSL | 15:117db924cf7c | 4381 | } |
wolfSSL | 15:117db924cf7c | 4382 | mOidDumpDone = 1; |
wolfSSL | 15:117db924cf7c | 4383 | } |
wolfSSL | 15:117db924cf7c | 4384 | #endif /* ECC_DUMP_OID */ |
wolfSSL | 15:117db924cf7c | 4385 | |
wolfSSL | 16:8e0d178b1d1e | 4386 | |
wolfSSL | 16:8e0d178b1d1e | 4387 | WOLFSSL_ABI |
wolfSSL | 16:8e0d178b1d1e | 4388 | ecc_key* wc_ecc_key_new(void* heap) |
wolfSSL | 16:8e0d178b1d1e | 4389 | { |
wolfSSL | 16:8e0d178b1d1e | 4390 | ecc_key* key; |
wolfSSL | 16:8e0d178b1d1e | 4391 | |
wolfSSL | 16:8e0d178b1d1e | 4392 | key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4393 | if (key) { |
wolfSSL | 16:8e0d178b1d1e | 4394 | if (wc_ecc_init_ex(key, heap, INVALID_DEVID) != 0) { |
wolfSSL | 16:8e0d178b1d1e | 4395 | XFREE(key, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4396 | key = NULL; |
wolfSSL | 16:8e0d178b1d1e | 4397 | } |
wolfSSL | 16:8e0d178b1d1e | 4398 | } |
wolfSSL | 16:8e0d178b1d1e | 4399 | |
wolfSSL | 16:8e0d178b1d1e | 4400 | return key; |
wolfSSL | 16:8e0d178b1d1e | 4401 | } |
wolfSSL | 16:8e0d178b1d1e | 4402 | |
wolfSSL | 16:8e0d178b1d1e | 4403 | |
wolfSSL | 16:8e0d178b1d1e | 4404 | WOLFSSL_ABI |
wolfSSL | 16:8e0d178b1d1e | 4405 | void wc_ecc_key_free(ecc_key* key) |
wolfSSL | 16:8e0d178b1d1e | 4406 | { |
wolfSSL | 16:8e0d178b1d1e | 4407 | if (key) { |
wolfSSL | 16:8e0d178b1d1e | 4408 | void* heap = key->heap; |
wolfSSL | 16:8e0d178b1d1e | 4409 | |
wolfSSL | 16:8e0d178b1d1e | 4410 | wc_ecc_free(key); |
wolfSSL | 16:8e0d178b1d1e | 4411 | ForceZero(key, sizeof(ecc_key)); |
wolfSSL | 16:8e0d178b1d1e | 4412 | XFREE(key, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4413 | (void)heap; |
wolfSSL | 16:8e0d178b1d1e | 4414 | } |
wolfSSL | 16:8e0d178b1d1e | 4415 | } |
wolfSSL | 16:8e0d178b1d1e | 4416 | |
wolfSSL | 16:8e0d178b1d1e | 4417 | |
wolfSSL | 15:117db924cf7c | 4418 | /** |
wolfSSL | 15:117db924cf7c | 4419 | Make a new ECC key |
wolfSSL | 15:117db924cf7c | 4420 | rng An active RNG state |
wolfSSL | 15:117db924cf7c | 4421 | keysize The keysize for the new key (in octets from 20 to 65 bytes) |
wolfSSL | 15:117db924cf7c | 4422 | key [out] Destination of the newly created key |
wolfSSL | 15:117db924cf7c | 4423 | return MP_OKAY if successful, |
wolfSSL | 15:117db924cf7c | 4424 | upon error all allocated memory will be freed |
wolfSSL | 15:117db924cf7c | 4425 | */ |
wolfSSL | 15:117db924cf7c | 4426 | int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) |
wolfSSL | 15:117db924cf7c | 4427 | { |
wolfSSL | 15:117db924cf7c | 4428 | return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); |
wolfSSL | 15:117db924cf7c | 4429 | } |
wolfSSL | 15:117db924cf7c | 4430 | |
wolfSSL | 15:117db924cf7c | 4431 | /* Setup dynamic pointers if using normal math for proper freeing */ |
wolfSSL | 16:8e0d178b1d1e | 4432 | WOLFSSL_ABI |
wolfSSL | 15:117db924cf7c | 4433 | int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) |
wolfSSL | 15:117db924cf7c | 4434 | { |
wolfSSL | 15:117db924cf7c | 4435 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 4436 | |
wolfSSL | 15:117db924cf7c | 4437 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 4438 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 4439 | } |
wolfSSL | 15:117db924cf7c | 4440 | |
wolfSSL | 15:117db924cf7c | 4441 | #ifdef ECC_DUMP_OID |
wolfSSL | 15:117db924cf7c | 4442 | wc_ecc_dump_oids(); |
wolfSSL | 15:117db924cf7c | 4443 | #endif |
wolfSSL | 15:117db924cf7c | 4444 | |
wolfSSL | 15:117db924cf7c | 4445 | XMEMSET(key, 0, sizeof(ecc_key)); |
wolfSSL | 15:117db924cf7c | 4446 | key->state = ECC_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 4447 | |
wolfSSL | 16:8e0d178b1d1e | 4448 | #if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB) |
wolfSSL | 15:117db924cf7c | 4449 | key->devId = devId; |
wolfSSL | 15:117db924cf7c | 4450 | #else |
wolfSSL | 15:117db924cf7c | 4451 | (void)devId; |
wolfSSL | 15:117db924cf7c | 4452 | #endif |
wolfSSL | 15:117db924cf7c | 4453 | |
wolfSSL | 15:117db924cf7c | 4454 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 4455 | key->slot = ATECC_INVALID_SLOT; |
wolfSSL | 15:117db924cf7c | 4456 | #else |
wolfSSL | 15:117db924cf7c | 4457 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 4458 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 15:117db924cf7c | 4459 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 15:117db924cf7c | 4460 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 15:117db924cf7c | 4461 | alt_fp_init(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 4462 | alt_fp_init(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 4463 | alt_fp_init(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 4464 | ret = mp_init(&key->k); |
wolfSSL | 16:8e0d178b1d1e | 4465 | if (ret != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 4466 | return MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 4467 | } |
wolfSSL | 15:117db924cf7c | 4468 | #else |
wolfSSL | 15:117db924cf7c | 4469 | ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, |
wolfSSL | 15:117db924cf7c | 4470 | NULL, NULL); |
wolfSSL | 15:117db924cf7c | 4471 | if (ret != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4472 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 4473 | } |
wolfSSL | 16:8e0d178b1d1e | 4474 | #endif /* ALT_ECC_SIZE */ |
wolfSSL | 15:117db924cf7c | 4475 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 4476 | |
wolfSSL | 15:117db924cf7c | 4477 | #ifdef WOLFSSL_HEAP_TEST |
wolfSSL | 15:117db924cf7c | 4478 | key->heap = (void*)WOLFSSL_HEAP_TEST; |
wolfSSL | 15:117db924cf7c | 4479 | #else |
wolfSSL | 15:117db924cf7c | 4480 | key->heap = heap; |
wolfSSL | 15:117db924cf7c | 4481 | #endif |
wolfSSL | 15:117db924cf7c | 4482 | |
wolfSSL | 15:117db924cf7c | 4483 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 4484 | /* handle as async */ |
wolfSSL | 15:117db924cf7c | 4485 | ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, |
wolfSSL | 15:117db924cf7c | 4486 | key->heap, devId); |
wolfSSL | 15:117db924cf7c | 4487 | #endif |
wolfSSL | 15:117db924cf7c | 4488 | |
wolfSSL | 16:8e0d178b1d1e | 4489 | #if defined(WOLFSSL_DSP) |
wolfSSL | 16:8e0d178b1d1e | 4490 | key->handle = -1; |
wolfSSL | 16:8e0d178b1d1e | 4491 | #endif |
wolfSSL | 15:117db924cf7c | 4492 | return ret; |
wolfSSL | 15:117db924cf7c | 4493 | } |
wolfSSL | 15:117db924cf7c | 4494 | |
wolfSSL | 15:117db924cf7c | 4495 | int wc_ecc_init(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 4496 | { |
wolfSSL | 15:117db924cf7c | 4497 | return wc_ecc_init_ex(key, NULL, INVALID_DEVID); |
wolfSSL | 15:117db924cf7c | 4498 | } |
wolfSSL | 15:117db924cf7c | 4499 | |
wolfSSL | 16:8e0d178b1d1e | 4500 | #ifdef HAVE_PKCS11 |
wolfSSL | 16:8e0d178b1d1e | 4501 | int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap, |
wolfSSL | 16:8e0d178b1d1e | 4502 | int devId) |
wolfSSL | 16:8e0d178b1d1e | 4503 | { |
wolfSSL | 16:8e0d178b1d1e | 4504 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 4505 | |
wolfSSL | 16:8e0d178b1d1e | 4506 | if (key == NULL) |
wolfSSL | 16:8e0d178b1d1e | 4507 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 4508 | if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN)) |
wolfSSL | 16:8e0d178b1d1e | 4509 | ret = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 4510 | |
wolfSSL | 16:8e0d178b1d1e | 4511 | if (ret == 0) |
wolfSSL | 16:8e0d178b1d1e | 4512 | ret = wc_ecc_init_ex(key, heap, devId); |
wolfSSL | 16:8e0d178b1d1e | 4513 | |
wolfSSL | 16:8e0d178b1d1e | 4514 | if (ret == 0 && id != NULL && len != 0) { |
wolfSSL | 16:8e0d178b1d1e | 4515 | XMEMCPY(key->id, id, len); |
wolfSSL | 16:8e0d178b1d1e | 4516 | key->idLen = len; |
wolfSSL | 16:8e0d178b1d1e | 4517 | } |
wolfSSL | 16:8e0d178b1d1e | 4518 | |
wolfSSL | 16:8e0d178b1d1e | 4519 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 4520 | } |
wolfSSL | 16:8e0d178b1d1e | 4521 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4522 | |
wolfSSL | 15:117db924cf7c | 4523 | int wc_ecc_set_flags(ecc_key* key, word32 flags) |
wolfSSL | 15:117db924cf7c | 4524 | { |
wolfSSL | 15:117db924cf7c | 4525 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 4526 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 4527 | } |
wolfSSL | 15:117db924cf7c | 4528 | key->flags |= flags; |
wolfSSL | 15:117db924cf7c | 4529 | return 0; |
wolfSSL | 15:117db924cf7c | 4530 | } |
wolfSSL | 15:117db924cf7c | 4531 | |
wolfSSL | 16:8e0d178b1d1e | 4532 | |
wolfSSL | 16:8e0d178b1d1e | 4533 | static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp) |
wolfSSL | 16:8e0d178b1d1e | 4534 | { |
wolfSSL | 16:8e0d178b1d1e | 4535 | int err; |
wolfSSL | 16:8e0d178b1d1e | 4536 | word32 orderBits; |
wolfSSL | 16:8e0d178b1d1e | 4537 | DECLARE_CURVE_SPECS(curve, 1); |
wolfSSL | 16:8e0d178b1d1e | 4538 | |
wolfSSL | 16:8e0d178b1d1e | 4539 | ALLOC_CURVE_SPECS(1); |
wolfSSL | 16:8e0d178b1d1e | 4540 | err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER); |
wolfSSL | 16:8e0d178b1d1e | 4541 | if (err != 0) { |
wolfSSL | 16:8e0d178b1d1e | 4542 | FREE_CURVE_SPECS(); |
wolfSSL | 16:8e0d178b1d1e | 4543 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4544 | } |
wolfSSL | 16:8e0d178b1d1e | 4545 | orderBits = mp_count_bits(curve->order); |
wolfSSL | 16:8e0d178b1d1e | 4546 | |
wolfSSL | 16:8e0d178b1d1e | 4547 | wc_ecc_curve_free(curve); |
wolfSSL | 16:8e0d178b1d1e | 4548 | FREE_CURVE_SPECS(); |
wolfSSL | 16:8e0d178b1d1e | 4549 | return (int)orderBits; |
wolfSSL | 16:8e0d178b1d1e | 4550 | } |
wolfSSL | 16:8e0d178b1d1e | 4551 | |
wolfSSL | 15:117db924cf7c | 4552 | #ifdef HAVE_ECC_SIGN |
wolfSSL | 15:117db924cf7c | 4553 | |
wolfSSL | 15:117db924cf7c | 4554 | #ifndef NO_ASN |
wolfSSL | 15:117db924cf7c | 4555 | |
wolfSSL | 16:8e0d178b1d1e | 4556 | #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || \ |
wolfSSL | 16:8e0d178b1d1e | 4557 | defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 4558 | static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, |
wolfSSL | 15:117db924cf7c | 4559 | mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng, |
wolfSSL | 15:117db924cf7c | 4560 | ecc_key* key) |
wolfSSL | 15:117db924cf7c | 4561 | { |
wolfSSL | 15:117db924cf7c | 4562 | int err; |
wolfSSL | 15:117db924cf7c | 4563 | #ifdef PLUTON_CRYPTO_ECC |
wolfSSL | 15:117db924cf7c | 4564 | if (key->devId != INVALID_DEVID) /* use hardware */ |
wolfSSL | 15:117db924cf7c | 4565 | #endif |
wolfSSL | 15:117db924cf7c | 4566 | { |
wolfSSL | 16:8e0d178b1d1e | 4567 | #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 4568 | CRYS_ECDSA_SignUserContext_t sigCtxTemp; |
wolfSSL | 16:8e0d178b1d1e | 4569 | word32 raw_sig_size = *outlen; |
wolfSSL | 16:8e0d178b1d1e | 4570 | word32 msgLenInBytes = inlen; |
wolfSSL | 16:8e0d178b1d1e | 4571 | CRYS_ECPKI_HASH_OpMode_t hash_mode; |
wolfSSL | 16:8e0d178b1d1e | 4572 | #endif |
wolfSSL | 15:117db924cf7c | 4573 | word32 keysize = (word32)key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 4574 | word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp); |
wolfSSL | 15:117db924cf7c | 4575 | |
wolfSSL | 15:117db924cf7c | 4576 | /* Check args */ |
wolfSSL | 16:8e0d178b1d1e | 4577 | if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) { |
wolfSSL | 15:117db924cf7c | 4578 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 4579 | } |
wolfSSL | 15:117db924cf7c | 4580 | |
wolfSSL | 15:117db924cf7c | 4581 | #if defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 4582 | key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE); |
wolfSSL | 16:8e0d178b1d1e | 4583 | if (key->slot == ATECC_INVALID_SLOT) { |
wolfSSL | 16:8e0d178b1d1e | 4584 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 4585 | } |
wolfSSL | 16:8e0d178b1d1e | 4586 | |
wolfSSL | 15:117db924cf7c | 4587 | /* Sign: Result is 32-bytes of R then 32-bytes of S */ |
wolfSSL | 16:8e0d178b1d1e | 4588 | err = atmel_ecc_sign(key->slot, in, out); |
wolfSSL | 16:8e0d178b1d1e | 4589 | if (err != 0) { |
wolfSSL | 16:8e0d178b1d1e | 4590 | return err; |
wolfSSL | 15:117db924cf7c | 4591 | } |
wolfSSL | 15:117db924cf7c | 4592 | #elif defined(PLUTON_CRYPTO_ECC) |
wolfSSL | 15:117db924cf7c | 4593 | { |
wolfSSL | 16:8e0d178b1d1e | 4594 | /* if the input is larger than curve order, we must truncate */ |
wolfSSL | 16:8e0d178b1d1e | 4595 | if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) { |
wolfSSL | 16:8e0d178b1d1e | 4596 | inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; |
wolfSSL | 16:8e0d178b1d1e | 4597 | } |
wolfSSL | 16:8e0d178b1d1e | 4598 | |
wolfSSL | 15:117db924cf7c | 4599 | /* perform ECC sign */ |
wolfSSL | 15:117db924cf7c | 4600 | word32 raw_sig_size = *outlen; |
wolfSSL | 15:117db924cf7c | 4601 | err = Crypto_EccSign(in, inlen, out, &raw_sig_size); |
wolfSSL | 15:117db924cf7c | 4602 | if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){ |
wolfSSL | 15:117db924cf7c | 4603 | return BAD_COND_E; |
wolfSSL | 15:117db924cf7c | 4604 | } |
wolfSSL | 15:117db924cf7c | 4605 | } |
wolfSSL | 16:8e0d178b1d1e | 4606 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 4607 | |
wolfSSL | 16:8e0d178b1d1e | 4608 | hash_mode = cc310_hashModeECC(msgLenInBytes); |
wolfSSL | 16:8e0d178b1d1e | 4609 | if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) { |
wolfSSL | 16:8e0d178b1d1e | 4610 | hash_mode = cc310_hashModeECC(keysize); |
wolfSSL | 16:8e0d178b1d1e | 4611 | hash_mode = CRYS_ECPKI_HASH_SHA256_mode; |
wolfSSL | 16:8e0d178b1d1e | 4612 | } |
wolfSSL | 16:8e0d178b1d1e | 4613 | |
wolfSSL | 16:8e0d178b1d1e | 4614 | /* truncate if hash is longer than key size */ |
wolfSSL | 16:8e0d178b1d1e | 4615 | if (msgLenInBytes > keysize) { |
wolfSSL | 16:8e0d178b1d1e | 4616 | msgLenInBytes = keysize; |
wolfSSL | 16:8e0d178b1d1e | 4617 | } |
wolfSSL | 16:8e0d178b1d1e | 4618 | |
wolfSSL | 16:8e0d178b1d1e | 4619 | /* create signature from an input buffer using a private key*/ |
wolfSSL | 16:8e0d178b1d1e | 4620 | err = CRYS_ECDSA_Sign(&wc_rndState, |
wolfSSL | 16:8e0d178b1d1e | 4621 | wc_rndGenVectFunc, |
wolfSSL | 16:8e0d178b1d1e | 4622 | &sigCtxTemp, |
wolfSSL | 16:8e0d178b1d1e | 4623 | &key->ctx.privKey, |
wolfSSL | 16:8e0d178b1d1e | 4624 | hash_mode, |
wolfSSL | 16:8e0d178b1d1e | 4625 | (byte*)in, |
wolfSSL | 16:8e0d178b1d1e | 4626 | msgLenInBytes, |
wolfSSL | 16:8e0d178b1d1e | 4627 | out, |
wolfSSL | 16:8e0d178b1d1e | 4628 | &raw_sig_size); |
wolfSSL | 16:8e0d178b1d1e | 4629 | |
wolfSSL | 16:8e0d178b1d1e | 4630 | if (err != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 4631 | WOLFSSL_MSG("CRYS_ECDSA_Sign failed"); |
wolfSSL | 16:8e0d178b1d1e | 4632 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4633 | } |
wolfSSL | 15:117db924cf7c | 4634 | #endif |
wolfSSL | 15:117db924cf7c | 4635 | |
wolfSSL | 15:117db924cf7c | 4636 | /* Load R and S */ |
wolfSSL | 15:117db924cf7c | 4637 | err = mp_read_unsigned_bin(r, &out[0], keysize); |
wolfSSL | 15:117db924cf7c | 4638 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4639 | return err; |
wolfSSL | 15:117db924cf7c | 4640 | } |
wolfSSL | 15:117db924cf7c | 4641 | err = mp_read_unsigned_bin(s, &out[keysize], keysize); |
wolfSSL | 15:117db924cf7c | 4642 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4643 | return err; |
wolfSSL | 15:117db924cf7c | 4644 | } |
wolfSSL | 15:117db924cf7c | 4645 | |
wolfSSL | 15:117db924cf7c | 4646 | /* Check for zeros */ |
wolfSSL | 15:117db924cf7c | 4647 | if (mp_iszero(r) || mp_iszero(s)) { |
wolfSSL | 15:117db924cf7c | 4648 | return MP_ZERO_E; |
wolfSSL | 15:117db924cf7c | 4649 | } |
wolfSSL | 15:117db924cf7c | 4650 | } |
wolfSSL | 15:117db924cf7c | 4651 | #ifdef PLUTON_CRYPTO_ECC |
wolfSSL | 15:117db924cf7c | 4652 | else { |
wolfSSL | 15:117db924cf7c | 4653 | err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); |
wolfSSL | 15:117db924cf7c | 4654 | } |
wolfSSL | 15:117db924cf7c | 4655 | #endif |
wolfSSL | 15:117db924cf7c | 4656 | (void)rng; |
wolfSSL | 15:117db924cf7c | 4657 | |
wolfSSL | 15:117db924cf7c | 4658 | return err; |
wolfSSL | 15:117db924cf7c | 4659 | } |
wolfSSL | 16:8e0d178b1d1e | 4660 | #endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */ |
wolfSSL | 16:8e0d178b1d1e | 4661 | |
wolfSSL | 16:8e0d178b1d1e | 4662 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 16:8e0d178b1d1e | 4663 | static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out, |
wolfSSL | 16:8e0d178b1d1e | 4664 | word32 *outlen, WC_RNG* rng, ecc_key* key) |
wolfSSL | 15:117db924cf7c | 4665 | { |
wolfSSL | 15:117db924cf7c | 4666 | int err; |
wolfSSL | 15:117db924cf7c | 4667 | mp_int *r = NULL, *s = NULL; |
wolfSSL | 15:117db924cf7c | 4668 | |
wolfSSL | 15:117db924cf7c | 4669 | if (in == NULL || out == NULL || outlen == NULL || key == NULL || |
wolfSSL | 15:117db924cf7c | 4670 | rng == NULL) { |
wolfSSL | 15:117db924cf7c | 4671 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 4672 | } |
wolfSSL | 15:117db924cf7c | 4673 | |
wolfSSL | 15:117db924cf7c | 4674 | err = wc_ecc_alloc_async(key); |
wolfSSL | 16:8e0d178b1d1e | 4675 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 4676 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4677 | } |
wolfSSL | 15:117db924cf7c | 4678 | r = key->r; |
wolfSSL | 15:117db924cf7c | 4679 | s = key->s; |
wolfSSL | 15:117db924cf7c | 4680 | |
wolfSSL | 15:117db924cf7c | 4681 | switch(key->state) { |
wolfSSL | 15:117db924cf7c | 4682 | case ECC_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 4683 | case ECC_STATE_SIGN_DO: |
wolfSSL | 15:117db924cf7c | 4684 | key->state = ECC_STATE_SIGN_DO; |
wolfSSL | 15:117db924cf7c | 4685 | |
wolfSSL | 15:117db924cf7c | 4686 | if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ |
wolfSSL | 15:117db924cf7c | 4687 | break; |
wolfSSL | 15:117db924cf7c | 4688 | } |
wolfSSL | 15:117db924cf7c | 4689 | |
wolfSSL | 15:117db924cf7c | 4690 | err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); |
wolfSSL | 15:117db924cf7c | 4691 | if (err < 0) { |
wolfSSL | 15:117db924cf7c | 4692 | break; |
wolfSSL | 15:117db924cf7c | 4693 | } |
wolfSSL | 15:117db924cf7c | 4694 | |
wolfSSL | 15:117db924cf7c | 4695 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 4696 | |
wolfSSL | 15:117db924cf7c | 4697 | case ECC_STATE_SIGN_ENCODE: |
wolfSSL | 15:117db924cf7c | 4698 | key->state = ECC_STATE_SIGN_ENCODE; |
wolfSSL | 15:117db924cf7c | 4699 | |
wolfSSL | 15:117db924cf7c | 4700 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 4701 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 4702 | /* Nitrox requires r and s in sep buffer, so split it */ |
wolfSSL | 15:117db924cf7c | 4703 | NitroxEccRsSplit(key, &r->raw, &s->raw); |
wolfSSL | 15:117db924cf7c | 4704 | #endif |
wolfSSL | 15:117db924cf7c | 4705 | #ifndef WOLFSSL_ASYNC_CRYPT_TEST |
wolfSSL | 15:117db924cf7c | 4706 | /* only do this if not simulator, since it overwrites result */ |
wolfSSL | 15:117db924cf7c | 4707 | wc_bigint_to_mp(&r->raw, r); |
wolfSSL | 15:117db924cf7c | 4708 | wc_bigint_to_mp(&s->raw, s); |
wolfSSL | 15:117db924cf7c | 4709 | #endif |
wolfSSL | 15:117db924cf7c | 4710 | } |
wolfSSL | 15:117db924cf7c | 4711 | |
wolfSSL | 15:117db924cf7c | 4712 | /* encoded with DSA header */ |
wolfSSL | 15:117db924cf7c | 4713 | err = StoreECC_DSA_Sig(out, outlen, r, s); |
wolfSSL | 15:117db924cf7c | 4714 | |
wolfSSL | 15:117db924cf7c | 4715 | /* done with R/S */ |
wolfSSL | 15:117db924cf7c | 4716 | mp_clear(r); |
wolfSSL | 15:117db924cf7c | 4717 | mp_clear(s); |
wolfSSL | 15:117db924cf7c | 4718 | break; |
wolfSSL | 15:117db924cf7c | 4719 | |
wolfSSL | 15:117db924cf7c | 4720 | default: |
wolfSSL | 15:117db924cf7c | 4721 | err = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 4722 | break; |
wolfSSL | 15:117db924cf7c | 4723 | } |
wolfSSL | 15:117db924cf7c | 4724 | |
wolfSSL | 15:117db924cf7c | 4725 | /* if async pending then return and skip done cleanup below */ |
wolfSSL | 15:117db924cf7c | 4726 | if (err == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 4727 | key->state++; |
wolfSSL | 15:117db924cf7c | 4728 | return err; |
wolfSSL | 15:117db924cf7c | 4729 | } |
wolfSSL | 15:117db924cf7c | 4730 | |
wolfSSL | 15:117db924cf7c | 4731 | /* cleanup */ |
wolfSSL | 15:117db924cf7c | 4732 | wc_ecc_free_async(key); |
wolfSSL | 15:117db924cf7c | 4733 | key->state = ECC_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 4734 | |
wolfSSL | 15:117db924cf7c | 4735 | return err; |
wolfSSL | 15:117db924cf7c | 4736 | } |
wolfSSL | 16:8e0d178b1d1e | 4737 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 16:8e0d178b1d1e | 4738 | |
wolfSSL | 16:8e0d178b1d1e | 4739 | /** |
wolfSSL | 16:8e0d178b1d1e | 4740 | Sign a message digest |
wolfSSL | 16:8e0d178b1d1e | 4741 | in The message digest to sign |
wolfSSL | 16:8e0d178b1d1e | 4742 | inlen The length of the digest |
wolfSSL | 16:8e0d178b1d1e | 4743 | out [out] The destination for the signature |
wolfSSL | 16:8e0d178b1d1e | 4744 | outlen [in/out] The max size and resulting size of the signature |
wolfSSL | 16:8e0d178b1d1e | 4745 | key A private ECC key |
wolfSSL | 16:8e0d178b1d1e | 4746 | return MP_OKAY if successful |
wolfSSL | 16:8e0d178b1d1e | 4747 | */ |
wolfSSL | 16:8e0d178b1d1e | 4748 | WOLFSSL_ABI |
wolfSSL | 16:8e0d178b1d1e | 4749 | int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, |
wolfSSL | 16:8e0d178b1d1e | 4750 | WC_RNG* rng, ecc_key* key) |
wolfSSL | 16:8e0d178b1d1e | 4751 | { |
wolfSSL | 16:8e0d178b1d1e | 4752 | int err; |
wolfSSL | 16:8e0d178b1d1e | 4753 | #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 16:8e0d178b1d1e | 4754 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 4755 | mp_int *r = NULL, *s = NULL; |
wolfSSL | 16:8e0d178b1d1e | 4756 | #else |
wolfSSL | 16:8e0d178b1d1e | 4757 | mp_int r[1], s[1]; |
wolfSSL | 16:8e0d178b1d1e | 4758 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4759 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4760 | |
wolfSSL | 16:8e0d178b1d1e | 4761 | if (in == NULL || out == NULL || outlen == NULL || key == NULL || |
wolfSSL | 16:8e0d178b1d1e | 4762 | rng == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 4763 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 4764 | } |
wolfSSL | 16:8e0d178b1d1e | 4765 | |
wolfSSL | 16:8e0d178b1d1e | 4766 | #ifdef WOLF_CRYPTO_CB |
wolfSSL | 16:8e0d178b1d1e | 4767 | if (key->devId != INVALID_DEVID) { |
wolfSSL | 16:8e0d178b1d1e | 4768 | err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key); |
wolfSSL | 16:8e0d178b1d1e | 4769 | if (err != CRYPTOCB_UNAVAILABLE) |
wolfSSL | 16:8e0d178b1d1e | 4770 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4771 | /* fall-through when unavailable */ |
wolfSSL | 16:8e0d178b1d1e | 4772 | } |
wolfSSL | 16:8e0d178b1d1e | 4773 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4774 | |
wolfSSL | 16:8e0d178b1d1e | 4775 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 16:8e0d178b1d1e | 4776 | /* handle async cases */ |
wolfSSL | 16:8e0d178b1d1e | 4777 | err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key); |
wolfSSL | 16:8e0d178b1d1e | 4778 | #else |
wolfSSL | 16:8e0d178b1d1e | 4779 | |
wolfSSL | 16:8e0d178b1d1e | 4780 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 4781 | r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4782 | if (r == NULL) |
wolfSSL | 16:8e0d178b1d1e | 4783 | return MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 4784 | s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4785 | if (s == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 4786 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4787 | return MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 4788 | } |
wolfSSL | 16:8e0d178b1d1e | 4789 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4790 | XMEMSET(r, 0, sizeof(mp_int)); |
wolfSSL | 16:8e0d178b1d1e | 4791 | XMEMSET(s, 0, sizeof(mp_int)); |
wolfSSL | 16:8e0d178b1d1e | 4792 | |
wolfSSL | 16:8e0d178b1d1e | 4793 | if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ |
wolfSSL | 16:8e0d178b1d1e | 4794 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 4795 | XFREE(s, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4796 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4797 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4798 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4799 | } |
wolfSSL | 16:8e0d178b1d1e | 4800 | |
wolfSSL | 16:8e0d178b1d1e | 4801 | /* hardware crypto */ |
wolfSSL | 16:8e0d178b1d1e | 4802 | #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 4803 | err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key); |
wolfSSL | 16:8e0d178b1d1e | 4804 | #else |
wolfSSL | 16:8e0d178b1d1e | 4805 | err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); |
wolfSSL | 16:8e0d178b1d1e | 4806 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4807 | if (err < 0) { |
wolfSSL | 16:8e0d178b1d1e | 4808 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 4809 | XFREE(s, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4810 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4811 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4812 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4813 | } |
wolfSSL | 16:8e0d178b1d1e | 4814 | |
wolfSSL | 16:8e0d178b1d1e | 4815 | /* encoded with DSA header */ |
wolfSSL | 16:8e0d178b1d1e | 4816 | err = StoreECC_DSA_Sig(out, outlen, r, s); |
wolfSSL | 16:8e0d178b1d1e | 4817 | |
wolfSSL | 16:8e0d178b1d1e | 4818 | /* cleanup */ |
wolfSSL | 16:8e0d178b1d1e | 4819 | mp_clear(r); |
wolfSSL | 16:8e0d178b1d1e | 4820 | mp_clear(s); |
wolfSSL | 16:8e0d178b1d1e | 4821 | |
wolfSSL | 16:8e0d178b1d1e | 4822 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 4823 | XFREE(s, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4824 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 4825 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4826 | #endif /* WOLFSSL_ASYNC_CRYPT */ |
wolfSSL | 16:8e0d178b1d1e | 4827 | |
wolfSSL | 16:8e0d178b1d1e | 4828 | return err; |
wolfSSL | 16:8e0d178b1d1e | 4829 | } |
wolfSSL | 15:117db924cf7c | 4830 | #endif /* !NO_ASN */ |
wolfSSL | 15:117db924cf7c | 4831 | |
wolfSSL | 16:8e0d178b1d1e | 4832 | #if defined(WOLFSSL_STM32_PKA) |
wolfSSL | 16:8e0d178b1d1e | 4833 | int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, |
wolfSSL | 16:8e0d178b1d1e | 4834 | ecc_key* key, mp_int *r, mp_int *s) |
wolfSSL | 16:8e0d178b1d1e | 4835 | { |
wolfSSL | 16:8e0d178b1d1e | 4836 | return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s); |
wolfSSL | 16:8e0d178b1d1e | 4837 | } |
wolfSSL | 16:8e0d178b1d1e | 4838 | #elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 4839 | /** |
wolfSSL | 15:117db924cf7c | 4840 | Sign a message digest |
wolfSSL | 15:117db924cf7c | 4841 | in The message digest to sign |
wolfSSL | 15:117db924cf7c | 4842 | inlen The length of the digest |
wolfSSL | 15:117db924cf7c | 4843 | key A private ECC key |
wolfSSL | 15:117db924cf7c | 4844 | r [out] The destination for r component of the signature |
wolfSSL | 15:117db924cf7c | 4845 | s [out] The destination for s component of the signature |
wolfSSL | 15:117db924cf7c | 4846 | return MP_OKAY if successful |
wolfSSL | 15:117db924cf7c | 4847 | */ |
wolfSSL | 15:117db924cf7c | 4848 | int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, |
wolfSSL | 15:117db924cf7c | 4849 | ecc_key* key, mp_int *r, mp_int *s) |
wolfSSL | 15:117db924cf7c | 4850 | { |
wolfSSL | 16:8e0d178b1d1e | 4851 | int err = 0; |
wolfSSL | 15:117db924cf7c | 4852 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 4853 | mp_int* e; |
wolfSSL | 15:117db924cf7c | 4854 | #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \ |
wolfSSL | 15:117db924cf7c | 4855 | !defined(WOLFSSL_SMALL_STACK) |
wolfSSL | 15:117db924cf7c | 4856 | mp_int e_lcl; |
wolfSSL | 15:117db924cf7c | 4857 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4858 | |
wolfSSL | 16:8e0d178b1d1e | 4859 | #if defined(WOLFSSL_ECDSA_SET_K) || \ |
wolfSSL | 16:8e0d178b1d1e | 4860 | (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ |
wolfSSL | 16:8e0d178b1d1e | 4861 | (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))) |
wolfSSL | 16:8e0d178b1d1e | 4862 | DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); |
wolfSSL | 16:8e0d178b1d1e | 4863 | #else |
wolfSSL | 15:117db924cf7c | 4864 | DECLARE_CURVE_SPECS(curve, 1); |
wolfSSL | 16:8e0d178b1d1e | 4865 | #endif |
wolfSSL | 15:117db924cf7c | 4866 | #endif /* !WOLFSSL_SP_MATH */ |
wolfSSL | 15:117db924cf7c | 4867 | |
wolfSSL | 16:8e0d178b1d1e | 4868 | if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) { |
wolfSSL | 15:117db924cf7c | 4869 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 4870 | } |
wolfSSL | 15:117db924cf7c | 4871 | |
wolfSSL | 15:117db924cf7c | 4872 | /* is this a private key? */ |
wolfSSL | 15:117db924cf7c | 4873 | if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) { |
wolfSSL | 15:117db924cf7c | 4874 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 4875 | } |
wolfSSL | 15:117db924cf7c | 4876 | |
wolfSSL | 15:117db924cf7c | 4877 | /* is the IDX valid ? */ |
wolfSSL | 15:117db924cf7c | 4878 | if (wc_ecc_is_valid_idx(key->idx) != 1) { |
wolfSSL | 15:117db924cf7c | 4879 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 4880 | } |
wolfSSL | 15:117db924cf7c | 4881 | |
wolfSSL | 15:117db924cf7c | 4882 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 16:8e0d178b1d1e | 4883 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 4884 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 4885 | #ifndef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 4886 | return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4887 | #else |
wolfSSL | 16:8e0d178b1d1e | 4888 | return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k, |
wolfSSL | 16:8e0d178b1d1e | 4889 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4890 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4891 | } |
wolfSSL | 16:8e0d178b1d1e | 4892 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4893 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 4894 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 4895 | #ifndef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 4896 | return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4897 | #else |
wolfSSL | 16:8e0d178b1d1e | 4898 | return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k, |
wolfSSL | 16:8e0d178b1d1e | 4899 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4900 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4901 | } |
wolfSSL | 16:8e0d178b1d1e | 4902 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4903 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 4904 | #else |
wolfSSL | 15:117db924cf7c | 4905 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 16:8e0d178b1d1e | 4906 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 4907 | if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) |
wolfSSL | 15:117db924cf7c | 4908 | #endif |
wolfSSL | 15:117db924cf7c | 4909 | { |
wolfSSL | 15:117db924cf7c | 4910 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 4911 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 4912 | ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 4913 | #ifndef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 4914 | return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, |
wolfSSL | 16:8e0d178b1d1e | 4915 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4916 | #else |
wolfSSL | 16:8e0d178b1d1e | 4917 | return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k, |
wolfSSL | 16:8e0d178b1d1e | 4918 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4919 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4920 | } |
wolfSSL | 16:8e0d178b1d1e | 4921 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4922 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 4923 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 4924 | ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 4925 | #ifndef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 4926 | return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, |
wolfSSL | 16:8e0d178b1d1e | 4927 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4928 | #else |
wolfSSL | 16:8e0d178b1d1e | 4929 | return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k, |
wolfSSL | 16:8e0d178b1d1e | 4930 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 4931 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4932 | } |
wolfSSL | 15:117db924cf7c | 4933 | #endif |
wolfSSL | 15:117db924cf7c | 4934 | } |
wolfSSL | 15:117db924cf7c | 4935 | #endif /* WOLFSSL_HAVE_SP_ECC */ |
wolfSSL | 15:117db924cf7c | 4936 | |
wolfSSL | 15:117db924cf7c | 4937 | |
wolfSSL | 15:117db924cf7c | 4938 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ |
wolfSSL | 15:117db924cf7c | 4939 | defined(WOLFSSL_ASYNC_CRYPT_TEST) |
wolfSSL | 15:117db924cf7c | 4940 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 4941 | if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) { |
wolfSSL | 15:117db924cf7c | 4942 | WC_ASYNC_TEST* testDev = &key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 4943 | testDev->eccSign.in = in; |
wolfSSL | 15:117db924cf7c | 4944 | testDev->eccSign.inSz = inlen; |
wolfSSL | 15:117db924cf7c | 4945 | testDev->eccSign.rng = rng; |
wolfSSL | 15:117db924cf7c | 4946 | testDev->eccSign.key = key; |
wolfSSL | 15:117db924cf7c | 4947 | testDev->eccSign.r = r; |
wolfSSL | 15:117db924cf7c | 4948 | testDev->eccSign.s = s; |
wolfSSL | 15:117db924cf7c | 4949 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 4950 | } |
wolfSSL | 15:117db924cf7c | 4951 | } |
wolfSSL | 15:117db924cf7c | 4952 | #endif |
wolfSSL | 15:117db924cf7c | 4953 | |
wolfSSL | 15:117db924cf7c | 4954 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) |
wolfSSL | 15:117db924cf7c | 4955 | err = wc_ecc_alloc_mpint(key, &key->e); |
wolfSSL | 15:117db924cf7c | 4956 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 4957 | return err; |
wolfSSL | 15:117db924cf7c | 4958 | } |
wolfSSL | 15:117db924cf7c | 4959 | e = key->e; |
wolfSSL | 15:117db924cf7c | 4960 | #elif !defined(WOLFSSL_SMALL_STACK) |
wolfSSL | 15:117db924cf7c | 4961 | e = &e_lcl; |
wolfSSL | 15:117db924cf7c | 4962 | #else |
wolfSSL | 15:117db924cf7c | 4963 | e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 4964 | if (e == NULL) { |
wolfSSL | 15:117db924cf7c | 4965 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 4966 | } |
wolfSSL | 15:117db924cf7c | 4967 | #endif |
wolfSSL | 15:117db924cf7c | 4968 | |
wolfSSL | 15:117db924cf7c | 4969 | /* get the hash and load it as a bignum into 'e' */ |
wolfSSL | 15:117db924cf7c | 4970 | /* init the bignums */ |
wolfSSL | 15:117db924cf7c | 4971 | if ((err = mp_init(e)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4972 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 4973 | XFREE(e, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 4974 | #endif |
wolfSSL | 15:117db924cf7c | 4975 | return err; |
wolfSSL | 15:117db924cf7c | 4976 | } |
wolfSSL | 15:117db924cf7c | 4977 | |
wolfSSL | 15:117db924cf7c | 4978 | /* load curve info */ |
wolfSSL | 16:8e0d178b1d1e | 4979 | #if defined(WOLFSSL_ECDSA_SET_K) |
wolfSSL | 16:8e0d178b1d1e | 4980 | ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); |
wolfSSL | 16:8e0d178b1d1e | 4981 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 16:8e0d178b1d1e | 4982 | #else |
wolfSSL | 16:8e0d178b1d1e | 4983 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ |
wolfSSL | 16:8e0d178b1d1e | 4984 | (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)) |
wolfSSL | 16:8e0d178b1d1e | 4985 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 16:8e0d178b1d1e | 4986 | ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); |
wolfSSL | 16:8e0d178b1d1e | 4987 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 16:8e0d178b1d1e | 4988 | } |
wolfSSL | 16:8e0d178b1d1e | 4989 | else |
wolfSSL | 16:8e0d178b1d1e | 4990 | #endif |
wolfSSL | 16:8e0d178b1d1e | 4991 | { |
wolfSSL | 16:8e0d178b1d1e | 4992 | ALLOC_CURVE_SPECS(1); |
wolfSSL | 16:8e0d178b1d1e | 4993 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); |
wolfSSL | 16:8e0d178b1d1e | 4994 | } |
wolfSSL | 16:8e0d178b1d1e | 4995 | #endif |
wolfSSL | 15:117db924cf7c | 4996 | |
wolfSSL | 15:117db924cf7c | 4997 | /* load digest into e */ |
wolfSSL | 15:117db924cf7c | 4998 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 4999 | /* we may need to truncate if hash is longer than key size */ |
wolfSSL | 15:117db924cf7c | 5000 | word32 orderBits = mp_count_bits(curve->order); |
wolfSSL | 15:117db924cf7c | 5001 | |
wolfSSL | 15:117db924cf7c | 5002 | /* truncate down to byte size, may be all that's needed */ |
wolfSSL | 15:117db924cf7c | 5003 | if ((WOLFSSL_BIT_SIZE * inlen) > orderBits) |
wolfSSL | 15:117db924cf7c | 5004 | inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; |
wolfSSL | 15:117db924cf7c | 5005 | err = mp_read_unsigned_bin(e, (byte*)in, inlen); |
wolfSSL | 15:117db924cf7c | 5006 | |
wolfSSL | 15:117db924cf7c | 5007 | /* may still need bit truncation too */ |
wolfSSL | 15:117db924cf7c | 5008 | if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) |
wolfSSL | 15:117db924cf7c | 5009 | mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); |
wolfSSL | 15:117db924cf7c | 5010 | } |
wolfSSL | 15:117db924cf7c | 5011 | |
wolfSSL | 15:117db924cf7c | 5012 | /* make up a key and export the public copy */ |
wolfSSL | 15:117db924cf7c | 5013 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5014 | int loop_check = 0; |
wolfSSL | 15:117db924cf7c | 5015 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 5016 | ecc_key* pubkey; |
wolfSSL | 15:117db924cf7c | 5017 | #else |
wolfSSL | 15:117db924cf7c | 5018 | ecc_key pubkey[1]; |
wolfSSL | 15:117db924cf7c | 5019 | #endif |
wolfSSL | 15:117db924cf7c | 5020 | |
wolfSSL | 15:117db924cf7c | 5021 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 5022 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 5023 | #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 5024 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 5025 | if (NitroxEccIsCurveSupported(key)) |
wolfSSL | 15:117db924cf7c | 5026 | #endif |
wolfSSL | 15:117db924cf7c | 5027 | { |
wolfSSL | 15:117db924cf7c | 5028 | word32 keySz = key->dp->size; |
wolfSSL | 15:117db924cf7c | 5029 | mp_int* k; |
wolfSSL | 15:117db924cf7c | 5030 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 5031 | err = wc_ecc_alloc_mpint(key, &key->signK); |
wolfSSL | 15:117db924cf7c | 5032 | if (err != 0) |
wolfSSL | 15:117db924cf7c | 5033 | return err; |
wolfSSL | 15:117db924cf7c | 5034 | k = key->signK; |
wolfSSL | 15:117db924cf7c | 5035 | #else |
wolfSSL | 15:117db924cf7c | 5036 | mp_int k_lcl; |
wolfSSL | 15:117db924cf7c | 5037 | k = &k_lcl; |
wolfSSL | 15:117db924cf7c | 5038 | #endif |
wolfSSL | 15:117db924cf7c | 5039 | |
wolfSSL | 15:117db924cf7c | 5040 | err = mp_init(k); |
wolfSSL | 15:117db924cf7c | 5041 | |
wolfSSL | 15:117db924cf7c | 5042 | /* make sure r and s are allocated */ |
wolfSSL | 15:117db924cf7c | 5043 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 5044 | /* Nitrox V needs single buffer for R and S */ |
wolfSSL | 15:117db924cf7c | 5045 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5046 | err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2); |
wolfSSL | 15:117db924cf7c | 5047 | /* Nitrox V only needs Prime and Order */ |
wolfSSL | 15:117db924cf7c | 5048 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5049 | err = wc_ecc_curve_load(key->dp, &curve, |
wolfSSL | 15:117db924cf7c | 5050 | (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER)); |
wolfSSL | 15:117db924cf7c | 5051 | #else |
wolfSSL | 15:117db924cf7c | 5052 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5053 | err = wc_bigint_alloc(&key->r->raw, key->dp->size); |
wolfSSL | 15:117db924cf7c | 5054 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5055 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 15:117db924cf7c | 5056 | #endif |
wolfSSL | 15:117db924cf7c | 5057 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5058 | err = wc_bigint_alloc(&key->s->raw, key->dp->size); |
wolfSSL | 15:117db924cf7c | 5059 | |
wolfSSL | 15:117db924cf7c | 5060 | /* load e and k */ |
wolfSSL | 15:117db924cf7c | 5061 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5062 | err = wc_mp_to_bigint_sz(e, &e->raw, keySz); |
wolfSSL | 15:117db924cf7c | 5063 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5064 | err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz); |
wolfSSL | 15:117db924cf7c | 5065 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5066 | err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order); |
wolfSSL | 15:117db924cf7c | 5067 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5068 | err = wc_mp_to_bigint_sz(k, &k->raw, keySz); |
wolfSSL | 15:117db924cf7c | 5069 | |
wolfSSL | 15:117db924cf7c | 5070 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 5071 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5072 | err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw, |
wolfSSL | 15:117db924cf7c | 5073 | &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw); |
wolfSSL | 15:117db924cf7c | 5074 | #else |
wolfSSL | 15:117db924cf7c | 5075 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5076 | err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw, |
wolfSSL | 15:117db924cf7c | 5077 | &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw, |
wolfSSL | 15:117db924cf7c | 5078 | &curve->prime->raw, &curve->order->raw, &curve->Gx->raw, |
wolfSSL | 15:117db924cf7c | 5079 | &curve->Gy->raw); |
wolfSSL | 15:117db924cf7c | 5080 | #endif |
wolfSSL | 15:117db924cf7c | 5081 | |
wolfSSL | 15:117db924cf7c | 5082 | #ifndef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 5083 | mp_clear(e); |
wolfSSL | 15:117db924cf7c | 5084 | mp_clear(k); |
wolfSSL | 15:117db924cf7c | 5085 | #endif |
wolfSSL | 15:117db924cf7c | 5086 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 5087 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 5088 | |
wolfSSL | 15:117db924cf7c | 5089 | return err; |
wolfSSL | 15:117db924cf7c | 5090 | } |
wolfSSL | 15:117db924cf7c | 5091 | #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ |
wolfSSL | 15:117db924cf7c | 5092 | } |
wolfSSL | 16:8e0d178b1d1e | 5093 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 15:117db924cf7c | 5094 | |
wolfSSL | 15:117db924cf7c | 5095 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5096 | pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5097 | if (pubkey == NULL) |
wolfSSL | 15:117db924cf7c | 5098 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5099 | #endif |
wolfSSL | 15:117db924cf7c | 5100 | |
wolfSSL | 15:117db924cf7c | 5101 | /* don't use async for key, since we don't support async return here */ |
wolfSSL | 15:117db924cf7c | 5102 | if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap, |
wolfSSL | 15:117db924cf7c | 5103 | INVALID_DEVID)) == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5104 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5105 | mp_int* b = NULL; |
wolfSSL | 15:117db924cf7c | 5106 | #else |
wolfSSL | 15:117db924cf7c | 5107 | mp_int b[1]; |
wolfSSL | 15:117db924cf7c | 5108 | #endif |
wolfSSL | 15:117db924cf7c | 5109 | |
wolfSSL | 15:117db924cf7c | 5110 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5111 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5112 | b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, |
wolfSSL | 15:117db924cf7c | 5113 | DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5114 | if (b == NULL) |
wolfSSL | 15:117db924cf7c | 5115 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5116 | } |
wolfSSL | 15:117db924cf7c | 5117 | #endif |
wolfSSL | 15:117db924cf7c | 5118 | |
wolfSSL | 15:117db924cf7c | 5119 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5120 | err = mp_init(b); |
wolfSSL | 15:117db924cf7c | 5121 | } |
wolfSSL | 15:117db924cf7c | 5122 | |
wolfSSL | 15:117db924cf7c | 5123 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 5124 | /* if custom curve, apply params to pubkey */ |
wolfSSL | 15:117db924cf7c | 5125 | if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) { |
wolfSSL | 15:117db924cf7c | 5126 | err = wc_ecc_set_custom_curve(pubkey, key->dp); |
wolfSSL | 15:117db924cf7c | 5127 | } |
wolfSSL | 15:117db924cf7c | 5128 | #endif |
wolfSSL | 15:117db924cf7c | 5129 | |
wolfSSL | 15:117db924cf7c | 5130 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5131 | /* Generate blinding value - non-zero value. */ |
wolfSSL | 15:117db924cf7c | 5132 | do { |
wolfSSL | 15:117db924cf7c | 5133 | if (++loop_check > 64) { |
wolfSSL | 15:117db924cf7c | 5134 | err = RNG_FAILURE_E; |
wolfSSL | 15:117db924cf7c | 5135 | break; |
wolfSSL | 15:117db924cf7c | 5136 | } |
wolfSSL | 15:117db924cf7c | 5137 | |
wolfSSL | 15:117db924cf7c | 5138 | err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order); |
wolfSSL | 15:117db924cf7c | 5139 | } |
wolfSSL | 15:117db924cf7c | 5140 | while (err == MP_ZERO_E); |
wolfSSL | 15:117db924cf7c | 5141 | loop_check = 0; |
wolfSSL | 15:117db924cf7c | 5142 | } |
wolfSSL | 15:117db924cf7c | 5143 | |
wolfSSL | 15:117db924cf7c | 5144 | for (; err == MP_OKAY;) { |
wolfSSL | 15:117db924cf7c | 5145 | if (++loop_check > 64) { |
wolfSSL | 15:117db924cf7c | 5146 | err = RNG_FAILURE_E; |
wolfSSL | 15:117db924cf7c | 5147 | break; |
wolfSSL | 15:117db924cf7c | 5148 | } |
wolfSSL | 16:8e0d178b1d1e | 5149 | #ifdef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 5150 | if (key->sign_k != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 5151 | if (loop_check > 1) { |
wolfSSL | 16:8e0d178b1d1e | 5152 | err = RNG_FAILURE_E; |
wolfSSL | 16:8e0d178b1d1e | 5153 | break; |
wolfSSL | 16:8e0d178b1d1e | 5154 | } |
wolfSSL | 16:8e0d178b1d1e | 5155 | |
wolfSSL | 16:8e0d178b1d1e | 5156 | err = mp_copy(key->sign_k, &pubkey->k); |
wolfSSL | 16:8e0d178b1d1e | 5157 | if (err != MP_OKAY) break; |
wolfSSL | 16:8e0d178b1d1e | 5158 | |
wolfSSL | 16:8e0d178b1d1e | 5159 | mp_forcezero(key->sign_k); |
wolfSSL | 16:8e0d178b1d1e | 5160 | mp_free(key->sign_k); |
wolfSSL | 16:8e0d178b1d1e | 5161 | XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5162 | key->sign_k = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5163 | err = wc_ecc_make_pub_ex(pubkey, curve, NULL); |
wolfSSL | 16:8e0d178b1d1e | 5164 | } |
wolfSSL | 16:8e0d178b1d1e | 5165 | else |
wolfSSL | 16:8e0d178b1d1e | 5166 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5167 | { |
wolfSSL | 16:8e0d178b1d1e | 5168 | err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, |
wolfSSL | 15:117db924cf7c | 5169 | key->dp->id); |
wolfSSL | 16:8e0d178b1d1e | 5170 | } |
wolfSSL | 15:117db924cf7c | 5171 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5172 | |
wolfSSL | 15:117db924cf7c | 5173 | /* find r = x1 mod n */ |
wolfSSL | 15:117db924cf7c | 5174 | err = mp_mod(pubkey->pubkey.x, curve->order, r); |
wolfSSL | 15:117db924cf7c | 5175 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5176 | |
wolfSSL | 15:117db924cf7c | 5177 | if (mp_iszero(r) == MP_YES) { |
wolfSSL | 15:117db924cf7c | 5178 | #ifndef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 5179 | mp_clear(pubkey->pubkey.x); |
wolfSSL | 15:117db924cf7c | 5180 | mp_clear(pubkey->pubkey.y); |
wolfSSL | 15:117db924cf7c | 5181 | mp_clear(pubkey->pubkey.z); |
wolfSSL | 15:117db924cf7c | 5182 | #endif |
wolfSSL | 15:117db924cf7c | 5183 | mp_forcezero(&pubkey->k); |
wolfSSL | 15:117db924cf7c | 5184 | } |
wolfSSL | 15:117db924cf7c | 5185 | else { |
wolfSSL | 15:117db924cf7c | 5186 | /* find s = (e + xr)/k |
wolfSSL | 15:117db924cf7c | 5187 | = b.(e/k.b + x.r/k.b) */ |
wolfSSL | 15:117db924cf7c | 5188 | |
wolfSSL | 15:117db924cf7c | 5189 | /* k = k.b */ |
wolfSSL | 15:117db924cf7c | 5190 | err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k); |
wolfSSL | 15:117db924cf7c | 5191 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5192 | |
wolfSSL | 15:117db924cf7c | 5193 | /* k = 1/k.b */ |
wolfSSL | 15:117db924cf7c | 5194 | err = mp_invmod(&pubkey->k, curve->order, &pubkey->k); |
wolfSSL | 15:117db924cf7c | 5195 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5196 | |
wolfSSL | 15:117db924cf7c | 5197 | /* s = x.r */ |
wolfSSL | 15:117db924cf7c | 5198 | err = mp_mulmod(&key->k, r, curve->order, s); |
wolfSSL | 15:117db924cf7c | 5199 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5200 | |
wolfSSL | 15:117db924cf7c | 5201 | /* s = x.r/k.b */ |
wolfSSL | 15:117db924cf7c | 5202 | err = mp_mulmod(&pubkey->k, s, curve->order, s); |
wolfSSL | 15:117db924cf7c | 5203 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5204 | |
wolfSSL | 15:117db924cf7c | 5205 | /* e = e/k.b */ |
wolfSSL | 15:117db924cf7c | 5206 | err = mp_mulmod(&pubkey->k, e, curve->order, e); |
wolfSSL | 15:117db924cf7c | 5207 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5208 | |
wolfSSL | 15:117db924cf7c | 5209 | /* s = e/k.b + x.r/k.b |
wolfSSL | 15:117db924cf7c | 5210 | = (e + x.r)/k.b */ |
wolfSSL | 15:117db924cf7c | 5211 | err = mp_add(e, s, s); |
wolfSSL | 15:117db924cf7c | 5212 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5213 | |
wolfSSL | 15:117db924cf7c | 5214 | /* s = b.(e + x.r)/k.b |
wolfSSL | 15:117db924cf7c | 5215 | = (e + x.r)/k */ |
wolfSSL | 15:117db924cf7c | 5216 | err = mp_mulmod(s, b, curve->order, s); |
wolfSSL | 15:117db924cf7c | 5217 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5218 | |
wolfSSL | 15:117db924cf7c | 5219 | /* s = (e + xr)/k */ |
wolfSSL | 15:117db924cf7c | 5220 | err = mp_mod(s, curve->order, s); |
wolfSSL | 15:117db924cf7c | 5221 | if (err != MP_OKAY) break; |
wolfSSL | 15:117db924cf7c | 5222 | |
wolfSSL | 15:117db924cf7c | 5223 | if (mp_iszero(s) == MP_NO) |
wolfSSL | 15:117db924cf7c | 5224 | break; |
wolfSSL | 15:117db924cf7c | 5225 | } |
wolfSSL | 15:117db924cf7c | 5226 | } |
wolfSSL | 15:117db924cf7c | 5227 | mp_clear(b); |
wolfSSL | 15:117db924cf7c | 5228 | mp_free(b); |
wolfSSL | 15:117db924cf7c | 5229 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5230 | XFREE(b, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5231 | #endif |
wolfSSL | 15:117db924cf7c | 5232 | wc_ecc_free(pubkey); |
wolfSSL | 15:117db924cf7c | 5233 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5234 | XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5235 | #endif |
wolfSSL | 15:117db924cf7c | 5236 | } |
wolfSSL | 15:117db924cf7c | 5237 | } |
wolfSSL | 15:117db924cf7c | 5238 | |
wolfSSL | 15:117db924cf7c | 5239 | mp_clear(e); |
wolfSSL | 15:117db924cf7c | 5240 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 5241 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5242 | XFREE(e, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5243 | #endif |
wolfSSL | 15:117db924cf7c | 5244 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 5245 | #endif /* WOLFSSL_SP_MATH */ |
wolfSSL | 15:117db924cf7c | 5246 | |
wolfSSL | 15:117db924cf7c | 5247 | return err; |
wolfSSL | 15:117db924cf7c | 5248 | } |
wolfSSL | 16:8e0d178b1d1e | 5249 | |
wolfSSL | 16:8e0d178b1d1e | 5250 | #ifdef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 5251 | int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key) |
wolfSSL | 16:8e0d178b1d1e | 5252 | { |
wolfSSL | 16:8e0d178b1d1e | 5253 | int ret = 0; |
wolfSSL | 16:8e0d178b1d1e | 5254 | |
wolfSSL | 16:8e0d178b1d1e | 5255 | if (k == NULL || klen == 0 || key == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 5256 | ret = BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 5257 | } |
wolfSSL | 16:8e0d178b1d1e | 5258 | |
wolfSSL | 16:8e0d178b1d1e | 5259 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 5260 | if (key->sign_k == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 5261 | key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, |
wolfSSL | 16:8e0d178b1d1e | 5262 | DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5263 | if (key->sign_k == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 5264 | ret = MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 5265 | } |
wolfSSL | 16:8e0d178b1d1e | 5266 | } |
wolfSSL | 16:8e0d178b1d1e | 5267 | } |
wolfSSL | 16:8e0d178b1d1e | 5268 | |
wolfSSL | 16:8e0d178b1d1e | 5269 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 5270 | ret = mp_init(key->sign_k); |
wolfSSL | 16:8e0d178b1d1e | 5271 | } |
wolfSSL | 16:8e0d178b1d1e | 5272 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 5273 | ret = mp_read_unsigned_bin(key->sign_k, k, klen); |
wolfSSL | 16:8e0d178b1d1e | 5274 | } |
wolfSSL | 16:8e0d178b1d1e | 5275 | |
wolfSSL | 16:8e0d178b1d1e | 5276 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 5277 | } |
wolfSSL | 16:8e0d178b1d1e | 5278 | #endif /* WOLFSSL_ECDSA_SET_K */ |
wolfSSL | 16:8e0d178b1d1e | 5279 | #endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/ |
wolfSSL | 16:8e0d178b1d1e | 5280 | |
wolfSSL | 15:117db924cf7c | 5281 | #endif /* HAVE_ECC_SIGN */ |
wolfSSL | 15:117db924cf7c | 5282 | |
wolfSSL | 15:117db924cf7c | 5283 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 5284 | void wc_ecc_free_curve(const ecc_set_type* curve, void* heap) |
wolfSSL | 15:117db924cf7c | 5285 | { |
wolfSSL | 16:8e0d178b1d1e | 5286 | #ifndef WOLFSSL_ECC_CURVE_STATIC |
wolfSSL | 15:117db924cf7c | 5287 | if (curve->prime != NULL) |
wolfSSL | 15:117db924cf7c | 5288 | XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5289 | if (curve->Af != NULL) |
wolfSSL | 15:117db924cf7c | 5290 | XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5291 | if (curve->Bf != NULL) |
wolfSSL | 15:117db924cf7c | 5292 | XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5293 | if (curve->order != NULL) |
wolfSSL | 15:117db924cf7c | 5294 | XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5295 | if (curve->Gx != NULL) |
wolfSSL | 15:117db924cf7c | 5296 | XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5297 | if (curve->Gy != NULL) |
wolfSSL | 15:117db924cf7c | 5298 | XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 16:8e0d178b1d1e | 5299 | #endif |
wolfSSL | 15:117db924cf7c | 5300 | |
wolfSSL | 15:117db924cf7c | 5301 | XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5302 | |
wolfSSL | 15:117db924cf7c | 5303 | (void)heap; |
wolfSSL | 15:117db924cf7c | 5304 | } |
wolfSSL | 15:117db924cf7c | 5305 | #endif /* WOLFSSL_CUSTOM_CURVES */ |
wolfSSL | 15:117db924cf7c | 5306 | |
wolfSSL | 15:117db924cf7c | 5307 | /** |
wolfSSL | 15:117db924cf7c | 5308 | Free an ECC key from memory |
wolfSSL | 15:117db924cf7c | 5309 | key The key you wish to free |
wolfSSL | 15:117db924cf7c | 5310 | */ |
wolfSSL | 16:8e0d178b1d1e | 5311 | WOLFSSL_ABI |
wolfSSL | 15:117db924cf7c | 5312 | int wc_ecc_free(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 5313 | { |
wolfSSL | 15:117db924cf7c | 5314 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 5315 | return 0; |
wolfSSL | 15:117db924cf7c | 5316 | } |
wolfSSL | 15:117db924cf7c | 5317 | |
wolfSSL | 16:8e0d178b1d1e | 5318 | #ifdef WOLFSSL_ECDSA_SET_K |
wolfSSL | 16:8e0d178b1d1e | 5319 | if (key->sign_k != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 5320 | mp_forcezero(key->sign_k); |
wolfSSL | 16:8e0d178b1d1e | 5321 | mp_free(key->sign_k); |
wolfSSL | 16:8e0d178b1d1e | 5322 | XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5323 | } |
wolfSSL | 16:8e0d178b1d1e | 5324 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5325 | |
wolfSSL | 16:8e0d178b1d1e | 5326 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 5327 | #ifdef WC_ASYNC_ENABLE_ECC |
wolfSSL | 15:117db924cf7c | 5328 | wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); |
wolfSSL | 15:117db924cf7c | 5329 | #endif |
wolfSSL | 15:117db924cf7c | 5330 | wc_ecc_free_async(key); |
wolfSSL | 15:117db924cf7c | 5331 | #endif |
wolfSSL | 15:117db924cf7c | 5332 | |
wolfSSL | 15:117db924cf7c | 5333 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 5334 | atmel_ecc_free(key->slot); |
wolfSSL | 16:8e0d178b1d1e | 5335 | key->slot = ATECC_INVALID_SLOT; |
wolfSSL | 16:8e0d178b1d1e | 5336 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 5337 | |
wolfSSL | 15:117db924cf7c | 5338 | mp_clear(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 5339 | mp_clear(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 5340 | mp_clear(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 5341 | |
wolfSSL | 15:117db924cf7c | 5342 | mp_forcezero(&key->k); |
wolfSSL | 15:117db924cf7c | 5343 | |
wolfSSL | 15:117db924cf7c | 5344 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 5345 | if (key->deallocSet && key->dp != NULL) |
wolfSSL | 15:117db924cf7c | 5346 | wc_ecc_free_curve(key->dp, key->heap); |
wolfSSL | 15:117db924cf7c | 5347 | #endif |
wolfSSL | 15:117db924cf7c | 5348 | |
wolfSSL | 15:117db924cf7c | 5349 | return 0; |
wolfSSL | 15:117db924cf7c | 5350 | } |
wolfSSL | 15:117db924cf7c | 5351 | |
wolfSSL | 16:8e0d178b1d1e | 5352 | #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 5353 | #ifdef ECC_SHAMIR |
wolfSSL | 15:117db924cf7c | 5354 | |
wolfSSL | 15:117db924cf7c | 5355 | /** Computes kA*A + kB*B = C using Shamir's Trick |
wolfSSL | 15:117db924cf7c | 5356 | A First point to multiply |
wolfSSL | 15:117db924cf7c | 5357 | kA What to multiple A by |
wolfSSL | 15:117db924cf7c | 5358 | B Second point to multiply |
wolfSSL | 15:117db924cf7c | 5359 | kB What to multiple B by |
wolfSSL | 15:117db924cf7c | 5360 | C [out] Destination point (can overlap with A or B) |
wolfSSL | 15:117db924cf7c | 5361 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 5362 | modulus Modulus for curve |
wolfSSL | 15:117db924cf7c | 5363 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 5364 | */ |
wolfSSL | 15:117db924cf7c | 5365 | #ifdef FP_ECC |
wolfSSL | 15:117db924cf7c | 5366 | static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 15:117db924cf7c | 5367 | ecc_point* B, mp_int* kB, |
wolfSSL | 15:117db924cf7c | 5368 | ecc_point* C, mp_int* a, mp_int* modulus, |
wolfSSL | 15:117db924cf7c | 5369 | void* heap) |
wolfSSL | 15:117db924cf7c | 5370 | #else |
wolfSSL | 15:117db924cf7c | 5371 | int ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 15:117db924cf7c | 5372 | ecc_point* B, mp_int* kB, |
wolfSSL | 15:117db924cf7c | 5373 | ecc_point* C, mp_int* a, mp_int* modulus, |
wolfSSL | 15:117db924cf7c | 5374 | void* heap) |
wolfSSL | 15:117db924cf7c | 5375 | #endif |
wolfSSL | 15:117db924cf7c | 5376 | { |
wolfSSL | 16:8e0d178b1d1e | 5377 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 16:8e0d178b1d1e | 5378 | ecc_key key; |
wolfSSL | 16:8e0d178b1d1e | 5379 | #endif |
wolfSSL | 15:117db924cf7c | 5380 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5381 | ecc_point** precomp = NULL; |
wolfSSL | 15:117db924cf7c | 5382 | #else |
wolfSSL | 15:117db924cf7c | 5383 | ecc_point* precomp[SHAMIR_PRECOMP_SZ]; |
wolfSSL | 15:117db924cf7c | 5384 | #endif |
wolfSSL | 15:117db924cf7c | 5385 | unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble; |
wolfSSL | 15:117db924cf7c | 5386 | unsigned char* tA; |
wolfSSL | 15:117db924cf7c | 5387 | unsigned char* tB; |
wolfSSL | 15:117db924cf7c | 5388 | int err = MP_OKAY, first, x, y; |
wolfSSL | 15:117db924cf7c | 5389 | mp_digit mp = 0; |
wolfSSL | 15:117db924cf7c | 5390 | |
wolfSSL | 15:117db924cf7c | 5391 | /* argchks */ |
wolfSSL | 15:117db924cf7c | 5392 | if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || |
wolfSSL | 15:117db924cf7c | 5393 | modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 5394 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 5395 | } |
wolfSSL | 15:117db924cf7c | 5396 | |
wolfSSL | 15:117db924cf7c | 5397 | /* allocate memory */ |
wolfSSL | 15:117db924cf7c | 5398 | tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5399 | if (tA == NULL) { |
wolfSSL | 15:117db924cf7c | 5400 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 5401 | } |
wolfSSL | 15:117db924cf7c | 5402 | tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5403 | if (tB == NULL) { |
wolfSSL | 15:117db924cf7c | 5404 | XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5405 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 5406 | } |
wolfSSL | 15:117db924cf7c | 5407 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5408 | precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap, |
wolfSSL | 15:117db924cf7c | 5409 | DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5410 | if (precomp == NULL) { |
wolfSSL | 15:117db924cf7c | 5411 | XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5412 | XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5413 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 5414 | } |
wolfSSL | 15:117db924cf7c | 5415 | #endif |
wolfSSL | 15:117db924cf7c | 5416 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 5417 | key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5418 | key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5419 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 5420 | key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5421 | key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5422 | key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5423 | #endif |
wolfSSL | 15:117db924cf7c | 5424 | if (key.t1 == NULL || key.t2 == NULL |
wolfSSL | 15:117db924cf7c | 5425 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 5426 | || key.x == NULL || key.y == NULL || key.z == NULL |
wolfSSL | 15:117db924cf7c | 5427 | #endif |
wolfSSL | 15:117db924cf7c | 5428 | ) { |
wolfSSL | 15:117db924cf7c | 5429 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 5430 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5431 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5432 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5433 | #endif |
wolfSSL | 15:117db924cf7c | 5434 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5435 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5436 | XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5437 | XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5438 | XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5439 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5440 | } |
wolfSSL | 15:117db924cf7c | 5441 | C->key = &key; |
wolfSSL | 15:117db924cf7c | 5442 | #endif /* WOLFSSL_SMALL_STACK_CACHE */ |
wolfSSL | 15:117db924cf7c | 5443 | |
wolfSSL | 15:117db924cf7c | 5444 | /* init variables */ |
wolfSSL | 15:117db924cf7c | 5445 | XMEMSET(tA, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 5446 | XMEMSET(tB, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 5447 | #ifndef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5448 | XMEMSET(precomp, 0, sizeof(precomp)); |
wolfSSL | 15:117db924cf7c | 5449 | #else |
wolfSSL | 15:117db924cf7c | 5450 | XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ); |
wolfSSL | 15:117db924cf7c | 5451 | #endif |
wolfSSL | 15:117db924cf7c | 5452 | |
wolfSSL | 15:117db924cf7c | 5453 | /* get sizes */ |
wolfSSL | 15:117db924cf7c | 5454 | lenA = mp_unsigned_bin_size(kA); |
wolfSSL | 15:117db924cf7c | 5455 | lenB = mp_unsigned_bin_size(kB); |
wolfSSL | 15:117db924cf7c | 5456 | len = MAX(lenA, lenB); |
wolfSSL | 15:117db924cf7c | 5457 | |
wolfSSL | 15:117db924cf7c | 5458 | /* sanity check */ |
wolfSSL | 15:117db924cf7c | 5459 | if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { |
wolfSSL | 15:117db924cf7c | 5460 | err = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 5461 | } |
wolfSSL | 15:117db924cf7c | 5462 | |
wolfSSL | 15:117db924cf7c | 5463 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5464 | /* extract and justify kA */ |
wolfSSL | 15:117db924cf7c | 5465 | err = mp_to_unsigned_bin(kA, (len - lenA) + tA); |
wolfSSL | 15:117db924cf7c | 5466 | |
wolfSSL | 15:117db924cf7c | 5467 | /* extract and justify kB */ |
wolfSSL | 15:117db924cf7c | 5468 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5469 | err = mp_to_unsigned_bin(kB, (len - lenB) + tB); |
wolfSSL | 15:117db924cf7c | 5470 | |
wolfSSL | 15:117db924cf7c | 5471 | /* allocate the table */ |
wolfSSL | 15:117db924cf7c | 5472 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5473 | for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) { |
wolfSSL | 15:117db924cf7c | 5474 | precomp[x] = wc_ecc_new_point_h(heap); |
wolfSSL | 15:117db924cf7c | 5475 | if (precomp[x] == NULL) { |
wolfSSL | 15:117db924cf7c | 5476 | err = GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 5477 | break; |
wolfSSL | 15:117db924cf7c | 5478 | } |
wolfSSL | 15:117db924cf7c | 5479 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 5480 | precomp[x]->key = &key; |
wolfSSL | 15:117db924cf7c | 5481 | #endif |
wolfSSL | 15:117db924cf7c | 5482 | } |
wolfSSL | 15:117db924cf7c | 5483 | } |
wolfSSL | 15:117db924cf7c | 5484 | } |
wolfSSL | 15:117db924cf7c | 5485 | |
wolfSSL | 15:117db924cf7c | 5486 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5487 | /* init montgomery reduction */ |
wolfSSL | 15:117db924cf7c | 5488 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 5489 | |
wolfSSL | 15:117db924cf7c | 5490 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5491 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 5492 | mp_int* mu; |
wolfSSL | 15:117db924cf7c | 5493 | #else |
wolfSSL | 15:117db924cf7c | 5494 | mp_int mu[1]; |
wolfSSL | 15:117db924cf7c | 5495 | #endif |
wolfSSL | 15:117db924cf7c | 5496 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5497 | mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5498 | if (mu == NULL) |
wolfSSL | 15:117db924cf7c | 5499 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5500 | #endif |
wolfSSL | 15:117db924cf7c | 5501 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5502 | err = mp_init(mu); |
wolfSSL | 15:117db924cf7c | 5503 | } |
wolfSSL | 15:117db924cf7c | 5504 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5505 | err = mp_montgomery_calc_normalization(mu, modulus); |
wolfSSL | 15:117db924cf7c | 5506 | |
wolfSSL | 15:117db924cf7c | 5507 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5508 | /* copy ones ... */ |
wolfSSL | 15:117db924cf7c | 5509 | err = mp_mulmod(A->x, mu, modulus, precomp[1]->x); |
wolfSSL | 15:117db924cf7c | 5510 | |
wolfSSL | 15:117db924cf7c | 5511 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5512 | err = mp_mulmod(A->y, mu, modulus, precomp[1]->y); |
wolfSSL | 15:117db924cf7c | 5513 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5514 | err = mp_mulmod(A->z, mu, modulus, precomp[1]->z); |
wolfSSL | 15:117db924cf7c | 5515 | |
wolfSSL | 15:117db924cf7c | 5516 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5517 | err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x); |
wolfSSL | 15:117db924cf7c | 5518 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5519 | err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y); |
wolfSSL | 15:117db924cf7c | 5520 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5521 | err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z); |
wolfSSL | 15:117db924cf7c | 5522 | |
wolfSSL | 15:117db924cf7c | 5523 | /* done with mu */ |
wolfSSL | 15:117db924cf7c | 5524 | mp_clear(mu); |
wolfSSL | 16:8e0d178b1d1e | 5525 | } |
wolfSSL | 15:117db924cf7c | 5526 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 5527 | if (mu != NULL) { |
wolfSSL | 15:117db924cf7c | 5528 | XFREE(mu, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5529 | } |
wolfSSL | 15:117db924cf7c | 5530 | #endif |
wolfSSL | 15:117db924cf7c | 5531 | } |
wolfSSL | 15:117db924cf7c | 5532 | |
wolfSSL | 15:117db924cf7c | 5533 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5534 | /* precomp [i,0](A + B) table */ |
wolfSSL | 15:117db924cf7c | 5535 | err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5536 | |
wolfSSL | 15:117db924cf7c | 5537 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5538 | err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], |
wolfSSL | 15:117db924cf7c | 5539 | a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5540 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5541 | /* precomp [0,i](A + B) table */ |
wolfSSL | 15:117db924cf7c | 5542 | err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5543 | |
wolfSSL | 15:117db924cf7c | 5544 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5545 | err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], |
wolfSSL | 15:117db924cf7c | 5546 | a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5547 | |
wolfSSL | 15:117db924cf7c | 5548 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5549 | /* precomp [i,j](A + B) table (i != 0, j != 0) */ |
wolfSSL | 15:117db924cf7c | 5550 | for (x = 1; x < 4; x++) { |
wolfSSL | 15:117db924cf7c | 5551 | for (y = 1; y < 4; y++) { |
wolfSSL | 15:117db924cf7c | 5552 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5553 | err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], |
wolfSSL | 15:117db924cf7c | 5554 | precomp[x+(y<<2)], a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5555 | } |
wolfSSL | 15:117db924cf7c | 5556 | } |
wolfSSL | 15:117db924cf7c | 5557 | } |
wolfSSL | 15:117db924cf7c | 5558 | } |
wolfSSL | 15:117db924cf7c | 5559 | |
wolfSSL | 15:117db924cf7c | 5560 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5561 | nibble = 3; |
wolfSSL | 15:117db924cf7c | 5562 | first = 1; |
wolfSSL | 15:117db924cf7c | 5563 | bitbufA = tA[0]; |
wolfSSL | 15:117db924cf7c | 5564 | bitbufB = tB[0]; |
wolfSSL | 15:117db924cf7c | 5565 | |
wolfSSL | 15:117db924cf7c | 5566 | /* for every byte of the multiplicands */ |
wolfSSL | 15:117db924cf7c | 5567 | for (x = 0;; ) { |
wolfSSL | 15:117db924cf7c | 5568 | /* grab a nibble */ |
wolfSSL | 15:117db924cf7c | 5569 | if (++nibble == 4) { |
wolfSSL | 15:117db924cf7c | 5570 | if (x == (int)len) break; |
wolfSSL | 15:117db924cf7c | 5571 | bitbufA = tA[x]; |
wolfSSL | 15:117db924cf7c | 5572 | bitbufB = tB[x]; |
wolfSSL | 15:117db924cf7c | 5573 | nibble = 0; |
wolfSSL | 15:117db924cf7c | 5574 | x++; |
wolfSSL | 15:117db924cf7c | 5575 | } |
wolfSSL | 15:117db924cf7c | 5576 | |
wolfSSL | 15:117db924cf7c | 5577 | /* extract two bits from both, shift/update */ |
wolfSSL | 15:117db924cf7c | 5578 | nA = (bitbufA >> 6) & 0x03; |
wolfSSL | 15:117db924cf7c | 5579 | nB = (bitbufB >> 6) & 0x03; |
wolfSSL | 15:117db924cf7c | 5580 | bitbufA = (bitbufA << 2) & 0xFF; |
wolfSSL | 15:117db924cf7c | 5581 | bitbufB = (bitbufB << 2) & 0xFF; |
wolfSSL | 15:117db924cf7c | 5582 | |
wolfSSL | 15:117db924cf7c | 5583 | /* if both zero, if first, continue */ |
wolfSSL | 15:117db924cf7c | 5584 | if ((nA == 0) && (nB == 0) && (first == 1)) { |
wolfSSL | 15:117db924cf7c | 5585 | continue; |
wolfSSL | 15:117db924cf7c | 5586 | } |
wolfSSL | 15:117db924cf7c | 5587 | |
wolfSSL | 15:117db924cf7c | 5588 | /* double twice, only if this isn't the first */ |
wolfSSL | 15:117db924cf7c | 5589 | if (first == 0) { |
wolfSSL | 15:117db924cf7c | 5590 | /* double twice */ |
wolfSSL | 15:117db924cf7c | 5591 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5592 | err = ecc_projective_dbl_point(C, C, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5593 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5594 | err = ecc_projective_dbl_point(C, C, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5595 | else |
wolfSSL | 15:117db924cf7c | 5596 | break; |
wolfSSL | 15:117db924cf7c | 5597 | } |
wolfSSL | 15:117db924cf7c | 5598 | |
wolfSSL | 15:117db924cf7c | 5599 | /* if not both zero */ |
wolfSSL | 15:117db924cf7c | 5600 | if ((nA != 0) || (nB != 0)) { |
wolfSSL | 15:117db924cf7c | 5601 | if (first == 1) { |
wolfSSL | 15:117db924cf7c | 5602 | /* if first, copy from table */ |
wolfSSL | 15:117db924cf7c | 5603 | first = 0; |
wolfSSL | 15:117db924cf7c | 5604 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5605 | err = mp_copy(precomp[nA + (nB<<2)]->x, C->x); |
wolfSSL | 15:117db924cf7c | 5606 | |
wolfSSL | 15:117db924cf7c | 5607 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5608 | err = mp_copy(precomp[nA + (nB<<2)]->y, C->y); |
wolfSSL | 15:117db924cf7c | 5609 | |
wolfSSL | 15:117db924cf7c | 5610 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5611 | err = mp_copy(precomp[nA + (nB<<2)]->z, C->z); |
wolfSSL | 15:117db924cf7c | 5612 | else |
wolfSSL | 15:117db924cf7c | 5613 | break; |
wolfSSL | 15:117db924cf7c | 5614 | } else { |
wolfSSL | 15:117db924cf7c | 5615 | /* if not first, add from table */ |
wolfSSL | 15:117db924cf7c | 5616 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5617 | err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, |
wolfSSL | 15:117db924cf7c | 5618 | a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 5619 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5620 | break; |
wolfSSL | 16:8e0d178b1d1e | 5621 | if (mp_iszero(C->z)) { |
wolfSSL | 16:8e0d178b1d1e | 5622 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 5623 | if (mp_iszero(C->x) && mp_iszero(C->y)) { |
wolfSSL | 16:8e0d178b1d1e | 5624 | err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C, |
wolfSSL | 16:8e0d178b1d1e | 5625 | a, modulus, mp); |
wolfSSL | 16:8e0d178b1d1e | 5626 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 5627 | break; |
wolfSSL | 16:8e0d178b1d1e | 5628 | } |
wolfSSL | 16:8e0d178b1d1e | 5629 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 5630 | else { |
wolfSSL | 16:8e0d178b1d1e | 5631 | err = mp_set(C->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 5632 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 5633 | break; |
wolfSSL | 16:8e0d178b1d1e | 5634 | err = mp_set(C->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 5635 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 5636 | break; |
wolfSSL | 16:8e0d178b1d1e | 5637 | err = mp_set(C->z, 1); |
wolfSSL | 16:8e0d178b1d1e | 5638 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 5639 | break; |
wolfSSL | 16:8e0d178b1d1e | 5640 | first = 1; |
wolfSSL | 16:8e0d178b1d1e | 5641 | } |
wolfSSL | 16:8e0d178b1d1e | 5642 | } |
wolfSSL | 15:117db924cf7c | 5643 | } |
wolfSSL | 15:117db924cf7c | 5644 | } |
wolfSSL | 15:117db924cf7c | 5645 | } |
wolfSSL | 15:117db924cf7c | 5646 | } |
wolfSSL | 15:117db924cf7c | 5647 | |
wolfSSL | 15:117db924cf7c | 5648 | /* reduce to affine */ |
wolfSSL | 15:117db924cf7c | 5649 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 5650 | err = ecc_map(C, modulus, mp); |
wolfSSL | 15:117db924cf7c | 5651 | |
wolfSSL | 15:117db924cf7c | 5652 | /* clean up */ |
wolfSSL | 15:117db924cf7c | 5653 | for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) { |
wolfSSL | 15:117db924cf7c | 5654 | wc_ecc_del_point_h(precomp[x], heap); |
wolfSSL | 15:117db924cf7c | 5655 | } |
wolfSSL | 15:117db924cf7c | 5656 | |
wolfSSL | 15:117db924cf7c | 5657 | ForceZero(tA, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 5658 | ForceZero(tB, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 5659 | #ifdef WOLFSSL_SMALL_STACK_CACHE |
wolfSSL | 15:117db924cf7c | 5660 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 5661 | XFREE(key.z, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5662 | XFREE(key.y, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5663 | XFREE(key.x, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5664 | #endif |
wolfSSL | 15:117db924cf7c | 5665 | XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5666 | XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5667 | C->key = NULL; |
wolfSSL | 15:117db924cf7c | 5668 | #endif |
wolfSSL | 15:117db924cf7c | 5669 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5670 | XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5671 | #endif |
wolfSSL | 15:117db924cf7c | 5672 | XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5673 | XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 5674 | |
wolfSSL | 15:117db924cf7c | 5675 | return err; |
wolfSSL | 15:117db924cf7c | 5676 | } |
wolfSSL | 15:117db924cf7c | 5677 | |
wolfSSL | 15:117db924cf7c | 5678 | #endif /* ECC_SHAMIR */ |
wolfSSL | 16:8e0d178b1d1e | 5679 | #endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/ |
wolfSSL | 15:117db924cf7c | 5680 | |
wolfSSL | 15:117db924cf7c | 5681 | |
wolfSSL | 15:117db924cf7c | 5682 | #ifdef HAVE_ECC_VERIFY |
wolfSSL | 15:117db924cf7c | 5683 | #ifndef NO_ASN |
wolfSSL | 15:117db924cf7c | 5684 | /* verify |
wolfSSL | 15:117db924cf7c | 5685 | * |
wolfSSL | 15:117db924cf7c | 5686 | * w = s^-1 mod n |
wolfSSL | 15:117db924cf7c | 5687 | * u1 = xw |
wolfSSL | 15:117db924cf7c | 5688 | * u2 = rw |
wolfSSL | 15:117db924cf7c | 5689 | * X = u1*G + u2*Q |
wolfSSL | 15:117db924cf7c | 5690 | * v = X_x1 mod n |
wolfSSL | 15:117db924cf7c | 5691 | * accept if v == r |
wolfSSL | 15:117db924cf7c | 5692 | */ |
wolfSSL | 15:117db924cf7c | 5693 | |
wolfSSL | 15:117db924cf7c | 5694 | /** |
wolfSSL | 15:117db924cf7c | 5695 | Verify an ECC signature |
wolfSSL | 15:117db924cf7c | 5696 | sig The signature to verify |
wolfSSL | 15:117db924cf7c | 5697 | siglen The length of the signature (octets) |
wolfSSL | 15:117db924cf7c | 5698 | hash The hash (message digest) that was signed |
wolfSSL | 15:117db924cf7c | 5699 | hashlen The length of the hash (octets) |
wolfSSL | 15:117db924cf7c | 5700 | res Result of signature, 1==valid, 0==invalid |
wolfSSL | 15:117db924cf7c | 5701 | key The corresponding public ECC key |
wolfSSL | 15:117db924cf7c | 5702 | return MP_OKAY if successful (even if the signature is not valid) |
wolfSSL | 15:117db924cf7c | 5703 | */ |
wolfSSL | 15:117db924cf7c | 5704 | int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, |
wolfSSL | 15:117db924cf7c | 5705 | word32 hashlen, int* res, ecc_key* key) |
wolfSSL | 15:117db924cf7c | 5706 | { |
wolfSSL | 15:117db924cf7c | 5707 | int err; |
wolfSSL | 15:117db924cf7c | 5708 | mp_int *r = NULL, *s = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5709 | #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)) && \ |
wolfSSL | 16:8e0d178b1d1e | 5710 | !defined(WOLFSSL_SMALL_STACK) |
wolfSSL | 16:8e0d178b1d1e | 5711 | mp_int r_lcl, s_lcl; |
wolfSSL | 15:117db924cf7c | 5712 | #endif |
wolfSSL | 15:117db924cf7c | 5713 | |
wolfSSL | 15:117db924cf7c | 5714 | if (sig == NULL || hash == NULL || res == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 5715 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 5716 | } |
wolfSSL | 15:117db924cf7c | 5717 | |
wolfSSL | 16:8e0d178b1d1e | 5718 | #ifdef WOLF_CRYPTO_CB |
wolfSSL | 15:117db924cf7c | 5719 | if (key->devId != INVALID_DEVID) { |
wolfSSL | 16:8e0d178b1d1e | 5720 | err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key); |
wolfSSL | 16:8e0d178b1d1e | 5721 | if (err != CRYPTOCB_UNAVAILABLE) |
wolfSSL | 15:117db924cf7c | 5722 | return err; |
wolfSSL | 16:8e0d178b1d1e | 5723 | /* fall-through when unavailable */ |
wolfSSL | 16:8e0d178b1d1e | 5724 | } |
wolfSSL | 16:8e0d178b1d1e | 5725 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5726 | |
wolfSSL | 16:8e0d178b1d1e | 5727 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 5728 | err = wc_ecc_alloc_async(key); |
wolfSSL | 15:117db924cf7c | 5729 | if (err != 0) |
wolfSSL | 15:117db924cf7c | 5730 | return err; |
wolfSSL | 15:117db924cf7c | 5731 | r = key->r; |
wolfSSL | 15:117db924cf7c | 5732 | s = key->s; |
wolfSSL | 15:117db924cf7c | 5733 | #else |
wolfSSL | 16:8e0d178b1d1e | 5734 | #ifndef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 5735 | r = &r_lcl; |
wolfSSL | 16:8e0d178b1d1e | 5736 | s = &s_lcl; |
wolfSSL | 16:8e0d178b1d1e | 5737 | #else |
wolfSSL | 15:117db924cf7c | 5738 | r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5739 | if (r == NULL) |
wolfSSL | 15:117db924cf7c | 5740 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5741 | s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5742 | if (s == NULL) { |
wolfSSL | 15:117db924cf7c | 5743 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5744 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 5745 | } |
wolfSSL | 16:8e0d178b1d1e | 5746 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5747 | XMEMSET(r, 0, sizeof(mp_int)); |
wolfSSL | 16:8e0d178b1d1e | 5748 | XMEMSET(s, 0, sizeof(mp_int)); |
wolfSSL | 16:8e0d178b1d1e | 5749 | #endif /* WOLFSSL_ASYNC_CRYPT */ |
wolfSSL | 16:8e0d178b1d1e | 5750 | |
wolfSSL | 16:8e0d178b1d1e | 5751 | switch (key->state) { |
wolfSSL | 15:117db924cf7c | 5752 | case ECC_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 5753 | case ECC_STATE_VERIFY_DECODE: |
wolfSSL | 15:117db924cf7c | 5754 | key->state = ECC_STATE_VERIFY_DECODE; |
wolfSSL | 15:117db924cf7c | 5755 | |
wolfSSL | 15:117db924cf7c | 5756 | /* default to invalid signature */ |
wolfSSL | 15:117db924cf7c | 5757 | *res = 0; |
wolfSSL | 15:117db924cf7c | 5758 | |
wolfSSL | 15:117db924cf7c | 5759 | /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. |
wolfSSL | 15:117db924cf7c | 5760 | * If either of those don't allocate correctly, none of |
wolfSSL | 15:117db924cf7c | 5761 | * the rest of this function will execute, and everything |
wolfSSL | 15:117db924cf7c | 5762 | * gets cleaned up at the end. */ |
wolfSSL | 15:117db924cf7c | 5763 | /* decode DSA header */ |
wolfSSL | 15:117db924cf7c | 5764 | err = DecodeECC_DSA_Sig(sig, siglen, r, s); |
wolfSSL | 15:117db924cf7c | 5765 | if (err < 0) { |
wolfSSL | 15:117db924cf7c | 5766 | break; |
wolfSSL | 15:117db924cf7c | 5767 | } |
wolfSSL | 15:117db924cf7c | 5768 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 5769 | |
wolfSSL | 15:117db924cf7c | 5770 | case ECC_STATE_VERIFY_DO: |
wolfSSL | 15:117db924cf7c | 5771 | key->state = ECC_STATE_VERIFY_DO; |
wolfSSL | 15:117db924cf7c | 5772 | |
wolfSSL | 15:117db924cf7c | 5773 | err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key); |
wolfSSL | 15:117db924cf7c | 5774 | |
wolfSSL | 15:117db924cf7c | 5775 | #ifndef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 5776 | /* done with R/S */ |
wolfSSL | 15:117db924cf7c | 5777 | mp_clear(r); |
wolfSSL | 15:117db924cf7c | 5778 | mp_clear(s); |
wolfSSL | 15:117db924cf7c | 5779 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5780 | XFREE(s, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 5781 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5782 | r = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5783 | s = NULL; |
wolfSSL | 15:117db924cf7c | 5784 | #endif |
wolfSSL | 15:117db924cf7c | 5785 | #endif |
wolfSSL | 15:117db924cf7c | 5786 | |
wolfSSL | 15:117db924cf7c | 5787 | if (err < 0) { |
wolfSSL | 15:117db924cf7c | 5788 | break; |
wolfSSL | 15:117db924cf7c | 5789 | } |
wolfSSL | 15:117db924cf7c | 5790 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 5791 | |
wolfSSL | 15:117db924cf7c | 5792 | case ECC_STATE_VERIFY_RES: |
wolfSSL | 15:117db924cf7c | 5793 | key->state = ECC_STATE_VERIFY_RES; |
wolfSSL | 15:117db924cf7c | 5794 | err = 0; |
wolfSSL | 15:117db924cf7c | 5795 | break; |
wolfSSL | 15:117db924cf7c | 5796 | |
wolfSSL | 15:117db924cf7c | 5797 | default: |
wolfSSL | 15:117db924cf7c | 5798 | err = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 5799 | } |
wolfSSL | 15:117db924cf7c | 5800 | |
wolfSSL | 15:117db924cf7c | 5801 | /* if async pending then return and skip done cleanup below */ |
wolfSSL | 15:117db924cf7c | 5802 | if (err == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 5803 | key->state++; |
wolfSSL | 15:117db924cf7c | 5804 | return err; |
wolfSSL | 15:117db924cf7c | 5805 | } |
wolfSSL | 15:117db924cf7c | 5806 | |
wolfSSL | 15:117db924cf7c | 5807 | /* cleanup */ |
wolfSSL | 16:8e0d178b1d1e | 5808 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 5809 | wc_ecc_free_async(key); |
wolfSSL | 16:8e0d178b1d1e | 5810 | #elif defined(WOLFSSL_SMALL_STACK) |
wolfSSL | 16:8e0d178b1d1e | 5811 | XFREE(s, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5812 | XFREE(r, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 16:8e0d178b1d1e | 5813 | r = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5814 | s = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5815 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5816 | |
wolfSSL | 15:117db924cf7c | 5817 | key->state = ECC_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 5818 | |
wolfSSL | 15:117db924cf7c | 5819 | return err; |
wolfSSL | 15:117db924cf7c | 5820 | } |
wolfSSL | 15:117db924cf7c | 5821 | #endif /* !NO_ASN */ |
wolfSSL | 15:117db924cf7c | 5822 | |
wolfSSL | 15:117db924cf7c | 5823 | |
wolfSSL | 15:117db924cf7c | 5824 | /** |
wolfSSL | 15:117db924cf7c | 5825 | Verify an ECC signature |
wolfSSL | 15:117db924cf7c | 5826 | r The signature R component to verify |
wolfSSL | 15:117db924cf7c | 5827 | s The signature S component to verify |
wolfSSL | 15:117db924cf7c | 5828 | hash The hash (message digest) that was signed |
wolfSSL | 15:117db924cf7c | 5829 | hashlen The length of the hash (octets) |
wolfSSL | 15:117db924cf7c | 5830 | res Result of signature, 1==valid, 0==invalid |
wolfSSL | 15:117db924cf7c | 5831 | key The corresponding public ECC key |
wolfSSL | 15:117db924cf7c | 5832 | return MP_OKAY if successful (even if the signature is not valid) |
wolfSSL | 15:117db924cf7c | 5833 | */ |
wolfSSL | 16:8e0d178b1d1e | 5834 | |
wolfSSL | 15:117db924cf7c | 5835 | int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, |
wolfSSL | 15:117db924cf7c | 5836 | word32 hashlen, int* res, ecc_key* key) |
wolfSSL | 16:8e0d178b1d1e | 5837 | #if defined(WOLFSSL_STM32_PKA) |
wolfSSL | 16:8e0d178b1d1e | 5838 | { |
wolfSSL | 16:8e0d178b1d1e | 5839 | return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key); |
wolfSSL | 16:8e0d178b1d1e | 5840 | } |
wolfSSL | 16:8e0d178b1d1e | 5841 | #else |
wolfSSL | 15:117db924cf7c | 5842 | { |
wolfSSL | 15:117db924cf7c | 5843 | int err; |
wolfSSL | 16:8e0d178b1d1e | 5844 | word32 keySz; |
wolfSSL | 15:117db924cf7c | 5845 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 5846 | byte sigRS[ATECC_KEY_SIZE*2]; |
wolfSSL | 16:8e0d178b1d1e | 5847 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 5848 | byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2]; |
wolfSSL | 16:8e0d178b1d1e | 5849 | CRYS_ECDSA_VerifyUserContext_t sigCtxTemp; |
wolfSSL | 16:8e0d178b1d1e | 5850 | word32 msgLenInBytes = hashlen; |
wolfSSL | 16:8e0d178b1d1e | 5851 | CRYS_ECPKI_HASH_OpMode_t hash_mode; |
wolfSSL | 16:8e0d178b1d1e | 5852 | #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) |
wolfSSL | 15:117db924cf7c | 5853 | int did_init = 0; |
wolfSSL | 15:117db924cf7c | 5854 | ecc_point *mG = NULL, *mQ = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5855 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 5856 | mp_int* v = NULL; |
wolfSSL | 15:117db924cf7c | 5857 | mp_int* w = NULL; |
wolfSSL | 15:117db924cf7c | 5858 | mp_int* u1 = NULL; |
wolfSSL | 15:117db924cf7c | 5859 | mp_int* u2 = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5860 | #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) |
wolfSSL | 15:117db924cf7c | 5861 | mp_int* e_lcl = NULL; |
wolfSSL | 16:8e0d178b1d1e | 5862 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5863 | #else /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 5864 | mp_int v[1]; |
wolfSSL | 15:117db924cf7c | 5865 | mp_int w[1]; |
wolfSSL | 15:117db924cf7c | 5866 | mp_int u1[1]; |
wolfSSL | 15:117db924cf7c | 5867 | mp_int u2[1]; |
wolfSSL | 16:8e0d178b1d1e | 5868 | #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) |
wolfSSL | 15:117db924cf7c | 5869 | mp_int e_lcl[1]; |
wolfSSL | 16:8e0d178b1d1e | 5870 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5871 | #endif /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 5872 | mp_int* e; |
wolfSSL | 15:117db924cf7c | 5873 | DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); |
wolfSSL | 15:117db924cf7c | 5874 | #endif |
wolfSSL | 15:117db924cf7c | 5875 | |
wolfSSL | 15:117db924cf7c | 5876 | if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) |
wolfSSL | 15:117db924cf7c | 5877 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 5878 | |
wolfSSL | 15:117db924cf7c | 5879 | /* default to invalid signature */ |
wolfSSL | 15:117db924cf7c | 5880 | *res = 0; |
wolfSSL | 15:117db924cf7c | 5881 | |
wolfSSL | 15:117db924cf7c | 5882 | /* is the IDX valid ? */ |
wolfSSL | 15:117db924cf7c | 5883 | if (wc_ecc_is_valid_idx(key->idx) != 1) { |
wolfSSL | 15:117db924cf7c | 5884 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 5885 | } |
wolfSSL | 15:117db924cf7c | 5886 | |
wolfSSL | 16:8e0d178b1d1e | 5887 | keySz = key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 5888 | |
wolfSSL | 15:117db924cf7c | 5889 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ |
wolfSSL | 15:117db924cf7c | 5890 | defined(WOLFSSL_ASYNC_CRYPT_TEST) |
wolfSSL | 15:117db924cf7c | 5891 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 5892 | if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) { |
wolfSSL | 15:117db924cf7c | 5893 | WC_ASYNC_TEST* testDev = &key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 5894 | testDev->eccVerify.r = r; |
wolfSSL | 15:117db924cf7c | 5895 | testDev->eccVerify.s = s; |
wolfSSL | 15:117db924cf7c | 5896 | testDev->eccVerify.hash = hash; |
wolfSSL | 15:117db924cf7c | 5897 | testDev->eccVerify.hashlen = hashlen; |
wolfSSL | 15:117db924cf7c | 5898 | testDev->eccVerify.stat = res; |
wolfSSL | 15:117db924cf7c | 5899 | testDev->eccVerify.key = key; |
wolfSSL | 15:117db924cf7c | 5900 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 5901 | } |
wolfSSL | 15:117db924cf7c | 5902 | } |
wolfSSL | 15:117db924cf7c | 5903 | #endif |
wolfSSL | 15:117db924cf7c | 5904 | |
wolfSSL | 15:117db924cf7c | 5905 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 5906 | /* Extract R and S */ |
wolfSSL | 15:117db924cf7c | 5907 | err = mp_to_unsigned_bin(r, &sigRS[0]); |
wolfSSL | 15:117db924cf7c | 5908 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5909 | return err; |
wolfSSL | 15:117db924cf7c | 5910 | } |
wolfSSL | 16:8e0d178b1d1e | 5911 | err = mp_to_unsigned_bin(s, &sigRS[keySz]); |
wolfSSL | 15:117db924cf7c | 5912 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5913 | return err; |
wolfSSL | 15:117db924cf7c | 5914 | } |
wolfSSL | 15:117db924cf7c | 5915 | |
wolfSSL | 16:8e0d178b1d1e | 5916 | err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); |
wolfSSL | 16:8e0d178b1d1e | 5917 | if (err != 0) { |
wolfSSL | 16:8e0d178b1d1e | 5918 | return err; |
wolfSSL | 15:117db924cf7c | 5919 | } |
wolfSSL | 15:117db924cf7c | 5920 | (void)hashlen; |
wolfSSL | 16:8e0d178b1d1e | 5921 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 5922 | |
wolfSSL | 16:8e0d178b1d1e | 5923 | /* Extract R and S */ |
wolfSSL | 16:8e0d178b1d1e | 5924 | |
wolfSSL | 16:8e0d178b1d1e | 5925 | err = mp_to_unsigned_bin(r, &sigRS[0]); |
wolfSSL | 16:8e0d178b1d1e | 5926 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 5927 | return err; |
wolfSSL | 16:8e0d178b1d1e | 5928 | } |
wolfSSL | 16:8e0d178b1d1e | 5929 | err = mp_to_unsigned_bin(s, &sigRS[keySz]); |
wolfSSL | 16:8e0d178b1d1e | 5930 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 5931 | return err; |
wolfSSL | 16:8e0d178b1d1e | 5932 | } |
wolfSSL | 16:8e0d178b1d1e | 5933 | |
wolfSSL | 16:8e0d178b1d1e | 5934 | hash_mode = cc310_hashModeECC(msgLenInBytes); |
wolfSSL | 16:8e0d178b1d1e | 5935 | if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) { |
wolfSSL | 16:8e0d178b1d1e | 5936 | /* hash_mode = */ cc310_hashModeECC(keySz); |
wolfSSL | 16:8e0d178b1d1e | 5937 | hash_mode = CRYS_ECPKI_HASH_SHA256_mode; |
wolfSSL | 16:8e0d178b1d1e | 5938 | } |
wolfSSL | 16:8e0d178b1d1e | 5939 | /* truncate if hash is longer than key size */ |
wolfSSL | 16:8e0d178b1d1e | 5940 | if (msgLenInBytes > keySz) { |
wolfSSL | 16:8e0d178b1d1e | 5941 | msgLenInBytes = keySz; |
wolfSSL | 16:8e0d178b1d1e | 5942 | } |
wolfSSL | 16:8e0d178b1d1e | 5943 | |
wolfSSL | 16:8e0d178b1d1e | 5944 | /* verify the signature using the public key */ |
wolfSSL | 16:8e0d178b1d1e | 5945 | err = CRYS_ECDSA_Verify(&sigCtxTemp, |
wolfSSL | 16:8e0d178b1d1e | 5946 | &key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 5947 | hash_mode, |
wolfSSL | 16:8e0d178b1d1e | 5948 | &sigRS[0], |
wolfSSL | 16:8e0d178b1d1e | 5949 | keySz*2, |
wolfSSL | 16:8e0d178b1d1e | 5950 | (byte*)hash, |
wolfSSL | 16:8e0d178b1d1e | 5951 | msgLenInBytes); |
wolfSSL | 16:8e0d178b1d1e | 5952 | |
wolfSSL | 16:8e0d178b1d1e | 5953 | if (err != SA_SILIB_RET_OK) { |
wolfSSL | 16:8e0d178b1d1e | 5954 | WOLFSSL_MSG("CRYS_ECDSA_Verify failed"); |
wolfSSL | 16:8e0d178b1d1e | 5955 | return err; |
wolfSSL | 16:8e0d178b1d1e | 5956 | } |
wolfSSL | 16:8e0d178b1d1e | 5957 | /* valid signature if we get to this point */ |
wolfSSL | 16:8e0d178b1d1e | 5958 | *res = 1; |
wolfSSL | 15:117db924cf7c | 5959 | #else |
wolfSSL | 15:117db924cf7c | 5960 | /* checking if private key with no public part */ |
wolfSSL | 15:117db924cf7c | 5961 | if (key->type == ECC_PRIVATEKEY_ONLY) { |
wolfSSL | 15:117db924cf7c | 5962 | WOLFSSL_MSG("Verify called with private key, generating public part"); |
wolfSSL | 15:117db924cf7c | 5963 | err = wc_ecc_make_pub_ex(key, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 5964 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 5965 | WOLFSSL_MSG("Unable to extract public key"); |
wolfSSL | 15:117db924cf7c | 5966 | return err; |
wolfSSL | 15:117db924cf7c | 5967 | } |
wolfSSL | 15:117db924cf7c | 5968 | } |
wolfSSL | 15:117db924cf7c | 5969 | |
wolfSSL | 16:8e0d178b1d1e | 5970 | #if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC) |
wolfSSL | 16:8e0d178b1d1e | 5971 | if (key->handle != -1) { |
wolfSSL | 16:8e0d178b1d1e | 5972 | return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x, key->pubkey.y, |
wolfSSL | 16:8e0d178b1d1e | 5973 | key->pubkey.z, r, s, res, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 5974 | } |
wolfSSL | 16:8e0d178b1d1e | 5975 | if (wolfSSL_GetHandleCbSet() == 1) { |
wolfSSL | 16:8e0d178b1d1e | 5976 | return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x, key->pubkey.y, |
wolfSSL | 16:8e0d178b1d1e | 5977 | key->pubkey.z, r, s, res, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 5978 | } |
wolfSSL | 16:8e0d178b1d1e | 5979 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5980 | #if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC) |
wolfSSL | 16:8e0d178b1d1e | 5981 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 5982 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 15:117db924cf7c | 5983 | return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, |
wolfSSL | 15:117db924cf7c | 5984 | key->pubkey.z, r, s, res, key->heap); |
wolfSSL | 15:117db924cf7c | 5985 | } |
wolfSSL | 16:8e0d178b1d1e | 5986 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5987 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 5988 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 5989 | return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, key->pubkey.y, |
wolfSSL | 16:8e0d178b1d1e | 5990 | key->pubkey.z, r, s, res, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 5991 | } |
wolfSSL | 16:8e0d178b1d1e | 5992 | #endif |
wolfSSL | 16:8e0d178b1d1e | 5993 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 5994 | #else |
wolfSSL | 16:8e0d178b1d1e | 5995 | #if defined WOLFSSL_HAVE_SP_ECC && !defined(FREESCALE_LTC_ECC) |
wolfSSL | 16:8e0d178b1d1e | 5996 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 5997 | if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) |
wolfSSL | 15:117db924cf7c | 5998 | #endif |
wolfSSL | 15:117db924cf7c | 5999 | { |
wolfSSL | 16:8e0d178b1d1e | 6000 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 6001 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 6002 | ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 6003 | return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, |
wolfSSL | 16:8e0d178b1d1e | 6004 | key->pubkey.y, key->pubkey.z,r, s, res, |
wolfSSL | 16:8e0d178b1d1e | 6005 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6006 | } |
wolfSSL | 15:117db924cf7c | 6007 | #endif /* WOLFSSL_SP_NO_256 */ |
wolfSSL | 16:8e0d178b1d1e | 6008 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 6009 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 6010 | ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 6011 | return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, |
wolfSSL | 16:8e0d178b1d1e | 6012 | key->pubkey.y, key->pubkey.z,r, s, res, |
wolfSSL | 16:8e0d178b1d1e | 6013 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6014 | } |
wolfSSL | 16:8e0d178b1d1e | 6015 | #endif /* WOLFSSL_SP_384 */ |
wolfSSL | 16:8e0d178b1d1e | 6016 | } |
wolfSSL | 15:117db924cf7c | 6017 | #endif /* WOLFSSL_HAVE_SP_ECC */ |
wolfSSL | 15:117db924cf7c | 6018 | |
wolfSSL | 15:117db924cf7c | 6019 | ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); |
wolfSSL | 15:117db924cf7c | 6020 | |
wolfSSL | 15:117db924cf7c | 6021 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) |
wolfSSL | 15:117db924cf7c | 6022 | err = wc_ecc_alloc_mpint(key, &key->e); |
wolfSSL | 15:117db924cf7c | 6023 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 6024 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6025 | return err; |
wolfSSL | 15:117db924cf7c | 6026 | } |
wolfSSL | 15:117db924cf7c | 6027 | e = key->e; |
wolfSSL | 15:117db924cf7c | 6028 | #else |
wolfSSL | 15:117db924cf7c | 6029 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6030 | e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6031 | if (e_lcl == NULL) { |
wolfSSL | 15:117db924cf7c | 6032 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6033 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6034 | } |
wolfSSL | 15:117db924cf7c | 6035 | #endif |
wolfSSL | 15:117db924cf7c | 6036 | e = e_lcl; |
wolfSSL | 16:8e0d178b1d1e | 6037 | #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */ |
wolfSSL | 15:117db924cf7c | 6038 | |
wolfSSL | 15:117db924cf7c | 6039 | err = mp_init(e); |
wolfSSL | 15:117db924cf7c | 6040 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6041 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6042 | |
wolfSSL | 15:117db924cf7c | 6043 | /* read in the specs for this curve */ |
wolfSSL | 15:117db924cf7c | 6044 | err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); |
wolfSSL | 15:117db924cf7c | 6045 | |
wolfSSL | 15:117db924cf7c | 6046 | /* check for zero */ |
wolfSSL | 15:117db924cf7c | 6047 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6048 | if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || |
wolfSSL | 15:117db924cf7c | 6049 | mp_cmp(r, curve->order) != MP_LT || |
wolfSSL | 15:117db924cf7c | 6050 | mp_cmp(s, curve->order) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 6051 | err = MP_ZERO_E; |
wolfSSL | 15:117db924cf7c | 6052 | } |
wolfSSL | 15:117db924cf7c | 6053 | } |
wolfSSL | 15:117db924cf7c | 6054 | |
wolfSSL | 15:117db924cf7c | 6055 | /* read hash */ |
wolfSSL | 15:117db924cf7c | 6056 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6057 | /* we may need to truncate if hash is longer than key size */ |
wolfSSL | 15:117db924cf7c | 6058 | unsigned int orderBits = mp_count_bits(curve->order); |
wolfSSL | 15:117db924cf7c | 6059 | |
wolfSSL | 15:117db924cf7c | 6060 | /* truncate down to byte size, may be all that's needed */ |
wolfSSL | 15:117db924cf7c | 6061 | if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) |
wolfSSL | 15:117db924cf7c | 6062 | hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; |
wolfSSL | 15:117db924cf7c | 6063 | err = mp_read_unsigned_bin(e, hash, hashlen); |
wolfSSL | 15:117db924cf7c | 6064 | |
wolfSSL | 15:117db924cf7c | 6065 | /* may still need bit truncation too */ |
wolfSSL | 15:117db924cf7c | 6066 | if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) |
wolfSSL | 15:117db924cf7c | 6067 | mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); |
wolfSSL | 15:117db924cf7c | 6068 | } |
wolfSSL | 15:117db924cf7c | 6069 | |
wolfSSL | 15:117db924cf7c | 6070 | /* check for async hardware acceleration */ |
wolfSSL | 15:117db924cf7c | 6071 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 6072 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { |
wolfSSL | 15:117db924cf7c | 6073 | #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 6074 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 6075 | if (NitroxEccIsCurveSupported(key)) |
wolfSSL | 15:117db924cf7c | 6076 | #endif |
wolfSSL | 15:117db924cf7c | 6077 | { |
wolfSSL | 15:117db924cf7c | 6078 | err = wc_mp_to_bigint_sz(e, &e->raw, keySz); |
wolfSSL | 15:117db924cf7c | 6079 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6080 | err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz); |
wolfSSL | 15:117db924cf7c | 6081 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6082 | err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz); |
wolfSSL | 15:117db924cf7c | 6083 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6084 | #ifdef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 6085 | err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw, |
wolfSSL | 15:117db924cf7c | 6086 | &key->pubkey.y->raw, &r->raw, &s->raw, |
wolfSSL | 15:117db924cf7c | 6087 | &curve->prime->raw, &curve->order->raw, res); |
wolfSSL | 15:117db924cf7c | 6088 | #else |
wolfSSL | 15:117db924cf7c | 6089 | err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw, |
wolfSSL | 15:117db924cf7c | 6090 | &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw, |
wolfSSL | 15:117db924cf7c | 6091 | &curve->Bf->raw, &curve->prime->raw, &curve->order->raw, |
wolfSSL | 15:117db924cf7c | 6092 | &curve->Gx->raw, &curve->Gy->raw, res); |
wolfSSL | 15:117db924cf7c | 6093 | #endif |
wolfSSL | 15:117db924cf7c | 6094 | |
wolfSSL | 15:117db924cf7c | 6095 | #ifndef HAVE_CAVIUM_V |
wolfSSL | 15:117db924cf7c | 6096 | mp_clear(e); |
wolfSSL | 15:117db924cf7c | 6097 | #endif |
wolfSSL | 15:117db924cf7c | 6098 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 6099 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6100 | |
wolfSSL | 15:117db924cf7c | 6101 | return err; |
wolfSSL | 15:117db924cf7c | 6102 | } |
wolfSSL | 15:117db924cf7c | 6103 | #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ |
wolfSSL | 15:117db924cf7c | 6104 | } |
wolfSSL | 16:8e0d178b1d1e | 6105 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */ |
wolfSSL | 15:117db924cf7c | 6106 | |
wolfSSL | 15:117db924cf7c | 6107 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6108 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6109 | v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6110 | if (v == NULL) |
wolfSSL | 15:117db924cf7c | 6111 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6112 | } |
wolfSSL | 15:117db924cf7c | 6113 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6114 | w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6115 | if (w == NULL) |
wolfSSL | 15:117db924cf7c | 6116 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6117 | } |
wolfSSL | 15:117db924cf7c | 6118 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6119 | u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6120 | if (u1 == NULL) |
wolfSSL | 15:117db924cf7c | 6121 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6122 | } |
wolfSSL | 15:117db924cf7c | 6123 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6124 | u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6125 | if (u2 == NULL) |
wolfSSL | 15:117db924cf7c | 6126 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6127 | } |
wolfSSL | 15:117db924cf7c | 6128 | #endif |
wolfSSL | 15:117db924cf7c | 6129 | |
wolfSSL | 15:117db924cf7c | 6130 | /* allocate ints */ |
wolfSSL | 15:117db924cf7c | 6131 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6132 | if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6133 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6134 | } |
wolfSSL | 15:117db924cf7c | 6135 | did_init = 1; |
wolfSSL | 15:117db924cf7c | 6136 | } |
wolfSSL | 15:117db924cf7c | 6137 | |
wolfSSL | 15:117db924cf7c | 6138 | /* allocate points */ |
wolfSSL | 15:117db924cf7c | 6139 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6140 | mG = wc_ecc_new_point_h(key->heap); |
wolfSSL | 15:117db924cf7c | 6141 | mQ = wc_ecc_new_point_h(key->heap); |
wolfSSL | 15:117db924cf7c | 6142 | if (mQ == NULL || mG == NULL) |
wolfSSL | 15:117db924cf7c | 6143 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6144 | } |
wolfSSL | 15:117db924cf7c | 6145 | |
wolfSSL | 15:117db924cf7c | 6146 | /* w = s^-1 mod n */ |
wolfSSL | 15:117db924cf7c | 6147 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6148 | err = mp_invmod(s, curve->order, w); |
wolfSSL | 15:117db924cf7c | 6149 | |
wolfSSL | 15:117db924cf7c | 6150 | /* u1 = ew */ |
wolfSSL | 15:117db924cf7c | 6151 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6152 | err = mp_mulmod(e, w, curve->order, u1); |
wolfSSL | 15:117db924cf7c | 6153 | |
wolfSSL | 15:117db924cf7c | 6154 | /* u2 = rw */ |
wolfSSL | 15:117db924cf7c | 6155 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6156 | err = mp_mulmod(r, w, curve->order, u2); |
wolfSSL | 15:117db924cf7c | 6157 | |
wolfSSL | 15:117db924cf7c | 6158 | /* find mG and mQ */ |
wolfSSL | 15:117db924cf7c | 6159 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6160 | err = mp_copy(curve->Gx, mG->x); |
wolfSSL | 15:117db924cf7c | 6161 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6162 | err = mp_copy(curve->Gy, mG->y); |
wolfSSL | 15:117db924cf7c | 6163 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6164 | err = mp_set(mG->z, 1); |
wolfSSL | 15:117db924cf7c | 6165 | |
wolfSSL | 15:117db924cf7c | 6166 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6167 | err = mp_copy(key->pubkey.x, mQ->x); |
wolfSSL | 15:117db924cf7c | 6168 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6169 | err = mp_copy(key->pubkey.y, mQ->y); |
wolfSSL | 15:117db924cf7c | 6170 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6171 | err = mp_copy(key->pubkey.z, mQ->z); |
wolfSSL | 15:117db924cf7c | 6172 | |
wolfSSL | 16:8e0d178b1d1e | 6173 | #if defined(FREESCALE_LTC_ECC) |
wolfSSL | 15:117db924cf7c | 6174 | /* use PKHA to compute u1*mG + u2*mQ */ |
wolfSSL | 15:117db924cf7c | 6175 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6176 | err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap); |
wolfSSL | 15:117db924cf7c | 6177 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6178 | err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); |
wolfSSL | 15:117db924cf7c | 6179 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6180 | err = wc_ecc_point_add(mG, mQ, mG, curve->prime); |
wolfSSL | 15:117db924cf7c | 6181 | #else |
wolfSSL | 15:117db924cf7c | 6182 | #ifndef ECC_SHAMIR |
wolfSSL | 16:8e0d178b1d1e | 6183 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6184 | { |
wolfSSL | 16:8e0d178b1d1e | 6185 | mp_digit mp = 0; |
wolfSSL | 16:8e0d178b1d1e | 6186 | |
wolfSSL | 16:8e0d178b1d1e | 6187 | if (!mp_iszero(u1)) { |
wolfSSL | 16:8e0d178b1d1e | 6188 | /* compute u1*mG + u2*mQ = mG */ |
wolfSSL | 15:117db924cf7c | 6189 | err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, |
wolfSSL | 15:117db924cf7c | 6190 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6191 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 6192 | err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, |
wolfSSL | 15:117db924cf7c | 6193 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6194 | } |
wolfSSL | 16:8e0d178b1d1e | 6195 | |
wolfSSL | 16:8e0d178b1d1e | 6196 | /* find the montgomery mp */ |
wolfSSL | 16:8e0d178b1d1e | 6197 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6198 | err = mp_montgomery_setup(curve->prime, &mp); |
wolfSSL | 16:8e0d178b1d1e | 6199 | |
wolfSSL | 16:8e0d178b1d1e | 6200 | /* add them */ |
wolfSSL | 16:8e0d178b1d1e | 6201 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6202 | err = ecc_projective_add_point(mQ, mG, mG, curve->Af, |
wolfSSL | 16:8e0d178b1d1e | 6203 | curve->prime, mp); |
wolfSSL | 16:8e0d178b1d1e | 6204 | if (err == MP_OKAY && mp_iszero(mG->z)) { |
wolfSSL | 16:8e0d178b1d1e | 6205 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 6206 | if (mp_iszero(mG->x) && mp_iszero(mG->y)) { |
wolfSSL | 16:8e0d178b1d1e | 6207 | err = ecc_projective_dbl_point(mQ, mG, curve->Af, |
wolfSSL | 16:8e0d178b1d1e | 6208 | curve->prime, mp); |
wolfSSL | 16:8e0d178b1d1e | 6209 | } |
wolfSSL | 16:8e0d178b1d1e | 6210 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 6211 | else { |
wolfSSL | 16:8e0d178b1d1e | 6212 | err = mp_set(mG->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 6213 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6214 | err = mp_set(mG->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 6215 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6216 | err = mp_set(mG->z, 1); |
wolfSSL | 16:8e0d178b1d1e | 6217 | } |
wolfSSL | 16:8e0d178b1d1e | 6218 | } |
wolfSSL | 16:8e0d178b1d1e | 6219 | } |
wolfSSL | 16:8e0d178b1d1e | 6220 | else { |
wolfSSL | 16:8e0d178b1d1e | 6221 | /* compute 0*mG + u2*mQ = mG */ |
wolfSSL | 16:8e0d178b1d1e | 6222 | err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0, |
wolfSSL | 16:8e0d178b1d1e | 6223 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6224 | /* find the montgomery mp */ |
wolfSSL | 16:8e0d178b1d1e | 6225 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6226 | err = mp_montgomery_setup(curve->prime, &mp); |
wolfSSL | 16:8e0d178b1d1e | 6227 | } |
wolfSSL | 15:117db924cf7c | 6228 | |
wolfSSL | 15:117db924cf7c | 6229 | /* reduce */ |
wolfSSL | 15:117db924cf7c | 6230 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6231 | err = ecc_map(mG, curve->prime, mp); |
wolfSSL | 15:117db924cf7c | 6232 | } |
wolfSSL | 15:117db924cf7c | 6233 | #else |
wolfSSL | 16:8e0d178b1d1e | 6234 | /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ |
wolfSSL | 16:8e0d178b1d1e | 6235 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 6236 | err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime, |
wolfSSL | 16:8e0d178b1d1e | 6237 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6238 | } |
wolfSSL | 15:117db924cf7c | 6239 | #endif /* ECC_SHAMIR */ |
wolfSSL | 15:117db924cf7c | 6240 | #endif /* FREESCALE_LTC_ECC */ |
wolfSSL | 15:117db924cf7c | 6241 | /* v = X_x1 mod n */ |
wolfSSL | 15:117db924cf7c | 6242 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6243 | err = mp_mod(mG->x, curve->order, v); |
wolfSSL | 15:117db924cf7c | 6244 | |
wolfSSL | 15:117db924cf7c | 6245 | /* does v == r */ |
wolfSSL | 15:117db924cf7c | 6246 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6247 | if (mp_cmp(v, r) == MP_EQ) |
wolfSSL | 15:117db924cf7c | 6248 | *res = 1; |
wolfSSL | 15:117db924cf7c | 6249 | } |
wolfSSL | 15:117db924cf7c | 6250 | |
wolfSSL | 15:117db924cf7c | 6251 | /* cleanup */ |
wolfSSL | 15:117db924cf7c | 6252 | wc_ecc_del_point_h(mG, key->heap); |
wolfSSL | 15:117db924cf7c | 6253 | wc_ecc_del_point_h(mQ, key->heap); |
wolfSSL | 15:117db924cf7c | 6254 | |
wolfSSL | 15:117db924cf7c | 6255 | mp_clear(e); |
wolfSSL | 15:117db924cf7c | 6256 | if (did_init) { |
wolfSSL | 15:117db924cf7c | 6257 | mp_clear(v); |
wolfSSL | 15:117db924cf7c | 6258 | mp_clear(w); |
wolfSSL | 15:117db924cf7c | 6259 | mp_clear(u1); |
wolfSSL | 15:117db924cf7c | 6260 | mp_clear(u2); |
wolfSSL | 15:117db924cf7c | 6261 | } |
wolfSSL | 15:117db924cf7c | 6262 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6263 | XFREE(u2, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6264 | XFREE(u1, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6265 | XFREE(w, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6266 | XFREE(v, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6267 | #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) |
wolfSSL | 15:117db924cf7c | 6268 | XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6269 | #endif |
wolfSSL | 15:117db924cf7c | 6270 | #endif |
wolfSSL | 15:117db924cf7c | 6271 | |
wolfSSL | 15:117db924cf7c | 6272 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 6273 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6274 | |
wolfSSL | 15:117db924cf7c | 6275 | #endif /* WOLFSSL_SP_MATH */ |
wolfSSL | 15:117db924cf7c | 6276 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 6277 | |
wolfSSL | 16:8e0d178b1d1e | 6278 | (void)keySz; |
wolfSSL | 16:8e0d178b1d1e | 6279 | (void)hashlen; |
wolfSSL | 16:8e0d178b1d1e | 6280 | |
wolfSSL | 15:117db924cf7c | 6281 | return err; |
wolfSSL | 15:117db924cf7c | 6282 | } |
wolfSSL | 16:8e0d178b1d1e | 6283 | #endif /* WOLFSSL_STM32_PKA */ |
wolfSSL | 15:117db924cf7c | 6284 | #endif /* HAVE_ECC_VERIFY */ |
wolfSSL | 15:117db924cf7c | 6285 | |
wolfSSL | 15:117db924cf7c | 6286 | #ifdef HAVE_ECC_KEY_IMPORT |
wolfSSL | 16:8e0d178b1d1e | 6287 | /* import point from der |
wolfSSL | 16:8e0d178b1d1e | 6288 | * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */ |
wolfSSL | 16:8e0d178b1d1e | 6289 | int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, |
wolfSSL | 16:8e0d178b1d1e | 6290 | ecc_point* point, int shortKeySize) |
wolfSSL | 15:117db924cf7c | 6291 | { |
wolfSSL | 15:117db924cf7c | 6292 | int err = 0; |
wolfSSL | 16:8e0d178b1d1e | 6293 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 6294 | int compressed = 0; |
wolfSSL | 16:8e0d178b1d1e | 6295 | #endif |
wolfSSL | 15:117db924cf7c | 6296 | int keysize; |
wolfSSL | 15:117db924cf7c | 6297 | byte pointType; |
wolfSSL | 15:117db924cf7c | 6298 | |
wolfSSL | 16:8e0d178b1d1e | 6299 | #ifndef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 6300 | (void)shortKeySize; |
wolfSSL | 16:8e0d178b1d1e | 6301 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6302 | |
wolfSSL | 15:117db924cf7c | 6303 | if (in == NULL || point == NULL || (curve_idx < 0) || |
wolfSSL | 15:117db924cf7c | 6304 | (wc_ecc_is_valid_idx(curve_idx) == 0)) |
wolfSSL | 15:117db924cf7c | 6305 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6306 | |
wolfSSL | 15:117db924cf7c | 6307 | /* must be odd */ |
wolfSSL | 15:117db924cf7c | 6308 | if ((inLen & 1) == 0) { |
wolfSSL | 15:117db924cf7c | 6309 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6310 | } |
wolfSSL | 15:117db924cf7c | 6311 | |
wolfSSL | 15:117db924cf7c | 6312 | /* init point */ |
wolfSSL | 15:117db924cf7c | 6313 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 6314 | point->x = (mp_int*)&point->xyz[0]; |
wolfSSL | 15:117db924cf7c | 6315 | point->y = (mp_int*)&point->xyz[1]; |
wolfSSL | 15:117db924cf7c | 6316 | point->z = (mp_int*)&point->xyz[2]; |
wolfSSL | 15:117db924cf7c | 6317 | alt_fp_init(point->x); |
wolfSSL | 15:117db924cf7c | 6318 | alt_fp_init(point->y); |
wolfSSL | 15:117db924cf7c | 6319 | alt_fp_init(point->z); |
wolfSSL | 15:117db924cf7c | 6320 | #else |
wolfSSL | 15:117db924cf7c | 6321 | err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 6322 | #endif |
wolfSSL | 15:117db924cf7c | 6323 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6324 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6325 | |
wolfSSL | 15:117db924cf7c | 6326 | /* check for point type (4, 2, or 3) */ |
wolfSSL | 15:117db924cf7c | 6327 | pointType = in[0]; |
wolfSSL | 15:117db924cf7c | 6328 | if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN && |
wolfSSL | 15:117db924cf7c | 6329 | pointType != ECC_POINT_COMP_ODD) { |
wolfSSL | 15:117db924cf7c | 6330 | err = ASN_PARSE_E; |
wolfSSL | 15:117db924cf7c | 6331 | } |
wolfSSL | 15:117db924cf7c | 6332 | |
wolfSSL | 15:117db924cf7c | 6333 | if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { |
wolfSSL | 15:117db924cf7c | 6334 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 6335 | compressed = 1; |
wolfSSL | 15:117db924cf7c | 6336 | #else |
wolfSSL | 15:117db924cf7c | 6337 | err = NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 6338 | #endif |
wolfSSL | 15:117db924cf7c | 6339 | } |
wolfSSL | 15:117db924cf7c | 6340 | |
wolfSSL | 15:117db924cf7c | 6341 | /* adjust to skip first byte */ |
wolfSSL | 15:117db924cf7c | 6342 | inLen -= 1; |
wolfSSL | 15:117db924cf7c | 6343 | in += 1; |
wolfSSL | 15:117db924cf7c | 6344 | |
wolfSSL | 16:8e0d178b1d1e | 6345 | /* calculate key size based on inLen / 2 if uncompressed or shortKeySize |
wolfSSL | 16:8e0d178b1d1e | 6346 | * is true */ |
wolfSSL | 16:8e0d178b1d1e | 6347 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 6348 | keysize = compressed && !shortKeySize ? inLen : inLen>>1; |
wolfSSL | 16:8e0d178b1d1e | 6349 | #else |
wolfSSL | 15:117db924cf7c | 6350 | keysize = inLen>>1; |
wolfSSL | 15:117db924cf7c | 6351 | #endif |
wolfSSL | 15:117db924cf7c | 6352 | |
wolfSSL | 15:117db924cf7c | 6353 | /* read data */ |
wolfSSL | 15:117db924cf7c | 6354 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6355 | err = mp_read_unsigned_bin(point->x, (byte*)in, keysize); |
wolfSSL | 15:117db924cf7c | 6356 | |
wolfSSL | 15:117db924cf7c | 6357 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 6358 | if (err == MP_OKAY && compressed == 1) { /* build y */ |
wolfSSL | 15:117db924cf7c | 6359 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 6360 | int did_init = 0; |
wolfSSL | 15:117db924cf7c | 6361 | mp_int t1, t2; |
wolfSSL | 15:117db924cf7c | 6362 | DECLARE_CURVE_SPECS(curve, 3); |
wolfSSL | 15:117db924cf7c | 6363 | |
wolfSSL | 15:117db924cf7c | 6364 | ALLOC_CURVE_SPECS(3); |
wolfSSL | 15:117db924cf7c | 6365 | |
wolfSSL | 15:117db924cf7c | 6366 | if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6367 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6368 | else |
wolfSSL | 15:117db924cf7c | 6369 | did_init = 1; |
wolfSSL | 15:117db924cf7c | 6370 | |
wolfSSL | 15:117db924cf7c | 6371 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 6372 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6373 | err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, |
wolfSSL | 15:117db924cf7c | 6374 | (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | |
wolfSSL | 15:117db924cf7c | 6375 | ECC_CURVE_FIELD_BF)); |
wolfSSL | 15:117db924cf7c | 6376 | |
wolfSSL | 15:117db924cf7c | 6377 | /* compute x^3 */ |
wolfSSL | 15:117db924cf7c | 6378 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6379 | err = mp_sqr(point->x, &t1); |
wolfSSL | 15:117db924cf7c | 6380 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6381 | err = mp_mulmod(&t1, point->x, curve->prime, &t1); |
wolfSSL | 15:117db924cf7c | 6382 | |
wolfSSL | 15:117db924cf7c | 6383 | /* compute x^3 + a*x */ |
wolfSSL | 15:117db924cf7c | 6384 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6385 | err = mp_mulmod(curve->Af, point->x, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 6386 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6387 | err = mp_add(&t1, &t2, &t1); |
wolfSSL | 15:117db924cf7c | 6388 | |
wolfSSL | 15:117db924cf7c | 6389 | /* compute x^3 + a*x + b */ |
wolfSSL | 15:117db924cf7c | 6390 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6391 | err = mp_add(&t1, curve->Bf, &t1); |
wolfSSL | 15:117db924cf7c | 6392 | |
wolfSSL | 15:117db924cf7c | 6393 | /* compute sqrt(x^3 + a*x + b) */ |
wolfSSL | 15:117db924cf7c | 6394 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6395 | err = mp_sqrtmod_prime(&t1, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 6396 | |
wolfSSL | 15:117db924cf7c | 6397 | /* adjust y */ |
wolfSSL | 15:117db924cf7c | 6398 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6399 | if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) || |
wolfSSL | 15:117db924cf7c | 6400 | (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) { |
wolfSSL | 15:117db924cf7c | 6401 | err = mp_mod(&t2, curve->prime, point->y); |
wolfSSL | 15:117db924cf7c | 6402 | } |
wolfSSL | 15:117db924cf7c | 6403 | else { |
wolfSSL | 15:117db924cf7c | 6404 | err = mp_submod(curve->prime, &t2, curve->prime, point->y); |
wolfSSL | 15:117db924cf7c | 6405 | } |
wolfSSL | 15:117db924cf7c | 6406 | } |
wolfSSL | 15:117db924cf7c | 6407 | |
wolfSSL | 15:117db924cf7c | 6408 | if (did_init) { |
wolfSSL | 15:117db924cf7c | 6409 | mp_clear(&t2); |
wolfSSL | 15:117db924cf7c | 6410 | mp_clear(&t1); |
wolfSSL | 15:117db924cf7c | 6411 | } |
wolfSSL | 15:117db924cf7c | 6412 | |
wolfSSL | 15:117db924cf7c | 6413 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 6414 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6415 | #else |
wolfSSL | 16:8e0d178b1d1e | 6416 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 6417 | if (curve_idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 6418 | ecc_sets[curve_idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 6419 | sp_ecc_uncompress_256(point->x, pointType, point->y); |
wolfSSL | 16:8e0d178b1d1e | 6420 | } |
wolfSSL | 16:8e0d178b1d1e | 6421 | else |
wolfSSL | 16:8e0d178b1d1e | 6422 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6423 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 6424 | if (curve_idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 6425 | ecc_sets[curve_idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 6426 | sp_ecc_uncompress_384(point->x, pointType, point->y); |
wolfSSL | 16:8e0d178b1d1e | 6427 | } |
wolfSSL | 16:8e0d178b1d1e | 6428 | else |
wolfSSL | 16:8e0d178b1d1e | 6429 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6430 | { |
wolfSSL | 16:8e0d178b1d1e | 6431 | err = WC_KEY_SIZE_E; |
wolfSSL | 16:8e0d178b1d1e | 6432 | } |
wolfSSL | 16:8e0d178b1d1e | 6433 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6434 | } |
wolfSSL | 16:8e0d178b1d1e | 6435 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6436 | |
wolfSSL | 16:8e0d178b1d1e | 6437 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 6438 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 6439 | if (compressed == 0) |
wolfSSL | 16:8e0d178b1d1e | 6440 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6441 | err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize); |
wolfSSL | 16:8e0d178b1d1e | 6442 | } |
wolfSSL | 15:117db924cf7c | 6443 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6444 | err = mp_set(point->z, 1); |
wolfSSL | 15:117db924cf7c | 6445 | |
wolfSSL | 15:117db924cf7c | 6446 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6447 | mp_clear(point->x); |
wolfSSL | 15:117db924cf7c | 6448 | mp_clear(point->y); |
wolfSSL | 15:117db924cf7c | 6449 | mp_clear(point->z); |
wolfSSL | 15:117db924cf7c | 6450 | } |
wolfSSL | 15:117db924cf7c | 6451 | |
wolfSSL | 15:117db924cf7c | 6452 | return err; |
wolfSSL | 15:117db924cf7c | 6453 | } |
wolfSSL | 16:8e0d178b1d1e | 6454 | |
wolfSSL | 16:8e0d178b1d1e | 6455 | /* function for backwards compatiblity with previous implementations */ |
wolfSSL | 16:8e0d178b1d1e | 6456 | int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, |
wolfSSL | 16:8e0d178b1d1e | 6457 | ecc_point* point) |
wolfSSL | 16:8e0d178b1d1e | 6458 | { |
wolfSSL | 16:8e0d178b1d1e | 6459 | return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1); |
wolfSSL | 16:8e0d178b1d1e | 6460 | } |
wolfSSL | 15:117db924cf7c | 6461 | #endif /* HAVE_ECC_KEY_IMPORT */ |
wolfSSL | 15:117db924cf7c | 6462 | |
wolfSSL | 15:117db924cf7c | 6463 | #ifdef HAVE_ECC_KEY_EXPORT |
wolfSSL | 15:117db924cf7c | 6464 | /* export point to der */ |
wolfSSL | 16:8e0d178b1d1e | 6465 | |
wolfSSL | 16:8e0d178b1d1e | 6466 | int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out, |
wolfSSL | 16:8e0d178b1d1e | 6467 | word32* outLen, int compressed) |
wolfSSL | 16:8e0d178b1d1e | 6468 | { |
wolfSSL | 16:8e0d178b1d1e | 6469 | if (compressed == 0) |
wolfSSL | 16:8e0d178b1d1e | 6470 | return wc_ecc_export_point_der(curve_idx, point, out, outLen); |
wolfSSL | 16:8e0d178b1d1e | 6471 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 6472 | else |
wolfSSL | 16:8e0d178b1d1e | 6473 | return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen); |
wolfSSL | 16:8e0d178b1d1e | 6474 | #else |
wolfSSL | 16:8e0d178b1d1e | 6475 | return NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 6476 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6477 | } |
wolfSSL | 16:8e0d178b1d1e | 6478 | |
wolfSSL | 15:117db924cf7c | 6479 | int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, |
wolfSSL | 15:117db924cf7c | 6480 | word32* outLen) |
wolfSSL | 15:117db924cf7c | 6481 | { |
wolfSSL | 15:117db924cf7c | 6482 | int ret = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 6483 | word32 numlen; |
wolfSSL | 15:117db924cf7c | 6484 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6485 | byte* buf; |
wolfSSL | 15:117db924cf7c | 6486 | #else |
wolfSSL | 15:117db924cf7c | 6487 | byte buf[ECC_BUFSIZE]; |
wolfSSL | 15:117db924cf7c | 6488 | #endif |
wolfSSL | 15:117db924cf7c | 6489 | |
wolfSSL | 15:117db924cf7c | 6490 | if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) |
wolfSSL | 15:117db924cf7c | 6491 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6492 | |
wolfSSL | 16:8e0d178b1d1e | 6493 | numlen = ecc_sets[curve_idx].size; |
wolfSSL | 16:8e0d178b1d1e | 6494 | |
wolfSSL | 15:117db924cf7c | 6495 | /* return length needed only */ |
wolfSSL | 15:117db924cf7c | 6496 | if (point != NULL && out == NULL && outLen != NULL) { |
wolfSSL | 15:117db924cf7c | 6497 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6498 | return LENGTH_ONLY_E; |
wolfSSL | 15:117db924cf7c | 6499 | } |
wolfSSL | 15:117db924cf7c | 6500 | |
wolfSSL | 15:117db924cf7c | 6501 | if (point == NULL || out == NULL || outLen == NULL) |
wolfSSL | 15:117db924cf7c | 6502 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6503 | |
wolfSSL | 15:117db924cf7c | 6504 | if (*outLen < (1 + 2*numlen)) { |
wolfSSL | 15:117db924cf7c | 6505 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6506 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 6507 | } |
wolfSSL | 15:117db924cf7c | 6508 | |
wolfSSL | 15:117db924cf7c | 6509 | /* store byte point type */ |
wolfSSL | 15:117db924cf7c | 6510 | out[0] = ECC_POINT_UNCOMP; |
wolfSSL | 15:117db924cf7c | 6511 | |
wolfSSL | 15:117db924cf7c | 6512 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6513 | buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 6514 | if (buf == NULL) |
wolfSSL | 15:117db924cf7c | 6515 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6516 | #endif |
wolfSSL | 15:117db924cf7c | 6517 | |
wolfSSL | 15:117db924cf7c | 6518 | /* pad and store x */ |
wolfSSL | 15:117db924cf7c | 6519 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 6520 | ret = mp_to_unsigned_bin(point->x, buf + |
wolfSSL | 15:117db924cf7c | 6521 | (numlen - mp_unsigned_bin_size(point->x))); |
wolfSSL | 15:117db924cf7c | 6522 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6523 | goto done; |
wolfSSL | 15:117db924cf7c | 6524 | XMEMCPY(out+1, buf, numlen); |
wolfSSL | 15:117db924cf7c | 6525 | |
wolfSSL | 15:117db924cf7c | 6526 | /* pad and store y */ |
wolfSSL | 15:117db924cf7c | 6527 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 6528 | ret = mp_to_unsigned_bin(point->y, buf + |
wolfSSL | 15:117db924cf7c | 6529 | (numlen - mp_unsigned_bin_size(point->y))); |
wolfSSL | 15:117db924cf7c | 6530 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6531 | goto done; |
wolfSSL | 15:117db924cf7c | 6532 | XMEMCPY(out+1+numlen, buf, numlen); |
wolfSSL | 15:117db924cf7c | 6533 | |
wolfSSL | 15:117db924cf7c | 6534 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6535 | |
wolfSSL | 15:117db924cf7c | 6536 | done: |
wolfSSL | 15:117db924cf7c | 6537 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6538 | XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 6539 | #endif |
wolfSSL | 15:117db924cf7c | 6540 | |
wolfSSL | 15:117db924cf7c | 6541 | return ret; |
wolfSSL | 15:117db924cf7c | 6542 | } |
wolfSSL | 15:117db924cf7c | 6543 | |
wolfSSL | 15:117db924cf7c | 6544 | |
wolfSSL | 16:8e0d178b1d1e | 6545 | /* export point to der */ |
wolfSSL | 16:8e0d178b1d1e | 6546 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 6547 | int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point, |
wolfSSL | 16:8e0d178b1d1e | 6548 | byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 6549 | { |
wolfSSL | 16:8e0d178b1d1e | 6550 | int ret = MP_OKAY; |
wolfSSL | 16:8e0d178b1d1e | 6551 | word32 numlen; |
wolfSSL | 16:8e0d178b1d1e | 6552 | word32 output_len; |
wolfSSL | 16:8e0d178b1d1e | 6553 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 6554 | byte* buf; |
wolfSSL | 16:8e0d178b1d1e | 6555 | #else |
wolfSSL | 16:8e0d178b1d1e | 6556 | byte buf[ECC_BUFSIZE]; |
wolfSSL | 16:8e0d178b1d1e | 6557 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6558 | |
wolfSSL | 16:8e0d178b1d1e | 6559 | if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) |
wolfSSL | 16:8e0d178b1d1e | 6560 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 6561 | |
wolfSSL | 16:8e0d178b1d1e | 6562 | numlen = ecc_sets[curve_idx].size; |
wolfSSL | 16:8e0d178b1d1e | 6563 | output_len = 1 + numlen; /* y point type + x */ |
wolfSSL | 16:8e0d178b1d1e | 6564 | |
wolfSSL | 16:8e0d178b1d1e | 6565 | /* return length needed only */ |
wolfSSL | 16:8e0d178b1d1e | 6566 | if (point != NULL && out == NULL && outLen != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 6567 | *outLen = output_len; |
wolfSSL | 16:8e0d178b1d1e | 6568 | return LENGTH_ONLY_E; |
wolfSSL | 16:8e0d178b1d1e | 6569 | } |
wolfSSL | 16:8e0d178b1d1e | 6570 | |
wolfSSL | 16:8e0d178b1d1e | 6571 | if (point == NULL || out == NULL || outLen == NULL) |
wolfSSL | 16:8e0d178b1d1e | 6572 | return ECC_BAD_ARG_E; |
wolfSSL | 16:8e0d178b1d1e | 6573 | |
wolfSSL | 16:8e0d178b1d1e | 6574 | |
wolfSSL | 16:8e0d178b1d1e | 6575 | if (*outLen < output_len) { |
wolfSSL | 16:8e0d178b1d1e | 6576 | *outLen = output_len; |
wolfSSL | 16:8e0d178b1d1e | 6577 | return BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 6578 | } |
wolfSSL | 16:8e0d178b1d1e | 6579 | |
wolfSSL | 16:8e0d178b1d1e | 6580 | /* store byte point type */ |
wolfSSL | 16:8e0d178b1d1e | 6581 | out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD : |
wolfSSL | 16:8e0d178b1d1e | 6582 | ECC_POINT_COMP_EVEN; |
wolfSSL | 16:8e0d178b1d1e | 6583 | |
wolfSSL | 16:8e0d178b1d1e | 6584 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 6585 | buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 16:8e0d178b1d1e | 6586 | if (buf == NULL) |
wolfSSL | 16:8e0d178b1d1e | 6587 | return MEMORY_E; |
wolfSSL | 16:8e0d178b1d1e | 6588 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6589 | |
wolfSSL | 16:8e0d178b1d1e | 6590 | /* pad and store x */ |
wolfSSL | 16:8e0d178b1d1e | 6591 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 16:8e0d178b1d1e | 6592 | ret = mp_to_unsigned_bin(point->x, buf + |
wolfSSL | 16:8e0d178b1d1e | 6593 | (numlen - mp_unsigned_bin_size(point->x))); |
wolfSSL | 16:8e0d178b1d1e | 6594 | if (ret != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 6595 | goto done; |
wolfSSL | 16:8e0d178b1d1e | 6596 | XMEMCPY(out+1, buf, numlen); |
wolfSSL | 16:8e0d178b1d1e | 6597 | |
wolfSSL | 16:8e0d178b1d1e | 6598 | *outLen = output_len; |
wolfSSL | 16:8e0d178b1d1e | 6599 | |
wolfSSL | 16:8e0d178b1d1e | 6600 | done: |
wolfSSL | 16:8e0d178b1d1e | 6601 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 6602 | XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 16:8e0d178b1d1e | 6603 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6604 | |
wolfSSL | 16:8e0d178b1d1e | 6605 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 6606 | } |
wolfSSL | 16:8e0d178b1d1e | 6607 | #endif /* HAVE_COMP_KEY */ |
wolfSSL | 16:8e0d178b1d1e | 6608 | |
wolfSSL | 15:117db924cf7c | 6609 | /* export public ECC key in ANSI X9.63 format */ |
wolfSSL | 15:117db924cf7c | 6610 | int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 15:117db924cf7c | 6611 | { |
wolfSSL | 15:117db924cf7c | 6612 | int ret = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 6613 | word32 numlen; |
wolfSSL | 15:117db924cf7c | 6614 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6615 | byte* buf; |
wolfSSL | 15:117db924cf7c | 6616 | #else |
wolfSSL | 15:117db924cf7c | 6617 | byte buf[ECC_BUFSIZE]; |
wolfSSL | 15:117db924cf7c | 6618 | #endif |
wolfSSL | 15:117db924cf7c | 6619 | word32 pubxlen, pubylen; |
wolfSSL | 15:117db924cf7c | 6620 | |
wolfSSL | 15:117db924cf7c | 6621 | /* return length needed only */ |
wolfSSL | 15:117db924cf7c | 6622 | if (key != NULL && out == NULL && outLen != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 6623 | /* if key hasn't been setup assume max bytes for size estimation */ |
wolfSSL | 16:8e0d178b1d1e | 6624 | numlen = key->dp ? key->dp->size : MAX_ECC_BYTES; |
wolfSSL | 15:117db924cf7c | 6625 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6626 | return LENGTH_ONLY_E; |
wolfSSL | 15:117db924cf7c | 6627 | } |
wolfSSL | 15:117db924cf7c | 6628 | |
wolfSSL | 15:117db924cf7c | 6629 | if (key == NULL || out == NULL || outLen == NULL) |
wolfSSL | 15:117db924cf7c | 6630 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6631 | |
wolfSSL | 15:117db924cf7c | 6632 | if (key->type == ECC_PRIVATEKEY_ONLY) |
wolfSSL | 15:117db924cf7c | 6633 | return ECC_PRIVATEONLY_E; |
wolfSSL | 15:117db924cf7c | 6634 | |
wolfSSL | 16:8e0d178b1d1e | 6635 | if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) { |
wolfSSL | 15:117db924cf7c | 6636 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 6637 | } |
wolfSSL | 15:117db924cf7c | 6638 | numlen = key->dp->size; |
wolfSSL | 15:117db924cf7c | 6639 | |
wolfSSL | 15:117db924cf7c | 6640 | /* verify room in out buffer */ |
wolfSSL | 15:117db924cf7c | 6641 | if (*outLen < (1 + 2*numlen)) { |
wolfSSL | 15:117db924cf7c | 6642 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6643 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 6644 | } |
wolfSSL | 15:117db924cf7c | 6645 | |
wolfSSL | 15:117db924cf7c | 6646 | /* verify public key length is less than key size */ |
wolfSSL | 15:117db924cf7c | 6647 | pubxlen = mp_unsigned_bin_size(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 6648 | pubylen = mp_unsigned_bin_size(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 6649 | if ((pubxlen > numlen) || (pubylen > numlen)) { |
wolfSSL | 15:117db924cf7c | 6650 | WOLFSSL_MSG("Public key x/y invalid!"); |
wolfSSL | 15:117db924cf7c | 6651 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 6652 | } |
wolfSSL | 15:117db924cf7c | 6653 | |
wolfSSL | 15:117db924cf7c | 6654 | /* store byte point type */ |
wolfSSL | 15:117db924cf7c | 6655 | out[0] = ECC_POINT_UNCOMP; |
wolfSSL | 15:117db924cf7c | 6656 | |
wolfSSL | 15:117db924cf7c | 6657 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6658 | buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 6659 | if (buf == NULL) |
wolfSSL | 15:117db924cf7c | 6660 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6661 | #endif |
wolfSSL | 15:117db924cf7c | 6662 | |
wolfSSL | 15:117db924cf7c | 6663 | /* pad and store x */ |
wolfSSL | 15:117db924cf7c | 6664 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 6665 | ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen)); |
wolfSSL | 15:117db924cf7c | 6666 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6667 | goto done; |
wolfSSL | 15:117db924cf7c | 6668 | XMEMCPY(out+1, buf, numlen); |
wolfSSL | 15:117db924cf7c | 6669 | |
wolfSSL | 15:117db924cf7c | 6670 | /* pad and store y */ |
wolfSSL | 15:117db924cf7c | 6671 | XMEMSET(buf, 0, ECC_BUFSIZE); |
wolfSSL | 15:117db924cf7c | 6672 | ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen)); |
wolfSSL | 15:117db924cf7c | 6673 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6674 | goto done; |
wolfSSL | 15:117db924cf7c | 6675 | XMEMCPY(out+1+numlen, buf, numlen); |
wolfSSL | 15:117db924cf7c | 6676 | |
wolfSSL | 15:117db924cf7c | 6677 | *outLen = 1 + 2*numlen; |
wolfSSL | 15:117db924cf7c | 6678 | |
wolfSSL | 15:117db924cf7c | 6679 | done: |
wolfSSL | 15:117db924cf7c | 6680 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6681 | XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 6682 | #endif |
wolfSSL | 15:117db924cf7c | 6683 | |
wolfSSL | 15:117db924cf7c | 6684 | return ret; |
wolfSSL | 15:117db924cf7c | 6685 | } |
wolfSSL | 15:117db924cf7c | 6686 | |
wolfSSL | 15:117db924cf7c | 6687 | |
wolfSSL | 15:117db924cf7c | 6688 | /* export public ECC key in ANSI X9.63 format, extended with |
wolfSSL | 15:117db924cf7c | 6689 | * compression option */ |
wolfSSL | 15:117db924cf7c | 6690 | int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, |
wolfSSL | 15:117db924cf7c | 6691 | int compressed) |
wolfSSL | 15:117db924cf7c | 6692 | { |
wolfSSL | 15:117db924cf7c | 6693 | if (compressed == 0) |
wolfSSL | 15:117db924cf7c | 6694 | return wc_ecc_export_x963(key, out, outLen); |
wolfSSL | 15:117db924cf7c | 6695 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 6696 | else |
wolfSSL | 15:117db924cf7c | 6697 | return wc_ecc_export_x963_compressed(key, out, outLen); |
wolfSSL | 15:117db924cf7c | 6698 | #else |
wolfSSL | 15:117db924cf7c | 6699 | return NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 6700 | #endif |
wolfSSL | 15:117db924cf7c | 6701 | } |
wolfSSL | 15:117db924cf7c | 6702 | #endif /* HAVE_ECC_KEY_EXPORT */ |
wolfSSL | 15:117db924cf7c | 6703 | |
wolfSSL | 15:117db924cf7c | 6704 | |
wolfSSL | 16:8e0d178b1d1e | 6705 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 6706 | |
wolfSSL | 15:117db924cf7c | 6707 | /* is ecc point on curve described by dp ? */ |
wolfSSL | 15:117db924cf7c | 6708 | int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) |
wolfSSL | 15:117db924cf7c | 6709 | { |
wolfSSL | 15:117db924cf7c | 6710 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 6711 | int err; |
wolfSSL | 15:117db924cf7c | 6712 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 16:8e0d178b1d1e | 6713 | mp_int* t1; |
wolfSSL | 16:8e0d178b1d1e | 6714 | mp_int* t2; |
wolfSSL | 15:117db924cf7c | 6715 | #else |
wolfSSL | 15:117db924cf7c | 6716 | mp_int t1[1], t2[1]; |
wolfSSL | 15:117db924cf7c | 6717 | #endif |
wolfSSL | 15:117db924cf7c | 6718 | |
wolfSSL | 15:117db924cf7c | 6719 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6720 | t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6721 | if (t1 == NULL) |
wolfSSL | 15:117db924cf7c | 6722 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6723 | t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6724 | if (t2 == NULL) { |
wolfSSL | 15:117db924cf7c | 6725 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6726 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6727 | } |
wolfSSL | 15:117db924cf7c | 6728 | #endif |
wolfSSL | 15:117db924cf7c | 6729 | |
wolfSSL | 15:117db924cf7c | 6730 | if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6731 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6732 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6733 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6734 | #endif |
wolfSSL | 15:117db924cf7c | 6735 | return err; |
wolfSSL | 15:117db924cf7c | 6736 | } |
wolfSSL | 15:117db924cf7c | 6737 | |
wolfSSL | 15:117db924cf7c | 6738 | /* compute y^2 */ |
wolfSSL | 15:117db924cf7c | 6739 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6740 | err = mp_sqr(ecp->y, t1); |
wolfSSL | 15:117db924cf7c | 6741 | |
wolfSSL | 15:117db924cf7c | 6742 | /* compute x^3 */ |
wolfSSL | 15:117db924cf7c | 6743 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6744 | err = mp_sqr(ecp->x, t2); |
wolfSSL | 15:117db924cf7c | 6745 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6746 | err = mp_mod(t2, prime, t2); |
wolfSSL | 15:117db924cf7c | 6747 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6748 | err = mp_mul(ecp->x, t2, t2); |
wolfSSL | 15:117db924cf7c | 6749 | |
wolfSSL | 15:117db924cf7c | 6750 | /* compute y^2 - x^3 */ |
wolfSSL | 15:117db924cf7c | 6751 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6752 | err = mp_sub(t1, t2, t1); |
wolfSSL | 15:117db924cf7c | 6753 | |
wolfSSL | 15:117db924cf7c | 6754 | /* Determine if curve "a" should be used in calc */ |
wolfSSL | 15:117db924cf7c | 6755 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 6756 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6757 | /* Use a and prime to determine if a == 3 */ |
wolfSSL | 15:117db924cf7c | 6758 | err = mp_set(t2, 0); |
wolfSSL | 15:117db924cf7c | 6759 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6760 | err = mp_submod(prime, a, prime, t2); |
wolfSSL | 15:117db924cf7c | 6761 | } |
wolfSSL | 15:117db924cf7c | 6762 | if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) { |
wolfSSL | 15:117db924cf7c | 6763 | /* compute y^2 - x^3 + a*x */ |
wolfSSL | 15:117db924cf7c | 6764 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6765 | err = mp_mulmod(t2, ecp->x, prime, t2); |
wolfSSL | 15:117db924cf7c | 6766 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6767 | err = mp_addmod(t1, t2, prime, t1); |
wolfSSL | 15:117db924cf7c | 6768 | } |
wolfSSL | 15:117db924cf7c | 6769 | else |
wolfSSL | 15:117db924cf7c | 6770 | #endif /* WOLFSSL_CUSTOM_CURVES */ |
wolfSSL | 15:117db924cf7c | 6771 | { |
wolfSSL | 15:117db924cf7c | 6772 | /* assumes "a" == 3 */ |
wolfSSL | 15:117db924cf7c | 6773 | (void)a; |
wolfSSL | 15:117db924cf7c | 6774 | |
wolfSSL | 15:117db924cf7c | 6775 | /* compute y^2 - x^3 + 3x */ |
wolfSSL | 15:117db924cf7c | 6776 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6777 | err = mp_add(t1, ecp->x, t1); |
wolfSSL | 15:117db924cf7c | 6778 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6779 | err = mp_add(t1, ecp->x, t1); |
wolfSSL | 15:117db924cf7c | 6780 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6781 | err = mp_add(t1, ecp->x, t1); |
wolfSSL | 15:117db924cf7c | 6782 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6783 | err = mp_mod(t1, prime, t1); |
wolfSSL | 15:117db924cf7c | 6784 | } |
wolfSSL | 15:117db924cf7c | 6785 | |
wolfSSL | 15:117db924cf7c | 6786 | /* adjust range (0, prime) */ |
wolfSSL | 15:117db924cf7c | 6787 | while (err == MP_OKAY && mp_isneg(t1)) { |
wolfSSL | 15:117db924cf7c | 6788 | err = mp_add(t1, prime, t1); |
wolfSSL | 15:117db924cf7c | 6789 | } |
wolfSSL | 15:117db924cf7c | 6790 | while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 6791 | err = mp_sub(t1, prime, t1); |
wolfSSL | 15:117db924cf7c | 6792 | } |
wolfSSL | 15:117db924cf7c | 6793 | |
wolfSSL | 15:117db924cf7c | 6794 | /* compare to b */ |
wolfSSL | 15:117db924cf7c | 6795 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6796 | if (mp_cmp(t1, b) != MP_EQ) { |
wolfSSL | 15:117db924cf7c | 6797 | err = MP_VAL; |
wolfSSL | 15:117db924cf7c | 6798 | } else { |
wolfSSL | 15:117db924cf7c | 6799 | err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 6800 | } |
wolfSSL | 15:117db924cf7c | 6801 | } |
wolfSSL | 15:117db924cf7c | 6802 | |
wolfSSL | 15:117db924cf7c | 6803 | mp_clear(t1); |
wolfSSL | 15:117db924cf7c | 6804 | mp_clear(t2); |
wolfSSL | 15:117db924cf7c | 6805 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 6806 | XFREE(t2, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6807 | XFREE(t1, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 6808 | #endif |
wolfSSL | 15:117db924cf7c | 6809 | |
wolfSSL | 15:117db924cf7c | 6810 | return err; |
wolfSSL | 15:117db924cf7c | 6811 | #else |
wolfSSL | 15:117db924cf7c | 6812 | (void)a; |
wolfSSL | 15:117db924cf7c | 6813 | (void)b; |
wolfSSL | 16:8e0d178b1d1e | 6814 | |
wolfSSL | 16:8e0d178b1d1e | 6815 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 6816 | if (mp_count_bits(prime) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 6817 | return sp_ecc_is_point_256(ecp->x, ecp->y); |
wolfSSL | 16:8e0d178b1d1e | 6818 | } |
wolfSSL | 16:8e0d178b1d1e | 6819 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6820 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 6821 | if (mp_count_bits(prime) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 6822 | return sp_ecc_is_point_384(ecp->x, ecp->y); |
wolfSSL | 16:8e0d178b1d1e | 6823 | } |
wolfSSL | 16:8e0d178b1d1e | 6824 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6825 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 6826 | #endif |
wolfSSL | 15:117db924cf7c | 6827 | } |
wolfSSL | 15:117db924cf7c | 6828 | |
wolfSSL | 15:117db924cf7c | 6829 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 6830 | /* validate privkey * generator == pubkey, 0 on success */ |
wolfSSL | 15:117db924cf7c | 6831 | static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) |
wolfSSL | 15:117db924cf7c | 6832 | { |
wolfSSL | 15:117db924cf7c | 6833 | int err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 6834 | ecc_point* base = NULL; |
wolfSSL | 15:117db924cf7c | 6835 | ecc_point* res = NULL; |
wolfSSL | 15:117db924cf7c | 6836 | DECLARE_CURVE_SPECS(curve, 2); |
wolfSSL | 15:117db924cf7c | 6837 | |
wolfSSL | 15:117db924cf7c | 6838 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 6839 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 6840 | |
wolfSSL | 15:117db924cf7c | 6841 | ALLOC_CURVE_SPECS(2); |
wolfSSL | 15:117db924cf7c | 6842 | |
wolfSSL | 15:117db924cf7c | 6843 | res = wc_ecc_new_point_h(key->heap); |
wolfSSL | 15:117db924cf7c | 6844 | if (res == NULL) |
wolfSSL | 15:117db924cf7c | 6845 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6846 | |
wolfSSL | 15:117db924cf7c | 6847 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 6848 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 6849 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 6850 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6851 | err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6852 | } |
wolfSSL | 16:8e0d178b1d1e | 6853 | } |
wolfSSL | 16:8e0d178b1d1e | 6854 | else |
wolfSSL | 16:8e0d178b1d1e | 6855 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6856 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 6857 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 6858 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 6859 | err = sp_ecc_mulmod_base_384(&key->k, res, 1, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6860 | } |
wolfSSL | 15:117db924cf7c | 6861 | } |
wolfSSL | 15:117db924cf7c | 6862 | else |
wolfSSL | 15:117db924cf7c | 6863 | #endif |
wolfSSL | 15:117db924cf7c | 6864 | #endif |
wolfSSL | 15:117db924cf7c | 6865 | { |
wolfSSL | 15:117db924cf7c | 6866 | base = wc_ecc_new_point_h(key->heap); |
wolfSSL | 15:117db924cf7c | 6867 | if (base == NULL) |
wolfSSL | 15:117db924cf7c | 6868 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6869 | |
wolfSSL | 15:117db924cf7c | 6870 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6871 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 6872 | err = wc_ecc_curve_load(key->dp, &curve, |
wolfSSL | 15:117db924cf7c | 6873 | (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY)); |
wolfSSL | 15:117db924cf7c | 6874 | } |
wolfSSL | 15:117db924cf7c | 6875 | |
wolfSSL | 15:117db924cf7c | 6876 | /* set up base generator */ |
wolfSSL | 15:117db924cf7c | 6877 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6878 | err = mp_copy(curve->Gx, base->x); |
wolfSSL | 15:117db924cf7c | 6879 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6880 | err = mp_copy(curve->Gy, base->y); |
wolfSSL | 15:117db924cf7c | 6881 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6882 | err = mp_set(base->z, 1); |
wolfSSL | 15:117db924cf7c | 6883 | |
wolfSSL | 15:117db924cf7c | 6884 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6885 | err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap); |
wolfSSL | 15:117db924cf7c | 6886 | } |
wolfSSL | 15:117db924cf7c | 6887 | |
wolfSSL | 15:117db924cf7c | 6888 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 6889 | /* compare result to public key */ |
wolfSSL | 15:117db924cf7c | 6890 | if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || |
wolfSSL | 15:117db924cf7c | 6891 | mp_cmp(res->y, key->pubkey.y) != MP_EQ || |
wolfSSL | 15:117db924cf7c | 6892 | mp_cmp(res->z, key->pubkey.z) != MP_EQ) { |
wolfSSL | 15:117db924cf7c | 6893 | /* didn't match */ |
wolfSSL | 15:117db924cf7c | 6894 | err = ECC_PRIV_KEY_E; |
wolfSSL | 15:117db924cf7c | 6895 | } |
wolfSSL | 15:117db924cf7c | 6896 | } |
wolfSSL | 15:117db924cf7c | 6897 | |
wolfSSL | 15:117db924cf7c | 6898 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 6899 | wc_ecc_del_point_h(res, key->heap); |
wolfSSL | 15:117db924cf7c | 6900 | wc_ecc_del_point_h(base, key->heap); |
wolfSSL | 15:117db924cf7c | 6901 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6902 | |
wolfSSL | 15:117db924cf7c | 6903 | return err; |
wolfSSL | 15:117db924cf7c | 6904 | } |
wolfSSL | 15:117db924cf7c | 6905 | #endif |
wolfSSL | 15:117db924cf7c | 6906 | |
wolfSSL | 15:117db924cf7c | 6907 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 15:117db924cf7c | 6908 | |
wolfSSL | 15:117db924cf7c | 6909 | /* check privkey generator helper, creates prime needed */ |
wolfSSL | 15:117db924cf7c | 6910 | static int ecc_check_privkey_gen_helper(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 6911 | { |
wolfSSL | 15:117db924cf7c | 6912 | int err; |
wolfSSL | 15:117db924cf7c | 6913 | #ifndef WOLFSSL_ATECC508A |
wolfSSL | 15:117db924cf7c | 6914 | DECLARE_CURVE_SPECS(curve, 2); |
wolfSSL | 15:117db924cf7c | 6915 | #endif |
wolfSSL | 15:117db924cf7c | 6916 | |
wolfSSL | 15:117db924cf7c | 6917 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 6918 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 6919 | |
wolfSSL | 15:117db924cf7c | 6920 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 6921 | /* Hardware based private key, so this operation is not supported */ |
wolfSSL | 16:8e0d178b1d1e | 6922 | err = MP_OKAY; /* just report success */ |
wolfSSL | 15:117db924cf7c | 6923 | |
wolfSSL | 15:117db924cf7c | 6924 | #else |
wolfSSL | 15:117db924cf7c | 6925 | ALLOC_CURVE_SPECS(2); |
wolfSSL | 15:117db924cf7c | 6926 | |
wolfSSL | 15:117db924cf7c | 6927 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 6928 | err = wc_ecc_curve_load(key->dp, &curve, |
wolfSSL | 15:117db924cf7c | 6929 | (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); |
wolfSSL | 15:117db924cf7c | 6930 | |
wolfSSL | 15:117db924cf7c | 6931 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 6932 | err = ecc_check_privkey_gen(key, curve->Af, curve->prime); |
wolfSSL | 15:117db924cf7c | 6933 | |
wolfSSL | 15:117db924cf7c | 6934 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 6935 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 6936 | |
wolfSSL | 15:117db924cf7c | 6937 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 6938 | |
wolfSSL | 15:117db924cf7c | 6939 | return err; |
wolfSSL | 15:117db924cf7c | 6940 | } |
wolfSSL | 15:117db924cf7c | 6941 | |
wolfSSL | 15:117db924cf7c | 6942 | #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ |
wolfSSL | 15:117db924cf7c | 6943 | |
wolfSSL | 15:117db924cf7c | 6944 | #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH) |
wolfSSL | 15:117db924cf7c | 6945 | /* validate order * pubkey = point at infinity, 0 on success */ |
wolfSSL | 15:117db924cf7c | 6946 | static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, |
wolfSSL | 15:117db924cf7c | 6947 | mp_int* prime, mp_int* order) |
wolfSSL | 15:117db924cf7c | 6948 | { |
wolfSSL | 15:117db924cf7c | 6949 | ecc_point* inf = NULL; |
wolfSSL | 15:117db924cf7c | 6950 | int err; |
wolfSSL | 15:117db924cf7c | 6951 | |
wolfSSL | 15:117db924cf7c | 6952 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 6953 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 6954 | |
wolfSSL | 15:117db924cf7c | 6955 | inf = wc_ecc_new_point_h(key->heap); |
wolfSSL | 15:117db924cf7c | 6956 | if (inf == NULL) |
wolfSSL | 15:117db924cf7c | 6957 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 6958 | else { |
wolfSSL | 15:117db924cf7c | 6959 | #ifdef WOLFSSL_HAVE_SP_ECC |
wolfSSL | 15:117db924cf7c | 6960 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 6961 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 15:117db924cf7c | 6962 | ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 15:117db924cf7c | 6963 | err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap); |
wolfSSL | 15:117db924cf7c | 6964 | } |
wolfSSL | 15:117db924cf7c | 6965 | else |
wolfSSL | 15:117db924cf7c | 6966 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6967 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 6968 | if (key->idx != ECC_CUSTOM_IDX && |
wolfSSL | 16:8e0d178b1d1e | 6969 | ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 6970 | err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap); |
wolfSSL | 16:8e0d178b1d1e | 6971 | } |
wolfSSL | 16:8e0d178b1d1e | 6972 | else |
wolfSSL | 16:8e0d178b1d1e | 6973 | #endif |
wolfSSL | 15:117db924cf7c | 6974 | #endif |
wolfSSL | 15:117db924cf7c | 6975 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 6976 | err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap); |
wolfSSL | 15:117db924cf7c | 6977 | if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) |
wolfSSL | 15:117db924cf7c | 6978 | err = ECC_INF_E; |
wolfSSL | 15:117db924cf7c | 6979 | #else |
wolfSSL | 15:117db924cf7c | 6980 | (void)a; |
wolfSSL | 15:117db924cf7c | 6981 | (void)prime; |
wolfSSL | 15:117db924cf7c | 6982 | |
wolfSSL | 15:117db924cf7c | 6983 | err = WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 6984 | #endif |
wolfSSL | 15:117db924cf7c | 6985 | } |
wolfSSL | 15:117db924cf7c | 6986 | |
wolfSSL | 15:117db924cf7c | 6987 | wc_ecc_del_point_h(inf, key->heap); |
wolfSSL | 15:117db924cf7c | 6988 | |
wolfSSL | 15:117db924cf7c | 6989 | return err; |
wolfSSL | 15:117db924cf7c | 6990 | } |
wolfSSL | 15:117db924cf7c | 6991 | #endif |
wolfSSL | 16:8e0d178b1d1e | 6992 | #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL*/ |
wolfSSL | 16:8e0d178b1d1e | 6993 | |
wolfSSL | 16:8e0d178b1d1e | 6994 | #ifdef OPENSSL_EXTRA |
wolfSSL | 16:8e0d178b1d1e | 6995 | int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) |
wolfSSL | 16:8e0d178b1d1e | 6996 | { |
wolfSSL | 16:8e0d178b1d1e | 6997 | int err = MP_OKAY; |
wolfSSL | 16:8e0d178b1d1e | 6998 | DECLARE_CURVE_SPECS(curve, 2); |
wolfSSL | 16:8e0d178b1d1e | 6999 | |
wolfSSL | 16:8e0d178b1d1e | 7000 | if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1)) |
wolfSSL | 16:8e0d178b1d1e | 7001 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 7002 | |
wolfSSL | 16:8e0d178b1d1e | 7003 | ALLOC_CURVE_SPECS(2); |
wolfSSL | 16:8e0d178b1d1e | 7004 | |
wolfSSL | 16:8e0d178b1d1e | 7005 | err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, |
wolfSSL | 16:8e0d178b1d1e | 7006 | (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY)); |
wolfSSL | 16:8e0d178b1d1e | 7007 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7008 | err = mp_copy(curve->Gx, ecp->x); |
wolfSSL | 16:8e0d178b1d1e | 7009 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7010 | err = mp_copy(curve->Gy, ecp->y); |
wolfSSL | 16:8e0d178b1d1e | 7011 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7012 | err = mp_set(ecp->z, 1); |
wolfSSL | 16:8e0d178b1d1e | 7013 | |
wolfSSL | 16:8e0d178b1d1e | 7014 | wc_ecc_curve_free(curve); |
wolfSSL | 16:8e0d178b1d1e | 7015 | FREE_CURVE_SPECS(); |
wolfSSL | 16:8e0d178b1d1e | 7016 | |
wolfSSL | 16:8e0d178b1d1e | 7017 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7018 | } |
wolfSSL | 16:8e0d178b1d1e | 7019 | #endif /* OPENSSLALL */ |
wolfSSL | 15:117db924cf7c | 7020 | |
wolfSSL | 15:117db924cf7c | 7021 | /* perform sanity checks on ecc key validity, 0 on success */ |
wolfSSL | 15:117db924cf7c | 7022 | int wc_ecc_check_key(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 7023 | { |
wolfSSL | 15:117db924cf7c | 7024 | int err; |
wolfSSL | 15:117db924cf7c | 7025 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 16:8e0d178b1d1e | 7026 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 7027 | mp_int* b = NULL; |
wolfSSL | 15:117db924cf7c | 7028 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 7029 | DECLARE_CURVE_SPECS(curve, 4); |
wolfSSL | 15:117db924cf7c | 7030 | #else |
wolfSSL | 15:117db924cf7c | 7031 | #ifndef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7032 | mp_int b_lcl; |
wolfSSL | 15:117db924cf7c | 7033 | #endif |
wolfSSL | 15:117db924cf7c | 7034 | DECLARE_CURVE_SPECS(curve, 3); |
wolfSSL | 15:117db924cf7c | 7035 | #endif /* USE_ECC_B_PARAM */ |
wolfSSL | 15:117db924cf7c | 7036 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 7037 | |
wolfSSL | 15:117db924cf7c | 7038 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 7039 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7040 | |
wolfSSL | 16:8e0d178b1d1e | 7041 | #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 7042 | |
wolfSSL | 16:8e0d178b1d1e | 7043 | err = 0; /* consider key check success on ATECC508A */ |
wolfSSL | 15:117db924cf7c | 7044 | |
wolfSSL | 15:117db924cf7c | 7045 | #else |
wolfSSL | 15:117db924cf7c | 7046 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 7047 | ALLOC_CURVE_SPECS(4); |
wolfSSL | 15:117db924cf7c | 7048 | #else |
wolfSSL | 15:117db924cf7c | 7049 | ALLOC_CURVE_SPECS(3); |
wolfSSL | 15:117db924cf7c | 7050 | #ifndef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7051 | b = &b_lcl; |
wolfSSL | 15:117db924cf7c | 7052 | #else |
wolfSSL | 15:117db924cf7c | 7053 | b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7054 | if (b == NULL) { |
wolfSSL | 15:117db924cf7c | 7055 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 7056 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7057 | } |
wolfSSL | 15:117db924cf7c | 7058 | #endif |
wolfSSL | 15:117db924cf7c | 7059 | XMEMSET(b, 0, sizeof(mp_int)); |
wolfSSL | 15:117db924cf7c | 7060 | #endif |
wolfSSL | 15:117db924cf7c | 7061 | |
wolfSSL | 15:117db924cf7c | 7062 | /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */ |
wolfSSL | 15:117db924cf7c | 7063 | /* pubkey point cannot be at infinity */ |
wolfSSL | 15:117db924cf7c | 7064 | if (wc_ecc_point_is_at_infinity(&key->pubkey)) { |
wolfSSL | 15:117db924cf7c | 7065 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7066 | XFREE(b, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7067 | #endif |
wolfSSL | 15:117db924cf7c | 7068 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 7069 | return ECC_INF_E; |
wolfSSL | 15:117db924cf7c | 7070 | } |
wolfSSL | 15:117db924cf7c | 7071 | |
wolfSSL | 15:117db924cf7c | 7072 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 7073 | err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME | |
wolfSSL | 15:117db924cf7c | 7074 | ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER |
wolfSSL | 15:117db924cf7c | 7075 | #ifdef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 7076 | | ECC_CURVE_FIELD_BF |
wolfSSL | 15:117db924cf7c | 7077 | #endif |
wolfSSL | 15:117db924cf7c | 7078 | )); |
wolfSSL | 15:117db924cf7c | 7079 | |
wolfSSL | 15:117db924cf7c | 7080 | #ifndef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 7081 | /* load curve b parameter */ |
wolfSSL | 15:117db924cf7c | 7082 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7083 | err = mp_init(b); |
wolfSSL | 15:117db924cf7c | 7084 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7085 | err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7086 | #else |
wolfSSL | 16:8e0d178b1d1e | 7087 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7088 | b = curve->Bf; |
wolfSSL | 15:117db924cf7c | 7089 | #endif |
wolfSSL | 15:117db924cf7c | 7090 | |
wolfSSL | 15:117db924cf7c | 7091 | /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */ |
wolfSSL | 15:117db924cf7c | 7092 | /* Qx must be in the range [0, p-1] */ |
wolfSSL | 16:8e0d178b1d1e | 7093 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7094 | if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT) |
wolfSSL | 16:8e0d178b1d1e | 7095 | err = ECC_OUT_OF_RANGE_E; |
wolfSSL | 16:8e0d178b1d1e | 7096 | } |
wolfSSL | 15:117db924cf7c | 7097 | |
wolfSSL | 15:117db924cf7c | 7098 | /* Qy must be in the range [0, p-1] */ |
wolfSSL | 16:8e0d178b1d1e | 7099 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7100 | if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT) |
wolfSSL | 16:8e0d178b1d1e | 7101 | err = ECC_OUT_OF_RANGE_E; |
wolfSSL | 16:8e0d178b1d1e | 7102 | } |
wolfSSL | 15:117db924cf7c | 7103 | |
wolfSSL | 15:117db924cf7c | 7104 | /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */ |
wolfSSL | 15:117db924cf7c | 7105 | /* make sure point is actually on curve */ |
wolfSSL | 15:117db924cf7c | 7106 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7107 | err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime); |
wolfSSL | 15:117db924cf7c | 7108 | |
wolfSSL | 15:117db924cf7c | 7109 | /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */ |
wolfSSL | 15:117db924cf7c | 7110 | /* pubkey * order must be at infinity */ |
wolfSSL | 15:117db924cf7c | 7111 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7112 | err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime, |
wolfSSL | 15:117db924cf7c | 7113 | curve->order); |
wolfSSL | 15:117db924cf7c | 7114 | |
wolfSSL | 15:117db924cf7c | 7115 | /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */ |
wolfSSL | 15:117db924cf7c | 7116 | /* private * base generator must equal pubkey */ |
wolfSSL | 15:117db924cf7c | 7117 | if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) |
wolfSSL | 15:117db924cf7c | 7118 | err = ecc_check_privkey_gen(key, curve->Af, curve->prime); |
wolfSSL | 15:117db924cf7c | 7119 | |
wolfSSL | 15:117db924cf7c | 7120 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 7121 | |
wolfSSL | 15:117db924cf7c | 7122 | #ifndef USE_ECC_B_PARAM |
wolfSSL | 15:117db924cf7c | 7123 | mp_clear(b); |
wolfSSL | 15:117db924cf7c | 7124 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7125 | XFREE(b, key->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7126 | #endif |
wolfSSL | 15:117db924cf7c | 7127 | #endif |
wolfSSL | 15:117db924cf7c | 7128 | |
wolfSSL | 15:117db924cf7c | 7129 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 7130 | |
wolfSSL | 15:117db924cf7c | 7131 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 7132 | #else |
wolfSSL | 15:117db924cf7c | 7133 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 7134 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7135 | |
wolfSSL | 15:117db924cf7c | 7136 | /* pubkey point cannot be at infinity */ |
wolfSSL | 16:8e0d178b1d1e | 7137 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 15:117db924cf7c | 7138 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { |
wolfSSL | 15:117db924cf7c | 7139 | err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k, |
wolfSSL | 15:117db924cf7c | 7140 | key->heap); |
wolfSSL | 15:117db924cf7c | 7141 | } |
wolfSSL | 15:117db924cf7c | 7142 | else |
wolfSSL | 16:8e0d178b1d1e | 7143 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7144 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 7145 | if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 7146 | err = sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, &key->k, |
wolfSSL | 16:8e0d178b1d1e | 7147 | key->heap); |
wolfSSL | 16:8e0d178b1d1e | 7148 | } |
wolfSSL | 16:8e0d178b1d1e | 7149 | else |
wolfSSL | 16:8e0d178b1d1e | 7150 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7151 | { |
wolfSSL | 15:117db924cf7c | 7152 | err = WC_KEY_SIZE_E; |
wolfSSL | 16:8e0d178b1d1e | 7153 | } |
wolfSSL | 15:117db924cf7c | 7154 | #endif |
wolfSSL | 15:117db924cf7c | 7155 | |
wolfSSL | 15:117db924cf7c | 7156 | return err; |
wolfSSL | 15:117db924cf7c | 7157 | } |
wolfSSL | 15:117db924cf7c | 7158 | |
wolfSSL | 15:117db924cf7c | 7159 | #ifdef HAVE_ECC_KEY_IMPORT |
wolfSSL | 15:117db924cf7c | 7160 | /* import public ECC key in ANSI X9.63 format */ |
wolfSSL | 15:117db924cf7c | 7161 | int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, |
wolfSSL | 15:117db924cf7c | 7162 | int curve_id) |
wolfSSL | 15:117db924cf7c | 7163 | { |
wolfSSL | 15:117db924cf7c | 7164 | int err = MP_OKAY; |
wolfSSL | 16:8e0d178b1d1e | 7165 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 7166 | int compressed = 0; |
wolfSSL | 16:8e0d178b1d1e | 7167 | #endif |
wolfSSL | 15:117db924cf7c | 7168 | int keysize = 0; |
wolfSSL | 15:117db924cf7c | 7169 | byte pointType; |
wolfSSL | 15:117db924cf7c | 7170 | |
wolfSSL | 15:117db924cf7c | 7171 | if (in == NULL || key == NULL) |
wolfSSL | 15:117db924cf7c | 7172 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7173 | |
wolfSSL | 15:117db924cf7c | 7174 | /* must be odd */ |
wolfSSL | 15:117db924cf7c | 7175 | if ((inLen & 1) == 0) { |
wolfSSL | 15:117db924cf7c | 7176 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 7177 | } |
wolfSSL | 15:117db924cf7c | 7178 | |
wolfSSL | 15:117db924cf7c | 7179 | /* make sure required variables are reset */ |
wolfSSL | 15:117db924cf7c | 7180 | wc_ecc_reset(key); |
wolfSSL | 15:117db924cf7c | 7181 | |
wolfSSL | 15:117db924cf7c | 7182 | /* init key */ |
wolfSSL | 15:117db924cf7c | 7183 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 7184 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 15:117db924cf7c | 7185 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 15:117db924cf7c | 7186 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 15:117db924cf7c | 7187 | alt_fp_init(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 7188 | alt_fp_init(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 7189 | alt_fp_init(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 7190 | err = mp_init(&key->k); |
wolfSSL | 15:117db924cf7c | 7191 | #else |
wolfSSL | 15:117db924cf7c | 7192 | err = mp_init_multi(&key->k, |
wolfSSL | 15:117db924cf7c | 7193 | key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 7194 | #endif |
wolfSSL | 15:117db924cf7c | 7195 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7196 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7197 | |
wolfSSL | 15:117db924cf7c | 7198 | /* check for point type (4, 2, or 3) */ |
wolfSSL | 15:117db924cf7c | 7199 | pointType = in[0]; |
wolfSSL | 15:117db924cf7c | 7200 | if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN && |
wolfSSL | 15:117db924cf7c | 7201 | pointType != ECC_POINT_COMP_ODD) { |
wolfSSL | 15:117db924cf7c | 7202 | err = ASN_PARSE_E; |
wolfSSL | 15:117db924cf7c | 7203 | } |
wolfSSL | 15:117db924cf7c | 7204 | |
wolfSSL | 15:117db924cf7c | 7205 | if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { |
wolfSSL | 15:117db924cf7c | 7206 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 7207 | compressed = 1; |
wolfSSL | 15:117db924cf7c | 7208 | #else |
wolfSSL | 15:117db924cf7c | 7209 | err = NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 7210 | #endif |
wolfSSL | 15:117db924cf7c | 7211 | } |
wolfSSL | 15:117db924cf7c | 7212 | |
wolfSSL | 15:117db924cf7c | 7213 | /* adjust to skip first byte */ |
wolfSSL | 15:117db924cf7c | 7214 | inLen -= 1; |
wolfSSL | 15:117db924cf7c | 7215 | in += 1; |
wolfSSL | 15:117db924cf7c | 7216 | |
wolfSSL | 16:8e0d178b1d1e | 7217 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 7218 | /* For SECP256R1 only save raw public key for hardware */ |
wolfSSL | 16:8e0d178b1d1e | 7219 | if (curve_id == ECC_SECP256R1 && inLen <= sizeof(key->pubkey_raw)) { |
wolfSSL | 16:8e0d178b1d1e | 7220 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 7221 | if (!compressed) |
wolfSSL | 16:8e0d178b1d1e | 7222 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7223 | XMEMCPY(key->pubkey_raw, (byte*)in, inLen); |
wolfSSL | 16:8e0d178b1d1e | 7224 | } |
wolfSSL | 16:8e0d178b1d1e | 7225 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7226 | |
wolfSSL | 15:117db924cf7c | 7227 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7228 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 7229 | /* adjust inLen if compressed */ |
wolfSSL | 15:117db924cf7c | 7230 | if (compressed) |
wolfSSL | 15:117db924cf7c | 7231 | inLen = inLen*2 + 1; /* used uncompressed len */ |
wolfSSL | 15:117db924cf7c | 7232 | #endif |
wolfSSL | 15:117db924cf7c | 7233 | |
wolfSSL | 15:117db924cf7c | 7234 | /* determine key size */ |
wolfSSL | 15:117db924cf7c | 7235 | keysize = (inLen>>1); |
wolfSSL | 15:117db924cf7c | 7236 | err = wc_ecc_set_curve(key, keysize, curve_id); |
wolfSSL | 15:117db924cf7c | 7237 | key->type = ECC_PUBLICKEY; |
wolfSSL | 15:117db924cf7c | 7238 | } |
wolfSSL | 15:117db924cf7c | 7239 | |
wolfSSL | 15:117db924cf7c | 7240 | /* read data */ |
wolfSSL | 15:117db924cf7c | 7241 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7242 | err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize); |
wolfSSL | 15:117db924cf7c | 7243 | |
wolfSSL | 15:117db924cf7c | 7244 | #ifdef HAVE_COMP_KEY |
wolfSSL | 15:117db924cf7c | 7245 | if (err == MP_OKAY && compressed == 1) { /* build y */ |
wolfSSL | 15:117db924cf7c | 7246 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 7247 | mp_int t1, t2; |
wolfSSL | 15:117db924cf7c | 7248 | int did_init = 0; |
wolfSSL | 15:117db924cf7c | 7249 | |
wolfSSL | 15:117db924cf7c | 7250 | DECLARE_CURVE_SPECS(curve, 3); |
wolfSSL | 15:117db924cf7c | 7251 | ALLOC_CURVE_SPECS(3); |
wolfSSL | 15:117db924cf7c | 7252 | |
wolfSSL | 15:117db924cf7c | 7253 | if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7254 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7255 | else |
wolfSSL | 15:117db924cf7c | 7256 | did_init = 1; |
wolfSSL | 15:117db924cf7c | 7257 | |
wolfSSL | 15:117db924cf7c | 7258 | /* load curve info */ |
wolfSSL | 15:117db924cf7c | 7259 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7260 | err = wc_ecc_curve_load(key->dp, &curve, |
wolfSSL | 15:117db924cf7c | 7261 | (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | |
wolfSSL | 15:117db924cf7c | 7262 | ECC_CURVE_FIELD_BF)); |
wolfSSL | 15:117db924cf7c | 7263 | |
wolfSSL | 15:117db924cf7c | 7264 | /* compute x^3 */ |
wolfSSL | 15:117db924cf7c | 7265 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7266 | err = mp_sqr(key->pubkey.x, &t1); |
wolfSSL | 15:117db924cf7c | 7267 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7268 | err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1); |
wolfSSL | 15:117db924cf7c | 7269 | |
wolfSSL | 15:117db924cf7c | 7270 | /* compute x^3 + a*x */ |
wolfSSL | 15:117db924cf7c | 7271 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7272 | err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 7273 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7274 | err = mp_add(&t1, &t2, &t1); |
wolfSSL | 15:117db924cf7c | 7275 | |
wolfSSL | 15:117db924cf7c | 7276 | /* compute x^3 + a*x + b */ |
wolfSSL | 15:117db924cf7c | 7277 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7278 | err = mp_add(&t1, curve->Bf, &t1); |
wolfSSL | 15:117db924cf7c | 7279 | |
wolfSSL | 15:117db924cf7c | 7280 | /* compute sqrt(x^3 + a*x + b) */ |
wolfSSL | 15:117db924cf7c | 7281 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7282 | err = mp_sqrtmod_prime(&t1, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 7283 | |
wolfSSL | 15:117db924cf7c | 7284 | /* adjust y */ |
wolfSSL | 15:117db924cf7c | 7285 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7286 | if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) || |
wolfSSL | 15:117db924cf7c | 7287 | (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) { |
wolfSSL | 15:117db924cf7c | 7288 | err = mp_mod(&t2, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 7289 | } |
wolfSSL | 15:117db924cf7c | 7290 | else { |
wolfSSL | 15:117db924cf7c | 7291 | err = mp_submod(curve->prime, &t2, curve->prime, &t2); |
wolfSSL | 15:117db924cf7c | 7292 | } |
wolfSSL | 15:117db924cf7c | 7293 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7294 | err = mp_copy(&t2, key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 7295 | } |
wolfSSL | 15:117db924cf7c | 7296 | |
wolfSSL | 15:117db924cf7c | 7297 | if (did_init) { |
wolfSSL | 15:117db924cf7c | 7298 | mp_clear(&t2); |
wolfSSL | 15:117db924cf7c | 7299 | mp_clear(&t1); |
wolfSSL | 15:117db924cf7c | 7300 | } |
wolfSSL | 15:117db924cf7c | 7301 | |
wolfSSL | 15:117db924cf7c | 7302 | wc_ecc_curve_free(curve); |
wolfSSL | 15:117db924cf7c | 7303 | FREE_CURVE_SPECS(); |
wolfSSL | 15:117db924cf7c | 7304 | #else |
wolfSSL | 16:8e0d178b1d1e | 7305 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 7306 | if (key->dp->id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 7307 | sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y); |
wolfSSL | 16:8e0d178b1d1e | 7308 | } |
wolfSSL | 16:8e0d178b1d1e | 7309 | else |
wolfSSL | 16:8e0d178b1d1e | 7310 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7311 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 7312 | if (key->dp->id == ECC_SECP384R1) { |
wolfSSL | 16:8e0d178b1d1e | 7313 | sp_ecc_uncompress_384(key->pubkey.x, pointType, key->pubkey.y); |
wolfSSL | 16:8e0d178b1d1e | 7314 | } |
wolfSSL | 16:8e0d178b1d1e | 7315 | else |
wolfSSL | 16:8e0d178b1d1e | 7316 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7317 | { |
wolfSSL | 16:8e0d178b1d1e | 7318 | err = WC_KEY_SIZE_E; |
wolfSSL | 16:8e0d178b1d1e | 7319 | } |
wolfSSL | 15:117db924cf7c | 7320 | #endif |
wolfSSL | 15:117db924cf7c | 7321 | } |
wolfSSL | 15:117db924cf7c | 7322 | #endif /* HAVE_COMP_KEY */ |
wolfSSL | 15:117db924cf7c | 7323 | |
wolfSSL | 16:8e0d178b1d1e | 7324 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7325 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 7326 | if (compressed == 0) |
wolfSSL | 16:8e0d178b1d1e | 7327 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7328 | { |
wolfSSL | 16:8e0d178b1d1e | 7329 | err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, |
wolfSSL | 16:8e0d178b1d1e | 7330 | keysize); |
wolfSSL | 16:8e0d178b1d1e | 7331 | } |
wolfSSL | 16:8e0d178b1d1e | 7332 | } |
wolfSSL | 15:117db924cf7c | 7333 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7334 | err = mp_set(key->pubkey.z, 1); |
wolfSSL | 15:117db924cf7c | 7335 | |
wolfSSL | 15:117db924cf7c | 7336 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 15:117db924cf7c | 7337 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7338 | err = wc_ecc_check_key(key); |
wolfSSL | 15:117db924cf7c | 7339 | #endif |
wolfSSL | 15:117db924cf7c | 7340 | |
wolfSSL | 15:117db924cf7c | 7341 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7342 | mp_clear(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 7343 | mp_clear(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 7344 | mp_clear(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 7345 | mp_clear(&key->k); |
wolfSSL | 15:117db924cf7c | 7346 | } |
wolfSSL | 15:117db924cf7c | 7347 | |
wolfSSL | 15:117db924cf7c | 7348 | return err; |
wolfSSL | 15:117db924cf7c | 7349 | } |
wolfSSL | 15:117db924cf7c | 7350 | |
wolfSSL | 16:8e0d178b1d1e | 7351 | WOLFSSL_ABI |
wolfSSL | 15:117db924cf7c | 7352 | int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) |
wolfSSL | 15:117db924cf7c | 7353 | { |
wolfSSL | 15:117db924cf7c | 7354 | return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); |
wolfSSL | 15:117db924cf7c | 7355 | } |
wolfSSL | 15:117db924cf7c | 7356 | #endif /* HAVE_ECC_KEY_IMPORT */ |
wolfSSL | 15:117db924cf7c | 7357 | |
wolfSSL | 15:117db924cf7c | 7358 | #ifdef HAVE_ECC_KEY_EXPORT |
wolfSSL | 16:8e0d178b1d1e | 7359 | |
wolfSSL | 16:8e0d178b1d1e | 7360 | /* export ecc key to component form, d is optional if only exporting public |
wolfSSL | 16:8e0d178b1d1e | 7361 | * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR |
wolfSSL | 16:8e0d178b1d1e | 7362 | * return MP_OKAY on success */ |
wolfSSL | 16:8e0d178b1d1e | 7363 | int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, |
wolfSSL | 16:8e0d178b1d1e | 7364 | byte* qy, word32* qyLen, byte* d, word32* dLen, int encType) |
wolfSSL | 16:8e0d178b1d1e | 7365 | { |
wolfSSL | 16:8e0d178b1d1e | 7366 | int err = 0; |
wolfSSL | 16:8e0d178b1d1e | 7367 | word32 keySz; |
wolfSSL | 16:8e0d178b1d1e | 7368 | |
wolfSSL | 16:8e0d178b1d1e | 7369 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 7370 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7371 | } |
wolfSSL | 15:117db924cf7c | 7372 | |
wolfSSL | 15:117db924cf7c | 7373 | if (wc_ecc_is_valid_idx(key->idx) == 0) { |
wolfSSL | 15:117db924cf7c | 7374 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 7375 | } |
wolfSSL | 16:8e0d178b1d1e | 7376 | keySz = key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 7377 | |
wolfSSL | 16:8e0d178b1d1e | 7378 | /* private key, d */ |
wolfSSL | 15:117db924cf7c | 7379 | if (d != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7380 | if (dLen == NULL || |
wolfSSL | 16:8e0d178b1d1e | 7381 | (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY)) |
wolfSSL | 15:117db924cf7c | 7382 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7383 | |
wolfSSL | 15:117db924cf7c | 7384 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 7385 | /* Hardware cannot export private portion */ |
wolfSSL | 16:8e0d178b1d1e | 7386 | return NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 7387 | #else |
wolfSSL | 16:8e0d178b1d1e | 7388 | err = wc_export_int(&key->k, d, dLen, keySz, encType); |
wolfSSL | 15:117db924cf7c | 7389 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7390 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7391 | #endif |
wolfSSL | 15:117db924cf7c | 7392 | } |
wolfSSL | 15:117db924cf7c | 7393 | |
wolfSSL | 15:117db924cf7c | 7394 | /* public x component */ |
wolfSSL | 16:8e0d178b1d1e | 7395 | if (qx != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7396 | if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY) |
wolfSSL | 16:8e0d178b1d1e | 7397 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 7398 | |
wolfSSL | 16:8e0d178b1d1e | 7399 | err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType); |
wolfSSL | 16:8e0d178b1d1e | 7400 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7401 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7402 | } |
wolfSSL | 15:117db924cf7c | 7403 | |
wolfSSL | 15:117db924cf7c | 7404 | /* public y component */ |
wolfSSL | 16:8e0d178b1d1e | 7405 | if (qy != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7406 | if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY) |
wolfSSL | 16:8e0d178b1d1e | 7407 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 7408 | |
wolfSSL | 16:8e0d178b1d1e | 7409 | err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType); |
wolfSSL | 16:8e0d178b1d1e | 7410 | if (err != MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7411 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7412 | } |
wolfSSL | 16:8e0d178b1d1e | 7413 | |
wolfSSL | 16:8e0d178b1d1e | 7414 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7415 | } |
wolfSSL | 16:8e0d178b1d1e | 7416 | |
wolfSSL | 16:8e0d178b1d1e | 7417 | |
wolfSSL | 16:8e0d178b1d1e | 7418 | /* export ecc private key only raw, outLen is in/out size as unsigned bin |
wolfSSL | 16:8e0d178b1d1e | 7419 | return MP_OKAY on success */ |
wolfSSL | 16:8e0d178b1d1e | 7420 | int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 16:8e0d178b1d1e | 7421 | { |
wolfSSL | 16:8e0d178b1d1e | 7422 | if (out == NULL || outLen == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7423 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 7424 | } |
wolfSSL | 16:8e0d178b1d1e | 7425 | |
wolfSSL | 16:8e0d178b1d1e | 7426 | return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen, |
wolfSSL | 16:8e0d178b1d1e | 7427 | WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7428 | } |
wolfSSL | 16:8e0d178b1d1e | 7429 | |
wolfSSL | 16:8e0d178b1d1e | 7430 | /* export public key to raw elements including public (Qx,Qy) as unsigned bin |
wolfSSL | 15:117db924cf7c | 7431 | * return MP_OKAY on success, negative on error */ |
wolfSSL | 15:117db924cf7c | 7432 | int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen, |
wolfSSL | 15:117db924cf7c | 7433 | byte* qy, word32* qyLen) |
wolfSSL | 15:117db924cf7c | 7434 | { |
wolfSSL | 16:8e0d178b1d1e | 7435 | if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7436 | return BAD_FUNC_ARG; |
wolfSSL | 16:8e0d178b1d1e | 7437 | } |
wolfSSL | 16:8e0d178b1d1e | 7438 | |
wolfSSL | 16:8e0d178b1d1e | 7439 | return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL, |
wolfSSL | 16:8e0d178b1d1e | 7440 | WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7441 | } |
wolfSSL | 16:8e0d178b1d1e | 7442 | |
wolfSSL | 16:8e0d178b1d1e | 7443 | /* export ecc key to raw elements including public (Qx,Qy) and |
wolfSSL | 16:8e0d178b1d1e | 7444 | * private (d) as unsigned bin |
wolfSSL | 15:117db924cf7c | 7445 | * return MP_OKAY on success, negative on error */ |
wolfSSL | 15:117db924cf7c | 7446 | int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen, |
wolfSSL | 15:117db924cf7c | 7447 | byte* qy, word32* qyLen, byte* d, word32* dLen) |
wolfSSL | 15:117db924cf7c | 7448 | { |
wolfSSL | 16:8e0d178b1d1e | 7449 | return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, |
wolfSSL | 16:8e0d178b1d1e | 7450 | WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 15:117db924cf7c | 7451 | } |
wolfSSL | 15:117db924cf7c | 7452 | |
wolfSSL | 15:117db924cf7c | 7453 | #endif /* HAVE_ECC_KEY_EXPORT */ |
wolfSSL | 15:117db924cf7c | 7454 | |
wolfSSL | 15:117db924cf7c | 7455 | #ifdef HAVE_ECC_KEY_IMPORT |
wolfSSL | 15:117db924cf7c | 7456 | /* import private key, public part optional if (pub) passed as NULL */ |
wolfSSL | 15:117db924cf7c | 7457 | int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, |
wolfSSL | 15:117db924cf7c | 7458 | const byte* pub, word32 pubSz, ecc_key* key, |
wolfSSL | 15:117db924cf7c | 7459 | int curve_id) |
wolfSSL | 15:117db924cf7c | 7460 | { |
wolfSSL | 15:117db924cf7c | 7461 | int ret; |
wolfSSL | 16:8e0d178b1d1e | 7462 | #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 7463 | const CRYS_ECPKI_Domain_t* pDomain; |
wolfSSL | 16:8e0d178b1d1e | 7464 | CRYS_ECPKI_BUILD_TempData_t tempBuff; |
wolfSSL | 16:8e0d178b1d1e | 7465 | #endif |
wolfSSL | 15:117db924cf7c | 7466 | if (key == NULL || priv == NULL) |
wolfSSL | 15:117db924cf7c | 7467 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7468 | |
wolfSSL | 15:117db924cf7c | 7469 | /* public optional, NULL if only importing private */ |
wolfSSL | 15:117db924cf7c | 7470 | if (pub != NULL) { |
wolfSSL | 16:8e0d178b1d1e | 7471 | #ifndef NO_ASN |
wolfSSL | 16:8e0d178b1d1e | 7472 | word32 idx = 0; |
wolfSSL | 15:117db924cf7c | 7473 | ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id); |
wolfSSL | 15:117db924cf7c | 7474 | if (ret < 0) |
wolfSSL | 15:117db924cf7c | 7475 | ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz); |
wolfSSL | 15:117db924cf7c | 7476 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 7477 | #else |
wolfSSL | 16:8e0d178b1d1e | 7478 | ret = NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 7479 | #endif |
wolfSSL | 15:117db924cf7c | 7480 | } |
wolfSSL | 15:117db924cf7c | 7481 | else { |
wolfSSL | 15:117db924cf7c | 7482 | /* make sure required variables are reset */ |
wolfSSL | 15:117db924cf7c | 7483 | wc_ecc_reset(key); |
wolfSSL | 15:117db924cf7c | 7484 | |
wolfSSL | 15:117db924cf7c | 7485 | /* set key size */ |
wolfSSL | 15:117db924cf7c | 7486 | ret = wc_ecc_set_curve(key, privSz, curve_id); |
wolfSSL | 15:117db924cf7c | 7487 | key->type = ECC_PRIVATEKEY_ONLY; |
wolfSSL | 15:117db924cf7c | 7488 | } |
wolfSSL | 15:117db924cf7c | 7489 | |
wolfSSL | 15:117db924cf7c | 7490 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 7491 | return ret; |
wolfSSL | 15:117db924cf7c | 7492 | |
wolfSSL | 15:117db924cf7c | 7493 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 7494 | /* Hardware does not support loading private keys */ |
wolfSSL | 16:8e0d178b1d1e | 7495 | return NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 7496 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 7497 | pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id)); |
wolfSSL | 16:8e0d178b1d1e | 7498 | |
wolfSSL | 16:8e0d178b1d1e | 7499 | if (pub != NULL && pub[0] != '\0') { |
wolfSSL | 16:8e0d178b1d1e | 7500 | /* create public key from external key buffer */ |
wolfSSL | 16:8e0d178b1d1e | 7501 | ret = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain, |
wolfSSL | 16:8e0d178b1d1e | 7502 | (byte*)pub, |
wolfSSL | 16:8e0d178b1d1e | 7503 | pubSz, |
wolfSSL | 16:8e0d178b1d1e | 7504 | &key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 7505 | &tempBuff); |
wolfSSL | 16:8e0d178b1d1e | 7506 | |
wolfSSL | 16:8e0d178b1d1e | 7507 | if (ret != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 7508 | WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed"); |
wolfSSL | 16:8e0d178b1d1e | 7509 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 7510 | } |
wolfSSL | 16:8e0d178b1d1e | 7511 | } |
wolfSSL | 16:8e0d178b1d1e | 7512 | /* import private key */ |
wolfSSL | 16:8e0d178b1d1e | 7513 | if (priv != NULL && priv[0] != '\0') { |
wolfSSL | 16:8e0d178b1d1e | 7514 | |
wolfSSL | 16:8e0d178b1d1e | 7515 | /* Create private key from external key buffer*/ |
wolfSSL | 16:8e0d178b1d1e | 7516 | ret = CRYS_ECPKI_BuildPrivKey(pDomain, |
wolfSSL | 16:8e0d178b1d1e | 7517 | priv, |
wolfSSL | 16:8e0d178b1d1e | 7518 | privSz, |
wolfSSL | 16:8e0d178b1d1e | 7519 | &key->ctx.privKey); |
wolfSSL | 16:8e0d178b1d1e | 7520 | |
wolfSSL | 16:8e0d178b1d1e | 7521 | if (ret != SA_SILIB_RET_OK) { |
wolfSSL | 16:8e0d178b1d1e | 7522 | WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed"); |
wolfSSL | 16:8e0d178b1d1e | 7523 | return ret; |
wolfSSL | 16:8e0d178b1d1e | 7524 | } |
wolfSSL | 16:8e0d178b1d1e | 7525 | |
wolfSSL | 16:8e0d178b1d1e | 7526 | ret = mp_read_unsigned_bin(&key->k, priv, privSz); |
wolfSSL | 16:8e0d178b1d1e | 7527 | } |
wolfSSL | 15:117db924cf7c | 7528 | |
wolfSSL | 15:117db924cf7c | 7529 | #else |
wolfSSL | 15:117db924cf7c | 7530 | |
wolfSSL | 15:117db924cf7c | 7531 | ret = mp_read_unsigned_bin(&key->k, priv, privSz); |
wolfSSL | 16:8e0d178b1d1e | 7532 | #ifdef HAVE_WOLF_BIGINT |
wolfSSL | 16:8e0d178b1d1e | 7533 | if (ret == 0 && |
wolfSSL | 16:8e0d178b1d1e | 7534 | wc_bigint_from_unsigned_bin(&key->k.raw, priv, privSz) != 0) { |
wolfSSL | 16:8e0d178b1d1e | 7535 | mp_clear(&key->k); |
wolfSSL | 16:8e0d178b1d1e | 7536 | ret = ASN_GETINT_E; |
wolfSSL | 16:8e0d178b1d1e | 7537 | } |
wolfSSL | 16:8e0d178b1d1e | 7538 | #endif /* HAVE_WOLF_BIGINT */ |
wolfSSL | 16:8e0d178b1d1e | 7539 | |
wolfSSL | 15:117db924cf7c | 7540 | |
wolfSSL | 15:117db924cf7c | 7541 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 7542 | |
wolfSSL | 15:117db924cf7c | 7543 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 15:117db924cf7c | 7544 | if ((pub != NULL) && (ret == MP_OKAY)) |
wolfSSL | 15:117db924cf7c | 7545 | /* public key needed to perform key validation */ |
wolfSSL | 15:117db924cf7c | 7546 | ret = ecc_check_privkey_gen_helper(key); |
wolfSSL | 15:117db924cf7c | 7547 | #endif |
wolfSSL | 15:117db924cf7c | 7548 | |
wolfSSL | 15:117db924cf7c | 7549 | return ret; |
wolfSSL | 15:117db924cf7c | 7550 | } |
wolfSSL | 15:117db924cf7c | 7551 | |
wolfSSL | 15:117db924cf7c | 7552 | /* ecc private key import, public key in ANSI X9.63 format, private raw */ |
wolfSSL | 15:117db924cf7c | 7553 | int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, |
wolfSSL | 15:117db924cf7c | 7554 | word32 pubSz, ecc_key* key) |
wolfSSL | 15:117db924cf7c | 7555 | { |
wolfSSL | 15:117db924cf7c | 7556 | return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, |
wolfSSL | 15:117db924cf7c | 7557 | ECC_CURVE_DEF); |
wolfSSL | 15:117db924cf7c | 7558 | } |
wolfSSL | 15:117db924cf7c | 7559 | #endif /* HAVE_ECC_KEY_IMPORT */ |
wolfSSL | 15:117db924cf7c | 7560 | |
wolfSSL | 15:117db924cf7c | 7561 | #ifndef NO_ASN |
wolfSSL | 15:117db924cf7c | 7562 | /** |
wolfSSL | 15:117db924cf7c | 7563 | Convert ECC R,S to signature |
wolfSSL | 15:117db924cf7c | 7564 | r R component of signature |
wolfSSL | 15:117db924cf7c | 7565 | s S component of signature |
wolfSSL | 15:117db924cf7c | 7566 | out DER-encoded ECDSA signature |
wolfSSL | 15:117db924cf7c | 7567 | outlen [in/out] output buffer size, output signature size |
wolfSSL | 15:117db924cf7c | 7568 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 7569 | */ |
wolfSSL | 15:117db924cf7c | 7570 | int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) |
wolfSSL | 15:117db924cf7c | 7571 | { |
wolfSSL | 15:117db924cf7c | 7572 | int err; |
wolfSSL | 15:117db924cf7c | 7573 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7574 | mp_int* rtmp = NULL; |
wolfSSL | 15:117db924cf7c | 7575 | mp_int* stmp = NULL; |
wolfSSL | 15:117db924cf7c | 7576 | #else |
wolfSSL | 15:117db924cf7c | 7577 | mp_int rtmp[1]; |
wolfSSL | 15:117db924cf7c | 7578 | mp_int stmp[1]; |
wolfSSL | 15:117db924cf7c | 7579 | #endif |
wolfSSL | 15:117db924cf7c | 7580 | |
wolfSSL | 15:117db924cf7c | 7581 | if (r == NULL || s == NULL || out == NULL || outlen == NULL) |
wolfSSL | 15:117db924cf7c | 7582 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 7583 | |
wolfSSL | 15:117db924cf7c | 7584 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7585 | rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7586 | if (rtmp == NULL) |
wolfSSL | 15:117db924cf7c | 7587 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7588 | stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7589 | if (stmp == NULL) { |
wolfSSL | 15:117db924cf7c | 7590 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7591 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7592 | } |
wolfSSL | 15:117db924cf7c | 7593 | #endif |
wolfSSL | 15:117db924cf7c | 7594 | |
wolfSSL | 15:117db924cf7c | 7595 | err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 7596 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7597 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7598 | XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7599 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7600 | #endif |
wolfSSL | 15:117db924cf7c | 7601 | return err; |
wolfSSL | 15:117db924cf7c | 7602 | } |
wolfSSL | 15:117db924cf7c | 7603 | |
wolfSSL | 15:117db924cf7c | 7604 | err = mp_read_radix(rtmp, r, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7605 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7606 | err = mp_read_radix(stmp, s, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7607 | |
wolfSSL | 15:117db924cf7c | 7608 | /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ |
wolfSSL | 15:117db924cf7c | 7609 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7610 | err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp); |
wolfSSL | 15:117db924cf7c | 7611 | |
wolfSSL | 15:117db924cf7c | 7612 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7613 | if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES) |
wolfSSL | 15:117db924cf7c | 7614 | err = MP_ZERO_E; |
wolfSSL | 15:117db924cf7c | 7615 | } |
wolfSSL | 15:117db924cf7c | 7616 | |
wolfSSL | 15:117db924cf7c | 7617 | mp_clear(rtmp); |
wolfSSL | 15:117db924cf7c | 7618 | mp_clear(stmp); |
wolfSSL | 15:117db924cf7c | 7619 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7620 | XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7621 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7622 | #endif |
wolfSSL | 15:117db924cf7c | 7623 | |
wolfSSL | 15:117db924cf7c | 7624 | return err; |
wolfSSL | 15:117db924cf7c | 7625 | } |
wolfSSL | 15:117db924cf7c | 7626 | |
wolfSSL | 15:117db924cf7c | 7627 | /** |
wolfSSL | 15:117db924cf7c | 7628 | Convert ECC R,S raw unsigned bin to signature |
wolfSSL | 15:117db924cf7c | 7629 | r R component of signature |
wolfSSL | 15:117db924cf7c | 7630 | rSz R size |
wolfSSL | 15:117db924cf7c | 7631 | s S component of signature |
wolfSSL | 15:117db924cf7c | 7632 | sSz S size |
wolfSSL | 15:117db924cf7c | 7633 | out DER-encoded ECDSA signature |
wolfSSL | 15:117db924cf7c | 7634 | outlen [in/out] output buffer size, output signature size |
wolfSSL | 15:117db924cf7c | 7635 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 7636 | */ |
wolfSSL | 15:117db924cf7c | 7637 | int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz, |
wolfSSL | 15:117db924cf7c | 7638 | byte* out, word32* outlen) |
wolfSSL | 15:117db924cf7c | 7639 | { |
wolfSSL | 15:117db924cf7c | 7640 | int err; |
wolfSSL | 15:117db924cf7c | 7641 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7642 | mp_int* rtmp = NULL; |
wolfSSL | 15:117db924cf7c | 7643 | mp_int* stmp = NULL; |
wolfSSL | 15:117db924cf7c | 7644 | #else |
wolfSSL | 15:117db924cf7c | 7645 | mp_int rtmp[1]; |
wolfSSL | 15:117db924cf7c | 7646 | mp_int stmp[1]; |
wolfSSL | 15:117db924cf7c | 7647 | #endif |
wolfSSL | 15:117db924cf7c | 7648 | |
wolfSSL | 15:117db924cf7c | 7649 | if (r == NULL || s == NULL || out == NULL || outlen == NULL) |
wolfSSL | 15:117db924cf7c | 7650 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 7651 | |
wolfSSL | 15:117db924cf7c | 7652 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7653 | rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7654 | if (rtmp == NULL) |
wolfSSL | 15:117db924cf7c | 7655 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7656 | stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7657 | if (stmp == NULL) { |
wolfSSL | 15:117db924cf7c | 7658 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7659 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7660 | } |
wolfSSL | 15:117db924cf7c | 7661 | #endif |
wolfSSL | 15:117db924cf7c | 7662 | |
wolfSSL | 15:117db924cf7c | 7663 | err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 7664 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7665 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7666 | XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7667 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7668 | #endif |
wolfSSL | 15:117db924cf7c | 7669 | return err; |
wolfSSL | 15:117db924cf7c | 7670 | } |
wolfSSL | 15:117db924cf7c | 7671 | |
wolfSSL | 15:117db924cf7c | 7672 | err = mp_read_unsigned_bin(rtmp, r, rSz); |
wolfSSL | 15:117db924cf7c | 7673 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7674 | err = mp_read_unsigned_bin(stmp, s, sSz); |
wolfSSL | 15:117db924cf7c | 7675 | |
wolfSSL | 15:117db924cf7c | 7676 | /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ |
wolfSSL | 15:117db924cf7c | 7677 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7678 | err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp); |
wolfSSL | 15:117db924cf7c | 7679 | |
wolfSSL | 15:117db924cf7c | 7680 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7681 | if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES) |
wolfSSL | 15:117db924cf7c | 7682 | err = MP_ZERO_E; |
wolfSSL | 15:117db924cf7c | 7683 | } |
wolfSSL | 15:117db924cf7c | 7684 | |
wolfSSL | 15:117db924cf7c | 7685 | mp_clear(rtmp); |
wolfSSL | 15:117db924cf7c | 7686 | mp_clear(stmp); |
wolfSSL | 15:117db924cf7c | 7687 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7688 | XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7689 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7690 | #endif |
wolfSSL | 15:117db924cf7c | 7691 | |
wolfSSL | 15:117db924cf7c | 7692 | return err; |
wolfSSL | 15:117db924cf7c | 7693 | } |
wolfSSL | 15:117db924cf7c | 7694 | |
wolfSSL | 15:117db924cf7c | 7695 | /** |
wolfSSL | 15:117db924cf7c | 7696 | Convert ECC signature to R,S |
wolfSSL | 15:117db924cf7c | 7697 | sig DER-encoded ECDSA signature |
wolfSSL | 15:117db924cf7c | 7698 | sigLen length of signature in octets |
wolfSSL | 15:117db924cf7c | 7699 | r R component of signature |
wolfSSL | 15:117db924cf7c | 7700 | rLen [in/out] output "r" buffer size, output "r" size |
wolfSSL | 15:117db924cf7c | 7701 | s S component of signature |
wolfSSL | 15:117db924cf7c | 7702 | sLen [in/out] output "s" buffer size, output "s" size |
wolfSSL | 15:117db924cf7c | 7703 | return MP_OKAY on success, negative on error |
wolfSSL | 15:117db924cf7c | 7704 | */ |
wolfSSL | 15:117db924cf7c | 7705 | int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, |
wolfSSL | 15:117db924cf7c | 7706 | byte* s, word32* sLen) |
wolfSSL | 15:117db924cf7c | 7707 | { |
wolfSSL | 15:117db924cf7c | 7708 | int err; |
wolfSSL | 16:8e0d178b1d1e | 7709 | int tmp_valid = 0; |
wolfSSL | 15:117db924cf7c | 7710 | word32 x = 0; |
wolfSSL | 15:117db924cf7c | 7711 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7712 | mp_int* rtmp = NULL; |
wolfSSL | 15:117db924cf7c | 7713 | mp_int* stmp = NULL; |
wolfSSL | 15:117db924cf7c | 7714 | #else |
wolfSSL | 15:117db924cf7c | 7715 | mp_int rtmp[1]; |
wolfSSL | 15:117db924cf7c | 7716 | mp_int stmp[1]; |
wolfSSL | 15:117db924cf7c | 7717 | #endif |
wolfSSL | 15:117db924cf7c | 7718 | |
wolfSSL | 15:117db924cf7c | 7719 | if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL) |
wolfSSL | 15:117db924cf7c | 7720 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 7721 | |
wolfSSL | 15:117db924cf7c | 7722 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7723 | rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7724 | if (rtmp == NULL) |
wolfSSL | 15:117db924cf7c | 7725 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7726 | stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7727 | if (stmp == NULL) { |
wolfSSL | 15:117db924cf7c | 7728 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7729 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7730 | } |
wolfSSL | 15:117db924cf7c | 7731 | #endif |
wolfSSL | 15:117db924cf7c | 7732 | |
wolfSSL | 15:117db924cf7c | 7733 | err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp); |
wolfSSL | 15:117db924cf7c | 7734 | |
wolfSSL | 16:8e0d178b1d1e | 7735 | /* rtmp and stmp are initialized */ |
wolfSSL | 15:117db924cf7c | 7736 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7737 | tmp_valid = 1; |
wolfSSL | 16:8e0d178b1d1e | 7738 | |
wolfSSL | 16:8e0d178b1d1e | 7739 | /* extract r */ |
wolfSSL | 15:117db924cf7c | 7740 | x = mp_unsigned_bin_size(rtmp); |
wolfSSL | 15:117db924cf7c | 7741 | if (*rLen < x) |
wolfSSL | 15:117db924cf7c | 7742 | err = BUFFER_E; |
wolfSSL | 16:8e0d178b1d1e | 7743 | } |
wolfSSL | 16:8e0d178b1d1e | 7744 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7745 | *rLen = x; |
wolfSSL | 16:8e0d178b1d1e | 7746 | err = mp_to_unsigned_bin(rtmp, r); |
wolfSSL | 15:117db924cf7c | 7747 | } |
wolfSSL | 15:117db924cf7c | 7748 | |
wolfSSL | 15:117db924cf7c | 7749 | /* extract s */ |
wolfSSL | 15:117db924cf7c | 7750 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7751 | x = mp_unsigned_bin_size(stmp); |
wolfSSL | 15:117db924cf7c | 7752 | if (*sLen < x) |
wolfSSL | 15:117db924cf7c | 7753 | err = BUFFER_E; |
wolfSSL | 15:117db924cf7c | 7754 | |
wolfSSL | 15:117db924cf7c | 7755 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7756 | *sLen = x; |
wolfSSL | 15:117db924cf7c | 7757 | err = mp_to_unsigned_bin(stmp, s); |
wolfSSL | 15:117db924cf7c | 7758 | } |
wolfSSL | 15:117db924cf7c | 7759 | } |
wolfSSL | 15:117db924cf7c | 7760 | |
wolfSSL | 16:8e0d178b1d1e | 7761 | if (tmp_valid) { |
wolfSSL | 16:8e0d178b1d1e | 7762 | mp_clear(rtmp); |
wolfSSL | 16:8e0d178b1d1e | 7763 | mp_clear(stmp); |
wolfSSL | 16:8e0d178b1d1e | 7764 | } |
wolfSSL | 15:117db924cf7c | 7765 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 7766 | XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7767 | XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 7768 | #endif |
wolfSSL | 15:117db924cf7c | 7769 | |
wolfSSL | 15:117db924cf7c | 7770 | return err; |
wolfSSL | 15:117db924cf7c | 7771 | } |
wolfSSL | 15:117db924cf7c | 7772 | #endif /* !NO_ASN */ |
wolfSSL | 15:117db924cf7c | 7773 | |
wolfSSL | 15:117db924cf7c | 7774 | #ifdef HAVE_ECC_KEY_IMPORT |
wolfSSL | 15:117db924cf7c | 7775 | static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, |
wolfSSL | 15:117db924cf7c | 7776 | const char* qy, const char* d, int curve_id, int encType) |
wolfSSL | 15:117db924cf7c | 7777 | { |
wolfSSL | 15:117db924cf7c | 7778 | int err = MP_OKAY; |
wolfSSL | 16:8e0d178b1d1e | 7779 | #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) |
wolfSSL | 16:8e0d178b1d1e | 7780 | const CRYS_ECPKI_Domain_t* pDomain; |
wolfSSL | 16:8e0d178b1d1e | 7781 | CRYS_ECPKI_BUILD_TempData_t tempBuff; |
wolfSSL | 16:8e0d178b1d1e | 7782 | byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; |
wolfSSL | 16:8e0d178b1d1e | 7783 | word32 keySz = 0; |
wolfSSL | 16:8e0d178b1d1e | 7784 | #endif |
wolfSSL | 15:117db924cf7c | 7785 | /* if d is NULL, only import as public key using Qx,Qy */ |
wolfSSL | 15:117db924cf7c | 7786 | if (key == NULL || qx == NULL || qy == NULL) { |
wolfSSL | 15:117db924cf7c | 7787 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7788 | } |
wolfSSL | 15:117db924cf7c | 7789 | |
wolfSSL | 15:117db924cf7c | 7790 | /* make sure required variables are reset */ |
wolfSSL | 15:117db924cf7c | 7791 | wc_ecc_reset(key); |
wolfSSL | 15:117db924cf7c | 7792 | |
wolfSSL | 15:117db924cf7c | 7793 | /* set curve type and index */ |
wolfSSL | 15:117db924cf7c | 7794 | err = wc_ecc_set_curve(key, 0, curve_id); |
wolfSSL | 15:117db924cf7c | 7795 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 7796 | return err; |
wolfSSL | 15:117db924cf7c | 7797 | } |
wolfSSL | 15:117db924cf7c | 7798 | |
wolfSSL | 15:117db924cf7c | 7799 | /* init key */ |
wolfSSL | 15:117db924cf7c | 7800 | #ifdef ALT_ECC_SIZE |
wolfSSL | 15:117db924cf7c | 7801 | key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; |
wolfSSL | 15:117db924cf7c | 7802 | key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; |
wolfSSL | 15:117db924cf7c | 7803 | key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; |
wolfSSL | 15:117db924cf7c | 7804 | alt_fp_init(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 7805 | alt_fp_init(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 7806 | alt_fp_init(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 7807 | err = mp_init(&key->k); |
wolfSSL | 15:117db924cf7c | 7808 | #else |
wolfSSL | 15:117db924cf7c | 7809 | err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, |
wolfSSL | 15:117db924cf7c | 7810 | NULL, NULL); |
wolfSSL | 15:117db924cf7c | 7811 | #endif |
wolfSSL | 15:117db924cf7c | 7812 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7813 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 7814 | |
wolfSSL | 15:117db924cf7c | 7815 | /* read Qx */ |
wolfSSL | 15:117db924cf7c | 7816 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7817 | if (encType == WC_TYPE_HEX_STR) |
wolfSSL | 15:117db924cf7c | 7818 | err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7819 | else |
wolfSSL | 15:117db924cf7c | 7820 | err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx, |
wolfSSL | 15:117db924cf7c | 7821 | key->dp->size); |
wolfSSL | 15:117db924cf7c | 7822 | } |
wolfSSL | 15:117db924cf7c | 7823 | |
wolfSSL | 15:117db924cf7c | 7824 | /* read Qy */ |
wolfSSL | 15:117db924cf7c | 7825 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7826 | if (encType == WC_TYPE_HEX_STR) |
wolfSSL | 15:117db924cf7c | 7827 | err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7828 | else |
wolfSSL | 15:117db924cf7c | 7829 | err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy, |
wolfSSL | 15:117db924cf7c | 7830 | key->dp->size); |
wolfSSL | 15:117db924cf7c | 7831 | |
wolfSSL | 15:117db924cf7c | 7832 | } |
wolfSSL | 15:117db924cf7c | 7833 | |
wolfSSL | 15:117db924cf7c | 7834 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7835 | err = mp_set(key->pubkey.z, 1); |
wolfSSL | 15:117db924cf7c | 7836 | |
wolfSSL | 16:8e0d178b1d1e | 7837 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 7838 | /* For SECP256R1 only save raw public key for hardware */ |
wolfSSL | 16:8e0d178b1d1e | 7839 | if (err == MP_OKAY && curve_id == ECC_SECP256R1) { |
wolfSSL | 16:8e0d178b1d1e | 7840 | word32 keySz = key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 7841 | err = wc_export_int(key->pubkey.x, key->pubkey_raw, |
wolfSSL | 16:8e0d178b1d1e | 7842 | &keySz, keySz, WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7843 | if (err == MP_OKAY) |
wolfSSL | 16:8e0d178b1d1e | 7844 | err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz], |
wolfSSL | 16:8e0d178b1d1e | 7845 | &keySz, keySz, WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7846 | } |
wolfSSL | 16:8e0d178b1d1e | 7847 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 7848 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7849 | key_raw[0] = ECC_POINT_UNCOMP; |
wolfSSL | 16:8e0d178b1d1e | 7850 | keySz = (word32)key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 7851 | err = wc_export_int(key->pubkey.x, &key_raw[1], &keySz, keySz, |
wolfSSL | 16:8e0d178b1d1e | 7852 | WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7853 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7854 | err = wc_export_int(key->pubkey.y, &key_raw[1+keySz], |
wolfSSL | 16:8e0d178b1d1e | 7855 | &keySz, keySz, WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7856 | } |
wolfSSL | 16:8e0d178b1d1e | 7857 | |
wolfSSL | 16:8e0d178b1d1e | 7858 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7859 | pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(curve_id)); |
wolfSSL | 16:8e0d178b1d1e | 7860 | |
wolfSSL | 16:8e0d178b1d1e | 7861 | /* create public key from external key buffer */ |
wolfSSL | 16:8e0d178b1d1e | 7862 | err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain, |
wolfSSL | 16:8e0d178b1d1e | 7863 | key_raw, |
wolfSSL | 16:8e0d178b1d1e | 7864 | keySz*2 + 1, |
wolfSSL | 16:8e0d178b1d1e | 7865 | &key->ctx.pubKey, |
wolfSSL | 16:8e0d178b1d1e | 7866 | &tempBuff); |
wolfSSL | 16:8e0d178b1d1e | 7867 | } |
wolfSSL | 16:8e0d178b1d1e | 7868 | |
wolfSSL | 16:8e0d178b1d1e | 7869 | if (err != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 7870 | WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed"); |
wolfSSL | 16:8e0d178b1d1e | 7871 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7872 | } |
wolfSSL | 16:8e0d178b1d1e | 7873 | } |
wolfSSL | 16:8e0d178b1d1e | 7874 | |
wolfSSL | 16:8e0d178b1d1e | 7875 | #endif |
wolfSSL | 16:8e0d178b1d1e | 7876 | |
wolfSSL | 15:117db924cf7c | 7877 | /* import private key */ |
wolfSSL | 15:117db924cf7c | 7878 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7879 | if (d != NULL && d[0] != '\0') { |
wolfSSL | 16:8e0d178b1d1e | 7880 | #ifdef WOLFSSL_ATECC508A |
wolfSSL | 16:8e0d178b1d1e | 7881 | /* Hardware doesn't support loading private key */ |
wolfSSL | 16:8e0d178b1d1e | 7882 | err = NOT_COMPILED_IN; |
wolfSSL | 16:8e0d178b1d1e | 7883 | |
wolfSSL | 16:8e0d178b1d1e | 7884 | #elif defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 16:8e0d178b1d1e | 7885 | |
wolfSSL | 15:117db924cf7c | 7886 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 15:117db924cf7c | 7887 | |
wolfSSL | 16:8e0d178b1d1e | 7888 | if (encType == WC_TYPE_HEX_STR) |
wolfSSL | 15:117db924cf7c | 7889 | err = mp_read_radix(&key->k, d, MP_RADIX_HEX); |
wolfSSL | 15:117db924cf7c | 7890 | else |
wolfSSL | 15:117db924cf7c | 7891 | err = mp_read_unsigned_bin(&key->k, (const byte*)d, |
wolfSSL | 15:117db924cf7c | 7892 | key->dp->size); |
wolfSSL | 16:8e0d178b1d1e | 7893 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7894 | err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz, |
wolfSSL | 16:8e0d178b1d1e | 7895 | WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 16:8e0d178b1d1e | 7896 | } |
wolfSSL | 16:8e0d178b1d1e | 7897 | |
wolfSSL | 16:8e0d178b1d1e | 7898 | if (err == MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 7899 | /* Create private key from external key buffer*/ |
wolfSSL | 16:8e0d178b1d1e | 7900 | err = CRYS_ECPKI_BuildPrivKey(pDomain, |
wolfSSL | 16:8e0d178b1d1e | 7901 | key_raw, |
wolfSSL | 16:8e0d178b1d1e | 7902 | keySz, |
wolfSSL | 16:8e0d178b1d1e | 7903 | &key->ctx.privKey); |
wolfSSL | 16:8e0d178b1d1e | 7904 | |
wolfSSL | 16:8e0d178b1d1e | 7905 | if (err != SA_SILIB_RET_OK){ |
wolfSSL | 16:8e0d178b1d1e | 7906 | WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed"); |
wolfSSL | 16:8e0d178b1d1e | 7907 | return err; |
wolfSSL | 16:8e0d178b1d1e | 7908 | } |
wolfSSL | 16:8e0d178b1d1e | 7909 | } |
wolfSSL | 16:8e0d178b1d1e | 7910 | |
wolfSSL | 16:8e0d178b1d1e | 7911 | #else |
wolfSSL | 16:8e0d178b1d1e | 7912 | key->type = ECC_PRIVATEKEY; |
wolfSSL | 16:8e0d178b1d1e | 7913 | |
wolfSSL | 16:8e0d178b1d1e | 7914 | if (encType == WC_TYPE_HEX_STR) |
wolfSSL | 16:8e0d178b1d1e | 7915 | err = mp_read_radix(&key->k, d, MP_RADIX_HEX); |
wolfSSL | 16:8e0d178b1d1e | 7916 | else |
wolfSSL | 16:8e0d178b1d1e | 7917 | err = mp_read_unsigned_bin(&key->k, (const byte*)d, |
wolfSSL | 16:8e0d178b1d1e | 7918 | key->dp->size); |
wolfSSL | 16:8e0d178b1d1e | 7919 | #endif /* WOLFSSL_ATECC508A */ |
wolfSSL | 15:117db924cf7c | 7920 | } else { |
wolfSSL | 15:117db924cf7c | 7921 | key->type = ECC_PUBLICKEY; |
wolfSSL | 15:117db924cf7c | 7922 | } |
wolfSSL | 15:117db924cf7c | 7923 | } |
wolfSSL | 15:117db924cf7c | 7924 | |
wolfSSL | 15:117db924cf7c | 7925 | #ifdef WOLFSSL_VALIDATE_ECC_IMPORT |
wolfSSL | 15:117db924cf7c | 7926 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 7927 | err = wc_ecc_check_key(key); |
wolfSSL | 15:117db924cf7c | 7928 | #endif |
wolfSSL | 15:117db924cf7c | 7929 | |
wolfSSL | 15:117db924cf7c | 7930 | if (err != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 7931 | mp_clear(key->pubkey.x); |
wolfSSL | 15:117db924cf7c | 7932 | mp_clear(key->pubkey.y); |
wolfSSL | 15:117db924cf7c | 7933 | mp_clear(key->pubkey.z); |
wolfSSL | 15:117db924cf7c | 7934 | mp_clear(&key->k); |
wolfSSL | 15:117db924cf7c | 7935 | } |
wolfSSL | 15:117db924cf7c | 7936 | |
wolfSSL | 15:117db924cf7c | 7937 | return err; |
wolfSSL | 15:117db924cf7c | 7938 | } |
wolfSSL | 15:117db924cf7c | 7939 | |
wolfSSL | 15:117db924cf7c | 7940 | /** |
wolfSSL | 15:117db924cf7c | 7941 | Import raw ECC key |
wolfSSL | 15:117db924cf7c | 7942 | key The destination ecc_key structure |
wolfSSL | 15:117db924cf7c | 7943 | qx x component of the public key, as ASCII hex string |
wolfSSL | 15:117db924cf7c | 7944 | qy y component of the public key, as ASCII hex string |
wolfSSL | 15:117db924cf7c | 7945 | d private key, as ASCII hex string, optional if importing public |
wolfSSL | 15:117db924cf7c | 7946 | key only |
wolfSSL | 15:117db924cf7c | 7947 | dp Custom ecc_set_type |
wolfSSL | 15:117db924cf7c | 7948 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 7949 | */ |
wolfSSL | 15:117db924cf7c | 7950 | int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, |
wolfSSL | 15:117db924cf7c | 7951 | const char* d, int curve_id) |
wolfSSL | 15:117db924cf7c | 7952 | { |
wolfSSL | 15:117db924cf7c | 7953 | return wc_ecc_import_raw_private(key, qx, qy, d, curve_id, |
wolfSSL | 16:8e0d178b1d1e | 7954 | WC_TYPE_HEX_STR); |
wolfSSL | 15:117db924cf7c | 7955 | |
wolfSSL | 15:117db924cf7c | 7956 | } |
wolfSSL | 15:117db924cf7c | 7957 | |
wolfSSL | 15:117db924cf7c | 7958 | /* Import x, y and optional private (d) as unsigned binary */ |
wolfSSL | 15:117db924cf7c | 7959 | int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy, |
wolfSSL | 15:117db924cf7c | 7960 | byte* d, int curve_id) |
wolfSSL | 15:117db924cf7c | 7961 | { |
wolfSSL | 15:117db924cf7c | 7962 | return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy, |
wolfSSL | 16:8e0d178b1d1e | 7963 | (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN); |
wolfSSL | 15:117db924cf7c | 7964 | } |
wolfSSL | 15:117db924cf7c | 7965 | |
wolfSSL | 15:117db924cf7c | 7966 | /** |
wolfSSL | 15:117db924cf7c | 7967 | Import raw ECC key |
wolfSSL | 15:117db924cf7c | 7968 | key The destination ecc_key structure |
wolfSSL | 15:117db924cf7c | 7969 | qx x component of the public key, as ASCII hex string |
wolfSSL | 15:117db924cf7c | 7970 | qy y component of the public key, as ASCII hex string |
wolfSSL | 15:117db924cf7c | 7971 | d private key, as ASCII hex string, optional if importing public |
wolfSSL | 15:117db924cf7c | 7972 | key only |
wolfSSL | 15:117db924cf7c | 7973 | curveName ECC curve name, from ecc_sets[] |
wolfSSL | 15:117db924cf7c | 7974 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 7975 | */ |
wolfSSL | 15:117db924cf7c | 7976 | int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, |
wolfSSL | 15:117db924cf7c | 7977 | const char* d, const char* curveName) |
wolfSSL | 15:117db924cf7c | 7978 | { |
wolfSSL | 15:117db924cf7c | 7979 | int err, x; |
wolfSSL | 15:117db924cf7c | 7980 | |
wolfSSL | 15:117db924cf7c | 7981 | /* if d is NULL, only import as public key using Qx,Qy */ |
wolfSSL | 15:117db924cf7c | 7982 | if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) { |
wolfSSL | 15:117db924cf7c | 7983 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 7984 | } |
wolfSSL | 15:117db924cf7c | 7985 | |
wolfSSL | 15:117db924cf7c | 7986 | /* set curve type and index */ |
wolfSSL | 15:117db924cf7c | 7987 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 15:117db924cf7c | 7988 | if (XSTRNCMP(ecc_sets[x].name, curveName, |
wolfSSL | 15:117db924cf7c | 7989 | XSTRLEN(curveName)) == 0) { |
wolfSSL | 15:117db924cf7c | 7990 | break; |
wolfSSL | 15:117db924cf7c | 7991 | } |
wolfSSL | 15:117db924cf7c | 7992 | } |
wolfSSL | 15:117db924cf7c | 7993 | |
wolfSSL | 15:117db924cf7c | 7994 | if (ecc_sets[x].size == 0) { |
wolfSSL | 15:117db924cf7c | 7995 | WOLFSSL_MSG("ecc_set curve name not found"); |
wolfSSL | 15:117db924cf7c | 7996 | err = ASN_PARSE_E; |
wolfSSL | 15:117db924cf7c | 7997 | } else { |
wolfSSL | 15:117db924cf7c | 7998 | return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id, |
wolfSSL | 16:8e0d178b1d1e | 7999 | WC_TYPE_HEX_STR); |
wolfSSL | 15:117db924cf7c | 8000 | } |
wolfSSL | 15:117db924cf7c | 8001 | |
wolfSSL | 15:117db924cf7c | 8002 | return err; |
wolfSSL | 15:117db924cf7c | 8003 | } |
wolfSSL | 15:117db924cf7c | 8004 | #endif /* HAVE_ECC_KEY_IMPORT */ |
wolfSSL | 15:117db924cf7c | 8005 | |
wolfSSL | 15:117db924cf7c | 8006 | /* key size in octets */ |
wolfSSL | 15:117db924cf7c | 8007 | int wc_ecc_size(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 8008 | { |
wolfSSL | 16:8e0d178b1d1e | 8009 | if (key == NULL) |
wolfSSL | 16:8e0d178b1d1e | 8010 | return 0; |
wolfSSL | 15:117db924cf7c | 8011 | |
wolfSSL | 15:117db924cf7c | 8012 | return key->dp->size; |
wolfSSL | 15:117db924cf7c | 8013 | } |
wolfSSL | 15:117db924cf7c | 8014 | |
wolfSSL | 16:8e0d178b1d1e | 8015 | /* maximum signature size based on key size */ |
wolfSSL | 15:117db924cf7c | 8016 | int wc_ecc_sig_size_calc(int sz) |
wolfSSL | 15:117db924cf7c | 8017 | { |
wolfSSL | 16:8e0d178b1d1e | 8018 | int maxSigSz = 0; |
wolfSSL | 16:8e0d178b1d1e | 8019 | |
wolfSSL | 16:8e0d178b1d1e | 8020 | /* calculate based on key bits */ |
wolfSSL | 16:8e0d178b1d1e | 8021 | /* maximum possible signature header size is 7 bytes plus 2 bytes padding */ |
wolfSSL | 16:8e0d178b1d1e | 8022 | maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ; |
wolfSSL | 16:8e0d178b1d1e | 8023 | |
wolfSSL | 16:8e0d178b1d1e | 8024 | /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */ |
wolfSSL | 16:8e0d178b1d1e | 8025 | if (maxSigSz < (128 + 2)) { |
wolfSSL | 16:8e0d178b1d1e | 8026 | maxSigSz -= 1; |
wolfSSL | 16:8e0d178b1d1e | 8027 | } |
wolfSSL | 16:8e0d178b1d1e | 8028 | |
wolfSSL | 16:8e0d178b1d1e | 8029 | return maxSigSz; |
wolfSSL | 16:8e0d178b1d1e | 8030 | } |
wolfSSL | 16:8e0d178b1d1e | 8031 | |
wolfSSL | 16:8e0d178b1d1e | 8032 | /* maximum signature size based on actual key curve */ |
wolfSSL | 15:117db924cf7c | 8033 | int wc_ecc_sig_size(ecc_key* key) |
wolfSSL | 15:117db924cf7c | 8034 | { |
wolfSSL | 16:8e0d178b1d1e | 8035 | int maxSigSz; |
wolfSSL | 16:8e0d178b1d1e | 8036 | int orderBits, keySz; |
wolfSSL | 16:8e0d178b1d1e | 8037 | |
wolfSSL | 16:8e0d178b1d1e | 8038 | if (key == NULL || key->dp == NULL) |
wolfSSL | 16:8e0d178b1d1e | 8039 | return 0; |
wolfSSL | 16:8e0d178b1d1e | 8040 | |
wolfSSL | 16:8e0d178b1d1e | 8041 | /* the signature r and s will always be less than order */ |
wolfSSL | 16:8e0d178b1d1e | 8042 | /* if the order MSB (top bit of byte) is set then ASN encoding needs |
wolfSSL | 16:8e0d178b1d1e | 8043 | extra byte for r and s, so add 2 */ |
wolfSSL | 16:8e0d178b1d1e | 8044 | keySz = key->dp->size; |
wolfSSL | 16:8e0d178b1d1e | 8045 | orderBits = wc_ecc_get_curve_order_bit_count(key->dp); |
wolfSSL | 16:8e0d178b1d1e | 8046 | if (orderBits > keySz * 8) { |
wolfSSL | 16:8e0d178b1d1e | 8047 | keySz = (orderBits + 7) / 8; |
wolfSSL | 16:8e0d178b1d1e | 8048 | } |
wolfSSL | 16:8e0d178b1d1e | 8049 | /* maximum possible signature header size is 7 bytes */ |
wolfSSL | 16:8e0d178b1d1e | 8050 | maxSigSz = (keySz * 2) + SIG_HEADER_SZ; |
wolfSSL | 16:8e0d178b1d1e | 8051 | if ((orderBits % 8) == 0) { |
wolfSSL | 16:8e0d178b1d1e | 8052 | /* MSB can be set, so add 2 */ |
wolfSSL | 16:8e0d178b1d1e | 8053 | maxSigSz += ECC_MAX_PAD_SZ; |
wolfSSL | 16:8e0d178b1d1e | 8054 | } |
wolfSSL | 16:8e0d178b1d1e | 8055 | /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */ |
wolfSSL | 16:8e0d178b1d1e | 8056 | if (maxSigSz < (128 + 2)) { |
wolfSSL | 16:8e0d178b1d1e | 8057 | maxSigSz -= 1; |
wolfSSL | 16:8e0d178b1d1e | 8058 | } |
wolfSSL | 16:8e0d178b1d1e | 8059 | |
wolfSSL | 16:8e0d178b1d1e | 8060 | return maxSigSz; |
wolfSSL | 15:117db924cf7c | 8061 | } |
wolfSSL | 15:117db924cf7c | 8062 | |
wolfSSL | 15:117db924cf7c | 8063 | |
wolfSSL | 15:117db924cf7c | 8064 | #ifdef FP_ECC |
wolfSSL | 15:117db924cf7c | 8065 | |
wolfSSL | 15:117db924cf7c | 8066 | /* fixed point ECC cache */ |
wolfSSL | 15:117db924cf7c | 8067 | /* number of entries in the cache */ |
wolfSSL | 15:117db924cf7c | 8068 | #ifndef FP_ENTRIES |
wolfSSL | 15:117db924cf7c | 8069 | #define FP_ENTRIES 15 |
wolfSSL | 15:117db924cf7c | 8070 | #endif |
wolfSSL | 15:117db924cf7c | 8071 | |
wolfSSL | 15:117db924cf7c | 8072 | /* number of bits in LUT */ |
wolfSSL | 15:117db924cf7c | 8073 | #ifndef FP_LUT |
wolfSSL | 15:117db924cf7c | 8074 | #define FP_LUT 8U |
wolfSSL | 15:117db924cf7c | 8075 | #endif |
wolfSSL | 15:117db924cf7c | 8076 | |
wolfSSL | 15:117db924cf7c | 8077 | #ifdef ECC_SHAMIR |
wolfSSL | 15:117db924cf7c | 8078 | /* Sharmir requires a bigger LUT, TAO */ |
wolfSSL | 15:117db924cf7c | 8079 | #if (FP_LUT > 12) || (FP_LUT < 4) |
wolfSSL | 15:117db924cf7c | 8080 | #error FP_LUT must be between 4 and 12 inclusively |
wolfSSL | 15:117db924cf7c | 8081 | #endif |
wolfSSL | 15:117db924cf7c | 8082 | #else |
wolfSSL | 15:117db924cf7c | 8083 | #if (FP_LUT > 12) || (FP_LUT < 2) |
wolfSSL | 15:117db924cf7c | 8084 | #error FP_LUT must be between 2 and 12 inclusively |
wolfSSL | 15:117db924cf7c | 8085 | #endif |
wolfSSL | 15:117db924cf7c | 8086 | #endif |
wolfSSL | 15:117db924cf7c | 8087 | |
wolfSSL | 15:117db924cf7c | 8088 | |
wolfSSL | 15:117db924cf7c | 8089 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 8090 | |
wolfSSL | 15:117db924cf7c | 8091 | /** Our FP cache */ |
wolfSSL | 15:117db924cf7c | 8092 | typedef struct { |
wolfSSL | 15:117db924cf7c | 8093 | ecc_point* g; /* cached COPY of base point */ |
wolfSSL | 15:117db924cf7c | 8094 | ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */ |
wolfSSL | 15:117db924cf7c | 8095 | mp_int mu; /* copy of the montgomery constant */ |
wolfSSL | 15:117db924cf7c | 8096 | int lru_count; /* amount of times this entry has been used */ |
wolfSSL | 15:117db924cf7c | 8097 | int lock; /* flag to indicate cache eviction */ |
wolfSSL | 15:117db924cf7c | 8098 | /* permitted (0) or not (1) */ |
wolfSSL | 15:117db924cf7c | 8099 | } fp_cache_t; |
wolfSSL | 15:117db924cf7c | 8100 | |
wolfSSL | 15:117db924cf7c | 8101 | /* if HAVE_THREAD_LS this cache is per thread, no locking needed */ |
wolfSSL | 15:117db924cf7c | 8102 | static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES]; |
wolfSSL | 15:117db924cf7c | 8103 | |
wolfSSL | 15:117db924cf7c | 8104 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 8105 | static volatile int initMutex = 0; /* prevent multiple mutex inits */ |
wolfSSL | 15:117db924cf7c | 8106 | static wolfSSL_Mutex ecc_fp_lock; |
wolfSSL | 15:117db924cf7c | 8107 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 8108 | |
wolfSSL | 15:117db924cf7c | 8109 | /* simple table to help direct the generation of the LUT */ |
wolfSSL | 15:117db924cf7c | 8110 | static const struct { |
wolfSSL | 15:117db924cf7c | 8111 | int ham, terma, termb; |
wolfSSL | 15:117db924cf7c | 8112 | } lut_orders[] = { |
wolfSSL | 15:117db924cf7c | 8113 | { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 }, |
wolfSSL | 15:117db924cf7c | 8114 | { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 }, |
wolfSSL | 15:117db924cf7c | 8115 | { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 }, |
wolfSSL | 15:117db924cf7c | 8116 | { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 }, |
wolfSSL | 15:117db924cf7c | 8117 | { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 }, |
wolfSSL | 15:117db924cf7c | 8118 | { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 }, |
wolfSSL | 15:117db924cf7c | 8119 | { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 }, |
wolfSSL | 15:117db924cf7c | 8120 | { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 }, |
wolfSSL | 15:117db924cf7c | 8121 | #if FP_LUT > 6 |
wolfSSL | 15:117db924cf7c | 8122 | { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, |
wolfSSL | 15:117db924cf7c | 8123 | { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, |
wolfSSL | 15:117db924cf7c | 8124 | { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, |
wolfSSL | 15:117db924cf7c | 8125 | { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, |
wolfSSL | 15:117db924cf7c | 8126 | { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, |
wolfSSL | 15:117db924cf7c | 8127 | { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, |
wolfSSL | 15:117db924cf7c | 8128 | { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, |
wolfSSL | 15:117db924cf7c | 8129 | { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, |
wolfSSL | 15:117db924cf7c | 8130 | #if FP_LUT > 7 |
wolfSSL | 15:117db924cf7c | 8131 | { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, |
wolfSSL | 15:117db924cf7c | 8132 | { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, |
wolfSSL | 15:117db924cf7c | 8133 | { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, |
wolfSSL | 15:117db924cf7c | 8134 | { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, |
wolfSSL | 15:117db924cf7c | 8135 | { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, |
wolfSSL | 15:117db924cf7c | 8136 | { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, |
wolfSSL | 15:117db924cf7c | 8137 | { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, |
wolfSSL | 15:117db924cf7c | 8138 | { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, |
wolfSSL | 15:117db924cf7c | 8139 | { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, |
wolfSSL | 15:117db924cf7c | 8140 | { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, |
wolfSSL | 15:117db924cf7c | 8141 | { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, |
wolfSSL | 15:117db924cf7c | 8142 | { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, |
wolfSSL | 15:117db924cf7c | 8143 | { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, |
wolfSSL | 15:117db924cf7c | 8144 | { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, |
wolfSSL | 15:117db924cf7c | 8145 | { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, |
wolfSSL | 15:117db924cf7c | 8146 | { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, |
wolfSSL | 15:117db924cf7c | 8147 | #if FP_LUT > 8 |
wolfSSL | 15:117db924cf7c | 8148 | { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, |
wolfSSL | 15:117db924cf7c | 8149 | { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, |
wolfSSL | 15:117db924cf7c | 8150 | { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, |
wolfSSL | 15:117db924cf7c | 8151 | { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, |
wolfSSL | 15:117db924cf7c | 8152 | { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, |
wolfSSL | 15:117db924cf7c | 8153 | { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, |
wolfSSL | 15:117db924cf7c | 8154 | { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, |
wolfSSL | 15:117db924cf7c | 8155 | { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, |
wolfSSL | 15:117db924cf7c | 8156 | { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, |
wolfSSL | 15:117db924cf7c | 8157 | { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, |
wolfSSL | 15:117db924cf7c | 8158 | { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, |
wolfSSL | 15:117db924cf7c | 8159 | { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, |
wolfSSL | 15:117db924cf7c | 8160 | { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, |
wolfSSL | 15:117db924cf7c | 8161 | { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, |
wolfSSL | 15:117db924cf7c | 8162 | { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, |
wolfSSL | 15:117db924cf7c | 8163 | { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, |
wolfSSL | 15:117db924cf7c | 8164 | { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, |
wolfSSL | 15:117db924cf7c | 8165 | { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, |
wolfSSL | 15:117db924cf7c | 8166 | { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, |
wolfSSL | 15:117db924cf7c | 8167 | { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, |
wolfSSL | 15:117db924cf7c | 8168 | { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, |
wolfSSL | 15:117db924cf7c | 8169 | { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, |
wolfSSL | 15:117db924cf7c | 8170 | { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, |
wolfSSL | 15:117db924cf7c | 8171 | { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, |
wolfSSL | 15:117db924cf7c | 8172 | { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, |
wolfSSL | 15:117db924cf7c | 8173 | { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, |
wolfSSL | 15:117db924cf7c | 8174 | { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, |
wolfSSL | 15:117db924cf7c | 8175 | { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, |
wolfSSL | 15:117db924cf7c | 8176 | { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, |
wolfSSL | 15:117db924cf7c | 8177 | { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, |
wolfSSL | 15:117db924cf7c | 8178 | { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, |
wolfSSL | 15:117db924cf7c | 8179 | { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, |
wolfSSL | 15:117db924cf7c | 8180 | #if FP_LUT > 9 |
wolfSSL | 15:117db924cf7c | 8181 | { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, |
wolfSSL | 15:117db924cf7c | 8182 | { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, |
wolfSSL | 15:117db924cf7c | 8183 | { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, |
wolfSSL | 15:117db924cf7c | 8184 | { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, |
wolfSSL | 15:117db924cf7c | 8185 | { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, |
wolfSSL | 15:117db924cf7c | 8186 | { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, |
wolfSSL | 15:117db924cf7c | 8187 | { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, |
wolfSSL | 15:117db924cf7c | 8188 | { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, |
wolfSSL | 15:117db924cf7c | 8189 | { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, |
wolfSSL | 15:117db924cf7c | 8190 | { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, |
wolfSSL | 15:117db924cf7c | 8191 | { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, |
wolfSSL | 15:117db924cf7c | 8192 | { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, |
wolfSSL | 15:117db924cf7c | 8193 | { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, |
wolfSSL | 15:117db924cf7c | 8194 | { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, |
wolfSSL | 15:117db924cf7c | 8195 | { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, |
wolfSSL | 15:117db924cf7c | 8196 | { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, |
wolfSSL | 15:117db924cf7c | 8197 | { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, |
wolfSSL | 15:117db924cf7c | 8198 | { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, |
wolfSSL | 15:117db924cf7c | 8199 | { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, |
wolfSSL | 15:117db924cf7c | 8200 | { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, |
wolfSSL | 15:117db924cf7c | 8201 | { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, |
wolfSSL | 15:117db924cf7c | 8202 | { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, |
wolfSSL | 15:117db924cf7c | 8203 | { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, |
wolfSSL | 15:117db924cf7c | 8204 | { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, |
wolfSSL | 15:117db924cf7c | 8205 | { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, |
wolfSSL | 15:117db924cf7c | 8206 | { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, |
wolfSSL | 15:117db924cf7c | 8207 | { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, |
wolfSSL | 15:117db924cf7c | 8208 | { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, |
wolfSSL | 15:117db924cf7c | 8209 | { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, |
wolfSSL | 15:117db924cf7c | 8210 | { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, |
wolfSSL | 15:117db924cf7c | 8211 | { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, |
wolfSSL | 15:117db924cf7c | 8212 | { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, |
wolfSSL | 15:117db924cf7c | 8213 | { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, |
wolfSSL | 15:117db924cf7c | 8214 | { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, |
wolfSSL | 15:117db924cf7c | 8215 | { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, |
wolfSSL | 15:117db924cf7c | 8216 | { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, |
wolfSSL | 15:117db924cf7c | 8217 | { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, |
wolfSSL | 15:117db924cf7c | 8218 | { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, |
wolfSSL | 15:117db924cf7c | 8219 | { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, |
wolfSSL | 15:117db924cf7c | 8220 | { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, |
wolfSSL | 15:117db924cf7c | 8221 | { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, |
wolfSSL | 15:117db924cf7c | 8222 | { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, |
wolfSSL | 15:117db924cf7c | 8223 | { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, |
wolfSSL | 15:117db924cf7c | 8224 | { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, |
wolfSSL | 15:117db924cf7c | 8225 | { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, |
wolfSSL | 15:117db924cf7c | 8226 | { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, |
wolfSSL | 15:117db924cf7c | 8227 | { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, |
wolfSSL | 15:117db924cf7c | 8228 | { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, |
wolfSSL | 15:117db924cf7c | 8229 | { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, |
wolfSSL | 15:117db924cf7c | 8230 | { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, |
wolfSSL | 15:117db924cf7c | 8231 | { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, |
wolfSSL | 15:117db924cf7c | 8232 | { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, |
wolfSSL | 15:117db924cf7c | 8233 | { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, |
wolfSSL | 15:117db924cf7c | 8234 | { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, |
wolfSSL | 15:117db924cf7c | 8235 | { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, |
wolfSSL | 15:117db924cf7c | 8236 | { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, |
wolfSSL | 15:117db924cf7c | 8237 | { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, |
wolfSSL | 15:117db924cf7c | 8238 | { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, |
wolfSSL | 15:117db924cf7c | 8239 | { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, |
wolfSSL | 15:117db924cf7c | 8240 | { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, |
wolfSSL | 15:117db924cf7c | 8241 | { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, |
wolfSSL | 15:117db924cf7c | 8242 | { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, |
wolfSSL | 15:117db924cf7c | 8243 | { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, |
wolfSSL | 15:117db924cf7c | 8244 | { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, |
wolfSSL | 15:117db924cf7c | 8245 | #if FP_LUT > 10 |
wolfSSL | 15:117db924cf7c | 8246 | { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, |
wolfSSL | 15:117db924cf7c | 8247 | { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, |
wolfSSL | 15:117db924cf7c | 8248 | { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, |
wolfSSL | 15:117db924cf7c | 8249 | { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, |
wolfSSL | 15:117db924cf7c | 8250 | { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, |
wolfSSL | 15:117db924cf7c | 8251 | { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, |
wolfSSL | 15:117db924cf7c | 8252 | { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, |
wolfSSL | 15:117db924cf7c | 8253 | { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, |
wolfSSL | 15:117db924cf7c | 8254 | { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, |
wolfSSL | 15:117db924cf7c | 8255 | { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, |
wolfSSL | 15:117db924cf7c | 8256 | { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, |
wolfSSL | 15:117db924cf7c | 8257 | { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, |
wolfSSL | 15:117db924cf7c | 8258 | { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, |
wolfSSL | 15:117db924cf7c | 8259 | { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, |
wolfSSL | 15:117db924cf7c | 8260 | { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, |
wolfSSL | 15:117db924cf7c | 8261 | { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, |
wolfSSL | 15:117db924cf7c | 8262 | { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, |
wolfSSL | 15:117db924cf7c | 8263 | { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, |
wolfSSL | 15:117db924cf7c | 8264 | { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, |
wolfSSL | 15:117db924cf7c | 8265 | { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, |
wolfSSL | 15:117db924cf7c | 8266 | { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, |
wolfSSL | 15:117db924cf7c | 8267 | { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, |
wolfSSL | 15:117db924cf7c | 8268 | { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, |
wolfSSL | 15:117db924cf7c | 8269 | { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, |
wolfSSL | 15:117db924cf7c | 8270 | { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, |
wolfSSL | 15:117db924cf7c | 8271 | { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, |
wolfSSL | 15:117db924cf7c | 8272 | { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, |
wolfSSL | 15:117db924cf7c | 8273 | { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, |
wolfSSL | 15:117db924cf7c | 8274 | { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, |
wolfSSL | 15:117db924cf7c | 8275 | { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, |
wolfSSL | 15:117db924cf7c | 8276 | { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, |
wolfSSL | 15:117db924cf7c | 8277 | { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, |
wolfSSL | 15:117db924cf7c | 8278 | { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, |
wolfSSL | 15:117db924cf7c | 8279 | { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, |
wolfSSL | 15:117db924cf7c | 8280 | { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, |
wolfSSL | 15:117db924cf7c | 8281 | { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, |
wolfSSL | 15:117db924cf7c | 8282 | { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, |
wolfSSL | 15:117db924cf7c | 8283 | { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, |
wolfSSL | 15:117db924cf7c | 8284 | { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, |
wolfSSL | 15:117db924cf7c | 8285 | { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, |
wolfSSL | 15:117db924cf7c | 8286 | { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, |
wolfSSL | 15:117db924cf7c | 8287 | { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, |
wolfSSL | 15:117db924cf7c | 8288 | { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, |
wolfSSL | 15:117db924cf7c | 8289 | { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, |
wolfSSL | 15:117db924cf7c | 8290 | { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, |
wolfSSL | 15:117db924cf7c | 8291 | { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, |
wolfSSL | 15:117db924cf7c | 8292 | { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, |
wolfSSL | 15:117db924cf7c | 8293 | { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, |
wolfSSL | 15:117db924cf7c | 8294 | { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, |
wolfSSL | 15:117db924cf7c | 8295 | { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, |
wolfSSL | 15:117db924cf7c | 8296 | { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, |
wolfSSL | 15:117db924cf7c | 8297 | { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, |
wolfSSL | 15:117db924cf7c | 8298 | { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, |
wolfSSL | 15:117db924cf7c | 8299 | { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, |
wolfSSL | 15:117db924cf7c | 8300 | { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, |
wolfSSL | 15:117db924cf7c | 8301 | { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, |
wolfSSL | 15:117db924cf7c | 8302 | { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, |
wolfSSL | 15:117db924cf7c | 8303 | { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, |
wolfSSL | 15:117db924cf7c | 8304 | { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, |
wolfSSL | 15:117db924cf7c | 8305 | { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, |
wolfSSL | 15:117db924cf7c | 8306 | { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, |
wolfSSL | 15:117db924cf7c | 8307 | { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, |
wolfSSL | 15:117db924cf7c | 8308 | { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, |
wolfSSL | 15:117db924cf7c | 8309 | { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, |
wolfSSL | 15:117db924cf7c | 8310 | { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, |
wolfSSL | 15:117db924cf7c | 8311 | { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, |
wolfSSL | 15:117db924cf7c | 8312 | { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, |
wolfSSL | 15:117db924cf7c | 8313 | { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, |
wolfSSL | 15:117db924cf7c | 8314 | { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, |
wolfSSL | 15:117db924cf7c | 8315 | { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, |
wolfSSL | 15:117db924cf7c | 8316 | { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, |
wolfSSL | 15:117db924cf7c | 8317 | { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, |
wolfSSL | 15:117db924cf7c | 8318 | { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, |
wolfSSL | 15:117db924cf7c | 8319 | { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, |
wolfSSL | 15:117db924cf7c | 8320 | { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, |
wolfSSL | 15:117db924cf7c | 8321 | { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, |
wolfSSL | 15:117db924cf7c | 8322 | { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, |
wolfSSL | 15:117db924cf7c | 8323 | { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, |
wolfSSL | 15:117db924cf7c | 8324 | { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, |
wolfSSL | 15:117db924cf7c | 8325 | { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, |
wolfSSL | 15:117db924cf7c | 8326 | { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, |
wolfSSL | 15:117db924cf7c | 8327 | { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, |
wolfSSL | 15:117db924cf7c | 8328 | { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, |
wolfSSL | 15:117db924cf7c | 8329 | { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, |
wolfSSL | 15:117db924cf7c | 8330 | { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, |
wolfSSL | 15:117db924cf7c | 8331 | { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, |
wolfSSL | 15:117db924cf7c | 8332 | { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, |
wolfSSL | 15:117db924cf7c | 8333 | { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, |
wolfSSL | 15:117db924cf7c | 8334 | { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, |
wolfSSL | 15:117db924cf7c | 8335 | { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, |
wolfSSL | 15:117db924cf7c | 8336 | { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, |
wolfSSL | 15:117db924cf7c | 8337 | { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, |
wolfSSL | 15:117db924cf7c | 8338 | { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, |
wolfSSL | 15:117db924cf7c | 8339 | { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, |
wolfSSL | 15:117db924cf7c | 8340 | { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, |
wolfSSL | 15:117db924cf7c | 8341 | { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, |
wolfSSL | 15:117db924cf7c | 8342 | { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, |
wolfSSL | 15:117db924cf7c | 8343 | { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, |
wolfSSL | 15:117db924cf7c | 8344 | { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, |
wolfSSL | 15:117db924cf7c | 8345 | { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, |
wolfSSL | 15:117db924cf7c | 8346 | { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, |
wolfSSL | 15:117db924cf7c | 8347 | { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, |
wolfSSL | 15:117db924cf7c | 8348 | { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, |
wolfSSL | 15:117db924cf7c | 8349 | { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, |
wolfSSL | 15:117db924cf7c | 8350 | { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, |
wolfSSL | 15:117db924cf7c | 8351 | { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, |
wolfSSL | 15:117db924cf7c | 8352 | { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, |
wolfSSL | 15:117db924cf7c | 8353 | { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, |
wolfSSL | 15:117db924cf7c | 8354 | { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, |
wolfSSL | 15:117db924cf7c | 8355 | { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, |
wolfSSL | 15:117db924cf7c | 8356 | { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, |
wolfSSL | 15:117db924cf7c | 8357 | { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, |
wolfSSL | 15:117db924cf7c | 8358 | { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, |
wolfSSL | 15:117db924cf7c | 8359 | { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, |
wolfSSL | 15:117db924cf7c | 8360 | { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, |
wolfSSL | 15:117db924cf7c | 8361 | { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, |
wolfSSL | 15:117db924cf7c | 8362 | { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, |
wolfSSL | 15:117db924cf7c | 8363 | { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, |
wolfSSL | 15:117db924cf7c | 8364 | { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, |
wolfSSL | 15:117db924cf7c | 8365 | { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, |
wolfSSL | 15:117db924cf7c | 8366 | { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, |
wolfSSL | 15:117db924cf7c | 8367 | { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, |
wolfSSL | 15:117db924cf7c | 8368 | { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, |
wolfSSL | 15:117db924cf7c | 8369 | { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, |
wolfSSL | 15:117db924cf7c | 8370 | { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, |
wolfSSL | 15:117db924cf7c | 8371 | { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, |
wolfSSL | 15:117db924cf7c | 8372 | { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, |
wolfSSL | 15:117db924cf7c | 8373 | { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, |
wolfSSL | 15:117db924cf7c | 8374 | #if FP_LUT > 11 |
wolfSSL | 15:117db924cf7c | 8375 | { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, |
wolfSSL | 15:117db924cf7c | 8376 | { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, |
wolfSSL | 15:117db924cf7c | 8377 | { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, |
wolfSSL | 15:117db924cf7c | 8378 | { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, |
wolfSSL | 15:117db924cf7c | 8379 | { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, |
wolfSSL | 15:117db924cf7c | 8380 | { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, |
wolfSSL | 15:117db924cf7c | 8381 | { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, |
wolfSSL | 15:117db924cf7c | 8382 | { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, |
wolfSSL | 15:117db924cf7c | 8383 | { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, |
wolfSSL | 15:117db924cf7c | 8384 | { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, |
wolfSSL | 15:117db924cf7c | 8385 | { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, |
wolfSSL | 15:117db924cf7c | 8386 | { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, |
wolfSSL | 15:117db924cf7c | 8387 | { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, |
wolfSSL | 15:117db924cf7c | 8388 | { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, |
wolfSSL | 15:117db924cf7c | 8389 | { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, |
wolfSSL | 15:117db924cf7c | 8390 | { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, |
wolfSSL | 15:117db924cf7c | 8391 | { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, |
wolfSSL | 15:117db924cf7c | 8392 | { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, |
wolfSSL | 15:117db924cf7c | 8393 | { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, |
wolfSSL | 15:117db924cf7c | 8394 | { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, |
wolfSSL | 15:117db924cf7c | 8395 | { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, |
wolfSSL | 15:117db924cf7c | 8396 | { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, |
wolfSSL | 15:117db924cf7c | 8397 | { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, |
wolfSSL | 15:117db924cf7c | 8398 | { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, |
wolfSSL | 15:117db924cf7c | 8399 | { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, |
wolfSSL | 15:117db924cf7c | 8400 | { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, |
wolfSSL | 15:117db924cf7c | 8401 | { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, |
wolfSSL | 15:117db924cf7c | 8402 | { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, |
wolfSSL | 15:117db924cf7c | 8403 | { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, |
wolfSSL | 15:117db924cf7c | 8404 | { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, |
wolfSSL | 15:117db924cf7c | 8405 | { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, |
wolfSSL | 15:117db924cf7c | 8406 | { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, |
wolfSSL | 15:117db924cf7c | 8407 | { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, |
wolfSSL | 15:117db924cf7c | 8408 | { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, |
wolfSSL | 15:117db924cf7c | 8409 | { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, |
wolfSSL | 15:117db924cf7c | 8410 | { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, |
wolfSSL | 15:117db924cf7c | 8411 | { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, |
wolfSSL | 15:117db924cf7c | 8412 | { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, |
wolfSSL | 15:117db924cf7c | 8413 | { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, |
wolfSSL | 15:117db924cf7c | 8414 | { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, |
wolfSSL | 15:117db924cf7c | 8415 | { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, |
wolfSSL | 15:117db924cf7c | 8416 | { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, |
wolfSSL | 15:117db924cf7c | 8417 | { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, |
wolfSSL | 15:117db924cf7c | 8418 | { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, |
wolfSSL | 15:117db924cf7c | 8419 | { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, |
wolfSSL | 15:117db924cf7c | 8420 | { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, |
wolfSSL | 15:117db924cf7c | 8421 | { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, |
wolfSSL | 15:117db924cf7c | 8422 | { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, |
wolfSSL | 15:117db924cf7c | 8423 | { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, |
wolfSSL | 15:117db924cf7c | 8424 | { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, |
wolfSSL | 15:117db924cf7c | 8425 | { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, |
wolfSSL | 15:117db924cf7c | 8426 | { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, |
wolfSSL | 15:117db924cf7c | 8427 | { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, |
wolfSSL | 15:117db924cf7c | 8428 | { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, |
wolfSSL | 15:117db924cf7c | 8429 | { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, |
wolfSSL | 15:117db924cf7c | 8430 | { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, |
wolfSSL | 15:117db924cf7c | 8431 | { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, |
wolfSSL | 15:117db924cf7c | 8432 | { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, |
wolfSSL | 15:117db924cf7c | 8433 | { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, |
wolfSSL | 15:117db924cf7c | 8434 | { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, |
wolfSSL | 15:117db924cf7c | 8435 | { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, |
wolfSSL | 15:117db924cf7c | 8436 | { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, |
wolfSSL | 15:117db924cf7c | 8437 | { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, |
wolfSSL | 15:117db924cf7c | 8438 | { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, |
wolfSSL | 15:117db924cf7c | 8439 | { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, |
wolfSSL | 15:117db924cf7c | 8440 | { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, |
wolfSSL | 15:117db924cf7c | 8441 | { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, |
wolfSSL | 15:117db924cf7c | 8442 | { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, |
wolfSSL | 15:117db924cf7c | 8443 | { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, |
wolfSSL | 15:117db924cf7c | 8444 | { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, |
wolfSSL | 15:117db924cf7c | 8445 | { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, |
wolfSSL | 15:117db924cf7c | 8446 | { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, |
wolfSSL | 15:117db924cf7c | 8447 | { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, |
wolfSSL | 15:117db924cf7c | 8448 | { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, |
wolfSSL | 15:117db924cf7c | 8449 | { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, |
wolfSSL | 15:117db924cf7c | 8450 | { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, |
wolfSSL | 15:117db924cf7c | 8451 | { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, |
wolfSSL | 15:117db924cf7c | 8452 | { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, |
wolfSSL | 15:117db924cf7c | 8453 | { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, |
wolfSSL | 15:117db924cf7c | 8454 | { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, |
wolfSSL | 15:117db924cf7c | 8455 | { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, |
wolfSSL | 15:117db924cf7c | 8456 | { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, |
wolfSSL | 15:117db924cf7c | 8457 | { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, |
wolfSSL | 15:117db924cf7c | 8458 | { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, |
wolfSSL | 15:117db924cf7c | 8459 | { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, |
wolfSSL | 15:117db924cf7c | 8460 | { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, |
wolfSSL | 15:117db924cf7c | 8461 | { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, |
wolfSSL | 15:117db924cf7c | 8462 | { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, |
wolfSSL | 15:117db924cf7c | 8463 | { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, |
wolfSSL | 15:117db924cf7c | 8464 | { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, |
wolfSSL | 15:117db924cf7c | 8465 | { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, |
wolfSSL | 15:117db924cf7c | 8466 | { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, |
wolfSSL | 15:117db924cf7c | 8467 | { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, |
wolfSSL | 15:117db924cf7c | 8468 | { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, |
wolfSSL | 15:117db924cf7c | 8469 | { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, |
wolfSSL | 15:117db924cf7c | 8470 | { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, |
wolfSSL | 15:117db924cf7c | 8471 | { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, |
wolfSSL | 15:117db924cf7c | 8472 | { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, |
wolfSSL | 15:117db924cf7c | 8473 | { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, |
wolfSSL | 15:117db924cf7c | 8474 | { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, |
wolfSSL | 15:117db924cf7c | 8475 | { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, |
wolfSSL | 15:117db924cf7c | 8476 | { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, |
wolfSSL | 15:117db924cf7c | 8477 | { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, |
wolfSSL | 15:117db924cf7c | 8478 | { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, |
wolfSSL | 15:117db924cf7c | 8479 | { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, |
wolfSSL | 15:117db924cf7c | 8480 | { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, |
wolfSSL | 15:117db924cf7c | 8481 | { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, |
wolfSSL | 15:117db924cf7c | 8482 | { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, |
wolfSSL | 15:117db924cf7c | 8483 | { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, |
wolfSSL | 15:117db924cf7c | 8484 | { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, |
wolfSSL | 15:117db924cf7c | 8485 | { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, |
wolfSSL | 15:117db924cf7c | 8486 | { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, |
wolfSSL | 15:117db924cf7c | 8487 | { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, |
wolfSSL | 15:117db924cf7c | 8488 | { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, |
wolfSSL | 15:117db924cf7c | 8489 | { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, |
wolfSSL | 15:117db924cf7c | 8490 | { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, |
wolfSSL | 15:117db924cf7c | 8491 | { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, |
wolfSSL | 15:117db924cf7c | 8492 | { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, |
wolfSSL | 15:117db924cf7c | 8493 | { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, |
wolfSSL | 15:117db924cf7c | 8494 | { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, |
wolfSSL | 15:117db924cf7c | 8495 | { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, |
wolfSSL | 15:117db924cf7c | 8496 | { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, |
wolfSSL | 15:117db924cf7c | 8497 | { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, |
wolfSSL | 15:117db924cf7c | 8498 | { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, |
wolfSSL | 15:117db924cf7c | 8499 | { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, |
wolfSSL | 15:117db924cf7c | 8500 | { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, |
wolfSSL | 15:117db924cf7c | 8501 | { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, |
wolfSSL | 15:117db924cf7c | 8502 | { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, |
wolfSSL | 15:117db924cf7c | 8503 | { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, |
wolfSSL | 15:117db924cf7c | 8504 | { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, |
wolfSSL | 15:117db924cf7c | 8505 | { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, |
wolfSSL | 15:117db924cf7c | 8506 | { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, |
wolfSSL | 15:117db924cf7c | 8507 | { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, |
wolfSSL | 15:117db924cf7c | 8508 | { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, |
wolfSSL | 15:117db924cf7c | 8509 | { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, |
wolfSSL | 15:117db924cf7c | 8510 | { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, |
wolfSSL | 15:117db924cf7c | 8511 | { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, |
wolfSSL | 15:117db924cf7c | 8512 | { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, |
wolfSSL | 15:117db924cf7c | 8513 | { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, |
wolfSSL | 15:117db924cf7c | 8514 | { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, |
wolfSSL | 15:117db924cf7c | 8515 | { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, |
wolfSSL | 15:117db924cf7c | 8516 | { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, |
wolfSSL | 15:117db924cf7c | 8517 | { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, |
wolfSSL | 15:117db924cf7c | 8518 | { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, |
wolfSSL | 15:117db924cf7c | 8519 | { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, |
wolfSSL | 15:117db924cf7c | 8520 | { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, |
wolfSSL | 15:117db924cf7c | 8521 | { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, |
wolfSSL | 15:117db924cf7c | 8522 | { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, |
wolfSSL | 15:117db924cf7c | 8523 | { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, |
wolfSSL | 15:117db924cf7c | 8524 | { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, |
wolfSSL | 15:117db924cf7c | 8525 | { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, |
wolfSSL | 15:117db924cf7c | 8526 | { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, |
wolfSSL | 15:117db924cf7c | 8527 | { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, |
wolfSSL | 15:117db924cf7c | 8528 | { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, |
wolfSSL | 15:117db924cf7c | 8529 | { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, |
wolfSSL | 15:117db924cf7c | 8530 | { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, |
wolfSSL | 15:117db924cf7c | 8531 | { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, |
wolfSSL | 15:117db924cf7c | 8532 | { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, |
wolfSSL | 15:117db924cf7c | 8533 | { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, |
wolfSSL | 15:117db924cf7c | 8534 | { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, |
wolfSSL | 15:117db924cf7c | 8535 | { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, |
wolfSSL | 15:117db924cf7c | 8536 | { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, |
wolfSSL | 15:117db924cf7c | 8537 | { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, |
wolfSSL | 15:117db924cf7c | 8538 | { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, |
wolfSSL | 15:117db924cf7c | 8539 | { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, |
wolfSSL | 15:117db924cf7c | 8540 | { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, |
wolfSSL | 15:117db924cf7c | 8541 | { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, |
wolfSSL | 15:117db924cf7c | 8542 | { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, |
wolfSSL | 15:117db924cf7c | 8543 | { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, |
wolfSSL | 15:117db924cf7c | 8544 | { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, |
wolfSSL | 15:117db924cf7c | 8545 | { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, |
wolfSSL | 15:117db924cf7c | 8546 | { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, |
wolfSSL | 15:117db924cf7c | 8547 | { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, |
wolfSSL | 15:117db924cf7c | 8548 | { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, |
wolfSSL | 15:117db924cf7c | 8549 | { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, |
wolfSSL | 15:117db924cf7c | 8550 | { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, |
wolfSSL | 15:117db924cf7c | 8551 | { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, |
wolfSSL | 15:117db924cf7c | 8552 | { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, |
wolfSSL | 15:117db924cf7c | 8553 | { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, |
wolfSSL | 15:117db924cf7c | 8554 | { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, |
wolfSSL | 15:117db924cf7c | 8555 | { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, |
wolfSSL | 15:117db924cf7c | 8556 | { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, |
wolfSSL | 15:117db924cf7c | 8557 | { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, |
wolfSSL | 15:117db924cf7c | 8558 | { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, |
wolfSSL | 15:117db924cf7c | 8559 | { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, |
wolfSSL | 15:117db924cf7c | 8560 | { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, |
wolfSSL | 15:117db924cf7c | 8561 | { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, |
wolfSSL | 15:117db924cf7c | 8562 | { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, |
wolfSSL | 15:117db924cf7c | 8563 | { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, |
wolfSSL | 15:117db924cf7c | 8564 | { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, |
wolfSSL | 15:117db924cf7c | 8565 | { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, |
wolfSSL | 15:117db924cf7c | 8566 | { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, |
wolfSSL | 15:117db924cf7c | 8567 | { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, |
wolfSSL | 15:117db924cf7c | 8568 | { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, |
wolfSSL | 15:117db924cf7c | 8569 | { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, |
wolfSSL | 15:117db924cf7c | 8570 | { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, |
wolfSSL | 15:117db924cf7c | 8571 | { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, |
wolfSSL | 15:117db924cf7c | 8572 | { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, |
wolfSSL | 15:117db924cf7c | 8573 | { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, |
wolfSSL | 15:117db924cf7c | 8574 | { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, |
wolfSSL | 15:117db924cf7c | 8575 | { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, |
wolfSSL | 15:117db924cf7c | 8576 | { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, |
wolfSSL | 15:117db924cf7c | 8577 | { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, |
wolfSSL | 15:117db924cf7c | 8578 | { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, |
wolfSSL | 15:117db924cf7c | 8579 | { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, |
wolfSSL | 15:117db924cf7c | 8580 | { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, |
wolfSSL | 15:117db924cf7c | 8581 | { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, |
wolfSSL | 15:117db924cf7c | 8582 | { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, |
wolfSSL | 15:117db924cf7c | 8583 | { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, |
wolfSSL | 15:117db924cf7c | 8584 | { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, |
wolfSSL | 15:117db924cf7c | 8585 | { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, |
wolfSSL | 15:117db924cf7c | 8586 | { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, |
wolfSSL | 15:117db924cf7c | 8587 | { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, |
wolfSSL | 15:117db924cf7c | 8588 | { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, |
wolfSSL | 15:117db924cf7c | 8589 | { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, |
wolfSSL | 15:117db924cf7c | 8590 | { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, |
wolfSSL | 15:117db924cf7c | 8591 | { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, |
wolfSSL | 15:117db924cf7c | 8592 | { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, |
wolfSSL | 15:117db924cf7c | 8593 | { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, |
wolfSSL | 15:117db924cf7c | 8594 | { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, |
wolfSSL | 15:117db924cf7c | 8595 | { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, |
wolfSSL | 15:117db924cf7c | 8596 | { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, |
wolfSSL | 15:117db924cf7c | 8597 | { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, |
wolfSSL | 15:117db924cf7c | 8598 | { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, |
wolfSSL | 15:117db924cf7c | 8599 | { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, |
wolfSSL | 15:117db924cf7c | 8600 | { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, |
wolfSSL | 15:117db924cf7c | 8601 | { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, |
wolfSSL | 15:117db924cf7c | 8602 | { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, |
wolfSSL | 15:117db924cf7c | 8603 | { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, |
wolfSSL | 15:117db924cf7c | 8604 | { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, |
wolfSSL | 15:117db924cf7c | 8605 | { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, |
wolfSSL | 15:117db924cf7c | 8606 | { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, |
wolfSSL | 15:117db924cf7c | 8607 | { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, |
wolfSSL | 15:117db924cf7c | 8608 | { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, |
wolfSSL | 15:117db924cf7c | 8609 | { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, |
wolfSSL | 15:117db924cf7c | 8610 | { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, |
wolfSSL | 15:117db924cf7c | 8611 | { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, |
wolfSSL | 15:117db924cf7c | 8612 | { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, |
wolfSSL | 15:117db924cf7c | 8613 | { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, |
wolfSSL | 15:117db924cf7c | 8614 | { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, |
wolfSSL | 15:117db924cf7c | 8615 | { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, |
wolfSSL | 15:117db924cf7c | 8616 | { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, |
wolfSSL | 15:117db924cf7c | 8617 | { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, |
wolfSSL | 15:117db924cf7c | 8618 | { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, |
wolfSSL | 15:117db924cf7c | 8619 | { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, |
wolfSSL | 15:117db924cf7c | 8620 | { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, |
wolfSSL | 15:117db924cf7c | 8621 | { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, |
wolfSSL | 15:117db924cf7c | 8622 | { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, |
wolfSSL | 15:117db924cf7c | 8623 | { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, |
wolfSSL | 15:117db924cf7c | 8624 | { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, |
wolfSSL | 15:117db924cf7c | 8625 | { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, |
wolfSSL | 15:117db924cf7c | 8626 | { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, |
wolfSSL | 15:117db924cf7c | 8627 | { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, |
wolfSSL | 15:117db924cf7c | 8628 | { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, |
wolfSSL | 15:117db924cf7c | 8629 | { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, |
wolfSSL | 15:117db924cf7c | 8630 | { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, |
wolfSSL | 15:117db924cf7c | 8631 | #endif |
wolfSSL | 15:117db924cf7c | 8632 | #endif |
wolfSSL | 15:117db924cf7c | 8633 | #endif |
wolfSSL | 15:117db924cf7c | 8634 | #endif |
wolfSSL | 15:117db924cf7c | 8635 | #endif |
wolfSSL | 15:117db924cf7c | 8636 | #endif |
wolfSSL | 15:117db924cf7c | 8637 | }; |
wolfSSL | 15:117db924cf7c | 8638 | |
wolfSSL | 15:117db924cf7c | 8639 | |
wolfSSL | 15:117db924cf7c | 8640 | /* find a hole and free as required, return -1 if no hole found */ |
wolfSSL | 15:117db924cf7c | 8641 | static int find_hole(void) |
wolfSSL | 15:117db924cf7c | 8642 | { |
wolfSSL | 15:117db924cf7c | 8643 | unsigned x; |
wolfSSL | 15:117db924cf7c | 8644 | int y, z; |
wolfSSL | 15:117db924cf7c | 8645 | for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 15:117db924cf7c | 8646 | if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { |
wolfSSL | 15:117db924cf7c | 8647 | z = x; |
wolfSSL | 15:117db924cf7c | 8648 | y = fp_cache[x].lru_count; |
wolfSSL | 15:117db924cf7c | 8649 | } |
wolfSSL | 15:117db924cf7c | 8650 | } |
wolfSSL | 15:117db924cf7c | 8651 | |
wolfSSL | 15:117db924cf7c | 8652 | /* decrease all */ |
wolfSSL | 15:117db924cf7c | 8653 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 15:117db924cf7c | 8654 | if (fp_cache[x].lru_count > 3) { |
wolfSSL | 15:117db924cf7c | 8655 | --(fp_cache[x].lru_count); |
wolfSSL | 15:117db924cf7c | 8656 | } |
wolfSSL | 15:117db924cf7c | 8657 | } |
wolfSSL | 15:117db924cf7c | 8658 | |
wolfSSL | 15:117db924cf7c | 8659 | /* free entry z */ |
wolfSSL | 15:117db924cf7c | 8660 | if (z >= 0 && fp_cache[z].g) { |
wolfSSL | 15:117db924cf7c | 8661 | mp_clear(&fp_cache[z].mu); |
wolfSSL | 15:117db924cf7c | 8662 | wc_ecc_del_point(fp_cache[z].g); |
wolfSSL | 15:117db924cf7c | 8663 | fp_cache[z].g = NULL; |
wolfSSL | 15:117db924cf7c | 8664 | for (x = 0; x < (1U<<FP_LUT); x++) { |
wolfSSL | 15:117db924cf7c | 8665 | wc_ecc_del_point(fp_cache[z].LUT[x]); |
wolfSSL | 15:117db924cf7c | 8666 | fp_cache[z].LUT[x] = NULL; |
wolfSSL | 15:117db924cf7c | 8667 | } |
wolfSSL | 15:117db924cf7c | 8668 | fp_cache[z].lru_count = 0; |
wolfSSL | 15:117db924cf7c | 8669 | } |
wolfSSL | 15:117db924cf7c | 8670 | return z; |
wolfSSL | 15:117db924cf7c | 8671 | } |
wolfSSL | 15:117db924cf7c | 8672 | |
wolfSSL | 15:117db924cf7c | 8673 | /* determine if a base is already in the cache and if so, where */ |
wolfSSL | 15:117db924cf7c | 8674 | static int find_base(ecc_point* g) |
wolfSSL | 15:117db924cf7c | 8675 | { |
wolfSSL | 15:117db924cf7c | 8676 | int x; |
wolfSSL | 15:117db924cf7c | 8677 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 15:117db924cf7c | 8678 | if (fp_cache[x].g != NULL && |
wolfSSL | 15:117db924cf7c | 8679 | mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ && |
wolfSSL | 15:117db924cf7c | 8680 | mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ && |
wolfSSL | 15:117db924cf7c | 8681 | mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 8682 | break; |
wolfSSL | 15:117db924cf7c | 8683 | } |
wolfSSL | 15:117db924cf7c | 8684 | } |
wolfSSL | 15:117db924cf7c | 8685 | if (x == FP_ENTRIES) { |
wolfSSL | 15:117db924cf7c | 8686 | x = -1; |
wolfSSL | 15:117db924cf7c | 8687 | } |
wolfSSL | 15:117db924cf7c | 8688 | return x; |
wolfSSL | 15:117db924cf7c | 8689 | } |
wolfSSL | 15:117db924cf7c | 8690 | |
wolfSSL | 15:117db924cf7c | 8691 | /* add a new base to the cache */ |
wolfSSL | 15:117db924cf7c | 8692 | static int add_entry(int idx, ecc_point *g) |
wolfSSL | 15:117db924cf7c | 8693 | { |
wolfSSL | 15:117db924cf7c | 8694 | unsigned x, y; |
wolfSSL | 15:117db924cf7c | 8695 | |
wolfSSL | 15:117db924cf7c | 8696 | /* allocate base and LUT */ |
wolfSSL | 15:117db924cf7c | 8697 | fp_cache[idx].g = wc_ecc_new_point(); |
wolfSSL | 15:117db924cf7c | 8698 | if (fp_cache[idx].g == NULL) { |
wolfSSL | 15:117db924cf7c | 8699 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 8700 | } |
wolfSSL | 15:117db924cf7c | 8701 | |
wolfSSL | 15:117db924cf7c | 8702 | /* copy x and y */ |
wolfSSL | 15:117db924cf7c | 8703 | if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8704 | (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8705 | (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { |
wolfSSL | 15:117db924cf7c | 8706 | wc_ecc_del_point(fp_cache[idx].g); |
wolfSSL | 15:117db924cf7c | 8707 | fp_cache[idx].g = NULL; |
wolfSSL | 15:117db924cf7c | 8708 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 8709 | } |
wolfSSL | 15:117db924cf7c | 8710 | |
wolfSSL | 15:117db924cf7c | 8711 | for (x = 0; x < (1U<<FP_LUT); x++) { |
wolfSSL | 15:117db924cf7c | 8712 | fp_cache[idx].LUT[x] = wc_ecc_new_point(); |
wolfSSL | 15:117db924cf7c | 8713 | if (fp_cache[idx].LUT[x] == NULL) { |
wolfSSL | 15:117db924cf7c | 8714 | for (y = 0; y < x; y++) { |
wolfSSL | 15:117db924cf7c | 8715 | wc_ecc_del_point(fp_cache[idx].LUT[y]); |
wolfSSL | 15:117db924cf7c | 8716 | fp_cache[idx].LUT[y] = NULL; |
wolfSSL | 15:117db924cf7c | 8717 | } |
wolfSSL | 15:117db924cf7c | 8718 | wc_ecc_del_point(fp_cache[idx].g); |
wolfSSL | 15:117db924cf7c | 8719 | fp_cache[idx].g = NULL; |
wolfSSL | 15:117db924cf7c | 8720 | fp_cache[idx].lru_count = 0; |
wolfSSL | 15:117db924cf7c | 8721 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 8722 | } |
wolfSSL | 15:117db924cf7c | 8723 | } |
wolfSSL | 15:117db924cf7c | 8724 | |
wolfSSL | 15:117db924cf7c | 8725 | fp_cache[idx].lru_count = 0; |
wolfSSL | 15:117db924cf7c | 8726 | |
wolfSSL | 15:117db924cf7c | 8727 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 8728 | } |
wolfSSL | 15:117db924cf7c | 8729 | #endif |
wolfSSL | 15:117db924cf7c | 8730 | |
wolfSSL | 15:117db924cf7c | 8731 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 8732 | /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart |
wolfSSL | 15:117db924cf7c | 8733 | * |
wolfSSL | 15:117db924cf7c | 8734 | * The algorithm builds patterns in increasing bit order by first making all |
wolfSSL | 15:117db924cf7c | 8735 | * single bit input patterns, then all two bit input patterns and so on |
wolfSSL | 15:117db924cf7c | 8736 | */ |
wolfSSL | 15:117db924cf7c | 8737 | static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, |
wolfSSL | 15:117db924cf7c | 8738 | mp_int* mu) |
wolfSSL | 15:117db924cf7c | 8739 | { |
wolfSSL | 15:117db924cf7c | 8740 | int err; |
wolfSSL | 15:117db924cf7c | 8741 | unsigned x, y, bitlen, lut_gap; |
wolfSSL | 15:117db924cf7c | 8742 | mp_int tmp; |
wolfSSL | 15:117db924cf7c | 8743 | |
wolfSSL | 15:117db924cf7c | 8744 | if (mp_init(&tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8745 | return GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 8746 | |
wolfSSL | 15:117db924cf7c | 8747 | /* sanity check to make sure lut_order table is of correct size, |
wolfSSL | 15:117db924cf7c | 8748 | should compile out to a NOP if true */ |
wolfSSL | 15:117db924cf7c | 8749 | if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) { |
wolfSSL | 15:117db924cf7c | 8750 | err = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 8751 | } |
wolfSSL | 15:117db924cf7c | 8752 | else { |
wolfSSL | 15:117db924cf7c | 8753 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 15:117db924cf7c | 8754 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 15:117db924cf7c | 8755 | x = bitlen % FP_LUT; |
wolfSSL | 15:117db924cf7c | 8756 | if (x) { |
wolfSSL | 15:117db924cf7c | 8757 | bitlen += FP_LUT - x; |
wolfSSL | 15:117db924cf7c | 8758 | } |
wolfSSL | 15:117db924cf7c | 8759 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 15:117db924cf7c | 8760 | |
wolfSSL | 15:117db924cf7c | 8761 | /* init the mu */ |
wolfSSL | 15:117db924cf7c | 8762 | err = mp_init_copy(&fp_cache[idx].mu, mu); |
wolfSSL | 15:117db924cf7c | 8763 | } |
wolfSSL | 15:117db924cf7c | 8764 | |
wolfSSL | 15:117db924cf7c | 8765 | /* copy base */ |
wolfSSL | 15:117db924cf7c | 8766 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8767 | if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, |
wolfSSL | 15:117db924cf7c | 8768 | fp_cache[idx].LUT[1]->x) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8769 | (mp_mulmod(fp_cache[idx].g->y, mu, modulus, |
wolfSSL | 15:117db924cf7c | 8770 | fp_cache[idx].LUT[1]->y) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8771 | (mp_mulmod(fp_cache[idx].g->z, mu, modulus, |
wolfSSL | 15:117db924cf7c | 8772 | fp_cache[idx].LUT[1]->z) != MP_OKAY)) { |
wolfSSL | 15:117db924cf7c | 8773 | err = MP_MULMOD_E; |
wolfSSL | 15:117db924cf7c | 8774 | } |
wolfSSL | 15:117db924cf7c | 8775 | } |
wolfSSL | 15:117db924cf7c | 8776 | |
wolfSSL | 15:117db924cf7c | 8777 | /* make all single bit entries */ |
wolfSSL | 15:117db924cf7c | 8778 | for (x = 1; x < FP_LUT; x++) { |
wolfSSL | 15:117db924cf7c | 8779 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8780 | break; |
wolfSSL | 15:117db924cf7c | 8781 | if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, |
wolfSSL | 15:117db924cf7c | 8782 | fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8783 | (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, |
wolfSSL | 15:117db924cf7c | 8784 | fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 8785 | (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, |
wolfSSL | 15:117db924cf7c | 8786 | fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){ |
wolfSSL | 15:117db924cf7c | 8787 | err = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 8788 | break; |
wolfSSL | 15:117db924cf7c | 8789 | } else { |
wolfSSL | 15:117db924cf7c | 8790 | |
wolfSSL | 15:117db924cf7c | 8791 | /* now double it bitlen/FP_LUT times */ |
wolfSSL | 15:117db924cf7c | 8792 | for (y = 0; y < lut_gap; y++) { |
wolfSSL | 15:117db924cf7c | 8793 | if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x], |
wolfSSL | 15:117db924cf7c | 8794 | fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8795 | break; |
wolfSSL | 15:117db924cf7c | 8796 | } |
wolfSSL | 15:117db924cf7c | 8797 | } |
wolfSSL | 15:117db924cf7c | 8798 | } |
wolfSSL | 15:117db924cf7c | 8799 | } |
wolfSSL | 15:117db924cf7c | 8800 | |
wolfSSL | 15:117db924cf7c | 8801 | /* now make all entries in increase order of hamming weight */ |
wolfSSL | 15:117db924cf7c | 8802 | for (x = 2; x <= FP_LUT; x++) { |
wolfSSL | 15:117db924cf7c | 8803 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8804 | break; |
wolfSSL | 15:117db924cf7c | 8805 | for (y = 0; y < (1UL<<FP_LUT); y++) { |
wolfSSL | 15:117db924cf7c | 8806 | if (lut_orders[y].ham != (int)x) continue; |
wolfSSL | 15:117db924cf7c | 8807 | |
wolfSSL | 15:117db924cf7c | 8808 | /* perform the add */ |
wolfSSL | 15:117db924cf7c | 8809 | if ((err = ecc_projective_add_point( |
wolfSSL | 15:117db924cf7c | 8810 | fp_cache[idx].LUT[lut_orders[y].terma], |
wolfSSL | 15:117db924cf7c | 8811 | fp_cache[idx].LUT[lut_orders[y].termb], |
wolfSSL | 15:117db924cf7c | 8812 | fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8813 | break; |
wolfSSL | 15:117db924cf7c | 8814 | } |
wolfSSL | 15:117db924cf7c | 8815 | } |
wolfSSL | 15:117db924cf7c | 8816 | } |
wolfSSL | 15:117db924cf7c | 8817 | |
wolfSSL | 15:117db924cf7c | 8818 | /* now map all entries back to affine space to make point addition faster */ |
wolfSSL | 15:117db924cf7c | 8819 | for (x = 1; x < (1UL<<FP_LUT); x++) { |
wolfSSL | 15:117db924cf7c | 8820 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8821 | break; |
wolfSSL | 15:117db924cf7c | 8822 | |
wolfSSL | 15:117db924cf7c | 8823 | /* convert z to normal from montgomery */ |
wolfSSL | 15:117db924cf7c | 8824 | err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp); |
wolfSSL | 15:117db924cf7c | 8825 | |
wolfSSL | 15:117db924cf7c | 8826 | /* invert it */ |
wolfSSL | 15:117db924cf7c | 8827 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8828 | err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, |
wolfSSL | 15:117db924cf7c | 8829 | fp_cache[idx].LUT[x]->z); |
wolfSSL | 15:117db924cf7c | 8830 | |
wolfSSL | 15:117db924cf7c | 8831 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8832 | /* now square it */ |
wolfSSL | 15:117db924cf7c | 8833 | err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp); |
wolfSSL | 15:117db924cf7c | 8834 | |
wolfSSL | 15:117db924cf7c | 8835 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8836 | /* fix x */ |
wolfSSL | 15:117db924cf7c | 8837 | err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus, |
wolfSSL | 15:117db924cf7c | 8838 | fp_cache[idx].LUT[x]->x); |
wolfSSL | 15:117db924cf7c | 8839 | |
wolfSSL | 15:117db924cf7c | 8840 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8841 | /* get 1/z^3 */ |
wolfSSL | 15:117db924cf7c | 8842 | err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp); |
wolfSSL | 15:117db924cf7c | 8843 | |
wolfSSL | 15:117db924cf7c | 8844 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8845 | /* fix y */ |
wolfSSL | 15:117db924cf7c | 8846 | err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus, |
wolfSSL | 15:117db924cf7c | 8847 | fp_cache[idx].LUT[x]->y); |
wolfSSL | 15:117db924cf7c | 8848 | |
wolfSSL | 15:117db924cf7c | 8849 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8850 | /* free z */ |
wolfSSL | 15:117db924cf7c | 8851 | mp_clear(fp_cache[idx].LUT[x]->z); |
wolfSSL | 15:117db924cf7c | 8852 | } |
wolfSSL | 15:117db924cf7c | 8853 | |
wolfSSL | 15:117db924cf7c | 8854 | mp_clear(&tmp); |
wolfSSL | 15:117db924cf7c | 8855 | |
wolfSSL | 15:117db924cf7c | 8856 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8857 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 8858 | |
wolfSSL | 15:117db924cf7c | 8859 | /* err cleanup */ |
wolfSSL | 15:117db924cf7c | 8860 | for (y = 0; y < (1U<<FP_LUT); y++) { |
wolfSSL | 15:117db924cf7c | 8861 | wc_ecc_del_point(fp_cache[idx].LUT[y]); |
wolfSSL | 15:117db924cf7c | 8862 | fp_cache[idx].LUT[y] = NULL; |
wolfSSL | 15:117db924cf7c | 8863 | } |
wolfSSL | 15:117db924cf7c | 8864 | wc_ecc_del_point(fp_cache[idx].g); |
wolfSSL | 15:117db924cf7c | 8865 | fp_cache[idx].g = NULL; |
wolfSSL | 15:117db924cf7c | 8866 | fp_cache[idx].lru_count = 0; |
wolfSSL | 15:117db924cf7c | 8867 | mp_clear(&fp_cache[idx].mu); |
wolfSSL | 15:117db924cf7c | 8868 | |
wolfSSL | 15:117db924cf7c | 8869 | return err; |
wolfSSL | 15:117db924cf7c | 8870 | } |
wolfSSL | 15:117db924cf7c | 8871 | |
wolfSSL | 15:117db924cf7c | 8872 | /* perform a fixed point ECC mulmod */ |
wolfSSL | 15:117db924cf7c | 8873 | static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, |
wolfSSL | 15:117db924cf7c | 8874 | mp_int* modulus, mp_digit mp, int map) |
wolfSSL | 15:117db924cf7c | 8875 | { |
wolfSSL | 15:117db924cf7c | 8876 | #define KB_SIZE 128 |
wolfSSL | 15:117db924cf7c | 8877 | |
wolfSSL | 15:117db924cf7c | 8878 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 8879 | unsigned char* kb = NULL; |
wolfSSL | 15:117db924cf7c | 8880 | #else |
wolfSSL | 15:117db924cf7c | 8881 | unsigned char kb[KB_SIZE]; |
wolfSSL | 15:117db924cf7c | 8882 | #endif |
wolfSSL | 15:117db924cf7c | 8883 | int x, err; |
wolfSSL | 15:117db924cf7c | 8884 | unsigned y, z = 0, bitlen, bitpos, lut_gap, first; |
wolfSSL | 15:117db924cf7c | 8885 | mp_int tk, order; |
wolfSSL | 15:117db924cf7c | 8886 | |
wolfSSL | 15:117db924cf7c | 8887 | if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 8888 | return MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 8889 | |
wolfSSL | 15:117db924cf7c | 8890 | /* if it's smaller than modulus we fine */ |
wolfSSL | 15:117db924cf7c | 8891 | if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 15:117db924cf7c | 8892 | /* find order */ |
wolfSSL | 15:117db924cf7c | 8893 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 15:117db924cf7c | 8894 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 15:117db924cf7c | 8895 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 15:117db924cf7c | 8896 | } |
wolfSSL | 15:117db924cf7c | 8897 | |
wolfSSL | 15:117db924cf7c | 8898 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 15:117db924cf7c | 8899 | if (y == 66) --x; |
wolfSSL | 15:117db924cf7c | 8900 | |
wolfSSL | 15:117db924cf7c | 8901 | if ((err = mp_read_radix(&order, ecc_sets[x].order, |
wolfSSL | 15:117db924cf7c | 8902 | MP_RADIX_HEX)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8903 | goto done; |
wolfSSL | 15:117db924cf7c | 8904 | } |
wolfSSL | 15:117db924cf7c | 8905 | |
wolfSSL | 15:117db924cf7c | 8906 | /* k must be less than modulus */ |
wolfSSL | 15:117db924cf7c | 8907 | if (mp_cmp(k, &order) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 8908 | if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8909 | goto done; |
wolfSSL | 15:117db924cf7c | 8910 | } |
wolfSSL | 15:117db924cf7c | 8911 | } else { |
wolfSSL | 15:117db924cf7c | 8912 | if ((err = mp_copy(k, &tk)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8913 | goto done; |
wolfSSL | 15:117db924cf7c | 8914 | } |
wolfSSL | 15:117db924cf7c | 8915 | } |
wolfSSL | 15:117db924cf7c | 8916 | } else { |
wolfSSL | 15:117db924cf7c | 8917 | if ((err = mp_copy(k, &tk)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8918 | goto done; |
wolfSSL | 15:117db924cf7c | 8919 | } |
wolfSSL | 15:117db924cf7c | 8920 | } |
wolfSSL | 15:117db924cf7c | 8921 | |
wolfSSL | 15:117db924cf7c | 8922 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 15:117db924cf7c | 8923 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 15:117db924cf7c | 8924 | x = bitlen % FP_LUT; |
wolfSSL | 15:117db924cf7c | 8925 | if (x) { |
wolfSSL | 15:117db924cf7c | 8926 | bitlen += FP_LUT - x; |
wolfSSL | 15:117db924cf7c | 8927 | } |
wolfSSL | 15:117db924cf7c | 8928 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 15:117db924cf7c | 8929 | |
wolfSSL | 15:117db924cf7c | 8930 | /* get the k value */ |
wolfSSL | 15:117db924cf7c | 8931 | if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { |
wolfSSL | 15:117db924cf7c | 8932 | err = BUFFER_E; goto done; |
wolfSSL | 15:117db924cf7c | 8933 | } |
wolfSSL | 15:117db924cf7c | 8934 | |
wolfSSL | 15:117db924cf7c | 8935 | /* store k */ |
wolfSSL | 15:117db924cf7c | 8936 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 8937 | kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 8938 | if (kb == NULL) { |
wolfSSL | 15:117db924cf7c | 8939 | err = MEMORY_E; goto done; |
wolfSSL | 15:117db924cf7c | 8940 | } |
wolfSSL | 15:117db924cf7c | 8941 | #endif |
wolfSSL | 15:117db924cf7c | 8942 | |
wolfSSL | 15:117db924cf7c | 8943 | XMEMSET(kb, 0, KB_SIZE); |
wolfSSL | 15:117db924cf7c | 8944 | if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8945 | /* let's reverse kb so it's little endian */ |
wolfSSL | 15:117db924cf7c | 8946 | x = 0; |
wolfSSL | 15:117db924cf7c | 8947 | y = mp_unsigned_bin_size(&tk); |
wolfSSL | 15:117db924cf7c | 8948 | if (y > 0) { |
wolfSSL | 15:117db924cf7c | 8949 | y -= 1; |
wolfSSL | 15:117db924cf7c | 8950 | } |
wolfSSL | 15:117db924cf7c | 8951 | |
wolfSSL | 15:117db924cf7c | 8952 | while ((unsigned)x < y) { |
wolfSSL | 15:117db924cf7c | 8953 | z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z; |
wolfSSL | 15:117db924cf7c | 8954 | ++x; --y; |
wolfSSL | 15:117db924cf7c | 8955 | } |
wolfSSL | 15:117db924cf7c | 8956 | |
wolfSSL | 15:117db924cf7c | 8957 | /* at this point we can start, yipee */ |
wolfSSL | 15:117db924cf7c | 8958 | first = 1; |
wolfSSL | 15:117db924cf7c | 8959 | for (x = lut_gap-1; x >= 0; x--) { |
wolfSSL | 15:117db924cf7c | 8960 | /* extract FP_LUT bits from kb spread out by lut_gap bits and offset |
wolfSSL | 15:117db924cf7c | 8961 | by x bits from the start */ |
wolfSSL | 15:117db924cf7c | 8962 | bitpos = x; |
wolfSSL | 15:117db924cf7c | 8963 | for (y = z = 0; y < FP_LUT; y++) { |
wolfSSL | 15:117db924cf7c | 8964 | z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 15:117db924cf7c | 8965 | bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid |
wolfSSL | 15:117db924cf7c | 8966 | the mult in each loop */ |
wolfSSL | 15:117db924cf7c | 8967 | } |
wolfSSL | 15:117db924cf7c | 8968 | |
wolfSSL | 15:117db924cf7c | 8969 | /* double if not first */ |
wolfSSL | 15:117db924cf7c | 8970 | if (!first) { |
wolfSSL | 15:117db924cf7c | 8971 | if ((err = ecc_projective_dbl_point(R, R, a, modulus, |
wolfSSL | 16:8e0d178b1d1e | 8972 | mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8973 | break; |
wolfSSL | 15:117db924cf7c | 8974 | } |
wolfSSL | 15:117db924cf7c | 8975 | } |
wolfSSL | 15:117db924cf7c | 8976 | |
wolfSSL | 15:117db924cf7c | 8977 | /* add if not first, otherwise copy */ |
wolfSSL | 15:117db924cf7c | 8978 | if (!first && z) { |
wolfSSL | 16:8e0d178b1d1e | 8979 | if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a, |
wolfSSL | 16:8e0d178b1d1e | 8980 | modulus, mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 8981 | break; |
wolfSSL | 15:117db924cf7c | 8982 | } |
wolfSSL | 16:8e0d178b1d1e | 8983 | if (mp_iszero(R->z)) { |
wolfSSL | 16:8e0d178b1d1e | 8984 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 8985 | if (mp_iszero(R->x) && mp_iszero(R->y)) { |
wolfSSL | 16:8e0d178b1d1e | 8986 | if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z], |
wolfSSL | 16:8e0d178b1d1e | 8987 | R, a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 8988 | break; |
wolfSSL | 16:8e0d178b1d1e | 8989 | } |
wolfSSL | 16:8e0d178b1d1e | 8990 | } |
wolfSSL | 16:8e0d178b1d1e | 8991 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 8992 | else { |
wolfSSL | 16:8e0d178b1d1e | 8993 | err = mp_set(R->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 8994 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 8995 | break; |
wolfSSL | 16:8e0d178b1d1e | 8996 | } |
wolfSSL | 16:8e0d178b1d1e | 8997 | err = mp_set(R->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 8998 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 8999 | break; |
wolfSSL | 16:8e0d178b1d1e | 9000 | } |
wolfSSL | 16:8e0d178b1d1e | 9001 | err = mp_copy(&fp_cache[idx].mu, R->z); |
wolfSSL | 16:8e0d178b1d1e | 9002 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9003 | break; |
wolfSSL | 16:8e0d178b1d1e | 9004 | } |
wolfSSL | 16:8e0d178b1d1e | 9005 | first = 1; |
wolfSSL | 16:8e0d178b1d1e | 9006 | } |
wolfSSL | 16:8e0d178b1d1e | 9007 | } |
wolfSSL | 15:117db924cf7c | 9008 | } else if (z) { |
wolfSSL | 15:117db924cf7c | 9009 | if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 9010 | (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || |
wolfSSL | 15:117db924cf7c | 9011 | (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) { |
wolfSSL | 15:117db924cf7c | 9012 | err = GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 9013 | break; |
wolfSSL | 15:117db924cf7c | 9014 | } |
wolfSSL | 16:8e0d178b1d1e | 9015 | first = 0; |
wolfSSL | 15:117db924cf7c | 9016 | } |
wolfSSL | 15:117db924cf7c | 9017 | } |
wolfSSL | 15:117db924cf7c | 9018 | } |
wolfSSL | 15:117db924cf7c | 9019 | |
wolfSSL | 15:117db924cf7c | 9020 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9021 | (void) z; /* Acknowledge the unused assignment */ |
wolfSSL | 15:117db924cf7c | 9022 | ForceZero(kb, KB_SIZE); |
wolfSSL | 15:117db924cf7c | 9023 | |
wolfSSL | 15:117db924cf7c | 9024 | /* map R back from projective space */ |
wolfSSL | 15:117db924cf7c | 9025 | if (map) { |
wolfSSL | 15:117db924cf7c | 9026 | err = ecc_map(R, modulus, mp); |
wolfSSL | 15:117db924cf7c | 9027 | } else { |
wolfSSL | 15:117db924cf7c | 9028 | err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 9029 | } |
wolfSSL | 15:117db924cf7c | 9030 | } |
wolfSSL | 15:117db924cf7c | 9031 | |
wolfSSL | 15:117db924cf7c | 9032 | done: |
wolfSSL | 15:117db924cf7c | 9033 | /* cleanup */ |
wolfSSL | 15:117db924cf7c | 9034 | mp_clear(&order); |
wolfSSL | 15:117db924cf7c | 9035 | mp_clear(&tk); |
wolfSSL | 15:117db924cf7c | 9036 | |
wolfSSL | 15:117db924cf7c | 9037 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9038 | XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9039 | #endif |
wolfSSL | 15:117db924cf7c | 9040 | |
wolfSSL | 15:117db924cf7c | 9041 | #undef KB_SIZE |
wolfSSL | 15:117db924cf7c | 9042 | |
wolfSSL | 15:117db924cf7c | 9043 | return err; |
wolfSSL | 15:117db924cf7c | 9044 | } |
wolfSSL | 15:117db924cf7c | 9045 | #endif |
wolfSSL | 15:117db924cf7c | 9046 | |
wolfSSL | 15:117db924cf7c | 9047 | #ifdef ECC_SHAMIR |
wolfSSL | 15:117db924cf7c | 9048 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 9049 | /* perform a fixed point ECC mulmod */ |
wolfSSL | 15:117db924cf7c | 9050 | static int accel_fp_mul2add(int idx1, int idx2, |
wolfSSL | 15:117db924cf7c | 9051 | mp_int* kA, mp_int* kB, |
wolfSSL | 15:117db924cf7c | 9052 | ecc_point *R, mp_int* a, |
wolfSSL | 15:117db924cf7c | 9053 | mp_int* modulus, mp_digit mp) |
wolfSSL | 15:117db924cf7c | 9054 | { |
wolfSSL | 15:117db924cf7c | 9055 | #define KB_SIZE 128 |
wolfSSL | 15:117db924cf7c | 9056 | |
wolfSSL | 15:117db924cf7c | 9057 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9058 | unsigned char* kb[2] = {NULL, NULL}; |
wolfSSL | 15:117db924cf7c | 9059 | #else |
wolfSSL | 15:117db924cf7c | 9060 | unsigned char kb[2][KB_SIZE]; |
wolfSSL | 15:117db924cf7c | 9061 | #endif |
wolfSSL | 15:117db924cf7c | 9062 | int x, err; |
wolfSSL | 15:117db924cf7c | 9063 | unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB; |
wolfSSL | 15:117db924cf7c | 9064 | mp_int tka, tkb, order; |
wolfSSL | 15:117db924cf7c | 9065 | |
wolfSSL | 15:117db924cf7c | 9066 | if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9067 | return MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 9068 | |
wolfSSL | 15:117db924cf7c | 9069 | /* if it's smaller than modulus we fine */ |
wolfSSL | 15:117db924cf7c | 9070 | if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 15:117db924cf7c | 9071 | /* find order */ |
wolfSSL | 15:117db924cf7c | 9072 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 15:117db924cf7c | 9073 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 15:117db924cf7c | 9074 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 15:117db924cf7c | 9075 | } |
wolfSSL | 15:117db924cf7c | 9076 | |
wolfSSL | 15:117db924cf7c | 9077 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 15:117db924cf7c | 9078 | if (y == 66) --x; |
wolfSSL | 15:117db924cf7c | 9079 | |
wolfSSL | 15:117db924cf7c | 9080 | if ((err = mp_read_radix(&order, ecc_sets[x].order, |
wolfSSL | 15:117db924cf7c | 9081 | MP_RADIX_HEX)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9082 | goto done; |
wolfSSL | 15:117db924cf7c | 9083 | } |
wolfSSL | 15:117db924cf7c | 9084 | |
wolfSSL | 15:117db924cf7c | 9085 | /* kA must be less than modulus */ |
wolfSSL | 15:117db924cf7c | 9086 | if (mp_cmp(kA, &order) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 9087 | if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9088 | goto done; |
wolfSSL | 15:117db924cf7c | 9089 | } |
wolfSSL | 15:117db924cf7c | 9090 | } else { |
wolfSSL | 15:117db924cf7c | 9091 | if ((err = mp_copy(kA, &tka)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9092 | goto done; |
wolfSSL | 15:117db924cf7c | 9093 | } |
wolfSSL | 15:117db924cf7c | 9094 | } |
wolfSSL | 15:117db924cf7c | 9095 | } else { |
wolfSSL | 15:117db924cf7c | 9096 | if ((err = mp_copy(kA, &tka)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9097 | goto done; |
wolfSSL | 15:117db924cf7c | 9098 | } |
wolfSSL | 15:117db924cf7c | 9099 | } |
wolfSSL | 15:117db924cf7c | 9100 | |
wolfSSL | 15:117db924cf7c | 9101 | /* if it's smaller than modulus we fine */ |
wolfSSL | 15:117db924cf7c | 9102 | if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { |
wolfSSL | 15:117db924cf7c | 9103 | /* find order */ |
wolfSSL | 15:117db924cf7c | 9104 | y = mp_unsigned_bin_size(modulus); |
wolfSSL | 15:117db924cf7c | 9105 | for (x = 0; ecc_sets[x].size; x++) { |
wolfSSL | 15:117db924cf7c | 9106 | if (y <= (unsigned)ecc_sets[x].size) break; |
wolfSSL | 15:117db924cf7c | 9107 | } |
wolfSSL | 15:117db924cf7c | 9108 | |
wolfSSL | 15:117db924cf7c | 9109 | /* back off if we are on the 521 bit curve */ |
wolfSSL | 15:117db924cf7c | 9110 | if (y == 66) --x; |
wolfSSL | 15:117db924cf7c | 9111 | |
wolfSSL | 15:117db924cf7c | 9112 | if ((err = mp_read_radix(&order, ecc_sets[x].order, |
wolfSSL | 15:117db924cf7c | 9113 | MP_RADIX_HEX)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9114 | goto done; |
wolfSSL | 15:117db924cf7c | 9115 | } |
wolfSSL | 15:117db924cf7c | 9116 | |
wolfSSL | 15:117db924cf7c | 9117 | /* kB must be less than modulus */ |
wolfSSL | 15:117db924cf7c | 9118 | if (mp_cmp(kB, &order) != MP_LT) { |
wolfSSL | 15:117db924cf7c | 9119 | if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9120 | goto done; |
wolfSSL | 15:117db924cf7c | 9121 | } |
wolfSSL | 15:117db924cf7c | 9122 | } else { |
wolfSSL | 15:117db924cf7c | 9123 | if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9124 | goto done; |
wolfSSL | 15:117db924cf7c | 9125 | } |
wolfSSL | 15:117db924cf7c | 9126 | } |
wolfSSL | 15:117db924cf7c | 9127 | } else { |
wolfSSL | 15:117db924cf7c | 9128 | if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9129 | goto done; |
wolfSSL | 15:117db924cf7c | 9130 | } |
wolfSSL | 15:117db924cf7c | 9131 | } |
wolfSSL | 15:117db924cf7c | 9132 | |
wolfSSL | 15:117db924cf7c | 9133 | /* get bitlen and round up to next multiple of FP_LUT */ |
wolfSSL | 15:117db924cf7c | 9134 | bitlen = mp_unsigned_bin_size(modulus) << 3; |
wolfSSL | 15:117db924cf7c | 9135 | x = bitlen % FP_LUT; |
wolfSSL | 15:117db924cf7c | 9136 | if (x) { |
wolfSSL | 15:117db924cf7c | 9137 | bitlen += FP_LUT - x; |
wolfSSL | 15:117db924cf7c | 9138 | } |
wolfSSL | 15:117db924cf7c | 9139 | lut_gap = bitlen / FP_LUT; |
wolfSSL | 15:117db924cf7c | 9140 | |
wolfSSL | 15:117db924cf7c | 9141 | /* get the k value */ |
wolfSSL | 15:117db924cf7c | 9142 | if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || |
wolfSSL | 15:117db924cf7c | 9143 | (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { |
wolfSSL | 15:117db924cf7c | 9144 | err = BUFFER_E; goto done; |
wolfSSL | 15:117db924cf7c | 9145 | } |
wolfSSL | 15:117db924cf7c | 9146 | |
wolfSSL | 15:117db924cf7c | 9147 | /* store k */ |
wolfSSL | 15:117db924cf7c | 9148 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9149 | kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9150 | if (kb[0] == NULL) { |
wolfSSL | 15:117db924cf7c | 9151 | err = MEMORY_E; goto done; |
wolfSSL | 15:117db924cf7c | 9152 | } |
wolfSSL | 15:117db924cf7c | 9153 | #endif |
wolfSSL | 15:117db924cf7c | 9154 | |
wolfSSL | 15:117db924cf7c | 9155 | XMEMSET(kb[0], 0, KB_SIZE); |
wolfSSL | 15:117db924cf7c | 9156 | if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9157 | goto done; |
wolfSSL | 15:117db924cf7c | 9158 | } |
wolfSSL | 15:117db924cf7c | 9159 | |
wolfSSL | 15:117db924cf7c | 9160 | /* let's reverse kb so it's little endian */ |
wolfSSL | 15:117db924cf7c | 9161 | x = 0; |
wolfSSL | 15:117db924cf7c | 9162 | y = mp_unsigned_bin_size(&tka); |
wolfSSL | 15:117db924cf7c | 9163 | if (y > 0) { |
wolfSSL | 15:117db924cf7c | 9164 | y -= 1; |
wolfSSL | 15:117db924cf7c | 9165 | } |
wolfSSL | 15:117db924cf7c | 9166 | mp_clear(&tka); |
wolfSSL | 15:117db924cf7c | 9167 | while ((unsigned)x < y) { |
wolfSSL | 15:117db924cf7c | 9168 | z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z; |
wolfSSL | 15:117db924cf7c | 9169 | ++x; --y; |
wolfSSL | 15:117db924cf7c | 9170 | } |
wolfSSL | 15:117db924cf7c | 9171 | |
wolfSSL | 15:117db924cf7c | 9172 | /* store b */ |
wolfSSL | 15:117db924cf7c | 9173 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9174 | kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9175 | if (kb[1] == NULL) { |
wolfSSL | 15:117db924cf7c | 9176 | err = MEMORY_E; goto done; |
wolfSSL | 15:117db924cf7c | 9177 | } |
wolfSSL | 15:117db924cf7c | 9178 | #endif |
wolfSSL | 15:117db924cf7c | 9179 | |
wolfSSL | 15:117db924cf7c | 9180 | XMEMSET(kb[1], 0, KB_SIZE); |
wolfSSL | 15:117db924cf7c | 9181 | if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9182 | x = 0; |
wolfSSL | 15:117db924cf7c | 9183 | y = mp_unsigned_bin_size(&tkb); |
wolfSSL | 15:117db924cf7c | 9184 | if (y > 0) { |
wolfSSL | 15:117db924cf7c | 9185 | y -= 1; |
wolfSSL | 15:117db924cf7c | 9186 | } |
wolfSSL | 15:117db924cf7c | 9187 | |
wolfSSL | 15:117db924cf7c | 9188 | while ((unsigned)x < y) { |
wolfSSL | 15:117db924cf7c | 9189 | z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z; |
wolfSSL | 15:117db924cf7c | 9190 | ++x; --y; |
wolfSSL | 15:117db924cf7c | 9191 | } |
wolfSSL | 15:117db924cf7c | 9192 | |
wolfSSL | 15:117db924cf7c | 9193 | /* at this point we can start, yipee */ |
wolfSSL | 15:117db924cf7c | 9194 | first = 1; |
wolfSSL | 15:117db924cf7c | 9195 | for (x = lut_gap-1; x >= 0; x--) { |
wolfSSL | 15:117db924cf7c | 9196 | /* extract FP_LUT bits from kb spread out by lut_gap bits and |
wolfSSL | 15:117db924cf7c | 9197 | offset by x bits from the start */ |
wolfSSL | 15:117db924cf7c | 9198 | bitpos = x; |
wolfSSL | 15:117db924cf7c | 9199 | for (y = zA = zB = 0; y < FP_LUT; y++) { |
wolfSSL | 15:117db924cf7c | 9200 | zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 15:117db924cf7c | 9201 | zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; |
wolfSSL | 15:117db924cf7c | 9202 | bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid |
wolfSSL | 15:117db924cf7c | 9203 | the mult in each loop */ |
wolfSSL | 15:117db924cf7c | 9204 | } |
wolfSSL | 15:117db924cf7c | 9205 | |
wolfSSL | 15:117db924cf7c | 9206 | /* double if not first */ |
wolfSSL | 15:117db924cf7c | 9207 | if (!first) { |
wolfSSL | 15:117db924cf7c | 9208 | if ((err = ecc_projective_dbl_point(R, R, a, modulus, |
wolfSSL | 15:117db924cf7c | 9209 | mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9210 | break; |
wolfSSL | 15:117db924cf7c | 9211 | } |
wolfSSL | 16:8e0d178b1d1e | 9212 | |
wolfSSL | 16:8e0d178b1d1e | 9213 | /* add if not first, otherwise copy */ |
wolfSSL | 15:117db924cf7c | 9214 | if (zA) { |
wolfSSL | 15:117db924cf7c | 9215 | if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], |
wolfSSL | 16:8e0d178b1d1e | 9216 | R, a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9217 | break; |
wolfSSL | 15:117db924cf7c | 9218 | } |
wolfSSL | 16:8e0d178b1d1e | 9219 | if (mp_iszero(R->z)) { |
wolfSSL | 16:8e0d178b1d1e | 9220 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 9221 | if (mp_iszero(R->x) && mp_iszero(R->y)) { |
wolfSSL | 16:8e0d178b1d1e | 9222 | if ((err = ecc_projective_dbl_point( |
wolfSSL | 16:8e0d178b1d1e | 9223 | fp_cache[idx1].LUT[zA], R, |
wolfSSL | 16:8e0d178b1d1e | 9224 | a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9225 | break; |
wolfSSL | 16:8e0d178b1d1e | 9226 | } |
wolfSSL | 16:8e0d178b1d1e | 9227 | } |
wolfSSL | 16:8e0d178b1d1e | 9228 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 9229 | else { |
wolfSSL | 16:8e0d178b1d1e | 9230 | err = mp_set(R->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 9231 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9232 | break; |
wolfSSL | 16:8e0d178b1d1e | 9233 | } |
wolfSSL | 16:8e0d178b1d1e | 9234 | err = mp_set(R->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 9235 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9236 | break; |
wolfSSL | 16:8e0d178b1d1e | 9237 | } |
wolfSSL | 16:8e0d178b1d1e | 9238 | err = mp_copy(&fp_cache[idx1].mu, R->z); |
wolfSSL | 16:8e0d178b1d1e | 9239 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9240 | break; |
wolfSSL | 16:8e0d178b1d1e | 9241 | } |
wolfSSL | 16:8e0d178b1d1e | 9242 | first = 1; |
wolfSSL | 16:8e0d178b1d1e | 9243 | } |
wolfSSL | 16:8e0d178b1d1e | 9244 | } |
wolfSSL | 15:117db924cf7c | 9245 | } |
wolfSSL | 16:8e0d178b1d1e | 9246 | |
wolfSSL | 15:117db924cf7c | 9247 | if (zB) { |
wolfSSL | 15:117db924cf7c | 9248 | if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], |
wolfSSL | 16:8e0d178b1d1e | 9249 | R, a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9250 | break; |
wolfSSL | 15:117db924cf7c | 9251 | } |
wolfSSL | 16:8e0d178b1d1e | 9252 | if (mp_iszero(R->z)) { |
wolfSSL | 16:8e0d178b1d1e | 9253 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 9254 | if (mp_iszero(R->x) && mp_iszero(R->y)) { |
wolfSSL | 16:8e0d178b1d1e | 9255 | if ((err = ecc_projective_dbl_point( |
wolfSSL | 16:8e0d178b1d1e | 9256 | fp_cache[idx2].LUT[zB], R, |
wolfSSL | 16:8e0d178b1d1e | 9257 | a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9258 | break; |
wolfSSL | 16:8e0d178b1d1e | 9259 | } |
wolfSSL | 16:8e0d178b1d1e | 9260 | } |
wolfSSL | 16:8e0d178b1d1e | 9261 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 9262 | else { |
wolfSSL | 16:8e0d178b1d1e | 9263 | err = mp_set(R->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 9264 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9265 | break; |
wolfSSL | 16:8e0d178b1d1e | 9266 | } |
wolfSSL | 16:8e0d178b1d1e | 9267 | err = mp_set(R->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 9268 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9269 | break; |
wolfSSL | 16:8e0d178b1d1e | 9270 | } |
wolfSSL | 16:8e0d178b1d1e | 9271 | err = mp_copy(&fp_cache[idx2].mu, R->z); |
wolfSSL | 16:8e0d178b1d1e | 9272 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9273 | break; |
wolfSSL | 16:8e0d178b1d1e | 9274 | } |
wolfSSL | 16:8e0d178b1d1e | 9275 | first = 1; |
wolfSSL | 16:8e0d178b1d1e | 9276 | } |
wolfSSL | 16:8e0d178b1d1e | 9277 | } |
wolfSSL | 15:117db924cf7c | 9278 | } |
wolfSSL | 15:117db924cf7c | 9279 | } else { |
wolfSSL | 15:117db924cf7c | 9280 | if (zA) { |
wolfSSL | 15:117db924cf7c | 9281 | if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || |
wolfSSL | 16:8e0d178b1d1e | 9282 | (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || |
wolfSSL | 16:8e0d178b1d1e | 9283 | (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { |
wolfSSL | 15:117db924cf7c | 9284 | err = GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 9285 | break; |
wolfSSL | 15:117db924cf7c | 9286 | } |
wolfSSL | 15:117db924cf7c | 9287 | first = 0; |
wolfSSL | 15:117db924cf7c | 9288 | } |
wolfSSL | 15:117db924cf7c | 9289 | if (zB && first == 0) { |
wolfSSL | 15:117db924cf7c | 9290 | if (zB) { |
wolfSSL | 15:117db924cf7c | 9291 | if ((err = ecc_projective_add_point(R, |
wolfSSL | 16:8e0d178b1d1e | 9292 | fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){ |
wolfSSL | 15:117db924cf7c | 9293 | break; |
wolfSSL | 15:117db924cf7c | 9294 | } |
wolfSSL | 16:8e0d178b1d1e | 9295 | if (mp_iszero(R->z)) { |
wolfSSL | 16:8e0d178b1d1e | 9296 | /* When all zero then should have done an add */ |
wolfSSL | 16:8e0d178b1d1e | 9297 | if (mp_iszero(R->x) && mp_iszero(R->y)) { |
wolfSSL | 16:8e0d178b1d1e | 9298 | if ((err = ecc_projective_dbl_point( |
wolfSSL | 16:8e0d178b1d1e | 9299 | fp_cache[idx2].LUT[zB], R, |
wolfSSL | 16:8e0d178b1d1e | 9300 | a, modulus, mp)) != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9301 | break; |
wolfSSL | 16:8e0d178b1d1e | 9302 | } |
wolfSSL | 16:8e0d178b1d1e | 9303 | } |
wolfSSL | 16:8e0d178b1d1e | 9304 | /* When only Z zero then result is infinity */ |
wolfSSL | 16:8e0d178b1d1e | 9305 | else { |
wolfSSL | 16:8e0d178b1d1e | 9306 | err = mp_set(R->x, 0); |
wolfSSL | 16:8e0d178b1d1e | 9307 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9308 | break; |
wolfSSL | 16:8e0d178b1d1e | 9309 | } |
wolfSSL | 16:8e0d178b1d1e | 9310 | err = mp_set(R->y, 0); |
wolfSSL | 16:8e0d178b1d1e | 9311 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9312 | break; |
wolfSSL | 16:8e0d178b1d1e | 9313 | } |
wolfSSL | 16:8e0d178b1d1e | 9314 | err = mp_copy(&fp_cache[idx2].mu, R->z); |
wolfSSL | 16:8e0d178b1d1e | 9315 | if (err != MP_OKAY) { |
wolfSSL | 16:8e0d178b1d1e | 9316 | break; |
wolfSSL | 16:8e0d178b1d1e | 9317 | } |
wolfSSL | 16:8e0d178b1d1e | 9318 | first = 1; |
wolfSSL | 16:8e0d178b1d1e | 9319 | } |
wolfSSL | 16:8e0d178b1d1e | 9320 | } |
wolfSSL | 15:117db924cf7c | 9321 | } |
wolfSSL | 15:117db924cf7c | 9322 | } else if (zB && first == 1) { |
wolfSSL | 15:117db924cf7c | 9323 | if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || |
wolfSSL | 16:8e0d178b1d1e | 9324 | (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || |
wolfSSL | 16:8e0d178b1d1e | 9325 | (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { |
wolfSSL | 15:117db924cf7c | 9326 | err = GEN_MEM_ERR; |
wolfSSL | 15:117db924cf7c | 9327 | break; |
wolfSSL | 15:117db924cf7c | 9328 | } |
wolfSSL | 15:117db924cf7c | 9329 | first = 0; |
wolfSSL | 15:117db924cf7c | 9330 | } |
wolfSSL | 15:117db924cf7c | 9331 | } |
wolfSSL | 15:117db924cf7c | 9332 | } |
wolfSSL | 15:117db924cf7c | 9333 | } |
wolfSSL | 15:117db924cf7c | 9334 | |
wolfSSL | 15:117db924cf7c | 9335 | done: |
wolfSSL | 15:117db924cf7c | 9336 | /* cleanup */ |
wolfSSL | 15:117db924cf7c | 9337 | mp_clear(&tkb); |
wolfSSL | 15:117db924cf7c | 9338 | mp_clear(&tka); |
wolfSSL | 15:117db924cf7c | 9339 | mp_clear(&order); |
wolfSSL | 15:117db924cf7c | 9340 | |
wolfSSL | 15:117db924cf7c | 9341 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9342 | if (kb[0]) |
wolfSSL | 15:117db924cf7c | 9343 | #endif |
wolfSSL | 15:117db924cf7c | 9344 | ForceZero(kb[0], KB_SIZE); |
wolfSSL | 15:117db924cf7c | 9345 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9346 | if (kb[1]) |
wolfSSL | 15:117db924cf7c | 9347 | #endif |
wolfSSL | 15:117db924cf7c | 9348 | ForceZero(kb[1], KB_SIZE); |
wolfSSL | 15:117db924cf7c | 9349 | |
wolfSSL | 15:117db924cf7c | 9350 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9351 | XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9352 | XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9353 | #endif |
wolfSSL | 15:117db924cf7c | 9354 | |
wolfSSL | 15:117db924cf7c | 9355 | #undef KB_SIZE |
wolfSSL | 15:117db924cf7c | 9356 | |
wolfSSL | 15:117db924cf7c | 9357 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9358 | return err; |
wolfSSL | 15:117db924cf7c | 9359 | |
wolfSSL | 15:117db924cf7c | 9360 | return ecc_map(R, modulus, mp); |
wolfSSL | 15:117db924cf7c | 9361 | } |
wolfSSL | 15:117db924cf7c | 9362 | |
wolfSSL | 15:117db924cf7c | 9363 | |
wolfSSL | 15:117db924cf7c | 9364 | /** ECC Fixed Point mulmod global with heap hint used |
wolfSSL | 15:117db924cf7c | 9365 | Computes kA*A + kB*B = C using Shamir's Trick |
wolfSSL | 15:117db924cf7c | 9366 | A First point to multiply |
wolfSSL | 15:117db924cf7c | 9367 | kA What to multiple A by |
wolfSSL | 15:117db924cf7c | 9368 | B Second point to multiply |
wolfSSL | 15:117db924cf7c | 9369 | kB What to multiple B by |
wolfSSL | 15:117db924cf7c | 9370 | C [out] Destination point (can overlap with A or B) |
wolfSSL | 15:117db924cf7c | 9371 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 9372 | modulus Modulus for curve |
wolfSSL | 15:117db924cf7c | 9373 | return MP_OKAY on success |
wolfSSL | 15:117db924cf7c | 9374 | */ |
wolfSSL | 15:117db924cf7c | 9375 | int ecc_mul2add(ecc_point* A, mp_int* kA, |
wolfSSL | 15:117db924cf7c | 9376 | ecc_point* B, mp_int* kB, |
wolfSSL | 15:117db924cf7c | 9377 | ecc_point* C, mp_int* a, mp_int* modulus, void* heap) |
wolfSSL | 15:117db924cf7c | 9378 | { |
wolfSSL | 16:8e0d178b1d1e | 9379 | int idx1 = -1, idx2 = -1, err, mpInit = 0; |
wolfSSL | 15:117db924cf7c | 9380 | mp_digit mp; |
wolfSSL | 15:117db924cf7c | 9381 | mp_int mu; |
wolfSSL | 15:117db924cf7c | 9382 | |
wolfSSL | 15:117db924cf7c | 9383 | err = mp_init(&mu); |
wolfSSL | 15:117db924cf7c | 9384 | if (err != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9385 | return err; |
wolfSSL | 15:117db924cf7c | 9386 | |
wolfSSL | 15:117db924cf7c | 9387 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9388 | if (initMutex == 0) { |
wolfSSL | 15:117db924cf7c | 9389 | wc_InitMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9390 | initMutex = 1; |
wolfSSL | 15:117db924cf7c | 9391 | } |
wolfSSL | 15:117db924cf7c | 9392 | if (wc_LockMutex(&ecc_fp_lock) != 0) |
wolfSSL | 15:117db924cf7c | 9393 | return BAD_MUTEX_E; |
wolfSSL | 15:117db924cf7c | 9394 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9395 | |
wolfSSL | 15:117db924cf7c | 9396 | /* find point */ |
wolfSSL | 15:117db924cf7c | 9397 | idx1 = find_base(A); |
wolfSSL | 15:117db924cf7c | 9398 | |
wolfSSL | 15:117db924cf7c | 9399 | /* no entry? */ |
wolfSSL | 15:117db924cf7c | 9400 | if (idx1 == -1) { |
wolfSSL | 15:117db924cf7c | 9401 | /* find hole and add it */ |
wolfSSL | 15:117db924cf7c | 9402 | if ((idx1 = find_hole()) >= 0) { |
wolfSSL | 15:117db924cf7c | 9403 | err = add_entry(idx1, A); |
wolfSSL | 15:117db924cf7c | 9404 | } |
wolfSSL | 15:117db924cf7c | 9405 | } |
wolfSSL | 15:117db924cf7c | 9406 | if (err == MP_OKAY && idx1 != -1) { |
wolfSSL | 15:117db924cf7c | 9407 | /* increment LRU */ |
wolfSSL | 15:117db924cf7c | 9408 | ++(fp_cache[idx1].lru_count); |
wolfSSL | 15:117db924cf7c | 9409 | } |
wolfSSL | 15:117db924cf7c | 9410 | |
wolfSSL | 16:8e0d178b1d1e | 9411 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9412 | /* find point */ |
wolfSSL | 15:117db924cf7c | 9413 | idx2 = find_base(B); |
wolfSSL | 15:117db924cf7c | 9414 | |
wolfSSL | 15:117db924cf7c | 9415 | /* no entry? */ |
wolfSSL | 15:117db924cf7c | 9416 | if (idx2 == -1) { |
wolfSSL | 15:117db924cf7c | 9417 | /* find hole and add it */ |
wolfSSL | 15:117db924cf7c | 9418 | if ((idx2 = find_hole()) >= 0) |
wolfSSL | 15:117db924cf7c | 9419 | err = add_entry(idx2, B); |
wolfSSL | 15:117db924cf7c | 9420 | } |
wolfSSL | 15:117db924cf7c | 9421 | } |
wolfSSL | 15:117db924cf7c | 9422 | |
wolfSSL | 15:117db924cf7c | 9423 | if (err == MP_OKAY && idx2 != -1) { |
wolfSSL | 15:117db924cf7c | 9424 | /* increment LRU */ |
wolfSSL | 15:117db924cf7c | 9425 | ++(fp_cache[idx2].lru_count); |
wolfSSL | 15:117db924cf7c | 9426 | } |
wolfSSL | 15:117db924cf7c | 9427 | |
wolfSSL | 15:117db924cf7c | 9428 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9429 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 15:117db924cf7c | 9430 | if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { |
wolfSSL | 15:117db924cf7c | 9431 | /* compute mp */ |
wolfSSL | 15:117db924cf7c | 9432 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 9433 | |
wolfSSL | 15:117db924cf7c | 9434 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9435 | mpInit = 1; |
wolfSSL | 15:117db924cf7c | 9436 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 15:117db924cf7c | 9437 | } |
wolfSSL | 15:117db924cf7c | 9438 | |
wolfSSL | 15:117db924cf7c | 9439 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9440 | /* build the LUT */ |
wolfSSL | 15:117db924cf7c | 9441 | err = build_lut(idx1, a, modulus, mp, &mu); |
wolfSSL | 15:117db924cf7c | 9442 | } |
wolfSSL | 15:117db924cf7c | 9443 | } |
wolfSSL | 15:117db924cf7c | 9444 | |
wolfSSL | 15:117db924cf7c | 9445 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9446 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 15:117db924cf7c | 9447 | if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { |
wolfSSL | 15:117db924cf7c | 9448 | if (mpInit == 0) { |
wolfSSL | 15:117db924cf7c | 9449 | /* compute mp */ |
wolfSSL | 15:117db924cf7c | 9450 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 9451 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9452 | mpInit = 1; |
wolfSSL | 15:117db924cf7c | 9453 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 15:117db924cf7c | 9454 | } |
wolfSSL | 15:117db924cf7c | 9455 | } |
wolfSSL | 15:117db924cf7c | 9456 | |
wolfSSL | 15:117db924cf7c | 9457 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9458 | /* build the LUT */ |
wolfSSL | 15:117db924cf7c | 9459 | err = build_lut(idx2, a, modulus, mp, &mu); |
wolfSSL | 15:117db924cf7c | 9460 | } |
wolfSSL | 15:117db924cf7c | 9461 | } |
wolfSSL | 15:117db924cf7c | 9462 | |
wolfSSL | 15:117db924cf7c | 9463 | |
wolfSSL | 15:117db924cf7c | 9464 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9465 | if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && |
wolfSSL | 15:117db924cf7c | 9466 | fp_cache[idx2].lru_count >= 2) { |
wolfSSL | 15:117db924cf7c | 9467 | if (mpInit == 0) { |
wolfSSL | 15:117db924cf7c | 9468 | /* compute mp */ |
wolfSSL | 15:117db924cf7c | 9469 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 9470 | } |
wolfSSL | 15:117db924cf7c | 9471 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9472 | err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp); |
wolfSSL | 15:117db924cf7c | 9473 | } else { |
wolfSSL | 15:117db924cf7c | 9474 | err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap); |
wolfSSL | 15:117db924cf7c | 9475 | } |
wolfSSL | 15:117db924cf7c | 9476 | } |
wolfSSL | 15:117db924cf7c | 9477 | |
wolfSSL | 15:117db924cf7c | 9478 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9479 | wc_UnLockMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9480 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9481 | mp_clear(&mu); |
wolfSSL | 15:117db924cf7c | 9482 | |
wolfSSL | 15:117db924cf7c | 9483 | return err; |
wolfSSL | 15:117db924cf7c | 9484 | } |
wolfSSL | 15:117db924cf7c | 9485 | #endif |
wolfSSL | 15:117db924cf7c | 9486 | #endif /* ECC_SHAMIR */ |
wolfSSL | 15:117db924cf7c | 9487 | |
wolfSSL | 15:117db924cf7c | 9488 | /** ECC Fixed Point mulmod global |
wolfSSL | 15:117db924cf7c | 9489 | k The multiplicand |
wolfSSL | 15:117db924cf7c | 9490 | G Base point to multiply |
wolfSSL | 15:117db924cf7c | 9491 | R [out] Destination of product |
wolfSSL | 15:117db924cf7c | 9492 | a ECC curve parameter a |
wolfSSL | 15:117db924cf7c | 9493 | modulus The modulus for the curve |
wolfSSL | 16:8e0d178b1d1e | 9494 | map [boolean] If non-zero maps the point back to affine coordinates, |
wolfSSL | 15:117db924cf7c | 9495 | otherwise it's left in jacobian-montgomery form |
wolfSSL | 15:117db924cf7c | 9496 | return MP_OKAY if successful |
wolfSSL | 15:117db924cf7c | 9497 | */ |
wolfSSL | 15:117db924cf7c | 9498 | int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, |
wolfSSL | 15:117db924cf7c | 9499 | mp_int* modulus, int map, void* heap) |
wolfSSL | 15:117db924cf7c | 9500 | { |
wolfSSL | 15:117db924cf7c | 9501 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 9502 | int idx, err = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 9503 | mp_digit mp; |
wolfSSL | 15:117db924cf7c | 9504 | mp_int mu; |
wolfSSL | 15:117db924cf7c | 9505 | int mpSetup = 0; |
wolfSSL | 15:117db924cf7c | 9506 | |
wolfSSL | 15:117db924cf7c | 9507 | if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 9508 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 9509 | } |
wolfSSL | 15:117db924cf7c | 9510 | |
wolfSSL | 15:117db924cf7c | 9511 | if (mp_init(&mu) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9512 | return MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 9513 | |
wolfSSL | 15:117db924cf7c | 9514 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9515 | if (initMutex == 0) { |
wolfSSL | 15:117db924cf7c | 9516 | wc_InitMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9517 | initMutex = 1; |
wolfSSL | 15:117db924cf7c | 9518 | } |
wolfSSL | 15:117db924cf7c | 9519 | |
wolfSSL | 15:117db924cf7c | 9520 | if (wc_LockMutex(&ecc_fp_lock) != 0) |
wolfSSL | 15:117db924cf7c | 9521 | return BAD_MUTEX_E; |
wolfSSL | 15:117db924cf7c | 9522 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9523 | |
wolfSSL | 15:117db924cf7c | 9524 | /* find point */ |
wolfSSL | 15:117db924cf7c | 9525 | idx = find_base(G); |
wolfSSL | 15:117db924cf7c | 9526 | |
wolfSSL | 15:117db924cf7c | 9527 | /* no entry? */ |
wolfSSL | 15:117db924cf7c | 9528 | if (idx == -1) { |
wolfSSL | 15:117db924cf7c | 9529 | /* find hole and add it */ |
wolfSSL | 15:117db924cf7c | 9530 | idx = find_hole(); |
wolfSSL | 15:117db924cf7c | 9531 | |
wolfSSL | 15:117db924cf7c | 9532 | if (idx >= 0) |
wolfSSL | 15:117db924cf7c | 9533 | err = add_entry(idx, G); |
wolfSSL | 15:117db924cf7c | 9534 | } |
wolfSSL | 15:117db924cf7c | 9535 | if (err == MP_OKAY && idx >= 0) { |
wolfSSL | 15:117db924cf7c | 9536 | /* increment LRU */ |
wolfSSL | 15:117db924cf7c | 9537 | ++(fp_cache[idx].lru_count); |
wolfSSL | 15:117db924cf7c | 9538 | } |
wolfSSL | 15:117db924cf7c | 9539 | |
wolfSSL | 15:117db924cf7c | 9540 | |
wolfSSL | 15:117db924cf7c | 9541 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9542 | /* if it's 2 build the LUT, if it's higher just use the LUT */ |
wolfSSL | 15:117db924cf7c | 9543 | if (idx >= 0 && fp_cache[idx].lru_count == 2) { |
wolfSSL | 15:117db924cf7c | 9544 | /* compute mp */ |
wolfSSL | 15:117db924cf7c | 9545 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 9546 | |
wolfSSL | 15:117db924cf7c | 9547 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9548 | /* compute mu */ |
wolfSSL | 15:117db924cf7c | 9549 | mpSetup = 1; |
wolfSSL | 15:117db924cf7c | 9550 | err = mp_montgomery_calc_normalization(&mu, modulus); |
wolfSSL | 15:117db924cf7c | 9551 | } |
wolfSSL | 15:117db924cf7c | 9552 | |
wolfSSL | 15:117db924cf7c | 9553 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9554 | /* build the LUT */ |
wolfSSL | 15:117db924cf7c | 9555 | err = build_lut(idx, a, modulus, mp, &mu); |
wolfSSL | 15:117db924cf7c | 9556 | } |
wolfSSL | 15:117db924cf7c | 9557 | } |
wolfSSL | 15:117db924cf7c | 9558 | |
wolfSSL | 15:117db924cf7c | 9559 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 9560 | if (idx >= 0 && fp_cache[idx].lru_count >= 2) { |
wolfSSL | 15:117db924cf7c | 9561 | if (mpSetup == 0) { |
wolfSSL | 15:117db924cf7c | 9562 | /* compute mp */ |
wolfSSL | 15:117db924cf7c | 9563 | err = mp_montgomery_setup(modulus, &mp); |
wolfSSL | 15:117db924cf7c | 9564 | } |
wolfSSL | 15:117db924cf7c | 9565 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 9566 | err = accel_fp_mul(idx, k, R, a, modulus, mp, map); |
wolfSSL | 15:117db924cf7c | 9567 | } else { |
wolfSSL | 15:117db924cf7c | 9568 | err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap); |
wolfSSL | 15:117db924cf7c | 9569 | } |
wolfSSL | 15:117db924cf7c | 9570 | } |
wolfSSL | 15:117db924cf7c | 9571 | |
wolfSSL | 15:117db924cf7c | 9572 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9573 | wc_UnLockMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9574 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9575 | mp_clear(&mu); |
wolfSSL | 15:117db924cf7c | 9576 | |
wolfSSL | 15:117db924cf7c | 9577 | return err; |
wolfSSL | 15:117db924cf7c | 9578 | #else |
wolfSSL | 15:117db924cf7c | 9579 | if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) { |
wolfSSL | 15:117db924cf7c | 9580 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 9581 | } |
wolfSSL | 15:117db924cf7c | 9582 | |
wolfSSL | 16:8e0d178b1d1e | 9583 | #ifndef WOLFSSL_SP_NO_256 |
wolfSSL | 16:8e0d178b1d1e | 9584 | if (mp_count_bits(modulus) == 256) { |
wolfSSL | 16:8e0d178b1d1e | 9585 | return sp_ecc_mulmod_256(k, G, R, map, heap); |
wolfSSL | 16:8e0d178b1d1e | 9586 | } |
wolfSSL | 16:8e0d178b1d1e | 9587 | #endif |
wolfSSL | 16:8e0d178b1d1e | 9588 | #ifdef WOLFSSL_SP_384 |
wolfSSL | 16:8e0d178b1d1e | 9589 | if (mp_count_bits(modulus) == 384) { |
wolfSSL | 16:8e0d178b1d1e | 9590 | return sp_ecc_mulmod_384(k, G, R, map, heap); |
wolfSSL | 16:8e0d178b1d1e | 9591 | } |
wolfSSL | 16:8e0d178b1d1e | 9592 | #endif |
wolfSSL | 16:8e0d178b1d1e | 9593 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 9594 | #endif |
wolfSSL | 15:117db924cf7c | 9595 | } |
wolfSSL | 15:117db924cf7c | 9596 | |
wolfSSL | 15:117db924cf7c | 9597 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 9598 | /* helper function for freeing the cache ... |
wolfSSL | 15:117db924cf7c | 9599 | must be called with the cache mutex locked */ |
wolfSSL | 15:117db924cf7c | 9600 | static void wc_ecc_fp_free_cache(void) |
wolfSSL | 15:117db924cf7c | 9601 | { |
wolfSSL | 15:117db924cf7c | 9602 | unsigned x, y; |
wolfSSL | 15:117db924cf7c | 9603 | for (x = 0; x < FP_ENTRIES; x++) { |
wolfSSL | 15:117db924cf7c | 9604 | if (fp_cache[x].g != NULL) { |
wolfSSL | 15:117db924cf7c | 9605 | for (y = 0; y < (1U<<FP_LUT); y++) { |
wolfSSL | 15:117db924cf7c | 9606 | wc_ecc_del_point(fp_cache[x].LUT[y]); |
wolfSSL | 15:117db924cf7c | 9607 | fp_cache[x].LUT[y] = NULL; |
wolfSSL | 15:117db924cf7c | 9608 | } |
wolfSSL | 15:117db924cf7c | 9609 | wc_ecc_del_point(fp_cache[x].g); |
wolfSSL | 15:117db924cf7c | 9610 | fp_cache[x].g = NULL; |
wolfSSL | 15:117db924cf7c | 9611 | mp_clear(&fp_cache[x].mu); |
wolfSSL | 15:117db924cf7c | 9612 | fp_cache[x].lru_count = 0; |
wolfSSL | 15:117db924cf7c | 9613 | fp_cache[x].lock = 0; |
wolfSSL | 15:117db924cf7c | 9614 | } |
wolfSSL | 15:117db924cf7c | 9615 | } |
wolfSSL | 15:117db924cf7c | 9616 | } |
wolfSSL | 15:117db924cf7c | 9617 | #endif |
wolfSSL | 15:117db924cf7c | 9618 | |
wolfSSL | 15:117db924cf7c | 9619 | /** Free the Fixed Point cache */ |
wolfSSL | 15:117db924cf7c | 9620 | void wc_ecc_fp_free(void) |
wolfSSL | 15:117db924cf7c | 9621 | { |
wolfSSL | 15:117db924cf7c | 9622 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 9623 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9624 | if (initMutex == 0) { |
wolfSSL | 15:117db924cf7c | 9625 | wc_InitMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9626 | initMutex = 1; |
wolfSSL | 15:117db924cf7c | 9627 | } |
wolfSSL | 15:117db924cf7c | 9628 | |
wolfSSL | 15:117db924cf7c | 9629 | if (wc_LockMutex(&ecc_fp_lock) == 0) { |
wolfSSL | 15:117db924cf7c | 9630 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9631 | |
wolfSSL | 15:117db924cf7c | 9632 | wc_ecc_fp_free_cache(); |
wolfSSL | 15:117db924cf7c | 9633 | |
wolfSSL | 15:117db924cf7c | 9634 | #ifndef HAVE_THREAD_LS |
wolfSSL | 15:117db924cf7c | 9635 | wc_UnLockMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9636 | wc_FreeMutex(&ecc_fp_lock); |
wolfSSL | 15:117db924cf7c | 9637 | initMutex = 0; |
wolfSSL | 15:117db924cf7c | 9638 | } |
wolfSSL | 15:117db924cf7c | 9639 | #endif /* HAVE_THREAD_LS */ |
wolfSSL | 15:117db924cf7c | 9640 | #endif |
wolfSSL | 15:117db924cf7c | 9641 | } |
wolfSSL | 15:117db924cf7c | 9642 | |
wolfSSL | 15:117db924cf7c | 9643 | |
wolfSSL | 15:117db924cf7c | 9644 | #endif /* FP_ECC */ |
wolfSSL | 15:117db924cf7c | 9645 | |
wolfSSL | 15:117db924cf7c | 9646 | #ifdef HAVE_ECC_ENCRYPT |
wolfSSL | 15:117db924cf7c | 9647 | |
wolfSSL | 15:117db924cf7c | 9648 | |
wolfSSL | 15:117db924cf7c | 9649 | enum ecCliState { |
wolfSSL | 15:117db924cf7c | 9650 | ecCLI_INIT = 1, |
wolfSSL | 15:117db924cf7c | 9651 | ecCLI_SALT_GET = 2, |
wolfSSL | 15:117db924cf7c | 9652 | ecCLI_SALT_SET = 3, |
wolfSSL | 15:117db924cf7c | 9653 | ecCLI_SENT_REQ = 4, |
wolfSSL | 15:117db924cf7c | 9654 | ecCLI_RECV_RESP = 5, |
wolfSSL | 15:117db924cf7c | 9655 | ecCLI_BAD_STATE = 99 |
wolfSSL | 15:117db924cf7c | 9656 | }; |
wolfSSL | 15:117db924cf7c | 9657 | |
wolfSSL | 15:117db924cf7c | 9658 | enum ecSrvState { |
wolfSSL | 15:117db924cf7c | 9659 | ecSRV_INIT = 1, |
wolfSSL | 15:117db924cf7c | 9660 | ecSRV_SALT_GET = 2, |
wolfSSL | 15:117db924cf7c | 9661 | ecSRV_SALT_SET = 3, |
wolfSSL | 15:117db924cf7c | 9662 | ecSRV_RECV_REQ = 4, |
wolfSSL | 15:117db924cf7c | 9663 | ecSRV_SENT_RESP = 5, |
wolfSSL | 15:117db924cf7c | 9664 | ecSRV_BAD_STATE = 99 |
wolfSSL | 15:117db924cf7c | 9665 | }; |
wolfSSL | 15:117db924cf7c | 9666 | |
wolfSSL | 15:117db924cf7c | 9667 | |
wolfSSL | 15:117db924cf7c | 9668 | struct ecEncCtx { |
wolfSSL | 15:117db924cf7c | 9669 | const byte* kdfSalt; /* optional salt for kdf */ |
wolfSSL | 15:117db924cf7c | 9670 | const byte* kdfInfo; /* optional info for kdf */ |
wolfSSL | 15:117db924cf7c | 9671 | const byte* macSalt; /* optional salt for mac */ |
wolfSSL | 15:117db924cf7c | 9672 | word32 kdfSaltSz; /* size of kdfSalt */ |
wolfSSL | 15:117db924cf7c | 9673 | word32 kdfInfoSz; /* size of kdfInfo */ |
wolfSSL | 15:117db924cf7c | 9674 | word32 macSaltSz; /* size of macSalt */ |
wolfSSL | 15:117db924cf7c | 9675 | void* heap; /* heap hint for memory used */ |
wolfSSL | 15:117db924cf7c | 9676 | byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ |
wolfSSL | 15:117db924cf7c | 9677 | byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ |
wolfSSL | 15:117db924cf7c | 9678 | byte encAlgo; /* which encryption type */ |
wolfSSL | 15:117db924cf7c | 9679 | byte kdfAlgo; /* which key derivation function type */ |
wolfSSL | 15:117db924cf7c | 9680 | byte macAlgo; /* which mac function type */ |
wolfSSL | 15:117db924cf7c | 9681 | byte protocol; /* are we REQ_RESP client or server ? */ |
wolfSSL | 15:117db924cf7c | 9682 | byte cliSt; /* protocol state, for sanity checks */ |
wolfSSL | 15:117db924cf7c | 9683 | byte srvSt; /* protocol state, for sanity checks */ |
wolfSSL | 15:117db924cf7c | 9684 | }; |
wolfSSL | 15:117db924cf7c | 9685 | |
wolfSSL | 15:117db924cf7c | 9686 | |
wolfSSL | 15:117db924cf7c | 9687 | const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx) |
wolfSSL | 15:117db924cf7c | 9688 | { |
wolfSSL | 15:117db924cf7c | 9689 | if (ctx == NULL || ctx->protocol == 0) |
wolfSSL | 15:117db924cf7c | 9690 | return NULL; |
wolfSSL | 15:117db924cf7c | 9691 | |
wolfSSL | 15:117db924cf7c | 9692 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 15:117db924cf7c | 9693 | if (ctx->cliSt == ecCLI_INIT) { |
wolfSSL | 15:117db924cf7c | 9694 | ctx->cliSt = ecCLI_SALT_GET; |
wolfSSL | 15:117db924cf7c | 9695 | return ctx->clientSalt; |
wolfSSL | 15:117db924cf7c | 9696 | } |
wolfSSL | 15:117db924cf7c | 9697 | else { |
wolfSSL | 15:117db924cf7c | 9698 | ctx->cliSt = ecCLI_BAD_STATE; |
wolfSSL | 15:117db924cf7c | 9699 | return NULL; |
wolfSSL | 15:117db924cf7c | 9700 | } |
wolfSSL | 15:117db924cf7c | 9701 | } |
wolfSSL | 15:117db924cf7c | 9702 | else if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 15:117db924cf7c | 9703 | if (ctx->srvSt == ecSRV_INIT) { |
wolfSSL | 15:117db924cf7c | 9704 | ctx->srvSt = ecSRV_SALT_GET; |
wolfSSL | 15:117db924cf7c | 9705 | return ctx->serverSalt; |
wolfSSL | 15:117db924cf7c | 9706 | } |
wolfSSL | 15:117db924cf7c | 9707 | else { |
wolfSSL | 15:117db924cf7c | 9708 | ctx->srvSt = ecSRV_BAD_STATE; |
wolfSSL | 15:117db924cf7c | 9709 | return NULL; |
wolfSSL | 15:117db924cf7c | 9710 | } |
wolfSSL | 15:117db924cf7c | 9711 | } |
wolfSSL | 15:117db924cf7c | 9712 | |
wolfSSL | 15:117db924cf7c | 9713 | return NULL; |
wolfSSL | 15:117db924cf7c | 9714 | } |
wolfSSL | 15:117db924cf7c | 9715 | |
wolfSSL | 15:117db924cf7c | 9716 | |
wolfSSL | 15:117db924cf7c | 9717 | /* optional set info, can be called before or after set_peer_salt */ |
wolfSSL | 15:117db924cf7c | 9718 | int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) |
wolfSSL | 15:117db924cf7c | 9719 | { |
wolfSSL | 15:117db924cf7c | 9720 | if (ctx == NULL || info == 0 || sz < 0) |
wolfSSL | 15:117db924cf7c | 9721 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9722 | |
wolfSSL | 15:117db924cf7c | 9723 | ctx->kdfInfo = info; |
wolfSSL | 15:117db924cf7c | 9724 | ctx->kdfInfoSz = sz; |
wolfSSL | 15:117db924cf7c | 9725 | |
wolfSSL | 15:117db924cf7c | 9726 | return 0; |
wolfSSL | 15:117db924cf7c | 9727 | } |
wolfSSL | 15:117db924cf7c | 9728 | |
wolfSSL | 15:117db924cf7c | 9729 | |
wolfSSL | 15:117db924cf7c | 9730 | static const char* exchange_info = "Secure Message Exchange"; |
wolfSSL | 15:117db924cf7c | 9731 | |
wolfSSL | 15:117db924cf7c | 9732 | int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) |
wolfSSL | 15:117db924cf7c | 9733 | { |
wolfSSL | 15:117db924cf7c | 9734 | byte tmp[EXCHANGE_SALT_SZ/2]; |
wolfSSL | 15:117db924cf7c | 9735 | int halfSz = EXCHANGE_SALT_SZ/2; |
wolfSSL | 15:117db924cf7c | 9736 | |
wolfSSL | 15:117db924cf7c | 9737 | if (ctx == NULL || ctx->protocol == 0 || salt == NULL) |
wolfSSL | 15:117db924cf7c | 9738 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9739 | |
wolfSSL | 15:117db924cf7c | 9740 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 15:117db924cf7c | 9741 | XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); |
wolfSSL | 15:117db924cf7c | 9742 | if (ctx->cliSt == ecCLI_SALT_GET) |
wolfSSL | 15:117db924cf7c | 9743 | ctx->cliSt = ecCLI_SALT_SET; |
wolfSSL | 15:117db924cf7c | 9744 | else { |
wolfSSL | 15:117db924cf7c | 9745 | ctx->cliSt = ecCLI_BAD_STATE; |
wolfSSL | 15:117db924cf7c | 9746 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 9747 | } |
wolfSSL | 15:117db924cf7c | 9748 | } |
wolfSSL | 15:117db924cf7c | 9749 | else { |
wolfSSL | 15:117db924cf7c | 9750 | XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); |
wolfSSL | 15:117db924cf7c | 9751 | if (ctx->srvSt == ecSRV_SALT_GET) |
wolfSSL | 15:117db924cf7c | 9752 | ctx->srvSt = ecSRV_SALT_SET; |
wolfSSL | 15:117db924cf7c | 9753 | else { |
wolfSSL | 15:117db924cf7c | 9754 | ctx->srvSt = ecSRV_BAD_STATE; |
wolfSSL | 15:117db924cf7c | 9755 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 9756 | } |
wolfSSL | 15:117db924cf7c | 9757 | } |
wolfSSL | 15:117db924cf7c | 9758 | |
wolfSSL | 15:117db924cf7c | 9759 | /* mix half and half */ |
wolfSSL | 15:117db924cf7c | 9760 | /* tmp stores 2nd half of client before overwrite */ |
wolfSSL | 15:117db924cf7c | 9761 | XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); |
wolfSSL | 15:117db924cf7c | 9762 | XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); |
wolfSSL | 15:117db924cf7c | 9763 | XMEMCPY(ctx->serverSalt, tmp, halfSz); |
wolfSSL | 15:117db924cf7c | 9764 | |
wolfSSL | 15:117db924cf7c | 9765 | ctx->kdfSalt = ctx->clientSalt; |
wolfSSL | 15:117db924cf7c | 9766 | ctx->kdfSaltSz = EXCHANGE_SALT_SZ; |
wolfSSL | 15:117db924cf7c | 9767 | |
wolfSSL | 15:117db924cf7c | 9768 | ctx->macSalt = ctx->serverSalt; |
wolfSSL | 15:117db924cf7c | 9769 | ctx->macSaltSz = EXCHANGE_SALT_SZ; |
wolfSSL | 15:117db924cf7c | 9770 | |
wolfSSL | 15:117db924cf7c | 9771 | if (ctx->kdfInfo == NULL) { |
wolfSSL | 15:117db924cf7c | 9772 | /* default info */ |
wolfSSL | 15:117db924cf7c | 9773 | ctx->kdfInfo = (const byte*)exchange_info; |
wolfSSL | 15:117db924cf7c | 9774 | ctx->kdfInfoSz = EXCHANGE_INFO_SZ; |
wolfSSL | 15:117db924cf7c | 9775 | } |
wolfSSL | 15:117db924cf7c | 9776 | |
wolfSSL | 15:117db924cf7c | 9777 | return 0; |
wolfSSL | 15:117db924cf7c | 9778 | } |
wolfSSL | 15:117db924cf7c | 9779 | |
wolfSSL | 15:117db924cf7c | 9780 | |
wolfSSL | 15:117db924cf7c | 9781 | static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 9782 | { |
wolfSSL | 15:117db924cf7c | 9783 | byte* saltBuffer = NULL; |
wolfSSL | 15:117db924cf7c | 9784 | |
wolfSSL | 15:117db924cf7c | 9785 | if (ctx == NULL || rng == NULL || flags == 0) |
wolfSSL | 15:117db924cf7c | 9786 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9787 | |
wolfSSL | 15:117db924cf7c | 9788 | saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; |
wolfSSL | 15:117db924cf7c | 9789 | |
wolfSSL | 15:117db924cf7c | 9790 | return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); |
wolfSSL | 15:117db924cf7c | 9791 | } |
wolfSSL | 15:117db924cf7c | 9792 | |
wolfSSL | 15:117db924cf7c | 9793 | |
wolfSSL | 15:117db924cf7c | 9794 | static void ecc_ctx_init(ecEncCtx* ctx, int flags) |
wolfSSL | 15:117db924cf7c | 9795 | { |
wolfSSL | 15:117db924cf7c | 9796 | if (ctx) { |
wolfSSL | 15:117db924cf7c | 9797 | XMEMSET(ctx, 0, sizeof(ecEncCtx)); |
wolfSSL | 15:117db924cf7c | 9798 | |
wolfSSL | 15:117db924cf7c | 9799 | ctx->encAlgo = ecAES_128_CBC; |
wolfSSL | 15:117db924cf7c | 9800 | ctx->kdfAlgo = ecHKDF_SHA256; |
wolfSSL | 15:117db924cf7c | 9801 | ctx->macAlgo = ecHMAC_SHA256; |
wolfSSL | 15:117db924cf7c | 9802 | ctx->protocol = (byte)flags; |
wolfSSL | 15:117db924cf7c | 9803 | |
wolfSSL | 15:117db924cf7c | 9804 | if (flags == REQ_RESP_CLIENT) |
wolfSSL | 15:117db924cf7c | 9805 | ctx->cliSt = ecCLI_INIT; |
wolfSSL | 15:117db924cf7c | 9806 | if (flags == REQ_RESP_SERVER) |
wolfSSL | 15:117db924cf7c | 9807 | ctx->srvSt = ecSRV_INIT; |
wolfSSL | 15:117db924cf7c | 9808 | } |
wolfSSL | 15:117db924cf7c | 9809 | } |
wolfSSL | 15:117db924cf7c | 9810 | |
wolfSSL | 15:117db924cf7c | 9811 | |
wolfSSL | 15:117db924cf7c | 9812 | /* allow ecc context reset so user doesn't have to init/free for reuse */ |
wolfSSL | 15:117db924cf7c | 9813 | int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 9814 | { |
wolfSSL | 15:117db924cf7c | 9815 | if (ctx == NULL || rng == NULL) |
wolfSSL | 15:117db924cf7c | 9816 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9817 | |
wolfSSL | 15:117db924cf7c | 9818 | ecc_ctx_init(ctx, ctx->protocol); |
wolfSSL | 15:117db924cf7c | 9819 | return ecc_ctx_set_salt(ctx, ctx->protocol, rng); |
wolfSSL | 15:117db924cf7c | 9820 | } |
wolfSSL | 15:117db924cf7c | 9821 | |
wolfSSL | 15:117db924cf7c | 9822 | |
wolfSSL | 15:117db924cf7c | 9823 | ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap) |
wolfSSL | 15:117db924cf7c | 9824 | { |
wolfSSL | 15:117db924cf7c | 9825 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 9826 | ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap, |
wolfSSL | 15:117db924cf7c | 9827 | DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 9828 | |
wolfSSL | 15:117db924cf7c | 9829 | if (ctx) { |
wolfSSL | 15:117db924cf7c | 9830 | ctx->protocol = (byte)flags; |
wolfSSL | 15:117db924cf7c | 9831 | ctx->heap = heap; |
wolfSSL | 15:117db924cf7c | 9832 | } |
wolfSSL | 15:117db924cf7c | 9833 | |
wolfSSL | 15:117db924cf7c | 9834 | ret = wc_ecc_ctx_reset(ctx, rng); |
wolfSSL | 15:117db924cf7c | 9835 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 9836 | wc_ecc_ctx_free(ctx); |
wolfSSL | 15:117db924cf7c | 9837 | ctx = NULL; |
wolfSSL | 15:117db924cf7c | 9838 | } |
wolfSSL | 15:117db924cf7c | 9839 | |
wolfSSL | 15:117db924cf7c | 9840 | return ctx; |
wolfSSL | 15:117db924cf7c | 9841 | } |
wolfSSL | 15:117db924cf7c | 9842 | |
wolfSSL | 15:117db924cf7c | 9843 | |
wolfSSL | 15:117db924cf7c | 9844 | /* alloc/init and set defaults, return new Context */ |
wolfSSL | 15:117db924cf7c | 9845 | ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 9846 | { |
wolfSSL | 15:117db924cf7c | 9847 | return wc_ecc_ctx_new_ex(flags, rng, NULL); |
wolfSSL | 15:117db924cf7c | 9848 | } |
wolfSSL | 15:117db924cf7c | 9849 | |
wolfSSL | 15:117db924cf7c | 9850 | |
wolfSSL | 15:117db924cf7c | 9851 | /* free any resources, clear any keys */ |
wolfSSL | 15:117db924cf7c | 9852 | void wc_ecc_ctx_free(ecEncCtx* ctx) |
wolfSSL | 15:117db924cf7c | 9853 | { |
wolfSSL | 15:117db924cf7c | 9854 | if (ctx) { |
wolfSSL | 15:117db924cf7c | 9855 | ForceZero(ctx, sizeof(ecEncCtx)); |
wolfSSL | 15:117db924cf7c | 9856 | XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC); |
wolfSSL | 15:117db924cf7c | 9857 | } |
wolfSSL | 15:117db924cf7c | 9858 | } |
wolfSSL | 15:117db924cf7c | 9859 | |
wolfSSL | 15:117db924cf7c | 9860 | |
wolfSSL | 15:117db924cf7c | 9861 | static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, |
wolfSSL | 15:117db924cf7c | 9862 | int* keysLen, word32* digestSz, word32* blockSz) |
wolfSSL | 15:117db924cf7c | 9863 | { |
wolfSSL | 15:117db924cf7c | 9864 | if (ctx) { |
wolfSSL | 15:117db924cf7c | 9865 | switch (ctx->encAlgo) { |
wolfSSL | 15:117db924cf7c | 9866 | case ecAES_128_CBC: |
wolfSSL | 15:117db924cf7c | 9867 | *encKeySz = KEY_SIZE_128; |
wolfSSL | 15:117db924cf7c | 9868 | *ivSz = IV_SIZE_128; |
wolfSSL | 15:117db924cf7c | 9869 | *blockSz = AES_BLOCK_SIZE; |
wolfSSL | 15:117db924cf7c | 9870 | break; |
wolfSSL | 15:117db924cf7c | 9871 | default: |
wolfSSL | 15:117db924cf7c | 9872 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9873 | } |
wolfSSL | 15:117db924cf7c | 9874 | |
wolfSSL | 15:117db924cf7c | 9875 | switch (ctx->macAlgo) { |
wolfSSL | 15:117db924cf7c | 9876 | case ecHMAC_SHA256: |
wolfSSL | 15:117db924cf7c | 9877 | *digestSz = WC_SHA256_DIGEST_SIZE; |
wolfSSL | 15:117db924cf7c | 9878 | break; |
wolfSSL | 15:117db924cf7c | 9879 | default: |
wolfSSL | 15:117db924cf7c | 9880 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9881 | } |
wolfSSL | 15:117db924cf7c | 9882 | } else |
wolfSSL | 15:117db924cf7c | 9883 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9884 | |
wolfSSL | 15:117db924cf7c | 9885 | *keysLen = *encKeySz + *ivSz + *digestSz; |
wolfSSL | 15:117db924cf7c | 9886 | |
wolfSSL | 15:117db924cf7c | 9887 | return 0; |
wolfSSL | 15:117db924cf7c | 9888 | } |
wolfSSL | 15:117db924cf7c | 9889 | |
wolfSSL | 15:117db924cf7c | 9890 | |
wolfSSL | 15:117db924cf7c | 9891 | /* ecc encrypt with shared secret run through kdf |
wolfSSL | 15:117db924cf7c | 9892 | ctx holds non default algos and inputs |
wolfSSL | 15:117db924cf7c | 9893 | msgSz should be the right size for encAlgo, i.e., already padded |
wolfSSL | 15:117db924cf7c | 9894 | return 0 on success */ |
wolfSSL | 15:117db924cf7c | 9895 | int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, |
wolfSSL | 15:117db924cf7c | 9896 | word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) |
wolfSSL | 15:117db924cf7c | 9897 | { |
wolfSSL | 15:117db924cf7c | 9898 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 9899 | word32 blockSz; |
wolfSSL | 15:117db924cf7c | 9900 | word32 digestSz; |
wolfSSL | 15:117db924cf7c | 9901 | ecEncCtx localCtx; |
wolfSSL | 15:117db924cf7c | 9902 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9903 | byte* sharedSecret; |
wolfSSL | 15:117db924cf7c | 9904 | byte* keys; |
wolfSSL | 15:117db924cf7c | 9905 | #else |
wolfSSL | 15:117db924cf7c | 9906 | byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ |
wolfSSL | 15:117db924cf7c | 9907 | byte keys[ECC_BUFSIZE]; /* max size */ |
wolfSSL | 15:117db924cf7c | 9908 | #endif |
wolfSSL | 15:117db924cf7c | 9909 | word32 sharedSz = ECC_MAXSIZE; |
wolfSSL | 15:117db924cf7c | 9910 | int keysLen; |
wolfSSL | 15:117db924cf7c | 9911 | int encKeySz; |
wolfSSL | 15:117db924cf7c | 9912 | int ivSz; |
wolfSSL | 15:117db924cf7c | 9913 | int offset = 0; /* keys offset if doing msg exchange */ |
wolfSSL | 15:117db924cf7c | 9914 | byte* encKey; |
wolfSSL | 15:117db924cf7c | 9915 | byte* encIv; |
wolfSSL | 15:117db924cf7c | 9916 | byte* macKey; |
wolfSSL | 15:117db924cf7c | 9917 | |
wolfSSL | 15:117db924cf7c | 9918 | if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || |
wolfSSL | 15:117db924cf7c | 9919 | outSz == NULL) |
wolfSSL | 15:117db924cf7c | 9920 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9921 | |
wolfSSL | 15:117db924cf7c | 9922 | if (ctx == NULL) { /* use defaults */ |
wolfSSL | 15:117db924cf7c | 9923 | ecc_ctx_init(&localCtx, 0); |
wolfSSL | 15:117db924cf7c | 9924 | ctx = &localCtx; |
wolfSSL | 15:117db924cf7c | 9925 | } |
wolfSSL | 15:117db924cf7c | 9926 | |
wolfSSL | 15:117db924cf7c | 9927 | ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, |
wolfSSL | 15:117db924cf7c | 9928 | &blockSz); |
wolfSSL | 15:117db924cf7c | 9929 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 9930 | return ret; |
wolfSSL | 15:117db924cf7c | 9931 | |
wolfSSL | 15:117db924cf7c | 9932 | if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 15:117db924cf7c | 9933 | offset = keysLen; |
wolfSSL | 15:117db924cf7c | 9934 | keysLen *= 2; |
wolfSSL | 15:117db924cf7c | 9935 | |
wolfSSL | 15:117db924cf7c | 9936 | if (ctx->srvSt != ecSRV_RECV_REQ) |
wolfSSL | 15:117db924cf7c | 9937 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 9938 | |
wolfSSL | 15:117db924cf7c | 9939 | ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ |
wolfSSL | 15:117db924cf7c | 9940 | } |
wolfSSL | 15:117db924cf7c | 9941 | else if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 15:117db924cf7c | 9942 | if (ctx->cliSt != ecCLI_SALT_SET) |
wolfSSL | 15:117db924cf7c | 9943 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 9944 | |
wolfSSL | 15:117db924cf7c | 9945 | ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ |
wolfSSL | 15:117db924cf7c | 9946 | } |
wolfSSL | 15:117db924cf7c | 9947 | |
wolfSSL | 15:117db924cf7c | 9948 | if (keysLen > ECC_BUFSIZE) /* keys size */ |
wolfSSL | 15:117db924cf7c | 9949 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 9950 | |
wolfSSL | 15:117db924cf7c | 9951 | if ( (msgSz%blockSz) != 0) |
wolfSSL | 15:117db924cf7c | 9952 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 9953 | |
wolfSSL | 15:117db924cf7c | 9954 | if (*outSz < (msgSz + digestSz)) |
wolfSSL | 15:117db924cf7c | 9955 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 9956 | |
wolfSSL | 15:117db924cf7c | 9957 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 9958 | sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9959 | if (sharedSecret == NULL) |
wolfSSL | 15:117db924cf7c | 9960 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 9961 | |
wolfSSL | 15:117db924cf7c | 9962 | keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9963 | if (keys == NULL) { |
wolfSSL | 15:117db924cf7c | 9964 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 9965 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 9966 | } |
wolfSSL | 15:117db924cf7c | 9967 | #endif |
wolfSSL | 15:117db924cf7c | 9968 | |
wolfSSL | 15:117db924cf7c | 9969 | do { |
wolfSSL | 16:8e0d178b1d1e | 9970 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 9971 | ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 9972 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 9973 | break; |
wolfSSL | 15:117db924cf7c | 9974 | #endif |
wolfSSL | 15:117db924cf7c | 9975 | ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); |
wolfSSL | 15:117db924cf7c | 9976 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 9977 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 9978 | switch (ctx->kdfAlgo) { |
wolfSSL | 15:117db924cf7c | 9979 | case ecHKDF_SHA256 : |
wolfSSL | 15:117db924cf7c | 9980 | ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt, |
wolfSSL | 15:117db924cf7c | 9981 | ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, |
wolfSSL | 15:117db924cf7c | 9982 | keys, keysLen); |
wolfSSL | 15:117db924cf7c | 9983 | break; |
wolfSSL | 15:117db924cf7c | 9984 | |
wolfSSL | 15:117db924cf7c | 9985 | default: |
wolfSSL | 15:117db924cf7c | 9986 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 9987 | break; |
wolfSSL | 15:117db924cf7c | 9988 | } |
wolfSSL | 15:117db924cf7c | 9989 | } |
wolfSSL | 15:117db924cf7c | 9990 | |
wolfSSL | 15:117db924cf7c | 9991 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 9992 | encKey = keys + offset; |
wolfSSL | 15:117db924cf7c | 9993 | encIv = encKey + encKeySz; |
wolfSSL | 15:117db924cf7c | 9994 | macKey = encKey + encKeySz + ivSz; |
wolfSSL | 15:117db924cf7c | 9995 | |
wolfSSL | 15:117db924cf7c | 9996 | switch (ctx->encAlgo) { |
wolfSSL | 15:117db924cf7c | 9997 | case ecAES_128_CBC: |
wolfSSL | 15:117db924cf7c | 9998 | { |
wolfSSL | 15:117db924cf7c | 9999 | Aes aes; |
wolfSSL | 16:8e0d178b1d1e | 10000 | ret = wc_AesInit(&aes, NULL, INVALID_DEVID); |
wolfSSL | 16:8e0d178b1d1e | 10001 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 10002 | ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, |
wolfSSL | 15:117db924cf7c | 10003 | AES_ENCRYPTION); |
wolfSSL | 16:8e0d178b1d1e | 10004 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 10005 | ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz); |
wolfSSL | 16:8e0d178b1d1e | 10006 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) |
wolfSSL | 16:8e0d178b1d1e | 10007 | ret = wc_AsyncWait(ret, &aes.asyncDev, |
wolfSSL | 16:8e0d178b1d1e | 10008 | WC_ASYNC_FLAG_NONE); |
wolfSSL | 16:8e0d178b1d1e | 10009 | #endif |
wolfSSL | 16:8e0d178b1d1e | 10010 | } |
wolfSSL | 16:8e0d178b1d1e | 10011 | wc_AesFree(&aes); |
wolfSSL | 16:8e0d178b1d1e | 10012 | } |
wolfSSL | 15:117db924cf7c | 10013 | if (ret != 0) |
wolfSSL | 16:8e0d178b1d1e | 10014 | break; |
wolfSSL | 15:117db924cf7c | 10015 | } |
wolfSSL | 15:117db924cf7c | 10016 | break; |
wolfSSL | 15:117db924cf7c | 10017 | |
wolfSSL | 15:117db924cf7c | 10018 | default: |
wolfSSL | 15:117db924cf7c | 10019 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10020 | break; |
wolfSSL | 15:117db924cf7c | 10021 | } |
wolfSSL | 15:117db924cf7c | 10022 | } |
wolfSSL | 15:117db924cf7c | 10023 | |
wolfSSL | 15:117db924cf7c | 10024 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10025 | switch (ctx->macAlgo) { |
wolfSSL | 15:117db924cf7c | 10026 | case ecHMAC_SHA256: |
wolfSSL | 15:117db924cf7c | 10027 | { |
wolfSSL | 15:117db924cf7c | 10028 | Hmac hmac; |
wolfSSL | 15:117db924cf7c | 10029 | ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); |
wolfSSL | 15:117db924cf7c | 10030 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10031 | ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE); |
wolfSSL | 15:117db924cf7c | 10032 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10033 | ret = wc_HmacUpdate(&hmac, out, msgSz); |
wolfSSL | 15:117db924cf7c | 10034 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10035 | ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); |
wolfSSL | 15:117db924cf7c | 10036 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10037 | ret = wc_HmacFinal(&hmac, out+msgSz); |
wolfSSL | 15:117db924cf7c | 10038 | wc_HmacFree(&hmac); |
wolfSSL | 15:117db924cf7c | 10039 | } |
wolfSSL | 15:117db924cf7c | 10040 | } |
wolfSSL | 15:117db924cf7c | 10041 | break; |
wolfSSL | 15:117db924cf7c | 10042 | |
wolfSSL | 15:117db924cf7c | 10043 | default: |
wolfSSL | 15:117db924cf7c | 10044 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10045 | break; |
wolfSSL | 15:117db924cf7c | 10046 | } |
wolfSSL | 15:117db924cf7c | 10047 | } |
wolfSSL | 15:117db924cf7c | 10048 | |
wolfSSL | 15:117db924cf7c | 10049 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10050 | *outSz = msgSz + digestSz; |
wolfSSL | 15:117db924cf7c | 10051 | |
wolfSSL | 15:117db924cf7c | 10052 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10053 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10054 | XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10055 | #endif |
wolfSSL | 15:117db924cf7c | 10056 | |
wolfSSL | 15:117db924cf7c | 10057 | return ret; |
wolfSSL | 15:117db924cf7c | 10058 | } |
wolfSSL | 15:117db924cf7c | 10059 | |
wolfSSL | 15:117db924cf7c | 10060 | |
wolfSSL | 15:117db924cf7c | 10061 | /* ecc decrypt with shared secret run through kdf |
wolfSSL | 15:117db924cf7c | 10062 | ctx holds non default algos and inputs |
wolfSSL | 15:117db924cf7c | 10063 | return 0 on success */ |
wolfSSL | 15:117db924cf7c | 10064 | int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, |
wolfSSL | 15:117db924cf7c | 10065 | word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) |
wolfSSL | 15:117db924cf7c | 10066 | { |
wolfSSL | 15:117db924cf7c | 10067 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 10068 | word32 blockSz; |
wolfSSL | 15:117db924cf7c | 10069 | word32 digestSz; |
wolfSSL | 15:117db924cf7c | 10070 | ecEncCtx localCtx; |
wolfSSL | 15:117db924cf7c | 10071 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10072 | byte* sharedSecret; |
wolfSSL | 15:117db924cf7c | 10073 | byte* keys; |
wolfSSL | 15:117db924cf7c | 10074 | #else |
wolfSSL | 15:117db924cf7c | 10075 | byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ |
wolfSSL | 15:117db924cf7c | 10076 | byte keys[ECC_BUFSIZE]; /* max size */ |
wolfSSL | 15:117db924cf7c | 10077 | #endif |
wolfSSL | 15:117db924cf7c | 10078 | word32 sharedSz = ECC_MAXSIZE; |
wolfSSL | 15:117db924cf7c | 10079 | int keysLen; |
wolfSSL | 15:117db924cf7c | 10080 | int encKeySz; |
wolfSSL | 15:117db924cf7c | 10081 | int ivSz; |
wolfSSL | 15:117db924cf7c | 10082 | int offset = 0; /* in case using msg exchange */ |
wolfSSL | 15:117db924cf7c | 10083 | byte* encKey; |
wolfSSL | 15:117db924cf7c | 10084 | byte* encIv; |
wolfSSL | 15:117db924cf7c | 10085 | byte* macKey; |
wolfSSL | 15:117db924cf7c | 10086 | |
wolfSSL | 15:117db924cf7c | 10087 | if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || |
wolfSSL | 15:117db924cf7c | 10088 | outSz == NULL) |
wolfSSL | 15:117db924cf7c | 10089 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10090 | |
wolfSSL | 15:117db924cf7c | 10091 | if (ctx == NULL) { /* use defaults */ |
wolfSSL | 15:117db924cf7c | 10092 | ecc_ctx_init(&localCtx, 0); |
wolfSSL | 15:117db924cf7c | 10093 | ctx = &localCtx; |
wolfSSL | 15:117db924cf7c | 10094 | } |
wolfSSL | 15:117db924cf7c | 10095 | |
wolfSSL | 15:117db924cf7c | 10096 | ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, |
wolfSSL | 15:117db924cf7c | 10097 | &blockSz); |
wolfSSL | 15:117db924cf7c | 10098 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 10099 | return ret; |
wolfSSL | 15:117db924cf7c | 10100 | |
wolfSSL | 15:117db924cf7c | 10101 | if (ctx->protocol == REQ_RESP_CLIENT) { |
wolfSSL | 15:117db924cf7c | 10102 | offset = keysLen; |
wolfSSL | 15:117db924cf7c | 10103 | keysLen *= 2; |
wolfSSL | 15:117db924cf7c | 10104 | |
wolfSSL | 15:117db924cf7c | 10105 | if (ctx->cliSt != ecCLI_SENT_REQ) |
wolfSSL | 15:117db924cf7c | 10106 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 10107 | |
wolfSSL | 15:117db924cf7c | 10108 | ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ |
wolfSSL | 15:117db924cf7c | 10109 | } |
wolfSSL | 15:117db924cf7c | 10110 | else if (ctx->protocol == REQ_RESP_SERVER) { |
wolfSSL | 15:117db924cf7c | 10111 | if (ctx->srvSt != ecSRV_SALT_SET) |
wolfSSL | 15:117db924cf7c | 10112 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 10113 | |
wolfSSL | 15:117db924cf7c | 10114 | ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ |
wolfSSL | 15:117db924cf7c | 10115 | } |
wolfSSL | 15:117db924cf7c | 10116 | |
wolfSSL | 15:117db924cf7c | 10117 | if (keysLen > ECC_BUFSIZE) /* keys size */ |
wolfSSL | 15:117db924cf7c | 10118 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 10119 | |
wolfSSL | 15:117db924cf7c | 10120 | if ( ((msgSz-digestSz) % blockSz) != 0) |
wolfSSL | 15:117db924cf7c | 10121 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 10122 | |
wolfSSL | 15:117db924cf7c | 10123 | if (*outSz < (msgSz - digestSz)) |
wolfSSL | 15:117db924cf7c | 10124 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 10125 | |
wolfSSL | 15:117db924cf7c | 10126 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10127 | sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10128 | if (sharedSecret == NULL) |
wolfSSL | 15:117db924cf7c | 10129 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 10130 | |
wolfSSL | 15:117db924cf7c | 10131 | keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10132 | if (keys == NULL) { |
wolfSSL | 15:117db924cf7c | 10133 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10134 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 10135 | } |
wolfSSL | 15:117db924cf7c | 10136 | #endif |
wolfSSL | 15:117db924cf7c | 10137 | |
wolfSSL | 15:117db924cf7c | 10138 | do { |
wolfSSL | 16:8e0d178b1d1e | 10139 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) |
wolfSSL | 15:117db924cf7c | 10140 | ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); |
wolfSSL | 15:117db924cf7c | 10141 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 10142 | break; |
wolfSSL | 15:117db924cf7c | 10143 | #endif |
wolfSSL | 15:117db924cf7c | 10144 | ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); |
wolfSSL | 15:117db924cf7c | 10145 | } while (ret == WC_PENDING_E); |
wolfSSL | 15:117db924cf7c | 10146 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10147 | switch (ctx->kdfAlgo) { |
wolfSSL | 15:117db924cf7c | 10148 | case ecHKDF_SHA256 : |
wolfSSL | 15:117db924cf7c | 10149 | ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt, |
wolfSSL | 15:117db924cf7c | 10150 | ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, |
wolfSSL | 15:117db924cf7c | 10151 | keys, keysLen); |
wolfSSL | 15:117db924cf7c | 10152 | break; |
wolfSSL | 15:117db924cf7c | 10153 | |
wolfSSL | 15:117db924cf7c | 10154 | default: |
wolfSSL | 15:117db924cf7c | 10155 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10156 | break; |
wolfSSL | 15:117db924cf7c | 10157 | } |
wolfSSL | 15:117db924cf7c | 10158 | } |
wolfSSL | 15:117db924cf7c | 10159 | |
wolfSSL | 15:117db924cf7c | 10160 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10161 | encKey = keys + offset; |
wolfSSL | 15:117db924cf7c | 10162 | encIv = encKey + encKeySz; |
wolfSSL | 15:117db924cf7c | 10163 | macKey = encKey + encKeySz + ivSz; |
wolfSSL | 15:117db924cf7c | 10164 | |
wolfSSL | 15:117db924cf7c | 10165 | switch (ctx->macAlgo) { |
wolfSSL | 15:117db924cf7c | 10166 | case ecHMAC_SHA256: |
wolfSSL | 15:117db924cf7c | 10167 | { |
wolfSSL | 15:117db924cf7c | 10168 | byte verify[WC_SHA256_DIGEST_SIZE]; |
wolfSSL | 15:117db924cf7c | 10169 | Hmac hmac; |
wolfSSL | 15:117db924cf7c | 10170 | |
wolfSSL | 15:117db924cf7c | 10171 | ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); |
wolfSSL | 15:117db924cf7c | 10172 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10173 | ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE); |
wolfSSL | 15:117db924cf7c | 10174 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10175 | ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz); |
wolfSSL | 15:117db924cf7c | 10176 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10177 | ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); |
wolfSSL | 15:117db924cf7c | 10178 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10179 | ret = wc_HmacFinal(&hmac, verify); |
wolfSSL | 15:117db924cf7c | 10180 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10181 | if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0) |
wolfSSL | 15:117db924cf7c | 10182 | ret = -1; |
wolfSSL | 15:117db924cf7c | 10183 | } |
wolfSSL | 15:117db924cf7c | 10184 | |
wolfSSL | 15:117db924cf7c | 10185 | wc_HmacFree(&hmac); |
wolfSSL | 15:117db924cf7c | 10186 | } |
wolfSSL | 15:117db924cf7c | 10187 | break; |
wolfSSL | 15:117db924cf7c | 10188 | } |
wolfSSL | 15:117db924cf7c | 10189 | |
wolfSSL | 15:117db924cf7c | 10190 | default: |
wolfSSL | 15:117db924cf7c | 10191 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10192 | break; |
wolfSSL | 15:117db924cf7c | 10193 | } |
wolfSSL | 15:117db924cf7c | 10194 | } |
wolfSSL | 15:117db924cf7c | 10195 | |
wolfSSL | 15:117db924cf7c | 10196 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 10197 | switch (ctx->encAlgo) { |
wolfSSL | 15:117db924cf7c | 10198 | #ifdef HAVE_AES_CBC |
wolfSSL | 15:117db924cf7c | 10199 | case ecAES_128_CBC: |
wolfSSL | 15:117db924cf7c | 10200 | { |
wolfSSL | 15:117db924cf7c | 10201 | Aes aes; |
wolfSSL | 15:117db924cf7c | 10202 | ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, |
wolfSSL | 15:117db924cf7c | 10203 | AES_DECRYPTION); |
wolfSSL | 15:117db924cf7c | 10204 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 10205 | break; |
wolfSSL | 15:117db924cf7c | 10206 | ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); |
wolfSSL | 16:8e0d178b1d1e | 10207 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) |
wolfSSL | 15:117db924cf7c | 10208 | ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE); |
wolfSSL | 15:117db924cf7c | 10209 | #endif |
wolfSSL | 15:117db924cf7c | 10210 | } |
wolfSSL | 15:117db924cf7c | 10211 | break; |
wolfSSL | 15:117db924cf7c | 10212 | #endif |
wolfSSL | 15:117db924cf7c | 10213 | default: |
wolfSSL | 15:117db924cf7c | 10214 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10215 | break; |
wolfSSL | 15:117db924cf7c | 10216 | } |
wolfSSL | 15:117db924cf7c | 10217 | } |
wolfSSL | 15:117db924cf7c | 10218 | |
wolfSSL | 15:117db924cf7c | 10219 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 10220 | *outSz = msgSz - digestSz; |
wolfSSL | 15:117db924cf7c | 10221 | |
wolfSSL | 15:117db924cf7c | 10222 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10223 | XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10224 | XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER); |
wolfSSL | 15:117db924cf7c | 10225 | #endif |
wolfSSL | 15:117db924cf7c | 10226 | |
wolfSSL | 15:117db924cf7c | 10227 | return ret; |
wolfSSL | 15:117db924cf7c | 10228 | } |
wolfSSL | 15:117db924cf7c | 10229 | |
wolfSSL | 15:117db924cf7c | 10230 | |
wolfSSL | 15:117db924cf7c | 10231 | #endif /* HAVE_ECC_ENCRYPT */ |
wolfSSL | 15:117db924cf7c | 10232 | |
wolfSSL | 15:117db924cf7c | 10233 | |
wolfSSL | 15:117db924cf7c | 10234 | #ifdef HAVE_COMP_KEY |
wolfSSL | 16:8e0d178b1d1e | 10235 | #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL) |
wolfSSL | 15:117db924cf7c | 10236 | |
wolfSSL | 15:117db924cf7c | 10237 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 10238 | int do_mp_jacobi(mp_int* a, mp_int* n, int* c); |
wolfSSL | 15:117db924cf7c | 10239 | |
wolfSSL | 15:117db924cf7c | 10240 | int do_mp_jacobi(mp_int* a, mp_int* n, int* c) |
wolfSSL | 15:117db924cf7c | 10241 | { |
wolfSSL | 15:117db924cf7c | 10242 | int k, s, res; |
wolfSSL | 15:117db924cf7c | 10243 | int r = 0; /* initialize to help static analysis out */ |
wolfSSL | 15:117db924cf7c | 10244 | mp_digit residue; |
wolfSSL | 15:117db924cf7c | 10245 | |
wolfSSL | 15:117db924cf7c | 10246 | /* if a < 0 return MP_VAL */ |
wolfSSL | 15:117db924cf7c | 10247 | if (mp_isneg(a) == MP_YES) { |
wolfSSL | 15:117db924cf7c | 10248 | return MP_VAL; |
wolfSSL | 15:117db924cf7c | 10249 | } |
wolfSSL | 15:117db924cf7c | 10250 | |
wolfSSL | 15:117db924cf7c | 10251 | /* if n <= 0 return MP_VAL */ |
wolfSSL | 15:117db924cf7c | 10252 | if (mp_cmp_d(n, 0) != MP_GT) { |
wolfSSL | 15:117db924cf7c | 10253 | return MP_VAL; |
wolfSSL | 15:117db924cf7c | 10254 | } |
wolfSSL | 15:117db924cf7c | 10255 | |
wolfSSL | 15:117db924cf7c | 10256 | /* step 1. handle case of a == 0 */ |
wolfSSL | 15:117db924cf7c | 10257 | if (mp_iszero (a) == MP_YES) { |
wolfSSL | 15:117db924cf7c | 10258 | /* special case of a == 0 and n == 1 */ |
wolfSSL | 15:117db924cf7c | 10259 | if (mp_cmp_d (n, 1) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10260 | *c = 1; |
wolfSSL | 15:117db924cf7c | 10261 | } else { |
wolfSSL | 15:117db924cf7c | 10262 | *c = 0; |
wolfSSL | 15:117db924cf7c | 10263 | } |
wolfSSL | 15:117db924cf7c | 10264 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 10265 | } |
wolfSSL | 15:117db924cf7c | 10266 | |
wolfSSL | 15:117db924cf7c | 10267 | /* step 2. if a == 1, return 1 */ |
wolfSSL | 15:117db924cf7c | 10268 | if (mp_cmp_d (a, 1) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10269 | *c = 1; |
wolfSSL | 15:117db924cf7c | 10270 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 10271 | } |
wolfSSL | 15:117db924cf7c | 10272 | |
wolfSSL | 15:117db924cf7c | 10273 | /* default */ |
wolfSSL | 15:117db924cf7c | 10274 | s = 0; |
wolfSSL | 15:117db924cf7c | 10275 | |
wolfSSL | 15:117db924cf7c | 10276 | /* divide out larger power of two */ |
wolfSSL | 15:117db924cf7c | 10277 | k = mp_cnt_lsb(a); |
wolfSSL | 15:117db924cf7c | 10278 | res = mp_div_2d(a, k, a, NULL); |
wolfSSL | 15:117db924cf7c | 10279 | |
wolfSSL | 15:117db924cf7c | 10280 | if (res == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10281 | /* step 4. if e is even set s=1 */ |
wolfSSL | 15:117db924cf7c | 10282 | if ((k & 1) == 0) { |
wolfSSL | 15:117db924cf7c | 10283 | s = 1; |
wolfSSL | 15:117db924cf7c | 10284 | } else { |
wolfSSL | 15:117db924cf7c | 10285 | /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ |
wolfSSL | 15:117db924cf7c | 10286 | residue = n->dp[0] & 7; |
wolfSSL | 15:117db924cf7c | 10287 | |
wolfSSL | 15:117db924cf7c | 10288 | if (residue == 1 || residue == 7) { |
wolfSSL | 15:117db924cf7c | 10289 | s = 1; |
wolfSSL | 15:117db924cf7c | 10290 | } else if (residue == 3 || residue == 5) { |
wolfSSL | 15:117db924cf7c | 10291 | s = -1; |
wolfSSL | 15:117db924cf7c | 10292 | } |
wolfSSL | 15:117db924cf7c | 10293 | } |
wolfSSL | 15:117db924cf7c | 10294 | |
wolfSSL | 15:117db924cf7c | 10295 | /* step 5. if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */ |
wolfSSL | 15:117db924cf7c | 10296 | if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) { |
wolfSSL | 15:117db924cf7c | 10297 | s = -s; |
wolfSSL | 15:117db924cf7c | 10298 | } |
wolfSSL | 15:117db924cf7c | 10299 | } |
wolfSSL | 15:117db924cf7c | 10300 | |
wolfSSL | 15:117db924cf7c | 10301 | if (res == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10302 | /* if a == 1 we're done */ |
wolfSSL | 15:117db924cf7c | 10303 | if (mp_cmp_d(a, 1) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10304 | *c = s; |
wolfSSL | 15:117db924cf7c | 10305 | } else { |
wolfSSL | 15:117db924cf7c | 10306 | /* n1 = n mod a */ |
wolfSSL | 15:117db924cf7c | 10307 | res = mp_mod (n, a, n); |
wolfSSL | 15:117db924cf7c | 10308 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10309 | res = do_mp_jacobi(n, a, &r); |
wolfSSL | 15:117db924cf7c | 10310 | |
wolfSSL | 15:117db924cf7c | 10311 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10312 | *c = s * r; |
wolfSSL | 15:117db924cf7c | 10313 | } |
wolfSSL | 15:117db924cf7c | 10314 | } |
wolfSSL | 15:117db924cf7c | 10315 | |
wolfSSL | 15:117db924cf7c | 10316 | return res; |
wolfSSL | 15:117db924cf7c | 10317 | } |
wolfSSL | 15:117db924cf7c | 10318 | |
wolfSSL | 15:117db924cf7c | 10319 | |
wolfSSL | 15:117db924cf7c | 10320 | /* computes the jacobi c = (a | n) (or Legendre if n is prime) |
wolfSSL | 15:117db924cf7c | 10321 | * HAC pp. 73 Algorithm 2.149 |
wolfSSL | 15:117db924cf7c | 10322 | * HAC is wrong here, as the special case of (0 | 1) is not |
wolfSSL | 15:117db924cf7c | 10323 | * handled correctly. |
wolfSSL | 15:117db924cf7c | 10324 | */ |
wolfSSL | 15:117db924cf7c | 10325 | int mp_jacobi(mp_int* a, mp_int* n, int* c) |
wolfSSL | 15:117db924cf7c | 10326 | { |
wolfSSL | 15:117db924cf7c | 10327 | mp_int a1, n1; |
wolfSSL | 15:117db924cf7c | 10328 | int res; |
wolfSSL | 15:117db924cf7c | 10329 | |
wolfSSL | 15:117db924cf7c | 10330 | /* step 3. write a = a1 * 2**k */ |
wolfSSL | 15:117db924cf7c | 10331 | if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10332 | return res; |
wolfSSL | 15:117db924cf7c | 10333 | } |
wolfSSL | 15:117db924cf7c | 10334 | |
wolfSSL | 15:117db924cf7c | 10335 | if ((res = mp_copy(a, &a1)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10336 | goto done; |
wolfSSL | 15:117db924cf7c | 10337 | } |
wolfSSL | 15:117db924cf7c | 10338 | |
wolfSSL | 15:117db924cf7c | 10339 | if ((res = mp_copy(n, &n1)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10340 | goto done; |
wolfSSL | 15:117db924cf7c | 10341 | } |
wolfSSL | 15:117db924cf7c | 10342 | |
wolfSSL | 15:117db924cf7c | 10343 | res = do_mp_jacobi(&a1, &n1, c); |
wolfSSL | 15:117db924cf7c | 10344 | |
wolfSSL | 15:117db924cf7c | 10345 | done: |
wolfSSL | 15:117db924cf7c | 10346 | /* cleanup */ |
wolfSSL | 15:117db924cf7c | 10347 | mp_clear(&n1); |
wolfSSL | 15:117db924cf7c | 10348 | mp_clear(&a1); |
wolfSSL | 15:117db924cf7c | 10349 | |
wolfSSL | 15:117db924cf7c | 10350 | return res; |
wolfSSL | 15:117db924cf7c | 10351 | } |
wolfSSL | 15:117db924cf7c | 10352 | |
wolfSSL | 15:117db924cf7c | 10353 | |
wolfSSL | 15:117db924cf7c | 10354 | /* Solves the modular equation x^2 = n (mod p) |
wolfSSL | 15:117db924cf7c | 10355 | * where prime number is greater than 2 (odd prime). |
wolfSSL | 15:117db924cf7c | 10356 | * The result is returned in the third argument x |
wolfSSL | 15:117db924cf7c | 10357 | * the function returns MP_OKAY on success, MP_VAL or another error on failure |
wolfSSL | 15:117db924cf7c | 10358 | */ |
wolfSSL | 15:117db924cf7c | 10359 | int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) |
wolfSSL | 15:117db924cf7c | 10360 | { |
wolfSSL | 15:117db924cf7c | 10361 | #ifdef SQRTMOD_USE_MOD_EXP |
wolfSSL | 15:117db924cf7c | 10362 | int res; |
wolfSSL | 15:117db924cf7c | 10363 | |
wolfSSL | 15:117db924cf7c | 10364 | mp_int e; |
wolfSSL | 15:117db924cf7c | 10365 | |
wolfSSL | 15:117db924cf7c | 10366 | res = mp_init(&e); |
wolfSSL | 15:117db924cf7c | 10367 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10368 | res = mp_add_d(prime, 1, &e); |
wolfSSL | 15:117db924cf7c | 10369 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10370 | res = mp_div_2d(&e, 2, &e, NULL); |
wolfSSL | 15:117db924cf7c | 10371 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10372 | res = mp_exptmod(n, &e, prime, ret); |
wolfSSL | 15:117db924cf7c | 10373 | |
wolfSSL | 15:117db924cf7c | 10374 | mp_clear(&e); |
wolfSSL | 15:117db924cf7c | 10375 | |
wolfSSL | 15:117db924cf7c | 10376 | return res; |
wolfSSL | 15:117db924cf7c | 10377 | #else |
wolfSSL | 15:117db924cf7c | 10378 | int res, legendre, done = 0; |
wolfSSL | 15:117db924cf7c | 10379 | mp_int t1, C, Q, S, Z, M, T, R, two; |
wolfSSL | 15:117db924cf7c | 10380 | mp_digit i; |
wolfSSL | 15:117db924cf7c | 10381 | |
wolfSSL | 15:117db924cf7c | 10382 | /* first handle the simple cases n = 0 or n = 1 */ |
wolfSSL | 15:117db924cf7c | 10383 | if (mp_cmp_d(n, 0) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10384 | mp_zero(ret); |
wolfSSL | 15:117db924cf7c | 10385 | return MP_OKAY; |
wolfSSL | 15:117db924cf7c | 10386 | } |
wolfSSL | 15:117db924cf7c | 10387 | if (mp_cmp_d(n, 1) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10388 | return mp_set(ret, 1); |
wolfSSL | 15:117db924cf7c | 10389 | } |
wolfSSL | 15:117db924cf7c | 10390 | |
wolfSSL | 15:117db924cf7c | 10391 | /* prime must be odd */ |
wolfSSL | 15:117db924cf7c | 10392 | if (mp_cmp_d(prime, 2) == MP_EQ) { |
wolfSSL | 15:117db924cf7c | 10393 | return MP_VAL; |
wolfSSL | 15:117db924cf7c | 10394 | } |
wolfSSL | 15:117db924cf7c | 10395 | |
wolfSSL | 15:117db924cf7c | 10396 | /* is quadratic non-residue mod prime */ |
wolfSSL | 15:117db924cf7c | 10397 | if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10398 | return res; |
wolfSSL | 15:117db924cf7c | 10399 | } |
wolfSSL | 15:117db924cf7c | 10400 | if (legendre == -1) { |
wolfSSL | 15:117db924cf7c | 10401 | return MP_VAL; |
wolfSSL | 15:117db924cf7c | 10402 | } |
wolfSSL | 15:117db924cf7c | 10403 | |
wolfSSL | 15:117db924cf7c | 10404 | if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10405 | return res; |
wolfSSL | 15:117db924cf7c | 10406 | |
wolfSSL | 15:117db924cf7c | 10407 | if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) |
wolfSSL | 15:117db924cf7c | 10408 | != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10409 | mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); |
wolfSSL | 15:117db924cf7c | 10410 | mp_clear(&M); |
wolfSSL | 15:117db924cf7c | 10411 | return res; |
wolfSSL | 15:117db924cf7c | 10412 | } |
wolfSSL | 15:117db924cf7c | 10413 | |
wolfSSL | 15:117db924cf7c | 10414 | /* SPECIAL CASE: if prime mod 4 == 3 |
wolfSSL | 15:117db924cf7c | 10415 | * compute directly: res = n^(prime+1)/4 mod prime |
wolfSSL | 15:117db924cf7c | 10416 | * Handbook of Applied Cryptography algorithm 3.36 |
wolfSSL | 15:117db924cf7c | 10417 | */ |
wolfSSL | 15:117db924cf7c | 10418 | res = mp_mod_d(prime, 4, &i); |
wolfSSL | 15:117db924cf7c | 10419 | if (res == MP_OKAY && i == 3) { |
wolfSSL | 15:117db924cf7c | 10420 | res = mp_add_d(prime, 1, &t1); |
wolfSSL | 15:117db924cf7c | 10421 | |
wolfSSL | 15:117db924cf7c | 10422 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10423 | res = mp_div_2(&t1, &t1); |
wolfSSL | 15:117db924cf7c | 10424 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10425 | res = mp_div_2(&t1, &t1); |
wolfSSL | 15:117db924cf7c | 10426 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10427 | res = mp_exptmod(n, &t1, prime, ret); |
wolfSSL | 15:117db924cf7c | 10428 | |
wolfSSL | 15:117db924cf7c | 10429 | done = 1; |
wolfSSL | 15:117db924cf7c | 10430 | } |
wolfSSL | 15:117db924cf7c | 10431 | |
wolfSSL | 15:117db924cf7c | 10432 | /* NOW: TonelliShanks algorithm */ |
wolfSSL | 15:117db924cf7c | 10433 | if (res == MP_OKAY && done == 0) { |
wolfSSL | 15:117db924cf7c | 10434 | |
wolfSSL | 15:117db924cf7c | 10435 | /* factor out powers of 2 from prime-1, defining Q and S |
wolfSSL | 15:117db924cf7c | 10436 | * as: prime-1 = Q*2^S */ |
wolfSSL | 15:117db924cf7c | 10437 | /* Q = prime - 1 */ |
wolfSSL | 15:117db924cf7c | 10438 | res = mp_copy(prime, &Q); |
wolfSSL | 15:117db924cf7c | 10439 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10440 | res = mp_sub_d(&Q, 1, &Q); |
wolfSSL | 15:117db924cf7c | 10441 | |
wolfSSL | 15:117db924cf7c | 10442 | /* S = 0 */ |
wolfSSL | 15:117db924cf7c | 10443 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10444 | mp_zero(&S); |
wolfSSL | 15:117db924cf7c | 10445 | |
wolfSSL | 15:117db924cf7c | 10446 | while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) { |
wolfSSL | 15:117db924cf7c | 10447 | /* Q = Q / 2 */ |
wolfSSL | 15:117db924cf7c | 10448 | res = mp_div_2(&Q, &Q); |
wolfSSL | 15:117db924cf7c | 10449 | |
wolfSSL | 15:117db924cf7c | 10450 | /* S = S + 1 */ |
wolfSSL | 15:117db924cf7c | 10451 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10452 | res = mp_add_d(&S, 1, &S); |
wolfSSL | 15:117db924cf7c | 10453 | } |
wolfSSL | 15:117db924cf7c | 10454 | |
wolfSSL | 15:117db924cf7c | 10455 | /* find a Z such that the Legendre symbol (Z|prime) == -1 */ |
wolfSSL | 15:117db924cf7c | 10456 | /* Z = 2 */ |
wolfSSL | 15:117db924cf7c | 10457 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10458 | res = mp_set_int(&Z, 2); |
wolfSSL | 15:117db924cf7c | 10459 | |
wolfSSL | 15:117db924cf7c | 10460 | while (res == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10461 | res = mp_jacobi(&Z, prime, &legendre); |
wolfSSL | 15:117db924cf7c | 10462 | if (res == MP_OKAY && legendre == -1) |
wolfSSL | 15:117db924cf7c | 10463 | break; |
wolfSSL | 15:117db924cf7c | 10464 | |
wolfSSL | 15:117db924cf7c | 10465 | /* Z = Z + 1 */ |
wolfSSL | 15:117db924cf7c | 10466 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10467 | res = mp_add_d(&Z, 1, &Z); |
wolfSSL | 15:117db924cf7c | 10468 | } |
wolfSSL | 15:117db924cf7c | 10469 | |
wolfSSL | 15:117db924cf7c | 10470 | /* C = Z ^ Q mod prime */ |
wolfSSL | 15:117db924cf7c | 10471 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10472 | res = mp_exptmod(&Z, &Q, prime, &C); |
wolfSSL | 15:117db924cf7c | 10473 | |
wolfSSL | 15:117db924cf7c | 10474 | /* t1 = (Q + 1) / 2 */ |
wolfSSL | 15:117db924cf7c | 10475 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10476 | res = mp_add_d(&Q, 1, &t1); |
wolfSSL | 15:117db924cf7c | 10477 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10478 | res = mp_div_2(&t1, &t1); |
wolfSSL | 15:117db924cf7c | 10479 | |
wolfSSL | 15:117db924cf7c | 10480 | /* R = n ^ ((Q + 1) / 2) mod prime */ |
wolfSSL | 15:117db924cf7c | 10481 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10482 | res = mp_exptmod(n, &t1, prime, &R); |
wolfSSL | 15:117db924cf7c | 10483 | |
wolfSSL | 15:117db924cf7c | 10484 | /* T = n ^ Q mod prime */ |
wolfSSL | 15:117db924cf7c | 10485 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10486 | res = mp_exptmod(n, &Q, prime, &T); |
wolfSSL | 15:117db924cf7c | 10487 | |
wolfSSL | 15:117db924cf7c | 10488 | /* M = S */ |
wolfSSL | 15:117db924cf7c | 10489 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10490 | res = mp_copy(&S, &M); |
wolfSSL | 15:117db924cf7c | 10491 | |
wolfSSL | 15:117db924cf7c | 10492 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10493 | res = mp_set_int(&two, 2); |
wolfSSL | 15:117db924cf7c | 10494 | |
wolfSSL | 15:117db924cf7c | 10495 | while (res == MP_OKAY && done == 0) { |
wolfSSL | 15:117db924cf7c | 10496 | res = mp_copy(&T, &t1); |
wolfSSL | 15:117db924cf7c | 10497 | |
wolfSSL | 15:117db924cf7c | 10498 | /* reduce to 1 and count */ |
wolfSSL | 15:117db924cf7c | 10499 | i = 0; |
wolfSSL | 15:117db924cf7c | 10500 | while (res == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 10501 | if (mp_cmp_d(&t1, 1) == MP_EQ) |
wolfSSL | 15:117db924cf7c | 10502 | break; |
wolfSSL | 15:117db924cf7c | 10503 | res = mp_exptmod(&t1, &two, prime, &t1); |
wolfSSL | 15:117db924cf7c | 10504 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10505 | i++; |
wolfSSL | 15:117db924cf7c | 10506 | } |
wolfSSL | 15:117db924cf7c | 10507 | if (res == MP_OKAY && i == 0) { |
wolfSSL | 15:117db924cf7c | 10508 | res = mp_copy(&R, ret); |
wolfSSL | 15:117db924cf7c | 10509 | done = 1; |
wolfSSL | 15:117db924cf7c | 10510 | } |
wolfSSL | 15:117db924cf7c | 10511 | |
wolfSSL | 15:117db924cf7c | 10512 | if (done == 0) { |
wolfSSL | 15:117db924cf7c | 10513 | /* t1 = 2 ^ (M - i - 1) */ |
wolfSSL | 15:117db924cf7c | 10514 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10515 | res = mp_sub_d(&M, i, &t1); |
wolfSSL | 15:117db924cf7c | 10516 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10517 | res = mp_sub_d(&t1, 1, &t1); |
wolfSSL | 15:117db924cf7c | 10518 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10519 | res = mp_exptmod(&two, &t1, prime, &t1); |
wolfSSL | 15:117db924cf7c | 10520 | |
wolfSSL | 15:117db924cf7c | 10521 | /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ |
wolfSSL | 15:117db924cf7c | 10522 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10523 | res = mp_exptmod(&C, &t1, prime, &t1); |
wolfSSL | 15:117db924cf7c | 10524 | |
wolfSSL | 15:117db924cf7c | 10525 | /* C = (t1 * t1) mod prime */ |
wolfSSL | 15:117db924cf7c | 10526 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10527 | res = mp_sqrmod(&t1, prime, &C); |
wolfSSL | 15:117db924cf7c | 10528 | |
wolfSSL | 15:117db924cf7c | 10529 | /* R = (R * t1) mod prime */ |
wolfSSL | 15:117db924cf7c | 10530 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10531 | res = mp_mulmod(&R, &t1, prime, &R); |
wolfSSL | 15:117db924cf7c | 10532 | |
wolfSSL | 15:117db924cf7c | 10533 | /* T = (T * C) mod prime */ |
wolfSSL | 15:117db924cf7c | 10534 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10535 | res = mp_mulmod(&T, &C, prime, &T); |
wolfSSL | 15:117db924cf7c | 10536 | |
wolfSSL | 15:117db924cf7c | 10537 | /* M = i */ |
wolfSSL | 15:117db924cf7c | 10538 | if (res == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 10539 | res = mp_set(&M, i); |
wolfSSL | 15:117db924cf7c | 10540 | } |
wolfSSL | 15:117db924cf7c | 10541 | } |
wolfSSL | 15:117db924cf7c | 10542 | } |
wolfSSL | 15:117db924cf7c | 10543 | |
wolfSSL | 15:117db924cf7c | 10544 | /* done */ |
wolfSSL | 15:117db924cf7c | 10545 | mp_clear(&t1); |
wolfSSL | 15:117db924cf7c | 10546 | mp_clear(&C); |
wolfSSL | 15:117db924cf7c | 10547 | mp_clear(&Q); |
wolfSSL | 15:117db924cf7c | 10548 | mp_clear(&S); |
wolfSSL | 15:117db924cf7c | 10549 | mp_clear(&Z); |
wolfSSL | 15:117db924cf7c | 10550 | mp_clear(&M); |
wolfSSL | 15:117db924cf7c | 10551 | mp_clear(&T); |
wolfSSL | 15:117db924cf7c | 10552 | mp_clear(&R); |
wolfSSL | 15:117db924cf7c | 10553 | mp_clear(&two); |
wolfSSL | 15:117db924cf7c | 10554 | |
wolfSSL | 15:117db924cf7c | 10555 | return res; |
wolfSSL | 15:117db924cf7c | 10556 | #endif |
wolfSSL | 15:117db924cf7c | 10557 | } |
wolfSSL | 15:117db924cf7c | 10558 | #endif |
wolfSSL | 16:8e0d178b1d1e | 10559 | #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */ |
wolfSSL | 15:117db924cf7c | 10560 | |
wolfSSL | 15:117db924cf7c | 10561 | |
wolfSSL | 15:117db924cf7c | 10562 | /* export public ECC key in ANSI X9.63 format compressed */ |
wolfSSL | 15:117db924cf7c | 10563 | static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) |
wolfSSL | 15:117db924cf7c | 10564 | { |
wolfSSL | 15:117db924cf7c | 10565 | word32 numlen; |
wolfSSL | 15:117db924cf7c | 10566 | int ret = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 10567 | |
wolfSSL | 15:117db924cf7c | 10568 | if (key == NULL || out == NULL || outLen == NULL) |
wolfSSL | 15:117db924cf7c | 10569 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10570 | |
wolfSSL | 15:117db924cf7c | 10571 | if (wc_ecc_is_valid_idx(key->idx) == 0) { |
wolfSSL | 15:117db924cf7c | 10572 | return ECC_BAD_ARG_E; |
wolfSSL | 15:117db924cf7c | 10573 | } |
wolfSSL | 15:117db924cf7c | 10574 | numlen = key->dp->size; |
wolfSSL | 15:117db924cf7c | 10575 | |
wolfSSL | 15:117db924cf7c | 10576 | if (*outLen < (1 + numlen)) { |
wolfSSL | 15:117db924cf7c | 10577 | *outLen = 1 + numlen; |
wolfSSL | 15:117db924cf7c | 10578 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 10579 | } |
wolfSSL | 15:117db924cf7c | 10580 | |
wolfSSL | 15:117db924cf7c | 10581 | /* store first byte */ |
wolfSSL | 15:117db924cf7c | 10582 | out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; |
wolfSSL | 15:117db924cf7c | 10583 | |
wolfSSL | 15:117db924cf7c | 10584 | /* pad and store x */ |
wolfSSL | 15:117db924cf7c | 10585 | XMEMSET(out+1, 0, numlen); |
wolfSSL | 15:117db924cf7c | 10586 | ret = mp_to_unsigned_bin(key->pubkey.x, |
wolfSSL | 15:117db924cf7c | 10587 | out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); |
wolfSSL | 15:117db924cf7c | 10588 | *outLen = 1 + numlen; |
wolfSSL | 15:117db924cf7c | 10589 | |
wolfSSL | 15:117db924cf7c | 10590 | return ret; |
wolfSSL | 15:117db924cf7c | 10591 | } |
wolfSSL | 15:117db924cf7c | 10592 | |
wolfSSL | 15:117db924cf7c | 10593 | #endif /* HAVE_COMP_KEY */ |
wolfSSL | 15:117db924cf7c | 10594 | |
wolfSSL | 15:117db924cf7c | 10595 | |
wolfSSL | 15:117db924cf7c | 10596 | int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz) |
wolfSSL | 15:117db924cf7c | 10597 | { |
wolfSSL | 15:117db924cf7c | 10598 | int x; |
wolfSSL | 15:117db924cf7c | 10599 | |
wolfSSL | 15:117db924cf7c | 10600 | if (oidSum == 0) { |
wolfSSL | 15:117db924cf7c | 10601 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10602 | } |
wolfSSL | 15:117db924cf7c | 10603 | |
wolfSSL | 15:117db924cf7c | 10604 | /* find matching OID sum (based on encoded value) */ |
wolfSSL | 15:117db924cf7c | 10605 | for (x = 0; ecc_sets[x].size != 0; x++) { |
wolfSSL | 15:117db924cf7c | 10606 | if (ecc_sets[x].oidSum == oidSum) { |
wolfSSL | 16:8e0d178b1d1e | 10607 | int ret; |
wolfSSL | 15:117db924cf7c | 10608 | #ifdef HAVE_OID_ENCODING |
wolfSSL | 16:8e0d178b1d1e | 10609 | ret = 0; |
wolfSSL | 15:117db924cf7c | 10610 | /* check cache */ |
wolfSSL | 15:117db924cf7c | 10611 | oid_cache_t* o = &ecc_oid_cache[x]; |
wolfSSL | 15:117db924cf7c | 10612 | if (o->oidSz == 0) { |
wolfSSL | 15:117db924cf7c | 10613 | o->oidSz = sizeof(o->oid); |
wolfSSL | 15:117db924cf7c | 10614 | ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, |
wolfSSL | 15:117db924cf7c | 10615 | o->oid, &o->oidSz); |
wolfSSL | 15:117db924cf7c | 10616 | } |
wolfSSL | 15:117db924cf7c | 10617 | if (oidSz) { |
wolfSSL | 15:117db924cf7c | 10618 | *oidSz = o->oidSz; |
wolfSSL | 15:117db924cf7c | 10619 | } |
wolfSSL | 15:117db924cf7c | 10620 | if (oid) { |
wolfSSL | 15:117db924cf7c | 10621 | *oid = o->oid; |
wolfSSL | 15:117db924cf7c | 10622 | } |
wolfSSL | 16:8e0d178b1d1e | 10623 | /* on success return curve id */ |
wolfSSL | 16:8e0d178b1d1e | 10624 | if (ret == 0) { |
wolfSSL | 16:8e0d178b1d1e | 10625 | ret = ecc_sets[x].id; |
wolfSSL | 16:8e0d178b1d1e | 10626 | } |
wolfSSL | 15:117db924cf7c | 10627 | #else |
wolfSSL | 15:117db924cf7c | 10628 | if (oidSz) { |
wolfSSL | 15:117db924cf7c | 10629 | *oidSz = ecc_sets[x].oidSz; |
wolfSSL | 15:117db924cf7c | 10630 | } |
wolfSSL | 15:117db924cf7c | 10631 | if (oid) { |
wolfSSL | 15:117db924cf7c | 10632 | *oid = ecc_sets[x].oid; |
wolfSSL | 15:117db924cf7c | 10633 | } |
wolfSSL | 16:8e0d178b1d1e | 10634 | ret = ecc_sets[x].id; |
wolfSSL | 15:117db924cf7c | 10635 | #endif |
wolfSSL | 15:117db924cf7c | 10636 | return ret; |
wolfSSL | 15:117db924cf7c | 10637 | } |
wolfSSL | 15:117db924cf7c | 10638 | } |
wolfSSL | 15:117db924cf7c | 10639 | |
wolfSSL | 15:117db924cf7c | 10640 | return NOT_COMPILED_IN; |
wolfSSL | 15:117db924cf7c | 10641 | } |
wolfSSL | 15:117db924cf7c | 10642 | |
wolfSSL | 15:117db924cf7c | 10643 | #ifdef WOLFSSL_CUSTOM_CURVES |
wolfSSL | 15:117db924cf7c | 10644 | int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) |
wolfSSL | 15:117db924cf7c | 10645 | { |
wolfSSL | 15:117db924cf7c | 10646 | if (key == NULL || dp == NULL) { |
wolfSSL | 15:117db924cf7c | 10647 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10648 | } |
wolfSSL | 15:117db924cf7c | 10649 | |
wolfSSL | 15:117db924cf7c | 10650 | key->idx = ECC_CUSTOM_IDX; |
wolfSSL | 15:117db924cf7c | 10651 | key->dp = dp; |
wolfSSL | 15:117db924cf7c | 10652 | |
wolfSSL | 15:117db924cf7c | 10653 | return 0; |
wolfSSL | 15:117db924cf7c | 10654 | } |
wolfSSL | 15:117db924cf7c | 10655 | #endif /* WOLFSSL_CUSTOM_CURVES */ |
wolfSSL | 15:117db924cf7c | 10656 | |
wolfSSL | 15:117db924cf7c | 10657 | #ifdef HAVE_X963_KDF |
wolfSSL | 15:117db924cf7c | 10658 | |
wolfSSL | 15:117db924cf7c | 10659 | static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr) |
wolfSSL | 15:117db924cf7c | 10660 | { |
wolfSSL | 15:117db924cf7c | 10661 | int i; |
wolfSSL | 15:117db924cf7c | 10662 | |
wolfSSL | 15:117db924cf7c | 10663 | /* in network byte order so start at end and work back */ |
wolfSSL | 15:117db924cf7c | 10664 | for (i = 3; i >= 0; i--) { |
wolfSSL | 15:117db924cf7c | 10665 | if (++inOutCtr[i]) /* we're done unless we overflow */ |
wolfSSL | 15:117db924cf7c | 10666 | return; |
wolfSSL | 15:117db924cf7c | 10667 | } |
wolfSSL | 15:117db924cf7c | 10668 | } |
wolfSSL | 15:117db924cf7c | 10669 | |
wolfSSL | 15:117db924cf7c | 10670 | /* ASN X9.63 Key Derivation Function (SEC1) */ |
wolfSSL | 15:117db924cf7c | 10671 | int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz, |
wolfSSL | 15:117db924cf7c | 10672 | const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz) |
wolfSSL | 15:117db924cf7c | 10673 | { |
wolfSSL | 15:117db924cf7c | 10674 | int ret, i; |
wolfSSL | 15:117db924cf7c | 10675 | int digestSz, copySz; |
wolfSSL | 15:117db924cf7c | 10676 | int remaining = outSz; |
wolfSSL | 15:117db924cf7c | 10677 | byte* outIdx; |
wolfSSL | 15:117db924cf7c | 10678 | byte counter[4]; |
wolfSSL | 15:117db924cf7c | 10679 | byte tmp[WC_MAX_DIGEST_SIZE]; |
wolfSSL | 15:117db924cf7c | 10680 | |
wolfSSL | 15:117db924cf7c | 10681 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10682 | wc_HashAlg* hash; |
wolfSSL | 15:117db924cf7c | 10683 | #else |
wolfSSL | 15:117db924cf7c | 10684 | wc_HashAlg hash[1]; |
wolfSSL | 15:117db924cf7c | 10685 | #endif |
wolfSSL | 15:117db924cf7c | 10686 | |
wolfSSL | 15:117db924cf7c | 10687 | if (secret == NULL || secretSz == 0 || out == NULL) |
wolfSSL | 15:117db924cf7c | 10688 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10689 | |
wolfSSL | 15:117db924cf7c | 10690 | /* X9.63 allowed algos only */ |
wolfSSL | 15:117db924cf7c | 10691 | if (type != WC_HASH_TYPE_SHA && type != WC_HASH_TYPE_SHA224 && |
wolfSSL | 15:117db924cf7c | 10692 | type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 && |
wolfSSL | 15:117db924cf7c | 10693 | type != WC_HASH_TYPE_SHA512) |
wolfSSL | 15:117db924cf7c | 10694 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 10695 | |
wolfSSL | 15:117db924cf7c | 10696 | digestSz = wc_HashGetDigestSize(type); |
wolfSSL | 15:117db924cf7c | 10697 | if (digestSz < 0) |
wolfSSL | 15:117db924cf7c | 10698 | return digestSz; |
wolfSSL | 15:117db924cf7c | 10699 | |
wolfSSL | 15:117db924cf7c | 10700 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10701 | hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL, |
wolfSSL | 15:117db924cf7c | 10702 | DYNAMIC_TYPE_HASHES); |
wolfSSL | 15:117db924cf7c | 10703 | if (hash == NULL) |
wolfSSL | 15:117db924cf7c | 10704 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 10705 | #endif |
wolfSSL | 15:117db924cf7c | 10706 | |
wolfSSL | 15:117db924cf7c | 10707 | ret = wc_HashInit(hash, type); |
wolfSSL | 15:117db924cf7c | 10708 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 10709 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10710 | XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); |
wolfSSL | 15:117db924cf7c | 10711 | #endif |
wolfSSL | 15:117db924cf7c | 10712 | return ret; |
wolfSSL | 15:117db924cf7c | 10713 | } |
wolfSSL | 15:117db924cf7c | 10714 | |
wolfSSL | 15:117db924cf7c | 10715 | outIdx = out; |
wolfSSL | 15:117db924cf7c | 10716 | XMEMSET(counter, 0, sizeof(counter)); |
wolfSSL | 15:117db924cf7c | 10717 | |
wolfSSL | 15:117db924cf7c | 10718 | for (i = 1; remaining > 0; i++) { |
wolfSSL | 15:117db924cf7c | 10719 | |
wolfSSL | 15:117db924cf7c | 10720 | IncrementX963KdfCounter(counter); |
wolfSSL | 15:117db924cf7c | 10721 | |
wolfSSL | 15:117db924cf7c | 10722 | ret = wc_HashUpdate(hash, type, secret, secretSz); |
wolfSSL | 15:117db924cf7c | 10723 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 10724 | break; |
wolfSSL | 15:117db924cf7c | 10725 | } |
wolfSSL | 15:117db924cf7c | 10726 | |
wolfSSL | 15:117db924cf7c | 10727 | ret = wc_HashUpdate(hash, type, counter, sizeof(counter)); |
wolfSSL | 15:117db924cf7c | 10728 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 10729 | break; |
wolfSSL | 15:117db924cf7c | 10730 | } |
wolfSSL | 15:117db924cf7c | 10731 | |
wolfSSL | 15:117db924cf7c | 10732 | if (sinfo) { |
wolfSSL | 15:117db924cf7c | 10733 | ret = wc_HashUpdate(hash, type, sinfo, sinfoSz); |
wolfSSL | 15:117db924cf7c | 10734 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 10735 | break; |
wolfSSL | 15:117db924cf7c | 10736 | } |
wolfSSL | 15:117db924cf7c | 10737 | } |
wolfSSL | 15:117db924cf7c | 10738 | |
wolfSSL | 15:117db924cf7c | 10739 | ret = wc_HashFinal(hash, type, tmp); |
wolfSSL | 15:117db924cf7c | 10740 | if (ret != 0) { |
wolfSSL | 16:8e0d178b1d1e | 10741 | break; |
wolfSSL | 15:117db924cf7c | 10742 | } |
wolfSSL | 15:117db924cf7c | 10743 | |
wolfSSL | 15:117db924cf7c | 10744 | copySz = min(remaining, digestSz); |
wolfSSL | 15:117db924cf7c | 10745 | XMEMCPY(outIdx, tmp, copySz); |
wolfSSL | 15:117db924cf7c | 10746 | |
wolfSSL | 15:117db924cf7c | 10747 | remaining -= copySz; |
wolfSSL | 15:117db924cf7c | 10748 | outIdx += copySz; |
wolfSSL | 15:117db924cf7c | 10749 | } |
wolfSSL | 15:117db924cf7c | 10750 | |
wolfSSL | 16:8e0d178b1d1e | 10751 | wc_HashFree(hash, type); |
wolfSSL | 16:8e0d178b1d1e | 10752 | |
wolfSSL | 15:117db924cf7c | 10753 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 10754 | XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); |
wolfSSL | 15:117db924cf7c | 10755 | #endif |
wolfSSL | 15:117db924cf7c | 10756 | |
wolfSSL | 16:8e0d178b1d1e | 10757 | return ret; |
wolfSSL | 15:117db924cf7c | 10758 | } |
wolfSSL | 15:117db924cf7c | 10759 | #endif /* HAVE_X963_KDF */ |
wolfSSL | 15:117db924cf7c | 10760 | |
wolfSSL | 15:117db924cf7c | 10761 | #endif /* HAVE_ECC */ |
wolfSSL | 15:117db924cf7c | 10762 |