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

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

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 7:481bce714567 1 /* ecc.c
wolfSSL 7:481bce714567 2 *
wolfSSL 7:481bce714567 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 7:481bce714567 4 *
wolfSSL 7:481bce714567 5 * This file is part of wolfSSL.
wolfSSL 7:481bce714567 6 *
wolfSSL 7:481bce714567 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 7:481bce714567 8 * it under the terms of the GNU General Public License as published by
wolfSSL 7:481bce714567 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 7:481bce714567 10 * (at your option) any later version.
wolfSSL 7:481bce714567 11 *
wolfSSL 7:481bce714567 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 7:481bce714567 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 7:481bce714567 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 7:481bce714567 15 * GNU General Public License for more details.
wolfSSL 7:481bce714567 16 *
wolfSSL 7:481bce714567 17 * You should have received a copy of the GNU General Public License
wolfSSL 7:481bce714567 18 * along with this program; if not, write to the Free Software
wolfSSL 7:481bce714567 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 7:481bce714567 20 */
wolfSSL 7:481bce714567 21
wolfSSL 7:481bce714567 22
wolfSSL 7:481bce714567 23
wolfSSL 7:481bce714567 24 #ifdef HAVE_CONFIG_H
wolfSSL 7:481bce714567 25 #include <config.h>
wolfSSL 7:481bce714567 26 #endif
wolfSSL 7:481bce714567 27
wolfSSL 7:481bce714567 28 /* in case user set HAVE_ECC there */
wolfSSL 7:481bce714567 29 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 7:481bce714567 30
wolfSSL 7:481bce714567 31 /*
wolfSSL 7:481bce714567 32 Possible ECC enable options:
wolfSSL 7:481bce714567 33 * HAVE_ECC: Overall control of ECC default: on
wolfSSL 7:481bce714567 34 * HAVE_ECC_ENCRYPT: ECC encrypt/decrypt w/AES and HKDF default: off
wolfSSL 7:481bce714567 35 * HAVE_ECC_SIGN: ECC sign default: on
wolfSSL 7:481bce714567 36 * HAVE_ECC_VERIFY: ECC verify default: on
wolfSSL 7:481bce714567 37 * HAVE_ECC_DHE: ECC build shared secret default: on
wolfSSL 7:481bce714567 38 * HAVE_ECC_CDH: ECC cofactor DH shared secret default: off
wolfSSL 7:481bce714567 39 * HAVE_ECC_KEY_IMPORT: ECC Key import default: on
wolfSSL 7:481bce714567 40 * HAVE_ECC_KEY_EXPORT: ECC Key export default: on
wolfSSL 7:481bce714567 41 * ECC_SHAMIR: Enables Shamir calc method default: on
wolfSSL 7:481bce714567 42 * HAVE_COMP_KEY: Enables compressed key default: off
wolfSSL 7:481bce714567 43 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off
wolfSSL 7:481bce714567 44 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen default: off
wolfSSL 7:481bce714567 45 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off
wolfSSL 7:481bce714567 46 * Includes the curve "a" variable in calculation
wolfSSL 7:481bce714567 47 * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off
wolfSSL 7:481bce714567 48 * ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance
wolfSSL 7:481bce714567 49 default: off
wolfSSL 7:481bce714567 50 * FP_ECC: ECC Fixed Point Cache default: off
wolfSSL 7:481bce714567 51 * USE_ECC_B_PARAM: Enable ECC curve B param default: off
wolfSSL 7:481bce714567 52 (on for HAVE_COMP_KEY)
wolfSSL 7:481bce714567 53 */
wolfSSL 7:481bce714567 54
wolfSSL 7:481bce714567 55 /*
wolfSSL 7:481bce714567 56 ECC Curve Types:
wolfSSL 7:481bce714567 57 * NO_ECC_SECP Disables SECP curves default: off (not defined)
wolfSSL 7:481bce714567 58 * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off
wolfSSL 7:481bce714567 59 * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off
wolfSSL 7:481bce714567 60 * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off
wolfSSL 7:481bce714567 61 * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off
wolfSSL 7:481bce714567 62 */
wolfSSL 7:481bce714567 63
wolfSSL 7:481bce714567 64 /*
wolfSSL 7:481bce714567 65 ECC Curve Sizes:
wolfSSL 7:481bce714567 66 * ECC_USER_CURVES: Allows custom combination of key sizes below
wolfSSL 7:481bce714567 67 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
wolfSSL 7:481bce714567 68 * HAVE_ECC112: 112 bit key
wolfSSL 7:481bce714567 69 * HAVE_ECC128: 128 bit key
wolfSSL 7:481bce714567 70 * HAVE_ECC160: 160 bit key
wolfSSL 7:481bce714567 71 * HAVE_ECC192: 192 bit key
wolfSSL 7:481bce714567 72 * HAVE_ECC224: 224 bit key
wolfSSL 7:481bce714567 73 * HAVE_ECC239: 239 bit key
wolfSSL 7:481bce714567 74 * NO_ECC256: Disables 256 bit key (on by default)
wolfSSL 7:481bce714567 75 * HAVE_ECC320: 320 bit key
wolfSSL 7:481bce714567 76 * HAVE_ECC384: 384 bit key
wolfSSL 7:481bce714567 77 * HAVE_ECC512: 512 bit key
wolfSSL 7:481bce714567 78 * HAVE_ECC521: 521 bit key
wolfSSL 7:481bce714567 79 */
wolfSSL 7:481bce714567 80
wolfSSL 7:481bce714567 81
wolfSSL 7:481bce714567 82 #ifdef HAVE_ECC
wolfSSL 7:481bce714567 83
wolfSSL 7:481bce714567 84 /* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
wolfSSL 7:481bce714567 85 #if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
wolfSSL 7:481bce714567 86 !defined(WOLFSSL_CUSTOM_CURVES)
wolfSSL 7:481bce714567 87 #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
wolfSSL 7:481bce714567 88 #endif
wolfSSL 7:481bce714567 89
wolfSSL 7:481bce714567 90 /* Make sure ASN is enabled for ECC sign/verify */
wolfSSL 7:481bce714567 91 #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN)
wolfSSL 7:481bce714567 92 #error ASN must be enabled for ECC sign/verify
wolfSSL 7:481bce714567 93 #endif
wolfSSL 7:481bce714567 94
wolfSSL 7:481bce714567 95
wolfSSL 7:481bce714567 96 #include <wolfssl/wolfcrypt/ecc.h>
wolfSSL 7:481bce714567 97 #include <wolfssl/wolfcrypt/asn.h>
wolfSSL 7:481bce714567 98 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 7:481bce714567 99 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 7:481bce714567 100
wolfSSL 7:481bce714567 101 #ifdef HAVE_ECC_ENCRYPT
wolfSSL 7:481bce714567 102 #include <wolfssl/wolfcrypt/hmac.h>
wolfSSL 7:481bce714567 103 #include <wolfssl/wolfcrypt/aes.h>
wolfSSL 7:481bce714567 104 #endif
wolfSSL 7:481bce714567 105
wolfSSL 7:481bce714567 106 #ifdef HAVE_X963_KDF
wolfSSL 7:481bce714567 107 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 7:481bce714567 108 #endif
wolfSSL 7:481bce714567 109
wolfSSL 7:481bce714567 110 #ifdef NO_INLINE
wolfSSL 7:481bce714567 111 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 7:481bce714567 112 #else
wolfSSL 7:481bce714567 113 #define WOLFSSL_MISC_INCLUDED
wolfSSL 7:481bce714567 114 #include <wolfcrypt/src/misc.c>
wolfSSL 7:481bce714567 115 #endif
wolfSSL 7:481bce714567 116
wolfSSL 7:481bce714567 117 #if defined(FREESCALE_LTC_ECC)
wolfSSL 7:481bce714567 118 #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
wolfSSL 7:481bce714567 119 #endif
wolfSSL 7:481bce714567 120
wolfSSL 7:481bce714567 121 #ifdef USE_FAST_MATH
wolfSSL 7:481bce714567 122 #define GEN_MEM_ERR FP_MEM
wolfSSL 7:481bce714567 123 #else
wolfSSL 7:481bce714567 124 #define GEN_MEM_ERR MP_MEM
wolfSSL 7:481bce714567 125 #endif
wolfSSL 7:481bce714567 126
wolfSSL 7:481bce714567 127
wolfSSL 7:481bce714567 128 /* internal ECC states */
wolfSSL 7:481bce714567 129 enum {
wolfSSL 7:481bce714567 130 ECC_STATE_NONE = 0,
wolfSSL 7:481bce714567 131
wolfSSL 7:481bce714567 132 ECC_STATE_SHARED_SEC_GEN,
wolfSSL 7:481bce714567 133 ECC_STATE_SHARED_SEC_RES,
wolfSSL 7:481bce714567 134
wolfSSL 7:481bce714567 135 ECC_STATE_SIGN_DO,
wolfSSL 7:481bce714567 136 ECC_STATE_SIGN_ENCODE,
wolfSSL 7:481bce714567 137
wolfSSL 7:481bce714567 138 ECC_STATE_VERIFY_DECODE,
wolfSSL 7:481bce714567 139 ECC_STATE_VERIFY_DO,
wolfSSL 7:481bce714567 140 ECC_STATE_VERIFY_RES,
wolfSSL 7:481bce714567 141 };
wolfSSL 7:481bce714567 142
wolfSSL 7:481bce714567 143
wolfSSL 7:481bce714567 144 /* map
wolfSSL 7:481bce714567 145 ptmul -> mulmod
wolfSSL 7:481bce714567 146 */
wolfSSL 7:481bce714567 147
wolfSSL 7:481bce714567 148 /* 256-bit curve on by default whether user curves or not */
wolfSSL 7:481bce714567 149 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 150 #define ECC112
wolfSSL 7:481bce714567 151 #endif
wolfSSL 7:481bce714567 152 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 153 #define ECC128
wolfSSL 7:481bce714567 154 #endif
wolfSSL 7:481bce714567 155 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 156 #define ECC160
wolfSSL 7:481bce714567 157 #endif
wolfSSL 7:481bce714567 158 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 159 #define ECC192
wolfSSL 7:481bce714567 160 #endif
wolfSSL 7:481bce714567 161 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 162 #define ECC224
wolfSSL 7:481bce714567 163 #endif
wolfSSL 7:481bce714567 164 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 165 #define ECC239
wolfSSL 7:481bce714567 166 #endif
wolfSSL 7:481bce714567 167 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 168 #define ECC256
wolfSSL 7:481bce714567 169 #endif
wolfSSL 7:481bce714567 170 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 171 #define ECC320
wolfSSL 7:481bce714567 172 #endif
wolfSSL 7:481bce714567 173 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 174 #define ECC384
wolfSSL 7:481bce714567 175 #endif
wolfSSL 7:481bce714567 176 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 177 #define ECC512
wolfSSL 7:481bce714567 178 #endif
wolfSSL 7:481bce714567 179 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
wolfSSL 7:481bce714567 180 #define ECC521
wolfSSL 7:481bce714567 181 #endif
wolfSSL 7:481bce714567 182
wolfSSL 7:481bce714567 183
wolfSSL 7:481bce714567 184 /* The encoded OID's for ECC curves */
wolfSSL 7:481bce714567 185 #ifdef ECC112
wolfSSL 7:481bce714567 186 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 187 static const ecc_oid_t ecc_oid_secp112r1[] = {
wolfSSL 7:481bce714567 188 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 189 1,3,132,0,6
wolfSSL 7:481bce714567 190 #else
wolfSSL 7:481bce714567 191 0x2B,0x81,0x04,0x00,0x06
wolfSSL 7:481bce714567 192 #endif
wolfSSL 7:481bce714567 193 };
wolfSSL 7:481bce714567 194 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 195 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 196 static const ecc_oid_t ecc_oid_secp112r2[] = {
wolfSSL 7:481bce714567 197 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 198 1,3,132,0,7
wolfSSL 7:481bce714567 199 #else
wolfSSL 7:481bce714567 200 0x2B,0x81,0x04,0x00,0x07
wolfSSL 7:481bce714567 201 #endif
wolfSSL 7:481bce714567 202 };
wolfSSL 7:481bce714567 203 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 204 #endif /* ECC112 */
wolfSSL 7:481bce714567 205 #ifdef ECC128
wolfSSL 7:481bce714567 206 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 207 static const ecc_oid_t ecc_oid_secp128r1[] = {
wolfSSL 7:481bce714567 208 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 209 1,3,132,0,28
wolfSSL 7:481bce714567 210 #else
wolfSSL 7:481bce714567 211 0x2B,0x81,0x04,0x00,0x1C
wolfSSL 7:481bce714567 212 #endif
wolfSSL 7:481bce714567 213 };
wolfSSL 7:481bce714567 214 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 215 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 216 static const ecc_oid_t ecc_oid_secp128r2[] = {
wolfSSL 7:481bce714567 217 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 218 1,3,132,0,29
wolfSSL 7:481bce714567 219 #else
wolfSSL 7:481bce714567 220 0x2B,0x81,0x04,0x00,0x1D
wolfSSL 7:481bce714567 221 #endif
wolfSSL 7:481bce714567 222 };
wolfSSL 7:481bce714567 223 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 224 #endif /* ECC128 */
wolfSSL 7:481bce714567 225 #ifdef ECC160
wolfSSL 7:481bce714567 226 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 227 static const ecc_oid_t ecc_oid_secp160r1[] = {
wolfSSL 7:481bce714567 228 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 229 1,3,132,0,8
wolfSSL 7:481bce714567 230 #else
wolfSSL 7:481bce714567 231 0x2B,0x81,0x04,0x00,0x08
wolfSSL 7:481bce714567 232 #endif
wolfSSL 7:481bce714567 233 };
wolfSSL 7:481bce714567 234 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 235 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 236 static const ecc_oid_t ecc_oid_secp160r2[] = {
wolfSSL 7:481bce714567 237 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 238 1,3,132,0,30
wolfSSL 7:481bce714567 239 #else
wolfSSL 7:481bce714567 240 0x2B,0x81,0x04,0x00,0x1E
wolfSSL 7:481bce714567 241 #endif
wolfSSL 7:481bce714567 242 };
wolfSSL 7:481bce714567 243 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 244 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 245 static const ecc_oid_t ecc_oid_secp160k1[] = {
wolfSSL 7:481bce714567 246 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 247 1,3,132,0,9
wolfSSL 7:481bce714567 248 #else
wolfSSL 7:481bce714567 249 0x2B,0x81,0x04,0x00,0x09
wolfSSL 7:481bce714567 250 #endif
wolfSSL 7:481bce714567 251 };
wolfSSL 7:481bce714567 252 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 253 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 254 static const ecc_oid_t ecc_oid_brainpoolp160r1[] = {
wolfSSL 7:481bce714567 255 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 256 1,3,36,3,3,2,8,1,1,1
wolfSSL 7:481bce714567 257 #else
wolfSSL 7:481bce714567 258 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01
wolfSSL 7:481bce714567 259 #endif
wolfSSL 7:481bce714567 260 };
wolfSSL 7:481bce714567 261 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 262 #endif /* ECC160 */
wolfSSL 7:481bce714567 263 #ifdef ECC192
wolfSSL 7:481bce714567 264 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 265 static const ecc_oid_t ecc_oid_secp192r1[] = {
wolfSSL 7:481bce714567 266 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 267 1,2,840,10045,3,1,1
wolfSSL 7:481bce714567 268 #else
wolfSSL 7:481bce714567 269 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01
wolfSSL 7:481bce714567 270 #endif
wolfSSL 7:481bce714567 271 };
wolfSSL 7:481bce714567 272 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 273 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 274 static const ecc_oid_t ecc_oid_prime192v2[] = {
wolfSSL 7:481bce714567 275 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 276 1,2,840,10045,3,1,2
wolfSSL 7:481bce714567 277 #else
wolfSSL 7:481bce714567 278 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02
wolfSSL 7:481bce714567 279 #endif
wolfSSL 7:481bce714567 280 };
wolfSSL 7:481bce714567 281 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 282 #ifdef HAVE_ECC_SECPR3
wolfSSL 7:481bce714567 283 static const ecc_oid_t ecc_oid_prime192v3[] = {
wolfSSL 7:481bce714567 284 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 285 1,2,840,10045,3,1,3
wolfSSL 7:481bce714567 286 #else
wolfSSL 7:481bce714567 287 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03
wolfSSL 7:481bce714567 288 #endif
wolfSSL 7:481bce714567 289 };
wolfSSL 7:481bce714567 290 #endif /* HAVE_ECC_SECPR3 */
wolfSSL 7:481bce714567 291 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 292 static const ecc_oid_t ecc_oid_secp192k1[] = {
wolfSSL 7:481bce714567 293 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 294 1,3,132,0,31
wolfSSL 7:481bce714567 295 #else
wolfSSL 7:481bce714567 296 0x2B,0x81,0x04,0x00,0x1F
wolfSSL 7:481bce714567 297 #endif
wolfSSL 7:481bce714567 298 };
wolfSSL 7:481bce714567 299 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 300 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 301 static const ecc_oid_t ecc_oid_brainpoolp192r1[] = {
wolfSSL 7:481bce714567 302 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 303 1,3,36,3,3,2,8,1,1,3
wolfSSL 7:481bce714567 304 #else
wolfSSL 7:481bce714567 305 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03
wolfSSL 7:481bce714567 306 #endif
wolfSSL 7:481bce714567 307 };
wolfSSL 7:481bce714567 308 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 309 #endif /* ECC192 */
wolfSSL 7:481bce714567 310 #ifdef ECC224
wolfSSL 7:481bce714567 311 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 312 static const ecc_oid_t ecc_oid_secp224r1[] = {
wolfSSL 7:481bce714567 313 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 314 1,3,132,0,33
wolfSSL 7:481bce714567 315 #else
wolfSSL 7:481bce714567 316 0x2B,0x81,0x04,0x00,0x21
wolfSSL 7:481bce714567 317 #endif
wolfSSL 7:481bce714567 318 };
wolfSSL 7:481bce714567 319 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 320 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 321 static const ecc_oid_t ecc_oid_secp224k1[] = {
wolfSSL 7:481bce714567 322 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 323 1,3,132,0,32
wolfSSL 7:481bce714567 324 #else
wolfSSL 7:481bce714567 325 0x2B,0x81,0x04,0x00,0x20
wolfSSL 7:481bce714567 326 #endif
wolfSSL 7:481bce714567 327 };
wolfSSL 7:481bce714567 328 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 329 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 330 static const ecc_oid_t ecc_oid_brainpoolp224r1[] = {
wolfSSL 7:481bce714567 331 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 332 1,3,36,3,3,2,8,1,1,5
wolfSSL 7:481bce714567 333 #else
wolfSSL 7:481bce714567 334 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05
wolfSSL 7:481bce714567 335 #endif
wolfSSL 7:481bce714567 336 };
wolfSSL 7:481bce714567 337 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 338 #endif /* ECC224 */
wolfSSL 7:481bce714567 339 #ifdef ECC239
wolfSSL 7:481bce714567 340 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 341 static const ecc_oid_t ecc_oid_prime239v1[] = {
wolfSSL 7:481bce714567 342 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 343 1,2,840,10045,3,1,4
wolfSSL 7:481bce714567 344 #else
wolfSSL 7:481bce714567 345 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04
wolfSSL 7:481bce714567 346 #endif
wolfSSL 7:481bce714567 347 };
wolfSSL 7:481bce714567 348 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 349 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 350 static const ecc_oid_t ecc_oid_prime239v2[] = {
wolfSSL 7:481bce714567 351 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 352 1,2,840,10045,3,1,5
wolfSSL 7:481bce714567 353 #else
wolfSSL 7:481bce714567 354 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05
wolfSSL 7:481bce714567 355 #endif
wolfSSL 7:481bce714567 356 };
wolfSSL 7:481bce714567 357 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 358 #ifdef HAVE_ECC_SECPR3
wolfSSL 7:481bce714567 359 static const ecc_oid_t ecc_oid_prime239v3[] = {
wolfSSL 7:481bce714567 360 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 361 1,2,840,10045,3,1,6
wolfSSL 7:481bce714567 362 #else
wolfSSL 7:481bce714567 363 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06
wolfSSL 7:481bce714567 364 #endif
wolfSSL 7:481bce714567 365 };
wolfSSL 7:481bce714567 366 #endif /* HAVE_ECC_SECPR3 */
wolfSSL 7:481bce714567 367 #endif /* ECC239 */
wolfSSL 7:481bce714567 368 #ifdef ECC256
wolfSSL 7:481bce714567 369 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 370 static const ecc_oid_t ecc_oid_secp256r1[] = {
wolfSSL 7:481bce714567 371 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 372 1,2,840,10045,3,1,7
wolfSSL 7:481bce714567 373 #else
wolfSSL 7:481bce714567 374 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07
wolfSSL 7:481bce714567 375 #endif
wolfSSL 7:481bce714567 376 };
wolfSSL 7:481bce714567 377 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 378 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 379 static const ecc_oid_t ecc_oid_secp256k1[] = {
wolfSSL 7:481bce714567 380 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 381 1,3,132,0,10
wolfSSL 7:481bce714567 382 #else
wolfSSL 7:481bce714567 383 0x2B,0x81,0x04,0x00,0x0A
wolfSSL 7:481bce714567 384 #endif
wolfSSL 7:481bce714567 385 };
wolfSSL 7:481bce714567 386 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 387 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 388 static const ecc_oid_t ecc_oid_brainpoolp256r1[] = {
wolfSSL 7:481bce714567 389 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 390 1,3,36,3,3,2,8,1,1,7
wolfSSL 7:481bce714567 391 #else
wolfSSL 7:481bce714567 392 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07
wolfSSL 7:481bce714567 393 #endif
wolfSSL 7:481bce714567 394 };
wolfSSL 7:481bce714567 395 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 396 #endif /* ECC256 */
wolfSSL 7:481bce714567 397 #ifdef ECC320
wolfSSL 7:481bce714567 398 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 399 static const ecc_oid_t ecc_oid_brainpoolp320r1[] = {
wolfSSL 7:481bce714567 400 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 401 1,3,36,3,3,2,8,1,1,9
wolfSSL 7:481bce714567 402 #else
wolfSSL 7:481bce714567 403 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09
wolfSSL 7:481bce714567 404 #endif
wolfSSL 7:481bce714567 405 };
wolfSSL 7:481bce714567 406 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 407 #endif /* ECC320 */
wolfSSL 7:481bce714567 408 #ifdef ECC384
wolfSSL 7:481bce714567 409 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 410 static const ecc_oid_t ecc_oid_secp384r1[] = {
wolfSSL 7:481bce714567 411 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 412 1,3,132,0,34
wolfSSL 7:481bce714567 413 #else
wolfSSL 7:481bce714567 414 0x2B,0x81,0x04,0x00,0x22
wolfSSL 7:481bce714567 415 #endif
wolfSSL 7:481bce714567 416 };
wolfSSL 7:481bce714567 417 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 418 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 419 static const ecc_oid_t ecc_oid_brainpoolp384r1[] = {
wolfSSL 7:481bce714567 420 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 421 1,3,36,3,3,2,8,1,1,11
wolfSSL 7:481bce714567 422 #else
wolfSSL 7:481bce714567 423 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B
wolfSSL 7:481bce714567 424 #endif
wolfSSL 7:481bce714567 425 };
wolfSSL 7:481bce714567 426 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 427 #endif /* ECC384 */
wolfSSL 7:481bce714567 428 #ifdef ECC512
wolfSSL 7:481bce714567 429 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 430 static const ecc_oid_t ecc_oid_brainpoolp512r1[] = {
wolfSSL 7:481bce714567 431 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 432 1,3,36,3,3,2,8,1,1,13
wolfSSL 7:481bce714567 433 #else
wolfSSL 7:481bce714567 434 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D
wolfSSL 7:481bce714567 435 #endif
wolfSSL 7:481bce714567 436 };
wolfSSL 7:481bce714567 437 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 438 #endif /* ECC512 */
wolfSSL 7:481bce714567 439 #ifdef ECC521
wolfSSL 7:481bce714567 440 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 441 static const ecc_oid_t ecc_oid_secp521r1[] = {
wolfSSL 7:481bce714567 442 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 443 1,3,132,0,35
wolfSSL 7:481bce714567 444 #else
wolfSSL 7:481bce714567 445 0x2B,0x81,0x04,0x00,0x23
wolfSSL 7:481bce714567 446 #endif
wolfSSL 7:481bce714567 447 };
wolfSSL 7:481bce714567 448 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 449 #endif /* ECC521 */
wolfSSL 7:481bce714567 450
wolfSSL 7:481bce714567 451
wolfSSL 7:481bce714567 452 /* This holds the key settings.
wolfSSL 7:481bce714567 453 ***MUST*** be organized by size from smallest to largest. */
wolfSSL 7:481bce714567 454
wolfSSL 7:481bce714567 455 const ecc_set_type ecc_sets[] = {
wolfSSL 7:481bce714567 456 #ifdef ECC112
wolfSSL 7:481bce714567 457 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 458 {
wolfSSL 7:481bce714567 459 14, /* size/bytes */
wolfSSL 7:481bce714567 460 ECC_SECP112R1, /* ID */
wolfSSL 7:481bce714567 461 "SECP112R1", /* curve name */
wolfSSL 7:481bce714567 462 "DB7C2ABF62E35E668076BEAD208B", /* prime */
wolfSSL 7:481bce714567 463 "DB7C2ABF62E35E668076BEAD2088", /* A */
wolfSSL 7:481bce714567 464 "659EF8BA043916EEDE8911702B22", /* B */
wolfSSL 7:481bce714567 465 "DB7C2ABF62E35E7628DFAC6561C5", /* order */
wolfSSL 7:481bce714567 466 "9487239995A5EE76B55F9C2F098", /* Gx */
wolfSSL 7:481bce714567 467 "A89CE5AF8724C0A23E0E0FF77500", /* Gy */
wolfSSL 7:481bce714567 468 ecc_oid_secp112r1, /* oid/oidSz */
wolfSSL 7:481bce714567 469 sizeof(ecc_oid_secp112r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 470 ECC_SECP112R1_OID, /* oid sum */
wolfSSL 7:481bce714567 471 1, /* cofactor */
wolfSSL 7:481bce714567 472 },
wolfSSL 7:481bce714567 473 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 474 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 475 {
wolfSSL 7:481bce714567 476 14, /* size/bytes */
wolfSSL 7:481bce714567 477 ECC_SECP112R2, /* ID */
wolfSSL 7:481bce714567 478 "SECP112R2", /* curve name */
wolfSSL 7:481bce714567 479 "DB7C2ABF62E35E668076BEAD208B", /* prime */
wolfSSL 7:481bce714567 480 "6127C24C05F38A0AAAF65C0EF02C", /* A */
wolfSSL 7:481bce714567 481 "51DEF1815DB5ED74FCC34C85D709", /* B */
wolfSSL 7:481bce714567 482 "36DF0AAFD8B8D7597CA10520D04B", /* order */
wolfSSL 7:481bce714567 483 "4BA30AB5E892B4E1649DD0928643", /* Gx */
wolfSSL 7:481bce714567 484 "ADCD46F5882E3747DEF36E956E97", /* Gy */
wolfSSL 7:481bce714567 485 ecc_oid_secp112r2, /* oid/oidSz */
wolfSSL 7:481bce714567 486 sizeof(ecc_oid_secp112r2) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 487 ECC_SECP112R2_OID, /* oid sum */
wolfSSL 7:481bce714567 488 4, /* cofactor */
wolfSSL 7:481bce714567 489 },
wolfSSL 7:481bce714567 490 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 491 #endif /* ECC112 */
wolfSSL 7:481bce714567 492 #ifdef ECC128
wolfSSL 7:481bce714567 493 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 494 {
wolfSSL 7:481bce714567 495 16, /* size/bytes */
wolfSSL 7:481bce714567 496 ECC_SECP128R1, /* ID */
wolfSSL 7:481bce714567 497 "SECP128R1", /* curve name */
wolfSSL 7:481bce714567 498 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 499 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 500 "E87579C11079F43DD824993C2CEE5ED3", /* B */
wolfSSL 7:481bce714567 501 "FFFFFFFE0000000075A30D1B9038A115", /* order */
wolfSSL 7:481bce714567 502 "161FF7528B899B2D0C28607CA52C5B86", /* Gx */
wolfSSL 7:481bce714567 503 "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */
wolfSSL 7:481bce714567 504 ecc_oid_secp128r1, /* oid/oidSz */
wolfSSL 7:481bce714567 505 sizeof(ecc_oid_secp128r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 506 ECC_SECP128R1_OID, /* oid sum */
wolfSSL 7:481bce714567 507 1, /* cofactor */
wolfSSL 7:481bce714567 508 },
wolfSSL 7:481bce714567 509 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 510 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 511 {
wolfSSL 7:481bce714567 512 16, /* size/bytes */
wolfSSL 7:481bce714567 513 ECC_SECP128R2, /* ID */
wolfSSL 7:481bce714567 514 "SECP128R2", /* curve name */
wolfSSL 7:481bce714567 515 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 516 "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */
wolfSSL 7:481bce714567 517 "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */
wolfSSL 7:481bce714567 518 "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */
wolfSSL 7:481bce714567 519 "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */
wolfSSL 7:481bce714567 520 "27B6916A894D3AEE7106FE805FC34B44", /* Gy */
wolfSSL 7:481bce714567 521 ecc_oid_secp128r2, /* oid/oidSz */
wolfSSL 7:481bce714567 522 sizeof(ecc_oid_secp128r2) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 523 ECC_SECP128R2_OID, /* oid sum */
wolfSSL 7:481bce714567 524 4, /* cofactor */
wolfSSL 7:481bce714567 525 },
wolfSSL 7:481bce714567 526 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 527 #endif /* ECC128 */
wolfSSL 7:481bce714567 528 #ifdef ECC160
wolfSSL 7:481bce714567 529 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 530 {
wolfSSL 7:481bce714567 531 20, /* size/bytes */
wolfSSL 7:481bce714567 532 ECC_SECP160R1, /* ID */
wolfSSL 7:481bce714567 533 "SECP160R1", /* curve name */
wolfSSL 7:481bce714567 534 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */
wolfSSL 7:481bce714567 535 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */
wolfSSL 7:481bce714567 536 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */
wolfSSL 7:481bce714567 537 "100000000000000000001F4C8F927AED3CA752257",/* order */
wolfSSL 7:481bce714567 538 "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */
wolfSSL 7:481bce714567 539 "23A628553168947D59DCC912042351377AC5FB32", /* Gy */
wolfSSL 7:481bce714567 540 ecc_oid_secp160r1, /* oid/oidSz */
wolfSSL 7:481bce714567 541 sizeof(ecc_oid_secp160r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 542 ECC_SECP160R1_OID, /* oid sum */
wolfSSL 7:481bce714567 543 1, /* cofactor */
wolfSSL 7:481bce714567 544 },
wolfSSL 7:481bce714567 545 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 546 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 547 {
wolfSSL 7:481bce714567 548 20, /* size/bytes */
wolfSSL 7:481bce714567 549 ECC_SECP160R2, /* ID */
wolfSSL 7:481bce714567 550 "SECP160R2", /* curve name */
wolfSSL 7:481bce714567 551 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */
wolfSSL 7:481bce714567 552 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */
wolfSSL 7:481bce714567 553 "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */
wolfSSL 7:481bce714567 554 "100000000000000000000351EE786A818F3A1A16B",/* order */
wolfSSL 7:481bce714567 555 "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */
wolfSSL 7:481bce714567 556 "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */
wolfSSL 7:481bce714567 557 ecc_oid_secp160r2, /* oid/oidSz */
wolfSSL 7:481bce714567 558 sizeof(ecc_oid_secp160r2) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 559 ECC_SECP160R2_OID, /* oid sum */
wolfSSL 7:481bce714567 560 1, /* cofactor */
wolfSSL 7:481bce714567 561 },
wolfSSL 7:481bce714567 562 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 563 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 564 {
wolfSSL 7:481bce714567 565 20, /* size/bytes */
wolfSSL 7:481bce714567 566 ECC_SECP160K1, /* ID */
wolfSSL 7:481bce714567 567 "SECP160K1", /* curve name */
wolfSSL 7:481bce714567 568 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */
wolfSSL 7:481bce714567 569 "0000000000000000000000000000000000000000", /* A */
wolfSSL 7:481bce714567 570 "0000000000000000000000000000000000000007", /* B */
wolfSSL 7:481bce714567 571 "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */
wolfSSL 7:481bce714567 572 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */
wolfSSL 7:481bce714567 573 "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */
wolfSSL 7:481bce714567 574 ecc_oid_secp160k1, /* oid/oidSz */
wolfSSL 7:481bce714567 575 sizeof(ecc_oid_secp160k1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 576 ECC_SECP160K1_OID, /* oid sum */
wolfSSL 7:481bce714567 577 1, /* cofactor */
wolfSSL 7:481bce714567 578 },
wolfSSL 7:481bce714567 579 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 580 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 581 {
wolfSSL 7:481bce714567 582 20, /* size/bytes */
wolfSSL 7:481bce714567 583 ECC_BRAINPOOLP160R1, /* ID */
wolfSSL 7:481bce714567 584 "BRAINPOOLP160R1", /* curve name */
wolfSSL 7:481bce714567 585 "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */
wolfSSL 7:481bce714567 586 "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */
wolfSSL 7:481bce714567 587 "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */
wolfSSL 7:481bce714567 588 "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */
wolfSSL 7:481bce714567 589 "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */
wolfSSL 7:481bce714567 590 "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */
wolfSSL 7:481bce714567 591 ecc_oid_brainpoolp160r1, /* oid/oidSz */
wolfSSL 7:481bce714567 592 sizeof(ecc_oid_brainpoolp160r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 593 ECC_BRAINPOOLP160R1_OID, /* oid sum */
wolfSSL 7:481bce714567 594 1, /* cofactor */
wolfSSL 7:481bce714567 595 },
wolfSSL 7:481bce714567 596 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 597 #endif /* ECC160 */
wolfSSL 7:481bce714567 598 #ifdef ECC192
wolfSSL 7:481bce714567 599 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 600 {
wolfSSL 7:481bce714567 601 24, /* size/bytes */
wolfSSL 7:481bce714567 602 ECC_SECP192R1, /* ID */
wolfSSL 7:481bce714567 603 "SECP192R1", /* curve name */
wolfSSL 7:481bce714567 604 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 605 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 606 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B */
wolfSSL 7:481bce714567 607 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */
wolfSSL 7:481bce714567 608 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */
wolfSSL 7:481bce714567 609 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */
wolfSSL 7:481bce714567 610 ecc_oid_secp192r1, /* oid/oidSz */
wolfSSL 7:481bce714567 611 sizeof(ecc_oid_secp192r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 612 ECC_SECP192R1_OID, /* oid sum */
wolfSSL 7:481bce714567 613 1, /* cofactor */
wolfSSL 7:481bce714567 614 },
wolfSSL 7:481bce714567 615 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 616 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 617 {
wolfSSL 7:481bce714567 618 24, /* size/bytes */
wolfSSL 7:481bce714567 619 ECC_PRIME192V2, /* ID */
wolfSSL 7:481bce714567 620 "PRIME192V2", /* curve name */
wolfSSL 7:481bce714567 621 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 622 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 623 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */
wolfSSL 7:481bce714567 624 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */
wolfSSL 7:481bce714567 625 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */
wolfSSL 7:481bce714567 626 "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */
wolfSSL 7:481bce714567 627 ecc_oid_prime192v2, /* oid/oidSz */
wolfSSL 7:481bce714567 628 sizeof(ecc_oid_prime192v2) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 629 ECC_PRIME192V2_OID, /* oid sum */
wolfSSL 7:481bce714567 630 1, /* cofactor */
wolfSSL 7:481bce714567 631 },
wolfSSL 7:481bce714567 632 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 633 #ifdef HAVE_ECC_SECPR3
wolfSSL 7:481bce714567 634 {
wolfSSL 7:481bce714567 635 24, /* size/bytes */
wolfSSL 7:481bce714567 636 ECC_PRIME192V3, /* ID */
wolfSSL 7:481bce714567 637 "PRIME192V3", /* curve name */
wolfSSL 7:481bce714567 638 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 639 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 640 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */
wolfSSL 7:481bce714567 641 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */
wolfSSL 7:481bce714567 642 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */
wolfSSL 7:481bce714567 643 "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */
wolfSSL 7:481bce714567 644 ecc_oid_prime192v3, /* oid/oidSz */
wolfSSL 7:481bce714567 645 sizeof(ecc_oid_prime192v3) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 646 ECC_PRIME192V3_OID, /* oid sum */
wolfSSL 7:481bce714567 647 1, /* cofactor */
wolfSSL 7:481bce714567 648 },
wolfSSL 7:481bce714567 649 #endif /* HAVE_ECC_SECPR3 */
wolfSSL 7:481bce714567 650 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 651 {
wolfSSL 7:481bce714567 652 24, /* size/bytes */
wolfSSL 7:481bce714567 653 ECC_SECP192K1, /* ID */
wolfSSL 7:481bce714567 654 "SECP192K1", /* curve name */
wolfSSL 7:481bce714567 655 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */
wolfSSL 7:481bce714567 656 "000000000000000000000000000000000000000000000000", /* A */
wolfSSL 7:481bce714567 657 "000000000000000000000000000000000000000000000003", /* B */
wolfSSL 7:481bce714567 658 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */
wolfSSL 7:481bce714567 659 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */
wolfSSL 7:481bce714567 660 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */
wolfSSL 7:481bce714567 661 ecc_oid_secp192k1, /* oid/oidSz */
wolfSSL 7:481bce714567 662 sizeof(ecc_oid_secp192k1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 663 ECC_SECP192K1_OID, /* oid sum */
wolfSSL 7:481bce714567 664 1, /* cofactor */
wolfSSL 7:481bce714567 665 },
wolfSSL 7:481bce714567 666 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 667 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 668 {
wolfSSL 7:481bce714567 669 24, /* size/bytes */
wolfSSL 7:481bce714567 670 ECC_BRAINPOOLP192R1, /* ID */
wolfSSL 7:481bce714567 671 "BRAINPOOLP192R1", /* curve name */
wolfSSL 7:481bce714567 672 "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */
wolfSSL 7:481bce714567 673 "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */
wolfSSL 7:481bce714567 674 "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */
wolfSSL 7:481bce714567 675 "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */
wolfSSL 7:481bce714567 676 "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */
wolfSSL 7:481bce714567 677 "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */
wolfSSL 7:481bce714567 678 ecc_oid_brainpoolp192r1, /* oid/oidSz */
wolfSSL 7:481bce714567 679 sizeof(ecc_oid_brainpoolp192r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 680 ECC_BRAINPOOLP192R1_OID, /* oid sum */
wolfSSL 7:481bce714567 681 1, /* cofactor */
wolfSSL 7:481bce714567 682 },
wolfSSL 7:481bce714567 683 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 684 #endif /* ECC192 */
wolfSSL 7:481bce714567 685 #ifdef ECC224
wolfSSL 7:481bce714567 686 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 687 {
wolfSSL 7:481bce714567 688 28, /* size/bytes */
wolfSSL 7:481bce714567 689 ECC_SECP224R1, /* ID */
wolfSSL 7:481bce714567 690 "SECP224R1", /* curve name */
wolfSSL 7:481bce714567 691 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */
wolfSSL 7:481bce714567 692 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */
wolfSSL 7:481bce714567 693 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B */
wolfSSL 7:481bce714567 694 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
wolfSSL 7:481bce714567 695 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
wolfSSL 7:481bce714567 696 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
wolfSSL 7:481bce714567 697 ecc_oid_secp224r1, /* oid/oidSz */
wolfSSL 7:481bce714567 698 sizeof(ecc_oid_secp224r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 699 ECC_SECP224R1_OID, /* oid sum */
wolfSSL 7:481bce714567 700 1, /* cofactor */
wolfSSL 7:481bce714567 701 },
wolfSSL 7:481bce714567 702 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 703 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 704 {
wolfSSL 7:481bce714567 705 28, /* size/bytes */
wolfSSL 7:481bce714567 706 ECC_SECP224K1, /* ID */
wolfSSL 7:481bce714567 707 "SECP224K1", /* curve name */
wolfSSL 7:481bce714567 708 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */
wolfSSL 7:481bce714567 709 "00000000000000000000000000000000000000000000000000000000", /* A */
wolfSSL 7:481bce714567 710 "00000000000000000000000000000000000000000000000000000005", /* B */
wolfSSL 7:481bce714567 711 "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */
wolfSSL 7:481bce714567 712 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */
wolfSSL 7:481bce714567 713 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */
wolfSSL 7:481bce714567 714 ecc_oid_secp224k1, /* oid/oidSz */
wolfSSL 7:481bce714567 715 sizeof(ecc_oid_secp224k1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 716 ECC_SECP224K1_OID, /* oid sum */
wolfSSL 7:481bce714567 717 1, /* cofactor */
wolfSSL 7:481bce714567 718 },
wolfSSL 7:481bce714567 719 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 720 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 721 {
wolfSSL 7:481bce714567 722 28, /* size/bytes */
wolfSSL 7:481bce714567 723 ECC_BRAINPOOLP224R1, /* ID */
wolfSSL 7:481bce714567 724 "BRAINPOOLP224R1", /* curve name */
wolfSSL 7:481bce714567 725 "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */
wolfSSL 7:481bce714567 726 "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */
wolfSSL 7:481bce714567 727 "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */
wolfSSL 7:481bce714567 728 "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */
wolfSSL 7:481bce714567 729 "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */
wolfSSL 7:481bce714567 730 "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */
wolfSSL 7:481bce714567 731 ecc_oid_brainpoolp224r1, /* oid/oidSz */
wolfSSL 7:481bce714567 732 sizeof(ecc_oid_brainpoolp224r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 733 ECC_BRAINPOOLP224R1_OID, /* oid sum */
wolfSSL 7:481bce714567 734 1, /* cofactor */
wolfSSL 7:481bce714567 735 },
wolfSSL 7:481bce714567 736 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 737 #endif /* ECC224 */
wolfSSL 7:481bce714567 738 #ifdef ECC239
wolfSSL 7:481bce714567 739 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 740 {
wolfSSL 7:481bce714567 741 30, /* size/bytes */
wolfSSL 7:481bce714567 742 ECC_PRIME239V1, /* ID */
wolfSSL 7:481bce714567 743 "PRIME239V1", /* curve name */
wolfSSL 7:481bce714567 744 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 745 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 746 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */
wolfSSL 7:481bce714567 747 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */
wolfSSL 7:481bce714567 748 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */
wolfSSL 7:481bce714567 749 "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */
wolfSSL 7:481bce714567 750 ecc_oid_prime239v1, /* oid/oidSz */
wolfSSL 7:481bce714567 751 sizeof(ecc_oid_prime239v1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 752 ECC_PRIME239V1_OID, /* oid sum */
wolfSSL 7:481bce714567 753 1, /* cofactor */
wolfSSL 7:481bce714567 754 },
wolfSSL 7:481bce714567 755 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 756 #ifdef HAVE_ECC_SECPR2
wolfSSL 7:481bce714567 757 {
wolfSSL 7:481bce714567 758 30, /* size/bytes */
wolfSSL 7:481bce714567 759 ECC_PRIME239V2, /* ID */
wolfSSL 7:481bce714567 760 "PRIME239V2", /* curve name */
wolfSSL 7:481bce714567 761 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 762 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 763 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */
wolfSSL 7:481bce714567 764 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */
wolfSSL 7:481bce714567 765 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */
wolfSSL 7:481bce714567 766 "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */
wolfSSL 7:481bce714567 767 ecc_oid_prime239v2, /* oid/oidSz */
wolfSSL 7:481bce714567 768 sizeof(ecc_oid_prime239v2) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 769 ECC_PRIME239V2_OID, /* oid sum */
wolfSSL 7:481bce714567 770 1, /* cofactor */
wolfSSL 7:481bce714567 771 },
wolfSSL 7:481bce714567 772 #endif /* HAVE_ECC_SECPR2 */
wolfSSL 7:481bce714567 773 #ifdef HAVE_ECC_SECPR3
wolfSSL 7:481bce714567 774 {
wolfSSL 7:481bce714567 775 30, /* size/bytes */
wolfSSL 7:481bce714567 776 ECC_PRIME239V3, /* ID */
wolfSSL 7:481bce714567 777 "PRIME239V3", /* curve name */
wolfSSL 7:481bce714567 778 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 779 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 780 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */
wolfSSL 7:481bce714567 781 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */
wolfSSL 7:481bce714567 782 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */
wolfSSL 7:481bce714567 783 "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */
wolfSSL 7:481bce714567 784 ecc_oid_prime239v3, /* oid/oidSz */
wolfSSL 7:481bce714567 785 sizeof(ecc_oid_prime239v3) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 786 ECC_PRIME239V3_OID, /* oid sum */
wolfSSL 7:481bce714567 787 1, /* cofactor */
wolfSSL 7:481bce714567 788 },
wolfSSL 7:481bce714567 789 #endif /* HAVE_ECC_SECPR3 */
wolfSSL 7:481bce714567 790 #endif /* ECC239 */
wolfSSL 7:481bce714567 791 #ifdef ECC256
wolfSSL 7:481bce714567 792 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 793 {
wolfSSL 7:481bce714567 794 32, /* size/bytes */
wolfSSL 7:481bce714567 795 ECC_SECP256R1, /* ID */
wolfSSL 7:481bce714567 796 "SECP256R1", /* curve name */
wolfSSL 7:481bce714567 797 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 798 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 799 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B */
wolfSSL 7:481bce714567 800 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */
wolfSSL 7:481bce714567 801 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */
wolfSSL 7:481bce714567 802 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */
wolfSSL 7:481bce714567 803 ecc_oid_secp256r1, /* oid/oidSz */
wolfSSL 7:481bce714567 804 sizeof(ecc_oid_secp256r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 805 ECC_SECP256R1_OID, /* oid sum */
wolfSSL 7:481bce714567 806 1, /* cofactor */
wolfSSL 7:481bce714567 807 },
wolfSSL 7:481bce714567 808 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 809 #ifdef HAVE_ECC_KOBLITZ
wolfSSL 7:481bce714567 810 {
wolfSSL 7:481bce714567 811 32, /* size/bytes */
wolfSSL 7:481bce714567 812 ECC_SECP256K1, /* ID */
wolfSSL 7:481bce714567 813 "SECP256K1", /* curve name */
wolfSSL 7:481bce714567 814 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */
wolfSSL 7:481bce714567 815 "0000000000000000000000000000000000000000000000000000000000000000", /* A */
wolfSSL 7:481bce714567 816 "0000000000000000000000000000000000000000000000000000000000000007", /* B */
wolfSSL 7:481bce714567 817 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */
wolfSSL 7:481bce714567 818 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */
wolfSSL 7:481bce714567 819 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */
wolfSSL 7:481bce714567 820 ecc_oid_secp256k1, /* oid/oidSz */
wolfSSL 7:481bce714567 821 sizeof(ecc_oid_secp256k1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 822 ECC_SECP256K1_OID, /* oid sum */
wolfSSL 7:481bce714567 823 1, /* cofactor */
wolfSSL 7:481bce714567 824 },
wolfSSL 7:481bce714567 825 #endif /* HAVE_ECC_KOBLITZ */
wolfSSL 7:481bce714567 826 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 827 {
wolfSSL 7:481bce714567 828 32, /* size/bytes */
wolfSSL 7:481bce714567 829 ECC_BRAINPOOLP256R1, /* ID */
wolfSSL 7:481bce714567 830 "BRAINPOOLP256R1", /* curve name */
wolfSSL 7:481bce714567 831 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */
wolfSSL 7:481bce714567 832 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
wolfSSL 7:481bce714567 833 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
wolfSSL 7:481bce714567 834 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */
wolfSSL 7:481bce714567 835 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */
wolfSSL 7:481bce714567 836 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */
wolfSSL 7:481bce714567 837 ecc_oid_brainpoolp256r1, /* oid/oidSz */
wolfSSL 7:481bce714567 838 sizeof(ecc_oid_brainpoolp256r1) / sizeof(ecc_oid_t),
wolfSSL 7:481bce714567 839 ECC_BRAINPOOLP256R1_OID, /* oid sum */
wolfSSL 7:481bce714567 840 1, /* cofactor */
wolfSSL 7:481bce714567 841 },
wolfSSL 7:481bce714567 842 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 843 #endif /* ECC256 */
wolfSSL 7:481bce714567 844 #ifdef ECC320
wolfSSL 7:481bce714567 845 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 846 {
wolfSSL 7:481bce714567 847 40, /* size/bytes */
wolfSSL 7:481bce714567 848 ECC_BRAINPOOLP320R1, /* ID */
wolfSSL 7:481bce714567 849 "BRAINPOOLP320R1", /* curve name */
wolfSSL 7:481bce714567 850 "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */
wolfSSL 7:481bce714567 851 "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */
wolfSSL 7:481bce714567 852 "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */
wolfSSL 7:481bce714567 853 "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */
wolfSSL 7:481bce714567 854 "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */
wolfSSL 7:481bce714567 855 "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */
wolfSSL 7:481bce714567 856 ecc_oid_brainpoolp320r1, sizeof(ecc_oid_brainpoolp320r1) / sizeof(ecc_oid_t), /* oid/oidSz */
wolfSSL 7:481bce714567 857 ECC_BRAINPOOLP320R1_OID, /* oid sum */
wolfSSL 7:481bce714567 858 1, /* cofactor */
wolfSSL 7:481bce714567 859 },
wolfSSL 7:481bce714567 860 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 861 #endif /* ECC320 */
wolfSSL 7:481bce714567 862 #ifdef ECC384
wolfSSL 7:481bce714567 863 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 864 {
wolfSSL 7:481bce714567 865 48, /* size/bytes */
wolfSSL 7:481bce714567 866 ECC_SECP384R1, /* ID */
wolfSSL 7:481bce714567 867 "SECP384R1", /* curve name */
wolfSSL 7:481bce714567 868 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */
wolfSSL 7:481bce714567 869 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */
wolfSSL 7:481bce714567 870 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B */
wolfSSL 7:481bce714567 871 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */
wolfSSL 7:481bce714567 872 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */
wolfSSL 7:481bce714567 873 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */
wolfSSL 7:481bce714567 874 ecc_oid_secp384r1, sizeof(ecc_oid_secp384r1) / sizeof(ecc_oid_t), /* oid/oidSz */
wolfSSL 7:481bce714567 875 ECC_SECP384R1_OID, /* oid sum */
wolfSSL 7:481bce714567 876 1, /* cofactor */
wolfSSL 7:481bce714567 877 },
wolfSSL 7:481bce714567 878 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 879 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 880 {
wolfSSL 7:481bce714567 881 48, /* size/bytes */
wolfSSL 7:481bce714567 882 ECC_BRAINPOOLP384R1, /* ID */
wolfSSL 7:481bce714567 883 "BRAINPOOLP384R1", /* curve name */
wolfSSL 7:481bce714567 884 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */
wolfSSL 7:481bce714567 885 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */
wolfSSL 7:481bce714567 886 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */
wolfSSL 7:481bce714567 887 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */
wolfSSL 7:481bce714567 888 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */
wolfSSL 7:481bce714567 889 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */
wolfSSL 7:481bce714567 890 ecc_oid_brainpoolp384r1, sizeof(ecc_oid_brainpoolp384r1) / sizeof(ecc_oid_t), /* oid/oidSz */
wolfSSL 7:481bce714567 891 ECC_BRAINPOOLP384R1_OID, /* oid sum */
wolfSSL 7:481bce714567 892 1, /* cofactor */
wolfSSL 7:481bce714567 893 },
wolfSSL 7:481bce714567 894 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 895 #endif /* ECC384 */
wolfSSL 7:481bce714567 896 #ifdef ECC512
wolfSSL 7:481bce714567 897 #ifdef HAVE_ECC_BRAINPOOL
wolfSSL 7:481bce714567 898 {
wolfSSL 7:481bce714567 899 64, /* size/bytes */
wolfSSL 7:481bce714567 900 ECC_BRAINPOOLP512R1, /* ID */
wolfSSL 7:481bce714567 901 "BRAINPOOLP512R1", /* curve name */
wolfSSL 7:481bce714567 902 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */
wolfSSL 7:481bce714567 903 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */
wolfSSL 7:481bce714567 904 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */
wolfSSL 7:481bce714567 905 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */
wolfSSL 7:481bce714567 906 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */
wolfSSL 7:481bce714567 907 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */
wolfSSL 7:481bce714567 908 ecc_oid_brainpoolp512r1, sizeof(ecc_oid_brainpoolp512r1) / sizeof(ecc_oid_t), /* oid/oidSz */
wolfSSL 7:481bce714567 909 ECC_BRAINPOOLP512R1_OID, /* oid sum */
wolfSSL 7:481bce714567 910 1, /* cofactor */
wolfSSL 7:481bce714567 911 },
wolfSSL 7:481bce714567 912 #endif /* HAVE_ECC_BRAINPOOL */
wolfSSL 7:481bce714567 913 #endif /* ECC512 */
wolfSSL 7:481bce714567 914 #ifdef ECC521
wolfSSL 7:481bce714567 915 #ifndef NO_ECC_SECP
wolfSSL 7:481bce714567 916 {
wolfSSL 7:481bce714567 917 66, /* size/bytes */
wolfSSL 7:481bce714567 918 ECC_SECP521R1, /* ID */
wolfSSL 7:481bce714567 919 "SECP521R1", /* curve name */
wolfSSL 7:481bce714567 920 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
wolfSSL 7:481bce714567 921 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */
wolfSSL 7:481bce714567 922 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */
wolfSSL 7:481bce714567 923 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */
wolfSSL 7:481bce714567 924 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */
wolfSSL 7:481bce714567 925 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */
wolfSSL 7:481bce714567 926 ecc_oid_secp521r1, sizeof(ecc_oid_secp521r1) / sizeof(ecc_oid_t), /* oid/oidSz */
wolfSSL 7:481bce714567 927 ECC_SECP521R1_OID, /* oid sum */
wolfSSL 7:481bce714567 928 1, /* cofactor */
wolfSSL 7:481bce714567 929 },
wolfSSL 7:481bce714567 930 #endif /* !NO_ECC_SECP */
wolfSSL 7:481bce714567 931 #endif /* ECC521 */
wolfSSL 7:481bce714567 932 {
wolfSSL 7:481bce714567 933 0, -1,
wolfSSL 7:481bce714567 934 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
wolfSSL 7:481bce714567 935 NULL, 0, 0, 0
wolfSSL 7:481bce714567 936 }
wolfSSL 7:481bce714567 937 };
wolfSSL 7:481bce714567 938 #define ECC_SET_COUNT (sizeof(ecc_sets)/sizeof(ecc_set_type))
wolfSSL 7:481bce714567 939
wolfSSL 7:481bce714567 940 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 941 /* encoded OID cache */
wolfSSL 7:481bce714567 942 typedef struct {
wolfSSL 7:481bce714567 943 word32 oidSz;
wolfSSL 7:481bce714567 944 byte oid[ECC_MAX_OID_LEN];
wolfSSL 7:481bce714567 945 } oid_cache_t;
wolfSSL 7:481bce714567 946 static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
wolfSSL 7:481bce714567 947 #endif
wolfSSL 7:481bce714567 948
wolfSSL 7:481bce714567 949
wolfSSL 7:481bce714567 950 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 951 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
wolfSSL 7:481bce714567 952 #endif
wolfSSL 7:481bce714567 953
wolfSSL 7:481bce714567 954 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 955
wolfSSL 7:481bce714567 956 int ecc_map(ecc_point*, mp_int*, mp_digit);
wolfSSL 7:481bce714567 957 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
wolfSSL 7:481bce714567 958 mp_int* a, mp_int* modulus, mp_digit mp);
wolfSSL 7:481bce714567 959 int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* a,
wolfSSL 7:481bce714567 960 mp_int* modulus, mp_digit mp);
wolfSSL 7:481bce714567 961 static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, mp_int* order);
wolfSSL 7:481bce714567 962 #ifdef ECC_SHAMIR
wolfSSL 7:481bce714567 963 static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
wolfSSL 7:481bce714567 964 ecc_point* C, mp_int* a, mp_int* modulus, void* heap);
wolfSSL 7:481bce714567 965 #endif
wolfSSL 7:481bce714567 966
wolfSSL 7:481bce714567 967 int mp_jacobi(mp_int* a, mp_int* n, int* c);
wolfSSL 7:481bce714567 968 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
wolfSSL 7:481bce714567 969
wolfSSL 7:481bce714567 970
wolfSSL 7:481bce714567 971 /* Curve Specs */
wolfSSL 7:481bce714567 972 typedef struct ecc_curve_spec {
wolfSSL 7:481bce714567 973 const ecc_set_type* dp;
wolfSSL 7:481bce714567 974
wolfSSL 7:481bce714567 975 mp_int* prime;
wolfSSL 7:481bce714567 976 mp_int* Af;
wolfSSL 7:481bce714567 977 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 978 mp_int* Bf;
wolfSSL 7:481bce714567 979 #endif
wolfSSL 7:481bce714567 980 mp_int* order;
wolfSSL 7:481bce714567 981 mp_int* Gx;
wolfSSL 7:481bce714567 982 mp_int* Gy;
wolfSSL 7:481bce714567 983
wolfSSL 7:481bce714567 984 #ifdef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 985 mp_int prime_lcl;
wolfSSL 7:481bce714567 986 mp_int Af_lcl;
wolfSSL 7:481bce714567 987 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 988 mp_int Bf_lcl;
wolfSSL 7:481bce714567 989 #endif
wolfSSL 7:481bce714567 990 mp_int order_lcl;
wolfSSL 7:481bce714567 991 mp_int Gx_lcl;
wolfSSL 7:481bce714567 992 mp_int Gy_lcl;
wolfSSL 7:481bce714567 993 #else
wolfSSL 7:481bce714567 994 mp_int* spec_ints;
wolfSSL 7:481bce714567 995 word32 spec_count;
wolfSSL 7:481bce714567 996 word32 spec_use;
wolfSSL 7:481bce714567 997 #endif
wolfSSL 7:481bce714567 998
wolfSSL 7:481bce714567 999 byte load_mask;
wolfSSL 7:481bce714567 1000 } ecc_curve_spec;
wolfSSL 7:481bce714567 1001
wolfSSL 7:481bce714567 1002 enum ecc_curve_load_mask {
wolfSSL 7:481bce714567 1003 ECC_CURVE_FIELD_NONE = 0x00,
wolfSSL 7:481bce714567 1004 ECC_CURVE_FIELD_PRIME = 0x01,
wolfSSL 7:481bce714567 1005 ECC_CURVE_FIELD_AF = 0x02,
wolfSSL 7:481bce714567 1006 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 1007 ECC_CURVE_FIELD_BF = 0x04,
wolfSSL 7:481bce714567 1008 #endif
wolfSSL 7:481bce714567 1009 ECC_CURVE_FIELD_ORDER = 0x08,
wolfSSL 7:481bce714567 1010 ECC_CURVE_FIELD_GX = 0x10,
wolfSSL 7:481bce714567 1011 ECC_CURVE_FIELD_GY = 0x20,
wolfSSL 7:481bce714567 1012 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 1013 ECC_CURVE_FIELD_ALL = 0x3F,
wolfSSL 7:481bce714567 1014 ECC_CURVE_FIELD_COUNT = 6,
wolfSSL 7:481bce714567 1015 #else
wolfSSL 7:481bce714567 1016 ECC_CURVE_FIELD_ALL = 0x3B,
wolfSSL 7:481bce714567 1017 ECC_CURVE_FIELD_COUNT = 5,
wolfSSL 7:481bce714567 1018 #endif
wolfSSL 7:481bce714567 1019 };
wolfSSL 7:481bce714567 1020
wolfSSL 7:481bce714567 1021 #ifdef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1022 /* cache (mp_int) of the curve parameters */
wolfSSL 7:481bce714567 1023 static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
wolfSSL 7:481bce714567 1024
wolfSSL 7:481bce714567 1025 #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL;
wolfSSL 7:481bce714567 1026 #else
wolfSSL 7:481bce714567 1027 #define DECLARE_CURVE_SPECS(intcount) \
wolfSSL 7:481bce714567 1028 mp_int spec_ints[(intcount)]; \
wolfSSL 7:481bce714567 1029 ecc_curve_spec curve_lcl; \
wolfSSL 7:481bce714567 1030 ecc_curve_spec* curve = &curve_lcl; \
wolfSSL 7:481bce714567 1031 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
wolfSSL 7:481bce714567 1032 curve->spec_ints = spec_ints; \
wolfSSL 7:481bce714567 1033 curve->spec_count = intcount;
wolfSSL 7:481bce714567 1034 #endif /* ECC_CACHE_CURVE */
wolfSSL 7:481bce714567 1035
wolfSSL 7:481bce714567 1036 static void _wc_ecc_curve_free(ecc_curve_spec* curve)
wolfSSL 7:481bce714567 1037 {
wolfSSL 7:481bce714567 1038 if (curve == NULL) {
wolfSSL 7:481bce714567 1039 return;
wolfSSL 7:481bce714567 1040 }
wolfSSL 7:481bce714567 1041
wolfSSL 7:481bce714567 1042 /* don't clear fast math (only normal math uses alloc's) */
wolfSSL 7:481bce714567 1043 #if !defined(USE_FAST_MATH)
wolfSSL 7:481bce714567 1044 if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
wolfSSL 7:481bce714567 1045 mp_clear(curve->prime);
wolfSSL 7:481bce714567 1046 if (curve->load_mask & ECC_CURVE_FIELD_AF)
wolfSSL 7:481bce714567 1047 mp_clear(curve->Af);
wolfSSL 7:481bce714567 1048 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 1049 if (curve->load_mask & ECC_CURVE_FIELD_BF)
wolfSSL 7:481bce714567 1050 mp_clear(curve->Bf);
wolfSSL 7:481bce714567 1051 #endif
wolfSSL 7:481bce714567 1052 if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
wolfSSL 7:481bce714567 1053 mp_clear(curve->order);
wolfSSL 7:481bce714567 1054 if (curve->load_mask & ECC_CURVE_FIELD_GX)
wolfSSL 7:481bce714567 1055 mp_clear(curve->Gx);
wolfSSL 7:481bce714567 1056 if (curve->load_mask & ECC_CURVE_FIELD_GY)
wolfSSL 7:481bce714567 1057 mp_clear(curve->Gy);
wolfSSL 7:481bce714567 1058 #endif
wolfSSL 7:481bce714567 1059 curve->load_mask = 0;
wolfSSL 7:481bce714567 1060 }
wolfSSL 7:481bce714567 1061
wolfSSL 7:481bce714567 1062 static void wc_ecc_curve_free(ecc_curve_spec* curve)
wolfSSL 7:481bce714567 1063 {
wolfSSL 7:481bce714567 1064 /* don't free cached curves */
wolfSSL 7:481bce714567 1065 #ifndef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1066 _wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 1067 #endif
wolfSSL 7:481bce714567 1068 (void)curve;
wolfSSL 7:481bce714567 1069 }
wolfSSL 7:481bce714567 1070
wolfSSL 7:481bce714567 1071 static int wc_ecc_curve_load_item(const char* src, mp_int** dst,
wolfSSL 7:481bce714567 1072 ecc_curve_spec* curve, byte mask)
wolfSSL 7:481bce714567 1073 {
wolfSSL 7:481bce714567 1074 int err;
wolfSSL 7:481bce714567 1075
wolfSSL 7:481bce714567 1076 #ifndef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1077 /* get mp_int from temp */
wolfSSL 7:481bce714567 1078 if (curve->spec_use >= curve->spec_count) {
wolfSSL 7:481bce714567 1079 WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
wolfSSL 7:481bce714567 1080 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1081 }
wolfSSL 7:481bce714567 1082 *dst = &curve->spec_ints[curve->spec_use++];
wolfSSL 7:481bce714567 1083 #endif
wolfSSL 7:481bce714567 1084
wolfSSL 7:481bce714567 1085 err = mp_init(*dst);
wolfSSL 7:481bce714567 1086 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1087 curve->load_mask |= mask;
wolfSSL 7:481bce714567 1088
wolfSSL 7:481bce714567 1089 err = mp_read_radix(*dst, src, 16);
wolfSSL 7:481bce714567 1090 }
wolfSSL 7:481bce714567 1091 return err;
wolfSSL 7:481bce714567 1092 }
wolfSSL 7:481bce714567 1093
wolfSSL 7:481bce714567 1094 static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
wolfSSL 7:481bce714567 1095 byte load_mask)
wolfSSL 7:481bce714567 1096 {
wolfSSL 7:481bce714567 1097 int ret = 0, x;
wolfSSL 7:481bce714567 1098 ecc_curve_spec* curve;
wolfSSL 7:481bce714567 1099 byte load_items; /* mask of items to load */
wolfSSL 7:481bce714567 1100
wolfSSL 7:481bce714567 1101 if (dp == NULL || pCurve == NULL)
wolfSSL 7:481bce714567 1102 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 1103
wolfSSL 7:481bce714567 1104 #ifdef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1105 /* find ecc_set index based on curve_id */
wolfSSL 7:481bce714567 1106 for (x = 0; ecc_sets[x].size != 0; x++) {
wolfSSL 7:481bce714567 1107 if (dp->id == ecc_sets[x].id)
wolfSSL 7:481bce714567 1108 break; /* found index */
wolfSSL 7:481bce714567 1109 }
wolfSSL 7:481bce714567 1110 if (ecc_sets[x].size == 0)
wolfSSL 7:481bce714567 1111 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1112
wolfSSL 7:481bce714567 1113 /* make sure cache has been allocated */
wolfSSL 7:481bce714567 1114 if (ecc_curve_spec_cache[x] == NULL) {
wolfSSL 7:481bce714567 1115 ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(
wolfSSL 7:481bce714567 1116 sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 1117 if (ecc_curve_spec_cache[x] == NULL)
wolfSSL 7:481bce714567 1118 return MEMORY_E;
wolfSSL 7:481bce714567 1119 XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));
wolfSSL 7:481bce714567 1120 }
wolfSSL 7:481bce714567 1121
wolfSSL 7:481bce714567 1122 /* set curve pointer to cache */
wolfSSL 7:481bce714567 1123 *pCurve = ecc_curve_spec_cache[x];
wolfSSL 7:481bce714567 1124
wolfSSL 7:481bce714567 1125 #endif /* ECC_CACHE_CURVE */
wolfSSL 7:481bce714567 1126 curve = *pCurve;
wolfSSL 7:481bce714567 1127
wolfSSL 7:481bce714567 1128 /* make sure the curve is initialized */
wolfSSL 7:481bce714567 1129 if (curve->dp != dp) {
wolfSSL 7:481bce714567 1130 curve->load_mask = 0;
wolfSSL 7:481bce714567 1131
wolfSSL 7:481bce714567 1132 #ifdef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1133 curve->prime = &curve->prime_lcl;
wolfSSL 7:481bce714567 1134 curve->Af = &curve->Af_lcl;
wolfSSL 7:481bce714567 1135 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 1136 curve->Bf = &curve->Bf_lcl;
wolfSSL 7:481bce714567 1137 #endif
wolfSSL 7:481bce714567 1138 curve->order = &curve->order_lcl;
wolfSSL 7:481bce714567 1139 curve->Gx = &curve->Gx_lcl;
wolfSSL 7:481bce714567 1140 curve->Gy = &curve->Gy_lcl;
wolfSSL 7:481bce714567 1141 #endif
wolfSSL 7:481bce714567 1142 }
wolfSSL 7:481bce714567 1143 curve->dp = dp; /* set dp info */
wolfSSL 7:481bce714567 1144
wolfSSL 7:481bce714567 1145 /* determine items to load */
wolfSSL 7:481bce714567 1146 load_items = (~curve->load_mask & load_mask);
wolfSSL 7:481bce714567 1147
wolfSSL 7:481bce714567 1148 /* load items */
wolfSSL 7:481bce714567 1149 x = 0;
wolfSSL 7:481bce714567 1150 if (load_items & ECC_CURVE_FIELD_PRIME)
wolfSSL 7:481bce714567 1151 x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,
wolfSSL 7:481bce714567 1152 ECC_CURVE_FIELD_PRIME);
wolfSSL 7:481bce714567 1153 if (load_items & ECC_CURVE_FIELD_AF)
wolfSSL 7:481bce714567 1154 x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
wolfSSL 7:481bce714567 1155 ECC_CURVE_FIELD_AF);
wolfSSL 7:481bce714567 1156 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 1157 if (load_items & ECC_CURVE_FIELD_BF)
wolfSSL 7:481bce714567 1158 x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
wolfSSL 7:481bce714567 1159 ECC_CURVE_FIELD_BF);
wolfSSL 7:481bce714567 1160 #endif
wolfSSL 7:481bce714567 1161 if (load_items & ECC_CURVE_FIELD_ORDER)
wolfSSL 7:481bce714567 1162 x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
wolfSSL 7:481bce714567 1163 ECC_CURVE_FIELD_ORDER);
wolfSSL 7:481bce714567 1164 if (load_items & ECC_CURVE_FIELD_GX)
wolfSSL 7:481bce714567 1165 x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,
wolfSSL 7:481bce714567 1166 ECC_CURVE_FIELD_GX);
wolfSSL 7:481bce714567 1167 if (load_items & ECC_CURVE_FIELD_GY)
wolfSSL 7:481bce714567 1168 x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,
wolfSSL 7:481bce714567 1169 ECC_CURVE_FIELD_GY);
wolfSSL 7:481bce714567 1170
wolfSSL 7:481bce714567 1171 /* check for error */
wolfSSL 7:481bce714567 1172 if (x != 0) {
wolfSSL 7:481bce714567 1173 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 1174 ret = MP_READ_E;
wolfSSL 7:481bce714567 1175 }
wolfSSL 7:481bce714567 1176
wolfSSL 7:481bce714567 1177 return ret;
wolfSSL 7:481bce714567 1178 }
wolfSSL 7:481bce714567 1179
wolfSSL 7:481bce714567 1180 #ifdef ECC_CACHE_CURVE
wolfSSL 7:481bce714567 1181 void wc_ecc_curve_cache_free(void)
wolfSSL 7:481bce714567 1182 {
wolfSSL 7:481bce714567 1183 int x;
wolfSSL 7:481bce714567 1184
wolfSSL 7:481bce714567 1185 /* free all ECC curve caches */
wolfSSL 7:481bce714567 1186 for (x = 0; x < (int)ECC_SET_COUNT; x++) {
wolfSSL 7:481bce714567 1187 if (ecc_curve_spec_cache[x]) {
wolfSSL 7:481bce714567 1188 _wc_ecc_curve_free(ecc_curve_spec_cache[x]);
wolfSSL 7:481bce714567 1189 XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 1190 ecc_curve_spec_cache[x] = NULL;
wolfSSL 7:481bce714567 1191 }
wolfSSL 7:481bce714567 1192 }
wolfSSL 7:481bce714567 1193 }
wolfSSL 7:481bce714567 1194 #endif /* ECC_CACHE_CURVE */
wolfSSL 7:481bce714567 1195
wolfSSL 7:481bce714567 1196 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 1197
wolfSSL 7:481bce714567 1198
wolfSSL 7:481bce714567 1199 static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
wolfSSL 7:481bce714567 1200 {
wolfSSL 7:481bce714567 1201 if (keysize <= 0 && curve_id <= 0) {
wolfSSL 7:481bce714567 1202 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 1203 }
wolfSSL 7:481bce714567 1204
wolfSSL 7:481bce714567 1205 if (keysize > ECC_MAXSIZE) {
wolfSSL 7:481bce714567 1206 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1207 }
wolfSSL 7:481bce714567 1208
wolfSSL 7:481bce714567 1209 /* handle custom case */
wolfSSL 7:481bce714567 1210 if (key->idx != ECC_CUSTOM_IDX) {
wolfSSL 7:481bce714567 1211 int x;
wolfSSL 7:481bce714567 1212
wolfSSL 7:481bce714567 1213 /* find ecc_set based on curve_id or key size */
wolfSSL 7:481bce714567 1214 for (x = 0; ecc_sets[x].size != 0; x++) {
wolfSSL 7:481bce714567 1215 if (curve_id > ECC_CURVE_DEF) {
wolfSSL 7:481bce714567 1216 if (curve_id == ecc_sets[x].id)
wolfSSL 7:481bce714567 1217 break;
wolfSSL 7:481bce714567 1218 }
wolfSSL 7:481bce714567 1219 else if (keysize <= ecc_sets[x].size) {
wolfSSL 7:481bce714567 1220 break;
wolfSSL 7:481bce714567 1221 }
wolfSSL 7:481bce714567 1222 }
wolfSSL 7:481bce714567 1223 if (ecc_sets[x].size == 0) {
wolfSSL 7:481bce714567 1224 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1225 }
wolfSSL 7:481bce714567 1226
wolfSSL 7:481bce714567 1227 key->idx = x;
wolfSSL 7:481bce714567 1228 key->dp = &ecc_sets[x];
wolfSSL 7:481bce714567 1229 }
wolfSSL 7:481bce714567 1230
wolfSSL 7:481bce714567 1231 return 0;
wolfSSL 7:481bce714567 1232 }
wolfSSL 7:481bce714567 1233
wolfSSL 7:481bce714567 1234 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 1235
wolfSSL 7:481bce714567 1236 /**
wolfSSL 7:481bce714567 1237 Add two ECC points
wolfSSL 7:481bce714567 1238 P The point to add
wolfSSL 7:481bce714567 1239 Q The point to add
wolfSSL 7:481bce714567 1240 R [out] The destination of the double
wolfSSL 7:481bce714567 1241 a ECC curve parameter a
wolfSSL 7:481bce714567 1242 modulus The modulus of the field the ECC curve is in
wolfSSL 7:481bce714567 1243 mp The "b" value from montgomery_setup()
wolfSSL 7:481bce714567 1244 return MP_OKAY on success
wolfSSL 7:481bce714567 1245 */
wolfSSL 7:481bce714567 1246 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
wolfSSL 7:481bce714567 1247 mp_int* a, mp_int* modulus, mp_digit mp)
wolfSSL 7:481bce714567 1248 {
wolfSSL 7:481bce714567 1249 mp_int t1, t2;
wolfSSL 7:481bce714567 1250 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1251 mp_int rx, ry, rz;
wolfSSL 7:481bce714567 1252 #endif
wolfSSL 7:481bce714567 1253 mp_int *x, *y, *z;
wolfSSL 7:481bce714567 1254 int err;
wolfSSL 7:481bce714567 1255
wolfSSL 7:481bce714567 1256 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
wolfSSL 7:481bce714567 1257 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1258 }
wolfSSL 7:481bce714567 1259
wolfSSL 7:481bce714567 1260 /* if Q == R then swap P and Q, so we don't require a local x,y,z */
wolfSSL 7:481bce714567 1261 if (Q == R) {
wolfSSL 7:481bce714567 1262 ecc_point* tPt = P;
wolfSSL 7:481bce714567 1263 P = Q;
wolfSSL 7:481bce714567 1264 Q = tPt;
wolfSSL 7:481bce714567 1265 }
wolfSSL 7:481bce714567 1266
wolfSSL 7:481bce714567 1267 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1268 return err;
wolfSSL 7:481bce714567 1269 }
wolfSSL 7:481bce714567 1270
wolfSSL 7:481bce714567 1271 /* should we dbl instead? */
wolfSSL 7:481bce714567 1272 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1273 err = mp_sub(modulus, Q->y, &t1);
wolfSSL 7:481bce714567 1274 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1275 if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
wolfSSL 7:481bce714567 1276 (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
wolfSSL 7:481bce714567 1277 (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, &t1) == MP_EQ)) {
wolfSSL 7:481bce714567 1278 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1279 mp_clear(&t1);
wolfSSL 7:481bce714567 1280 mp_clear(&t2);
wolfSSL 7:481bce714567 1281 #endif
wolfSSL 7:481bce714567 1282 return ecc_projective_dbl_point(P, R, a, modulus, mp);
wolfSSL 7:481bce714567 1283 }
wolfSSL 7:481bce714567 1284 }
wolfSSL 7:481bce714567 1285
wolfSSL 7:481bce714567 1286 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 1287 goto done;
wolfSSL 7:481bce714567 1288 }
wolfSSL 7:481bce714567 1289
wolfSSL 7:481bce714567 1290 /* If use ALT_ECC_SIZE we need to use local stack variable since
wolfSSL 7:481bce714567 1291 ecc_point x,y,z is reduced size */
wolfSSL 7:481bce714567 1292 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1293 /* Use local stack variable */
wolfSSL 7:481bce714567 1294 x = &rx;
wolfSSL 7:481bce714567 1295 y = &ry;
wolfSSL 7:481bce714567 1296 z = &rz;
wolfSSL 7:481bce714567 1297
wolfSSL 7:481bce714567 1298 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1299 goto done;
wolfSSL 7:481bce714567 1300 }
wolfSSL 7:481bce714567 1301 #else
wolfSSL 7:481bce714567 1302 /* Use destination directly */
wolfSSL 7:481bce714567 1303 x = R->x;
wolfSSL 7:481bce714567 1304 y = R->y;
wolfSSL 7:481bce714567 1305 z = R->z;
wolfSSL 7:481bce714567 1306 #endif
wolfSSL 7:481bce714567 1307
wolfSSL 7:481bce714567 1308 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1309 err = mp_copy(P->x, x);
wolfSSL 7:481bce714567 1310 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1311 err = mp_copy(P->y, y);
wolfSSL 7:481bce714567 1312 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1313 err = mp_copy(P->z, z);
wolfSSL 7:481bce714567 1314
wolfSSL 7:481bce714567 1315 /* if Z is one then these are no-operations */
wolfSSL 7:481bce714567 1316 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1317 if (!mp_iszero(Q->z)) {
wolfSSL 7:481bce714567 1318 /* T1 = Z' * Z' */
wolfSSL 7:481bce714567 1319 err = mp_sqr(Q->z, &t1);
wolfSSL 7:481bce714567 1320 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1321 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1322
wolfSSL 7:481bce714567 1323 /* X = X * T1 */
wolfSSL 7:481bce714567 1324 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1325 err = mp_mul(&t1, x, x);
wolfSSL 7:481bce714567 1326 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1327 err = mp_montgomery_reduce(x, modulus, mp);
wolfSSL 7:481bce714567 1328
wolfSSL 7:481bce714567 1329 /* T1 = Z' * T1 */
wolfSSL 7:481bce714567 1330 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1331 err = mp_mul(Q->z, &t1, &t1);
wolfSSL 7:481bce714567 1332 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1333 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1334
wolfSSL 7:481bce714567 1335 /* Y = Y * T1 */
wolfSSL 7:481bce714567 1336 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1337 err = mp_mul(&t1, y, y);
wolfSSL 7:481bce714567 1338 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1339 err = mp_montgomery_reduce(y, modulus, mp);
wolfSSL 7:481bce714567 1340 }
wolfSSL 7:481bce714567 1341 }
wolfSSL 7:481bce714567 1342
wolfSSL 7:481bce714567 1343 /* T1 = Z*Z */
wolfSSL 7:481bce714567 1344 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1345 err = mp_sqr(z, &t1);
wolfSSL 7:481bce714567 1346 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1347 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1348
wolfSSL 7:481bce714567 1349 /* T2 = X' * T1 */
wolfSSL 7:481bce714567 1350 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1351 err = mp_mul(Q->x, &t1, &t2);
wolfSSL 7:481bce714567 1352 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1353 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1354
wolfSSL 7:481bce714567 1355 /* T1 = Z * T1 */
wolfSSL 7:481bce714567 1356 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1357 err = mp_mul(z, &t1, &t1);
wolfSSL 7:481bce714567 1358 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1359 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1360
wolfSSL 7:481bce714567 1361 /* T1 = Y' * T1 */
wolfSSL 7:481bce714567 1362 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1363 err = mp_mul(Q->y, &t1, &t1);
wolfSSL 7:481bce714567 1364 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1365 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1366
wolfSSL 7:481bce714567 1367 /* Y = Y - T1 */
wolfSSL 7:481bce714567 1368 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1369 err = mp_sub(y, &t1, y);
wolfSSL 7:481bce714567 1370 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1371 if (mp_isneg(y))
wolfSSL 7:481bce714567 1372 err = mp_add(y, modulus, y);
wolfSSL 7:481bce714567 1373 }
wolfSSL 7:481bce714567 1374 /* T1 = 2T1 */
wolfSSL 7:481bce714567 1375 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1376 err = mp_add(&t1, &t1, &t1);
wolfSSL 7:481bce714567 1377 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1378 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1379 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1380 }
wolfSSL 7:481bce714567 1381 /* T1 = Y + T1 */
wolfSSL 7:481bce714567 1382 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1383 err = mp_add(&t1, y, &t1);
wolfSSL 7:481bce714567 1384 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1385 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1386 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1387 }
wolfSSL 7:481bce714567 1388 /* X = X - T2 */
wolfSSL 7:481bce714567 1389 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1390 err = mp_sub(x, &t2, x);
wolfSSL 7:481bce714567 1391 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1392 if (mp_isneg(x))
wolfSSL 7:481bce714567 1393 err = mp_add(x, modulus, x);
wolfSSL 7:481bce714567 1394 }
wolfSSL 7:481bce714567 1395 /* T2 = 2T2 */
wolfSSL 7:481bce714567 1396 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1397 err = mp_add(&t2, &t2, &t2);
wolfSSL 7:481bce714567 1398 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1399 if (mp_cmp(&t2, modulus) != MP_LT)
wolfSSL 7:481bce714567 1400 err = mp_sub(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1401 }
wolfSSL 7:481bce714567 1402 /* T2 = X + T2 */
wolfSSL 7:481bce714567 1403 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1404 err = mp_add(&t2, x, &t2);
wolfSSL 7:481bce714567 1405 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1406 if (mp_cmp(&t2, modulus) != MP_LT)
wolfSSL 7:481bce714567 1407 err = mp_sub(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1408 }
wolfSSL 7:481bce714567 1409
wolfSSL 7:481bce714567 1410 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1411 if (!mp_iszero(Q->z)) {
wolfSSL 7:481bce714567 1412 /* Z = Z * Z' */
wolfSSL 7:481bce714567 1413 err = mp_mul(z, Q->z, z);
wolfSSL 7:481bce714567 1414 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1415 err = mp_montgomery_reduce(z, modulus, mp);
wolfSSL 7:481bce714567 1416 }
wolfSSL 7:481bce714567 1417 }
wolfSSL 7:481bce714567 1418
wolfSSL 7:481bce714567 1419 /* Z = Z * X */
wolfSSL 7:481bce714567 1420 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1421 err = mp_mul(z, x, z);
wolfSSL 7:481bce714567 1422 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1423 err = mp_montgomery_reduce(z, modulus, mp);
wolfSSL 7:481bce714567 1424
wolfSSL 7:481bce714567 1425 /* T1 = T1 * X */
wolfSSL 7:481bce714567 1426 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1427 err = mp_mul(&t1, x, &t1);
wolfSSL 7:481bce714567 1428 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1429 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1430
wolfSSL 7:481bce714567 1431 /* X = X * X */
wolfSSL 7:481bce714567 1432 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1433 err = mp_sqr(x, x);
wolfSSL 7:481bce714567 1434 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1435 err = mp_montgomery_reduce(x, modulus, mp);
wolfSSL 7:481bce714567 1436
wolfSSL 7:481bce714567 1437 /* T2 = T2 * x */
wolfSSL 7:481bce714567 1438 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1439 err = mp_mul(&t2, x, &t2);
wolfSSL 7:481bce714567 1440 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1441 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1442
wolfSSL 7:481bce714567 1443 /* T1 = T1 * X */
wolfSSL 7:481bce714567 1444 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1445 err = mp_mul(&t1, x, &t1);
wolfSSL 7:481bce714567 1446 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1447 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1448
wolfSSL 7:481bce714567 1449 /* X = Y*Y */
wolfSSL 7:481bce714567 1450 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1451 err = mp_sqr(y, x);
wolfSSL 7:481bce714567 1452 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1453 err = mp_montgomery_reduce(x, modulus, mp);
wolfSSL 7:481bce714567 1454
wolfSSL 7:481bce714567 1455 /* X = X - T2 */
wolfSSL 7:481bce714567 1456 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1457 err = mp_sub(x, &t2, x);
wolfSSL 7:481bce714567 1458 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1459 if (mp_isneg(x))
wolfSSL 7:481bce714567 1460 err = mp_add(x, modulus, x);
wolfSSL 7:481bce714567 1461 }
wolfSSL 7:481bce714567 1462 /* T2 = T2 - X */
wolfSSL 7:481bce714567 1463 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1464 err = mp_sub(&t2, x, &t2);
wolfSSL 7:481bce714567 1465 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1466 if (mp_isneg(&t2))
wolfSSL 7:481bce714567 1467 err = mp_add(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1468 }
wolfSSL 7:481bce714567 1469 /* T2 = T2 - X */
wolfSSL 7:481bce714567 1470 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1471 err = mp_sub(&t2, x, &t2);
wolfSSL 7:481bce714567 1472 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1473 if (mp_isneg(&t2))
wolfSSL 7:481bce714567 1474 err = mp_add(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1475 }
wolfSSL 7:481bce714567 1476 /* T2 = T2 * Y */
wolfSSL 7:481bce714567 1477 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1478 err = mp_mul(&t2, y, &t2);
wolfSSL 7:481bce714567 1479 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1480 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1481
wolfSSL 7:481bce714567 1482 /* Y = T2 - T1 */
wolfSSL 7:481bce714567 1483 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1484 err = mp_sub(&t2, &t1, y);
wolfSSL 7:481bce714567 1485 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1486 if (mp_isneg(y))
wolfSSL 7:481bce714567 1487 err = mp_add(y, modulus, y);
wolfSSL 7:481bce714567 1488 }
wolfSSL 7:481bce714567 1489 /* Y = Y/2 */
wolfSSL 7:481bce714567 1490 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1491 if (mp_isodd(y) == MP_YES)
wolfSSL 7:481bce714567 1492 err = mp_add(y, modulus, y);
wolfSSL 7:481bce714567 1493 }
wolfSSL 7:481bce714567 1494 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1495 err = mp_div_2(y, y);
wolfSSL 7:481bce714567 1496
wolfSSL 7:481bce714567 1497 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1498 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1499 err = mp_copy(x, R->x);
wolfSSL 7:481bce714567 1500 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1501 err = mp_copy(y, R->y);
wolfSSL 7:481bce714567 1502 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1503 err = mp_copy(z, R->z);
wolfSSL 7:481bce714567 1504 #endif
wolfSSL 7:481bce714567 1505
wolfSSL 7:481bce714567 1506 done:
wolfSSL 7:481bce714567 1507 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1508 /* clean up */
wolfSSL 7:481bce714567 1509 mp_clear(&t1);
wolfSSL 7:481bce714567 1510 mp_clear(&t2);
wolfSSL 7:481bce714567 1511 #endif
wolfSSL 7:481bce714567 1512
wolfSSL 7:481bce714567 1513 return err;
wolfSSL 7:481bce714567 1514 }
wolfSSL 7:481bce714567 1515
wolfSSL 7:481bce714567 1516 /* ### Point doubling in Jacobian coordinate system ###
wolfSSL 7:481bce714567 1517 *
wolfSSL 7:481bce714567 1518 * let us have a curve: y^2 = x^3 + a*x + b
wolfSSL 7:481bce714567 1519 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6
wolfSSL 7:481bce714567 1520 *
wolfSSL 7:481bce714567 1521 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
wolfSSL 7:481bce714567 1522 * Xr = M^2 - 2*S
wolfSSL 7:481bce714567 1523 * Yr = M * (S - Xr) - 8*T
wolfSSL 7:481bce714567 1524 * Zr = 2 * Yp * Zp
wolfSSL 7:481bce714567 1525 *
wolfSSL 7:481bce714567 1526 * M = 3 * Xp^2 + a*Zp^4
wolfSSL 7:481bce714567 1527 * T = Yp^4
wolfSSL 7:481bce714567 1528 * S = 4 * Xp * Yp^2
wolfSSL 7:481bce714567 1529 *
wolfSSL 7:481bce714567 1530 * SPECIAL CASE: when a == 3 we can compute M as
wolfSSL 7:481bce714567 1531 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
wolfSSL 7:481bce714567 1532 */
wolfSSL 7:481bce714567 1533
wolfSSL 7:481bce714567 1534 /**
wolfSSL 7:481bce714567 1535 Double an ECC point
wolfSSL 7:481bce714567 1536 P The point to double
wolfSSL 7:481bce714567 1537 R [out] The destination of the double
wolfSSL 7:481bce714567 1538 a ECC curve parameter a
wolfSSL 7:481bce714567 1539 modulus The modulus of the field the ECC curve is in
wolfSSL 7:481bce714567 1540 mp The "b" value from montgomery_setup()
wolfSSL 7:481bce714567 1541 return MP_OKAY on success
wolfSSL 7:481bce714567 1542 */
wolfSSL 7:481bce714567 1543 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
wolfSSL 7:481bce714567 1544 mp_int* modulus, mp_digit mp)
wolfSSL 7:481bce714567 1545 {
wolfSSL 7:481bce714567 1546 mp_int t1, t2;
wolfSSL 7:481bce714567 1547 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1548 mp_int rx, ry, rz;
wolfSSL 7:481bce714567 1549 #endif
wolfSSL 7:481bce714567 1550 mp_int *x, *y, *z;
wolfSSL 7:481bce714567 1551 int err;
wolfSSL 7:481bce714567 1552
wolfSSL 7:481bce714567 1553 if (P == NULL || R == NULL || modulus == NULL)
wolfSSL 7:481bce714567 1554 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1555
wolfSSL 7:481bce714567 1556 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1557 return err;
wolfSSL 7:481bce714567 1558 }
wolfSSL 7:481bce714567 1559
wolfSSL 7:481bce714567 1560 /* If use ALT_ECC_SIZE we need to use local stack variable since
wolfSSL 7:481bce714567 1561 ecc_point x,y,z is reduced size */
wolfSSL 7:481bce714567 1562 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1563 /* Use local stack variable */
wolfSSL 7:481bce714567 1564 x = &rx;
wolfSSL 7:481bce714567 1565 y = &ry;
wolfSSL 7:481bce714567 1566 z = &rz;
wolfSSL 7:481bce714567 1567
wolfSSL 7:481bce714567 1568 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1569 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1570 mp_clear(&t1);
wolfSSL 7:481bce714567 1571 mp_clear(&t2);
wolfSSL 7:481bce714567 1572 #endif
wolfSSL 7:481bce714567 1573 return err;
wolfSSL 7:481bce714567 1574 }
wolfSSL 7:481bce714567 1575 #else
wolfSSL 7:481bce714567 1576 /* Use destination directly */
wolfSSL 7:481bce714567 1577 x = R->x;
wolfSSL 7:481bce714567 1578 y = R->y;
wolfSSL 7:481bce714567 1579 z = R->z;
wolfSSL 7:481bce714567 1580 #endif
wolfSSL 7:481bce714567 1581
wolfSSL 7:481bce714567 1582 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1583 err = mp_copy(P->x, x);
wolfSSL 7:481bce714567 1584 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1585 err = mp_copy(P->y, y);
wolfSSL 7:481bce714567 1586 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1587 err = mp_copy(P->z, z);
wolfSSL 7:481bce714567 1588
wolfSSL 7:481bce714567 1589 /* T1 = Z * Z */
wolfSSL 7:481bce714567 1590 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1591 err = mp_sqr(z, &t1);
wolfSSL 7:481bce714567 1592 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1593 err = mp_montgomery_reduce(&t1, modulus, mp);
wolfSSL 7:481bce714567 1594
wolfSSL 7:481bce714567 1595 /* Z = Y * Z */
wolfSSL 7:481bce714567 1596 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1597 err = mp_mul(z, y, z);
wolfSSL 7:481bce714567 1598 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1599 err = mp_montgomery_reduce(z, modulus, mp);
wolfSSL 7:481bce714567 1600
wolfSSL 7:481bce714567 1601 /* Z = 2Z */
wolfSSL 7:481bce714567 1602 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1603 err = mp_add(z, z, z);
wolfSSL 7:481bce714567 1604 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1605 if (mp_cmp(z, modulus) != MP_LT)
wolfSSL 7:481bce714567 1606 err = mp_sub(z, modulus, z);
wolfSSL 7:481bce714567 1607 }
wolfSSL 7:481bce714567 1608
wolfSSL 7:481bce714567 1609 /* Determine if curve "a" should be used in calc */
wolfSSL 7:481bce714567 1610 #ifdef WOLFSSL_CUSTOM_CURVES
wolfSSL 7:481bce714567 1611 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1612 /* Use a and prime to determine if a == 3 */
wolfSSL 7:481bce714567 1613 err = mp_submod(modulus, a, modulus, &t2);
wolfSSL 7:481bce714567 1614 }
wolfSSL 7:481bce714567 1615 if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
wolfSSL 7:481bce714567 1616 /* use "a" in calc */
wolfSSL 7:481bce714567 1617
wolfSSL 7:481bce714567 1618 /* T2 = T1 * T1 */
wolfSSL 7:481bce714567 1619 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1620 err = mp_sqr(&t1, &t2);
wolfSSL 7:481bce714567 1621 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1622 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1623 /* T1 = T2 * a */
wolfSSL 7:481bce714567 1624 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1625 err = mp_mulmod(&t2, a, modulus, &t1);
wolfSSL 7:481bce714567 1626 /* T2 = X * X */
wolfSSL 7:481bce714567 1627 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1628 err = mp_sqr(x, &t2);
wolfSSL 7:481bce714567 1629 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1630 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1631 /* T1 = T2 + T1 */
wolfSSL 7:481bce714567 1632 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1633 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 1634 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1635 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1636 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1637 }
wolfSSL 7:481bce714567 1638 /* T1 = T2 + T1 */
wolfSSL 7:481bce714567 1639 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1640 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 1641 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1642 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1643 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1644 }
wolfSSL 7:481bce714567 1645 /* T1 = T2 + T1 */
wolfSSL 7:481bce714567 1646 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1647 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 1648 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1649 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1650 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1651 }
wolfSSL 7:481bce714567 1652 }
wolfSSL 7:481bce714567 1653 else
wolfSSL 7:481bce714567 1654 #endif /* WOLFSSL_CUSTOM_CURVES */
wolfSSL 7:481bce714567 1655 {
wolfSSL 7:481bce714567 1656 /* assumes "a" == 3 */
wolfSSL 7:481bce714567 1657 (void)a;
wolfSSL 7:481bce714567 1658
wolfSSL 7:481bce714567 1659 /* T2 = X - T1 */
wolfSSL 7:481bce714567 1660 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1661 err = mp_sub(x, &t1, &t2);
wolfSSL 7:481bce714567 1662 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1663 if (mp_isneg(&t2))
wolfSSL 7:481bce714567 1664 err = mp_add(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1665 }
wolfSSL 7:481bce714567 1666 /* T1 = X + T1 */
wolfSSL 7:481bce714567 1667 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1668 err = mp_add(&t1, x, &t1);
wolfSSL 7:481bce714567 1669 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1670 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1671 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1672 }
wolfSSL 7:481bce714567 1673 /* T2 = T1 * T2 */
wolfSSL 7:481bce714567 1674 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1675 err = mp_mul(&t1, &t2, &t2);
wolfSSL 7:481bce714567 1676 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1677 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1678
wolfSSL 7:481bce714567 1679 /* T1 = 2T2 */
wolfSSL 7:481bce714567 1680 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1681 err = mp_add(&t2, &t2, &t1);
wolfSSL 7:481bce714567 1682 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1683 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1684 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1685 }
wolfSSL 7:481bce714567 1686 /* T1 = T1 + T2 */
wolfSSL 7:481bce714567 1687 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1688 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 1689 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1690 if (mp_cmp(&t1, modulus) != MP_LT)
wolfSSL 7:481bce714567 1691 err = mp_sub(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1692 }
wolfSSL 7:481bce714567 1693 }
wolfSSL 7:481bce714567 1694
wolfSSL 7:481bce714567 1695 /* Y = 2Y */
wolfSSL 7:481bce714567 1696 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1697 err = mp_add(y, y, y);
wolfSSL 7:481bce714567 1698 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1699 if (mp_cmp(y, modulus) != MP_LT)
wolfSSL 7:481bce714567 1700 err = mp_sub(y, modulus, y);
wolfSSL 7:481bce714567 1701 }
wolfSSL 7:481bce714567 1702 /* Y = Y * Y */
wolfSSL 7:481bce714567 1703 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1704 err = mp_sqr(y, y);
wolfSSL 7:481bce714567 1705 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1706 err = mp_montgomery_reduce(y, modulus, mp);
wolfSSL 7:481bce714567 1707
wolfSSL 7:481bce714567 1708 /* T2 = Y * Y */
wolfSSL 7:481bce714567 1709 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1710 err = mp_sqr(y, &t2);
wolfSSL 7:481bce714567 1711 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1712 err = mp_montgomery_reduce(&t2, modulus, mp);
wolfSSL 7:481bce714567 1713
wolfSSL 7:481bce714567 1714 /* T2 = T2/2 */
wolfSSL 7:481bce714567 1715 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1716 if (mp_isodd(&t2) == MP_YES)
wolfSSL 7:481bce714567 1717 err = mp_add(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1718 }
wolfSSL 7:481bce714567 1719 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1720 err = mp_div_2(&t2, &t2);
wolfSSL 7:481bce714567 1721
wolfSSL 7:481bce714567 1722 /* Y = Y * X */
wolfSSL 7:481bce714567 1723 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1724 err = mp_mul(y, x, y);
wolfSSL 7:481bce714567 1725 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1726 err = mp_montgomery_reduce(y, modulus, mp);
wolfSSL 7:481bce714567 1727
wolfSSL 7:481bce714567 1728 /* X = T1 * T1 */
wolfSSL 7:481bce714567 1729 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1730 err = mp_sqr(&t1, x);
wolfSSL 7:481bce714567 1731 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1732 err = mp_montgomery_reduce(x, modulus, mp);
wolfSSL 7:481bce714567 1733
wolfSSL 7:481bce714567 1734 /* X = X - Y */
wolfSSL 7:481bce714567 1735 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1736 err = mp_sub(x, y, x);
wolfSSL 7:481bce714567 1737 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1738 if (mp_isneg(x))
wolfSSL 7:481bce714567 1739 err = mp_add(x, modulus, x);
wolfSSL 7:481bce714567 1740 }
wolfSSL 7:481bce714567 1741 /* X = X - Y */
wolfSSL 7:481bce714567 1742 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1743 err = mp_sub(x, y, x);
wolfSSL 7:481bce714567 1744 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1745 if (mp_isneg(x))
wolfSSL 7:481bce714567 1746 err = mp_add(x, modulus, x);
wolfSSL 7:481bce714567 1747 }
wolfSSL 7:481bce714567 1748
wolfSSL 7:481bce714567 1749 /* Y = Y - X */
wolfSSL 7:481bce714567 1750 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1751 err = mp_sub(y, x, y);
wolfSSL 7:481bce714567 1752 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1753 if (mp_isneg(y))
wolfSSL 7:481bce714567 1754 err = mp_add(y, modulus, y);
wolfSSL 7:481bce714567 1755 }
wolfSSL 7:481bce714567 1756 /* Y = Y * T1 */
wolfSSL 7:481bce714567 1757 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1758 err = mp_mul(y, &t1, y);
wolfSSL 7:481bce714567 1759 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1760 err = mp_montgomery_reduce(y, modulus, mp);
wolfSSL 7:481bce714567 1761
wolfSSL 7:481bce714567 1762 /* Y = Y - T2 */
wolfSSL 7:481bce714567 1763 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1764 err = mp_sub(y, &t2, y);
wolfSSL 7:481bce714567 1765 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 1766 if (mp_isneg(y))
wolfSSL 7:481bce714567 1767 err = mp_add(y, modulus, y);
wolfSSL 7:481bce714567 1768 }
wolfSSL 7:481bce714567 1769
wolfSSL 7:481bce714567 1770 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1771 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1772 err = mp_copy(x, R->x);
wolfSSL 7:481bce714567 1773 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1774 err = mp_copy(y, R->y);
wolfSSL 7:481bce714567 1775 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1776 err = mp_copy(z, R->z);
wolfSSL 7:481bce714567 1777 #endif
wolfSSL 7:481bce714567 1778
wolfSSL 7:481bce714567 1779 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1780 /* clean up */
wolfSSL 7:481bce714567 1781 mp_clear(&t1);
wolfSSL 7:481bce714567 1782 mp_clear(&t2);
wolfSSL 7:481bce714567 1783 #endif
wolfSSL 7:481bce714567 1784
wolfSSL 7:481bce714567 1785 return err;
wolfSSL 7:481bce714567 1786 }
wolfSSL 7:481bce714567 1787
wolfSSL 7:481bce714567 1788
wolfSSL 7:481bce714567 1789 /**
wolfSSL 7:481bce714567 1790 Map a projective jacbobian point back to affine space
wolfSSL 7:481bce714567 1791 P [in/out] The point to map
wolfSSL 7:481bce714567 1792 modulus The modulus of the field the ECC curve is in
wolfSSL 7:481bce714567 1793 mp The "b" value from montgomery_setup()
wolfSSL 7:481bce714567 1794 return MP_OKAY on success
wolfSSL 7:481bce714567 1795 */
wolfSSL 7:481bce714567 1796 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
wolfSSL 7:481bce714567 1797 {
wolfSSL 7:481bce714567 1798 mp_int t1, t2;
wolfSSL 7:481bce714567 1799 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1800 mp_int rx, ry, rz;
wolfSSL 7:481bce714567 1801 #endif
wolfSSL 7:481bce714567 1802 mp_int *x, *y, *z;
wolfSSL 7:481bce714567 1803 int err;
wolfSSL 7:481bce714567 1804
wolfSSL 7:481bce714567 1805 if (P == NULL || modulus == NULL)
wolfSSL 7:481bce714567 1806 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1807
wolfSSL 7:481bce714567 1808 /* special case for point at infinity */
wolfSSL 7:481bce714567 1809 if (mp_cmp_d(P->z, 0) == MP_EQ) {
wolfSSL 7:481bce714567 1810 err = mp_set(P->x, 0);
wolfSSL 7:481bce714567 1811 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1812 err = mp_set(P->y, 0);
wolfSSL 7:481bce714567 1813 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1814 err = mp_set(P->z, 1);
wolfSSL 7:481bce714567 1815 return err;
wolfSSL 7:481bce714567 1816 }
wolfSSL 7:481bce714567 1817
wolfSSL 7:481bce714567 1818 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1819 return MEMORY_E;
wolfSSL 7:481bce714567 1820 }
wolfSSL 7:481bce714567 1821
wolfSSL 7:481bce714567 1822 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1823 /* Use local stack variable */
wolfSSL 7:481bce714567 1824 x = &rx;
wolfSSL 7:481bce714567 1825 y = &ry;
wolfSSL 7:481bce714567 1826 z = &rz;
wolfSSL 7:481bce714567 1827
wolfSSL 7:481bce714567 1828 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 1829 goto done;
wolfSSL 7:481bce714567 1830 }
wolfSSL 7:481bce714567 1831
wolfSSL 7:481bce714567 1832 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1833 err = mp_copy(P->x, x);
wolfSSL 7:481bce714567 1834 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1835 err = mp_copy(P->y, y);
wolfSSL 7:481bce714567 1836 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1837 err = mp_copy(P->z, z);
wolfSSL 7:481bce714567 1838 #else
wolfSSL 7:481bce714567 1839 /* Use destination directly */
wolfSSL 7:481bce714567 1840 x = P->x;
wolfSSL 7:481bce714567 1841 y = P->y;
wolfSSL 7:481bce714567 1842 z = P->z;
wolfSSL 7:481bce714567 1843 #endif
wolfSSL 7:481bce714567 1844
wolfSSL 7:481bce714567 1845 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 1846 goto done;
wolfSSL 7:481bce714567 1847 }
wolfSSL 7:481bce714567 1848
wolfSSL 7:481bce714567 1849 /* first map z back to normal */
wolfSSL 7:481bce714567 1850 err = mp_montgomery_reduce(z, modulus, mp);
wolfSSL 7:481bce714567 1851
wolfSSL 7:481bce714567 1852 /* get 1/z */
wolfSSL 7:481bce714567 1853 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1854 err = mp_invmod(z, modulus, &t1);
wolfSSL 7:481bce714567 1855
wolfSSL 7:481bce714567 1856 /* get 1/z^2 and 1/z^3 */
wolfSSL 7:481bce714567 1857 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1858 err = mp_sqr(&t1, &t2);
wolfSSL 7:481bce714567 1859 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1860 err = mp_mod(&t2, modulus, &t2);
wolfSSL 7:481bce714567 1861 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1862 err = mp_mul(&t1, &t2, &t1);
wolfSSL 7:481bce714567 1863 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1864 err = mp_mod(&t1, modulus, &t1);
wolfSSL 7:481bce714567 1865
wolfSSL 7:481bce714567 1866 /* multiply against x/y */
wolfSSL 7:481bce714567 1867 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1868 err = mp_mul(x, &t2, x);
wolfSSL 7:481bce714567 1869 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1870 err = mp_montgomery_reduce(x, modulus, mp);
wolfSSL 7:481bce714567 1871 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1872 err = mp_mul(y, &t1, y);
wolfSSL 7:481bce714567 1873 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1874 err = mp_montgomery_reduce(y, modulus, mp);
wolfSSL 7:481bce714567 1875
wolfSSL 7:481bce714567 1876 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1877 err = mp_set(z, 1);
wolfSSL 7:481bce714567 1878
wolfSSL 7:481bce714567 1879 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 1880 /* return result */
wolfSSL 7:481bce714567 1881 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1882 err = mp_copy(x, P->x);
wolfSSL 7:481bce714567 1883 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1884 err = mp_copy(y, P->y);
wolfSSL 7:481bce714567 1885 if (err == MP_OKAY)
wolfSSL 7:481bce714567 1886 err = mp_copy(z, P->z);
wolfSSL 7:481bce714567 1887 #endif
wolfSSL 7:481bce714567 1888
wolfSSL 7:481bce714567 1889 done:
wolfSSL 7:481bce714567 1890 /* clean up */
wolfSSL 7:481bce714567 1891 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1892 mp_clear(&t1);
wolfSSL 7:481bce714567 1893 mp_clear(&t2);
wolfSSL 7:481bce714567 1894 #endif
wolfSSL 7:481bce714567 1895
wolfSSL 7:481bce714567 1896 return err;
wolfSSL 7:481bce714567 1897 }
wolfSSL 7:481bce714567 1898
wolfSSL 7:481bce714567 1899 #if !defined(FREESCALE_LTC_ECC)
wolfSSL 7:481bce714567 1900
wolfSSL 7:481bce714567 1901 #ifndef WC_NO_CACHE_RESISTANT
wolfSSL 7:481bce714567 1902 #if defined(TFM_TIMING_RESISTANT) && defined(USE_FAST_MATH) && \
wolfSSL 7:481bce714567 1903 !defined(__cplusplus)
wolfSSL 7:481bce714567 1904 /* let's use the one we already have */
wolfSSL 7:481bce714567 1905 extern const wolfssl_word wc_off_on_addr[2];
wolfSSL 7:481bce714567 1906 #elif defined(ECC_TIMING_RESISTANT)
wolfSSL 7:481bce714567 1907 static const wolfssl_word wc_off_on_addr[2] =
wolfSSL 7:481bce714567 1908 {
wolfSSL 7:481bce714567 1909 #if defined(WC_64BIT_CPU)
wolfSSL 7:481bce714567 1910 W64LIT(0x0000000000000000),
wolfSSL 7:481bce714567 1911 W64LIT(0xffffffffffffffff)
wolfSSL 7:481bce714567 1912 #elif defined(WC_16BIT_CPU)
wolfSSL 7:481bce714567 1913 0x0000U,
wolfSSL 7:481bce714567 1914 0xffffU
wolfSSL 7:481bce714567 1915 #else
wolfSSL 7:481bce714567 1916 /* 32 bit */
wolfSSL 7:481bce714567 1917 0x00000000U,
wolfSSL 7:481bce714567 1918 0xffffffffU
wolfSSL 7:481bce714567 1919 #endif
wolfSSL 7:481bce714567 1920 };
wolfSSL 7:481bce714567 1921 #endif /* TFM_TIMING_RESISTANT && USE_FAST_MATH */
wolfSSL 7:481bce714567 1922 #endif /* WC_NO_CACHE_RESISTANT */
wolfSSL 7:481bce714567 1923
wolfSSL 7:481bce714567 1924 /**
wolfSSL 7:481bce714567 1925 Perform a point multiplication
wolfSSL 7:481bce714567 1926 k The scalar to multiply by
wolfSSL 7:481bce714567 1927 G The base point
wolfSSL 7:481bce714567 1928 R [out] Destination for kG
wolfSSL 7:481bce714567 1929 a ECC curve parameter a
wolfSSL 7:481bce714567 1930 modulus The modulus of the field the ECC curve is in
wolfSSL 7:481bce714567 1931 map Boolean whether to map back to affine or not
wolfSSL 7:481bce714567 1932 (1==map, 0 == leave in projective)
wolfSSL 7:481bce714567 1933 return MP_OKAY on success
wolfSSL 7:481bce714567 1934 */
wolfSSL 7:481bce714567 1935 #ifdef FP_ECC
wolfSSL 7:481bce714567 1936 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
wolfSSL 7:481bce714567 1937 mp_int* a, mp_int* modulus, int map,
wolfSSL 7:481bce714567 1938 void* heap)
wolfSSL 7:481bce714567 1939 #else
wolfSSL 7:481bce714567 1940 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
wolfSSL 7:481bce714567 1941 mp_int* a, mp_int* modulus, int map,
wolfSSL 7:481bce714567 1942 void* heap)
wolfSSL 7:481bce714567 1943 #endif
wolfSSL 7:481bce714567 1944 {
wolfSSL 7:481bce714567 1945 #ifndef ECC_TIMING_RESISTANT
wolfSSL 7:481bce714567 1946 /* size of sliding window, don't change this! */
wolfSSL 7:481bce714567 1947 #define WINSIZE 4
wolfSSL 7:481bce714567 1948 #define M_POINTS 8
wolfSSL 7:481bce714567 1949 int first = 1, bitbuf = 0, bitcpy = 0, j;
wolfSSL 7:481bce714567 1950 #else
wolfSSL 7:481bce714567 1951 #define M_POINTS 3
wolfSSL 7:481bce714567 1952 #endif
wolfSSL 7:481bce714567 1953
wolfSSL 7:481bce714567 1954 ecc_point *tG, *M[M_POINTS];
wolfSSL 7:481bce714567 1955 int i, err;
wolfSSL 7:481bce714567 1956 mp_int mu;
wolfSSL 7:481bce714567 1957 mp_digit mp;
wolfSSL 7:481bce714567 1958 mp_digit buf;
wolfSSL 7:481bce714567 1959 int bitcnt = 0, mode = 0, digidx = 0;
wolfSSL 7:481bce714567 1960
wolfSSL 7:481bce714567 1961 if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
wolfSSL 7:481bce714567 1962 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 1963 }
wolfSSL 7:481bce714567 1964
wolfSSL 7:481bce714567 1965 /* init variables */
wolfSSL 7:481bce714567 1966 tG = NULL;
wolfSSL 7:481bce714567 1967 XMEMSET(M, 0, sizeof(M));
wolfSSL 7:481bce714567 1968
wolfSSL 7:481bce714567 1969 /* init montgomery reduction */
wolfSSL 7:481bce714567 1970 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 1971 return err;
wolfSSL 7:481bce714567 1972 }
wolfSSL 7:481bce714567 1973
wolfSSL 7:481bce714567 1974 if ((err = mp_init(&mu)) != MP_OKAY) {
wolfSSL 7:481bce714567 1975 return err;
wolfSSL 7:481bce714567 1976 }
wolfSSL 7:481bce714567 1977 if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) {
wolfSSL 7:481bce714567 1978 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1979 mp_clear(&mu);
wolfSSL 7:481bce714567 1980 #endif
wolfSSL 7:481bce714567 1981 return err;
wolfSSL 7:481bce714567 1982 }
wolfSSL 7:481bce714567 1983
wolfSSL 7:481bce714567 1984 /* alloc ram for window temps */
wolfSSL 7:481bce714567 1985 for (i = 0; i < M_POINTS; i++) {
wolfSSL 7:481bce714567 1986 M[i] = wc_ecc_new_point_h(heap);
wolfSSL 7:481bce714567 1987 if (M[i] == NULL) {
wolfSSL 7:481bce714567 1988 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 1989 mp_clear(&mu);
wolfSSL 7:481bce714567 1990 #endif
wolfSSL 7:481bce714567 1991 err = MEMORY_E; goto exit;
wolfSSL 7:481bce714567 1992 }
wolfSSL 7:481bce714567 1993 }
wolfSSL 7:481bce714567 1994
wolfSSL 7:481bce714567 1995 /* make a copy of G in case R==G */
wolfSSL 7:481bce714567 1996 tG = wc_ecc_new_point_h(heap);
wolfSSL 7:481bce714567 1997 if (tG == NULL)
wolfSSL 7:481bce714567 1998 err = MEMORY_E;
wolfSSL 7:481bce714567 1999
wolfSSL 7:481bce714567 2000 /* tG = G and convert to montgomery */
wolfSSL 7:481bce714567 2001 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2002 if (mp_cmp_d(&mu, 1) == MP_EQ) {
wolfSSL 7:481bce714567 2003 err = mp_copy(G->x, tG->x);
wolfSSL 7:481bce714567 2004 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2005 err = mp_copy(G->y, tG->y);
wolfSSL 7:481bce714567 2006 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2007 err = mp_copy(G->z, tG->z);
wolfSSL 7:481bce714567 2008 } else {
wolfSSL 7:481bce714567 2009 err = mp_mulmod(G->x, &mu, modulus, tG->x);
wolfSSL 7:481bce714567 2010 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2011 err = mp_mulmod(G->y, &mu, modulus, tG->y);
wolfSSL 7:481bce714567 2012 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2013 err = mp_mulmod(G->z, &mu, modulus, tG->z);
wolfSSL 7:481bce714567 2014 }
wolfSSL 7:481bce714567 2015 }
wolfSSL 7:481bce714567 2016
wolfSSL 7:481bce714567 2017 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 2018 /* done with mu */
wolfSSL 7:481bce714567 2019 mp_clear(&mu);
wolfSSL 7:481bce714567 2020 #endif
wolfSSL 7:481bce714567 2021
wolfSSL 7:481bce714567 2022 #ifndef ECC_TIMING_RESISTANT
wolfSSL 7:481bce714567 2023
wolfSSL 7:481bce714567 2024 /* calc the M tab, which holds kG for k==8..15 */
wolfSSL 7:481bce714567 2025 /* M[0] == 8G */
wolfSSL 7:481bce714567 2026 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2027 err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);
wolfSSL 7:481bce714567 2028 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2029 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
wolfSSL 7:481bce714567 2030 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2031 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
wolfSSL 7:481bce714567 2032
wolfSSL 7:481bce714567 2033 /* now find (8+k)G for k=1..7 */
wolfSSL 7:481bce714567 2034 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2035 for (j = 9; j < 16; j++) {
wolfSSL 7:481bce714567 2036 err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a,
wolfSSL 7:481bce714567 2037 modulus, mp);
wolfSSL 7:481bce714567 2038 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2039 }
wolfSSL 7:481bce714567 2040
wolfSSL 7:481bce714567 2041 /* setup sliding window */
wolfSSL 7:481bce714567 2042 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2043 mode = 0;
wolfSSL 7:481bce714567 2044 bitcnt = 1;
wolfSSL 7:481bce714567 2045 buf = 0;
wolfSSL 7:481bce714567 2046 digidx = get_digit_count(k) - 1;
wolfSSL 7:481bce714567 2047 bitcpy = bitbuf = 0;
wolfSSL 7:481bce714567 2048 first = 1;
wolfSSL 7:481bce714567 2049
wolfSSL 7:481bce714567 2050 /* perform ops */
wolfSSL 7:481bce714567 2051 for (;;) {
wolfSSL 7:481bce714567 2052 /* grab next digit as required */
wolfSSL 7:481bce714567 2053 if (--bitcnt == 0) {
wolfSSL 7:481bce714567 2054 if (digidx == -1) {
wolfSSL 7:481bce714567 2055 break;
wolfSSL 7:481bce714567 2056 }
wolfSSL 7:481bce714567 2057 buf = get_digit(k, digidx);
wolfSSL 7:481bce714567 2058 bitcnt = (int) DIGIT_BIT;
wolfSSL 7:481bce714567 2059 --digidx;
wolfSSL 7:481bce714567 2060 }
wolfSSL 7:481bce714567 2061
wolfSSL 7:481bce714567 2062 /* grab the next msb from the ltiplicand */
wolfSSL 7:481bce714567 2063 i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
wolfSSL 7:481bce714567 2064 buf <<= 1;
wolfSSL 7:481bce714567 2065
wolfSSL 7:481bce714567 2066 /* skip leading zero bits */
wolfSSL 7:481bce714567 2067 if (mode == 0 && i == 0)
wolfSSL 7:481bce714567 2068 continue;
wolfSSL 7:481bce714567 2069
wolfSSL 7:481bce714567 2070 /* if the bit is zero and mode == 1 then we double */
wolfSSL 7:481bce714567 2071 if (mode == 1 && i == 0) {
wolfSSL 7:481bce714567 2072 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
wolfSSL 7:481bce714567 2073 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2074 continue;
wolfSSL 7:481bce714567 2075 }
wolfSSL 7:481bce714567 2076
wolfSSL 7:481bce714567 2077 /* else we add it to the window */
wolfSSL 7:481bce714567 2078 bitbuf |= (i << (WINSIZE - ++bitcpy));
wolfSSL 7:481bce714567 2079 mode = 2;
wolfSSL 7:481bce714567 2080
wolfSSL 7:481bce714567 2081 if (bitcpy == WINSIZE) {
wolfSSL 7:481bce714567 2082 /* if this is the first window we do a simple copy */
wolfSSL 7:481bce714567 2083 if (first == 1) {
wolfSSL 7:481bce714567 2084 /* R = kG [k = first window] */
wolfSSL 7:481bce714567 2085 err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
wolfSSL 7:481bce714567 2086 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2087
wolfSSL 7:481bce714567 2088 err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
wolfSSL 7:481bce714567 2089 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2090
wolfSSL 7:481bce714567 2091 err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
wolfSSL 7:481bce714567 2092 first = 0;
wolfSSL 7:481bce714567 2093 } else {
wolfSSL 7:481bce714567 2094 /* normal window */
wolfSSL 7:481bce714567 2095 /* ok window is filled so double as required and add */
wolfSSL 7:481bce714567 2096 /* double first */
wolfSSL 7:481bce714567 2097 for (j = 0; j < WINSIZE; j++) {
wolfSSL 7:481bce714567 2098 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
wolfSSL 7:481bce714567 2099 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2100 }
wolfSSL 7:481bce714567 2101 if (err != MP_OKAY) break; /* out of first for(;;) */
wolfSSL 7:481bce714567 2102
wolfSSL 7:481bce714567 2103 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
wolfSSL 7:481bce714567 2104 err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
wolfSSL 7:481bce714567 2105 modulus, mp);
wolfSSL 7:481bce714567 2106 }
wolfSSL 7:481bce714567 2107 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2108 /* empty window and reset */
wolfSSL 7:481bce714567 2109 bitcpy = bitbuf = 0;
wolfSSL 7:481bce714567 2110 mode = 1;
wolfSSL 7:481bce714567 2111 }
wolfSSL 7:481bce714567 2112 }
wolfSSL 7:481bce714567 2113 }
wolfSSL 7:481bce714567 2114
wolfSSL 7:481bce714567 2115 /* if bits remain then double/add */
wolfSSL 7:481bce714567 2116 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2117 if (mode == 2 && bitcpy > 0) {
wolfSSL 7:481bce714567 2118 /* double then add */
wolfSSL 7:481bce714567 2119 for (j = 0; j < bitcpy; j++) {
wolfSSL 7:481bce714567 2120 /* only double if we have had at least one add first */
wolfSSL 7:481bce714567 2121 if (first == 0) {
wolfSSL 7:481bce714567 2122 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
wolfSSL 7:481bce714567 2123 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2124 }
wolfSSL 7:481bce714567 2125
wolfSSL 7:481bce714567 2126 bitbuf <<= 1;
wolfSSL 7:481bce714567 2127 if ((bitbuf & (1 << WINSIZE)) != 0) {
wolfSSL 7:481bce714567 2128 if (first == 1) {
wolfSSL 7:481bce714567 2129 /* first add, so copy */
wolfSSL 7:481bce714567 2130 err = mp_copy(tG->x, R->x);
wolfSSL 7:481bce714567 2131 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2132
wolfSSL 7:481bce714567 2133 err = mp_copy(tG->y, R->y);
wolfSSL 7:481bce714567 2134 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2135
wolfSSL 7:481bce714567 2136 err = mp_copy(tG->z, R->z);
wolfSSL 7:481bce714567 2137 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2138 first = 0;
wolfSSL 7:481bce714567 2139 } else {
wolfSSL 7:481bce714567 2140 /* then add */
wolfSSL 7:481bce714567 2141 err = ecc_projective_add_point(R, tG, R, a, modulus,
wolfSSL 7:481bce714567 2142 mp);
wolfSSL 7:481bce714567 2143 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 2144 }
wolfSSL 7:481bce714567 2145 }
wolfSSL 7:481bce714567 2146 }
wolfSSL 7:481bce714567 2147 }
wolfSSL 7:481bce714567 2148 }
wolfSSL 7:481bce714567 2149
wolfSSL 7:481bce714567 2150 #undef WINSIZE
wolfSSL 7:481bce714567 2151
wolfSSL 7:481bce714567 2152 #else /* ECC_TIMING_RESISTANT */
wolfSSL 7:481bce714567 2153
wolfSSL 7:481bce714567 2154 /* calc the M tab */
wolfSSL 7:481bce714567 2155 /* M[0] == G */
wolfSSL 7:481bce714567 2156 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2157 err = mp_copy(tG->x, M[0]->x);
wolfSSL 7:481bce714567 2158 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2159 err = mp_copy(tG->y, M[0]->y);
wolfSSL 7:481bce714567 2160 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2161 err = mp_copy(tG->z, M[0]->z);
wolfSSL 7:481bce714567 2162
wolfSSL 7:481bce714567 2163 /* M[1] == 2G */
wolfSSL 7:481bce714567 2164 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2165 err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);
wolfSSL 7:481bce714567 2166
wolfSSL 7:481bce714567 2167 /* setup sliding window */
wolfSSL 7:481bce714567 2168 mode = 0;
wolfSSL 7:481bce714567 2169 bitcnt = 1;
wolfSSL 7:481bce714567 2170 buf = 0;
wolfSSL 7:481bce714567 2171 digidx = get_digit_count(k) - 1;
wolfSSL 7:481bce714567 2172
wolfSSL 7:481bce714567 2173 /* perform ops */
wolfSSL 7:481bce714567 2174 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2175 for (;;) {
wolfSSL 7:481bce714567 2176 /* grab next digit as required */
wolfSSL 7:481bce714567 2177 if (--bitcnt == 0) {
wolfSSL 7:481bce714567 2178 if (digidx == -1) {
wolfSSL 7:481bce714567 2179 break;
wolfSSL 7:481bce714567 2180 }
wolfSSL 7:481bce714567 2181 buf = get_digit(k, digidx);
wolfSSL 7:481bce714567 2182 bitcnt = (int)DIGIT_BIT;
wolfSSL 7:481bce714567 2183 --digidx;
wolfSSL 7:481bce714567 2184 }
wolfSSL 7:481bce714567 2185
wolfSSL 7:481bce714567 2186 /* grab the next msb from the multiplicand */
wolfSSL 7:481bce714567 2187 i = (buf >> (DIGIT_BIT - 1)) & 1;
wolfSSL 7:481bce714567 2188 buf <<= 1;
wolfSSL 7:481bce714567 2189
wolfSSL 7:481bce714567 2190 if (mode == 0 && i == 0) {
wolfSSL 7:481bce714567 2191 /* timing resistant - dummy operations */
wolfSSL 7:481bce714567 2192 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2193 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
wolfSSL 7:481bce714567 2194 mp);
wolfSSL 7:481bce714567 2195 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2196 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
wolfSSL 7:481bce714567 2197 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2198 continue;
wolfSSL 7:481bce714567 2199 }
wolfSSL 7:481bce714567 2200
wolfSSL 7:481bce714567 2201 if (mode == 0 && i == 1) {
wolfSSL 7:481bce714567 2202 mode = 1;
wolfSSL 7:481bce714567 2203 /* timing resistant - dummy operations */
wolfSSL 7:481bce714567 2204 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2205 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
wolfSSL 7:481bce714567 2206 mp);
wolfSSL 7:481bce714567 2207 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2208 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
wolfSSL 7:481bce714567 2209 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2210 continue;
wolfSSL 7:481bce714567 2211 }
wolfSSL 7:481bce714567 2212
wolfSSL 7:481bce714567 2213 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2214 err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus,
wolfSSL 7:481bce714567 2215 mp);
wolfSSL 7:481bce714567 2216 #ifdef WC_NO_CACHE_RESISTANT
wolfSSL 7:481bce714567 2217 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2218 err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
wolfSSL 7:481bce714567 2219 #else
wolfSSL 7:481bce714567 2220 /* instead of using M[i] for double, which leaks key bit to cache
wolfSSL 7:481bce714567 2221 * monitor, use M[2] as temp, make sure address calc is constant,
wolfSSL 7:481bce714567 2222 * keep M[0] and M[1] in cache */
wolfSSL 7:481bce714567 2223 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2224 err = mp_copy((mp_int*)
wolfSSL 7:481bce714567 2225 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2226 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
wolfSSL 7:481bce714567 2227 M[2]->x);
wolfSSL 7:481bce714567 2228 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2229 err = mp_copy((mp_int*)
wolfSSL 7:481bce714567 2230 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2231 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
wolfSSL 7:481bce714567 2232 M[2]->y);
wolfSSL 7:481bce714567 2233 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2234 err = mp_copy((mp_int*)
wolfSSL 7:481bce714567 2235 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2236 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
wolfSSL 7:481bce714567 2237 M[2]->z);
wolfSSL 7:481bce714567 2238 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2239 err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
wolfSSL 7:481bce714567 2240 /* copy M[2] back to M[i] */
wolfSSL 7:481bce714567 2241 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2242 err = mp_copy(M[2]->x,
wolfSSL 7:481bce714567 2243 (mp_int*)
wolfSSL 7:481bce714567 2244 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2245 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
wolfSSL 7:481bce714567 2246 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2247 err = mp_copy(M[2]->y,
wolfSSL 7:481bce714567 2248 (mp_int*)
wolfSSL 7:481bce714567 2249 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2250 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
wolfSSL 7:481bce714567 2251 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2252 err = mp_copy(M[2]->z,
wolfSSL 7:481bce714567 2253 (mp_int*)
wolfSSL 7:481bce714567 2254 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
wolfSSL 7:481bce714567 2255 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
wolfSSL 7:481bce714567 2256 if (err != MP_OKAY)
wolfSSL 7:481bce714567 2257 break;
wolfSSL 7:481bce714567 2258 #endif /* WC_NO_CACHE_RESISTANT */
wolfSSL 7:481bce714567 2259 } /* end for */
wolfSSL 7:481bce714567 2260 }
wolfSSL 7:481bce714567 2261
wolfSSL 7:481bce714567 2262 /* copy result out */
wolfSSL 7:481bce714567 2263 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2264 err = mp_copy(M[0]->x, R->x);
wolfSSL 7:481bce714567 2265 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2266 err = mp_copy(M[0]->y, R->y);
wolfSSL 7:481bce714567 2267 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2268 err = mp_copy(M[0]->z, R->z);
wolfSSL 7:481bce714567 2269
wolfSSL 7:481bce714567 2270 #endif /* ECC_TIMING_RESISTANT */
wolfSSL 7:481bce714567 2271
wolfSSL 7:481bce714567 2272 /* map R back from projective space */
wolfSSL 7:481bce714567 2273 if (err == MP_OKAY && map)
wolfSSL 7:481bce714567 2274 err = ecc_map(R, modulus, mp);
wolfSSL 7:481bce714567 2275
wolfSSL 7:481bce714567 2276 exit:
wolfSSL 7:481bce714567 2277
wolfSSL 7:481bce714567 2278 /* done */
wolfSSL 7:481bce714567 2279 wc_ecc_del_point_h(tG, heap);
wolfSSL 7:481bce714567 2280 for (i = 0; i < M_POINTS; i++) {
wolfSSL 7:481bce714567 2281 wc_ecc_del_point_h(M[i], heap);
wolfSSL 7:481bce714567 2282 }
wolfSSL 7:481bce714567 2283
wolfSSL 7:481bce714567 2284 return err;
wolfSSL 7:481bce714567 2285 }
wolfSSL 7:481bce714567 2286
wolfSSL 7:481bce714567 2287 /** ECC Fixed Point mulmod global
wolfSSL 7:481bce714567 2288 k The multiplicand
wolfSSL 7:481bce714567 2289 G Base point to multiply
wolfSSL 7:481bce714567 2290 R [out] Destination of product
wolfSSL 7:481bce714567 2291 a ECC curve parameter a
wolfSSL 7:481bce714567 2292 modulus The modulus for the curve
wolfSSL 7:481bce714567 2293 map [boolean] If non-zero maps the point back to affine co-ordinates,
wolfSSL 7:481bce714567 2294 otherwise it's left in jacobian-montgomery form
wolfSSL 7:481bce714567 2295 return MP_OKAY if successful
wolfSSL 7:481bce714567 2296 */
wolfSSL 7:481bce714567 2297 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
wolfSSL 7:481bce714567 2298 mp_int* modulus, int map)
wolfSSL 7:481bce714567 2299 {
wolfSSL 7:481bce714567 2300 return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
wolfSSL 7:481bce714567 2301 }
wolfSSL 7:481bce714567 2302
wolfSSL 7:481bce714567 2303 #endif /* !FREESCALE_LTC_ECC */
wolfSSL 7:481bce714567 2304
wolfSSL 7:481bce714567 2305
wolfSSL 7:481bce714567 2306 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 2307
wolfSSL 7:481bce714567 2308 static void alt_fp_init(fp_int* a)
wolfSSL 7:481bce714567 2309 {
wolfSSL 7:481bce714567 2310 a->size = FP_SIZE_ECC;
wolfSSL 7:481bce714567 2311 fp_zero(a);
wolfSSL 7:481bce714567 2312 }
wolfSSL 7:481bce714567 2313
wolfSSL 7:481bce714567 2314 #endif /* ALT_ECC_SIZE */
wolfSSL 7:481bce714567 2315
wolfSSL 7:481bce714567 2316
wolfSSL 7:481bce714567 2317 /**
wolfSSL 7:481bce714567 2318 * use a heap hint when creating new ecc_point
wolfSSL 7:481bce714567 2319 * return an allocated point on success or NULL on failure
wolfSSL 7:481bce714567 2320 */
wolfSSL 7:481bce714567 2321 ecc_point* wc_ecc_new_point_h(void* heap)
wolfSSL 7:481bce714567 2322 {
wolfSSL 7:481bce714567 2323 ecc_point* p;
wolfSSL 7:481bce714567 2324
wolfSSL 7:481bce714567 2325 p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 2326 if (p == NULL) {
wolfSSL 7:481bce714567 2327 return NULL;
wolfSSL 7:481bce714567 2328 }
wolfSSL 7:481bce714567 2329 XMEMSET(p, 0, sizeof(ecc_point));
wolfSSL 7:481bce714567 2330
wolfSSL 7:481bce714567 2331 #ifndef ALT_ECC_SIZE
wolfSSL 7:481bce714567 2332 if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 7:481bce714567 2333 XFREE(p, heap, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 2334 return NULL;
wolfSSL 7:481bce714567 2335 }
wolfSSL 7:481bce714567 2336 #else
wolfSSL 7:481bce714567 2337 p->x = (mp_int*)&p->xyz[0];
wolfSSL 7:481bce714567 2338 p->y = (mp_int*)&p->xyz[1];
wolfSSL 7:481bce714567 2339 p->z = (mp_int*)&p->xyz[2];
wolfSSL 7:481bce714567 2340 alt_fp_init(p->x);
wolfSSL 7:481bce714567 2341 alt_fp_init(p->y);
wolfSSL 7:481bce714567 2342 alt_fp_init(p->z);
wolfSSL 7:481bce714567 2343 #endif
wolfSSL 7:481bce714567 2344
wolfSSL 7:481bce714567 2345 return p;
wolfSSL 7:481bce714567 2346 }
wolfSSL 7:481bce714567 2347
wolfSSL 7:481bce714567 2348
wolfSSL 7:481bce714567 2349 /**
wolfSSL 7:481bce714567 2350 Allocate a new ECC point
wolfSSL 7:481bce714567 2351 return A newly allocated point or NULL on error
wolfSSL 7:481bce714567 2352 */
wolfSSL 7:481bce714567 2353 ecc_point* wc_ecc_new_point(void)
wolfSSL 7:481bce714567 2354 {
wolfSSL 7:481bce714567 2355 return wc_ecc_new_point_h(NULL);
wolfSSL 7:481bce714567 2356 }
wolfSSL 7:481bce714567 2357
wolfSSL 7:481bce714567 2358
wolfSSL 7:481bce714567 2359 void wc_ecc_del_point_h(ecc_point* p, void* heap)
wolfSSL 7:481bce714567 2360 {
wolfSSL 7:481bce714567 2361 /* prevents free'ing null arguments */
wolfSSL 7:481bce714567 2362 if (p != NULL) {
wolfSSL 7:481bce714567 2363 mp_clear(p->x);
wolfSSL 7:481bce714567 2364 mp_clear(p->y);
wolfSSL 7:481bce714567 2365 mp_clear(p->z);
wolfSSL 7:481bce714567 2366 XFREE(p, heap, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 2367 }
wolfSSL 7:481bce714567 2368 (void)heap;
wolfSSL 7:481bce714567 2369 }
wolfSSL 7:481bce714567 2370
wolfSSL 7:481bce714567 2371
wolfSSL 7:481bce714567 2372 /** Free an ECC point from memory
wolfSSL 7:481bce714567 2373 p The point to free
wolfSSL 7:481bce714567 2374 */
wolfSSL 7:481bce714567 2375 void wc_ecc_del_point(ecc_point* p)
wolfSSL 7:481bce714567 2376 {
wolfSSL 7:481bce714567 2377 wc_ecc_del_point_h(p, NULL);
wolfSSL 7:481bce714567 2378 }
wolfSSL 7:481bce714567 2379
wolfSSL 7:481bce714567 2380
wolfSSL 7:481bce714567 2381 /** Copy the value of a point to an other one
wolfSSL 7:481bce714567 2382 p The point to copy
wolfSSL 7:481bce714567 2383 r The created point
wolfSSL 7:481bce714567 2384 */
wolfSSL 7:481bce714567 2385 int wc_ecc_copy_point(ecc_point* p, ecc_point *r)
wolfSSL 7:481bce714567 2386 {
wolfSSL 7:481bce714567 2387 int ret;
wolfSSL 7:481bce714567 2388
wolfSSL 7:481bce714567 2389 /* prevents null arguments */
wolfSSL 7:481bce714567 2390 if (p == NULL || r == NULL)
wolfSSL 7:481bce714567 2391 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2392
wolfSSL 7:481bce714567 2393 ret = mp_copy(p->x, r->x);
wolfSSL 7:481bce714567 2394 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 2395 return ret;
wolfSSL 7:481bce714567 2396 ret = mp_copy(p->y, r->y);
wolfSSL 7:481bce714567 2397 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 2398 return ret;
wolfSSL 7:481bce714567 2399 ret = mp_copy(p->z, r->z);
wolfSSL 7:481bce714567 2400 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 2401 return ret;
wolfSSL 7:481bce714567 2402
wolfSSL 7:481bce714567 2403 return MP_OKAY;
wolfSSL 7:481bce714567 2404 }
wolfSSL 7:481bce714567 2405
wolfSSL 7:481bce714567 2406 /** Compare the value of a point with an other one
wolfSSL 7:481bce714567 2407 a The point to compare
wolfSSL 7:481bce714567 2408 b The other point to compare
wolfSSL 7:481bce714567 2409
wolfSSL 7:481bce714567 2410 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
wolfSSL 7:481bce714567 2411 */
wolfSSL 7:481bce714567 2412 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
wolfSSL 7:481bce714567 2413 {
wolfSSL 7:481bce714567 2414 int ret;
wolfSSL 7:481bce714567 2415
wolfSSL 7:481bce714567 2416 /* prevents null arguments */
wolfSSL 7:481bce714567 2417 if (a == NULL || b == NULL)
wolfSSL 7:481bce714567 2418 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2419
wolfSSL 7:481bce714567 2420 ret = mp_cmp(a->x, b->x);
wolfSSL 7:481bce714567 2421 if (ret != MP_EQ)
wolfSSL 7:481bce714567 2422 return ret;
wolfSSL 7:481bce714567 2423 ret = mp_cmp(a->y, b->y);
wolfSSL 7:481bce714567 2424 if (ret != MP_EQ)
wolfSSL 7:481bce714567 2425 return ret;
wolfSSL 7:481bce714567 2426 ret = mp_cmp(a->z, b->z);
wolfSSL 7:481bce714567 2427 if (ret != MP_EQ)
wolfSSL 7:481bce714567 2428 return ret;
wolfSSL 7:481bce714567 2429
wolfSSL 7:481bce714567 2430 return MP_EQ;
wolfSSL 7:481bce714567 2431 }
wolfSSL 7:481bce714567 2432
wolfSSL 7:481bce714567 2433 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 2434
wolfSSL 7:481bce714567 2435
wolfSSL 7:481bce714567 2436 /** Returns whether an ECC idx is valid or not
wolfSSL 7:481bce714567 2437 n The idx number to check
wolfSSL 7:481bce714567 2438 return 1 if valid, 0 if not
wolfSSL 7:481bce714567 2439 */
wolfSSL 7:481bce714567 2440 int wc_ecc_is_valid_idx(int n)
wolfSSL 7:481bce714567 2441 {
wolfSSL 7:481bce714567 2442 int x;
wolfSSL 7:481bce714567 2443
wolfSSL 7:481bce714567 2444 for (x = 0; ecc_sets[x].size != 0; x++)
wolfSSL 7:481bce714567 2445 ;
wolfSSL 7:481bce714567 2446 /* -1 is a valid index --- indicating that the domain params
wolfSSL 7:481bce714567 2447 were supplied by the user */
wolfSSL 7:481bce714567 2448 if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
wolfSSL 7:481bce714567 2449 return 1;
wolfSSL 7:481bce714567 2450 }
wolfSSL 7:481bce714567 2451
wolfSSL 7:481bce714567 2452 return 0;
wolfSSL 7:481bce714567 2453 }
wolfSSL 7:481bce714567 2454
wolfSSL 7:481bce714567 2455
wolfSSL 7:481bce714567 2456 /*
wolfSSL 7:481bce714567 2457 * Returns the curve name that corresponds to an ecc_curve_id identifier
wolfSSL 7:481bce714567 2458 *
wolfSSL 7:481bce714567 2459 * id curve id, from ecc_curve_id enum in ecc.h
wolfSSL 7:481bce714567 2460 * return const char* representing curve name, from ecc_sets[] on success,
wolfSSL 7:481bce714567 2461 * otherwise NULL if id not found.
wolfSSL 7:481bce714567 2462 */
wolfSSL 7:481bce714567 2463 const char* wc_ecc_get_curve_name_from_id(int id)
wolfSSL 7:481bce714567 2464 {
wolfSSL 7:481bce714567 2465 int i;
wolfSSL 7:481bce714567 2466
wolfSSL 7:481bce714567 2467 for (i = 0; ecc_sets[i].size != 0; i++) {
wolfSSL 7:481bce714567 2468 if (id == ecc_sets[i].id)
wolfSSL 7:481bce714567 2469 break;
wolfSSL 7:481bce714567 2470 }
wolfSSL 7:481bce714567 2471
wolfSSL 7:481bce714567 2472 if (ecc_sets[i].size == 0) {
wolfSSL 7:481bce714567 2473 WOLFSSL_MSG("ecc_set curve not found");
wolfSSL 7:481bce714567 2474 return NULL;
wolfSSL 7:481bce714567 2475 }
wolfSSL 7:481bce714567 2476
wolfSSL 7:481bce714567 2477 return ecc_sets[i].name;
wolfSSL 7:481bce714567 2478 }
wolfSSL 7:481bce714567 2479
wolfSSL 7:481bce714567 2480
wolfSSL 7:481bce714567 2481 /* Returns the curve size that corresponds to a given ecc_curve_id identifier
wolfSSL 7:481bce714567 2482 *
wolfSSL 7:481bce714567 2483 * id curve id, from ecc_curve_id enum in ecc.h
wolfSSL 7:481bce714567 2484 * return curve size, from ecc_sets[] on success, negative on error
wolfSSL 7:481bce714567 2485 */
wolfSSL 7:481bce714567 2486 int wc_ecc_get_curve_size_from_id(int id)
wolfSSL 7:481bce714567 2487 {
wolfSSL 7:481bce714567 2488 int i;
wolfSSL 7:481bce714567 2489
wolfSSL 7:481bce714567 2490 for (i = 0; ecc_sets[i].size != 0; i++) {
wolfSSL 7:481bce714567 2491 if (id == ecc_sets[i].id)
wolfSSL 7:481bce714567 2492 break;
wolfSSL 7:481bce714567 2493 }
wolfSSL 7:481bce714567 2494
wolfSSL 7:481bce714567 2495 if (ecc_sets[i].size == 0) {
wolfSSL 7:481bce714567 2496 WOLFSSL_MSG("ecc_set curve not found");
wolfSSL 7:481bce714567 2497 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2498 }
wolfSSL 7:481bce714567 2499
wolfSSL 7:481bce714567 2500 return ecc_sets[i].size;
wolfSSL 7:481bce714567 2501 }
wolfSSL 7:481bce714567 2502
wolfSSL 7:481bce714567 2503
wolfSSL 7:481bce714567 2504 #ifdef HAVE_ECC_DHE
wolfSSL 7:481bce714567 2505 /**
wolfSSL 7:481bce714567 2506 Create an ECC shared secret between two keys
wolfSSL 7:481bce714567 2507 private_key The private ECC key (heap hint based off of private key)
wolfSSL 7:481bce714567 2508 public_key The public key
wolfSSL 7:481bce714567 2509 out [out] Destination of the shared secret
wolfSSL 7:481bce714567 2510 Conforms to EC-DH from ANSI X9.63
wolfSSL 7:481bce714567 2511 outlen [in/out] The max size and resulting size of the shared secret
wolfSSL 7:481bce714567 2512 return MP_OKAY if successful
wolfSSL 7:481bce714567 2513 */
wolfSSL 7:481bce714567 2514 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
wolfSSL 7:481bce714567 2515 word32* outlen)
wolfSSL 7:481bce714567 2516 {
wolfSSL 7:481bce714567 2517 int err;
wolfSSL 7:481bce714567 2518
wolfSSL 7:481bce714567 2519 if (private_key == NULL || public_key == NULL || out == NULL ||
wolfSSL 7:481bce714567 2520 outlen == NULL) {
wolfSSL 7:481bce714567 2521 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2522 }
wolfSSL 7:481bce714567 2523
wolfSSL 7:481bce714567 2524 /* type valid? */
wolfSSL 7:481bce714567 2525 if (private_key->type != ECC_PRIVATEKEY) {
wolfSSL 7:481bce714567 2526 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2527 }
wolfSSL 7:481bce714567 2528
wolfSSL 7:481bce714567 2529 /* Verify domain params supplied */
wolfSSL 7:481bce714567 2530 if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
wolfSSL 7:481bce714567 2531 wc_ecc_is_valid_idx(public_key->idx) == 0) {
wolfSSL 7:481bce714567 2532 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2533 }
wolfSSL 7:481bce714567 2534
wolfSSL 7:481bce714567 2535 /* Verify curve id matches */
wolfSSL 7:481bce714567 2536 if (private_key->dp->id != public_key->dp->id) {
wolfSSL 7:481bce714567 2537 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2538 }
wolfSSL 7:481bce714567 2539
wolfSSL 7:481bce714567 2540 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 2541 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
wolfSSL 7:481bce714567 2542 #ifdef HAVE_CAVIUM
wolfSSL 7:481bce714567 2543 /* TODO: Not implemented */
wolfSSL 7:481bce714567 2544 #else
wolfSSL 7:481bce714567 2545 AsyncCryptTestDev* testDev = &private_key->asyncDev.dev;
wolfSSL 7:481bce714567 2546 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 7:481bce714567 2547 testDev->type = ASYNC_TEST_ECC_SHARED_SEC;
wolfSSL 7:481bce714567 2548 testDev->eccSharedSec.private_key = private_key;
wolfSSL 7:481bce714567 2549 testDev->eccSharedSec.public_key = public_key;
wolfSSL 7:481bce714567 2550 testDev->eccSharedSec.out = out;
wolfSSL 7:481bce714567 2551 testDev->eccSharedSec.outLen = outlen;
wolfSSL 7:481bce714567 2552 return WC_PENDING_E;
wolfSSL 7:481bce714567 2553 }
wolfSSL 7:481bce714567 2554 #endif
wolfSSL 7:481bce714567 2555 }
wolfSSL 7:481bce714567 2556 #endif
wolfSSL 7:481bce714567 2557
wolfSSL 7:481bce714567 2558 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 2559 err = atcatls_ecdh(private_key->slot, public_key->pubkey, out);
wolfSSL 7:481bce714567 2560 if (err != ATCA_SUCCESS) {
wolfSSL 7:481bce714567 2561 err = BAD_COND_E;
wolfSSL 7:481bce714567 2562 }
wolfSSL 7:481bce714567 2563 *outlen = private_key->dp->size;
wolfSSL 7:481bce714567 2564
wolfSSL 7:481bce714567 2565 #else
wolfSSL 7:481bce714567 2566 err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
wolfSSL 7:481bce714567 2567 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 2568
wolfSSL 7:481bce714567 2569 return err;
wolfSSL 7:481bce714567 2570 }
wolfSSL 7:481bce714567 2571
wolfSSL 7:481bce714567 2572
wolfSSL 7:481bce714567 2573 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 2574
wolfSSL 7:481bce714567 2575 static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
wolfSSL 7:481bce714567 2576 byte* out, word32 *outlen, ecc_curve_spec* curve)
wolfSSL 7:481bce714567 2577 {
wolfSSL 7:481bce714567 2578 int err;
wolfSSL 7:481bce714567 2579 ecc_point* result = NULL;
wolfSSL 7:481bce714567 2580 word32 x = 0;
wolfSSL 7:481bce714567 2581 mp_int* k = &private_key->k;
wolfSSL 7:481bce714567 2582 #ifdef HAVE_ECC_CDH
wolfSSL 7:481bce714567 2583 mp_int k_lcl;
wolfSSL 7:481bce714567 2584
wolfSSL 7:481bce714567 2585 /* if cofactor flag has been set */
wolfSSL 7:481bce714567 2586 if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
wolfSSL 7:481bce714567 2587 mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
wolfSSL 7:481bce714567 2588 /* only perform cofactor calc if not equal to 1 */
wolfSSL 7:481bce714567 2589 if (cofactor != 1) {
wolfSSL 7:481bce714567 2590 k = &k_lcl;
wolfSSL 7:481bce714567 2591 if (mp_init(k) != MP_OKAY)
wolfSSL 7:481bce714567 2592 return MEMORY_E;
wolfSSL 7:481bce714567 2593 /* multiply cofactor times private key "k" */
wolfSSL 7:481bce714567 2594 err = mp_mul_d(&private_key->k, cofactor, k);
wolfSSL 7:481bce714567 2595 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 2596 mp_clear(k);
wolfSSL 7:481bce714567 2597 return err;
wolfSSL 7:481bce714567 2598 }
wolfSSL 7:481bce714567 2599 }
wolfSSL 7:481bce714567 2600 }
wolfSSL 7:481bce714567 2601 #endif
wolfSSL 7:481bce714567 2602
wolfSSL 7:481bce714567 2603 /* make new point */
wolfSSL 7:481bce714567 2604 result = wc_ecc_new_point_h(private_key->heap);
wolfSSL 7:481bce714567 2605 if (result == NULL) {
wolfSSL 7:481bce714567 2606 #ifdef HAVE_ECC_CDH
wolfSSL 7:481bce714567 2607 if (k == &k_lcl)
wolfSSL 7:481bce714567 2608 mp_clear(k);
wolfSSL 7:481bce714567 2609 #endif
wolfSSL 7:481bce714567 2610 return MEMORY_E;
wolfSSL 7:481bce714567 2611 }
wolfSSL 7:481bce714567 2612
wolfSSL 7:481bce714567 2613 err = wc_ecc_mulmod_ex(k, point, result,
wolfSSL 7:481bce714567 2614 curve->Af, curve->prime, 1, private_key->heap);
wolfSSL 7:481bce714567 2615 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2616 x = mp_unsigned_bin_size(curve->prime);
wolfSSL 7:481bce714567 2617 if (*outlen < x) {
wolfSSL 7:481bce714567 2618 err = BUFFER_E;
wolfSSL 7:481bce714567 2619 }
wolfSSL 7:481bce714567 2620 }
wolfSSL 7:481bce714567 2621
wolfSSL 7:481bce714567 2622 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2623 XMEMSET(out, 0, x);
wolfSSL 7:481bce714567 2624 err = mp_to_unsigned_bin(result->x,out +
wolfSSL 7:481bce714567 2625 (x - mp_unsigned_bin_size(result->x)));
wolfSSL 7:481bce714567 2626 }
wolfSSL 7:481bce714567 2627 *outlen = x;
wolfSSL 7:481bce714567 2628
wolfSSL 7:481bce714567 2629 wc_ecc_del_point_h(result, private_key->heap);
wolfSSL 7:481bce714567 2630 #ifdef HAVE_ECC_CDH
wolfSSL 7:481bce714567 2631 if (k == &k_lcl)
wolfSSL 7:481bce714567 2632 mp_clear(k);
wolfSSL 7:481bce714567 2633 #endif
wolfSSL 7:481bce714567 2634
wolfSSL 7:481bce714567 2635 return err;
wolfSSL 7:481bce714567 2636 }
wolfSSL 7:481bce714567 2637
wolfSSL 7:481bce714567 2638
wolfSSL 7:481bce714567 2639 int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,
wolfSSL 7:481bce714567 2640 byte* out, word32 *outlen)
wolfSSL 7:481bce714567 2641 {
wolfSSL 7:481bce714567 2642 int err;
wolfSSL 7:481bce714567 2643 DECLARE_CURVE_SPECS(2)
wolfSSL 7:481bce714567 2644
wolfSSL 7:481bce714567 2645 if (private_key == NULL || point == NULL || out == NULL ||
wolfSSL 7:481bce714567 2646 outlen == NULL) {
wolfSSL 7:481bce714567 2647 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2648 }
wolfSSL 7:481bce714567 2649
wolfSSL 7:481bce714567 2650 /* load curve info */
wolfSSL 7:481bce714567 2651 err = wc_ecc_curve_load(private_key->dp, &curve,
wolfSSL 7:481bce714567 2652 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
wolfSSL 7:481bce714567 2653 if (err != MP_OKAY)
wolfSSL 7:481bce714567 2654 return err;
wolfSSL 7:481bce714567 2655
wolfSSL 7:481bce714567 2656 err = wc_ecc_shared_secret_gen_sync(private_key, point,
wolfSSL 7:481bce714567 2657 out, outlen, curve);
wolfSSL 7:481bce714567 2658
wolfSSL 7:481bce714567 2659 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 2660
wolfSSL 7:481bce714567 2661 return err;
wolfSSL 7:481bce714567 2662 }
wolfSSL 7:481bce714567 2663
wolfSSL 7:481bce714567 2664 /**
wolfSSL 7:481bce714567 2665 Create an ECC shared secret between private key and public point
wolfSSL 7:481bce714567 2666 private_key The private ECC key (heap hint based on private key)
wolfSSL 7:481bce714567 2667 point The point to use (public key)
wolfSSL 7:481bce714567 2668 out [out] Destination of the shared secret
wolfSSL 7:481bce714567 2669 Conforms to EC-DH from ANSI X9.63
wolfSSL 7:481bce714567 2670 outlen [in/out] The max size and resulting size of the shared secret
wolfSSL 7:481bce714567 2671 return MP_OKAY if successful
wolfSSL 7:481bce714567 2672 */
wolfSSL 7:481bce714567 2673 int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
wolfSSL 7:481bce714567 2674 byte* out, word32 *outlen)
wolfSSL 7:481bce714567 2675 {
wolfSSL 7:481bce714567 2676 int err;
wolfSSL 7:481bce714567 2677
wolfSSL 7:481bce714567 2678 if (private_key == NULL || point == NULL || out == NULL ||
wolfSSL 7:481bce714567 2679 outlen == NULL) {
wolfSSL 7:481bce714567 2680 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2681 }
wolfSSL 7:481bce714567 2682
wolfSSL 7:481bce714567 2683 /* type valid? */
wolfSSL 7:481bce714567 2684 if (private_key->type != ECC_PRIVATEKEY) {
wolfSSL 7:481bce714567 2685 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2686 }
wolfSSL 7:481bce714567 2687
wolfSSL 7:481bce714567 2688 /* Verify domain params supplied */
wolfSSL 7:481bce714567 2689 if (wc_ecc_is_valid_idx(private_key->idx) == 0)
wolfSSL 7:481bce714567 2690 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 2691
wolfSSL 7:481bce714567 2692 switch(private_key->state) {
wolfSSL 7:481bce714567 2693 case ECC_STATE_NONE:
wolfSSL 7:481bce714567 2694 case ECC_STATE_SHARED_SEC_GEN:
wolfSSL 7:481bce714567 2695 private_key->state = ECC_STATE_SHARED_SEC_GEN;
wolfSSL 7:481bce714567 2696
wolfSSL 7:481bce714567 2697 err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
wolfSSL 7:481bce714567 2698 if (err < 0) {
wolfSSL 7:481bce714567 2699 break;
wolfSSL 7:481bce714567 2700 }
wolfSSL 7:481bce714567 2701
wolfSSL 7:481bce714567 2702 /* fall through */
wolfSSL 7:481bce714567 2703 case ECC_STATE_SHARED_SEC_RES:
wolfSSL 7:481bce714567 2704 private_key->state = ECC_STATE_SHARED_SEC_RES;
wolfSSL 7:481bce714567 2705 err = 0;
wolfSSL 7:481bce714567 2706 break;
wolfSSL 7:481bce714567 2707
wolfSSL 7:481bce714567 2708 default:
wolfSSL 7:481bce714567 2709 err = BAD_STATE_E;
wolfSSL 7:481bce714567 2710 } /* switch */
wolfSSL 7:481bce714567 2711
wolfSSL 7:481bce714567 2712 /* if async pending then return and skip done cleanup below */
wolfSSL 7:481bce714567 2713 if (err == WC_PENDING_E) {
wolfSSL 7:481bce714567 2714 private_key->state++;
wolfSSL 7:481bce714567 2715 return err;
wolfSSL 7:481bce714567 2716 }
wolfSSL 7:481bce714567 2717
wolfSSL 7:481bce714567 2718 private_key->state = ECC_STATE_NONE;
wolfSSL 7:481bce714567 2719
wolfSSL 7:481bce714567 2720 return err;
wolfSSL 7:481bce714567 2721 }
wolfSSL 7:481bce714567 2722 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 2723 #endif /* HAVE_ECC_DHE */
wolfSSL 7:481bce714567 2724
wolfSSL 7:481bce714567 2725
wolfSSL 7:481bce714567 2726 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 2727 /* return 1 if point is at infinity, 0 if not, < 0 on error */
wolfSSL 7:481bce714567 2728 int wc_ecc_point_is_at_infinity(ecc_point* p)
wolfSSL 7:481bce714567 2729 {
wolfSSL 7:481bce714567 2730 if (p == NULL)
wolfSSL 7:481bce714567 2731 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2732
wolfSSL 7:481bce714567 2733 if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)
wolfSSL 7:481bce714567 2734 return 1;
wolfSSL 7:481bce714567 2735
wolfSSL 7:481bce714567 2736 return 0;
wolfSSL 7:481bce714567 2737 }
wolfSSL 7:481bce714567 2738
wolfSSL 7:481bce714567 2739 /* generate random and ensure its greater than 0 and less than order */
wolfSSL 7:481bce714567 2740 static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
wolfSSL 7:481bce714567 2741 {
wolfSSL 7:481bce714567 2742 int err;
wolfSSL 7:481bce714567 2743 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 2744 byte* buf;
wolfSSL 7:481bce714567 2745 #else
wolfSSL 7:481bce714567 2746 byte buf[ECC_MAXSIZE_GEN];
wolfSSL 7:481bce714567 2747 #endif
wolfSSL 7:481bce714567 2748
wolfSSL 7:481bce714567 2749 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 2750 buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 2751 if (buf == NULL)
wolfSSL 7:481bce714567 2752 return MEMORY_E;
wolfSSL 7:481bce714567 2753 #endif
wolfSSL 7:481bce714567 2754
wolfSSL 7:481bce714567 2755 /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
wolfSSL 7:481bce714567 2756 /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
wolfSSL 7:481bce714567 2757 size += 8;
wolfSSL 7:481bce714567 2758
wolfSSL 7:481bce714567 2759 /* make up random string */
wolfSSL 7:481bce714567 2760 err = wc_RNG_GenerateBlock(rng, buf, size);
wolfSSL 7:481bce714567 2761
wolfSSL 7:481bce714567 2762 /* load random buffer data into k */
wolfSSL 7:481bce714567 2763 if (err == 0)
wolfSSL 7:481bce714567 2764 err = mp_read_unsigned_bin(k, (byte*)buf, size);
wolfSSL 7:481bce714567 2765
wolfSSL 7:481bce714567 2766 /* quick sanity check to make sure we're not dealing with a 0 key */
wolfSSL 7:481bce714567 2767 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2768 if (mp_iszero(k) == MP_YES)
wolfSSL 7:481bce714567 2769 err = MP_ZERO_E;
wolfSSL 7:481bce714567 2770 }
wolfSSL 7:481bce714567 2771
wolfSSL 7:481bce714567 2772 /* the key should be smaller than the order of base point */
wolfSSL 7:481bce714567 2773 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2774 if (mp_cmp(k, order) != MP_LT) {
wolfSSL 7:481bce714567 2775 err = mp_mod(k, order, k);
wolfSSL 7:481bce714567 2776 }
wolfSSL 7:481bce714567 2777 }
wolfSSL 7:481bce714567 2778
wolfSSL 7:481bce714567 2779 #ifdef HAVE_WOLF_BIGINT
wolfSSL 7:481bce714567 2780 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2781 err = wc_mp_to_bigint(k, &k->raw);
wolfSSL 7:481bce714567 2782 #endif /* HAVE_WOLF_BIGINT */
wolfSSL 7:481bce714567 2783
wolfSSL 7:481bce714567 2784 ForceZero(buf, ECC_MAXSIZE);
wolfSSL 7:481bce714567 2785 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 2786 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 2787 #endif
wolfSSL 7:481bce714567 2788
wolfSSL 7:481bce714567 2789 return err;
wolfSSL 7:481bce714567 2790 }
wolfSSL 7:481bce714567 2791 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 2792
wolfSSL 7:481bce714567 2793 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
wolfSSL 7:481bce714567 2794 {
wolfSSL 7:481bce714567 2795 int err;
wolfSSL 7:481bce714567 2796 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 2797 ecc_point* base = NULL;
wolfSSL 7:481bce714567 2798 DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
wolfSSL 7:481bce714567 2799 #endif
wolfSSL 7:481bce714567 2800
wolfSSL 7:481bce714567 2801 if (key == NULL || rng == NULL) {
wolfSSL 7:481bce714567 2802 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 2803 }
wolfSSL 7:481bce714567 2804
wolfSSL 7:481bce714567 2805 err = wc_ecc_set_curve(key, keysize, curve_id);
wolfSSL 7:481bce714567 2806 if (err != 0) {
wolfSSL 7:481bce714567 2807 return err;
wolfSSL 7:481bce714567 2808 }
wolfSSL 7:481bce714567 2809
wolfSSL 7:481bce714567 2810 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 2811 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
wolfSSL 7:481bce714567 2812 #ifdef HAVE_CAVIUM
wolfSSL 7:481bce714567 2813 /* TODO: Not implemented */
wolfSSL 7:481bce714567 2814 #else
wolfSSL 7:481bce714567 2815 AsyncCryptTestDev* testDev = &key->asyncDev.dev;
wolfSSL 7:481bce714567 2816 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 7:481bce714567 2817 testDev->type = ASYNC_TEST_ECC_MAKE;
wolfSSL 7:481bce714567 2818 testDev->eccMake.rng = rng;
wolfSSL 7:481bce714567 2819 testDev->eccMake.key = key;
wolfSSL 7:481bce714567 2820 testDev->eccMake.size = keysize;
wolfSSL 7:481bce714567 2821 testDev->eccMake.curve_id = curve_id;
wolfSSL 7:481bce714567 2822 return WC_PENDING_E;
wolfSSL 7:481bce714567 2823 }
wolfSSL 7:481bce714567 2824 #endif
wolfSSL 7:481bce714567 2825 }
wolfSSL 7:481bce714567 2826 #endif /* WOLFSSL_ASYNC_CRYPT */
wolfSSL 7:481bce714567 2827
wolfSSL 7:481bce714567 2828 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 2829 key->type = ECC_PRIVATEKEY;
wolfSSL 7:481bce714567 2830 err = atcatls_create_key(key->slot, key->pubkey);
wolfSSL 7:481bce714567 2831 if (err != ATCA_SUCCESS) {
wolfSSL 7:481bce714567 2832 err = BAD_COND_E;
wolfSSL 7:481bce714567 2833 }
wolfSSL 7:481bce714567 2834
wolfSSL 7:481bce714567 2835 #else
wolfSSL 7:481bce714567 2836
wolfSSL 7:481bce714567 2837 /* setup the key variables */
wolfSSL 7:481bce714567 2838 err = mp_init(&key->k);
wolfSSL 7:481bce714567 2839 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2840 #ifndef ALT_ECC_SIZE
wolfSSL 7:481bce714567 2841 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
wolfSSL 7:481bce714567 2842 NULL, NULL, NULL);
wolfSSL 7:481bce714567 2843 #else
wolfSSL 7:481bce714567 2844 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
wolfSSL 7:481bce714567 2845 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
wolfSSL 7:481bce714567 2846 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
wolfSSL 7:481bce714567 2847 alt_fp_init(key->pubkey.x);
wolfSSL 7:481bce714567 2848 alt_fp_init(key->pubkey.y);
wolfSSL 7:481bce714567 2849 alt_fp_init(key->pubkey.z);
wolfSSL 7:481bce714567 2850 #endif
wolfSSL 7:481bce714567 2851 }
wolfSSL 7:481bce714567 2852
wolfSSL 7:481bce714567 2853 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 2854 base = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 2855 if (base == NULL)
wolfSSL 7:481bce714567 2856 err = MEMORY_E;
wolfSSL 7:481bce714567 2857 }
wolfSSL 7:481bce714567 2858
wolfSSL 7:481bce714567 2859 /* load curve info */
wolfSSL 7:481bce714567 2860 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2861 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
wolfSSL 7:481bce714567 2862
wolfSSL 7:481bce714567 2863 /* read in the x/y for this key */
wolfSSL 7:481bce714567 2864 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2865 err = mp_copy(curve->Gx, base->x);
wolfSSL 7:481bce714567 2866 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2867 err = mp_copy(curve->Gy, base->y);
wolfSSL 7:481bce714567 2868 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2869 err = mp_set(base->z, 1);
wolfSSL 7:481bce714567 2870
wolfSSL 7:481bce714567 2871 /* generate k */
wolfSSL 7:481bce714567 2872 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2873 err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
wolfSSL 7:481bce714567 2874
wolfSSL 7:481bce714567 2875 /* make the public key */
wolfSSL 7:481bce714567 2876 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2877 err = wc_ecc_mulmod_ex(&key->k, base, &key->pubkey,
wolfSSL 7:481bce714567 2878 curve->Af, curve->prime, 1, key->heap);
wolfSSL 7:481bce714567 2879
wolfSSL 7:481bce714567 2880 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
wolfSSL 7:481bce714567 2881 /* validate the public key, order * pubkey = point at infinity */
wolfSSL 7:481bce714567 2882 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2883 err = ecc_check_pubkey_order(key, curve->Af, curve->prime, curve->order);
wolfSSL 7:481bce714567 2884 #endif /* WOLFSSL_VALIDATE_KEYGEN */
wolfSSL 7:481bce714567 2885
wolfSSL 7:481bce714567 2886 if (err == MP_OKAY)
wolfSSL 7:481bce714567 2887 key->type = ECC_PRIVATEKEY;
wolfSSL 7:481bce714567 2888
wolfSSL 7:481bce714567 2889 /* cleanup these on failure case only */
wolfSSL 7:481bce714567 2890 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 2891 /* clean up */
wolfSSL 7:481bce714567 2892 #if !defined(USE_FAST_MATH) && !defined(ALT_ECC_SIZE)
wolfSSL 7:481bce714567 2893 mp_clear(key->pubkey.x);
wolfSSL 7:481bce714567 2894 mp_clear(key->pubkey.y);
wolfSSL 7:481bce714567 2895 mp_clear(key->pubkey.z);
wolfSSL 7:481bce714567 2896 #endif
wolfSSL 7:481bce714567 2897 mp_forcezero(&key->k);
wolfSSL 7:481bce714567 2898 }
wolfSSL 7:481bce714567 2899
wolfSSL 7:481bce714567 2900 /* cleanup allocations */
wolfSSL 7:481bce714567 2901 wc_ecc_del_point_h(base, key->heap);
wolfSSL 7:481bce714567 2902 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 2903
wolfSSL 7:481bce714567 2904 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 2905
wolfSSL 7:481bce714567 2906 return err;
wolfSSL 7:481bce714567 2907 }
wolfSSL 7:481bce714567 2908
wolfSSL 7:481bce714567 2909 #ifdef ECC_DUMP_OID
wolfSSL 7:481bce714567 2910 /* Optional dump of encoded OID for adding new curves */
wolfSSL 7:481bce714567 2911 static int mOidDumpDone;
wolfSSL 7:481bce714567 2912 static void wc_ecc_dump_oids(void)
wolfSSL 7:481bce714567 2913 {
wolfSSL 7:481bce714567 2914 int x;
wolfSSL 7:481bce714567 2915
wolfSSL 7:481bce714567 2916 if (mOidDumpDone) {
wolfSSL 7:481bce714567 2917 return;
wolfSSL 7:481bce714567 2918 }
wolfSSL 7:481bce714567 2919
wolfSSL 7:481bce714567 2920 /* find matching OID sum (based on encoded value) */
wolfSSL 7:481bce714567 2921 for (x = 0; ecc_sets[x].size != 0; x++) {
wolfSSL 7:481bce714567 2922 int i;
wolfSSL 7:481bce714567 2923 byte* oid;
wolfSSL 7:481bce714567 2924 word32 oidSz, sum = 0;
wolfSSL 7:481bce714567 2925
wolfSSL 7:481bce714567 2926 printf("ECC %s (%d):\n", ecc_sets[x].name, x);
wolfSSL 7:481bce714567 2927
wolfSSL 7:481bce714567 2928 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 2929 byte oidEnc[ECC_MAX_OID_LEN];
wolfSSL 7:481bce714567 2930
wolfSSL 7:481bce714567 2931 oid = oidEnc;
wolfSSL 7:481bce714567 2932 oidSz = ECC_MAX_OID_LEN;
wolfSSL 7:481bce714567 2933
wolfSSL 7:481bce714567 2934 printf("OID: ");
wolfSSL 7:481bce714567 2935 for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
wolfSSL 7:481bce714567 2936 printf("%d.", ecc_sets[x].oid[i]);
wolfSSL 7:481bce714567 2937 }
wolfSSL 7:481bce714567 2938 printf("\n");
wolfSSL 7:481bce714567 2939
wolfSSL 7:481bce714567 2940 EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
wolfSSL 7:481bce714567 2941 #else
wolfSSL 7:481bce714567 2942 oid = (byte*)ecc_sets[x].oid;
wolfSSL 7:481bce714567 2943 oidSz = ecc_sets[x].oidSz;
wolfSSL 7:481bce714567 2944 #endif
wolfSSL 7:481bce714567 2945
wolfSSL 7:481bce714567 2946 printf("OID Encoded: ");
wolfSSL 7:481bce714567 2947 for (i = 0; i < (int)oidSz; i++) {
wolfSSL 7:481bce714567 2948 printf("0x%02X,", oid[i]);
wolfSSL 7:481bce714567 2949 }
wolfSSL 7:481bce714567 2950 printf("\n");
wolfSSL 7:481bce714567 2951
wolfSSL 7:481bce714567 2952 for (i = 0; i < (int)oidSz; i++) {
wolfSSL 7:481bce714567 2953 sum += oid[i];
wolfSSL 7:481bce714567 2954 }
wolfSSL 7:481bce714567 2955 printf("Sum: %d\n", sum);
wolfSSL 7:481bce714567 2956
wolfSSL 7:481bce714567 2957 /* validate sum */
wolfSSL 7:481bce714567 2958 if (ecc_sets[x].oidSum != sum) {
wolfSSL 7:481bce714567 2959 printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum);
wolfSSL 7:481bce714567 2960 }
wolfSSL 7:481bce714567 2961 }
wolfSSL 7:481bce714567 2962 mOidDumpDone = 1;
wolfSSL 7:481bce714567 2963 }
wolfSSL 7:481bce714567 2964 #endif /* ECC_DUMP_OID */
wolfSSL 7:481bce714567 2965
wolfSSL 7:481bce714567 2966 /**
wolfSSL 7:481bce714567 2967 Make a new ECC key
wolfSSL 7:481bce714567 2968 rng An active RNG state
wolfSSL 7:481bce714567 2969 keysize The keysize for the new key (in octets from 20 to 65 bytes)
wolfSSL 7:481bce714567 2970 key [out] Destination of the newly created key
wolfSSL 7:481bce714567 2971 return MP_OKAY if successful,
wolfSSL 7:481bce714567 2972 upon error all allocated memory will be freed
wolfSSL 7:481bce714567 2973 */
wolfSSL 7:481bce714567 2974 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
wolfSSL 7:481bce714567 2975 {
wolfSSL 7:481bce714567 2976 return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
wolfSSL 7:481bce714567 2977 }
wolfSSL 7:481bce714567 2978
wolfSSL 7:481bce714567 2979 static INLINE void wc_ecc_free_rs(ecc_key* key, mp_int** r, mp_int** s)
wolfSSL 7:481bce714567 2980 {
wolfSSL 7:481bce714567 2981 if (*r) {
wolfSSL 7:481bce714567 2982 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 2983 mp_clear(*r);
wolfSSL 7:481bce714567 2984 #endif
wolfSSL 7:481bce714567 2985 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 2986 XFREE(*r, key->heap, DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 2987 key->r = NULL;
wolfSSL 7:481bce714567 2988 #endif
wolfSSL 7:481bce714567 2989 *r = NULL;
wolfSSL 7:481bce714567 2990 }
wolfSSL 7:481bce714567 2991 if (*s) {
wolfSSL 7:481bce714567 2992 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 2993 mp_clear(*s);
wolfSSL 7:481bce714567 2994 #endif
wolfSSL 7:481bce714567 2995 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 2996 XFREE(*s, key->heap, DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 2997 key->s = NULL;
wolfSSL 7:481bce714567 2998 #endif
wolfSSL 7:481bce714567 2999 *s = NULL;
wolfSSL 7:481bce714567 3000 }
wolfSSL 7:481bce714567 3001 (void)key;
wolfSSL 7:481bce714567 3002 }
wolfSSL 7:481bce714567 3003
wolfSSL 7:481bce714567 3004 /* Setup dynamic pointers if using normal math for proper freeing */
wolfSSL 7:481bce714567 3005 int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
wolfSSL 7:481bce714567 3006 {
wolfSSL 7:481bce714567 3007 int ret = 0;
wolfSSL 7:481bce714567 3008
wolfSSL 7:481bce714567 3009 if (key == NULL) {
wolfSSL 7:481bce714567 3010 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 3011 }
wolfSSL 7:481bce714567 3012
wolfSSL 7:481bce714567 3013 #ifdef ECC_DUMP_OID
wolfSSL 7:481bce714567 3014 wc_ecc_dump_oids();
wolfSSL 7:481bce714567 3015 #endif
wolfSSL 7:481bce714567 3016
wolfSSL 7:481bce714567 3017 XMEMSET(key, 0, sizeof(ecc_key));
wolfSSL 7:481bce714567 3018
wolfSSL 7:481bce714567 3019 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3020 key->slot = atmel_ecc_alloc();
wolfSSL 7:481bce714567 3021 if (key->slot == ATECC_INVALID_SLOT) {
wolfSSL 7:481bce714567 3022 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3023 }
wolfSSL 7:481bce714567 3024 #else
wolfSSL 7:481bce714567 3025 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 3026 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
wolfSSL 7:481bce714567 3027 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
wolfSSL 7:481bce714567 3028 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
wolfSSL 7:481bce714567 3029 alt_fp_init(key->pubkey.x);
wolfSSL 7:481bce714567 3030 alt_fp_init(key->pubkey.y);
wolfSSL 7:481bce714567 3031 alt_fp_init(key->pubkey.z);
wolfSSL 7:481bce714567 3032 ret = mp_init(&key->k);
wolfSSL 7:481bce714567 3033 #else
wolfSSL 7:481bce714567 3034 ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
wolfSSL 7:481bce714567 3035 NULL, NULL);
wolfSSL 7:481bce714567 3036 #endif /* ALT_ECC_SIZE */
wolfSSL 7:481bce714567 3037 if (ret != MP_OKAY) {
wolfSSL 7:481bce714567 3038 return MEMORY_E;
wolfSSL 7:481bce714567 3039 }
wolfSSL 7:481bce714567 3040 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 3041
wolfSSL 7:481bce714567 3042 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 3043 key->heap = (void*)WOLFSSL_HEAP_TEST;
wolfSSL 7:481bce714567 3044 #else
wolfSSL 7:481bce714567 3045 key->heap = heap;
wolfSSL 7:481bce714567 3046 #endif
wolfSSL 7:481bce714567 3047
wolfSSL 7:481bce714567 3048 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3049 if (devId != INVALID_DEVID) {
wolfSSL 7:481bce714567 3050 /* handle as async */
wolfSSL 7:481bce714567 3051 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
wolfSSL 7:481bce714567 3052 devId);
wolfSSL 7:481bce714567 3053 }
wolfSSL 7:481bce714567 3054 #else
wolfSSL 7:481bce714567 3055 (void)devId;
wolfSSL 7:481bce714567 3056 #endif
wolfSSL 7:481bce714567 3057
wolfSSL 7:481bce714567 3058 return ret;
wolfSSL 7:481bce714567 3059 }
wolfSSL 7:481bce714567 3060
wolfSSL 7:481bce714567 3061 int wc_ecc_init(ecc_key* key)
wolfSSL 7:481bce714567 3062 {
wolfSSL 7:481bce714567 3063 return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
wolfSSL 7:481bce714567 3064 }
wolfSSL 7:481bce714567 3065
wolfSSL 7:481bce714567 3066 int wc_ecc_set_flags(ecc_key* key, word32 flags)
wolfSSL 7:481bce714567 3067 {
wolfSSL 7:481bce714567 3068 if (key == NULL) {
wolfSSL 7:481bce714567 3069 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 3070 }
wolfSSL 7:481bce714567 3071 key->flags |= flags;
wolfSSL 7:481bce714567 3072 return 0;
wolfSSL 7:481bce714567 3073 }
wolfSSL 7:481bce714567 3074
wolfSSL 7:481bce714567 3075 #ifdef HAVE_ECC_SIGN
wolfSSL 7:481bce714567 3076
wolfSSL 7:481bce714567 3077 #ifndef NO_ASN
wolfSSL 7:481bce714567 3078 /**
wolfSSL 7:481bce714567 3079 Sign a message digest
wolfSSL 7:481bce714567 3080 in The message digest to sign
wolfSSL 7:481bce714567 3081 inlen The length of the digest
wolfSSL 7:481bce714567 3082 out [out] The destination for the signature
wolfSSL 7:481bce714567 3083 outlen [in/out] The max size and resulting size of the signature
wolfSSL 7:481bce714567 3084 key A private ECC key
wolfSSL 7:481bce714567 3085 return MP_OKAY if successful
wolfSSL 7:481bce714567 3086 */
wolfSSL 7:481bce714567 3087 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
wolfSSL 7:481bce714567 3088 WC_RNG* rng, ecc_key* key)
wolfSSL 7:481bce714567 3089 {
wolfSSL 7:481bce714567 3090 int err;
wolfSSL 7:481bce714567 3091 mp_int *r = NULL, *s = NULL;
wolfSSL 7:481bce714567 3092 #ifndef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3093 mp_int r_lcl, s_lcl;
wolfSSL 7:481bce714567 3094 r = &r_lcl;
wolfSSL 7:481bce714567 3095 s = &s_lcl;
wolfSSL 7:481bce714567 3096 #endif
wolfSSL 7:481bce714567 3097
wolfSSL 7:481bce714567 3098 if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
wolfSSL 7:481bce714567 3099 rng == NULL) {
wolfSSL 7:481bce714567 3100 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3101 }
wolfSSL 7:481bce714567 3102
wolfSSL 7:481bce714567 3103 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3104 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
wolfSSL 7:481bce714567 3105 #ifdef HAVE_CAVIUM
wolfSSL 7:481bce714567 3106 /* TODO: Not implemented */
wolfSSL 7:481bce714567 3107 #else
wolfSSL 7:481bce714567 3108 AsyncCryptTestDev* testDev = &key->asyncDev.dev;
wolfSSL 7:481bce714567 3109 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 7:481bce714567 3110 testDev->type = ASYNC_TEST_ECC_SIGN;
wolfSSL 7:481bce714567 3111 testDev->eccSign.in = in;
wolfSSL 7:481bce714567 3112 testDev->eccSign.inSz = inlen;
wolfSSL 7:481bce714567 3113 testDev->eccSign.out = out;
wolfSSL 7:481bce714567 3114 testDev->eccSign.outSz = outlen;
wolfSSL 7:481bce714567 3115 testDev->eccSign.rng = rng;
wolfSSL 7:481bce714567 3116 testDev->eccSign.key = key;
wolfSSL 7:481bce714567 3117 return WC_PENDING_E;
wolfSSL 7:481bce714567 3118 }
wolfSSL 7:481bce714567 3119 #endif
wolfSSL 7:481bce714567 3120 }
wolfSSL 7:481bce714567 3121 #endif
wolfSSL 7:481bce714567 3122
wolfSSL 7:481bce714567 3123 switch(key->state) {
wolfSSL 7:481bce714567 3124 case ECC_STATE_NONE:
wolfSSL 7:481bce714567 3125 case ECC_STATE_SIGN_DO:
wolfSSL 7:481bce714567 3126 key->state = ECC_STATE_SIGN_DO;
wolfSSL 7:481bce714567 3127
wolfSSL 7:481bce714567 3128 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3129 if (r == NULL)
wolfSSL 7:481bce714567 3130 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
wolfSSL 7:481bce714567 3131 DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 3132 if (s == NULL)
wolfSSL 7:481bce714567 3133 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
wolfSSL 7:481bce714567 3134 DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 3135 if (r == NULL || s == NULL) {
wolfSSL 7:481bce714567 3136 err = MEMORY_E; break;
wolfSSL 7:481bce714567 3137 }
wolfSSL 7:481bce714567 3138 key->r = r;
wolfSSL 7:481bce714567 3139 key->s = s;
wolfSSL 7:481bce714567 3140 #endif
wolfSSL 7:481bce714567 3141 XMEMSET(r, 0, sizeof(mp_int));
wolfSSL 7:481bce714567 3142 XMEMSET(s, 0, sizeof(mp_int));
wolfSSL 7:481bce714567 3143
wolfSSL 7:481bce714567 3144 if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL))
wolfSSL 7:481bce714567 3145 != MP_OKAY) {
wolfSSL 7:481bce714567 3146 break;
wolfSSL 7:481bce714567 3147 }
wolfSSL 7:481bce714567 3148
wolfSSL 7:481bce714567 3149 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3150 /* Check args */
wolfSSL 7:481bce714567 3151 if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) {
wolfSSL 7:481bce714567 3152 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3153 }
wolfSSL 7:481bce714567 3154
wolfSSL 7:481bce714567 3155 /* Sign: Result is 32-bytes of R then 32-bytes of S */
wolfSSL 7:481bce714567 3156 err = atcatls_sign(key->slot, in, out);
wolfSSL 7:481bce714567 3157 if (err != ATCA_SUCCESS) {
wolfSSL 7:481bce714567 3158 return BAD_COND_E;
wolfSSL 7:481bce714567 3159 }
wolfSSL 7:481bce714567 3160
wolfSSL 7:481bce714567 3161 /* Load R and S */
wolfSSL 7:481bce714567 3162 err = mp_read_unsigned_bin(r, &out[0], ATECC_KEY_SIZE);
wolfSSL 7:481bce714567 3163 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 3164 return err;
wolfSSL 7:481bce714567 3165 }
wolfSSL 7:481bce714567 3166 err = mp_read_unsigned_bin(s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE);
wolfSSL 7:481bce714567 3167 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 3168 return err;
wolfSSL 7:481bce714567 3169 }
wolfSSL 7:481bce714567 3170
wolfSSL 7:481bce714567 3171 /* Check for zeros */
wolfSSL 7:481bce714567 3172 if (mp_iszero(r) || mp_iszero(s)) {
wolfSSL 7:481bce714567 3173 return MP_ZERO_E;
wolfSSL 7:481bce714567 3174 }
wolfSSL 7:481bce714567 3175
wolfSSL 7:481bce714567 3176 #else
wolfSSL 7:481bce714567 3177
wolfSSL 7:481bce714567 3178 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
wolfSSL 7:481bce714567 3179 if (err < 0) {
wolfSSL 7:481bce714567 3180 break;
wolfSSL 7:481bce714567 3181 }
wolfSSL 7:481bce714567 3182
wolfSSL 7:481bce714567 3183 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 3184
wolfSSL 7:481bce714567 3185 /* fall through */
wolfSSL 7:481bce714567 3186 case ECC_STATE_SIGN_ENCODE:
wolfSSL 7:481bce714567 3187 key->state = ECC_STATE_SIGN_ENCODE;
wolfSSL 7:481bce714567 3188
wolfSSL 7:481bce714567 3189 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3190 r = key->r;
wolfSSL 7:481bce714567 3191 s = key->s;
wolfSSL 7:481bce714567 3192 #endif
wolfSSL 7:481bce714567 3193
wolfSSL 7:481bce714567 3194 /* encoded with DSA header */
wolfSSL 7:481bce714567 3195 err = StoreECC_DSA_Sig(out, outlen, r, s);
wolfSSL 7:481bce714567 3196 break;
wolfSSL 7:481bce714567 3197
wolfSSL 7:481bce714567 3198 default:
wolfSSL 7:481bce714567 3199 err = BAD_STATE_E;
wolfSSL 7:481bce714567 3200 }
wolfSSL 7:481bce714567 3201
wolfSSL 7:481bce714567 3202 /* if async pending then return and skip done cleanup below */
wolfSSL 7:481bce714567 3203 if (err == WC_PENDING_E) {
wolfSSL 7:481bce714567 3204 key->state++;
wolfSSL 7:481bce714567 3205 return err;
wolfSSL 7:481bce714567 3206 }
wolfSSL 7:481bce714567 3207
wolfSSL 7:481bce714567 3208 wc_ecc_free_rs(key, &r, &s);
wolfSSL 7:481bce714567 3209
wolfSSL 7:481bce714567 3210 key->state = ECC_STATE_NONE;
wolfSSL 7:481bce714567 3211
wolfSSL 7:481bce714567 3212 return err;
wolfSSL 7:481bce714567 3213 }
wolfSSL 7:481bce714567 3214 #endif /* !NO_ASN */
wolfSSL 7:481bce714567 3215
wolfSSL 7:481bce714567 3216 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3217 /**
wolfSSL 7:481bce714567 3218 Sign a message digest
wolfSSL 7:481bce714567 3219 in The message digest to sign
wolfSSL 7:481bce714567 3220 inlen The length of the digest
wolfSSL 7:481bce714567 3221 key A private ECC key
wolfSSL 7:481bce714567 3222 r [out] The destination for r component of the signature
wolfSSL 7:481bce714567 3223 s [out] The destination for s component of the signature
wolfSSL 7:481bce714567 3224 return MP_OKAY if successful
wolfSSL 7:481bce714567 3225 */
wolfSSL 7:481bce714567 3226 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
wolfSSL 7:481bce714567 3227 ecc_key* key, mp_int *r, mp_int *s)
wolfSSL 7:481bce714567 3228 {
wolfSSL 7:481bce714567 3229 int err;
wolfSSL 7:481bce714567 3230 mp_int e;
wolfSSL 7:481bce714567 3231 DECLARE_CURVE_SPECS(1)
wolfSSL 7:481bce714567 3232
wolfSSL 7:481bce714567 3233 if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
wolfSSL 7:481bce714567 3234 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3235
wolfSSL 7:481bce714567 3236 /* is this a private key? */
wolfSSL 7:481bce714567 3237 if (key->type != ECC_PRIVATEKEY) {
wolfSSL 7:481bce714567 3238 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3239 }
wolfSSL 7:481bce714567 3240
wolfSSL 7:481bce714567 3241 /* is the IDX valid ? */
wolfSSL 7:481bce714567 3242 if (wc_ecc_is_valid_idx(key->idx) != 1) {
wolfSSL 7:481bce714567 3243 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3244 }
wolfSSL 7:481bce714567 3245
wolfSSL 7:481bce714567 3246 /* get the hash and load it as a bignum into 'e' */
wolfSSL 7:481bce714567 3247 /* init the bignums */
wolfSSL 7:481bce714567 3248 if ((err = mp_init(&e)) != MP_OKAY) {
wolfSSL 7:481bce714567 3249 return err;
wolfSSL 7:481bce714567 3250 }
wolfSSL 7:481bce714567 3251
wolfSSL 7:481bce714567 3252 /* load curve info */
wolfSSL 7:481bce714567 3253 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
wolfSSL 7:481bce714567 3254
wolfSSL 7:481bce714567 3255 /* load digest into e */
wolfSSL 7:481bce714567 3256 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3257 /* we may need to truncate if hash is longer than key size */
wolfSSL 7:481bce714567 3258 word32 orderBits = mp_count_bits(curve->order);
wolfSSL 7:481bce714567 3259
wolfSSL 7:481bce714567 3260 /* truncate down to byte size, may be all that's needed */
wolfSSL 7:481bce714567 3261 if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
wolfSSL 7:481bce714567 3262 inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
wolfSSL 7:481bce714567 3263 err = mp_read_unsigned_bin(&e, (byte*)in, inlen);
wolfSSL 7:481bce714567 3264
wolfSSL 7:481bce714567 3265 /* may still need bit truncation too */
wolfSSL 7:481bce714567 3266 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
wolfSSL 7:481bce714567 3267 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
wolfSSL 7:481bce714567 3268 }
wolfSSL 7:481bce714567 3269
wolfSSL 7:481bce714567 3270 /* make up a key and export the public copy */
wolfSSL 7:481bce714567 3271 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3272 int loop_check = 0;
wolfSSL 7:481bce714567 3273 ecc_key pubkey;
wolfSSL 7:481bce714567 3274 if (wc_ecc_init_ex(&pubkey, key->heap, INVALID_DEVID) == MP_OKAY) {
wolfSSL 7:481bce714567 3275 for (;;) {
wolfSSL 7:481bce714567 3276 if (++loop_check > 64) {
wolfSSL 7:481bce714567 3277 err = RNG_FAILURE_E;
wolfSSL 7:481bce714567 3278 break;
wolfSSL 7:481bce714567 3279 }
wolfSSL 7:481bce714567 3280 err = wc_ecc_make_key_ex(rng, key->dp->size, &pubkey,
wolfSSL 7:481bce714567 3281 key->dp->id);
wolfSSL 7:481bce714567 3282 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3283
wolfSSL 7:481bce714567 3284 /* find r = x1 mod n */
wolfSSL 7:481bce714567 3285 err = mp_mod(pubkey.pubkey.x, curve->order, r);
wolfSSL 7:481bce714567 3286 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3287
wolfSSL 7:481bce714567 3288 if (mp_iszero(r) == MP_YES) {
wolfSSL 7:481bce714567 3289 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 3290 mp_clear(pubkey.pubkey.x);
wolfSSL 7:481bce714567 3291 mp_clear(pubkey.pubkey.y);
wolfSSL 7:481bce714567 3292 mp_clear(pubkey.pubkey.z);
wolfSSL 7:481bce714567 3293 mp_clear(&pubkey.k);
wolfSSL 7:481bce714567 3294 #endif
wolfSSL 7:481bce714567 3295 }
wolfSSL 7:481bce714567 3296 else {
wolfSSL 7:481bce714567 3297 /* find s = (e + xr)/k */
wolfSSL 7:481bce714567 3298 err = mp_invmod(&pubkey.k, curve->order, &pubkey.k);
wolfSSL 7:481bce714567 3299 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3300
wolfSSL 7:481bce714567 3301 /* s = xr */
wolfSSL 7:481bce714567 3302 err = mp_mulmod(&key->k, r, curve->order, s);
wolfSSL 7:481bce714567 3303 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3304
wolfSSL 7:481bce714567 3305 /* s = e + xr */
wolfSSL 7:481bce714567 3306 err = mp_add(&e, s, s);
wolfSSL 7:481bce714567 3307 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3308
wolfSSL 7:481bce714567 3309 /* s = e + xr */
wolfSSL 7:481bce714567 3310 err = mp_mod(s, curve->order, s);
wolfSSL 7:481bce714567 3311 if (err != MP_OKAY) break;
wolfSSL 7:481bce714567 3312
wolfSSL 7:481bce714567 3313 /* s = (e + xr)/k */
wolfSSL 7:481bce714567 3314 err = mp_mulmod(s, &pubkey.k, curve->order, s);
wolfSSL 7:481bce714567 3315
wolfSSL 7:481bce714567 3316 if (mp_iszero(s) == MP_NO)
wolfSSL 7:481bce714567 3317 break;
wolfSSL 7:481bce714567 3318 }
wolfSSL 7:481bce714567 3319 }
wolfSSL 7:481bce714567 3320 wc_ecc_free(&pubkey);
wolfSSL 7:481bce714567 3321 }
wolfSSL 7:481bce714567 3322 }
wolfSSL 7:481bce714567 3323
wolfSSL 7:481bce714567 3324 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 3325 mp_clear(&e);
wolfSSL 7:481bce714567 3326 #endif
wolfSSL 7:481bce714567 3327 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 3328
wolfSSL 7:481bce714567 3329 return err;
wolfSSL 7:481bce714567 3330 }
wolfSSL 7:481bce714567 3331 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 3332 #endif /* HAVE_ECC_SIGN */
wolfSSL 7:481bce714567 3333
wolfSSL 7:481bce714567 3334 /**
wolfSSL 7:481bce714567 3335 Free an ECC key from memory
wolfSSL 7:481bce714567 3336 key The key you wish to free
wolfSSL 7:481bce714567 3337 */
wolfSSL 7:481bce714567 3338 void wc_ecc_free(ecc_key* key)
wolfSSL 7:481bce714567 3339 {
wolfSSL 7:481bce714567 3340 if (key == NULL) {
wolfSSL 7:481bce714567 3341 return;
wolfSSL 7:481bce714567 3342 }
wolfSSL 7:481bce714567 3343
wolfSSL 7:481bce714567 3344 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3345 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
wolfSSL 7:481bce714567 3346 wolfAsync_DevCtxFree(&key->asyncDev);
wolfSSL 7:481bce714567 3347 }
wolfSSL 7:481bce714567 3348 wc_ecc_free_rs(key, &key->r, &key->s);
wolfSSL 7:481bce714567 3349 #endif
wolfSSL 7:481bce714567 3350
wolfSSL 7:481bce714567 3351 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3352 atmel_ecc_free(key->slot);
wolfSSL 7:481bce714567 3353 key->slot = -1;
wolfSSL 7:481bce714567 3354 #else
wolfSSL 7:481bce714567 3355
wolfSSL 7:481bce714567 3356 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 3357 mp_clear(key->pubkey.x);
wolfSSL 7:481bce714567 3358 mp_clear(key->pubkey.y);
wolfSSL 7:481bce714567 3359 mp_clear(key->pubkey.z);
wolfSSL 7:481bce714567 3360 #endif
wolfSSL 7:481bce714567 3361 mp_forcezero(&key->k);
wolfSSL 7:481bce714567 3362 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 3363 }
wolfSSL 7:481bce714567 3364
wolfSSL 7:481bce714567 3365 #ifdef ECC_SHAMIR
wolfSSL 7:481bce714567 3366
wolfSSL 7:481bce714567 3367 /** Computes kA*A + kB*B = C using Shamir's Trick
wolfSSL 7:481bce714567 3368 A First point to multiply
wolfSSL 7:481bce714567 3369 kA What to multiple A by
wolfSSL 7:481bce714567 3370 B Second point to multiply
wolfSSL 7:481bce714567 3371 kB What to multiple B by
wolfSSL 7:481bce714567 3372 C [out] Destination point (can overlap with A or B)
wolfSSL 7:481bce714567 3373 a ECC curve parameter a
wolfSSL 7:481bce714567 3374 modulus Modulus for curve
wolfSSL 7:481bce714567 3375 return MP_OKAY on success
wolfSSL 7:481bce714567 3376 */
wolfSSL 7:481bce714567 3377 #ifdef FP_ECC
wolfSSL 7:481bce714567 3378 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
wolfSSL 7:481bce714567 3379 ecc_point* B, mp_int* kB,
wolfSSL 7:481bce714567 3380 ecc_point* C, mp_int* a, mp_int* modulus,
wolfSSL 7:481bce714567 3381 void* heap)
wolfSSL 7:481bce714567 3382 #else
wolfSSL 7:481bce714567 3383 static int ecc_mul2add(ecc_point* A, mp_int* kA,
wolfSSL 7:481bce714567 3384 ecc_point* B, mp_int* kB,
wolfSSL 7:481bce714567 3385 ecc_point* C, mp_int* a, mp_int* modulus,
wolfSSL 7:481bce714567 3386 void* heap)
wolfSSL 7:481bce714567 3387 #endif
wolfSSL 7:481bce714567 3388 {
wolfSSL 7:481bce714567 3389 ecc_point* precomp[16];
wolfSSL 7:481bce714567 3390 unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
wolfSSL 7:481bce714567 3391 unsigned char* tA;
wolfSSL 7:481bce714567 3392 unsigned char* tB;
wolfSSL 7:481bce714567 3393 int err = MP_OKAY, first, x, y;
wolfSSL 7:481bce714567 3394 mp_digit mp;
wolfSSL 7:481bce714567 3395
wolfSSL 7:481bce714567 3396 /* argchks */
wolfSSL 7:481bce714567 3397 if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
wolfSSL 7:481bce714567 3398 modulus == NULL) {
wolfSSL 7:481bce714567 3399 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3400 }
wolfSSL 7:481bce714567 3401
wolfSSL 7:481bce714567 3402 /* allocate memory */
wolfSSL 7:481bce714567 3403 tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 3404 if (tA == NULL) {
wolfSSL 7:481bce714567 3405 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 3406 }
wolfSSL 7:481bce714567 3407 tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 3408 if (tB == NULL) {
wolfSSL 7:481bce714567 3409 XFREE(tA, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 3410 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 3411 }
wolfSSL 7:481bce714567 3412
wolfSSL 7:481bce714567 3413 /* init variables */
wolfSSL 7:481bce714567 3414 XMEMSET(tA, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 3415 XMEMSET(tB, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 3416 XMEMSET(precomp, 0, sizeof(precomp));
wolfSSL 7:481bce714567 3417
wolfSSL 7:481bce714567 3418 /* get sizes */
wolfSSL 7:481bce714567 3419 lenA = mp_unsigned_bin_size(kA);
wolfSSL 7:481bce714567 3420 lenB = mp_unsigned_bin_size(kB);
wolfSSL 7:481bce714567 3421 len = MAX(lenA, lenB);
wolfSSL 7:481bce714567 3422
wolfSSL 7:481bce714567 3423 /* sanity check */
wolfSSL 7:481bce714567 3424 if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
wolfSSL 7:481bce714567 3425 err = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 3426 }
wolfSSL 7:481bce714567 3427
wolfSSL 7:481bce714567 3428 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3429 /* extract and justify kA */
wolfSSL 7:481bce714567 3430 err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
wolfSSL 7:481bce714567 3431
wolfSSL 7:481bce714567 3432 /* extract and justify kB */
wolfSSL 7:481bce714567 3433 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3434 err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
wolfSSL 7:481bce714567 3435
wolfSSL 7:481bce714567 3436 /* allocate the table */
wolfSSL 7:481bce714567 3437 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3438 for (x = 0; x < 16; x++) {
wolfSSL 7:481bce714567 3439 precomp[x] = wc_ecc_new_point_h(heap);
wolfSSL 7:481bce714567 3440 if (precomp[x] == NULL) {
wolfSSL 7:481bce714567 3441 err = GEN_MEM_ERR;
wolfSSL 7:481bce714567 3442 break;
wolfSSL 7:481bce714567 3443 }
wolfSSL 7:481bce714567 3444 }
wolfSSL 7:481bce714567 3445 }
wolfSSL 7:481bce714567 3446 }
wolfSSL 7:481bce714567 3447
wolfSSL 7:481bce714567 3448 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3449 /* init montgomery reduction */
wolfSSL 7:481bce714567 3450 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 3451
wolfSSL 7:481bce714567 3452 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3453 mp_int mu;
wolfSSL 7:481bce714567 3454 err = mp_init(&mu);
wolfSSL 7:481bce714567 3455 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3456 err = mp_montgomery_calc_normalization(&mu, modulus);
wolfSSL 7:481bce714567 3457
wolfSSL 7:481bce714567 3458 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3459 /* copy ones ... */
wolfSSL 7:481bce714567 3460 err = mp_mulmod(A->x, &mu, modulus, precomp[1]->x);
wolfSSL 7:481bce714567 3461
wolfSSL 7:481bce714567 3462 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3463 err = mp_mulmod(A->y, &mu, modulus, precomp[1]->y);
wolfSSL 7:481bce714567 3464 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3465 err = mp_mulmod(A->z, &mu, modulus, precomp[1]->z);
wolfSSL 7:481bce714567 3466
wolfSSL 7:481bce714567 3467 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3468 err = mp_mulmod(B->x, &mu, modulus, precomp[1<<2]->x);
wolfSSL 7:481bce714567 3469 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3470 err = mp_mulmod(B->y, &mu, modulus, precomp[1<<2]->y);
wolfSSL 7:481bce714567 3471 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3472 err = mp_mulmod(B->z, &mu, modulus, precomp[1<<2]->z);
wolfSSL 7:481bce714567 3473
wolfSSL 7:481bce714567 3474 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 3475 /* done with mu */
wolfSSL 7:481bce714567 3476 mp_clear(&mu);
wolfSSL 7:481bce714567 3477 #endif
wolfSSL 7:481bce714567 3478 }
wolfSSL 7:481bce714567 3479 }
wolfSSL 7:481bce714567 3480
wolfSSL 7:481bce714567 3481 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3482 /* precomp [i,0](A + B) table */
wolfSSL 7:481bce714567 3483 err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);
wolfSSL 7:481bce714567 3484
wolfSSL 7:481bce714567 3485 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3486 err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
wolfSSL 7:481bce714567 3487 a, modulus, mp);
wolfSSL 7:481bce714567 3488 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3489 /* precomp [0,i](A + B) table */
wolfSSL 7:481bce714567 3490 err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);
wolfSSL 7:481bce714567 3491
wolfSSL 7:481bce714567 3492 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3493 err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
wolfSSL 7:481bce714567 3494 a, modulus, mp);
wolfSSL 7:481bce714567 3495
wolfSSL 7:481bce714567 3496 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3497 /* precomp [i,j](A + B) table (i != 0, j != 0) */
wolfSSL 7:481bce714567 3498 for (x = 1; x < 4; x++) {
wolfSSL 7:481bce714567 3499 for (y = 1; y < 4; y++) {
wolfSSL 7:481bce714567 3500 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3501 err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
wolfSSL 7:481bce714567 3502 precomp[x+(y<<2)], a, modulus, mp);
wolfSSL 7:481bce714567 3503 }
wolfSSL 7:481bce714567 3504 }
wolfSSL 7:481bce714567 3505 }
wolfSSL 7:481bce714567 3506
wolfSSL 7:481bce714567 3507 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3508 nibble = 3;
wolfSSL 7:481bce714567 3509 first = 1;
wolfSSL 7:481bce714567 3510 bitbufA = tA[0];
wolfSSL 7:481bce714567 3511 bitbufB = tB[0];
wolfSSL 7:481bce714567 3512
wolfSSL 7:481bce714567 3513 /* for every byte of the multiplicands */
wolfSSL 7:481bce714567 3514 for (x = 0;; ) {
wolfSSL 7:481bce714567 3515 /* grab a nibble */
wolfSSL 7:481bce714567 3516 if (++nibble == 4) {
wolfSSL 7:481bce714567 3517 if (x == (int)len) break;
wolfSSL 7:481bce714567 3518 bitbufA = tA[x];
wolfSSL 7:481bce714567 3519 bitbufB = tB[x];
wolfSSL 7:481bce714567 3520 nibble = 0;
wolfSSL 7:481bce714567 3521 x++;
wolfSSL 7:481bce714567 3522 }
wolfSSL 7:481bce714567 3523
wolfSSL 7:481bce714567 3524 /* extract two bits from both, shift/update */
wolfSSL 7:481bce714567 3525 nA = (bitbufA >> 6) & 0x03;
wolfSSL 7:481bce714567 3526 nB = (bitbufB >> 6) & 0x03;
wolfSSL 7:481bce714567 3527 bitbufA = (bitbufA << 2) & 0xFF;
wolfSSL 7:481bce714567 3528 bitbufB = (bitbufB << 2) & 0xFF;
wolfSSL 7:481bce714567 3529
wolfSSL 7:481bce714567 3530 /* if both zero, if first, continue */
wolfSSL 7:481bce714567 3531 if ((nA == 0) && (nB == 0) && (first == 1)) {
wolfSSL 7:481bce714567 3532 continue;
wolfSSL 7:481bce714567 3533 }
wolfSSL 7:481bce714567 3534
wolfSSL 7:481bce714567 3535 /* double twice, only if this isn't the first */
wolfSSL 7:481bce714567 3536 if (first == 0) {
wolfSSL 7:481bce714567 3537 /* double twice */
wolfSSL 7:481bce714567 3538 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3539 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
wolfSSL 7:481bce714567 3540 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3541 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
wolfSSL 7:481bce714567 3542 else
wolfSSL 7:481bce714567 3543 break;
wolfSSL 7:481bce714567 3544 }
wolfSSL 7:481bce714567 3545
wolfSSL 7:481bce714567 3546 /* if not both zero */
wolfSSL 7:481bce714567 3547 if ((nA != 0) || (nB != 0)) {
wolfSSL 7:481bce714567 3548 if (first == 1) {
wolfSSL 7:481bce714567 3549 /* if first, copy from table */
wolfSSL 7:481bce714567 3550 first = 0;
wolfSSL 7:481bce714567 3551 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3552 err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
wolfSSL 7:481bce714567 3553
wolfSSL 7:481bce714567 3554 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3555 err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
wolfSSL 7:481bce714567 3556
wolfSSL 7:481bce714567 3557 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3558 err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
wolfSSL 7:481bce714567 3559 else
wolfSSL 7:481bce714567 3560 break;
wolfSSL 7:481bce714567 3561 } else {
wolfSSL 7:481bce714567 3562 /* if not first, add from table */
wolfSSL 7:481bce714567 3563 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3564 err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
wolfSSL 7:481bce714567 3565 a, modulus, mp);
wolfSSL 7:481bce714567 3566 else
wolfSSL 7:481bce714567 3567 break;
wolfSSL 7:481bce714567 3568 }
wolfSSL 7:481bce714567 3569 }
wolfSSL 7:481bce714567 3570 }
wolfSSL 7:481bce714567 3571 }
wolfSSL 7:481bce714567 3572
wolfSSL 7:481bce714567 3573 /* reduce to affine */
wolfSSL 7:481bce714567 3574 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3575 err = ecc_map(C, modulus, mp);
wolfSSL 7:481bce714567 3576
wolfSSL 7:481bce714567 3577 /* clean up */
wolfSSL 7:481bce714567 3578 for (x = 0; x < 16; x++) {
wolfSSL 7:481bce714567 3579 wc_ecc_del_point_h(precomp[x], heap);
wolfSSL 7:481bce714567 3580 }
wolfSSL 7:481bce714567 3581
wolfSSL 7:481bce714567 3582 ForceZero(tA, ECC_BUFSIZE);
wolfSSL 7:481bce714567 3583 ForceZero(tB, ECC_BUFSIZE);
wolfSSL 7:481bce714567 3584 XFREE(tA, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 3585 XFREE(tB, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 3586
wolfSSL 7:481bce714567 3587 return err;
wolfSSL 7:481bce714567 3588 }
wolfSSL 7:481bce714567 3589
wolfSSL 7:481bce714567 3590 #endif /* ECC_SHAMIR */
wolfSSL 7:481bce714567 3591
wolfSSL 7:481bce714567 3592
wolfSSL 7:481bce714567 3593 #ifdef HAVE_ECC_VERIFY
wolfSSL 7:481bce714567 3594 #ifndef NO_ASN
wolfSSL 7:481bce714567 3595 /* verify
wolfSSL 7:481bce714567 3596 *
wolfSSL 7:481bce714567 3597 * w = s^-1 mod n
wolfSSL 7:481bce714567 3598 * u1 = xw
wolfSSL 7:481bce714567 3599 * u2 = rw
wolfSSL 7:481bce714567 3600 * X = u1*G + u2*Q
wolfSSL 7:481bce714567 3601 * v = X_x1 mod n
wolfSSL 7:481bce714567 3602 * accept if v == r
wolfSSL 7:481bce714567 3603 */
wolfSSL 7:481bce714567 3604
wolfSSL 7:481bce714567 3605 /**
wolfSSL 7:481bce714567 3606 Verify an ECC signature
wolfSSL 7:481bce714567 3607 sig The signature to verify
wolfSSL 7:481bce714567 3608 siglen The length of the signature (octets)
wolfSSL 7:481bce714567 3609 hash The hash (message digest) that was signed
wolfSSL 7:481bce714567 3610 hashlen The length of the hash (octets)
wolfSSL 7:481bce714567 3611 stat Result of signature, 1==valid, 0==invalid
wolfSSL 7:481bce714567 3612 key The corresponding public ECC key
wolfSSL 7:481bce714567 3613 return MP_OKAY if successful (even if the signature is not valid)
wolfSSL 7:481bce714567 3614 */
wolfSSL 7:481bce714567 3615 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
wolfSSL 7:481bce714567 3616 word32 hashlen, int* stat, ecc_key* key)
wolfSSL 7:481bce714567 3617 {
wolfSSL 7:481bce714567 3618 int err;
wolfSSL 7:481bce714567 3619 mp_int *r = NULL, *s = NULL;
wolfSSL 7:481bce714567 3620 #ifndef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3621 mp_int r_lcl, s_lcl;
wolfSSL 7:481bce714567 3622 r = &r_lcl;
wolfSSL 7:481bce714567 3623 s = &s_lcl;
wolfSSL 7:481bce714567 3624 #endif
wolfSSL 7:481bce714567 3625
wolfSSL 7:481bce714567 3626 if (sig == NULL || hash == NULL || stat == NULL || key == NULL) {
wolfSSL 7:481bce714567 3627 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3628 }
wolfSSL 7:481bce714567 3629
wolfSSL 7:481bce714567 3630 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3631 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
wolfSSL 7:481bce714567 3632 #ifdef HAVE_CAVIUM
wolfSSL 7:481bce714567 3633 /* TODO: Not implemented */
wolfSSL 7:481bce714567 3634 #else
wolfSSL 7:481bce714567 3635 AsyncCryptTestDev* testDev = &key->asyncDev.dev;
wolfSSL 7:481bce714567 3636 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 7:481bce714567 3637 testDev->type = ASYNC_TEST_ECC_VERIFY;
wolfSSL 7:481bce714567 3638 testDev->eccVerify.in = sig;
wolfSSL 7:481bce714567 3639 testDev->eccVerify.inSz = siglen;
wolfSSL 7:481bce714567 3640 testDev->eccVerify.out = hash;
wolfSSL 7:481bce714567 3641 testDev->eccVerify.outSz = hashlen;
wolfSSL 7:481bce714567 3642 testDev->eccVerify.stat = stat;
wolfSSL 7:481bce714567 3643 testDev->eccVerify.key = key;
wolfSSL 7:481bce714567 3644 return WC_PENDING_E;
wolfSSL 7:481bce714567 3645 }
wolfSSL 7:481bce714567 3646 #endif
wolfSSL 7:481bce714567 3647 }
wolfSSL 7:481bce714567 3648 #endif
wolfSSL 7:481bce714567 3649
wolfSSL 7:481bce714567 3650 switch(key->state) {
wolfSSL 7:481bce714567 3651 case ECC_STATE_NONE:
wolfSSL 7:481bce714567 3652 case ECC_STATE_VERIFY_DECODE:
wolfSSL 7:481bce714567 3653 key->state = ECC_STATE_VERIFY_DECODE;
wolfSSL 7:481bce714567 3654
wolfSSL 7:481bce714567 3655 /* default to invalid signature */
wolfSSL 7:481bce714567 3656 *stat = 0;
wolfSSL 7:481bce714567 3657
wolfSSL 7:481bce714567 3658 /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
wolfSSL 7:481bce714567 3659 * If either of those don't allocate correctly, none of
wolfSSL 7:481bce714567 3660 * the rest of this function will execute, and everything
wolfSSL 7:481bce714567 3661 * gets cleaned up at the end. */
wolfSSL 7:481bce714567 3662 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3663 if (r == NULL)
wolfSSL 7:481bce714567 3664 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
wolfSSL 7:481bce714567 3665 DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 3666 if (s == NULL)
wolfSSL 7:481bce714567 3667 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
wolfSSL 7:481bce714567 3668 DYNAMIC_TYPE_BIGINT);
wolfSSL 7:481bce714567 3669 if (r == NULL || s == NULL) {
wolfSSL 7:481bce714567 3670 err = MEMORY_E; break;
wolfSSL 7:481bce714567 3671 }
wolfSSL 7:481bce714567 3672 key->r = r;
wolfSSL 7:481bce714567 3673 key->s = s;
wolfSSL 7:481bce714567 3674 #endif
wolfSSL 7:481bce714567 3675 XMEMSET(r, 0, sizeof(mp_int));
wolfSSL 7:481bce714567 3676 XMEMSET(s, 0, sizeof(mp_int));
wolfSSL 7:481bce714567 3677
wolfSSL 7:481bce714567 3678 /* decode DSA header */
wolfSSL 7:481bce714567 3679 err = DecodeECC_DSA_Sig(sig, siglen, r, s);
wolfSSL 7:481bce714567 3680 if (err < 0) {
wolfSSL 7:481bce714567 3681 break;
wolfSSL 7:481bce714567 3682 }
wolfSSL 7:481bce714567 3683
wolfSSL 7:481bce714567 3684 /* fall through */
wolfSSL 7:481bce714567 3685 case ECC_STATE_VERIFY_DO:
wolfSSL 7:481bce714567 3686 key->state = ECC_STATE_VERIFY_DO;
wolfSSL 7:481bce714567 3687
wolfSSL 7:481bce714567 3688 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 3689 r = key->r;
wolfSSL 7:481bce714567 3690 s = key->s;
wolfSSL 7:481bce714567 3691 #endif
wolfSSL 7:481bce714567 3692
wolfSSL 7:481bce714567 3693 err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, stat,
wolfSSL 7:481bce714567 3694 key);
wolfSSL 7:481bce714567 3695 if (err < 0) {
wolfSSL 7:481bce714567 3696 break;
wolfSSL 7:481bce714567 3697 }
wolfSSL 7:481bce714567 3698
wolfSSL 7:481bce714567 3699 /* fall through */
wolfSSL 7:481bce714567 3700 case ECC_STATE_VERIFY_RES:
wolfSSL 7:481bce714567 3701 key->state = ECC_STATE_VERIFY_RES;
wolfSSL 7:481bce714567 3702 err = 0;
wolfSSL 7:481bce714567 3703 break;
wolfSSL 7:481bce714567 3704
wolfSSL 7:481bce714567 3705 default:
wolfSSL 7:481bce714567 3706 err = BAD_STATE_E;
wolfSSL 7:481bce714567 3707 }
wolfSSL 7:481bce714567 3708
wolfSSL 7:481bce714567 3709 /* if async pending then return and skip done cleanup below */
wolfSSL 7:481bce714567 3710 if (err == WC_PENDING_E) {
wolfSSL 7:481bce714567 3711 key->state++;
wolfSSL 7:481bce714567 3712 return err;
wolfSSL 7:481bce714567 3713 }
wolfSSL 7:481bce714567 3714
wolfSSL 7:481bce714567 3715 wc_ecc_free_rs(key, &r, &s);
wolfSSL 7:481bce714567 3716
wolfSSL 7:481bce714567 3717 key->state = ECC_STATE_NONE;
wolfSSL 7:481bce714567 3718
wolfSSL 7:481bce714567 3719 return err;
wolfSSL 7:481bce714567 3720 }
wolfSSL 7:481bce714567 3721 #endif /* !NO_ASN */
wolfSSL 7:481bce714567 3722
wolfSSL 7:481bce714567 3723
wolfSSL 7:481bce714567 3724 /**
wolfSSL 7:481bce714567 3725 Verify an ECC signature
wolfSSL 7:481bce714567 3726 r The signature R component to verify
wolfSSL 7:481bce714567 3727 s The signature S component to verify
wolfSSL 7:481bce714567 3728 hash The hash (message digest) that was signed
wolfSSL 7:481bce714567 3729 hashlen The length of the hash (octets)
wolfSSL 7:481bce714567 3730 stat Result of signature, 1==valid, 0==invalid
wolfSSL 7:481bce714567 3731 key The corresponding public ECC key
wolfSSL 7:481bce714567 3732 return MP_OKAY if successful (even if the signature is not valid)
wolfSSL 7:481bce714567 3733 */
wolfSSL 7:481bce714567 3734 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
wolfSSL 7:481bce714567 3735 word32 hashlen, int* stat, ecc_key* key)
wolfSSL 7:481bce714567 3736 {
wolfSSL 7:481bce714567 3737 int err;
wolfSSL 7:481bce714567 3738 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3739 ecc_point *mG = NULL, *mQ = NULL;
wolfSSL 7:481bce714567 3740 mp_int v;
wolfSSL 7:481bce714567 3741 mp_int w;
wolfSSL 7:481bce714567 3742 mp_int u1;
wolfSSL 7:481bce714567 3743 mp_int u2;
wolfSSL 7:481bce714567 3744 mp_int e;
wolfSSL 7:481bce714567 3745 DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT)
wolfSSL 7:481bce714567 3746 #else
wolfSSL 7:481bce714567 3747 byte sigRS[ATECC_KEY_SIZE*2];
wolfSSL 7:481bce714567 3748 #endif
wolfSSL 7:481bce714567 3749
wolfSSL 7:481bce714567 3750 if (r == NULL || s == NULL || hash == NULL || stat == NULL || key == NULL)
wolfSSL 7:481bce714567 3751 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3752
wolfSSL 7:481bce714567 3753 /* default to invalid signature */
wolfSSL 7:481bce714567 3754 *stat = 0;
wolfSSL 7:481bce714567 3755
wolfSSL 7:481bce714567 3756 /* is the IDX valid ? */
wolfSSL 7:481bce714567 3757 if (wc_ecc_is_valid_idx(key->idx) != 1) {
wolfSSL 7:481bce714567 3758 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3759 }
wolfSSL 7:481bce714567 3760
wolfSSL 7:481bce714567 3761 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3762 /* Extract R and S */
wolfSSL 7:481bce714567 3763 err = mp_to_unsigned_bin(r, &sigRS[0]);
wolfSSL 7:481bce714567 3764 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 3765 return err;
wolfSSL 7:481bce714567 3766 }
wolfSSL 7:481bce714567 3767 err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]);
wolfSSL 7:481bce714567 3768 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 3769 return err;
wolfSSL 7:481bce714567 3770 }
wolfSSL 7:481bce714567 3771
wolfSSL 7:481bce714567 3772 err = atcatls_verify(hash, sigRS, key->pubkey, (bool*)stat);
wolfSSL 7:481bce714567 3773 if (err != ATCA_SUCCESS) {
wolfSSL 7:481bce714567 3774 return BAD_COND_E;
wolfSSL 7:481bce714567 3775 }
wolfSSL 7:481bce714567 3776
wolfSSL 7:481bce714567 3777 #else
wolfSSL 7:481bce714567 3778
wolfSSL 7:481bce714567 3779 err = mp_init(&e);
wolfSSL 7:481bce714567 3780 if (err != MP_OKAY)
wolfSSL 7:481bce714567 3781 return MEMORY_E;
wolfSSL 7:481bce714567 3782
wolfSSL 7:481bce714567 3783 /* read in the specs for this curve */
wolfSSL 7:481bce714567 3784 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
wolfSSL 7:481bce714567 3785
wolfSSL 7:481bce714567 3786 /* check for zero */
wolfSSL 7:481bce714567 3787 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3788 if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
wolfSSL 7:481bce714567 3789 mp_cmp(r, curve->order) != MP_LT ||
wolfSSL 7:481bce714567 3790 mp_cmp(s, curve->order) != MP_LT) {
wolfSSL 7:481bce714567 3791 err = MP_ZERO_E;
wolfSSL 7:481bce714567 3792 }
wolfSSL 7:481bce714567 3793 }
wolfSSL 7:481bce714567 3794
wolfSSL 7:481bce714567 3795 /* read hash */
wolfSSL 7:481bce714567 3796 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3797 /* we may need to truncate if hash is longer than key size */
wolfSSL 7:481bce714567 3798 unsigned int orderBits = mp_count_bits(curve->order);
wolfSSL 7:481bce714567 3799
wolfSSL 7:481bce714567 3800 /* truncate down to byte size, may be all that's needed */
wolfSSL 7:481bce714567 3801 if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
wolfSSL 7:481bce714567 3802 hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
wolfSSL 7:481bce714567 3803 err = mp_read_unsigned_bin(&e, hash, hashlen);
wolfSSL 7:481bce714567 3804
wolfSSL 7:481bce714567 3805 /* may still need bit truncation too */
wolfSSL 7:481bce714567 3806 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
wolfSSL 7:481bce714567 3807 mp_rshb(&e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
wolfSSL 7:481bce714567 3808 }
wolfSSL 7:481bce714567 3809
wolfSSL 7:481bce714567 3810 /* allocate ints */
wolfSSL 7:481bce714567 3811 if ((err = mp_init_multi(&v, &w, &u1, &u2, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 3812 err = MEMORY_E;
wolfSSL 7:481bce714567 3813 }
wolfSSL 7:481bce714567 3814
wolfSSL 7:481bce714567 3815 /* allocate points */
wolfSSL 7:481bce714567 3816 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3817 mG = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 3818 mQ = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 3819 if (mQ == NULL || mG == NULL)
wolfSSL 7:481bce714567 3820 err = MEMORY_E;
wolfSSL 7:481bce714567 3821 }
wolfSSL 7:481bce714567 3822
wolfSSL 7:481bce714567 3823 /* w = s^-1 mod n */
wolfSSL 7:481bce714567 3824 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3825 err = mp_invmod(s, curve->order, &w);
wolfSSL 7:481bce714567 3826
wolfSSL 7:481bce714567 3827 /* u1 = ew */
wolfSSL 7:481bce714567 3828 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3829 err = mp_mulmod(&e, &w, curve->order, &u1);
wolfSSL 7:481bce714567 3830
wolfSSL 7:481bce714567 3831 /* u2 = rw */
wolfSSL 7:481bce714567 3832 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3833 err = mp_mulmod(r, &w, curve->order, &u2);
wolfSSL 7:481bce714567 3834
wolfSSL 7:481bce714567 3835 /* find mG and mQ */
wolfSSL 7:481bce714567 3836 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3837 err = mp_copy(curve->Gx, mG->x);
wolfSSL 7:481bce714567 3838 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3839 err = mp_copy(curve->Gy, mG->y);
wolfSSL 7:481bce714567 3840 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3841 err = mp_set(mG->z, 1);
wolfSSL 7:481bce714567 3842
wolfSSL 7:481bce714567 3843 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3844 err = mp_copy(key->pubkey.x, mQ->x);
wolfSSL 7:481bce714567 3845 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3846 err = mp_copy(key->pubkey.y, mQ->y);
wolfSSL 7:481bce714567 3847 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3848 err = mp_copy(key->pubkey.z, mQ->z);
wolfSSL 7:481bce714567 3849
wolfSSL 7:481bce714567 3850 #ifdef FREESCALE_LTC_ECC
wolfSSL 7:481bce714567 3851 /* use PKHA to compute u1*mG + u2*mQ */
wolfSSL 7:481bce714567 3852 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3853 err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
wolfSSL 7:481bce714567 3854 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3855 err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
wolfSSL 7:481bce714567 3856 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3857 err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
wolfSSL 7:481bce714567 3858 #else /* FREESCALE_LTC_ECC */
wolfSSL 7:481bce714567 3859 #ifndef ECC_SHAMIR
wolfSSL 7:481bce714567 3860 {
wolfSSL 7:481bce714567 3861 mp_digit mp;
wolfSSL 7:481bce714567 3862
wolfSSL 7:481bce714567 3863 /* compute u1*mG + u2*mQ = mG */
wolfSSL 7:481bce714567 3864 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3865 err = wc_ecc_mulmod_ex(&u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
wolfSSL 7:481bce714567 3866 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3867 err = wc_ecc_mulmod_ex(&u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
wolfSSL 7:481bce714567 3868
wolfSSL 7:481bce714567 3869 /* find the montgomery mp */
wolfSSL 7:481bce714567 3870 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3871 err = mp_montgomery_setup(curve->prime, &mp);
wolfSSL 7:481bce714567 3872
wolfSSL 7:481bce714567 3873 /* add them */
wolfSSL 7:481bce714567 3874 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3875 err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
wolfSSL 7:481bce714567 3876 curve->prime, mp);
wolfSSL 7:481bce714567 3877
wolfSSL 7:481bce714567 3878 /* reduce */
wolfSSL 7:481bce714567 3879 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3880 err = ecc_map(mG, curve->prime, mp);
wolfSSL 7:481bce714567 3881 }
wolfSSL 7:481bce714567 3882 #else
wolfSSL 7:481bce714567 3883 /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
wolfSSL 7:481bce714567 3884 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3885 err = ecc_mul2add(mG, &u1, mQ, &u2, mG, curve->Af, curve->prime,
wolfSSL 7:481bce714567 3886 key->heap);
wolfSSL 7:481bce714567 3887 #endif /* ECC_SHAMIR */
wolfSSL 7:481bce714567 3888 #endif /* FREESCALE_LTC_ECC */
wolfSSL 7:481bce714567 3889 /* v = X_x1 mod n */
wolfSSL 7:481bce714567 3890 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3891 err = mp_mod(mG->x, curve->order, &v);
wolfSSL 7:481bce714567 3892
wolfSSL 7:481bce714567 3893 /* does v == r */
wolfSSL 7:481bce714567 3894 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 3895 if (mp_cmp(&v, r) == MP_EQ)
wolfSSL 7:481bce714567 3896 *stat = 1;
wolfSSL 7:481bce714567 3897 }
wolfSSL 7:481bce714567 3898
wolfSSL 7:481bce714567 3899 /* cleanup */
wolfSSL 7:481bce714567 3900 wc_ecc_del_point_h(mG, key->heap);
wolfSSL 7:481bce714567 3901 wc_ecc_del_point_h(mQ, key->heap);
wolfSSL 7:481bce714567 3902
wolfSSL 7:481bce714567 3903 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 3904 mp_clear(&e);
wolfSSL 7:481bce714567 3905 mp_clear(&v);
wolfSSL 7:481bce714567 3906 mp_clear(&w);
wolfSSL 7:481bce714567 3907 mp_clear(&u1);
wolfSSL 7:481bce714567 3908 mp_clear(&u2);
wolfSSL 7:481bce714567 3909 #endif
wolfSSL 7:481bce714567 3910
wolfSSL 7:481bce714567 3911 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 3912
wolfSSL 7:481bce714567 3913 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 3914
wolfSSL 7:481bce714567 3915 return err;
wolfSSL 7:481bce714567 3916 }
wolfSSL 7:481bce714567 3917 #endif /* HAVE_ECC_VERIFY */
wolfSSL 7:481bce714567 3918
wolfSSL 7:481bce714567 3919 #ifdef HAVE_ECC_KEY_IMPORT
wolfSSL 7:481bce714567 3920 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 3921 /* import point from der */
wolfSSL 7:481bce714567 3922 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
wolfSSL 7:481bce714567 3923 ecc_point* point)
wolfSSL 7:481bce714567 3924 {
wolfSSL 7:481bce714567 3925 int err = 0;
wolfSSL 7:481bce714567 3926 int compressed = 0;
wolfSSL 7:481bce714567 3927
wolfSSL 7:481bce714567 3928 if (in == NULL || point == NULL || (curve_idx < 0) ||
wolfSSL 7:481bce714567 3929 (wc_ecc_is_valid_idx(curve_idx) == 0))
wolfSSL 7:481bce714567 3930 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3931
wolfSSL 7:481bce714567 3932 /* must be odd */
wolfSSL 7:481bce714567 3933 if ((inLen & 1) == 0) {
wolfSSL 7:481bce714567 3934 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 3935 }
wolfSSL 7:481bce714567 3936
wolfSSL 7:481bce714567 3937 /* init point */
wolfSSL 7:481bce714567 3938 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 3939 point->x = (mp_int*)&point->xyz[0];
wolfSSL 7:481bce714567 3940 point->y = (mp_int*)&point->xyz[1];
wolfSSL 7:481bce714567 3941 point->z = (mp_int*)&point->xyz[2];
wolfSSL 7:481bce714567 3942 alt_fp_init(point->x);
wolfSSL 7:481bce714567 3943 alt_fp_init(point->y);
wolfSSL 7:481bce714567 3944 alt_fp_init(point->z);
wolfSSL 7:481bce714567 3945 #else
wolfSSL 7:481bce714567 3946 err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
wolfSSL 7:481bce714567 3947 #endif
wolfSSL 7:481bce714567 3948 if (err != MP_OKAY)
wolfSSL 7:481bce714567 3949 return MEMORY_E;
wolfSSL 7:481bce714567 3950
wolfSSL 7:481bce714567 3951 /* check for 4, 2, or 3 */
wolfSSL 7:481bce714567 3952 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
wolfSSL 7:481bce714567 3953 err = ASN_PARSE_E;
wolfSSL 7:481bce714567 3954 }
wolfSSL 7:481bce714567 3955
wolfSSL 7:481bce714567 3956 if (in[0] == 0x02 || in[0] == 0x03) {
wolfSSL 7:481bce714567 3957 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 3958 compressed = 1;
wolfSSL 7:481bce714567 3959 #else
wolfSSL 7:481bce714567 3960 err = NOT_COMPILED_IN;
wolfSSL 7:481bce714567 3961 #endif
wolfSSL 7:481bce714567 3962 }
wolfSSL 7:481bce714567 3963
wolfSSL 7:481bce714567 3964 /* read data */
wolfSSL 7:481bce714567 3965 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3966 err = mp_read_unsigned_bin(point->x, (byte*)in+1, (inLen-1)>>1);
wolfSSL 7:481bce714567 3967
wolfSSL 7:481bce714567 3968 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 3969 if (err == MP_OKAY && compressed == 1) { /* build y */
wolfSSL 7:481bce714567 3970 mp_int t1, t2;
wolfSSL 7:481bce714567 3971 int did_init = 0;
wolfSSL 7:481bce714567 3972
wolfSSL 7:481bce714567 3973 DECLARE_CURVE_SPECS(3)
wolfSSL 7:481bce714567 3974
wolfSSL 7:481bce714567 3975 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 7:481bce714567 3976 err = MEMORY_E;
wolfSSL 7:481bce714567 3977 else
wolfSSL 7:481bce714567 3978 did_init = 1;
wolfSSL 7:481bce714567 3979
wolfSSL 7:481bce714567 3980 /* load curve info */
wolfSSL 7:481bce714567 3981 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3982 err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
wolfSSL 7:481bce714567 3983 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_BF));
wolfSSL 7:481bce714567 3984
wolfSSL 7:481bce714567 3985 /* compute x^3 */
wolfSSL 7:481bce714567 3986 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3987 err = mp_sqr(point->x, &t1);
wolfSSL 7:481bce714567 3988 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3989 err = mp_mulmod(&t1, point->x, curve->prime, &t1);
wolfSSL 7:481bce714567 3990
wolfSSL 7:481bce714567 3991 /* compute x^3 + a*x */
wolfSSL 7:481bce714567 3992 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3993 err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
wolfSSL 7:481bce714567 3994 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3995 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 3996
wolfSSL 7:481bce714567 3997 /* compute x^3 + a*x + b */
wolfSSL 7:481bce714567 3998 if (err == MP_OKAY)
wolfSSL 7:481bce714567 3999 err = mp_add(&t1, curve->Bf, &t1);
wolfSSL 7:481bce714567 4000
wolfSSL 7:481bce714567 4001 /* compute sqrt(x^3 + a*x + b) */
wolfSSL 7:481bce714567 4002 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4003 err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
wolfSSL 7:481bce714567 4004
wolfSSL 7:481bce714567 4005 /* adjust y */
wolfSSL 7:481bce714567 4006 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4007 if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
wolfSSL 7:481bce714567 4008 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
wolfSSL 7:481bce714567 4009 err = mp_mod(&t2, curve->prime, point->y);
wolfSSL 7:481bce714567 4010 }
wolfSSL 7:481bce714567 4011 else {
wolfSSL 7:481bce714567 4012 err = mp_submod(curve->prime, &t2, curve->prime, point->y);
wolfSSL 7:481bce714567 4013 }
wolfSSL 7:481bce714567 4014 }
wolfSSL 7:481bce714567 4015
wolfSSL 7:481bce714567 4016 if (did_init) {
wolfSSL 7:481bce714567 4017 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 4018 mp_clear(&t2);
wolfSSL 7:481bce714567 4019 mp_clear(&t1);
wolfSSL 7:481bce714567 4020 #endif
wolfSSL 7:481bce714567 4021 }
wolfSSL 7:481bce714567 4022
wolfSSL 7:481bce714567 4023 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 4024 }
wolfSSL 7:481bce714567 4025 #endif
wolfSSL 7:481bce714567 4026
wolfSSL 7:481bce714567 4027 if (err == MP_OKAY && compressed == 0)
wolfSSL 7:481bce714567 4028 err = mp_read_unsigned_bin(point->y,
wolfSSL 7:481bce714567 4029 (byte*)in+1+((inLen-1)>>1), (inLen-1)>>1);
wolfSSL 7:481bce714567 4030 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4031 err = mp_set(point->z, 1);
wolfSSL 7:481bce714567 4032
wolfSSL 7:481bce714567 4033 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 4034 mp_clear(point->x);
wolfSSL 7:481bce714567 4035 mp_clear(point->y);
wolfSSL 7:481bce714567 4036 mp_clear(point->z);
wolfSSL 7:481bce714567 4037 }
wolfSSL 7:481bce714567 4038
wolfSSL 7:481bce714567 4039 return err;
wolfSSL 7:481bce714567 4040 }
wolfSSL 7:481bce714567 4041 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4042 #endif /* HAVE_ECC_KEY_IMPORT */
wolfSSL 7:481bce714567 4043
wolfSSL 7:481bce714567 4044 #ifdef HAVE_ECC_KEY_EXPORT
wolfSSL 7:481bce714567 4045 /* export point to der */
wolfSSL 7:481bce714567 4046 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
wolfSSL 7:481bce714567 4047 word32* outLen)
wolfSSL 7:481bce714567 4048 {
wolfSSL 7:481bce714567 4049 int ret = MP_OKAY;
wolfSSL 7:481bce714567 4050 word32 numlen;
wolfSSL 7:481bce714567 4051 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4052 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4053 byte* buf;
wolfSSL 7:481bce714567 4054 #else
wolfSSL 7:481bce714567 4055 byte buf[ECC_BUFSIZE];
wolfSSL 7:481bce714567 4056 #endif
wolfSSL 7:481bce714567 4057 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4058
wolfSSL 7:481bce714567 4059 if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
wolfSSL 7:481bce714567 4060 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4061
wolfSSL 7:481bce714567 4062 /* return length needed only */
wolfSSL 7:481bce714567 4063 if (point != NULL && out == NULL && outLen != NULL) {
wolfSSL 7:481bce714567 4064 numlen = ecc_sets[curve_idx].size;
wolfSSL 7:481bce714567 4065 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4066 return LENGTH_ONLY_E;
wolfSSL 7:481bce714567 4067 }
wolfSSL 7:481bce714567 4068
wolfSSL 7:481bce714567 4069 if (point == NULL || out == NULL || outLen == NULL)
wolfSSL 7:481bce714567 4070 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4071
wolfSSL 7:481bce714567 4072 numlen = ecc_sets[curve_idx].size;
wolfSSL 7:481bce714567 4073
wolfSSL 7:481bce714567 4074 if (*outLen < (1 + 2*numlen)) {
wolfSSL 7:481bce714567 4075 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4076 return BUFFER_E;
wolfSSL 7:481bce714567 4077 }
wolfSSL 7:481bce714567 4078
wolfSSL 7:481bce714567 4079 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4080 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4081 ret = BAD_COND_E;
wolfSSL 7:481bce714567 4082
wolfSSL 7:481bce714567 4083 #else
wolfSSL 7:481bce714567 4084
wolfSSL 7:481bce714567 4085 /* store byte 0x04 */
wolfSSL 7:481bce714567 4086 out[0] = 0x04;
wolfSSL 7:481bce714567 4087
wolfSSL 7:481bce714567 4088 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4089 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 4090 if (buf == NULL)
wolfSSL 7:481bce714567 4091 return MEMORY_E;
wolfSSL 7:481bce714567 4092 #endif
wolfSSL 7:481bce714567 4093
wolfSSL 7:481bce714567 4094 /* pad and store x */
wolfSSL 7:481bce714567 4095 XMEMSET(buf, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 4096 ret = mp_to_unsigned_bin(point->x, buf +
wolfSSL 7:481bce714567 4097 (numlen - mp_unsigned_bin_size(point->x)));
wolfSSL 7:481bce714567 4098 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 4099 goto done;
wolfSSL 7:481bce714567 4100 XMEMCPY(out+1, buf, numlen);
wolfSSL 7:481bce714567 4101
wolfSSL 7:481bce714567 4102 /* pad and store y */
wolfSSL 7:481bce714567 4103 XMEMSET(buf, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 4104 ret = mp_to_unsigned_bin(point->y, buf +
wolfSSL 7:481bce714567 4105 (numlen - mp_unsigned_bin_size(point->y)));
wolfSSL 7:481bce714567 4106 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 4107 goto done;
wolfSSL 7:481bce714567 4108 XMEMCPY(out+1+numlen, buf, numlen);
wolfSSL 7:481bce714567 4109
wolfSSL 7:481bce714567 4110 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4111
wolfSSL 7:481bce714567 4112 done:
wolfSSL 7:481bce714567 4113 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4114 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 4115 #endif
wolfSSL 7:481bce714567 4116 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4117
wolfSSL 7:481bce714567 4118 return ret;
wolfSSL 7:481bce714567 4119 }
wolfSSL 7:481bce714567 4120
wolfSSL 7:481bce714567 4121
wolfSSL 7:481bce714567 4122 /* export public ECC key in ANSI X9.63 format */
wolfSSL 7:481bce714567 4123 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
wolfSSL 7:481bce714567 4124 {
wolfSSL 7:481bce714567 4125 int ret = MP_OKAY;
wolfSSL 7:481bce714567 4126 word32 numlen;
wolfSSL 7:481bce714567 4127 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4128 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4129 byte* buf;
wolfSSL 7:481bce714567 4130 #else
wolfSSL 7:481bce714567 4131 byte buf[ECC_BUFSIZE];
wolfSSL 7:481bce714567 4132 #endif
wolfSSL 7:481bce714567 4133 word32 pubxlen, pubylen;
wolfSSL 7:481bce714567 4134 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4135
wolfSSL 7:481bce714567 4136 /* return length needed only */
wolfSSL 7:481bce714567 4137 if (key != NULL && out == NULL && outLen != NULL) {
wolfSSL 7:481bce714567 4138 numlen = key->dp->size;
wolfSSL 7:481bce714567 4139 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4140 return LENGTH_ONLY_E;
wolfSSL 7:481bce714567 4141 }
wolfSSL 7:481bce714567 4142
wolfSSL 7:481bce714567 4143 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 7:481bce714567 4144 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4145
wolfSSL 7:481bce714567 4146 if (wc_ecc_is_valid_idx(key->idx) == 0) {
wolfSSL 7:481bce714567 4147 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4148 }
wolfSSL 7:481bce714567 4149 numlen = key->dp->size;
wolfSSL 7:481bce714567 4150
wolfSSL 7:481bce714567 4151 /* verify room in out buffer */
wolfSSL 7:481bce714567 4152 if (*outLen < (1 + 2*numlen)) {
wolfSSL 7:481bce714567 4153 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4154 return BUFFER_E;
wolfSSL 7:481bce714567 4155 }
wolfSSL 7:481bce714567 4156
wolfSSL 7:481bce714567 4157 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4158 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4159 ret = BAD_COND_E;
wolfSSL 7:481bce714567 4160
wolfSSL 7:481bce714567 4161 #else
wolfSSL 7:481bce714567 4162
wolfSSL 7:481bce714567 4163 /* verify public key length is less than key size */
wolfSSL 7:481bce714567 4164 pubxlen = mp_unsigned_bin_size(key->pubkey.x);
wolfSSL 7:481bce714567 4165 pubylen = mp_unsigned_bin_size(key->pubkey.y);
wolfSSL 7:481bce714567 4166 if ((pubxlen > numlen) || (pubylen > numlen)) {
wolfSSL 7:481bce714567 4167 WOLFSSL_MSG("Public key x/y invalid!");
wolfSSL 7:481bce714567 4168 return BUFFER_E;
wolfSSL 7:481bce714567 4169 }
wolfSSL 7:481bce714567 4170
wolfSSL 7:481bce714567 4171 /* store byte 0x04 */
wolfSSL 7:481bce714567 4172 out[0] = 0x04;
wolfSSL 7:481bce714567 4173
wolfSSL 7:481bce714567 4174 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4175 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 4176 if (buf == NULL)
wolfSSL 7:481bce714567 4177 return MEMORY_E;
wolfSSL 7:481bce714567 4178 #endif
wolfSSL 7:481bce714567 4179
wolfSSL 7:481bce714567 4180 /* pad and store x */
wolfSSL 7:481bce714567 4181 XMEMSET(buf, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 4182 ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
wolfSSL 7:481bce714567 4183 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 4184 goto done;
wolfSSL 7:481bce714567 4185 XMEMCPY(out+1, buf, numlen);
wolfSSL 7:481bce714567 4186
wolfSSL 7:481bce714567 4187 /* pad and store y */
wolfSSL 7:481bce714567 4188 XMEMSET(buf, 0, ECC_BUFSIZE);
wolfSSL 7:481bce714567 4189 ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
wolfSSL 7:481bce714567 4190 if (ret != MP_OKAY)
wolfSSL 7:481bce714567 4191 goto done;
wolfSSL 7:481bce714567 4192 XMEMCPY(out+1+numlen, buf, numlen);
wolfSSL 7:481bce714567 4193
wolfSSL 7:481bce714567 4194 *outLen = 1 + 2*numlen;
wolfSSL 7:481bce714567 4195
wolfSSL 7:481bce714567 4196 done:
wolfSSL 7:481bce714567 4197 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 4198 XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 4199 #endif
wolfSSL 7:481bce714567 4200 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4201
wolfSSL 7:481bce714567 4202 return ret;
wolfSSL 7:481bce714567 4203 }
wolfSSL 7:481bce714567 4204
wolfSSL 7:481bce714567 4205
wolfSSL 7:481bce714567 4206 /* export public ECC key in ANSI X9.63 format, extended with
wolfSSL 7:481bce714567 4207 * compression option */
wolfSSL 7:481bce714567 4208 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
wolfSSL 7:481bce714567 4209 int compressed)
wolfSSL 7:481bce714567 4210 {
wolfSSL 7:481bce714567 4211 if (compressed == 0)
wolfSSL 7:481bce714567 4212 return wc_ecc_export_x963(key, out, outLen);
wolfSSL 7:481bce714567 4213 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 4214 else
wolfSSL 7:481bce714567 4215 return wc_ecc_export_x963_compressed(key, out, outLen);
wolfSSL 7:481bce714567 4216 #else
wolfSSL 7:481bce714567 4217 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 4218 #endif
wolfSSL 7:481bce714567 4219 }
wolfSSL 7:481bce714567 4220 #endif /* HAVE_ECC_KEY_EXPORT */
wolfSSL 7:481bce714567 4221
wolfSSL 7:481bce714567 4222
wolfSSL 7:481bce714567 4223 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4224
wolfSSL 7:481bce714567 4225 /* is ecc point on curve described by dp ? */
wolfSSL 7:481bce714567 4226 int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
wolfSSL 7:481bce714567 4227 {
wolfSSL 7:481bce714567 4228 int err;
wolfSSL 7:481bce714567 4229 mp_int t1, t2;
wolfSSL 7:481bce714567 4230
wolfSSL 7:481bce714567 4231 if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 4232 return err;
wolfSSL 7:481bce714567 4233 }
wolfSSL 7:481bce714567 4234
wolfSSL 7:481bce714567 4235 /* compute y^2 */
wolfSSL 7:481bce714567 4236 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4237 err = mp_sqr(ecp->y, &t1);
wolfSSL 7:481bce714567 4238
wolfSSL 7:481bce714567 4239 /* compute x^3 */
wolfSSL 7:481bce714567 4240 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4241 err = mp_sqr(ecp->x, &t2);
wolfSSL 7:481bce714567 4242 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4243 err = mp_mod(&t2, prime, &t2);
wolfSSL 7:481bce714567 4244 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4245 err = mp_mul(ecp->x, &t2, &t2);
wolfSSL 7:481bce714567 4246
wolfSSL 7:481bce714567 4247 /* compute y^2 - x^3 */
wolfSSL 7:481bce714567 4248 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4249 err = mp_sub(&t1, &t2, &t1);
wolfSSL 7:481bce714567 4250
wolfSSL 7:481bce714567 4251 /* Determine if curve "a" should be used in calc */
wolfSSL 7:481bce714567 4252 #ifdef WOLFSSL_CUSTOM_CURVES
wolfSSL 7:481bce714567 4253 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4254 /* Use a and prime to determine if a == 3 */
wolfSSL 7:481bce714567 4255 err = mp_set(&t2, 0);
wolfSSL 7:481bce714567 4256 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4257 err = mp_submod(prime, a, prime, &t2);
wolfSSL 7:481bce714567 4258 }
wolfSSL 7:481bce714567 4259 if (err == MP_OKAY && mp_cmp_d(&t2, 3) != MP_EQ) {
wolfSSL 7:481bce714567 4260 /* compute y^2 - x^3 + a*x */
wolfSSL 7:481bce714567 4261 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4262 err = mp_mulmod(&t2, ecp->x, prime, &t2);
wolfSSL 7:481bce714567 4263 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4264 err = mp_addmod(&t1, &t2, prime, &t1);
wolfSSL 7:481bce714567 4265 }
wolfSSL 7:481bce714567 4266 else
wolfSSL 7:481bce714567 4267 #endif /* WOLFSSL_CUSTOM_CURVES */
wolfSSL 7:481bce714567 4268 {
wolfSSL 7:481bce714567 4269 /* assumes "a" == 3 */
wolfSSL 7:481bce714567 4270 (void)a;
wolfSSL 7:481bce714567 4271
wolfSSL 7:481bce714567 4272 /* compute y^2 - x^3 + 3x */
wolfSSL 7:481bce714567 4273 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4274 err = mp_add(&t1, ecp->x, &t1);
wolfSSL 7:481bce714567 4275 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4276 err = mp_add(&t1, ecp->x, &t1);
wolfSSL 7:481bce714567 4277 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4278 err = mp_add(&t1, ecp->x, &t1);
wolfSSL 7:481bce714567 4279 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4280 err = mp_mod(&t1, prime, &t1);
wolfSSL 7:481bce714567 4281 }
wolfSSL 7:481bce714567 4282
wolfSSL 7:481bce714567 4283 /* adjust range (0, prime) */
wolfSSL 7:481bce714567 4284 while (err == MP_OKAY && mp_isneg(&t1)) {
wolfSSL 7:481bce714567 4285 err = mp_add(&t1, prime, &t1);
wolfSSL 7:481bce714567 4286 }
wolfSSL 7:481bce714567 4287 while (err == MP_OKAY && mp_cmp(&t1, prime) != MP_LT) {
wolfSSL 7:481bce714567 4288 err = mp_sub(&t1, prime, &t1);
wolfSSL 7:481bce714567 4289 }
wolfSSL 7:481bce714567 4290
wolfSSL 7:481bce714567 4291 /* compare to b */
wolfSSL 7:481bce714567 4292 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4293 if (mp_cmp(&t1, b) != MP_EQ) {
wolfSSL 7:481bce714567 4294 err = MP_VAL;
wolfSSL 7:481bce714567 4295 } else {
wolfSSL 7:481bce714567 4296 err = MP_OKAY;
wolfSSL 7:481bce714567 4297 }
wolfSSL 7:481bce714567 4298 }
wolfSSL 7:481bce714567 4299
wolfSSL 7:481bce714567 4300 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 4301 mp_clear(&t1);
wolfSSL 7:481bce714567 4302 mp_clear(&t2);
wolfSSL 7:481bce714567 4303 #endif
wolfSSL 7:481bce714567 4304
wolfSSL 7:481bce714567 4305 return err;
wolfSSL 7:481bce714567 4306 }
wolfSSL 7:481bce714567 4307
wolfSSL 7:481bce714567 4308
wolfSSL 7:481bce714567 4309 /* validate privkey * generator == pubkey, 0 on success */
wolfSSL 7:481bce714567 4310 static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
wolfSSL 7:481bce714567 4311 {
wolfSSL 7:481bce714567 4312 int err = MP_OKAY;
wolfSSL 7:481bce714567 4313 ecc_point* base = NULL;
wolfSSL 7:481bce714567 4314 ecc_point* res = NULL;
wolfSSL 7:481bce714567 4315 DECLARE_CURVE_SPECS(2)
wolfSSL 7:481bce714567 4316
wolfSSL 7:481bce714567 4317 if (key == NULL)
wolfSSL 7:481bce714567 4318 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4319
wolfSSL 7:481bce714567 4320 base = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 4321 if (base == NULL)
wolfSSL 7:481bce714567 4322 return MEMORY_E;
wolfSSL 7:481bce714567 4323
wolfSSL 7:481bce714567 4324 /* load curve info */
wolfSSL 7:481bce714567 4325 err = wc_ecc_curve_load(key->dp, &curve,
wolfSSL 7:481bce714567 4326 (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
wolfSSL 7:481bce714567 4327
wolfSSL 7:481bce714567 4328 /* set up base generator */
wolfSSL 7:481bce714567 4329 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4330 err = mp_copy(curve->Gx, base->x);
wolfSSL 7:481bce714567 4331 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4332 err = mp_copy(curve->Gy, base->y);
wolfSSL 7:481bce714567 4333 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4334 err = mp_set(base->z, 1);
wolfSSL 7:481bce714567 4335
wolfSSL 7:481bce714567 4336 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4337 res = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 4338 if (res == NULL)
wolfSSL 7:481bce714567 4339 err = MEMORY_E;
wolfSSL 7:481bce714567 4340 else {
wolfSSL 7:481bce714567 4341 err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);
wolfSSL 7:481bce714567 4342 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4343 /* compare result to public key */
wolfSSL 7:481bce714567 4344 if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
wolfSSL 7:481bce714567 4345 mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
wolfSSL 7:481bce714567 4346 mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
wolfSSL 7:481bce714567 4347 /* didn't match */
wolfSSL 7:481bce714567 4348 err = ECC_PRIV_KEY_E;
wolfSSL 7:481bce714567 4349 }
wolfSSL 7:481bce714567 4350 }
wolfSSL 7:481bce714567 4351 }
wolfSSL 7:481bce714567 4352 }
wolfSSL 7:481bce714567 4353
wolfSSL 7:481bce714567 4354 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 4355 wc_ecc_del_point_h(res, key->heap);
wolfSSL 7:481bce714567 4356 wc_ecc_del_point_h(base, key->heap);
wolfSSL 7:481bce714567 4357
wolfSSL 7:481bce714567 4358 return err;
wolfSSL 7:481bce714567 4359 }
wolfSSL 7:481bce714567 4360
wolfSSL 7:481bce714567 4361 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
wolfSSL 7:481bce714567 4362
wolfSSL 7:481bce714567 4363 /* check privkey generator helper, creates prime needed */
wolfSSL 7:481bce714567 4364 static int ecc_check_privkey_gen_helper(ecc_key* key)
wolfSSL 7:481bce714567 4365 {
wolfSSL 7:481bce714567 4366 int err;
wolfSSL 7:481bce714567 4367 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4368 DECLARE_CURVE_SPECS(2)
wolfSSL 7:481bce714567 4369 #endif
wolfSSL 7:481bce714567 4370
wolfSSL 7:481bce714567 4371 if (key == NULL)
wolfSSL 7:481bce714567 4372 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4373
wolfSSL 7:481bce714567 4374 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4375 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4376 err = BAD_COND_E;
wolfSSL 7:481bce714567 4377
wolfSSL 7:481bce714567 4378 #else
wolfSSL 7:481bce714567 4379
wolfSSL 7:481bce714567 4380 /* load curve info */
wolfSSL 7:481bce714567 4381 err = wc_ecc_curve_load(key->dp, &curve,
wolfSSL 7:481bce714567 4382 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
wolfSSL 7:481bce714567 4383
wolfSSL 7:481bce714567 4384 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4385 err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
wolfSSL 7:481bce714567 4386
wolfSSL 7:481bce714567 4387 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 4388
wolfSSL 7:481bce714567 4389 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4390
wolfSSL 7:481bce714567 4391 return err;
wolfSSL 7:481bce714567 4392 }
wolfSSL 7:481bce714567 4393
wolfSSL 7:481bce714567 4394 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
wolfSSL 7:481bce714567 4395
wolfSSL 7:481bce714567 4396
wolfSSL 7:481bce714567 4397 /* validate order * pubkey = point at infinity, 0 on success */
wolfSSL 7:481bce714567 4398 static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime,
wolfSSL 7:481bce714567 4399 mp_int* order)
wolfSSL 7:481bce714567 4400 {
wolfSSL 7:481bce714567 4401 ecc_point* inf = NULL;
wolfSSL 7:481bce714567 4402 int err;
wolfSSL 7:481bce714567 4403
wolfSSL 7:481bce714567 4404 if (key == NULL)
wolfSSL 7:481bce714567 4405 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4406
wolfSSL 7:481bce714567 4407 inf = wc_ecc_new_point_h(key->heap);
wolfSSL 7:481bce714567 4408 if (inf == NULL)
wolfSSL 7:481bce714567 4409 err = MEMORY_E;
wolfSSL 7:481bce714567 4410 else {
wolfSSL 7:481bce714567 4411 err = wc_ecc_mulmod_ex(order, &key->pubkey, inf, a, prime, 1, key->heap);
wolfSSL 7:481bce714567 4412 if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
wolfSSL 7:481bce714567 4413 err = ECC_INF_E;
wolfSSL 7:481bce714567 4414 }
wolfSSL 7:481bce714567 4415
wolfSSL 7:481bce714567 4416 wc_ecc_del_point_h(inf, key->heap);
wolfSSL 7:481bce714567 4417
wolfSSL 7:481bce714567 4418 return err;
wolfSSL 7:481bce714567 4419 }
wolfSSL 7:481bce714567 4420
wolfSSL 7:481bce714567 4421 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4422
wolfSSL 7:481bce714567 4423
wolfSSL 7:481bce714567 4424 /* perform sanity checks on ecc key validity, 0 on success */
wolfSSL 7:481bce714567 4425 int wc_ecc_check_key(ecc_key* key)
wolfSSL 7:481bce714567 4426 {
wolfSSL 7:481bce714567 4427 int err;
wolfSSL 7:481bce714567 4428 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4429 mp_int* b;
wolfSSL 7:481bce714567 4430 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 4431 DECLARE_CURVE_SPECS(4)
wolfSSL 7:481bce714567 4432 #else
wolfSSL 7:481bce714567 4433 mp_int b_lcl;
wolfSSL 7:481bce714567 4434 DECLARE_CURVE_SPECS(3)
wolfSSL 7:481bce714567 4435 b = &b_lcl;
wolfSSL 7:481bce714567 4436 XMEMSET(b, 0, sizeof(mp_int));
wolfSSL 7:481bce714567 4437 #endif
wolfSSL 7:481bce714567 4438 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4439
wolfSSL 7:481bce714567 4440 if (key == NULL)
wolfSSL 7:481bce714567 4441 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4442
wolfSSL 7:481bce714567 4443 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4444 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4445 err = BAD_COND_E;
wolfSSL 7:481bce714567 4446
wolfSSL 7:481bce714567 4447 #else
wolfSSL 7:481bce714567 4448
wolfSSL 7:481bce714567 4449 /* pubkey point cannot be at infinity */
wolfSSL 7:481bce714567 4450 if (wc_ecc_point_is_at_infinity(&key->pubkey))
wolfSSL 7:481bce714567 4451 return ECC_INF_E;
wolfSSL 7:481bce714567 4452
wolfSSL 7:481bce714567 4453 /* load curve info */
wolfSSL 7:481bce714567 4454 err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
wolfSSL 7:481bce714567 4455 ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
wolfSSL 7:481bce714567 4456 #ifdef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 4457 | ECC_CURVE_FIELD_BF
wolfSSL 7:481bce714567 4458 #endif
wolfSSL 7:481bce714567 4459 ));
wolfSSL 7:481bce714567 4460
wolfSSL 7:481bce714567 4461 #ifndef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 4462 /* load curve b parameter */
wolfSSL 7:481bce714567 4463 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4464 err = mp_init(b);
wolfSSL 7:481bce714567 4465 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4466 err = mp_read_radix(b, key->dp->Bf, 16);
wolfSSL 7:481bce714567 4467 #else
wolfSSL 7:481bce714567 4468 b = curve->Bf;
wolfSSL 7:481bce714567 4469 #endif
wolfSSL 7:481bce714567 4470
wolfSSL 7:481bce714567 4471 /* Qx must be in the range [0, p-1] */
wolfSSL 7:481bce714567 4472 if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
wolfSSL 7:481bce714567 4473 err = ECC_OUT_OF_RANGE_E;
wolfSSL 7:481bce714567 4474
wolfSSL 7:481bce714567 4475 /* Qy must be in the range [0, p-1] */
wolfSSL 7:481bce714567 4476 if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
wolfSSL 7:481bce714567 4477 err = ECC_OUT_OF_RANGE_E;
wolfSSL 7:481bce714567 4478
wolfSSL 7:481bce714567 4479 /* make sure point is actually on curve */
wolfSSL 7:481bce714567 4480 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4481 err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
wolfSSL 7:481bce714567 4482
wolfSSL 7:481bce714567 4483 /* pubkey * order must be at infinity */
wolfSSL 7:481bce714567 4484 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4485 err = ecc_check_pubkey_order(key, curve->Af, curve->prime, curve->order);
wolfSSL 7:481bce714567 4486
wolfSSL 7:481bce714567 4487 /* private * base generator must equal pubkey */
wolfSSL 7:481bce714567 4488 if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
wolfSSL 7:481bce714567 4489 err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
wolfSSL 7:481bce714567 4490
wolfSSL 7:481bce714567 4491 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 4492
wolfSSL 7:481bce714567 4493 #ifndef USE_ECC_B_PARAM
wolfSSL 7:481bce714567 4494 mp_clear(b);
wolfSSL 7:481bce714567 4495 #endif
wolfSSL 7:481bce714567 4496
wolfSSL 7:481bce714567 4497 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4498
wolfSSL 7:481bce714567 4499 return err;
wolfSSL 7:481bce714567 4500 }
wolfSSL 7:481bce714567 4501
wolfSSL 7:481bce714567 4502 #ifdef HAVE_ECC_KEY_IMPORT
wolfSSL 7:481bce714567 4503 /* import public ECC key in ANSI X9.63 format */
wolfSSL 7:481bce714567 4504 int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
wolfSSL 7:481bce714567 4505 int curve_id)
wolfSSL 7:481bce714567 4506 {
wolfSSL 7:481bce714567 4507 int err = MP_OKAY;
wolfSSL 7:481bce714567 4508 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4509 int compressed = 0;
wolfSSL 7:481bce714567 4510 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4511 void* heap;
wolfSSL 7:481bce714567 4512
wolfSSL 7:481bce714567 4513 if (in == NULL || key == NULL)
wolfSSL 7:481bce714567 4514 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4515
wolfSSL 7:481bce714567 4516 /* must be odd */
wolfSSL 7:481bce714567 4517 if ((inLen & 1) == 0) {
wolfSSL 7:481bce714567 4518 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4519 }
wolfSSL 7:481bce714567 4520
wolfSSL 7:481bce714567 4521 heap = key->heap; /* save heap */
wolfSSL 7:481bce714567 4522 XMEMSET(key, 0, sizeof(ecc_key));
wolfSSL 7:481bce714567 4523 key->heap = heap; /* restore heap */
wolfSSL 7:481bce714567 4524
wolfSSL 7:481bce714567 4525 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4526 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4527 err = BAD_COND_E;
wolfSSL 7:481bce714567 4528
wolfSSL 7:481bce714567 4529 #else
wolfSSL 7:481bce714567 4530
wolfSSL 7:481bce714567 4531 /* init key */
wolfSSL 7:481bce714567 4532 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 4533 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
wolfSSL 7:481bce714567 4534 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
wolfSSL 7:481bce714567 4535 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
wolfSSL 7:481bce714567 4536 alt_fp_init(key->pubkey.x);
wolfSSL 7:481bce714567 4537 alt_fp_init(key->pubkey.y);
wolfSSL 7:481bce714567 4538 alt_fp_init(key->pubkey.z);
wolfSSL 7:481bce714567 4539 err = mp_init(&key->k);
wolfSSL 7:481bce714567 4540 #else
wolfSSL 7:481bce714567 4541 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
wolfSSL 7:481bce714567 4542 NULL, NULL);
wolfSSL 7:481bce714567 4543 #endif
wolfSSL 7:481bce714567 4544 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4545 return MEMORY_E;
wolfSSL 7:481bce714567 4546
wolfSSL 7:481bce714567 4547 /* check for 4, 2, or 3 */
wolfSSL 7:481bce714567 4548 if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
wolfSSL 7:481bce714567 4549 err = ASN_PARSE_E;
wolfSSL 7:481bce714567 4550 }
wolfSSL 7:481bce714567 4551
wolfSSL 7:481bce714567 4552 if (in[0] == 0x02 || in[0] == 0x03) {
wolfSSL 7:481bce714567 4553 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 4554 compressed = 1;
wolfSSL 7:481bce714567 4555 #else
wolfSSL 7:481bce714567 4556 err = NOT_COMPILED_IN;
wolfSSL 7:481bce714567 4557 #endif
wolfSSL 7:481bce714567 4558 }
wolfSSL 7:481bce714567 4559
wolfSSL 7:481bce714567 4560 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4561 int keysize;
wolfSSL 7:481bce714567 4562 /* adjust inLen if compressed */
wolfSSL 7:481bce714567 4563 if (compressed)
wolfSSL 7:481bce714567 4564 inLen = (inLen-1)*2 + 1; /* used uncompressed len */
wolfSSL 7:481bce714567 4565
wolfSSL 7:481bce714567 4566 /* determine key size */
wolfSSL 7:481bce714567 4567 keysize = ((inLen-1)>>1);
wolfSSL 7:481bce714567 4568 err = wc_ecc_set_curve(key, keysize, curve_id);
wolfSSL 7:481bce714567 4569 key->type = ECC_PUBLICKEY;
wolfSSL 7:481bce714567 4570 }
wolfSSL 7:481bce714567 4571
wolfSSL 7:481bce714567 4572 /* read data */
wolfSSL 7:481bce714567 4573 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4574 err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
wolfSSL 7:481bce714567 4575
wolfSSL 7:481bce714567 4576 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 4577 if (err == MP_OKAY && compressed == 1) { /* build y */
wolfSSL 7:481bce714567 4578 mp_int t1, t2;
wolfSSL 7:481bce714567 4579 int did_init = 0;
wolfSSL 7:481bce714567 4580
wolfSSL 7:481bce714567 4581 DECLARE_CURVE_SPECS(3)
wolfSSL 7:481bce714567 4582
wolfSSL 7:481bce714567 4583 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 7:481bce714567 4584 err = MEMORY_E;
wolfSSL 7:481bce714567 4585 else
wolfSSL 7:481bce714567 4586 did_init = 1;
wolfSSL 7:481bce714567 4587
wolfSSL 7:481bce714567 4588 /* load curve info */
wolfSSL 7:481bce714567 4589 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4590 err = wc_ecc_curve_load(key->dp, &curve,
wolfSSL 7:481bce714567 4591 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
wolfSSL 7:481bce714567 4592 ECC_CURVE_FIELD_BF));
wolfSSL 7:481bce714567 4593
wolfSSL 7:481bce714567 4594 /* compute x^3 */
wolfSSL 7:481bce714567 4595 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4596 err = mp_sqr(key->pubkey.x, &t1);
wolfSSL 7:481bce714567 4597 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4598 err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1);
wolfSSL 7:481bce714567 4599
wolfSSL 7:481bce714567 4600 /* compute x^3 + a*x */
wolfSSL 7:481bce714567 4601 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4602 err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2);
wolfSSL 7:481bce714567 4603 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4604 err = mp_add(&t1, &t2, &t1);
wolfSSL 7:481bce714567 4605
wolfSSL 7:481bce714567 4606 /* compute x^3 + a*x + b */
wolfSSL 7:481bce714567 4607 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4608 err = mp_add(&t1, curve->Bf, &t1);
wolfSSL 7:481bce714567 4609
wolfSSL 7:481bce714567 4610 /* compute sqrt(x^3 + a*x + b) */
wolfSSL 7:481bce714567 4611 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4612 err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
wolfSSL 7:481bce714567 4613
wolfSSL 7:481bce714567 4614 /* adjust y */
wolfSSL 7:481bce714567 4615 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4616 if ((mp_isodd(&t2) == MP_YES && in[0] == 0x03) ||
wolfSSL 7:481bce714567 4617 (mp_isodd(&t2) == MP_NO && in[0] == 0x02)) {
wolfSSL 7:481bce714567 4618 err = mp_mod(&t2, curve->prime, &t2);
wolfSSL 7:481bce714567 4619 }
wolfSSL 7:481bce714567 4620 else {
wolfSSL 7:481bce714567 4621 err = mp_submod(curve->prime, &t2, curve->prime, &t2);
wolfSSL 7:481bce714567 4622 }
wolfSSL 7:481bce714567 4623 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4624 err = mp_copy(&t2, key->pubkey.y);
wolfSSL 7:481bce714567 4625 }
wolfSSL 7:481bce714567 4626
wolfSSL 7:481bce714567 4627 if (did_init) {
wolfSSL 7:481bce714567 4628 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 4629 mp_clear(&t2);
wolfSSL 7:481bce714567 4630 mp_clear(&t1);
wolfSSL 7:481bce714567 4631 #endif
wolfSSL 7:481bce714567 4632 }
wolfSSL 7:481bce714567 4633
wolfSSL 7:481bce714567 4634 wc_ecc_curve_free(curve);
wolfSSL 7:481bce714567 4635 }
wolfSSL 7:481bce714567 4636 #endif /* HAVE_COMP_KEY */
wolfSSL 7:481bce714567 4637
wolfSSL 7:481bce714567 4638 if (err == MP_OKAY && compressed == 0)
wolfSSL 7:481bce714567 4639 err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
wolfSSL 7:481bce714567 4640 (inLen-1)>>1);
wolfSSL 7:481bce714567 4641 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4642 err = mp_set(key->pubkey.z, 1);
wolfSSL 7:481bce714567 4643
wolfSSL 7:481bce714567 4644 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
wolfSSL 7:481bce714567 4645 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4646 err = wc_ecc_check_key(key);
wolfSSL 7:481bce714567 4647 #endif
wolfSSL 7:481bce714567 4648
wolfSSL 7:481bce714567 4649 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 4650 mp_clear(key->pubkey.x);
wolfSSL 7:481bce714567 4651 mp_clear(key->pubkey.y);
wolfSSL 7:481bce714567 4652 mp_clear(key->pubkey.z);
wolfSSL 7:481bce714567 4653 mp_clear(&key->k);
wolfSSL 7:481bce714567 4654 }
wolfSSL 7:481bce714567 4655 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4656
wolfSSL 7:481bce714567 4657 return err;
wolfSSL 7:481bce714567 4658 }
wolfSSL 7:481bce714567 4659
wolfSSL 7:481bce714567 4660 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
wolfSSL 7:481bce714567 4661 {
wolfSSL 7:481bce714567 4662 return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
wolfSSL 7:481bce714567 4663 }
wolfSSL 7:481bce714567 4664 #endif /* HAVE_ECC_KEY_IMPORT */
wolfSSL 7:481bce714567 4665
wolfSSL 7:481bce714567 4666 #ifdef HAVE_ECC_KEY_EXPORT
wolfSSL 7:481bce714567 4667 /* export ecc private key only raw, outLen is in/out size
wolfSSL 7:481bce714567 4668 return MP_OKAY on success */
wolfSSL 7:481bce714567 4669 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
wolfSSL 7:481bce714567 4670 {
wolfSSL 7:481bce714567 4671 word32 numlen;
wolfSSL 7:481bce714567 4672
wolfSSL 7:481bce714567 4673 if (key == NULL || out == NULL || outLen == NULL) {
wolfSSL 7:481bce714567 4674 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4675 }
wolfSSL 7:481bce714567 4676
wolfSSL 7:481bce714567 4677 if (wc_ecc_is_valid_idx(key->idx) == 0) {
wolfSSL 7:481bce714567 4678 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4679 }
wolfSSL 7:481bce714567 4680 numlen = key->dp->size;
wolfSSL 7:481bce714567 4681
wolfSSL 7:481bce714567 4682 if (*outLen < numlen) {
wolfSSL 7:481bce714567 4683 *outLen = numlen;
wolfSSL 7:481bce714567 4684 return BUFFER_E;
wolfSSL 7:481bce714567 4685 }
wolfSSL 7:481bce714567 4686 *outLen = numlen;
wolfSSL 7:481bce714567 4687 XMEMSET(out, 0, *outLen);
wolfSSL 7:481bce714567 4688
wolfSSL 7:481bce714567 4689 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4690 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4691 return BAD_COND_E;
wolfSSL 7:481bce714567 4692
wolfSSL 7:481bce714567 4693 #else
wolfSSL 7:481bce714567 4694
wolfSSL 7:481bce714567 4695 return mp_to_unsigned_bin(&key->k, out + (numlen -
wolfSSL 7:481bce714567 4696 mp_unsigned_bin_size(&key->k)));
wolfSSL 7:481bce714567 4697 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4698 }
wolfSSL 7:481bce714567 4699
wolfSSL 7:481bce714567 4700
wolfSSL 7:481bce714567 4701 /* export ecc key to component form, d is optional if only exporting public
wolfSSL 7:481bce714567 4702 * return MP_OKAY on success */
wolfSSL 7:481bce714567 4703 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen,
wolfSSL 7:481bce714567 4704 byte* qy, word32* qyLen, byte* d, word32* dLen)
wolfSSL 7:481bce714567 4705 {
wolfSSL 7:481bce714567 4706 int err;
wolfSSL 7:481bce714567 4707 byte exportPriv = 0;
wolfSSL 7:481bce714567 4708 word32 numLen;
wolfSSL 7:481bce714567 4709
wolfSSL 7:481bce714567 4710 if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
wolfSSL 7:481bce714567 4711 qyLen == NULL) {
wolfSSL 7:481bce714567 4712 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4713 }
wolfSSL 7:481bce714567 4714
wolfSSL 7:481bce714567 4715 if (wc_ecc_is_valid_idx(key->idx) == 0) {
wolfSSL 7:481bce714567 4716 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4717 }
wolfSSL 7:481bce714567 4718 numLen = key->dp->size;
wolfSSL 7:481bce714567 4719
wolfSSL 7:481bce714567 4720 if (d != NULL) {
wolfSSL 7:481bce714567 4721 if (dLen == NULL || key->type != ECC_PRIVATEKEY)
wolfSSL 7:481bce714567 4722 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4723 exportPriv = 1;
wolfSSL 7:481bce714567 4724 }
wolfSSL 7:481bce714567 4725
wolfSSL 7:481bce714567 4726 /* check public buffer sizes */
wolfSSL 7:481bce714567 4727 if ((*qxLen < numLen) || (*qyLen < numLen)) {
wolfSSL 7:481bce714567 4728 *qxLen = numLen;
wolfSSL 7:481bce714567 4729 *qyLen = numLen;
wolfSSL 7:481bce714567 4730 return BUFFER_E;
wolfSSL 7:481bce714567 4731 }
wolfSSL 7:481bce714567 4732
wolfSSL 7:481bce714567 4733 *qxLen = numLen;
wolfSSL 7:481bce714567 4734 *qyLen = numLen;
wolfSSL 7:481bce714567 4735
wolfSSL 7:481bce714567 4736 XMEMSET(qx, 0, *qxLen);
wolfSSL 7:481bce714567 4737 XMEMSET(qy, 0, *qyLen);
wolfSSL 7:481bce714567 4738
wolfSSL 7:481bce714567 4739 /* private d component */
wolfSSL 7:481bce714567 4740 if (exportPriv == 1) {
wolfSSL 7:481bce714567 4741
wolfSSL 7:481bce714567 4742 /* check private buffer size */
wolfSSL 7:481bce714567 4743 if (*dLen < numLen) {
wolfSSL 7:481bce714567 4744 *dLen = numLen;
wolfSSL 7:481bce714567 4745 return BUFFER_E;
wolfSSL 7:481bce714567 4746 }
wolfSSL 7:481bce714567 4747
wolfSSL 7:481bce714567 4748 *dLen = numLen;
wolfSSL 7:481bce714567 4749 XMEMSET(d, 0, *dLen);
wolfSSL 7:481bce714567 4750
wolfSSL 7:481bce714567 4751 /* private key, d */
wolfSSL 7:481bce714567 4752 err = mp_to_unsigned_bin(&key->k, d +
wolfSSL 7:481bce714567 4753 (numLen - mp_unsigned_bin_size(&key->k)));
wolfSSL 7:481bce714567 4754 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4755 return err;
wolfSSL 7:481bce714567 4756 }
wolfSSL 7:481bce714567 4757
wolfSSL 7:481bce714567 4758 /* public x component */
wolfSSL 7:481bce714567 4759 err = mp_to_unsigned_bin(key->pubkey.x, qx +
wolfSSL 7:481bce714567 4760 (numLen - mp_unsigned_bin_size(key->pubkey.x)));
wolfSSL 7:481bce714567 4761 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4762 return err;
wolfSSL 7:481bce714567 4763
wolfSSL 7:481bce714567 4764 /* public y component */
wolfSSL 7:481bce714567 4765 err = mp_to_unsigned_bin(key->pubkey.y, qy +
wolfSSL 7:481bce714567 4766 (numLen - mp_unsigned_bin_size(key->pubkey.y)));
wolfSSL 7:481bce714567 4767 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4768 return err;
wolfSSL 7:481bce714567 4769
wolfSSL 7:481bce714567 4770 return 0;
wolfSSL 7:481bce714567 4771 }
wolfSSL 7:481bce714567 4772
wolfSSL 7:481bce714567 4773
wolfSSL 7:481bce714567 4774 /* export public key to raw elements including public (Qx,Qy)
wolfSSL 7:481bce714567 4775 * return MP_OKAY on success, negative on error */
wolfSSL 7:481bce714567 4776 int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
wolfSSL 7:481bce714567 4777 byte* qy, word32* qyLen)
wolfSSL 7:481bce714567 4778 {
wolfSSL 7:481bce714567 4779 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL);
wolfSSL 7:481bce714567 4780 }
wolfSSL 7:481bce714567 4781
wolfSSL 7:481bce714567 4782
wolfSSL 7:481bce714567 4783 /* export ecc key to raw elements including public (Qx,Qy) and private (d)
wolfSSL 7:481bce714567 4784 * return MP_OKAY on success, negative on error */
wolfSSL 7:481bce714567 4785 int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
wolfSSL 7:481bce714567 4786 byte* qy, word32* qyLen, byte* d, word32* dLen)
wolfSSL 7:481bce714567 4787 {
wolfSSL 7:481bce714567 4788 /* sanitize d and dLen, other args are checked later */
wolfSSL 7:481bce714567 4789 if (d == NULL || dLen == NULL)
wolfSSL 7:481bce714567 4790 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4791
wolfSSL 7:481bce714567 4792 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen);
wolfSSL 7:481bce714567 4793 }
wolfSSL 7:481bce714567 4794
wolfSSL 7:481bce714567 4795 #endif /* HAVE_ECC_KEY_EXPORT */
wolfSSL 7:481bce714567 4796
wolfSSL 7:481bce714567 4797 #ifdef HAVE_ECC_KEY_IMPORT
wolfSSL 7:481bce714567 4798 int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, const byte* pub,
wolfSSL 7:481bce714567 4799 word32 pubSz, ecc_key* key, int curve_id)
wolfSSL 7:481bce714567 4800 {
wolfSSL 7:481bce714567 4801 int ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
wolfSSL 7:481bce714567 4802 if (ret != 0)
wolfSSL 7:481bce714567 4803 return ret;
wolfSSL 7:481bce714567 4804
wolfSSL 7:481bce714567 4805 key->type = ECC_PRIVATEKEY;
wolfSSL 7:481bce714567 4806
wolfSSL 7:481bce714567 4807 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4808 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4809 return BAD_COND_E;
wolfSSL 7:481bce714567 4810
wolfSSL 7:481bce714567 4811 #else
wolfSSL 7:481bce714567 4812
wolfSSL 7:481bce714567 4813 ret = mp_read_unsigned_bin(&key->k, priv, privSz);
wolfSSL 7:481bce714567 4814
wolfSSL 7:481bce714567 4815 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 4816
wolfSSL 7:481bce714567 4817 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
wolfSSL 7:481bce714567 4818 if (ret == MP_OKAY)
wolfSSL 7:481bce714567 4819 ret = ecc_check_privkey_gen_helper(key);
wolfSSL 7:481bce714567 4820 #endif
wolfSSL 7:481bce714567 4821
wolfSSL 7:481bce714567 4822 return ret;
wolfSSL 7:481bce714567 4823 }
wolfSSL 7:481bce714567 4824
wolfSSL 7:481bce714567 4825 /* ecc private key import, public key in ANSI X9.63 format, private raw */
wolfSSL 7:481bce714567 4826 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
wolfSSL 7:481bce714567 4827 word32 pubSz, ecc_key* key)
wolfSSL 7:481bce714567 4828 {
wolfSSL 7:481bce714567 4829 return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
wolfSSL 7:481bce714567 4830 ECC_CURVE_DEF);
wolfSSL 7:481bce714567 4831 }
wolfSSL 7:481bce714567 4832 #endif /* HAVE_ECC_KEY_IMPORT */
wolfSSL 7:481bce714567 4833
wolfSSL 7:481bce714567 4834 #ifndef NO_ASN
wolfSSL 7:481bce714567 4835 /**
wolfSSL 7:481bce714567 4836 Convert ECC R,S to signature
wolfSSL 7:481bce714567 4837 r R component of signature
wolfSSL 7:481bce714567 4838 s S component of signature
wolfSSL 7:481bce714567 4839 out DER-encoded ECDSA signature
wolfSSL 7:481bce714567 4840 outlen [in/out] output buffer size, output signature size
wolfSSL 7:481bce714567 4841 return MP_OKAY on success
wolfSSL 7:481bce714567 4842 */
wolfSSL 7:481bce714567 4843 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
wolfSSL 7:481bce714567 4844 {
wolfSSL 7:481bce714567 4845 int err;
wolfSSL 7:481bce714567 4846 mp_int rtmp;
wolfSSL 7:481bce714567 4847 mp_int stmp;
wolfSSL 7:481bce714567 4848
wolfSSL 7:481bce714567 4849 if (r == NULL || s == NULL || out == NULL || outlen == NULL)
wolfSSL 7:481bce714567 4850 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4851
wolfSSL 7:481bce714567 4852 err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL);
wolfSSL 7:481bce714567 4853 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4854 return err;
wolfSSL 7:481bce714567 4855
wolfSSL 7:481bce714567 4856 err = mp_read_radix(&rtmp, r, 16);
wolfSSL 7:481bce714567 4857 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4858 err = mp_read_radix(&stmp, s, 16);
wolfSSL 7:481bce714567 4859
wolfSSL 7:481bce714567 4860 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
wolfSSL 7:481bce714567 4861 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4862 err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp);
wolfSSL 7:481bce714567 4863
wolfSSL 7:481bce714567 4864 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4865 if (mp_iszero(&rtmp) == MP_YES || mp_iszero(&stmp) == MP_YES)
wolfSSL 7:481bce714567 4866 err = MP_ZERO_E;
wolfSSL 7:481bce714567 4867 }
wolfSSL 7:481bce714567 4868
wolfSSL 7:481bce714567 4869 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 4870 mp_clear(&rtmp);
wolfSSL 7:481bce714567 4871 mp_clear(&stmp);
wolfSSL 7:481bce714567 4872 #endif
wolfSSL 7:481bce714567 4873
wolfSSL 7:481bce714567 4874 return err;
wolfSSL 7:481bce714567 4875 }
wolfSSL 7:481bce714567 4876
wolfSSL 7:481bce714567 4877
wolfSSL 7:481bce714567 4878 /**
wolfSSL 7:481bce714567 4879 Convert ECC signature to R,S
wolfSSL 7:481bce714567 4880 sig DER-encoded ECDSA signature
wolfSSL 7:481bce714567 4881 sigLen length of signature in octets
wolfSSL 7:481bce714567 4882 r R component of signature
wolfSSL 7:481bce714567 4883 rLen [in/out] output "r" buffer size, output "r" size
wolfSSL 7:481bce714567 4884 s S component of signature
wolfSSL 7:481bce714567 4885 sLen [in/out] output "s" buffer size, output "s" size
wolfSSL 7:481bce714567 4886 return MP_OKAY on success, negative on error
wolfSSL 7:481bce714567 4887 */
wolfSSL 7:481bce714567 4888 int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
wolfSSL 7:481bce714567 4889 byte* s, word32* sLen)
wolfSSL 7:481bce714567 4890 {
wolfSSL 7:481bce714567 4891 int err;
wolfSSL 7:481bce714567 4892 word32 x = 0;
wolfSSL 7:481bce714567 4893 mp_int rtmp;
wolfSSL 7:481bce714567 4894 mp_int stmp;
wolfSSL 7:481bce714567 4895
wolfSSL 7:481bce714567 4896 if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
wolfSSL 7:481bce714567 4897 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 4898
wolfSSL 7:481bce714567 4899 err = DecodeECC_DSA_Sig(sig, sigLen, &rtmp, &stmp);
wolfSSL 7:481bce714567 4900
wolfSSL 7:481bce714567 4901 /* extract r */
wolfSSL 7:481bce714567 4902 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4903 x = mp_unsigned_bin_size(&rtmp);
wolfSSL 7:481bce714567 4904 if (*rLen < x)
wolfSSL 7:481bce714567 4905 err = BUFFER_E;
wolfSSL 7:481bce714567 4906
wolfSSL 7:481bce714567 4907 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4908 *rLen = x;
wolfSSL 7:481bce714567 4909 err = mp_to_unsigned_bin(&rtmp, r);
wolfSSL 7:481bce714567 4910 }
wolfSSL 7:481bce714567 4911 }
wolfSSL 7:481bce714567 4912
wolfSSL 7:481bce714567 4913 /* extract s */
wolfSSL 7:481bce714567 4914 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4915 x = mp_unsigned_bin_size(&stmp);
wolfSSL 7:481bce714567 4916 if (*sLen < x)
wolfSSL 7:481bce714567 4917 err = BUFFER_E;
wolfSSL 7:481bce714567 4918
wolfSSL 7:481bce714567 4919 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4920 *sLen = x;
wolfSSL 7:481bce714567 4921 err = mp_to_unsigned_bin(&stmp, s);
wolfSSL 7:481bce714567 4922 }
wolfSSL 7:481bce714567 4923 }
wolfSSL 7:481bce714567 4924
wolfSSL 7:481bce714567 4925 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 4926 mp_clear(&rtmp);
wolfSSL 7:481bce714567 4927 mp_clear(&stmp);
wolfSSL 7:481bce714567 4928 #endif
wolfSSL 7:481bce714567 4929
wolfSSL 7:481bce714567 4930 return err;
wolfSSL 7:481bce714567 4931 }
wolfSSL 7:481bce714567 4932 #endif /* !NO_ASN */
wolfSSL 7:481bce714567 4933
wolfSSL 7:481bce714567 4934 #ifdef HAVE_ECC_KEY_IMPORT
wolfSSL 7:481bce714567 4935 static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
wolfSSL 7:481bce714567 4936 const char* qy, const char* d, int curve_id)
wolfSSL 7:481bce714567 4937 {
wolfSSL 7:481bce714567 4938 int err = MP_OKAY;
wolfSSL 7:481bce714567 4939 void* heap;
wolfSSL 7:481bce714567 4940
wolfSSL 7:481bce714567 4941 /* if d is NULL, only import as public key using Qx,Qy */
wolfSSL 7:481bce714567 4942 if (key == NULL || qx == NULL || qy == NULL) {
wolfSSL 7:481bce714567 4943 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 4944 }
wolfSSL 7:481bce714567 4945
wolfSSL 7:481bce714567 4946 heap = key->heap; /* save heap */
wolfSSL 7:481bce714567 4947 XMEMSET(key, 0, sizeof(ecc_key));
wolfSSL 7:481bce714567 4948 key->heap = heap; /* restore heap */
wolfSSL 7:481bce714567 4949
wolfSSL 7:481bce714567 4950 /* set curve type and index */
wolfSSL 7:481bce714567 4951 err = wc_ecc_set_curve(key, 0, curve_id);
wolfSSL 7:481bce714567 4952 if (err != 0) {
wolfSSL 7:481bce714567 4953 return err;
wolfSSL 7:481bce714567 4954 }
wolfSSL 7:481bce714567 4955
wolfSSL 7:481bce714567 4956 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 4957 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 4958 err = BAD_COND_E;
wolfSSL 7:481bce714567 4959
wolfSSL 7:481bce714567 4960 #else
wolfSSL 7:481bce714567 4961
wolfSSL 7:481bce714567 4962 /* init key */
wolfSSL 7:481bce714567 4963 #ifdef ALT_ECC_SIZE
wolfSSL 7:481bce714567 4964 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
wolfSSL 7:481bce714567 4965 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
wolfSSL 7:481bce714567 4966 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
wolfSSL 7:481bce714567 4967 alt_fp_init(key->pubkey.x);
wolfSSL 7:481bce714567 4968 alt_fp_init(key->pubkey.y);
wolfSSL 7:481bce714567 4969 alt_fp_init(key->pubkey.z);
wolfSSL 7:481bce714567 4970 err = mp_init(&key->k);
wolfSSL 7:481bce714567 4971 #else
wolfSSL 7:481bce714567 4972 err = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, &key->k,
wolfSSL 7:481bce714567 4973 NULL, NULL);
wolfSSL 7:481bce714567 4974 #endif
wolfSSL 7:481bce714567 4975 if (err != MP_OKAY)
wolfSSL 7:481bce714567 4976 return MEMORY_E;
wolfSSL 7:481bce714567 4977
wolfSSL 7:481bce714567 4978 /* read Qx */
wolfSSL 7:481bce714567 4979 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4980 err = mp_read_radix(key->pubkey.x, qx, 16);
wolfSSL 7:481bce714567 4981
wolfSSL 7:481bce714567 4982 /* read Qy */
wolfSSL 7:481bce714567 4983 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4984 err = mp_read_radix(key->pubkey.y, qy, 16);
wolfSSL 7:481bce714567 4985
wolfSSL 7:481bce714567 4986 if (err == MP_OKAY)
wolfSSL 7:481bce714567 4987 err = mp_set(key->pubkey.z, 1);
wolfSSL 7:481bce714567 4988
wolfSSL 7:481bce714567 4989 /* import private key */
wolfSSL 7:481bce714567 4990 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 4991 if (d != NULL) {
wolfSSL 7:481bce714567 4992 key->type = ECC_PRIVATEKEY;
wolfSSL 7:481bce714567 4993 err = mp_read_radix(&key->k, d, 16);
wolfSSL 7:481bce714567 4994 } else {
wolfSSL 7:481bce714567 4995 key->type = ECC_PUBLICKEY;
wolfSSL 7:481bce714567 4996 }
wolfSSL 7:481bce714567 4997 }
wolfSSL 7:481bce714567 4998
wolfSSL 7:481bce714567 4999 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
wolfSSL 7:481bce714567 5000 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5001 err = wc_ecc_check_key(key);
wolfSSL 7:481bce714567 5002 #endif
wolfSSL 7:481bce714567 5003
wolfSSL 7:481bce714567 5004 if (err != MP_OKAY) {
wolfSSL 7:481bce714567 5005 mp_clear(key->pubkey.x);
wolfSSL 7:481bce714567 5006 mp_clear(key->pubkey.y);
wolfSSL 7:481bce714567 5007 mp_clear(key->pubkey.z);
wolfSSL 7:481bce714567 5008 mp_clear(&key->k);
wolfSSL 7:481bce714567 5009 }
wolfSSL 7:481bce714567 5010 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 5011
wolfSSL 7:481bce714567 5012 return err;
wolfSSL 7:481bce714567 5013 }
wolfSSL 7:481bce714567 5014
wolfSSL 7:481bce714567 5015 /**
wolfSSL 7:481bce714567 5016 Import raw ECC key
wolfSSL 7:481bce714567 5017 key The destination ecc_key structure
wolfSSL 7:481bce714567 5018 qx x component of the public key, as ASCII hex string
wolfSSL 7:481bce714567 5019 qy y component of the public key, as ASCII hex string
wolfSSL 7:481bce714567 5020 d private key, as ASCII hex string, optional if importing public
wolfSSL 7:481bce714567 5021 key only
wolfSSL 7:481bce714567 5022 dp Custom ecc_set_type
wolfSSL 7:481bce714567 5023 return MP_OKAY on success
wolfSSL 7:481bce714567 5024 */
wolfSSL 7:481bce714567 5025 int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
wolfSSL 7:481bce714567 5026 const char* d, int curve_id)
wolfSSL 7:481bce714567 5027 {
wolfSSL 7:481bce714567 5028 return wc_ecc_import_raw_private(key, qx, qy, d, curve_id);
wolfSSL 7:481bce714567 5029
wolfSSL 7:481bce714567 5030 }
wolfSSL 7:481bce714567 5031
wolfSSL 7:481bce714567 5032 /**
wolfSSL 7:481bce714567 5033 Import raw ECC key
wolfSSL 7:481bce714567 5034 key The destination ecc_key structure
wolfSSL 7:481bce714567 5035 qx x component of the public key, as ASCII hex string
wolfSSL 7:481bce714567 5036 qy y component of the public key, as ASCII hex string
wolfSSL 7:481bce714567 5037 d private key, as ASCII hex string, optional if importing public
wolfSSL 7:481bce714567 5038 key only
wolfSSL 7:481bce714567 5039 curveName ECC curve name, from ecc_sets[]
wolfSSL 7:481bce714567 5040 return MP_OKAY on success
wolfSSL 7:481bce714567 5041 */
wolfSSL 7:481bce714567 5042 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
wolfSSL 7:481bce714567 5043 const char* d, const char* curveName)
wolfSSL 7:481bce714567 5044 {
wolfSSL 7:481bce714567 5045 int err, x;
wolfSSL 7:481bce714567 5046
wolfSSL 7:481bce714567 5047 /* if d is NULL, only import as public key using Qx,Qy */
wolfSSL 7:481bce714567 5048 if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
wolfSSL 7:481bce714567 5049 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 5050 }
wolfSSL 7:481bce714567 5051
wolfSSL 7:481bce714567 5052 /* set curve type and index */
wolfSSL 7:481bce714567 5053 for (x = 0; ecc_sets[x].size != 0; x++) {
wolfSSL 7:481bce714567 5054 if (XSTRNCMP(ecc_sets[x].name, curveName,
wolfSSL 7:481bce714567 5055 XSTRLEN(curveName)) == 0) {
wolfSSL 7:481bce714567 5056 break;
wolfSSL 7:481bce714567 5057 }
wolfSSL 7:481bce714567 5058 }
wolfSSL 7:481bce714567 5059
wolfSSL 7:481bce714567 5060 if (ecc_sets[x].size == 0) {
wolfSSL 7:481bce714567 5061 WOLFSSL_MSG("ecc_set curve name not found");
wolfSSL 7:481bce714567 5062 err = ASN_PARSE_E;
wolfSSL 7:481bce714567 5063 } else {
wolfSSL 7:481bce714567 5064 return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id);
wolfSSL 7:481bce714567 5065 }
wolfSSL 7:481bce714567 5066
wolfSSL 7:481bce714567 5067 return err;
wolfSSL 7:481bce714567 5068 }
wolfSSL 7:481bce714567 5069 #endif /* HAVE_ECC_KEY_IMPORT */
wolfSSL 7:481bce714567 5070
wolfSSL 7:481bce714567 5071 /* key size in octets */
wolfSSL 7:481bce714567 5072 int wc_ecc_size(ecc_key* key)
wolfSSL 7:481bce714567 5073 {
wolfSSL 7:481bce714567 5074 if (key == NULL) return 0;
wolfSSL 7:481bce714567 5075
wolfSSL 7:481bce714567 5076 return key->dp->size;
wolfSSL 7:481bce714567 5077 }
wolfSSL 7:481bce714567 5078
wolfSSL 7:481bce714567 5079
wolfSSL 7:481bce714567 5080 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual
wolfSSL 7:481bce714567 5081 value of signature size in octets */
wolfSSL 7:481bce714567 5082 int wc_ecc_sig_size(ecc_key* key)
wolfSSL 7:481bce714567 5083 {
wolfSSL 7:481bce714567 5084 int sz = wc_ecc_size(key);
wolfSSL 7:481bce714567 5085 if (sz <= 0)
wolfSSL 7:481bce714567 5086 return sz;
wolfSSL 7:481bce714567 5087
wolfSSL 7:481bce714567 5088 return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
wolfSSL 7:481bce714567 5089 }
wolfSSL 7:481bce714567 5090
wolfSSL 7:481bce714567 5091
wolfSSL 7:481bce714567 5092 #ifdef FP_ECC
wolfSSL 7:481bce714567 5093
wolfSSL 7:481bce714567 5094 /* fixed point ECC cache */
wolfSSL 7:481bce714567 5095 /* number of entries in the cache */
wolfSSL 7:481bce714567 5096 #ifndef FP_ENTRIES
wolfSSL 7:481bce714567 5097 #define FP_ENTRIES 15
wolfSSL 7:481bce714567 5098 #endif
wolfSSL 7:481bce714567 5099
wolfSSL 7:481bce714567 5100 /* number of bits in LUT */
wolfSSL 7:481bce714567 5101 #ifndef FP_LUT
wolfSSL 7:481bce714567 5102 #define FP_LUT 8U
wolfSSL 7:481bce714567 5103 #endif
wolfSSL 7:481bce714567 5104
wolfSSL 7:481bce714567 5105 #ifdef ECC_SHAMIR
wolfSSL 7:481bce714567 5106 /* Sharmir requires a bigger LUT, TAO */
wolfSSL 7:481bce714567 5107 #if (FP_LUT > 12) || (FP_LUT < 4)
wolfSSL 7:481bce714567 5108 #error FP_LUT must be between 4 and 12 inclusively
wolfSSL 7:481bce714567 5109 #endif
wolfSSL 7:481bce714567 5110 #else
wolfSSL 7:481bce714567 5111 #if (FP_LUT > 12) || (FP_LUT < 2)
wolfSSL 7:481bce714567 5112 #error FP_LUT must be between 2 and 12 inclusively
wolfSSL 7:481bce714567 5113 #endif
wolfSSL 7:481bce714567 5114 #endif
wolfSSL 7:481bce714567 5115
wolfSSL 7:481bce714567 5116
wolfSSL 7:481bce714567 5117 /** Our FP cache */
wolfSSL 7:481bce714567 5118 typedef struct {
wolfSSL 7:481bce714567 5119 ecc_point* g; /* cached COPY of base point */
wolfSSL 7:481bce714567 5120 ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
wolfSSL 7:481bce714567 5121 mp_int mu; /* copy of the montgomery constant */
wolfSSL 7:481bce714567 5122 int lru_count; /* amount of times this entry has been used */
wolfSSL 7:481bce714567 5123 int lock; /* flag to indicate cache eviction */
wolfSSL 7:481bce714567 5124 /* permitted (0) or not (1) */
wolfSSL 7:481bce714567 5125 } fp_cache_t;
wolfSSL 7:481bce714567 5126
wolfSSL 7:481bce714567 5127 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */
wolfSSL 7:481bce714567 5128 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
wolfSSL 7:481bce714567 5129
wolfSSL 7:481bce714567 5130 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 5131 static volatile int initMutex = 0; /* prevent multiple mutex inits */
wolfSSL 7:481bce714567 5132 static wolfSSL_Mutex ecc_fp_lock;
wolfSSL 7:481bce714567 5133 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 5134
wolfSSL 7:481bce714567 5135 /* simple table to help direct the generation of the LUT */
wolfSSL 7:481bce714567 5136 static const struct {
wolfSSL 7:481bce714567 5137 int ham, terma, termb;
wolfSSL 7:481bce714567 5138 } lut_orders[] = {
wolfSSL 7:481bce714567 5139 { 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 7:481bce714567 5140 { 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 7:481bce714567 5141 { 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 7:481bce714567 5142 { 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 7:481bce714567 5143 { 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 7:481bce714567 5144 { 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 7:481bce714567 5145 { 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 7:481bce714567 5146 { 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 7:481bce714567 5147 #if FP_LUT > 6
wolfSSL 7:481bce714567 5148 { 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 7:481bce714567 5149 { 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 7:481bce714567 5150 { 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 7:481bce714567 5151 { 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 7:481bce714567 5152 { 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 7:481bce714567 5153 { 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 7:481bce714567 5154 { 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 7:481bce714567 5155 { 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 7:481bce714567 5156 #if FP_LUT > 7
wolfSSL 7:481bce714567 5157 { 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 7:481bce714567 5158 { 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 7:481bce714567 5159 { 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 7:481bce714567 5160 { 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 7:481bce714567 5161 { 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 7:481bce714567 5162 { 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 7:481bce714567 5163 { 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 7:481bce714567 5164 { 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 7:481bce714567 5165 { 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 7:481bce714567 5166 { 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 7:481bce714567 5167 { 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 7:481bce714567 5168 { 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 7:481bce714567 5169 { 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 7:481bce714567 5170 { 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 7:481bce714567 5171 { 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 7:481bce714567 5172 { 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 7:481bce714567 5173 #if FP_LUT > 8
wolfSSL 7:481bce714567 5174 { 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 7:481bce714567 5175 { 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 7:481bce714567 5176 { 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 7:481bce714567 5177 { 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 7:481bce714567 5178 { 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 7:481bce714567 5179 { 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 7:481bce714567 5180 { 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 7:481bce714567 5181 { 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 7:481bce714567 5182 { 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 7:481bce714567 5183 { 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 7:481bce714567 5184 { 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 7:481bce714567 5185 { 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 7:481bce714567 5186 { 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 7:481bce714567 5187 { 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 7:481bce714567 5188 { 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 7:481bce714567 5189 { 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 7:481bce714567 5190 { 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 7:481bce714567 5191 { 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 7:481bce714567 5192 { 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 7:481bce714567 5193 { 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 7:481bce714567 5194 { 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 7:481bce714567 5195 { 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 7:481bce714567 5196 { 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 7:481bce714567 5197 { 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 7:481bce714567 5198 { 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 7:481bce714567 5199 { 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 7:481bce714567 5200 { 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 7:481bce714567 5201 { 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 7:481bce714567 5202 { 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 7:481bce714567 5203 { 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 7:481bce714567 5204 { 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 7:481bce714567 5205 { 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 7:481bce714567 5206 #if FP_LUT > 9
wolfSSL 7:481bce714567 5207 { 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 7:481bce714567 5208 { 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 7:481bce714567 5209 { 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 7:481bce714567 5210 { 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 7:481bce714567 5211 { 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 7:481bce714567 5212 { 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 7:481bce714567 5213 { 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 7:481bce714567 5214 { 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 7:481bce714567 5215 { 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 7:481bce714567 5216 { 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 7:481bce714567 5217 { 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 7:481bce714567 5218 { 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 7:481bce714567 5219 { 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 7:481bce714567 5220 { 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 7:481bce714567 5221 { 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 7:481bce714567 5222 { 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 7:481bce714567 5223 { 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 7:481bce714567 5224 { 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 7:481bce714567 5225 { 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 7:481bce714567 5226 { 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 7:481bce714567 5227 { 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 7:481bce714567 5228 { 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 7:481bce714567 5229 { 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 7:481bce714567 5230 { 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 7:481bce714567 5231 { 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 7:481bce714567 5232 { 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 7:481bce714567 5233 { 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 7:481bce714567 5234 { 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 7:481bce714567 5235 { 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 7:481bce714567 5236 { 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 7:481bce714567 5237 { 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 7:481bce714567 5238 { 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 7:481bce714567 5239 { 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 7:481bce714567 5240 { 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 7:481bce714567 5241 { 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 7:481bce714567 5242 { 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 7:481bce714567 5243 { 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 7:481bce714567 5244 { 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 7:481bce714567 5245 { 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 7:481bce714567 5246 { 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 7:481bce714567 5247 { 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 7:481bce714567 5248 { 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 7:481bce714567 5249 { 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 7:481bce714567 5250 { 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 7:481bce714567 5251 { 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 7:481bce714567 5252 { 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 7:481bce714567 5253 { 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 7:481bce714567 5254 { 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 7:481bce714567 5255 { 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 7:481bce714567 5256 { 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 7:481bce714567 5257 { 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 7:481bce714567 5258 { 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 7:481bce714567 5259 { 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 7:481bce714567 5260 { 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 7:481bce714567 5261 { 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 7:481bce714567 5262 { 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 7:481bce714567 5263 { 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 7:481bce714567 5264 { 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 7:481bce714567 5265 { 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 7:481bce714567 5266 { 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 7:481bce714567 5267 { 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 7:481bce714567 5268 { 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 7:481bce714567 5269 { 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 7:481bce714567 5270 { 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 7:481bce714567 5271 #if FP_LUT > 10
wolfSSL 7:481bce714567 5272 { 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 7:481bce714567 5273 { 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 7:481bce714567 5274 { 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 7:481bce714567 5275 { 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 7:481bce714567 5276 { 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 7:481bce714567 5277 { 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 7:481bce714567 5278 { 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 7:481bce714567 5279 { 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 7:481bce714567 5280 { 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 7:481bce714567 5281 { 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 7:481bce714567 5282 { 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 7:481bce714567 5283 { 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 7:481bce714567 5284 { 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 7:481bce714567 5285 { 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 7:481bce714567 5286 { 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 7:481bce714567 5287 { 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 7:481bce714567 5288 { 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 7:481bce714567 5289 { 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 7:481bce714567 5290 { 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 7:481bce714567 5291 { 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 7:481bce714567 5292 { 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 7:481bce714567 5293 { 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 7:481bce714567 5294 { 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 7:481bce714567 5295 { 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 7:481bce714567 5296 { 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 7:481bce714567 5297 { 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 7:481bce714567 5298 { 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 7:481bce714567 5299 { 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 7:481bce714567 5300 { 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 7:481bce714567 5301 { 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 7:481bce714567 5302 { 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 7:481bce714567 5303 { 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 7:481bce714567 5304 { 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 7:481bce714567 5305 { 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 7:481bce714567 5306 { 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 7:481bce714567 5307 { 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 7:481bce714567 5308 { 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 7:481bce714567 5309 { 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 7:481bce714567 5310 { 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 7:481bce714567 5311 { 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 7:481bce714567 5312 { 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 7:481bce714567 5313 { 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 7:481bce714567 5314 { 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 7:481bce714567 5315 { 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 7:481bce714567 5316 { 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 7:481bce714567 5317 { 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 7:481bce714567 5318 { 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 7:481bce714567 5319 { 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 7:481bce714567 5320 { 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 7:481bce714567 5321 { 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 7:481bce714567 5322 { 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 7:481bce714567 5323 { 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 7:481bce714567 5324 { 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 7:481bce714567 5325 { 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 7:481bce714567 5326 { 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 7:481bce714567 5327 { 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 7:481bce714567 5328 { 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 7:481bce714567 5329 { 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 7:481bce714567 5330 { 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 7:481bce714567 5331 { 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 7:481bce714567 5332 { 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 7:481bce714567 5333 { 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 7:481bce714567 5334 { 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 7:481bce714567 5335 { 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 7:481bce714567 5336 { 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 7:481bce714567 5337 { 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 7:481bce714567 5338 { 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 7:481bce714567 5339 { 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 7:481bce714567 5340 { 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 7:481bce714567 5341 { 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 7:481bce714567 5342 { 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 7:481bce714567 5343 { 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 7:481bce714567 5344 { 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 7:481bce714567 5345 { 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 7:481bce714567 5346 { 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 7:481bce714567 5347 { 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 7:481bce714567 5348 { 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 7:481bce714567 5349 { 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 7:481bce714567 5350 { 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 7:481bce714567 5351 { 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 7:481bce714567 5352 { 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 7:481bce714567 5353 { 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 7:481bce714567 5354 { 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 7:481bce714567 5355 { 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 7:481bce714567 5356 { 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 7:481bce714567 5357 { 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 7:481bce714567 5358 { 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 7:481bce714567 5359 { 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 7:481bce714567 5360 { 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 7:481bce714567 5361 { 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 7:481bce714567 5362 { 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 7:481bce714567 5363 { 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 7:481bce714567 5364 { 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 7:481bce714567 5365 { 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 7:481bce714567 5366 { 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 7:481bce714567 5367 { 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 7:481bce714567 5368 { 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 7:481bce714567 5369 { 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 7:481bce714567 5370 { 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 7:481bce714567 5371 { 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 7:481bce714567 5372 { 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 7:481bce714567 5373 { 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 7:481bce714567 5374 { 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 7:481bce714567 5375 { 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 7:481bce714567 5376 { 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 7:481bce714567 5377 { 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 7:481bce714567 5378 { 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 7:481bce714567 5379 { 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 7:481bce714567 5380 { 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 7:481bce714567 5381 { 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 7:481bce714567 5382 { 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 7:481bce714567 5383 { 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 7:481bce714567 5384 { 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 7:481bce714567 5385 { 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 7:481bce714567 5386 { 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 7:481bce714567 5387 { 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 7:481bce714567 5388 { 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 7:481bce714567 5389 { 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 7:481bce714567 5390 { 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 7:481bce714567 5391 { 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 7:481bce714567 5392 { 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 7:481bce714567 5393 { 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 7:481bce714567 5394 { 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 7:481bce714567 5395 { 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 7:481bce714567 5396 { 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 7:481bce714567 5397 { 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 7:481bce714567 5398 { 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 7:481bce714567 5399 { 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 7:481bce714567 5400 #if FP_LUT > 11
wolfSSL 7:481bce714567 5401 { 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 7:481bce714567 5402 { 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 7:481bce714567 5403 { 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 7:481bce714567 5404 { 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 7:481bce714567 5405 { 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 7:481bce714567 5406 { 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 7:481bce714567 5407 { 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 7:481bce714567 5408 { 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 7:481bce714567 5409 { 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 7:481bce714567 5410 { 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 7:481bce714567 5411 { 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 7:481bce714567 5412 { 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 7:481bce714567 5413 { 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 7:481bce714567 5414 { 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 7:481bce714567 5415 { 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 7:481bce714567 5416 { 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 7:481bce714567 5417 { 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 7:481bce714567 5418 { 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 7:481bce714567 5419 { 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 7:481bce714567 5420 { 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 7:481bce714567 5421 { 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 7:481bce714567 5422 { 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 7:481bce714567 5423 { 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 7:481bce714567 5424 { 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 7:481bce714567 5425 { 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 7:481bce714567 5426 { 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 7:481bce714567 5427 { 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 7:481bce714567 5428 { 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 7:481bce714567 5429 { 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 7:481bce714567 5430 { 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 7:481bce714567 5431 { 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 7:481bce714567 5432 { 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 7:481bce714567 5433 { 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 7:481bce714567 5434 { 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 7:481bce714567 5435 { 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 7:481bce714567 5436 { 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 7:481bce714567 5437 { 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 7:481bce714567 5438 { 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 7:481bce714567 5439 { 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 7:481bce714567 5440 { 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 7:481bce714567 5441 { 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 7:481bce714567 5442 { 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 7:481bce714567 5443 { 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 7:481bce714567 5444 { 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 7:481bce714567 5445 { 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 7:481bce714567 5446 { 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 7:481bce714567 5447 { 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 7:481bce714567 5448 { 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 7:481bce714567 5449 { 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 7:481bce714567 5450 { 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 7:481bce714567 5451 { 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 7:481bce714567 5452 { 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 7:481bce714567 5453 { 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 7:481bce714567 5454 { 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 7:481bce714567 5455 { 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 7:481bce714567 5456 { 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 7:481bce714567 5457 { 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 7:481bce714567 5458 { 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 7:481bce714567 5459 { 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 7:481bce714567 5460 { 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 7:481bce714567 5461 { 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 7:481bce714567 5462 { 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 7:481bce714567 5463 { 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 7:481bce714567 5464 { 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 7:481bce714567 5465 { 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 7:481bce714567 5466 { 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 7:481bce714567 5467 { 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 7:481bce714567 5468 { 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 7:481bce714567 5469 { 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 7:481bce714567 5470 { 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 7:481bce714567 5471 { 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 7:481bce714567 5472 { 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 7:481bce714567 5473 { 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 7:481bce714567 5474 { 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 7:481bce714567 5475 { 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 7:481bce714567 5476 { 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 7:481bce714567 5477 { 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 7:481bce714567 5478 { 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 7:481bce714567 5479 { 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 7:481bce714567 5480 { 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 7:481bce714567 5481 { 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 7:481bce714567 5482 { 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 7:481bce714567 5483 { 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 7:481bce714567 5484 { 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 7:481bce714567 5485 { 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 7:481bce714567 5486 { 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 7:481bce714567 5487 { 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 7:481bce714567 5488 { 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 7:481bce714567 5489 { 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 7:481bce714567 5490 { 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 7:481bce714567 5491 { 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 7:481bce714567 5492 { 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 7:481bce714567 5493 { 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 7:481bce714567 5494 { 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 7:481bce714567 5495 { 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 7:481bce714567 5496 { 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 7:481bce714567 5497 { 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 7:481bce714567 5498 { 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 7:481bce714567 5499 { 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 7:481bce714567 5500 { 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 7:481bce714567 5501 { 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 7:481bce714567 5502 { 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 7:481bce714567 5503 { 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 7:481bce714567 5504 { 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 7:481bce714567 5505 { 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 7:481bce714567 5506 { 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 7:481bce714567 5507 { 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 7:481bce714567 5508 { 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 7:481bce714567 5509 { 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 7:481bce714567 5510 { 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 7:481bce714567 5511 { 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 7:481bce714567 5512 { 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 7:481bce714567 5513 { 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 7:481bce714567 5514 { 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 7:481bce714567 5515 { 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 7:481bce714567 5516 { 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 7:481bce714567 5517 { 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 7:481bce714567 5518 { 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 7:481bce714567 5519 { 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 7:481bce714567 5520 { 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 7:481bce714567 5521 { 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 7:481bce714567 5522 { 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 7:481bce714567 5523 { 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 7:481bce714567 5524 { 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 7:481bce714567 5525 { 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 7:481bce714567 5526 { 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 7:481bce714567 5527 { 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 7:481bce714567 5528 { 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 7:481bce714567 5529 { 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 7:481bce714567 5530 { 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 7:481bce714567 5531 { 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 7:481bce714567 5532 { 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 7:481bce714567 5533 { 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 7:481bce714567 5534 { 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 7:481bce714567 5535 { 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 7:481bce714567 5536 { 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 7:481bce714567 5537 { 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 7:481bce714567 5538 { 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 7:481bce714567 5539 { 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 7:481bce714567 5540 { 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 7:481bce714567 5541 { 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 7:481bce714567 5542 { 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 7:481bce714567 5543 { 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 7:481bce714567 5544 { 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 7:481bce714567 5545 { 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 7:481bce714567 5546 { 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 7:481bce714567 5547 { 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 7:481bce714567 5548 { 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 7:481bce714567 5549 { 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 7:481bce714567 5550 { 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 7:481bce714567 5551 { 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 7:481bce714567 5552 { 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 7:481bce714567 5553 { 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 7:481bce714567 5554 { 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 7:481bce714567 5555 { 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 7:481bce714567 5556 { 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 7:481bce714567 5557 { 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 7:481bce714567 5558 { 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 7:481bce714567 5559 { 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 7:481bce714567 5560 { 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 7:481bce714567 5561 { 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 7:481bce714567 5562 { 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 7:481bce714567 5563 { 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 7:481bce714567 5564 { 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 7:481bce714567 5565 { 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 7:481bce714567 5566 { 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 7:481bce714567 5567 { 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 7:481bce714567 5568 { 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 7:481bce714567 5569 { 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 7:481bce714567 5570 { 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 7:481bce714567 5571 { 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 7:481bce714567 5572 { 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 7:481bce714567 5573 { 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 7:481bce714567 5574 { 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 7:481bce714567 5575 { 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 7:481bce714567 5576 { 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 7:481bce714567 5577 { 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 7:481bce714567 5578 { 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 7:481bce714567 5579 { 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 7:481bce714567 5580 { 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 7:481bce714567 5581 { 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 7:481bce714567 5582 { 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 7:481bce714567 5583 { 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 7:481bce714567 5584 { 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 7:481bce714567 5585 { 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 7:481bce714567 5586 { 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 7:481bce714567 5587 { 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 7:481bce714567 5588 { 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 7:481bce714567 5589 { 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 7:481bce714567 5590 { 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 7:481bce714567 5591 { 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 7:481bce714567 5592 { 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 7:481bce714567 5593 { 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 7:481bce714567 5594 { 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 7:481bce714567 5595 { 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 7:481bce714567 5596 { 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 7:481bce714567 5597 { 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 7:481bce714567 5598 { 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 7:481bce714567 5599 { 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 7:481bce714567 5600 { 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 7:481bce714567 5601 { 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 7:481bce714567 5602 { 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 7:481bce714567 5603 { 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 7:481bce714567 5604 { 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 7:481bce714567 5605 { 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 7:481bce714567 5606 { 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 7:481bce714567 5607 { 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 7:481bce714567 5608 { 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 7:481bce714567 5609 { 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 7:481bce714567 5610 { 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 7:481bce714567 5611 { 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 7:481bce714567 5612 { 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 7:481bce714567 5613 { 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 7:481bce714567 5614 { 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 7:481bce714567 5615 { 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 7:481bce714567 5616 { 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 7:481bce714567 5617 { 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 7:481bce714567 5618 { 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 7:481bce714567 5619 { 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 7:481bce714567 5620 { 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 7:481bce714567 5621 { 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 7:481bce714567 5622 { 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 7:481bce714567 5623 { 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 7:481bce714567 5624 { 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 7:481bce714567 5625 { 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 7:481bce714567 5626 { 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 7:481bce714567 5627 { 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 7:481bce714567 5628 { 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 7:481bce714567 5629 { 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 7:481bce714567 5630 { 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 7:481bce714567 5631 { 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 7:481bce714567 5632 { 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 7:481bce714567 5633 { 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 7:481bce714567 5634 { 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 7:481bce714567 5635 { 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 7:481bce714567 5636 { 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 7:481bce714567 5637 { 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 7:481bce714567 5638 { 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 7:481bce714567 5639 { 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 7:481bce714567 5640 { 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 7:481bce714567 5641 { 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 7:481bce714567 5642 { 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 7:481bce714567 5643 { 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 7:481bce714567 5644 { 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 7:481bce714567 5645 { 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 7:481bce714567 5646 { 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 7:481bce714567 5647 { 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 7:481bce714567 5648 { 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 7:481bce714567 5649 { 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 7:481bce714567 5650 { 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 7:481bce714567 5651 { 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 7:481bce714567 5652 { 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 7:481bce714567 5653 { 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 7:481bce714567 5654 { 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 7:481bce714567 5655 { 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 7:481bce714567 5656 { 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 7:481bce714567 5657 #endif
wolfSSL 7:481bce714567 5658 #endif
wolfSSL 7:481bce714567 5659 #endif
wolfSSL 7:481bce714567 5660 #endif
wolfSSL 7:481bce714567 5661 #endif
wolfSSL 7:481bce714567 5662 #endif
wolfSSL 7:481bce714567 5663 };
wolfSSL 7:481bce714567 5664
wolfSSL 7:481bce714567 5665 /* find a hole and free as required, return -1 if no hole found */
wolfSSL 7:481bce714567 5666 static int find_hole(void)
wolfSSL 7:481bce714567 5667 {
wolfSSL 7:481bce714567 5668 unsigned x;
wolfSSL 7:481bce714567 5669 int y, z;
wolfSSL 7:481bce714567 5670 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
wolfSSL 7:481bce714567 5671 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
wolfSSL 7:481bce714567 5672 z = x;
wolfSSL 7:481bce714567 5673 y = fp_cache[x].lru_count;
wolfSSL 7:481bce714567 5674 }
wolfSSL 7:481bce714567 5675 }
wolfSSL 7:481bce714567 5676
wolfSSL 7:481bce714567 5677 /* decrease all */
wolfSSL 7:481bce714567 5678 for (x = 0; x < FP_ENTRIES; x++) {
wolfSSL 7:481bce714567 5679 if (fp_cache[x].lru_count > 3) {
wolfSSL 7:481bce714567 5680 --(fp_cache[x].lru_count);
wolfSSL 7:481bce714567 5681 }
wolfSSL 7:481bce714567 5682 }
wolfSSL 7:481bce714567 5683
wolfSSL 7:481bce714567 5684 /* free entry z */
wolfSSL 7:481bce714567 5685 if (z >= 0 && fp_cache[z].g) {
wolfSSL 7:481bce714567 5686 mp_clear(&fp_cache[z].mu);
wolfSSL 7:481bce714567 5687 wc_ecc_del_point(fp_cache[z].g);
wolfSSL 7:481bce714567 5688 fp_cache[z].g = NULL;
wolfSSL 7:481bce714567 5689 for (x = 0; x < (1U<<FP_LUT); x++) {
wolfSSL 7:481bce714567 5690 wc_ecc_del_point(fp_cache[z].LUT[x]);
wolfSSL 7:481bce714567 5691 fp_cache[z].LUT[x] = NULL;
wolfSSL 7:481bce714567 5692 }
wolfSSL 7:481bce714567 5693 fp_cache[z].lru_count = 0;
wolfSSL 7:481bce714567 5694 }
wolfSSL 7:481bce714567 5695 return z;
wolfSSL 7:481bce714567 5696 }
wolfSSL 7:481bce714567 5697
wolfSSL 7:481bce714567 5698 /* determine if a base is already in the cache and if so, where */
wolfSSL 7:481bce714567 5699 static int find_base(ecc_point* g)
wolfSSL 7:481bce714567 5700 {
wolfSSL 7:481bce714567 5701 int x;
wolfSSL 7:481bce714567 5702 for (x = 0; x < FP_ENTRIES; x++) {
wolfSSL 7:481bce714567 5703 if (fp_cache[x].g != NULL &&
wolfSSL 7:481bce714567 5704 mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
wolfSSL 7:481bce714567 5705 mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
wolfSSL 7:481bce714567 5706 mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
wolfSSL 7:481bce714567 5707 break;
wolfSSL 7:481bce714567 5708 }
wolfSSL 7:481bce714567 5709 }
wolfSSL 7:481bce714567 5710 if (x == FP_ENTRIES) {
wolfSSL 7:481bce714567 5711 x = -1;
wolfSSL 7:481bce714567 5712 }
wolfSSL 7:481bce714567 5713 return x;
wolfSSL 7:481bce714567 5714 }
wolfSSL 7:481bce714567 5715
wolfSSL 7:481bce714567 5716 /* add a new base to the cache */
wolfSSL 7:481bce714567 5717 static int add_entry(int idx, ecc_point *g)
wolfSSL 7:481bce714567 5718 {
wolfSSL 7:481bce714567 5719 unsigned x, y;
wolfSSL 7:481bce714567 5720
wolfSSL 7:481bce714567 5721 /* allocate base and LUT */
wolfSSL 7:481bce714567 5722 fp_cache[idx].g = wc_ecc_new_point();
wolfSSL 7:481bce714567 5723 if (fp_cache[idx].g == NULL) {
wolfSSL 7:481bce714567 5724 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 5725 }
wolfSSL 7:481bce714567 5726
wolfSSL 7:481bce714567 5727 /* copy x and y */
wolfSSL 7:481bce714567 5728 if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 5729 (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 5730 (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
wolfSSL 7:481bce714567 5731 wc_ecc_del_point(fp_cache[idx].g);
wolfSSL 7:481bce714567 5732 fp_cache[idx].g = NULL;
wolfSSL 7:481bce714567 5733 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 5734 }
wolfSSL 7:481bce714567 5735
wolfSSL 7:481bce714567 5736 for (x = 0; x < (1U<<FP_LUT); x++) {
wolfSSL 7:481bce714567 5737 fp_cache[idx].LUT[x] = wc_ecc_new_point();
wolfSSL 7:481bce714567 5738 if (fp_cache[idx].LUT[x] == NULL) {
wolfSSL 7:481bce714567 5739 for (y = 0; y < x; y++) {
wolfSSL 7:481bce714567 5740 wc_ecc_del_point(fp_cache[idx].LUT[y]);
wolfSSL 7:481bce714567 5741 fp_cache[idx].LUT[y] = NULL;
wolfSSL 7:481bce714567 5742 }
wolfSSL 7:481bce714567 5743 wc_ecc_del_point(fp_cache[idx].g);
wolfSSL 7:481bce714567 5744 fp_cache[idx].g = NULL;
wolfSSL 7:481bce714567 5745 fp_cache[idx].lru_count = 0;
wolfSSL 7:481bce714567 5746 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 5747 }
wolfSSL 7:481bce714567 5748 }
wolfSSL 7:481bce714567 5749
wolfSSL 7:481bce714567 5750 fp_cache[idx].lru_count = 0;
wolfSSL 7:481bce714567 5751
wolfSSL 7:481bce714567 5752 return MP_OKAY;
wolfSSL 7:481bce714567 5753 }
wolfSSL 7:481bce714567 5754
wolfSSL 7:481bce714567 5755 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
wolfSSL 7:481bce714567 5756 *
wolfSSL 7:481bce714567 5757 * The algorithm builds patterns in increasing bit order by first making all
wolfSSL 7:481bce714567 5758 * single bit input patterns, then all two bit input patterns and so on
wolfSSL 7:481bce714567 5759 */
wolfSSL 7:481bce714567 5760 static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
wolfSSL 7:481bce714567 5761 mp_int* mu)
wolfSSL 7:481bce714567 5762 {
wolfSSL 7:481bce714567 5763 int err;
wolfSSL 7:481bce714567 5764 unsigned x, y, bitlen, lut_gap;
wolfSSL 7:481bce714567 5765 mp_int tmp;
wolfSSL 7:481bce714567 5766
wolfSSL 7:481bce714567 5767 if (mp_init(&tmp) != MP_OKAY)
wolfSSL 7:481bce714567 5768 return GEN_MEM_ERR;
wolfSSL 7:481bce714567 5769
wolfSSL 7:481bce714567 5770 /* sanity check to make sure lut_order table is of correct size,
wolfSSL 7:481bce714567 5771 should compile out to a NOP if true */
wolfSSL 7:481bce714567 5772 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
wolfSSL 7:481bce714567 5773 err = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 5774 }
wolfSSL 7:481bce714567 5775 else {
wolfSSL 7:481bce714567 5776 /* get bitlen and round up to next multiple of FP_LUT */
wolfSSL 7:481bce714567 5777 bitlen = mp_unsigned_bin_size(modulus) << 3;
wolfSSL 7:481bce714567 5778 x = bitlen % FP_LUT;
wolfSSL 7:481bce714567 5779 if (x) {
wolfSSL 7:481bce714567 5780 bitlen += FP_LUT - x;
wolfSSL 7:481bce714567 5781 }
wolfSSL 7:481bce714567 5782 lut_gap = bitlen / FP_LUT;
wolfSSL 7:481bce714567 5783
wolfSSL 7:481bce714567 5784 /* init the mu */
wolfSSL 7:481bce714567 5785 err = mp_init_copy(&fp_cache[idx].mu, mu);
wolfSSL 7:481bce714567 5786 }
wolfSSL 7:481bce714567 5787
wolfSSL 7:481bce714567 5788 /* copy base */
wolfSSL 7:481bce714567 5789 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 5790 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
wolfSSL 7:481bce714567 5791 fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 5792 (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
wolfSSL 7:481bce714567 5793 fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 5794 (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
wolfSSL 7:481bce714567 5795 fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
wolfSSL 7:481bce714567 5796 err = MP_MULMOD_E;
wolfSSL 7:481bce714567 5797 }
wolfSSL 7:481bce714567 5798 }
wolfSSL 7:481bce714567 5799
wolfSSL 7:481bce714567 5800 /* make all single bit entries */
wolfSSL 7:481bce714567 5801 for (x = 1; x < FP_LUT; x++) {
wolfSSL 7:481bce714567 5802 if (err != MP_OKAY)
wolfSSL 7:481bce714567 5803 break;
wolfSSL 7:481bce714567 5804 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
wolfSSL 7:481bce714567 5805 fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 5806 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
wolfSSL 7:481bce714567 5807 fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 5808 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
wolfSSL 7:481bce714567 5809 fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
wolfSSL 7:481bce714567 5810 err = MP_INIT_E;
wolfSSL 7:481bce714567 5811 break;
wolfSSL 7:481bce714567 5812 } else {
wolfSSL 7:481bce714567 5813
wolfSSL 7:481bce714567 5814 /* now double it bitlen/FP_LUT times */
wolfSSL 7:481bce714567 5815 for (y = 0; y < lut_gap; y++) {
wolfSSL 7:481bce714567 5816 if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
wolfSSL 7:481bce714567 5817 fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 5818 break;
wolfSSL 7:481bce714567 5819 }
wolfSSL 7:481bce714567 5820 }
wolfSSL 7:481bce714567 5821 }
wolfSSL 7:481bce714567 5822 }
wolfSSL 7:481bce714567 5823
wolfSSL 7:481bce714567 5824 /* now make all entries in increase order of hamming weight */
wolfSSL 7:481bce714567 5825 for (x = 2; x <= FP_LUT; x++) {
wolfSSL 7:481bce714567 5826 if (err != MP_OKAY)
wolfSSL 7:481bce714567 5827 break;
wolfSSL 7:481bce714567 5828 for (y = 0; y < (1UL<<FP_LUT); y++) {
wolfSSL 7:481bce714567 5829 if (err != MP_OKAY)
wolfSSL 7:481bce714567 5830 break;
wolfSSL 7:481bce714567 5831 if (lut_orders[y].ham != (int)x) continue;
wolfSSL 7:481bce714567 5832
wolfSSL 7:481bce714567 5833 /* perform the add */
wolfSSL 7:481bce714567 5834 if ((err = ecc_projective_add_point(
wolfSSL 7:481bce714567 5835 fp_cache[idx].LUT[lut_orders[y].terma],
wolfSSL 7:481bce714567 5836 fp_cache[idx].LUT[lut_orders[y].termb],
wolfSSL 7:481bce714567 5837 fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 5838 break;
wolfSSL 7:481bce714567 5839 }
wolfSSL 7:481bce714567 5840 }
wolfSSL 7:481bce714567 5841 }
wolfSSL 7:481bce714567 5842
wolfSSL 7:481bce714567 5843 /* now map all entries back to affine space to make point addition faster */
wolfSSL 7:481bce714567 5844 for (x = 1; x < (1UL<<FP_LUT); x++) {
wolfSSL 7:481bce714567 5845 if (err != MP_OKAY)
wolfSSL 7:481bce714567 5846 break;
wolfSSL 7:481bce714567 5847
wolfSSL 7:481bce714567 5848 /* convert z to normal from montgomery */
wolfSSL 7:481bce714567 5849 err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
wolfSSL 7:481bce714567 5850
wolfSSL 7:481bce714567 5851 /* invert it */
wolfSSL 7:481bce714567 5852 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5853 err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
wolfSSL 7:481bce714567 5854 fp_cache[idx].LUT[x]->z);
wolfSSL 7:481bce714567 5855
wolfSSL 7:481bce714567 5856 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5857 /* now square it */
wolfSSL 7:481bce714567 5858 err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);
wolfSSL 7:481bce714567 5859
wolfSSL 7:481bce714567 5860 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5861 /* fix x */
wolfSSL 7:481bce714567 5862 err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,
wolfSSL 7:481bce714567 5863 fp_cache[idx].LUT[x]->x);
wolfSSL 7:481bce714567 5864
wolfSSL 7:481bce714567 5865 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5866 /* get 1/z^3 */
wolfSSL 7:481bce714567 5867 err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);
wolfSSL 7:481bce714567 5868
wolfSSL 7:481bce714567 5869 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5870 /* fix y */
wolfSSL 7:481bce714567 5871 err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,
wolfSSL 7:481bce714567 5872 fp_cache[idx].LUT[x]->y);
wolfSSL 7:481bce714567 5873
wolfSSL 7:481bce714567 5874 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5875 /* free z */
wolfSSL 7:481bce714567 5876 mp_clear(fp_cache[idx].LUT[x]->z);
wolfSSL 7:481bce714567 5877 }
wolfSSL 7:481bce714567 5878
wolfSSL 7:481bce714567 5879 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 5880 mp_clear(&tmp);
wolfSSL 7:481bce714567 5881 #endif
wolfSSL 7:481bce714567 5882
wolfSSL 7:481bce714567 5883 if (err == MP_OKAY)
wolfSSL 7:481bce714567 5884 return MP_OKAY;
wolfSSL 7:481bce714567 5885
wolfSSL 7:481bce714567 5886 /* err cleanup */
wolfSSL 7:481bce714567 5887 for (y = 0; y < (1U<<FP_LUT); y++) {
wolfSSL 7:481bce714567 5888 wc_ecc_del_point(fp_cache[idx].LUT[y]);
wolfSSL 7:481bce714567 5889 fp_cache[idx].LUT[y] = NULL;
wolfSSL 7:481bce714567 5890 }
wolfSSL 7:481bce714567 5891 wc_ecc_del_point(fp_cache[idx].g);
wolfSSL 7:481bce714567 5892 fp_cache[idx].g = NULL;
wolfSSL 7:481bce714567 5893 fp_cache[idx].lru_count = 0;
wolfSSL 7:481bce714567 5894 mp_clear(&fp_cache[idx].mu);
wolfSSL 7:481bce714567 5895
wolfSSL 7:481bce714567 5896 return err;
wolfSSL 7:481bce714567 5897 }
wolfSSL 7:481bce714567 5898
wolfSSL 7:481bce714567 5899 /* perform a fixed point ECC mulmod */
wolfSSL 7:481bce714567 5900 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
wolfSSL 7:481bce714567 5901 mp_int* modulus, mp_digit mp, int map)
wolfSSL 7:481bce714567 5902 {
wolfSSL 7:481bce714567 5903 #define KB_SIZE 128
wolfSSL 7:481bce714567 5904
wolfSSL 7:481bce714567 5905 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 5906 unsigned char* kb = NULL;
wolfSSL 7:481bce714567 5907 #else
wolfSSL 7:481bce714567 5908 unsigned char kb[KB_SIZE];
wolfSSL 7:481bce714567 5909 #endif
wolfSSL 7:481bce714567 5910 int x, err;
wolfSSL 7:481bce714567 5911 unsigned y, z = 0, bitlen, bitpos, lut_gap, first;
wolfSSL 7:481bce714567 5912 mp_int tk, order;
wolfSSL 7:481bce714567 5913
wolfSSL 7:481bce714567 5914 if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 7:481bce714567 5915 return MP_INIT_E;
wolfSSL 7:481bce714567 5916
wolfSSL 7:481bce714567 5917 /* if it's smaller than modulus we fine */
wolfSSL 7:481bce714567 5918 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
wolfSSL 7:481bce714567 5919 /* find order */
wolfSSL 7:481bce714567 5920 y = mp_unsigned_bin_size(modulus);
wolfSSL 7:481bce714567 5921 for (x = 0; ecc_sets[x].size; x++) {
wolfSSL 7:481bce714567 5922 if (y <= (unsigned)ecc_sets[x].size) break;
wolfSSL 7:481bce714567 5923 }
wolfSSL 7:481bce714567 5924
wolfSSL 7:481bce714567 5925 /* back off if we are on the 521 bit curve */
wolfSSL 7:481bce714567 5926 if (y == 66) --x;
wolfSSL 7:481bce714567 5927
wolfSSL 7:481bce714567 5928 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
wolfSSL 7:481bce714567 5929 goto done;
wolfSSL 7:481bce714567 5930 }
wolfSSL 7:481bce714567 5931
wolfSSL 7:481bce714567 5932 /* k must be less than modulus */
wolfSSL 7:481bce714567 5933 if (mp_cmp(k, &order) != MP_LT) {
wolfSSL 7:481bce714567 5934 if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
wolfSSL 7:481bce714567 5935 goto done;
wolfSSL 7:481bce714567 5936 }
wolfSSL 7:481bce714567 5937 } else {
wolfSSL 7:481bce714567 5938 if ((err = mp_copy(k, &tk)) != MP_OKAY) {
wolfSSL 7:481bce714567 5939 goto done;
wolfSSL 7:481bce714567 5940 }
wolfSSL 7:481bce714567 5941 }
wolfSSL 7:481bce714567 5942 } else {
wolfSSL 7:481bce714567 5943 if ((err = mp_copy(k, &tk)) != MP_OKAY) {
wolfSSL 7:481bce714567 5944 goto done;
wolfSSL 7:481bce714567 5945 }
wolfSSL 7:481bce714567 5946 }
wolfSSL 7:481bce714567 5947
wolfSSL 7:481bce714567 5948 /* get bitlen and round up to next multiple of FP_LUT */
wolfSSL 7:481bce714567 5949 bitlen = mp_unsigned_bin_size(modulus) << 3;
wolfSSL 7:481bce714567 5950 x = bitlen % FP_LUT;
wolfSSL 7:481bce714567 5951 if (x) {
wolfSSL 7:481bce714567 5952 bitlen += FP_LUT - x;
wolfSSL 7:481bce714567 5953 }
wolfSSL 7:481bce714567 5954 lut_gap = bitlen / FP_LUT;
wolfSSL 7:481bce714567 5955
wolfSSL 7:481bce714567 5956 /* get the k value */
wolfSSL 7:481bce714567 5957 if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
wolfSSL 7:481bce714567 5958 err = BUFFER_E; goto done;
wolfSSL 7:481bce714567 5959 }
wolfSSL 7:481bce714567 5960
wolfSSL 7:481bce714567 5961 /* store k */
wolfSSL 7:481bce714567 5962 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 5963 kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 5964 if (kb == NULL) {
wolfSSL 7:481bce714567 5965 err = MEMORY_E; goto done;
wolfSSL 7:481bce714567 5966 }
wolfSSL 7:481bce714567 5967 #endif
wolfSSL 7:481bce714567 5968
wolfSSL 7:481bce714567 5969 XMEMSET(kb, 0, KB_SIZE);
wolfSSL 7:481bce714567 5970 if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
wolfSSL 7:481bce714567 5971 /* let's reverse kb so it's little endian */
wolfSSL 7:481bce714567 5972 x = 0;
wolfSSL 7:481bce714567 5973 y = mp_unsigned_bin_size(&tk);
wolfSSL 7:481bce714567 5974 if (y > 0) {
wolfSSL 7:481bce714567 5975 y -= 1;
wolfSSL 7:481bce714567 5976 }
wolfSSL 7:481bce714567 5977
wolfSSL 7:481bce714567 5978 while ((unsigned)x < y) {
wolfSSL 7:481bce714567 5979 z = kb[x]; kb[x] = kb[y]; kb[y] = z;
wolfSSL 7:481bce714567 5980 ++x; --y;
wolfSSL 7:481bce714567 5981 }
wolfSSL 7:481bce714567 5982
wolfSSL 7:481bce714567 5983 /* at this point we can start, yipee */
wolfSSL 7:481bce714567 5984 first = 1;
wolfSSL 7:481bce714567 5985 for (x = lut_gap-1; x >= 0; x--) {
wolfSSL 7:481bce714567 5986 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
wolfSSL 7:481bce714567 5987 by x bits from the start */
wolfSSL 7:481bce714567 5988 bitpos = x;
wolfSSL 7:481bce714567 5989 for (y = z = 0; y < FP_LUT; y++) {
wolfSSL 7:481bce714567 5990 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
wolfSSL 7:481bce714567 5991 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid
wolfSSL 7:481bce714567 5992 the mult in each loop */
wolfSSL 7:481bce714567 5993 }
wolfSSL 7:481bce714567 5994
wolfSSL 7:481bce714567 5995 /* double if not first */
wolfSSL 7:481bce714567 5996 if (!first) {
wolfSSL 7:481bce714567 5997 if ((err = ecc_projective_dbl_point(R, R, a, modulus,
wolfSSL 7:481bce714567 5998 mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 5999 break;
wolfSSL 7:481bce714567 6000 }
wolfSSL 7:481bce714567 6001 }
wolfSSL 7:481bce714567 6002
wolfSSL 7:481bce714567 6003 /* add if not first, otherwise copy */
wolfSSL 7:481bce714567 6004 if (!first && z) {
wolfSSL 7:481bce714567 6005 if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
wolfSSL 7:481bce714567 6006 a, modulus, mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 6007 break;
wolfSSL 7:481bce714567 6008 }
wolfSSL 7:481bce714567 6009 } else if (z) {
wolfSSL 7:481bce714567 6010 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 6011 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 6012 (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) {
wolfSSL 7:481bce714567 6013 err = GEN_MEM_ERR;
wolfSSL 7:481bce714567 6014 break;
wolfSSL 7:481bce714567 6015 }
wolfSSL 7:481bce714567 6016 first = 0;
wolfSSL 7:481bce714567 6017 }
wolfSSL 7:481bce714567 6018 }
wolfSSL 7:481bce714567 6019 }
wolfSSL 7:481bce714567 6020
wolfSSL 7:481bce714567 6021 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6022 (void) z; /* Acknowledge the unused assignment */
wolfSSL 7:481bce714567 6023 ForceZero(kb, KB_SIZE);
wolfSSL 7:481bce714567 6024
wolfSSL 7:481bce714567 6025 /* map R back from projective space */
wolfSSL 7:481bce714567 6026 if (map) {
wolfSSL 7:481bce714567 6027 err = ecc_map(R, modulus, mp);
wolfSSL 7:481bce714567 6028 } else {
wolfSSL 7:481bce714567 6029 err = MP_OKAY;
wolfSSL 7:481bce714567 6030 }
wolfSSL 7:481bce714567 6031 }
wolfSSL 7:481bce714567 6032
wolfSSL 7:481bce714567 6033 done:
wolfSSL 7:481bce714567 6034 /* cleanup */
wolfSSL 7:481bce714567 6035 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 6036 mp_clear(&order);
wolfSSL 7:481bce714567 6037 mp_clear(&tk);
wolfSSL 7:481bce714567 6038 #endif
wolfSSL 7:481bce714567 6039
wolfSSL 7:481bce714567 6040 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6041 XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6042 #endif
wolfSSL 7:481bce714567 6043
wolfSSL 7:481bce714567 6044 #undef KB_SIZE
wolfSSL 7:481bce714567 6045
wolfSSL 7:481bce714567 6046 return err;
wolfSSL 7:481bce714567 6047 }
wolfSSL 7:481bce714567 6048
wolfSSL 7:481bce714567 6049 #ifdef ECC_SHAMIR
wolfSSL 7:481bce714567 6050 /* perform a fixed point ECC mulmod */
wolfSSL 7:481bce714567 6051 static int accel_fp_mul2add(int idx1, int idx2,
wolfSSL 7:481bce714567 6052 mp_int* kA, mp_int* kB,
wolfSSL 7:481bce714567 6053 ecc_point *R, mp_int* a,
wolfSSL 7:481bce714567 6054 mp_int* modulus, mp_digit mp)
wolfSSL 7:481bce714567 6055 {
wolfSSL 7:481bce714567 6056 #define KB_SIZE 128
wolfSSL 7:481bce714567 6057
wolfSSL 7:481bce714567 6058 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6059 unsigned char* kb[2] = {NULL, NULL};
wolfSSL 7:481bce714567 6060 #else
wolfSSL 7:481bce714567 6061 unsigned char kb[2][KB_SIZE];
wolfSSL 7:481bce714567 6062 #endif
wolfSSL 7:481bce714567 6063 int x, err;
wolfSSL 7:481bce714567 6064 unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;
wolfSSL 7:481bce714567 6065 mp_int tka, tkb, order;
wolfSSL 7:481bce714567 6066
wolfSSL 7:481bce714567 6067 if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 7:481bce714567 6068 return MP_INIT_E;
wolfSSL 7:481bce714567 6069
wolfSSL 7:481bce714567 6070 /* if it's smaller than modulus we fine */
wolfSSL 7:481bce714567 6071 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
wolfSSL 7:481bce714567 6072 /* find order */
wolfSSL 7:481bce714567 6073 y = mp_unsigned_bin_size(modulus);
wolfSSL 7:481bce714567 6074 for (x = 0; ecc_sets[x].size; x++) {
wolfSSL 7:481bce714567 6075 if (y <= (unsigned)ecc_sets[x].size) break;
wolfSSL 7:481bce714567 6076 }
wolfSSL 7:481bce714567 6077
wolfSSL 7:481bce714567 6078 /* back off if we are on the 521 bit curve */
wolfSSL 7:481bce714567 6079 if (y == 66) --x;
wolfSSL 7:481bce714567 6080
wolfSSL 7:481bce714567 6081 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
wolfSSL 7:481bce714567 6082 goto done;
wolfSSL 7:481bce714567 6083 }
wolfSSL 7:481bce714567 6084
wolfSSL 7:481bce714567 6085 /* kA must be less than modulus */
wolfSSL 7:481bce714567 6086 if (mp_cmp(kA, &order) != MP_LT) {
wolfSSL 7:481bce714567 6087 if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
wolfSSL 7:481bce714567 6088 goto done;
wolfSSL 7:481bce714567 6089 }
wolfSSL 7:481bce714567 6090 } else {
wolfSSL 7:481bce714567 6091 if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
wolfSSL 7:481bce714567 6092 goto done;
wolfSSL 7:481bce714567 6093 }
wolfSSL 7:481bce714567 6094 }
wolfSSL 7:481bce714567 6095 } else {
wolfSSL 7:481bce714567 6096 if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
wolfSSL 7:481bce714567 6097 goto done;
wolfSSL 7:481bce714567 6098 }
wolfSSL 7:481bce714567 6099 }
wolfSSL 7:481bce714567 6100
wolfSSL 7:481bce714567 6101 /* if it's smaller than modulus we fine */
wolfSSL 7:481bce714567 6102 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
wolfSSL 7:481bce714567 6103 /* find order */
wolfSSL 7:481bce714567 6104 y = mp_unsigned_bin_size(modulus);
wolfSSL 7:481bce714567 6105 for (x = 0; ecc_sets[x].size; x++) {
wolfSSL 7:481bce714567 6106 if (y <= (unsigned)ecc_sets[x].size) break;
wolfSSL 7:481bce714567 6107 }
wolfSSL 7:481bce714567 6108
wolfSSL 7:481bce714567 6109 /* back off if we are on the 521 bit curve */
wolfSSL 7:481bce714567 6110 if (y == 66) --x;
wolfSSL 7:481bce714567 6111
wolfSSL 7:481bce714567 6112 if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) {
wolfSSL 7:481bce714567 6113 goto done;
wolfSSL 7:481bce714567 6114 }
wolfSSL 7:481bce714567 6115
wolfSSL 7:481bce714567 6116 /* kB must be less than modulus */
wolfSSL 7:481bce714567 6117 if (mp_cmp(kB, &order) != MP_LT) {
wolfSSL 7:481bce714567 6118 if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
wolfSSL 7:481bce714567 6119 goto done;
wolfSSL 7:481bce714567 6120 }
wolfSSL 7:481bce714567 6121 } else {
wolfSSL 7:481bce714567 6122 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
wolfSSL 7:481bce714567 6123 goto done;
wolfSSL 7:481bce714567 6124 }
wolfSSL 7:481bce714567 6125 }
wolfSSL 7:481bce714567 6126 } else {
wolfSSL 7:481bce714567 6127 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
wolfSSL 7:481bce714567 6128 goto done;
wolfSSL 7:481bce714567 6129 }
wolfSSL 7:481bce714567 6130 }
wolfSSL 7:481bce714567 6131
wolfSSL 7:481bce714567 6132 /* get bitlen and round up to next multiple of FP_LUT */
wolfSSL 7:481bce714567 6133 bitlen = mp_unsigned_bin_size(modulus) << 3;
wolfSSL 7:481bce714567 6134 x = bitlen % FP_LUT;
wolfSSL 7:481bce714567 6135 if (x) {
wolfSSL 7:481bce714567 6136 bitlen += FP_LUT - x;
wolfSSL 7:481bce714567 6137 }
wolfSSL 7:481bce714567 6138 lut_gap = bitlen / FP_LUT;
wolfSSL 7:481bce714567 6139
wolfSSL 7:481bce714567 6140 /* get the k value */
wolfSSL 7:481bce714567 6141 if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
wolfSSL 7:481bce714567 6142 (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) {
wolfSSL 7:481bce714567 6143 err = BUFFER_E; goto done;
wolfSSL 7:481bce714567 6144 }
wolfSSL 7:481bce714567 6145
wolfSSL 7:481bce714567 6146 /* store k */
wolfSSL 7:481bce714567 6147 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6148 kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6149 if (kb[0] == NULL) {
wolfSSL 7:481bce714567 6150 err = MEMORY_E; goto done;
wolfSSL 7:481bce714567 6151 }
wolfSSL 7:481bce714567 6152 #endif
wolfSSL 7:481bce714567 6153
wolfSSL 7:481bce714567 6154 XMEMSET(kb[0], 0, KB_SIZE);
wolfSSL 7:481bce714567 6155 if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
wolfSSL 7:481bce714567 6156 goto done;
wolfSSL 7:481bce714567 6157 }
wolfSSL 7:481bce714567 6158
wolfSSL 7:481bce714567 6159 /* let's reverse kb so it's little endian */
wolfSSL 7:481bce714567 6160 x = 0;
wolfSSL 7:481bce714567 6161 y = mp_unsigned_bin_size(&tka);
wolfSSL 7:481bce714567 6162 if (y > 0) {
wolfSSL 7:481bce714567 6163 y -= 1;
wolfSSL 7:481bce714567 6164 }
wolfSSL 7:481bce714567 6165 mp_clear(&tka);
wolfSSL 7:481bce714567 6166 while ((unsigned)x < y) {
wolfSSL 7:481bce714567 6167 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
wolfSSL 7:481bce714567 6168 ++x; --y;
wolfSSL 7:481bce714567 6169 }
wolfSSL 7:481bce714567 6170
wolfSSL 7:481bce714567 6171 /* store b */
wolfSSL 7:481bce714567 6172 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6173 kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6174 if (kb[1] == NULL) {
wolfSSL 7:481bce714567 6175 err = MEMORY_E; goto done;
wolfSSL 7:481bce714567 6176 }
wolfSSL 7:481bce714567 6177 #endif
wolfSSL 7:481bce714567 6178
wolfSSL 7:481bce714567 6179 XMEMSET(kb[1], 0, KB_SIZE);
wolfSSL 7:481bce714567 6180 if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
wolfSSL 7:481bce714567 6181 x = 0;
wolfSSL 7:481bce714567 6182 y = mp_unsigned_bin_size(&tkb);
wolfSSL 7:481bce714567 6183 if (y > 0) {
wolfSSL 7:481bce714567 6184 y -= 1;
wolfSSL 7:481bce714567 6185 }
wolfSSL 7:481bce714567 6186
wolfSSL 7:481bce714567 6187 while ((unsigned)x < y) {
wolfSSL 7:481bce714567 6188 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
wolfSSL 7:481bce714567 6189 ++x; --y;
wolfSSL 7:481bce714567 6190 }
wolfSSL 7:481bce714567 6191
wolfSSL 7:481bce714567 6192 /* at this point we can start, yipee */
wolfSSL 7:481bce714567 6193 first = 1;
wolfSSL 7:481bce714567 6194 for (x = lut_gap-1; x >= 0; x--) {
wolfSSL 7:481bce714567 6195 /* extract FP_LUT bits from kb spread out by lut_gap bits and
wolfSSL 7:481bce714567 6196 offset by x bits from the start */
wolfSSL 7:481bce714567 6197 bitpos = x;
wolfSSL 7:481bce714567 6198 for (y = zA = zB = 0; y < FP_LUT; y++) {
wolfSSL 7:481bce714567 6199 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
wolfSSL 7:481bce714567 6200 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
wolfSSL 7:481bce714567 6201 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid
wolfSSL 7:481bce714567 6202 the mult in each loop */
wolfSSL 7:481bce714567 6203 }
wolfSSL 7:481bce714567 6204
wolfSSL 7:481bce714567 6205 /* double if not first */
wolfSSL 7:481bce714567 6206 if (!first) {
wolfSSL 7:481bce714567 6207 if ((err = ecc_projective_dbl_point(R, R, a, modulus,
wolfSSL 7:481bce714567 6208 mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 6209 break;
wolfSSL 7:481bce714567 6210 }
wolfSSL 7:481bce714567 6211 }
wolfSSL 7:481bce714567 6212
wolfSSL 7:481bce714567 6213 /* add if not first, otherwise copy */
wolfSSL 7:481bce714567 6214 if (!first) {
wolfSSL 7:481bce714567 6215 if (zA) {
wolfSSL 7:481bce714567 6216 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
wolfSSL 7:481bce714567 6217 R, a, modulus, mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 6218 break;
wolfSSL 7:481bce714567 6219 }
wolfSSL 7:481bce714567 6220 }
wolfSSL 7:481bce714567 6221 if (zB) {
wolfSSL 7:481bce714567 6222 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
wolfSSL 7:481bce714567 6223 R, a, modulus, mp)) != MP_OKAY) {
wolfSSL 7:481bce714567 6224 break;
wolfSSL 7:481bce714567 6225 }
wolfSSL 7:481bce714567 6226 }
wolfSSL 7:481bce714567 6227 } else {
wolfSSL 7:481bce714567 6228 if (zA) {
wolfSSL 7:481bce714567 6229 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 6230 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 6231 (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) {
wolfSSL 7:481bce714567 6232 err = GEN_MEM_ERR;
wolfSSL 7:481bce714567 6233 break;
wolfSSL 7:481bce714567 6234 }
wolfSSL 7:481bce714567 6235 first = 0;
wolfSSL 7:481bce714567 6236 }
wolfSSL 7:481bce714567 6237 if (zB && first == 0) {
wolfSSL 7:481bce714567 6238 if (zB) {
wolfSSL 7:481bce714567 6239 if ((err = ecc_projective_add_point(R,
wolfSSL 7:481bce714567 6240 fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
wolfSSL 7:481bce714567 6241 break;
wolfSSL 7:481bce714567 6242 }
wolfSSL 7:481bce714567 6243 }
wolfSSL 7:481bce714567 6244 } else if (zB && first == 1) {
wolfSSL 7:481bce714567 6245 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
wolfSSL 7:481bce714567 6246 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
wolfSSL 7:481bce714567 6247 (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) {
wolfSSL 7:481bce714567 6248 err = GEN_MEM_ERR;
wolfSSL 7:481bce714567 6249 break;
wolfSSL 7:481bce714567 6250 }
wolfSSL 7:481bce714567 6251 first = 0;
wolfSSL 7:481bce714567 6252 }
wolfSSL 7:481bce714567 6253 }
wolfSSL 7:481bce714567 6254 }
wolfSSL 7:481bce714567 6255 }
wolfSSL 7:481bce714567 6256
wolfSSL 7:481bce714567 6257 done:
wolfSSL 7:481bce714567 6258 /* cleanup */
wolfSSL 7:481bce714567 6259 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 6260 mp_clear(&tkb);
wolfSSL 7:481bce714567 6261 mp_clear(&tka);
wolfSSL 7:481bce714567 6262 mp_clear(&order);
wolfSSL 7:481bce714567 6263 #endif
wolfSSL 7:481bce714567 6264
wolfSSL 7:481bce714567 6265 if (kb[0])
wolfSSL 7:481bce714567 6266 ForceZero(kb[0], KB_SIZE);
wolfSSL 7:481bce714567 6267 if (kb[1])
wolfSSL 7:481bce714567 6268 ForceZero(kb[1], KB_SIZE);
wolfSSL 7:481bce714567 6269
wolfSSL 7:481bce714567 6270 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6271 XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6272 XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6273 #endif
wolfSSL 7:481bce714567 6274
wolfSSL 7:481bce714567 6275 #undef KB_SIZE
wolfSSL 7:481bce714567 6276
wolfSSL 7:481bce714567 6277 if (err != MP_OKAY)
wolfSSL 7:481bce714567 6278 return err;
wolfSSL 7:481bce714567 6279
wolfSSL 7:481bce714567 6280 return ecc_map(R, modulus, mp);
wolfSSL 7:481bce714567 6281 }
wolfSSL 7:481bce714567 6282
wolfSSL 7:481bce714567 6283
wolfSSL 7:481bce714567 6284 /** ECC Fixed Point mulmod global with heap hint used
wolfSSL 7:481bce714567 6285 Computes kA*A + kB*B = C using Shamir's Trick
wolfSSL 7:481bce714567 6286 A First point to multiply
wolfSSL 7:481bce714567 6287 kA What to multiple A by
wolfSSL 7:481bce714567 6288 B Second point to multiply
wolfSSL 7:481bce714567 6289 kB What to multiple B by
wolfSSL 7:481bce714567 6290 C [out] Destination point (can overlap with A or B)
wolfSSL 7:481bce714567 6291 a ECC curve parameter a
wolfSSL 7:481bce714567 6292 modulus Modulus for curve
wolfSSL 7:481bce714567 6293 return MP_OKAY on success
wolfSSL 7:481bce714567 6294 */
wolfSSL 7:481bce714567 6295 int ecc_mul2add(ecc_point* A, mp_int* kA,
wolfSSL 7:481bce714567 6296 ecc_point* B, mp_int* kB,
wolfSSL 7:481bce714567 6297 ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
wolfSSL 7:481bce714567 6298 {
wolfSSL 7:481bce714567 6299 int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;
wolfSSL 7:481bce714567 6300 mp_digit mp;
wolfSSL 7:481bce714567 6301 mp_int mu;
wolfSSL 7:481bce714567 6302
wolfSSL 7:481bce714567 6303 err = mp_init(&mu);
wolfSSL 7:481bce714567 6304 if (err != MP_OKAY)
wolfSSL 7:481bce714567 6305 return err;
wolfSSL 7:481bce714567 6306
wolfSSL 7:481bce714567 6307 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6308 if (initMutex == 0) {
wolfSSL 7:481bce714567 6309 wc_InitMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6310 initMutex = 1;
wolfSSL 7:481bce714567 6311 }
wolfSSL 7:481bce714567 6312 if (wc_LockMutex(&ecc_fp_lock) != 0)
wolfSSL 7:481bce714567 6313 return BAD_MUTEX_E;
wolfSSL 7:481bce714567 6314 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6315
wolfSSL 7:481bce714567 6316 /* find point */
wolfSSL 7:481bce714567 6317 idx1 = find_base(A);
wolfSSL 7:481bce714567 6318
wolfSSL 7:481bce714567 6319 /* no entry? */
wolfSSL 7:481bce714567 6320 if (idx1 == -1) {
wolfSSL 7:481bce714567 6321 /* find hole and add it */
wolfSSL 7:481bce714567 6322 if ((idx1 = find_hole()) >= 0) {
wolfSSL 7:481bce714567 6323 err = add_entry(idx1, A);
wolfSSL 7:481bce714567 6324 }
wolfSSL 7:481bce714567 6325 }
wolfSSL 7:481bce714567 6326 if (err == MP_OKAY && idx1 != -1) {
wolfSSL 7:481bce714567 6327 /* increment LRU */
wolfSSL 7:481bce714567 6328 ++(fp_cache[idx1].lru_count);
wolfSSL 7:481bce714567 6329 }
wolfSSL 7:481bce714567 6330
wolfSSL 7:481bce714567 6331 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6332 /* find point */
wolfSSL 7:481bce714567 6333 idx2 = find_base(B);
wolfSSL 7:481bce714567 6334
wolfSSL 7:481bce714567 6335 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6336 /* no entry? */
wolfSSL 7:481bce714567 6337 if (idx2 == -1) {
wolfSSL 7:481bce714567 6338 /* find hole and add it */
wolfSSL 7:481bce714567 6339 if ((idx2 = find_hole()) >= 0)
wolfSSL 7:481bce714567 6340 err = add_entry(idx2, B);
wolfSSL 7:481bce714567 6341 }
wolfSSL 7:481bce714567 6342 }
wolfSSL 7:481bce714567 6343
wolfSSL 7:481bce714567 6344 if (err == MP_OKAY && idx2 != -1) {
wolfSSL 7:481bce714567 6345 /* increment LRU */
wolfSSL 7:481bce714567 6346 ++(fp_cache[idx2].lru_count);
wolfSSL 7:481bce714567 6347 }
wolfSSL 7:481bce714567 6348
wolfSSL 7:481bce714567 6349 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6350 /* if it's 2 build the LUT, if it's higher just use the LUT */
wolfSSL 7:481bce714567 6351 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
wolfSSL 7:481bce714567 6352 /* compute mp */
wolfSSL 7:481bce714567 6353 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 6354
wolfSSL 7:481bce714567 6355 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6356 mpInit = 1;
wolfSSL 7:481bce714567 6357 err = mp_montgomery_calc_normalization(&mu, modulus);
wolfSSL 7:481bce714567 6358 }
wolfSSL 7:481bce714567 6359
wolfSSL 7:481bce714567 6360 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6361 /* build the LUT */
wolfSSL 7:481bce714567 6362 err = build_lut(idx1, a, modulus, mp, &mu);
wolfSSL 7:481bce714567 6363 }
wolfSSL 7:481bce714567 6364 }
wolfSSL 7:481bce714567 6365
wolfSSL 7:481bce714567 6366 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6367 /* if it's 2 build the LUT, if it's higher just use the LUT */
wolfSSL 7:481bce714567 6368 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
wolfSSL 7:481bce714567 6369 if (mpInit == 0) {
wolfSSL 7:481bce714567 6370 /* compute mp */
wolfSSL 7:481bce714567 6371 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 6372 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6373 mpInit = 1;
wolfSSL 7:481bce714567 6374 err = mp_montgomery_calc_normalization(&mu, modulus);
wolfSSL 7:481bce714567 6375 }
wolfSSL 7:481bce714567 6376 }
wolfSSL 7:481bce714567 6377
wolfSSL 7:481bce714567 6378 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6379 /* build the LUT */
wolfSSL 7:481bce714567 6380 err = build_lut(idx2, a, modulus, mp, &mu);
wolfSSL 7:481bce714567 6381 }
wolfSSL 7:481bce714567 6382 }
wolfSSL 7:481bce714567 6383
wolfSSL 7:481bce714567 6384
wolfSSL 7:481bce714567 6385 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6386 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
wolfSSL 7:481bce714567 6387 fp_cache[idx2].lru_count >= 2) {
wolfSSL 7:481bce714567 6388 if (mpInit == 0) {
wolfSSL 7:481bce714567 6389 /* compute mp */
wolfSSL 7:481bce714567 6390 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 6391 }
wolfSSL 7:481bce714567 6392 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6393 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
wolfSSL 7:481bce714567 6394 } else {
wolfSSL 7:481bce714567 6395 err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
wolfSSL 7:481bce714567 6396 }
wolfSSL 7:481bce714567 6397 }
wolfSSL 7:481bce714567 6398
wolfSSL 7:481bce714567 6399 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6400 wc_UnLockMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6401 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6402 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 6403 mp_clear(&mu);
wolfSSL 7:481bce714567 6404 #endif
wolfSSL 7:481bce714567 6405
wolfSSL 7:481bce714567 6406 return err;
wolfSSL 7:481bce714567 6407 }
wolfSSL 7:481bce714567 6408 #endif /* ECC_SHAMIR */
wolfSSL 7:481bce714567 6409
wolfSSL 7:481bce714567 6410 /** ECC Fixed Point mulmod global
wolfSSL 7:481bce714567 6411 k The multiplicand
wolfSSL 7:481bce714567 6412 G Base point to multiply
wolfSSL 7:481bce714567 6413 R [out] Destination of product
wolfSSL 7:481bce714567 6414 a ECC curve parameter a
wolfSSL 7:481bce714567 6415 modulus The modulus for the curve
wolfSSL 7:481bce714567 6416 map [boolean] If non-zero maps the point back to affine co-ordinates,
wolfSSL 7:481bce714567 6417 otherwise it's left in jacobian-montgomery form
wolfSSL 7:481bce714567 6418 return MP_OKAY if successful
wolfSSL 7:481bce714567 6419 */
wolfSSL 7:481bce714567 6420 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
wolfSSL 7:481bce714567 6421 mp_int* modulus, int map, void* heap)
wolfSSL 7:481bce714567 6422 {
wolfSSL 7:481bce714567 6423 int idx, err = MP_OKAY;
wolfSSL 7:481bce714567 6424 mp_digit mp;
wolfSSL 7:481bce714567 6425 mp_int mu;
wolfSSL 7:481bce714567 6426 int mpSetup = 0;
wolfSSL 7:481bce714567 6427
wolfSSL 7:481bce714567 6428 if (mp_init(&mu) != MP_OKAY)
wolfSSL 7:481bce714567 6429 return MP_INIT_E;
wolfSSL 7:481bce714567 6430
wolfSSL 7:481bce714567 6431 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6432 if (initMutex == 0) {
wolfSSL 7:481bce714567 6433 wc_InitMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6434 initMutex = 1;
wolfSSL 7:481bce714567 6435 }
wolfSSL 7:481bce714567 6436
wolfSSL 7:481bce714567 6437 if (wc_LockMutex(&ecc_fp_lock) != 0)
wolfSSL 7:481bce714567 6438 return BAD_MUTEX_E;
wolfSSL 7:481bce714567 6439 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6440
wolfSSL 7:481bce714567 6441 /* find point */
wolfSSL 7:481bce714567 6442 idx = find_base(G);
wolfSSL 7:481bce714567 6443
wolfSSL 7:481bce714567 6444 /* no entry? */
wolfSSL 7:481bce714567 6445 if (idx == -1) {
wolfSSL 7:481bce714567 6446 /* find hole and add it */
wolfSSL 7:481bce714567 6447 idx = find_hole();
wolfSSL 7:481bce714567 6448
wolfSSL 7:481bce714567 6449 if (idx >= 0)
wolfSSL 7:481bce714567 6450 err = add_entry(idx, G);
wolfSSL 7:481bce714567 6451 }
wolfSSL 7:481bce714567 6452 if (err == MP_OKAY && idx >= 0) {
wolfSSL 7:481bce714567 6453 /* increment LRU */
wolfSSL 7:481bce714567 6454 ++(fp_cache[idx].lru_count);
wolfSSL 7:481bce714567 6455 }
wolfSSL 7:481bce714567 6456
wolfSSL 7:481bce714567 6457
wolfSSL 7:481bce714567 6458 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6459 /* if it's 2 build the LUT, if it's higher just use the LUT */
wolfSSL 7:481bce714567 6460 if (idx >= 0 && fp_cache[idx].lru_count == 2) {
wolfSSL 7:481bce714567 6461 /* compute mp */
wolfSSL 7:481bce714567 6462 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 6463
wolfSSL 7:481bce714567 6464 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6465 /* compute mu */
wolfSSL 7:481bce714567 6466 mpSetup = 1;
wolfSSL 7:481bce714567 6467 err = mp_montgomery_calc_normalization(&mu, modulus);
wolfSSL 7:481bce714567 6468 }
wolfSSL 7:481bce714567 6469
wolfSSL 7:481bce714567 6470 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6471 /* build the LUT */
wolfSSL 7:481bce714567 6472 err = build_lut(idx, a, modulus, mp, &mu);
wolfSSL 7:481bce714567 6473 }
wolfSSL 7:481bce714567 6474 }
wolfSSL 7:481bce714567 6475
wolfSSL 7:481bce714567 6476 if (err == MP_OKAY) {
wolfSSL 7:481bce714567 6477 if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
wolfSSL 7:481bce714567 6478 if (mpSetup == 0) {
wolfSSL 7:481bce714567 6479 /* compute mp */
wolfSSL 7:481bce714567 6480 err = mp_montgomery_setup(modulus, &mp);
wolfSSL 7:481bce714567 6481 }
wolfSSL 7:481bce714567 6482 if (err == MP_OKAY)
wolfSSL 7:481bce714567 6483 err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
wolfSSL 7:481bce714567 6484 } else {
wolfSSL 7:481bce714567 6485 err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);
wolfSSL 7:481bce714567 6486 }
wolfSSL 7:481bce714567 6487 }
wolfSSL 7:481bce714567 6488
wolfSSL 7:481bce714567 6489 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6490 wc_UnLockMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6491 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6492 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 6493 mp_clear(&mu);
wolfSSL 7:481bce714567 6494 #endif
wolfSSL 7:481bce714567 6495
wolfSSL 7:481bce714567 6496 return err;
wolfSSL 7:481bce714567 6497 }
wolfSSL 7:481bce714567 6498
wolfSSL 7:481bce714567 6499 /* helper function for freeing the cache ...
wolfSSL 7:481bce714567 6500 must be called with the cache mutex locked */
wolfSSL 7:481bce714567 6501 static void wc_ecc_fp_free_cache(void)
wolfSSL 7:481bce714567 6502 {
wolfSSL 7:481bce714567 6503 unsigned x, y;
wolfSSL 7:481bce714567 6504 for (x = 0; x < FP_ENTRIES; x++) {
wolfSSL 7:481bce714567 6505 if (fp_cache[x].g != NULL) {
wolfSSL 7:481bce714567 6506 for (y = 0; y < (1U<<FP_LUT); y++) {
wolfSSL 7:481bce714567 6507 wc_ecc_del_point(fp_cache[x].LUT[y]);
wolfSSL 7:481bce714567 6508 fp_cache[x].LUT[y] = NULL;
wolfSSL 7:481bce714567 6509 }
wolfSSL 7:481bce714567 6510 wc_ecc_del_point(fp_cache[x].g);
wolfSSL 7:481bce714567 6511 fp_cache[x].g = NULL;
wolfSSL 7:481bce714567 6512 mp_clear(&fp_cache[x].mu);
wolfSSL 7:481bce714567 6513 fp_cache[x].lru_count = 0;
wolfSSL 7:481bce714567 6514 fp_cache[x].lock = 0;
wolfSSL 7:481bce714567 6515 }
wolfSSL 7:481bce714567 6516 }
wolfSSL 7:481bce714567 6517 }
wolfSSL 7:481bce714567 6518
wolfSSL 7:481bce714567 6519 /** Free the Fixed Point cache */
wolfSSL 7:481bce714567 6520 void wc_ecc_fp_free(void)
wolfSSL 7:481bce714567 6521 {
wolfSSL 7:481bce714567 6522 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6523 if (initMutex == 0) {
wolfSSL 7:481bce714567 6524 wc_InitMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6525 initMutex = 1;
wolfSSL 7:481bce714567 6526 }
wolfSSL 7:481bce714567 6527
wolfSSL 7:481bce714567 6528 if (wc_LockMutex(&ecc_fp_lock) == 0) {
wolfSSL 7:481bce714567 6529 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6530
wolfSSL 7:481bce714567 6531 wc_ecc_fp_free_cache();
wolfSSL 7:481bce714567 6532
wolfSSL 7:481bce714567 6533 #ifndef HAVE_THREAD_LS
wolfSSL 7:481bce714567 6534 wc_UnLockMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6535 wc_FreeMutex(&ecc_fp_lock);
wolfSSL 7:481bce714567 6536 initMutex = 0;
wolfSSL 7:481bce714567 6537 }
wolfSSL 7:481bce714567 6538 #endif /* HAVE_THREAD_LS */
wolfSSL 7:481bce714567 6539 }
wolfSSL 7:481bce714567 6540
wolfSSL 7:481bce714567 6541
wolfSSL 7:481bce714567 6542 #endif /* FP_ECC */
wolfSSL 7:481bce714567 6543
wolfSSL 7:481bce714567 6544 #ifdef HAVE_ECC_ENCRYPT
wolfSSL 7:481bce714567 6545
wolfSSL 7:481bce714567 6546
wolfSSL 7:481bce714567 6547 enum ecCliState {
wolfSSL 7:481bce714567 6548 ecCLI_INIT = 1,
wolfSSL 7:481bce714567 6549 ecCLI_SALT_GET = 2,
wolfSSL 7:481bce714567 6550 ecCLI_SALT_SET = 3,
wolfSSL 7:481bce714567 6551 ecCLI_SENT_REQ = 4,
wolfSSL 7:481bce714567 6552 ecCLI_RECV_RESP = 5,
wolfSSL 7:481bce714567 6553 ecCLI_BAD_STATE = 99
wolfSSL 7:481bce714567 6554 };
wolfSSL 7:481bce714567 6555
wolfSSL 7:481bce714567 6556 enum ecSrvState {
wolfSSL 7:481bce714567 6557 ecSRV_INIT = 1,
wolfSSL 7:481bce714567 6558 ecSRV_SALT_GET = 2,
wolfSSL 7:481bce714567 6559 ecSRV_SALT_SET = 3,
wolfSSL 7:481bce714567 6560 ecSRV_RECV_REQ = 4,
wolfSSL 7:481bce714567 6561 ecSRV_SENT_RESP = 5,
wolfSSL 7:481bce714567 6562 ecSRV_BAD_STATE = 99
wolfSSL 7:481bce714567 6563 };
wolfSSL 7:481bce714567 6564
wolfSSL 7:481bce714567 6565
wolfSSL 7:481bce714567 6566 struct ecEncCtx {
wolfSSL 7:481bce714567 6567 const byte* kdfSalt; /* optional salt for kdf */
wolfSSL 7:481bce714567 6568 const byte* kdfInfo; /* optional info for kdf */
wolfSSL 7:481bce714567 6569 const byte* macSalt; /* optional salt for mac */
wolfSSL 7:481bce714567 6570 word32 kdfSaltSz; /* size of kdfSalt */
wolfSSL 7:481bce714567 6571 word32 kdfInfoSz; /* size of kdfInfo */
wolfSSL 7:481bce714567 6572 word32 macSaltSz; /* size of macSalt */
wolfSSL 7:481bce714567 6573 void* heap; /* heap hint for memory used */
wolfSSL 7:481bce714567 6574 byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
wolfSSL 7:481bce714567 6575 byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
wolfSSL 7:481bce714567 6576 byte encAlgo; /* which encryption type */
wolfSSL 7:481bce714567 6577 byte kdfAlgo; /* which key derivation function type */
wolfSSL 7:481bce714567 6578 byte macAlgo; /* which mac function type */
wolfSSL 7:481bce714567 6579 byte protocol; /* are we REQ_RESP client or server ? */
wolfSSL 7:481bce714567 6580 byte cliSt; /* protocol state, for sanity checks */
wolfSSL 7:481bce714567 6581 byte srvSt; /* protocol state, for sanity checks */
wolfSSL 7:481bce714567 6582 };
wolfSSL 7:481bce714567 6583
wolfSSL 7:481bce714567 6584
wolfSSL 7:481bce714567 6585 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
wolfSSL 7:481bce714567 6586 {
wolfSSL 7:481bce714567 6587 if (ctx == NULL || ctx->protocol == 0)
wolfSSL 7:481bce714567 6588 return NULL;
wolfSSL 7:481bce714567 6589
wolfSSL 7:481bce714567 6590 if (ctx->protocol == REQ_RESP_CLIENT) {
wolfSSL 7:481bce714567 6591 if (ctx->cliSt == ecCLI_INIT) {
wolfSSL 7:481bce714567 6592 ctx->cliSt = ecCLI_SALT_GET;
wolfSSL 7:481bce714567 6593 return ctx->clientSalt;
wolfSSL 7:481bce714567 6594 }
wolfSSL 7:481bce714567 6595 else {
wolfSSL 7:481bce714567 6596 ctx->cliSt = ecCLI_BAD_STATE;
wolfSSL 7:481bce714567 6597 return NULL;
wolfSSL 7:481bce714567 6598 }
wolfSSL 7:481bce714567 6599 }
wolfSSL 7:481bce714567 6600 else if (ctx->protocol == REQ_RESP_SERVER) {
wolfSSL 7:481bce714567 6601 if (ctx->srvSt == ecSRV_INIT) {
wolfSSL 7:481bce714567 6602 ctx->srvSt = ecSRV_SALT_GET;
wolfSSL 7:481bce714567 6603 return ctx->serverSalt;
wolfSSL 7:481bce714567 6604 }
wolfSSL 7:481bce714567 6605 else {
wolfSSL 7:481bce714567 6606 ctx->srvSt = ecSRV_BAD_STATE;
wolfSSL 7:481bce714567 6607 return NULL;
wolfSSL 7:481bce714567 6608 }
wolfSSL 7:481bce714567 6609 }
wolfSSL 7:481bce714567 6610
wolfSSL 7:481bce714567 6611 return NULL;
wolfSSL 7:481bce714567 6612 }
wolfSSL 7:481bce714567 6613
wolfSSL 7:481bce714567 6614
wolfSSL 7:481bce714567 6615 /* optional set info, can be called before or after set_peer_salt */
wolfSSL 7:481bce714567 6616 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
wolfSSL 7:481bce714567 6617 {
wolfSSL 7:481bce714567 6618 if (ctx == NULL || info == 0 || sz < 0)
wolfSSL 7:481bce714567 6619 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6620
wolfSSL 7:481bce714567 6621 ctx->kdfInfo = info;
wolfSSL 7:481bce714567 6622 ctx->kdfInfoSz = sz;
wolfSSL 7:481bce714567 6623
wolfSSL 7:481bce714567 6624 return 0;
wolfSSL 7:481bce714567 6625 }
wolfSSL 7:481bce714567 6626
wolfSSL 7:481bce714567 6627
wolfSSL 7:481bce714567 6628 static const char* exchange_info = "Secure Message Exchange";
wolfSSL 7:481bce714567 6629
wolfSSL 7:481bce714567 6630 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
wolfSSL 7:481bce714567 6631 {
wolfSSL 7:481bce714567 6632 byte tmp[EXCHANGE_SALT_SZ/2];
wolfSSL 7:481bce714567 6633 int halfSz = EXCHANGE_SALT_SZ/2;
wolfSSL 7:481bce714567 6634
wolfSSL 7:481bce714567 6635 if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
wolfSSL 7:481bce714567 6636 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6637
wolfSSL 7:481bce714567 6638 if (ctx->protocol == REQ_RESP_CLIENT) {
wolfSSL 7:481bce714567 6639 XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
wolfSSL 7:481bce714567 6640 if (ctx->cliSt == ecCLI_SALT_GET)
wolfSSL 7:481bce714567 6641 ctx->cliSt = ecCLI_SALT_SET;
wolfSSL 7:481bce714567 6642 else {
wolfSSL 7:481bce714567 6643 ctx->cliSt = ecCLI_BAD_STATE;
wolfSSL 7:481bce714567 6644 return BAD_STATE_E;
wolfSSL 7:481bce714567 6645 }
wolfSSL 7:481bce714567 6646 }
wolfSSL 7:481bce714567 6647 else {
wolfSSL 7:481bce714567 6648 XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
wolfSSL 7:481bce714567 6649 if (ctx->srvSt == ecSRV_SALT_GET)
wolfSSL 7:481bce714567 6650 ctx->srvSt = ecSRV_SALT_SET;
wolfSSL 7:481bce714567 6651 else {
wolfSSL 7:481bce714567 6652 ctx->srvSt = ecSRV_BAD_STATE;
wolfSSL 7:481bce714567 6653 return BAD_STATE_E;
wolfSSL 7:481bce714567 6654 }
wolfSSL 7:481bce714567 6655 }
wolfSSL 7:481bce714567 6656
wolfSSL 7:481bce714567 6657 /* mix half and half */
wolfSSL 7:481bce714567 6658 /* tmp stores 2nd half of client before overwrite */
wolfSSL 7:481bce714567 6659 XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
wolfSSL 7:481bce714567 6660 XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
wolfSSL 7:481bce714567 6661 XMEMCPY(ctx->serverSalt, tmp, halfSz);
wolfSSL 7:481bce714567 6662
wolfSSL 7:481bce714567 6663 ctx->kdfSalt = ctx->clientSalt;
wolfSSL 7:481bce714567 6664 ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
wolfSSL 7:481bce714567 6665
wolfSSL 7:481bce714567 6666 ctx->macSalt = ctx->serverSalt;
wolfSSL 7:481bce714567 6667 ctx->macSaltSz = EXCHANGE_SALT_SZ;
wolfSSL 7:481bce714567 6668
wolfSSL 7:481bce714567 6669 if (ctx->kdfInfo == NULL) {
wolfSSL 7:481bce714567 6670 /* default info */
wolfSSL 7:481bce714567 6671 ctx->kdfInfo = (const byte*)exchange_info;
wolfSSL 7:481bce714567 6672 ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
wolfSSL 7:481bce714567 6673 }
wolfSSL 7:481bce714567 6674
wolfSSL 7:481bce714567 6675 return 0;
wolfSSL 7:481bce714567 6676 }
wolfSSL 7:481bce714567 6677
wolfSSL 7:481bce714567 6678
wolfSSL 7:481bce714567 6679 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
wolfSSL 7:481bce714567 6680 {
wolfSSL 7:481bce714567 6681 byte* saltBuffer = NULL;
wolfSSL 7:481bce714567 6682
wolfSSL 7:481bce714567 6683 if (ctx == NULL || rng == NULL || flags == 0)
wolfSSL 7:481bce714567 6684 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6685
wolfSSL 7:481bce714567 6686 saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
wolfSSL 7:481bce714567 6687
wolfSSL 7:481bce714567 6688 return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
wolfSSL 7:481bce714567 6689 }
wolfSSL 7:481bce714567 6690
wolfSSL 7:481bce714567 6691
wolfSSL 7:481bce714567 6692 static void ecc_ctx_init(ecEncCtx* ctx, int flags)
wolfSSL 7:481bce714567 6693 {
wolfSSL 7:481bce714567 6694 if (ctx) {
wolfSSL 7:481bce714567 6695 XMEMSET(ctx, 0, sizeof(ecEncCtx));
wolfSSL 7:481bce714567 6696
wolfSSL 7:481bce714567 6697 ctx->encAlgo = ecAES_128_CBC;
wolfSSL 7:481bce714567 6698 ctx->kdfAlgo = ecHKDF_SHA256;
wolfSSL 7:481bce714567 6699 ctx->macAlgo = ecHMAC_SHA256;
wolfSSL 7:481bce714567 6700 ctx->protocol = (byte)flags;
wolfSSL 7:481bce714567 6701
wolfSSL 7:481bce714567 6702 if (flags == REQ_RESP_CLIENT)
wolfSSL 7:481bce714567 6703 ctx->cliSt = ecCLI_INIT;
wolfSSL 7:481bce714567 6704 if (flags == REQ_RESP_SERVER)
wolfSSL 7:481bce714567 6705 ctx->srvSt = ecSRV_INIT;
wolfSSL 7:481bce714567 6706 }
wolfSSL 7:481bce714567 6707 }
wolfSSL 7:481bce714567 6708
wolfSSL 7:481bce714567 6709
wolfSSL 7:481bce714567 6710 /* allow ecc context reset so user doesn't have to init/free for reuse */
wolfSSL 7:481bce714567 6711 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
wolfSSL 7:481bce714567 6712 {
wolfSSL 7:481bce714567 6713 if (ctx == NULL || rng == NULL)
wolfSSL 7:481bce714567 6714 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6715
wolfSSL 7:481bce714567 6716 ecc_ctx_init(ctx, ctx->protocol);
wolfSSL 7:481bce714567 6717 return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
wolfSSL 7:481bce714567 6718 }
wolfSSL 7:481bce714567 6719
wolfSSL 7:481bce714567 6720
wolfSSL 7:481bce714567 6721 ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
wolfSSL 7:481bce714567 6722 {
wolfSSL 7:481bce714567 6723 int ret = 0;
wolfSSL 7:481bce714567 6724 ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
wolfSSL 7:481bce714567 6725 DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 6726
wolfSSL 7:481bce714567 6727 if (ctx) {
wolfSSL 7:481bce714567 6728 ctx->protocol = (byte)flags;
wolfSSL 7:481bce714567 6729 ctx->heap = heap;
wolfSSL 7:481bce714567 6730 }
wolfSSL 7:481bce714567 6731
wolfSSL 7:481bce714567 6732 ret = wc_ecc_ctx_reset(ctx, rng);
wolfSSL 7:481bce714567 6733 if (ret != 0) {
wolfSSL 7:481bce714567 6734 wc_ecc_ctx_free(ctx);
wolfSSL 7:481bce714567 6735 ctx = NULL;
wolfSSL 7:481bce714567 6736 }
wolfSSL 7:481bce714567 6737
wolfSSL 7:481bce714567 6738 return ctx;
wolfSSL 7:481bce714567 6739 }
wolfSSL 7:481bce714567 6740
wolfSSL 7:481bce714567 6741
wolfSSL 7:481bce714567 6742 /* alloc/init and set defaults, return new Context */
wolfSSL 7:481bce714567 6743 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
wolfSSL 7:481bce714567 6744 {
wolfSSL 7:481bce714567 6745 return wc_ecc_ctx_new_ex(flags, rng, NULL);
wolfSSL 7:481bce714567 6746 }
wolfSSL 7:481bce714567 6747
wolfSSL 7:481bce714567 6748
wolfSSL 7:481bce714567 6749 /* free any resources, clear any keys */
wolfSSL 7:481bce714567 6750 void wc_ecc_ctx_free(ecEncCtx* ctx)
wolfSSL 7:481bce714567 6751 {
wolfSSL 7:481bce714567 6752 if (ctx) {
wolfSSL 7:481bce714567 6753 ForceZero(ctx, sizeof(ecEncCtx));
wolfSSL 7:481bce714567 6754 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC);
wolfSSL 7:481bce714567 6755 }
wolfSSL 7:481bce714567 6756 }
wolfSSL 7:481bce714567 6757
wolfSSL 7:481bce714567 6758
wolfSSL 7:481bce714567 6759 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
wolfSSL 7:481bce714567 6760 int* keysLen, word32* digestSz, word32* blockSz)
wolfSSL 7:481bce714567 6761 {
wolfSSL 7:481bce714567 6762 if (ctx) {
wolfSSL 7:481bce714567 6763 switch (ctx->encAlgo) {
wolfSSL 7:481bce714567 6764 case ecAES_128_CBC:
wolfSSL 7:481bce714567 6765 *encKeySz = KEY_SIZE_128;
wolfSSL 7:481bce714567 6766 *ivSz = IV_SIZE_128;
wolfSSL 7:481bce714567 6767 *blockSz = AES_BLOCK_SIZE;
wolfSSL 7:481bce714567 6768 break;
wolfSSL 7:481bce714567 6769 default:
wolfSSL 7:481bce714567 6770 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6771 }
wolfSSL 7:481bce714567 6772
wolfSSL 7:481bce714567 6773 switch (ctx->macAlgo) {
wolfSSL 7:481bce714567 6774 case ecHMAC_SHA256:
wolfSSL 7:481bce714567 6775 *digestSz = SHA256_DIGEST_SIZE;
wolfSSL 7:481bce714567 6776 break;
wolfSSL 7:481bce714567 6777 default:
wolfSSL 7:481bce714567 6778 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6779 }
wolfSSL 7:481bce714567 6780 } else
wolfSSL 7:481bce714567 6781 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6782
wolfSSL 7:481bce714567 6783 *keysLen = *encKeySz + *ivSz + *digestSz;
wolfSSL 7:481bce714567 6784
wolfSSL 7:481bce714567 6785 return 0;
wolfSSL 7:481bce714567 6786 }
wolfSSL 7:481bce714567 6787
wolfSSL 7:481bce714567 6788
wolfSSL 7:481bce714567 6789 /* ecc encrypt with shared secret run through kdf
wolfSSL 7:481bce714567 6790 ctx holds non default algos and inputs
wolfSSL 7:481bce714567 6791 msgSz should be the right size for encAlgo, i.e., already padded
wolfSSL 7:481bce714567 6792 return 0 on success */
wolfSSL 7:481bce714567 6793 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
wolfSSL 7:481bce714567 6794 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
wolfSSL 7:481bce714567 6795 {
wolfSSL 7:481bce714567 6796 int ret;
wolfSSL 7:481bce714567 6797 word32 blockSz;
wolfSSL 7:481bce714567 6798 word32 digestSz;
wolfSSL 7:481bce714567 6799 ecEncCtx localCtx;
wolfSSL 7:481bce714567 6800 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6801 byte* sharedSecret;
wolfSSL 7:481bce714567 6802 byte* keys;
wolfSSL 7:481bce714567 6803 #else
wolfSSL 7:481bce714567 6804 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
wolfSSL 7:481bce714567 6805 byte keys[ECC_BUFSIZE]; /* max size */
wolfSSL 7:481bce714567 6806 #endif
wolfSSL 7:481bce714567 6807 word32 sharedSz = ECC_MAXSIZE;
wolfSSL 7:481bce714567 6808 int keysLen;
wolfSSL 7:481bce714567 6809 int encKeySz;
wolfSSL 7:481bce714567 6810 int ivSz;
wolfSSL 7:481bce714567 6811 int offset = 0; /* keys offset if doing msg exchange */
wolfSSL 7:481bce714567 6812 byte* encKey;
wolfSSL 7:481bce714567 6813 byte* encIv;
wolfSSL 7:481bce714567 6814 byte* macKey;
wolfSSL 7:481bce714567 6815
wolfSSL 7:481bce714567 6816 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
wolfSSL 7:481bce714567 6817 outSz == NULL)
wolfSSL 7:481bce714567 6818 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6819
wolfSSL 7:481bce714567 6820 if (ctx == NULL) { /* use defaults */
wolfSSL 7:481bce714567 6821 ecc_ctx_init(&localCtx, 0);
wolfSSL 7:481bce714567 6822 ctx = &localCtx;
wolfSSL 7:481bce714567 6823 }
wolfSSL 7:481bce714567 6824
wolfSSL 7:481bce714567 6825 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
wolfSSL 7:481bce714567 6826 &blockSz);
wolfSSL 7:481bce714567 6827 if (ret != 0)
wolfSSL 7:481bce714567 6828 return ret;
wolfSSL 7:481bce714567 6829
wolfSSL 7:481bce714567 6830 if (ctx->protocol == REQ_RESP_SERVER) {
wolfSSL 7:481bce714567 6831 offset = keysLen;
wolfSSL 7:481bce714567 6832 keysLen *= 2;
wolfSSL 7:481bce714567 6833
wolfSSL 7:481bce714567 6834 if (ctx->srvSt != ecSRV_RECV_REQ)
wolfSSL 7:481bce714567 6835 return BAD_STATE_E;
wolfSSL 7:481bce714567 6836
wolfSSL 7:481bce714567 6837 ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
wolfSSL 7:481bce714567 6838 }
wolfSSL 7:481bce714567 6839 else if (ctx->protocol == REQ_RESP_CLIENT) {
wolfSSL 7:481bce714567 6840 if (ctx->cliSt != ecCLI_SALT_SET)
wolfSSL 7:481bce714567 6841 return BAD_STATE_E;
wolfSSL 7:481bce714567 6842
wolfSSL 7:481bce714567 6843 ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
wolfSSL 7:481bce714567 6844 }
wolfSSL 7:481bce714567 6845
wolfSSL 7:481bce714567 6846 if (keysLen > ECC_BUFSIZE) /* keys size */
wolfSSL 7:481bce714567 6847 return BUFFER_E;
wolfSSL 7:481bce714567 6848
wolfSSL 7:481bce714567 6849 if ( (msgSz%blockSz) != 0)
wolfSSL 7:481bce714567 6850 return BAD_PADDING_E;
wolfSSL 7:481bce714567 6851
wolfSSL 7:481bce714567 6852 if (*outSz < (msgSz + digestSz))
wolfSSL 7:481bce714567 6853 return BUFFER_E;
wolfSSL 7:481bce714567 6854
wolfSSL 7:481bce714567 6855 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6856 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6857 if (sharedSecret == NULL)
wolfSSL 7:481bce714567 6858 return MEMORY_E;
wolfSSL 7:481bce714567 6859
wolfSSL 7:481bce714567 6860 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6861 if (keys == NULL) {
wolfSSL 7:481bce714567 6862 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6863 return MEMORY_E;
wolfSSL 7:481bce714567 6864 }
wolfSSL 7:481bce714567 6865 #endif
wolfSSL 7:481bce714567 6866
wolfSSL 7:481bce714567 6867 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
wolfSSL 7:481bce714567 6868
wolfSSL 7:481bce714567 6869 if (ret == 0) {
wolfSSL 7:481bce714567 6870 switch (ctx->kdfAlgo) {
wolfSSL 7:481bce714567 6871 case ecHKDF_SHA256 :
wolfSSL 7:481bce714567 6872 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
wolfSSL 7:481bce714567 6873 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
wolfSSL 7:481bce714567 6874 keys, keysLen);
wolfSSL 7:481bce714567 6875 break;
wolfSSL 7:481bce714567 6876
wolfSSL 7:481bce714567 6877 default:
wolfSSL 7:481bce714567 6878 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6879 break;
wolfSSL 7:481bce714567 6880 }
wolfSSL 7:481bce714567 6881 }
wolfSSL 7:481bce714567 6882
wolfSSL 7:481bce714567 6883 if (ret == 0) {
wolfSSL 7:481bce714567 6884 encKey = keys + offset;
wolfSSL 7:481bce714567 6885 encIv = encKey + encKeySz;
wolfSSL 7:481bce714567 6886 macKey = encKey + encKeySz + ivSz;
wolfSSL 7:481bce714567 6887
wolfSSL 7:481bce714567 6888 switch (ctx->encAlgo) {
wolfSSL 7:481bce714567 6889 case ecAES_128_CBC:
wolfSSL 7:481bce714567 6890 {
wolfSSL 7:481bce714567 6891 Aes aes;
wolfSSL 7:481bce714567 6892 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
wolfSSL 7:481bce714567 6893 AES_ENCRYPTION);
wolfSSL 7:481bce714567 6894 if (ret != 0)
wolfSSL 7:481bce714567 6895 break;
wolfSSL 7:481bce714567 6896 ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
wolfSSL 7:481bce714567 6897 }
wolfSSL 7:481bce714567 6898 break;
wolfSSL 7:481bce714567 6899
wolfSSL 7:481bce714567 6900 default:
wolfSSL 7:481bce714567 6901 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6902 break;
wolfSSL 7:481bce714567 6903 }
wolfSSL 7:481bce714567 6904 }
wolfSSL 7:481bce714567 6905
wolfSSL 7:481bce714567 6906 if (ret == 0) {
wolfSSL 7:481bce714567 6907 switch (ctx->macAlgo) {
wolfSSL 7:481bce714567 6908 case ecHMAC_SHA256:
wolfSSL 7:481bce714567 6909 {
wolfSSL 7:481bce714567 6910 Hmac hmac;
wolfSSL 7:481bce714567 6911 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
wolfSSL 7:481bce714567 6912 if (ret != 0)
wolfSSL 7:481bce714567 6913 break;
wolfSSL 7:481bce714567 6914 ret = wc_HmacUpdate(&hmac, out, msgSz);
wolfSSL 7:481bce714567 6915 if (ret != 0)
wolfSSL 7:481bce714567 6916 break;
wolfSSL 7:481bce714567 6917 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
wolfSSL 7:481bce714567 6918 if (ret != 0)
wolfSSL 7:481bce714567 6919 break;
wolfSSL 7:481bce714567 6920 ret = wc_HmacFinal(&hmac, out+msgSz);
wolfSSL 7:481bce714567 6921 }
wolfSSL 7:481bce714567 6922 break;
wolfSSL 7:481bce714567 6923
wolfSSL 7:481bce714567 6924 default:
wolfSSL 7:481bce714567 6925 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6926 break;
wolfSSL 7:481bce714567 6927 }
wolfSSL 7:481bce714567 6928 }
wolfSSL 7:481bce714567 6929
wolfSSL 7:481bce714567 6930 if (ret == 0)
wolfSSL 7:481bce714567 6931 *outSz = msgSz + digestSz;
wolfSSL 7:481bce714567 6932
wolfSSL 7:481bce714567 6933 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6934 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6935 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 6936 #endif
wolfSSL 7:481bce714567 6937
wolfSSL 7:481bce714567 6938 return ret;
wolfSSL 7:481bce714567 6939 }
wolfSSL 7:481bce714567 6940
wolfSSL 7:481bce714567 6941
wolfSSL 7:481bce714567 6942 /* ecc decrypt with shared secret run through kdf
wolfSSL 7:481bce714567 6943 ctx holds non default algos and inputs
wolfSSL 7:481bce714567 6944 return 0 on success */
wolfSSL 7:481bce714567 6945 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
wolfSSL 7:481bce714567 6946 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
wolfSSL 7:481bce714567 6947 {
wolfSSL 7:481bce714567 6948 int ret;
wolfSSL 7:481bce714567 6949 word32 blockSz;
wolfSSL 7:481bce714567 6950 word32 digestSz;
wolfSSL 7:481bce714567 6951 ecEncCtx localCtx;
wolfSSL 7:481bce714567 6952 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 6953 byte* sharedSecret;
wolfSSL 7:481bce714567 6954 byte* keys;
wolfSSL 7:481bce714567 6955 #else
wolfSSL 7:481bce714567 6956 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
wolfSSL 7:481bce714567 6957 byte keys[ECC_BUFSIZE]; /* max size */
wolfSSL 7:481bce714567 6958 #endif
wolfSSL 7:481bce714567 6959 word32 sharedSz = ECC_MAXSIZE;
wolfSSL 7:481bce714567 6960 int keysLen;
wolfSSL 7:481bce714567 6961 int encKeySz;
wolfSSL 7:481bce714567 6962 int ivSz;
wolfSSL 7:481bce714567 6963 int offset = 0; /* in case using msg exchange */
wolfSSL 7:481bce714567 6964 byte* encKey;
wolfSSL 7:481bce714567 6965 byte* encIv;
wolfSSL 7:481bce714567 6966 byte* macKey;
wolfSSL 7:481bce714567 6967
wolfSSL 7:481bce714567 6968 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
wolfSSL 7:481bce714567 6969 outSz == NULL)
wolfSSL 7:481bce714567 6970 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 6971
wolfSSL 7:481bce714567 6972 if (ctx == NULL) { /* use defaults */
wolfSSL 7:481bce714567 6973 ecc_ctx_init(&localCtx, 0);
wolfSSL 7:481bce714567 6974 ctx = &localCtx;
wolfSSL 7:481bce714567 6975 }
wolfSSL 7:481bce714567 6976
wolfSSL 7:481bce714567 6977 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
wolfSSL 7:481bce714567 6978 &blockSz);
wolfSSL 7:481bce714567 6979 if (ret != 0)
wolfSSL 7:481bce714567 6980 return ret;
wolfSSL 7:481bce714567 6981
wolfSSL 7:481bce714567 6982 if (ctx->protocol == REQ_RESP_CLIENT) {
wolfSSL 7:481bce714567 6983 offset = keysLen;
wolfSSL 7:481bce714567 6984 keysLen *= 2;
wolfSSL 7:481bce714567 6985
wolfSSL 7:481bce714567 6986 if (ctx->cliSt != ecCLI_SENT_REQ)
wolfSSL 7:481bce714567 6987 return BAD_STATE_E;
wolfSSL 7:481bce714567 6988
wolfSSL 7:481bce714567 6989 ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
wolfSSL 7:481bce714567 6990 }
wolfSSL 7:481bce714567 6991 else if (ctx->protocol == REQ_RESP_SERVER) {
wolfSSL 7:481bce714567 6992 if (ctx->srvSt != ecSRV_SALT_SET)
wolfSSL 7:481bce714567 6993 return BAD_STATE_E;
wolfSSL 7:481bce714567 6994
wolfSSL 7:481bce714567 6995 ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
wolfSSL 7:481bce714567 6996 }
wolfSSL 7:481bce714567 6997
wolfSSL 7:481bce714567 6998 if (keysLen > ECC_BUFSIZE) /* keys size */
wolfSSL 7:481bce714567 6999 return BUFFER_E;
wolfSSL 7:481bce714567 7000
wolfSSL 7:481bce714567 7001 if ( ((msgSz-digestSz) % blockSz) != 0)
wolfSSL 7:481bce714567 7002 return BAD_PADDING_E;
wolfSSL 7:481bce714567 7003
wolfSSL 7:481bce714567 7004 if (*outSz < (msgSz - digestSz))
wolfSSL 7:481bce714567 7005 return BUFFER_E;
wolfSSL 7:481bce714567 7006
wolfSSL 7:481bce714567 7007 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7008 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7009 if (sharedSecret == NULL)
wolfSSL 7:481bce714567 7010 return MEMORY_E;
wolfSSL 7:481bce714567 7011
wolfSSL 7:481bce714567 7012 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7013 if (keys == NULL) {
wolfSSL 7:481bce714567 7014 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7015 return MEMORY_E;
wolfSSL 7:481bce714567 7016 }
wolfSSL 7:481bce714567 7017 #endif
wolfSSL 7:481bce714567 7018
wolfSSL 7:481bce714567 7019 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
wolfSSL 7:481bce714567 7020
wolfSSL 7:481bce714567 7021 if (ret == 0) {
wolfSSL 7:481bce714567 7022 switch (ctx->kdfAlgo) {
wolfSSL 7:481bce714567 7023 case ecHKDF_SHA256 :
wolfSSL 7:481bce714567 7024 ret = wc_HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
wolfSSL 7:481bce714567 7025 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
wolfSSL 7:481bce714567 7026 keys, keysLen);
wolfSSL 7:481bce714567 7027 break;
wolfSSL 7:481bce714567 7028
wolfSSL 7:481bce714567 7029 default:
wolfSSL 7:481bce714567 7030 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7031 break;
wolfSSL 7:481bce714567 7032 }
wolfSSL 7:481bce714567 7033 }
wolfSSL 7:481bce714567 7034
wolfSSL 7:481bce714567 7035 if (ret == 0) {
wolfSSL 7:481bce714567 7036 encKey = keys + offset;
wolfSSL 7:481bce714567 7037 encIv = encKey + encKeySz;
wolfSSL 7:481bce714567 7038 macKey = encKey + encKeySz + ivSz;
wolfSSL 7:481bce714567 7039
wolfSSL 7:481bce714567 7040 switch (ctx->macAlgo) {
wolfSSL 7:481bce714567 7041 case ecHMAC_SHA256:
wolfSSL 7:481bce714567 7042 {
wolfSSL 7:481bce714567 7043 byte verify[SHA256_DIGEST_SIZE];
wolfSSL 7:481bce714567 7044 Hmac hmac;
wolfSSL 7:481bce714567 7045 ret = wc_HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE);
wolfSSL 7:481bce714567 7046 if (ret != 0)
wolfSSL 7:481bce714567 7047 break;
wolfSSL 7:481bce714567 7048 ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
wolfSSL 7:481bce714567 7049 if (ret != 0)
wolfSSL 7:481bce714567 7050 break;
wolfSSL 7:481bce714567 7051 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
wolfSSL 7:481bce714567 7052 if (ret != 0)
wolfSSL 7:481bce714567 7053 break;
wolfSSL 7:481bce714567 7054 ret = wc_HmacFinal(&hmac, verify);
wolfSSL 7:481bce714567 7055 if (ret != 0)
wolfSSL 7:481bce714567 7056 break;
wolfSSL 7:481bce714567 7057 if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
wolfSSL 7:481bce714567 7058 ret = -1;
wolfSSL 7:481bce714567 7059 }
wolfSSL 7:481bce714567 7060 break;
wolfSSL 7:481bce714567 7061
wolfSSL 7:481bce714567 7062 default:
wolfSSL 7:481bce714567 7063 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7064 break;
wolfSSL 7:481bce714567 7065 }
wolfSSL 7:481bce714567 7066 }
wolfSSL 7:481bce714567 7067
wolfSSL 7:481bce714567 7068 if (ret == 0) {
wolfSSL 7:481bce714567 7069 switch (ctx->encAlgo) {
wolfSSL 7:481bce714567 7070 #ifdef HAVE_AES_CBC
wolfSSL 7:481bce714567 7071 case ecAES_128_CBC:
wolfSSL 7:481bce714567 7072 {
wolfSSL 7:481bce714567 7073 Aes aes;
wolfSSL 7:481bce714567 7074 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
wolfSSL 7:481bce714567 7075 AES_DECRYPTION);
wolfSSL 7:481bce714567 7076 if (ret != 0)
wolfSSL 7:481bce714567 7077 break;
wolfSSL 7:481bce714567 7078 ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
wolfSSL 7:481bce714567 7079 }
wolfSSL 7:481bce714567 7080 break;
wolfSSL 7:481bce714567 7081 #endif
wolfSSL 7:481bce714567 7082 default:
wolfSSL 7:481bce714567 7083 ret = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7084 break;
wolfSSL 7:481bce714567 7085 }
wolfSSL 7:481bce714567 7086 }
wolfSSL 7:481bce714567 7087
wolfSSL 7:481bce714567 7088 if (ret == 0)
wolfSSL 7:481bce714567 7089 *outSz = msgSz - digestSz;
wolfSSL 7:481bce714567 7090
wolfSSL 7:481bce714567 7091 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7092 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7093 XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7094 #endif
wolfSSL 7:481bce714567 7095
wolfSSL 7:481bce714567 7096 return ret;
wolfSSL 7:481bce714567 7097 }
wolfSSL 7:481bce714567 7098
wolfSSL 7:481bce714567 7099
wolfSSL 7:481bce714567 7100 #endif /* HAVE_ECC_ENCRYPT */
wolfSSL 7:481bce714567 7101
wolfSSL 7:481bce714567 7102
wolfSSL 7:481bce714567 7103 #ifdef HAVE_COMP_KEY
wolfSSL 7:481bce714567 7104 #ifndef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 7105
wolfSSL 7:481bce714567 7106 int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
wolfSSL 7:481bce714567 7107
wolfSSL 7:481bce714567 7108 int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
wolfSSL 7:481bce714567 7109 {
wolfSSL 7:481bce714567 7110 int k, s, r, res;
wolfSSL 7:481bce714567 7111 mp_digit residue;
wolfSSL 7:481bce714567 7112
wolfSSL 7:481bce714567 7113 /* if a < 0 return MP_VAL */
wolfSSL 7:481bce714567 7114 if (mp_isneg(a) == MP_YES) {
wolfSSL 7:481bce714567 7115 return MP_VAL;
wolfSSL 7:481bce714567 7116 }
wolfSSL 7:481bce714567 7117
wolfSSL 7:481bce714567 7118 /* if n <= 0 return MP_VAL */
wolfSSL 7:481bce714567 7119 if (mp_cmp_d(n, 0) != MP_GT) {
wolfSSL 7:481bce714567 7120 return MP_VAL;
wolfSSL 7:481bce714567 7121 }
wolfSSL 7:481bce714567 7122
wolfSSL 7:481bce714567 7123 /* step 1. handle case of a == 0 */
wolfSSL 7:481bce714567 7124 if (mp_iszero (a) == MP_YES) {
wolfSSL 7:481bce714567 7125 /* special case of a == 0 and n == 1 */
wolfSSL 7:481bce714567 7126 if (mp_cmp_d (n, 1) == MP_EQ) {
wolfSSL 7:481bce714567 7127 *c = 1;
wolfSSL 7:481bce714567 7128 } else {
wolfSSL 7:481bce714567 7129 *c = 0;
wolfSSL 7:481bce714567 7130 }
wolfSSL 7:481bce714567 7131 return MP_OKAY;
wolfSSL 7:481bce714567 7132 }
wolfSSL 7:481bce714567 7133
wolfSSL 7:481bce714567 7134 /* step 2. if a == 1, return 1 */
wolfSSL 7:481bce714567 7135 if (mp_cmp_d (a, 1) == MP_EQ) {
wolfSSL 7:481bce714567 7136 *c = 1;
wolfSSL 7:481bce714567 7137 return MP_OKAY;
wolfSSL 7:481bce714567 7138 }
wolfSSL 7:481bce714567 7139
wolfSSL 7:481bce714567 7140 /* default */
wolfSSL 7:481bce714567 7141 s = 0;
wolfSSL 7:481bce714567 7142
wolfSSL 7:481bce714567 7143 /* divide out larger power of two */
wolfSSL 7:481bce714567 7144 k = mp_cnt_lsb(a);
wolfSSL 7:481bce714567 7145 res = mp_div_2d(a, k, a, NULL);
wolfSSL 7:481bce714567 7146
wolfSSL 7:481bce714567 7147 if (res == MP_OKAY) {
wolfSSL 7:481bce714567 7148 /* step 4. if e is even set s=1 */
wolfSSL 7:481bce714567 7149 if ((k & 1) == 0) {
wolfSSL 7:481bce714567 7150 s = 1;
wolfSSL 7:481bce714567 7151 } else {
wolfSSL 7:481bce714567 7152 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
wolfSSL 7:481bce714567 7153 residue = n->dp[0] & 7;
wolfSSL 7:481bce714567 7154
wolfSSL 7:481bce714567 7155 if (residue == 1 || residue == 7) {
wolfSSL 7:481bce714567 7156 s = 1;
wolfSSL 7:481bce714567 7157 } else if (residue == 3 || residue == 5) {
wolfSSL 7:481bce714567 7158 s = -1;
wolfSSL 7:481bce714567 7159 }
wolfSSL 7:481bce714567 7160 }
wolfSSL 7:481bce714567 7161
wolfSSL 7:481bce714567 7162 /* step 5. if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */
wolfSSL 7:481bce714567 7163 if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {
wolfSSL 7:481bce714567 7164 s = -s;
wolfSSL 7:481bce714567 7165 }
wolfSSL 7:481bce714567 7166 }
wolfSSL 7:481bce714567 7167
wolfSSL 7:481bce714567 7168 if (res == MP_OKAY) {
wolfSSL 7:481bce714567 7169 /* if a == 1 we're done */
wolfSSL 7:481bce714567 7170 if (mp_cmp_d(a, 1) == MP_EQ) {
wolfSSL 7:481bce714567 7171 *c = s;
wolfSSL 7:481bce714567 7172 } else {
wolfSSL 7:481bce714567 7173 /* n1 = n mod a */
wolfSSL 7:481bce714567 7174 res = mp_mod (n, a, n);
wolfSSL 7:481bce714567 7175 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7176 res = do_mp_jacobi(n, a, &r);
wolfSSL 7:481bce714567 7177
wolfSSL 7:481bce714567 7178 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7179 *c = s * r;
wolfSSL 7:481bce714567 7180 }
wolfSSL 7:481bce714567 7181 }
wolfSSL 7:481bce714567 7182
wolfSSL 7:481bce714567 7183 return res;
wolfSSL 7:481bce714567 7184 }
wolfSSL 7:481bce714567 7185
wolfSSL 7:481bce714567 7186
wolfSSL 7:481bce714567 7187 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
wolfSSL 7:481bce714567 7188 * HAC pp. 73 Algorithm 2.149
wolfSSL 7:481bce714567 7189 * HAC is wrong here, as the special case of (0 | 1) is not
wolfSSL 7:481bce714567 7190 * handled correctly.
wolfSSL 7:481bce714567 7191 */
wolfSSL 7:481bce714567 7192 int mp_jacobi(mp_int* a, mp_int* n, int* c)
wolfSSL 7:481bce714567 7193 {
wolfSSL 7:481bce714567 7194 mp_int a1, n1;
wolfSSL 7:481bce714567 7195 int res;
wolfSSL 7:481bce714567 7196
wolfSSL 7:481bce714567 7197 /* step 3. write a = a1 * 2**k */
wolfSSL 7:481bce714567 7198 if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
wolfSSL 7:481bce714567 7199 return res;
wolfSSL 7:481bce714567 7200 }
wolfSSL 7:481bce714567 7201
wolfSSL 7:481bce714567 7202 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
wolfSSL 7:481bce714567 7203 goto done;
wolfSSL 7:481bce714567 7204 }
wolfSSL 7:481bce714567 7205
wolfSSL 7:481bce714567 7206 if ((res = mp_copy(n, &n1)) != MP_OKAY) {
wolfSSL 7:481bce714567 7207 goto done;
wolfSSL 7:481bce714567 7208 }
wolfSSL 7:481bce714567 7209
wolfSSL 7:481bce714567 7210 res = do_mp_jacobi(&a1, &n1, c);
wolfSSL 7:481bce714567 7211
wolfSSL 7:481bce714567 7212 done:
wolfSSL 7:481bce714567 7213 /* cleanup */
wolfSSL 7:481bce714567 7214 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 7215 mp_clear(&n1);
wolfSSL 7:481bce714567 7216 mp_clear(&a1);
wolfSSL 7:481bce714567 7217 #endif
wolfSSL 7:481bce714567 7218
wolfSSL 7:481bce714567 7219 return res;
wolfSSL 7:481bce714567 7220 }
wolfSSL 7:481bce714567 7221
wolfSSL 7:481bce714567 7222
wolfSSL 7:481bce714567 7223 /* Solves the modular equation x^2 = n (mod p)
wolfSSL 7:481bce714567 7224 * where prime number is greater than 2 (odd prime).
wolfSSL 7:481bce714567 7225 * The result is returned in the third argument x
wolfSSL 7:481bce714567 7226 * the function returns MP_OKAY on success, MP_VAL or another error on failure
wolfSSL 7:481bce714567 7227 */
wolfSSL 7:481bce714567 7228 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
wolfSSL 7:481bce714567 7229 {
wolfSSL 7:481bce714567 7230 int res, legendre, done = 0;
wolfSSL 7:481bce714567 7231 mp_int t1, C, Q, S, Z, M, T, R, two;
wolfSSL 7:481bce714567 7232 mp_digit i;
wolfSSL 7:481bce714567 7233
wolfSSL 7:481bce714567 7234 /* first handle the simple cases n = 0 or n = 1 */
wolfSSL 7:481bce714567 7235 if (mp_cmp_d(n, 0) == MP_EQ) {
wolfSSL 7:481bce714567 7236 mp_zero(ret);
wolfSSL 7:481bce714567 7237 return MP_OKAY;
wolfSSL 7:481bce714567 7238 }
wolfSSL 7:481bce714567 7239 if (mp_cmp_d(n, 1) == MP_EQ) {
wolfSSL 7:481bce714567 7240 return mp_set(ret, 1);
wolfSSL 7:481bce714567 7241 }
wolfSSL 7:481bce714567 7242
wolfSSL 7:481bce714567 7243 /* prime must be odd */
wolfSSL 7:481bce714567 7244 if (mp_cmp_d(prime, 2) == MP_EQ) {
wolfSSL 7:481bce714567 7245 return MP_VAL;
wolfSSL 7:481bce714567 7246 }
wolfSSL 7:481bce714567 7247
wolfSSL 7:481bce714567 7248 /* is quadratic non-residue mod prime */
wolfSSL 7:481bce714567 7249 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
wolfSSL 7:481bce714567 7250 return res;
wolfSSL 7:481bce714567 7251 }
wolfSSL 7:481bce714567 7252 if (legendre == -1) {
wolfSSL 7:481bce714567 7253 return MP_VAL;
wolfSSL 7:481bce714567 7254 }
wolfSSL 7:481bce714567 7255
wolfSSL 7:481bce714567 7256 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
wolfSSL 7:481bce714567 7257 return res;
wolfSSL 7:481bce714567 7258
wolfSSL 7:481bce714567 7259 if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
wolfSSL 7:481bce714567 7260 != MP_OKAY) {
wolfSSL 7:481bce714567 7261 mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
wolfSSL 7:481bce714567 7262 mp_clear(&M);
wolfSSL 7:481bce714567 7263 return res;
wolfSSL 7:481bce714567 7264 }
wolfSSL 7:481bce714567 7265
wolfSSL 7:481bce714567 7266 /* SPECIAL CASE: if prime mod 4 == 3
wolfSSL 7:481bce714567 7267 * compute directly: res = n^(prime+1)/4 mod prime
wolfSSL 7:481bce714567 7268 * Handbook of Applied Cryptography algorithm 3.36
wolfSSL 7:481bce714567 7269 */
wolfSSL 7:481bce714567 7270 res = mp_mod_d(prime, 4, &i);
wolfSSL 7:481bce714567 7271 if (res == MP_OKAY && i == 3) {
wolfSSL 7:481bce714567 7272 res = mp_add_d(prime, 1, &t1);
wolfSSL 7:481bce714567 7273
wolfSSL 7:481bce714567 7274 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7275 res = mp_div_2(&t1, &t1);
wolfSSL 7:481bce714567 7276 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7277 res = mp_div_2(&t1, &t1);
wolfSSL 7:481bce714567 7278 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7279 res = mp_exptmod(n, &t1, prime, ret);
wolfSSL 7:481bce714567 7280
wolfSSL 7:481bce714567 7281 done = 1;
wolfSSL 7:481bce714567 7282 }
wolfSSL 7:481bce714567 7283
wolfSSL 7:481bce714567 7284 /* NOW: TonelliShanks algorithm */
wolfSSL 7:481bce714567 7285 if (res == MP_OKAY && done == 0) {
wolfSSL 7:481bce714567 7286
wolfSSL 7:481bce714567 7287 /* factor out powers of 2 from prime-1, defining Q and S
wolfSSL 7:481bce714567 7288 * as: prime-1 = Q*2^S */
wolfSSL 7:481bce714567 7289 /* Q = prime - 1 */
wolfSSL 7:481bce714567 7290 res = mp_copy(prime, &Q);
wolfSSL 7:481bce714567 7291 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7292 res = mp_sub_d(&Q, 1, &Q);
wolfSSL 7:481bce714567 7293
wolfSSL 7:481bce714567 7294 /* S = 0 */
wolfSSL 7:481bce714567 7295 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7296 mp_zero(&S);
wolfSSL 7:481bce714567 7297
wolfSSL 7:481bce714567 7298 while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
wolfSSL 7:481bce714567 7299 /* Q = Q / 2 */
wolfSSL 7:481bce714567 7300 res = mp_div_2(&Q, &Q);
wolfSSL 7:481bce714567 7301
wolfSSL 7:481bce714567 7302 /* S = S + 1 */
wolfSSL 7:481bce714567 7303 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7304 res = mp_add_d(&S, 1, &S);
wolfSSL 7:481bce714567 7305 }
wolfSSL 7:481bce714567 7306
wolfSSL 7:481bce714567 7307 /* find a Z such that the Legendre symbol (Z|prime) == -1 */
wolfSSL 7:481bce714567 7308 /* Z = 2 */
wolfSSL 7:481bce714567 7309 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7310 res = mp_set_int(&Z, 2);
wolfSSL 7:481bce714567 7311
wolfSSL 7:481bce714567 7312 while (res == MP_OKAY) {
wolfSSL 7:481bce714567 7313 res = mp_jacobi(&Z, prime, &legendre);
wolfSSL 7:481bce714567 7314 if (res == MP_OKAY && legendre == -1)
wolfSSL 7:481bce714567 7315 break;
wolfSSL 7:481bce714567 7316
wolfSSL 7:481bce714567 7317 /* Z = Z + 1 */
wolfSSL 7:481bce714567 7318 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7319 res = mp_add_d(&Z, 1, &Z);
wolfSSL 7:481bce714567 7320 }
wolfSSL 7:481bce714567 7321
wolfSSL 7:481bce714567 7322 /* C = Z ^ Q mod prime */
wolfSSL 7:481bce714567 7323 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7324 res = mp_exptmod(&Z, &Q, prime, &C);
wolfSSL 7:481bce714567 7325
wolfSSL 7:481bce714567 7326 /* t1 = (Q + 1) / 2 */
wolfSSL 7:481bce714567 7327 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7328 res = mp_add_d(&Q, 1, &t1);
wolfSSL 7:481bce714567 7329 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7330 res = mp_div_2(&t1, &t1);
wolfSSL 7:481bce714567 7331
wolfSSL 7:481bce714567 7332 /* R = n ^ ((Q + 1) / 2) mod prime */
wolfSSL 7:481bce714567 7333 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7334 res = mp_exptmod(n, &t1, prime, &R);
wolfSSL 7:481bce714567 7335
wolfSSL 7:481bce714567 7336 /* T = n ^ Q mod prime */
wolfSSL 7:481bce714567 7337 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7338 res = mp_exptmod(n, &Q, prime, &T);
wolfSSL 7:481bce714567 7339
wolfSSL 7:481bce714567 7340 /* M = S */
wolfSSL 7:481bce714567 7341 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7342 res = mp_copy(&S, &M);
wolfSSL 7:481bce714567 7343
wolfSSL 7:481bce714567 7344 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7345 res = mp_set_int(&two, 2);
wolfSSL 7:481bce714567 7346
wolfSSL 7:481bce714567 7347 while (res == MP_OKAY && done == 0) {
wolfSSL 7:481bce714567 7348 res = mp_copy(&T, &t1);
wolfSSL 7:481bce714567 7349
wolfSSL 7:481bce714567 7350 /* reduce to 1 and count */
wolfSSL 7:481bce714567 7351 i = 0;
wolfSSL 7:481bce714567 7352 while (res == MP_OKAY) {
wolfSSL 7:481bce714567 7353 if (mp_cmp_d(&t1, 1) == MP_EQ)
wolfSSL 7:481bce714567 7354 break;
wolfSSL 7:481bce714567 7355 res = mp_exptmod(&t1, &two, prime, &t1);
wolfSSL 7:481bce714567 7356 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7357 i++;
wolfSSL 7:481bce714567 7358 }
wolfSSL 7:481bce714567 7359 if (res == MP_OKAY && i == 0) {
wolfSSL 7:481bce714567 7360 res = mp_copy(&R, ret);
wolfSSL 7:481bce714567 7361 done = 1;
wolfSSL 7:481bce714567 7362 }
wolfSSL 7:481bce714567 7363
wolfSSL 7:481bce714567 7364 if (done == 0) {
wolfSSL 7:481bce714567 7365 /* t1 = 2 ^ (M - i - 1) */
wolfSSL 7:481bce714567 7366 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7367 res = mp_sub_d(&M, i, &t1);
wolfSSL 7:481bce714567 7368 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7369 res = mp_sub_d(&t1, 1, &t1);
wolfSSL 7:481bce714567 7370 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7371 res = mp_exptmod(&two, &t1, prime, &t1);
wolfSSL 7:481bce714567 7372
wolfSSL 7:481bce714567 7373 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
wolfSSL 7:481bce714567 7374 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7375 res = mp_exptmod(&C, &t1, prime, &t1);
wolfSSL 7:481bce714567 7376
wolfSSL 7:481bce714567 7377 /* C = (t1 * t1) mod prime */
wolfSSL 7:481bce714567 7378 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7379 res = mp_sqrmod(&t1, prime, &C);
wolfSSL 7:481bce714567 7380
wolfSSL 7:481bce714567 7381 /* R = (R * t1) mod prime */
wolfSSL 7:481bce714567 7382 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7383 res = mp_mulmod(&R, &t1, prime, &R);
wolfSSL 7:481bce714567 7384
wolfSSL 7:481bce714567 7385 /* T = (T * C) mod prime */
wolfSSL 7:481bce714567 7386 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7387 res = mp_mulmod(&T, &C, prime, &T);
wolfSSL 7:481bce714567 7388
wolfSSL 7:481bce714567 7389 /* M = i */
wolfSSL 7:481bce714567 7390 if (res == MP_OKAY)
wolfSSL 7:481bce714567 7391 res = mp_set(&M, i);
wolfSSL 7:481bce714567 7392 }
wolfSSL 7:481bce714567 7393 }
wolfSSL 7:481bce714567 7394 }
wolfSSL 7:481bce714567 7395
wolfSSL 7:481bce714567 7396 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 7397 /* done */
wolfSSL 7:481bce714567 7398 mp_clear(&t1);
wolfSSL 7:481bce714567 7399 mp_clear(&C);
wolfSSL 7:481bce714567 7400 mp_clear(&Q);
wolfSSL 7:481bce714567 7401 mp_clear(&S);
wolfSSL 7:481bce714567 7402 mp_clear(&Z);
wolfSSL 7:481bce714567 7403 mp_clear(&M);
wolfSSL 7:481bce714567 7404 mp_clear(&T);
wolfSSL 7:481bce714567 7405 mp_clear(&R);
wolfSSL 7:481bce714567 7406 mp_clear(&two);
wolfSSL 7:481bce714567 7407 #endif
wolfSSL 7:481bce714567 7408
wolfSSL 7:481bce714567 7409 return res;
wolfSSL 7:481bce714567 7410 }
wolfSSL 7:481bce714567 7411 #endif /* !WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 7412
wolfSSL 7:481bce714567 7413
wolfSSL 7:481bce714567 7414 /* export public ECC key in ANSI X9.63 format compressed */
wolfSSL 7:481bce714567 7415 static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
wolfSSL 7:481bce714567 7416 {
wolfSSL 7:481bce714567 7417 word32 numlen;
wolfSSL 7:481bce714567 7418 int ret = MP_OKAY;
wolfSSL 7:481bce714567 7419
wolfSSL 7:481bce714567 7420 if (key == NULL || out == NULL || outLen == NULL)
wolfSSL 7:481bce714567 7421 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7422
wolfSSL 7:481bce714567 7423 if (wc_ecc_is_valid_idx(key->idx) == 0) {
wolfSSL 7:481bce714567 7424 return ECC_BAD_ARG_E;
wolfSSL 7:481bce714567 7425 }
wolfSSL 7:481bce714567 7426 numlen = key->dp->size;
wolfSSL 7:481bce714567 7427
wolfSSL 7:481bce714567 7428 if (*outLen < (1 + numlen)) {
wolfSSL 7:481bce714567 7429 *outLen = 1 + numlen;
wolfSSL 7:481bce714567 7430 return BUFFER_E;
wolfSSL 7:481bce714567 7431 }
wolfSSL 7:481bce714567 7432
wolfSSL 7:481bce714567 7433 #ifdef WOLFSSL_ATECC508A
wolfSSL 7:481bce714567 7434 /* TODO: Implement equiv call to ATECC508A */
wolfSSL 7:481bce714567 7435 ret = BAD_COND_E;
wolfSSL 7:481bce714567 7436
wolfSSL 7:481bce714567 7437 #else
wolfSSL 7:481bce714567 7438
wolfSSL 7:481bce714567 7439 /* store first byte */
wolfSSL 7:481bce714567 7440 out[0] = mp_isodd(key->pubkey.y) == MP_YES ? 0x03 : 0x02;
wolfSSL 7:481bce714567 7441
wolfSSL 7:481bce714567 7442 /* pad and store x */
wolfSSL 7:481bce714567 7443 XMEMSET(out+1, 0, numlen);
wolfSSL 7:481bce714567 7444 ret = mp_to_unsigned_bin(key->pubkey.x,
wolfSSL 7:481bce714567 7445 out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
wolfSSL 7:481bce714567 7446 *outLen = 1 + numlen;
wolfSSL 7:481bce714567 7447
wolfSSL 7:481bce714567 7448 #endif /* WOLFSSL_ATECC508A */
wolfSSL 7:481bce714567 7449
wolfSSL 7:481bce714567 7450 return ret;
wolfSSL 7:481bce714567 7451 }
wolfSSL 7:481bce714567 7452
wolfSSL 7:481bce714567 7453 #endif /* HAVE_COMP_KEY */
wolfSSL 7:481bce714567 7454
wolfSSL 7:481bce714567 7455
wolfSSL 7:481bce714567 7456 int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
wolfSSL 7:481bce714567 7457 {
wolfSSL 7:481bce714567 7458 int x;
wolfSSL 7:481bce714567 7459
wolfSSL 7:481bce714567 7460 if (oidSum == 0) {
wolfSSL 7:481bce714567 7461 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7462 }
wolfSSL 7:481bce714567 7463
wolfSSL 7:481bce714567 7464 /* find matching OID sum (based on encoded value) */
wolfSSL 7:481bce714567 7465 for (x = 0; ecc_sets[x].size != 0; x++) {
wolfSSL 7:481bce714567 7466 if (ecc_sets[x].oidSum == oidSum) {
wolfSSL 7:481bce714567 7467 int ret = 0;
wolfSSL 7:481bce714567 7468 #ifdef HAVE_OID_ENCODING
wolfSSL 7:481bce714567 7469 /* check cache */
wolfSSL 7:481bce714567 7470 oid_cache_t* o = &ecc_oid_cache[x];
wolfSSL 7:481bce714567 7471 if (o->oidSz == 0) {
wolfSSL 7:481bce714567 7472 o->oidSz = sizeof(o->oid);
wolfSSL 7:481bce714567 7473 ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
wolfSSL 7:481bce714567 7474 o->oid, &o->oidSz);
wolfSSL 7:481bce714567 7475 }
wolfSSL 7:481bce714567 7476 if (oidSz) {
wolfSSL 7:481bce714567 7477 *oidSz = o->oidSz;
wolfSSL 7:481bce714567 7478 }
wolfSSL 7:481bce714567 7479 if (oid) {
wolfSSL 7:481bce714567 7480 *oid = o->oid;
wolfSSL 7:481bce714567 7481 }
wolfSSL 7:481bce714567 7482 #else
wolfSSL 7:481bce714567 7483 if (oidSz) {
wolfSSL 7:481bce714567 7484 *oidSz = ecc_sets[x].oidSz;
wolfSSL 7:481bce714567 7485 }
wolfSSL 7:481bce714567 7486 if (oid) {
wolfSSL 7:481bce714567 7487 *oid = ecc_sets[x].oid;
wolfSSL 7:481bce714567 7488 }
wolfSSL 7:481bce714567 7489 #endif
wolfSSL 7:481bce714567 7490 /* on success return curve id */
wolfSSL 7:481bce714567 7491 if (ret == 0) {
wolfSSL 7:481bce714567 7492 ret = ecc_sets[x].id;
wolfSSL 7:481bce714567 7493 }
wolfSSL 7:481bce714567 7494 return ret;
wolfSSL 7:481bce714567 7495 }
wolfSSL 7:481bce714567 7496 }
wolfSSL 7:481bce714567 7497
wolfSSL 7:481bce714567 7498 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 7499 }
wolfSSL 7:481bce714567 7500
wolfSSL 7:481bce714567 7501 #ifdef WOLFSSL_CUSTOM_CURVES
wolfSSL 7:481bce714567 7502 int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
wolfSSL 7:481bce714567 7503 {
wolfSSL 7:481bce714567 7504 if (key == NULL || dp == NULL) {
wolfSSL 7:481bce714567 7505 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7506 }
wolfSSL 7:481bce714567 7507
wolfSSL 7:481bce714567 7508 key->idx = ECC_CUSTOM_IDX;
wolfSSL 7:481bce714567 7509 key->dp = dp;
wolfSSL 7:481bce714567 7510
wolfSSL 7:481bce714567 7511 return 0;
wolfSSL 7:481bce714567 7512 }
wolfSSL 7:481bce714567 7513 #endif /* WOLFSSL_CUSTOM_CURVES */
wolfSSL 7:481bce714567 7514
wolfSSL 7:481bce714567 7515 #ifdef HAVE_X963_KDF
wolfSSL 7:481bce714567 7516
wolfSSL 7:481bce714567 7517 static INLINE void IncrementX963KdfCounter(byte* inOutCtr)
wolfSSL 7:481bce714567 7518 {
wolfSSL 7:481bce714567 7519 int i;
wolfSSL 7:481bce714567 7520
wolfSSL 7:481bce714567 7521 /* in network byte order so start at end and work back */
wolfSSL 7:481bce714567 7522 for (i = 3; i >= 0; i--) {
wolfSSL 7:481bce714567 7523 if (++inOutCtr[i]) /* we're done unless we overflow */
wolfSSL 7:481bce714567 7524 return;
wolfSSL 7:481bce714567 7525 }
wolfSSL 7:481bce714567 7526 }
wolfSSL 7:481bce714567 7527
wolfSSL 7:481bce714567 7528 /* ASN X9.63 Key Derivation Function (SEC1) */
wolfSSL 7:481bce714567 7529 int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
wolfSSL 7:481bce714567 7530 const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
wolfSSL 7:481bce714567 7531 {
wolfSSL 7:481bce714567 7532 int ret, i;
wolfSSL 7:481bce714567 7533 int digestSz, copySz;
wolfSSL 7:481bce714567 7534 int remaining = outSz;
wolfSSL 7:481bce714567 7535 byte* outIdx;
wolfSSL 7:481bce714567 7536 byte counter[4];
wolfSSL 7:481bce714567 7537 byte tmp[WC_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 7538
wolfSSL 7:481bce714567 7539 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7540 wc_HashAlg* hash;
wolfSSL 7:481bce714567 7541 #else
wolfSSL 7:481bce714567 7542 wc_HashAlg hash[1];
wolfSSL 7:481bce714567 7543 #endif
wolfSSL 7:481bce714567 7544
wolfSSL 7:481bce714567 7545 if (secret == NULL || secretSz == 0 || out == NULL)
wolfSSL 7:481bce714567 7546 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7547
wolfSSL 7:481bce714567 7548 /* X9.63 allowed algos only */
wolfSSL 7:481bce714567 7549 if (type != WC_HASH_TYPE_SHA && type != WC_HASH_TYPE_SHA224 &&
wolfSSL 7:481bce714567 7550 type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
wolfSSL 7:481bce714567 7551 type != WC_HASH_TYPE_SHA512)
wolfSSL 7:481bce714567 7552 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7553
wolfSSL 7:481bce714567 7554 digestSz = wc_HashGetDigestSize(type);
wolfSSL 7:481bce714567 7555 if (digestSz < 0)
wolfSSL 7:481bce714567 7556 return digestSz;
wolfSSL 7:481bce714567 7557
wolfSSL 7:481bce714567 7558 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7559 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
wolfSSL 7:481bce714567 7560 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7561 if (hash == NULL)
wolfSSL 7:481bce714567 7562 return MEMORY_E;
wolfSSL 7:481bce714567 7563 #endif
wolfSSL 7:481bce714567 7564
wolfSSL 7:481bce714567 7565 ret = wc_HashInit(hash, type);
wolfSSL 7:481bce714567 7566 if (ret != 0) {
wolfSSL 7:481bce714567 7567 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7568 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7569 #endif
wolfSSL 7:481bce714567 7570 return ret;
wolfSSL 7:481bce714567 7571 }
wolfSSL 7:481bce714567 7572
wolfSSL 7:481bce714567 7573 outIdx = out;
wolfSSL 7:481bce714567 7574 XMEMSET(counter, 0, sizeof(counter));
wolfSSL 7:481bce714567 7575
wolfSSL 7:481bce714567 7576 for (i = 1; remaining > 0; i++) {
wolfSSL 7:481bce714567 7577
wolfSSL 7:481bce714567 7578 IncrementX963KdfCounter(counter);
wolfSSL 7:481bce714567 7579
wolfSSL 7:481bce714567 7580 ret = wc_HashUpdate(hash, type, secret, secretSz);
wolfSSL 7:481bce714567 7581 if (ret != 0) {
wolfSSL 7:481bce714567 7582 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7583 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7584 #endif
wolfSSL 7:481bce714567 7585 return ret;
wolfSSL 7:481bce714567 7586 }
wolfSSL 7:481bce714567 7587
wolfSSL 7:481bce714567 7588 ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
wolfSSL 7:481bce714567 7589 if (ret != 0) {
wolfSSL 7:481bce714567 7590 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7591 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7592 #endif
wolfSSL 7:481bce714567 7593 return ret;
wolfSSL 7:481bce714567 7594 }
wolfSSL 7:481bce714567 7595
wolfSSL 7:481bce714567 7596 if (sinfo) {
wolfSSL 7:481bce714567 7597 ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
wolfSSL 7:481bce714567 7598 if (ret != 0) {
wolfSSL 7:481bce714567 7599 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7600 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7601 #endif
wolfSSL 7:481bce714567 7602 return ret;
wolfSSL 7:481bce714567 7603 }
wolfSSL 7:481bce714567 7604 }
wolfSSL 7:481bce714567 7605
wolfSSL 7:481bce714567 7606 ret = wc_HashFinal(hash, type, tmp);
wolfSSL 7:481bce714567 7607 if (ret != 0) {
wolfSSL 7:481bce714567 7608 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7609 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7610 #endif
wolfSSL 7:481bce714567 7611 return ret;
wolfSSL 7:481bce714567 7612 }
wolfSSL 7:481bce714567 7613
wolfSSL 7:481bce714567 7614 copySz = min(remaining, digestSz);
wolfSSL 7:481bce714567 7615 XMEMCPY(outIdx, tmp, copySz);
wolfSSL 7:481bce714567 7616
wolfSSL 7:481bce714567 7617 remaining -= copySz;
wolfSSL 7:481bce714567 7618 outIdx += copySz;
wolfSSL 7:481bce714567 7619 }
wolfSSL 7:481bce714567 7620
wolfSSL 7:481bce714567 7621 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 7:481bce714567 7622 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 7:481bce714567 7623 #endif
wolfSSL 7:481bce714567 7624
wolfSSL 7:481bce714567 7625 return 0;
wolfSSL 7:481bce714567 7626 }
wolfSSL 7:481bce714567 7627 #endif /* HAVE_X963_KDF */
wolfSSL 7:481bce714567 7628
wolfSSL 7:481bce714567 7629
wolfSSL 7:481bce714567 7630 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 7:481bce714567 7631
wolfSSL 7:481bce714567 7632 int wc_ecc_async_handle(ecc_key* key, WOLF_EVENT_QUEUE* queue, WOLF_EVENT* event)
wolfSSL 7:481bce714567 7633 {
wolfSSL 7:481bce714567 7634 int ret;
wolfSSL 7:481bce714567 7635
wolfSSL 7:481bce714567 7636 if (key == NULL || queue == NULL || event == NULL) {
wolfSSL 7:481bce714567 7637 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 7638 }
wolfSSL 7:481bce714567 7639
wolfSSL 7:481bce714567 7640 /* make sure this ECC context had "wc_EccAsyncInit" called on it */
wolfSSL 7:481bce714567 7641 if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) {
wolfSSL 7:481bce714567 7642 return ASYNC_INIT_E;
wolfSSL 7:481bce714567 7643 }
wolfSSL 7:481bce714567 7644
wolfSSL 7:481bce714567 7645 /* setup the event and push to queue */
wolfSSL 7:481bce714567 7646 ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev);
wolfSSL 7:481bce714567 7647 if (ret == 0) {
wolfSSL 7:481bce714567 7648 ret = wolfEventQueue_Push(queue, event);
wolfSSL 7:481bce714567 7649 }
wolfSSL 7:481bce714567 7650
wolfSSL 7:481bce714567 7651 /* check for error (helps with debugging) */
wolfSSL 7:481bce714567 7652 if (ret != 0) {
wolfSSL 7:481bce714567 7653 WOLFSSL_MSG("wc_EccAsyncHandle failed");
wolfSSL 7:481bce714567 7654 }
wolfSSL 7:481bce714567 7655 return ret;
wolfSSL 7:481bce714567 7656 }
wolfSSL 7:481bce714567 7657
wolfSSL 7:481bce714567 7658 int wc_ecc_async_wait(int ret, ecc_key* key)
wolfSSL 7:481bce714567 7659 {
wolfSSL 7:481bce714567 7660 if (ret == WC_PENDING_E) {
wolfSSL 7:481bce714567 7661 WOLF_EVENT event;
wolfSSL 7:481bce714567 7662 XMEMSET(&event, 0, sizeof(event));
wolfSSL 7:481bce714567 7663 ret = wolfAsync_EventInit(&event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL, &key->asyncDev);
wolfSSL 7:481bce714567 7664 if (ret == 0) {
wolfSSL 7:481bce714567 7665 ret = wolfAsync_EventWait(&event);
wolfSSL 7:481bce714567 7666 if (ret == 0 && event.ret >= 0) {
wolfSSL 7:481bce714567 7667 ret = event.ret;
wolfSSL 7:481bce714567 7668 }
wolfSSL 7:481bce714567 7669 }
wolfSSL 7:481bce714567 7670 }
wolfSSL 7:481bce714567 7671 return ret;
wolfSSL 7:481bce714567 7672 }
wolfSSL 7:481bce714567 7673
wolfSSL 7:481bce714567 7674 #endif /* WOLFSSL_ASYNC_CRYPT */
wolfSSL 7:481bce714567 7675
wolfSSL 7:481bce714567 7676 #endif /* HAVE_ECC */
wolfSSL 7:481bce714567 7677