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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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