wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

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?

UserRevisionLine numberNew 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