Xuyi Wang / wolfcrypt

Dependents:   OS

Committer:
sPymbed
Date:
Mon Nov 25 14:23:49 2019 +0000
Revision:
1:e4ea39eba2fb
Parent:
0:1387ff3eed4a
improved

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sPymbed 0:1387ff3eed4a 1 /* ecc.c
sPymbed 0:1387ff3eed4a 2 *
sPymbed 0:1387ff3eed4a 3 * Copyright (C) 2006-2017 wolfSSL Inc.
sPymbed 0:1387ff3eed4a 4 *
sPymbed 0:1387ff3eed4a 5 * This file is part of wolfSSL.
sPymbed 0:1387ff3eed4a 6 *
sPymbed 0:1387ff3eed4a 7 * wolfSSL is free software; you can redistribute it and/or modify
sPymbed 0:1387ff3eed4a 8 * it under the terms of the GNU General Public License as published by
sPymbed 0:1387ff3eed4a 9 * the Free Software Foundation; either version 2 of the License, or
sPymbed 0:1387ff3eed4a 10 * (at your option) any later version.
sPymbed 0:1387ff3eed4a 11 *
sPymbed 0:1387ff3eed4a 12 * wolfSSL is distributed in the hope that it will be useful,
sPymbed 0:1387ff3eed4a 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sPymbed 0:1387ff3eed4a 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sPymbed 0:1387ff3eed4a 15 * GNU General Public License for more details.
sPymbed 0:1387ff3eed4a 16 *
sPymbed 0:1387ff3eed4a 17 * You should have received a copy of the GNU General Public License
sPymbed 0:1387ff3eed4a 18 * along with this program; if not, write to the Free Software
sPymbed 0:1387ff3eed4a 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
sPymbed 0:1387ff3eed4a 20 */
sPymbed 0:1387ff3eed4a 21
sPymbed 0:1387ff3eed4a 22
sPymbed 0:1387ff3eed4a 23
sPymbed 0:1387ff3eed4a 24 #ifdef HAVE_CONFIG_H
sPymbed 0:1387ff3eed4a 25 #include <config.h>
sPymbed 0:1387ff3eed4a 26 #endif
sPymbed 0:1387ff3eed4a 27
sPymbed 0:1387ff3eed4a 28 /* in case user set HAVE_ECC there */
sPymbed 0:1387ff3eed4a 29 #include <wolfcrypt/settings.h>
sPymbed 0:1387ff3eed4a 30
sPymbed 0:1387ff3eed4a 31 /*
sPymbed 0:1387ff3eed4a 32 Possible ECC enable options:
sPymbed 0:1387ff3eed4a 33 * HAVE_ECC: Overall control of ECC default: on
sPymbed 0:1387ff3eed4a 34 * HAVE_ECC_ENCRYPT: ECC encrypt/decrypt w/AES and HKDF default: off
sPymbed 0:1387ff3eed4a 35 * HAVE_ECC_SIGN: ECC sign default: on
sPymbed 0:1387ff3eed4a 36 * HAVE_ECC_VERIFY: ECC verify default: on
sPymbed 0:1387ff3eed4a 37 * HAVE_ECC_DHE: ECC build shared secret default: on
sPymbed 0:1387ff3eed4a 38 * HAVE_ECC_CDH: ECC cofactor DH shared secret default: off
sPymbed 0:1387ff3eed4a 39 * HAVE_ECC_KEY_IMPORT: ECC Key import default: on
sPymbed 0:1387ff3eed4a 40 * HAVE_ECC_KEY_EXPORT: ECC Key export default: on
sPymbed 0:1387ff3eed4a 41 * ECC_SHAMIR: Enables Shamir calc method default: on
sPymbed 0:1387ff3eed4a 42 * HAVE_COMP_KEY: Enables compressed key default: off
sPymbed 0:1387ff3eed4a 43 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off
sPymbed 0:1387ff3eed4a 44 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen default: off
sPymbed 0:1387ff3eed4a 45 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off
sPymbed 0:1387ff3eed4a 46 * Includes the curve "a" variable in calculation
sPymbed 0:1387ff3eed4a 47 * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off
sPymbed 0:1387ff3eed4a 48 * ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance
sPymbed 0:1387ff3eed4a 49 default: off
sPymbed 0:1387ff3eed4a 50 * FP_ECC: ECC Fixed Point Cache default: off
sPymbed 0:1387ff3eed4a 51 * USE_ECC_B_PARAM: Enable ECC curve B param default: off
sPymbed 0:1387ff3eed4a 52 (on for HAVE_COMP_KEY)
sPymbed 0:1387ff3eed4a 53 */
sPymbed 0:1387ff3eed4a 54
sPymbed 0:1387ff3eed4a 55 /*
sPymbed 0:1387ff3eed4a 56 ECC Curve Types:
sPymbed 0:1387ff3eed4a 57 * NO_ECC_SECP Disables SECP curves default: off (not defined)
sPymbed 0:1387ff3eed4a 58 * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off
sPymbed 0:1387ff3eed4a 59 * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off
sPymbed 0:1387ff3eed4a 60 * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off
sPymbed 0:1387ff3eed4a 61 * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off
sPymbed 0:1387ff3eed4a 62 */
sPymbed 0:1387ff3eed4a 63
sPymbed 0:1387ff3eed4a 64 /*
sPymbed 0:1387ff3eed4a 65 ECC Curve Sizes:
sPymbed 0:1387ff3eed4a 66 * ECC_USER_CURVES: Allows custom combination of key sizes below
sPymbed 0:1387ff3eed4a 67 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
sPymbed 0:1387ff3eed4a 68 * HAVE_ECC112: 112 bit key
sPymbed 0:1387ff3eed4a 69 * HAVE_ECC128: 128 bit key
sPymbed 0:1387ff3eed4a 70 * HAVE_ECC160: 160 bit key
sPymbed 0:1387ff3eed4a 71 * HAVE_ECC192: 192 bit key
sPymbed 0:1387ff3eed4a 72 * HAVE_ECC224: 224 bit key
sPymbed 0:1387ff3eed4a 73 * HAVE_ECC239: 239 bit key
sPymbed 0:1387ff3eed4a 74 * NO_ECC256: Disables 256 bit key (on by default)
sPymbed 0:1387ff3eed4a 75 * HAVE_ECC320: 320 bit key
sPymbed 0:1387ff3eed4a 76 * HAVE_ECC384: 384 bit key
sPymbed 0:1387ff3eed4a 77 * HAVE_ECC512: 512 bit key
sPymbed 0:1387ff3eed4a 78 * HAVE_ECC521: 521 bit key
sPymbed 0:1387ff3eed4a 79 */
sPymbed 0:1387ff3eed4a 80
sPymbed 0:1387ff3eed4a 81
sPymbed 0:1387ff3eed4a 82 #ifdef HAVE_ECC
sPymbed 0:1387ff3eed4a 83
sPymbed 0:1387ff3eed4a 84 /* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
sPymbed 0:1387ff3eed4a 85 #if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
sPymbed 0:1387ff3eed4a 86 !defined(WOLFSSL_CUSTOM_CURVES)
sPymbed 0:1387ff3eed4a 87 #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 88 #endif
sPymbed 0:1387ff3eed4a 89
sPymbed 0:1387ff3eed4a 90 /* Make sure ASN is enabled for ECC sign/verify */
sPymbed 0:1387ff3eed4a 91 #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN)
sPymbed 0:1387ff3eed4a 92 #error ASN must be enabled for ECC sign/verify
sPymbed 0:1387ff3eed4a 93 #endif
sPymbed 0:1387ff3eed4a 94
sPymbed 0:1387ff3eed4a 95
sPymbed 0:1387ff3eed4a 96 #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
sPymbed 0:1387ff3eed4a 97 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
sPymbed 0:1387ff3eed4a 98 #define FIPS_NO_WRAPPERS
sPymbed 0:1387ff3eed4a 99
sPymbed 0:1387ff3eed4a 100 #ifdef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 101 #pragma code_seg(".fipsA$f")
sPymbed 0:1387ff3eed4a 102 #pragma const_seg(".fipsB$f")
sPymbed 0:1387ff3eed4a 103 #endif
sPymbed 0:1387ff3eed4a 104 #endif
sPymbed 0:1387ff3eed4a 105
sPymbed 0:1387ff3eed4a 106 #include <wolfcrypt/ecc.h>
sPymbed 0:1387ff3eed4a 107 #include <wolfcrypt/asn.h>
sPymbed 0:1387ff3eed4a 108 #include <wolfcrypt/error-crypt.h>
sPymbed 0:1387ff3eed4a 109 #include <wolfcrypt/logging.h>
sPymbed 0:1387ff3eed4a 110 #include <wolfcrypt/types.h>
sPymbed 0:1387ff3eed4a 111
sPymbed 0:1387ff3eed4a 112 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 113 #include <wolfcrypt/sp.h>
sPymbed 0:1387ff3eed4a 114 #endif
sPymbed 0:1387ff3eed4a 115
sPymbed 0:1387ff3eed4a 116 #ifdef HAVE_ECC_ENCRYPT
sPymbed 0:1387ff3eed4a 117 #include <wolfcrypt/hmac.h>
sPymbed 0:1387ff3eed4a 118 #include <wolfcrypt/aes.h>
sPymbed 0:1387ff3eed4a 119 #endif
sPymbed 0:1387ff3eed4a 120
sPymbed 0:1387ff3eed4a 121 #ifdef HAVE_X963_KDF
sPymbed 0:1387ff3eed4a 122 #include <wolfcrypt/hash.h>
sPymbed 0:1387ff3eed4a 123 #endif
sPymbed 0:1387ff3eed4a 124
sPymbed 0:1387ff3eed4a 125 #ifdef WOLF_CRYPTO_DEV
sPymbed 0:1387ff3eed4a 126 #include <wolfcrypt/cryptodev.h>
sPymbed 0:1387ff3eed4a 127 #endif
sPymbed 0:1387ff3eed4a 128
sPymbed 0:1387ff3eed4a 129 #ifdef NO_INLINE
sPymbed 0:1387ff3eed4a 130 #include <wolfcrypt/misc.h>
sPymbed 0:1387ff3eed4a 131 #else
sPymbed 0:1387ff3eed4a 132 #define WOLFSSL_MISC_INCLUDED
sPymbed 0:1387ff3eed4a 133 #include <wolfcrypt/src/misc.c>
sPymbed 0:1387ff3eed4a 134 #endif
sPymbed 0:1387ff3eed4a 135
sPymbed 0:1387ff3eed4a 136 #if defined(FREESCALE_LTC_ECC)
sPymbed 0:1387ff3eed4a 137 #include <wolfcrypt/port/nxp/ksdk_port.h>
sPymbed 0:1387ff3eed4a 138 #endif
sPymbed 0:1387ff3eed4a 139
sPymbed 0:1387ff3eed4a 140 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 141 #define GEN_MEM_ERR MP_MEM
sPymbed 0:1387ff3eed4a 142 #elif defined(USE_FAST_MATH)
sPymbed 0:1387ff3eed4a 143 #define GEN_MEM_ERR FP_MEM
sPymbed 0:1387ff3eed4a 144 #else
sPymbed 0:1387ff3eed4a 145 #define GEN_MEM_ERR MP_MEM
sPymbed 0:1387ff3eed4a 146 #endif
sPymbed 0:1387ff3eed4a 147
sPymbed 0:1387ff3eed4a 148
sPymbed 0:1387ff3eed4a 149 /* internal ECC states */
sPymbed 0:1387ff3eed4a 150 enum {
sPymbed 0:1387ff3eed4a 151 ECC_STATE_NONE = 0,
sPymbed 0:1387ff3eed4a 152
sPymbed 0:1387ff3eed4a 153 ECC_STATE_SHARED_SEC_GEN,
sPymbed 0:1387ff3eed4a 154 ECC_STATE_SHARED_SEC_RES,
sPymbed 0:1387ff3eed4a 155
sPymbed 0:1387ff3eed4a 156 ECC_STATE_SIGN_DO,
sPymbed 0:1387ff3eed4a 157 ECC_STATE_SIGN_ENCODE,
sPymbed 0:1387ff3eed4a 158
sPymbed 0:1387ff3eed4a 159 ECC_STATE_VERIFY_DECODE,
sPymbed 0:1387ff3eed4a 160 ECC_STATE_VERIFY_DO,
sPymbed 0:1387ff3eed4a 161 ECC_STATE_VERIFY_RES,
sPymbed 0:1387ff3eed4a 162 };
sPymbed 0:1387ff3eed4a 163
sPymbed 0:1387ff3eed4a 164
sPymbed 0:1387ff3eed4a 165 /* map
sPymbed 0:1387ff3eed4a 166 ptmul -> mulmod
sPymbed 0:1387ff3eed4a 167 */
sPymbed 0:1387ff3eed4a 168
sPymbed 0:1387ff3eed4a 169 /* 256-bit curve on by default whether user curves or not */
sPymbed 0:1387ff3eed4a 170 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 171 #define ECC112
sPymbed 0:1387ff3eed4a 172 #endif
sPymbed 0:1387ff3eed4a 173 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 174 #define ECC128
sPymbed 0:1387ff3eed4a 175 #endif
sPymbed 0:1387ff3eed4a 176 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 177 #define ECC160
sPymbed 0:1387ff3eed4a 178 #endif
sPymbed 0:1387ff3eed4a 179 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 180 #define ECC192
sPymbed 0:1387ff3eed4a 181 #endif
sPymbed 0:1387ff3eed4a 182 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 183 #define ECC224
sPymbed 0:1387ff3eed4a 184 #endif
sPymbed 0:1387ff3eed4a 185 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 186 #define ECC239
sPymbed 0:1387ff3eed4a 187 #endif
sPymbed 0:1387ff3eed4a 188 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 189 #define ECC256
sPymbed 0:1387ff3eed4a 190 #endif
sPymbed 0:1387ff3eed4a 191 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 192 #define ECC320
sPymbed 0:1387ff3eed4a 193 #endif
sPymbed 0:1387ff3eed4a 194 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 195 #define ECC384
sPymbed 0:1387ff3eed4a 196 #endif
sPymbed 0:1387ff3eed4a 197 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 198 #define ECC512
sPymbed 0:1387ff3eed4a 199 #endif
sPymbed 0:1387ff3eed4a 200 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)
sPymbed 0:1387ff3eed4a 201 #define ECC521
sPymbed 0:1387ff3eed4a 202 #endif
sPymbed 0:1387ff3eed4a 203
sPymbed 0:1387ff3eed4a 204 /* The encoded OID's for ECC curves */
sPymbed 0:1387ff3eed4a 205 #ifdef ECC112
sPymbed 0:1387ff3eed4a 206 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 207 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 208 #define CODED_SECP112R1 {1,3,132,0,6}
sPymbed 0:1387ff3eed4a 209 #define CODED_SECP112R1_SZ 5
sPymbed 0:1387ff3eed4a 210 #else
sPymbed 0:1387ff3eed4a 211 #define CODED_SECP112R1 {0x2B,0x81,0x04,0x00,0x06}
sPymbed 0:1387ff3eed4a 212 #define CODED_SECP112R1_SZ 5
sPymbed 0:1387ff3eed4a 213 #endif
sPymbed 0:1387ff3eed4a 214 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 215 static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
sPymbed 0:1387ff3eed4a 216 #else
sPymbed 0:1387ff3eed4a 217 #define ecc_oid_secp112r1 CODED_SECP112R1
sPymbed 0:1387ff3eed4a 218 #endif
sPymbed 0:1387ff3eed4a 219 #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
sPymbed 0:1387ff3eed4a 220 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 221 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 222 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 223 #define CODED_SECP112R2 {1,3,132,0,7}
sPymbed 0:1387ff3eed4a 224 #define CODED_SECP112R2_SZ 5
sPymbed 0:1387ff3eed4a 225 #else
sPymbed 0:1387ff3eed4a 226 #define CODED_SECP112R2 {0x2B,0x81,0x04,0x00,0x07}
sPymbed 0:1387ff3eed4a 227 #define CODED_SECP112R2_SZ 5
sPymbed 0:1387ff3eed4a 228 #endif
sPymbed 0:1387ff3eed4a 229 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 230 static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
sPymbed 0:1387ff3eed4a 231 #else
sPymbed 0:1387ff3eed4a 232 #define ecc_oid_secp112r2 CODED_SECP112R2
sPymbed 0:1387ff3eed4a 233 #endif
sPymbed 0:1387ff3eed4a 234 #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
sPymbed 0:1387ff3eed4a 235 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 236 #endif /* ECC112 */
sPymbed 0:1387ff3eed4a 237 #ifdef ECC128
sPymbed 0:1387ff3eed4a 238 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 239 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 240 #define CODED_SECP128R1 {1,3,132,0,28}
sPymbed 0:1387ff3eed4a 241 #define CODED_SECP128R1_SZ 5
sPymbed 0:1387ff3eed4a 242 #else
sPymbed 0:1387ff3eed4a 243 #define CODED_SECP128R1 {0x2B,0x81,0x04,0x00,0x1C}
sPymbed 0:1387ff3eed4a 244 #define CODED_SECP128R1_SZ 5
sPymbed 0:1387ff3eed4a 245 #endif
sPymbed 0:1387ff3eed4a 246 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 247 static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
sPymbed 0:1387ff3eed4a 248 #else
sPymbed 0:1387ff3eed4a 249 #define ecc_oid_secp128r1 CODED_SECP128R1
sPymbed 0:1387ff3eed4a 250 #endif
sPymbed 0:1387ff3eed4a 251 #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
sPymbed 0:1387ff3eed4a 252 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 253 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 254 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 255 #define CODED_SECP128R2 {1,3,132,0,29}
sPymbed 0:1387ff3eed4a 256 #define CODED_SECP128R2_SZ 5
sPymbed 0:1387ff3eed4a 257 #else
sPymbed 0:1387ff3eed4a 258 #define CODED_SECP128R2 {0x2B,0x81,0x04,0x00,0x1D}
sPymbed 0:1387ff3eed4a 259 #define CODED_SECP128R2_SZ 5
sPymbed 0:1387ff3eed4a 260 #endif
sPymbed 0:1387ff3eed4a 261 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 262 static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
sPymbed 0:1387ff3eed4a 263 #else
sPymbed 0:1387ff3eed4a 264 #define ecc_oid_secp128r2 CODED_SECP128R2
sPymbed 0:1387ff3eed4a 265 #endif
sPymbed 0:1387ff3eed4a 266 #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
sPymbed 0:1387ff3eed4a 267 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 268 #endif /* ECC128 */
sPymbed 0:1387ff3eed4a 269 #ifdef ECC160
sPymbed 0:1387ff3eed4a 270 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 271 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 272 #define CODED_SECP160R1 {1,3,132,0,8}
sPymbed 0:1387ff3eed4a 273 #define CODED_SECP160R1_SZ 5
sPymbed 0:1387ff3eed4a 274 #else
sPymbed 0:1387ff3eed4a 275 #define CODED_SECP160R1 {0x2B,0x81,0x04,0x00,0x08}
sPymbed 0:1387ff3eed4a 276 #define CODED_SECP160R1_SZ 5
sPymbed 0:1387ff3eed4a 277 #endif
sPymbed 0:1387ff3eed4a 278 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 279 static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
sPymbed 0:1387ff3eed4a 280 #else
sPymbed 0:1387ff3eed4a 281 #define ecc_oid_secp160r1 CODED_SECP160R1
sPymbed 0:1387ff3eed4a 282 #endif
sPymbed 0:1387ff3eed4a 283 #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
sPymbed 0:1387ff3eed4a 284 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 285 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 286 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 287 #define CODED_SECP160R2 {1,3,132,0,30}
sPymbed 0:1387ff3eed4a 288 #define CODED_SECP160R1_SZ 5
sPymbed 0:1387ff3eed4a 289 #else
sPymbed 0:1387ff3eed4a 290 #define CODED_SECP160R2 {0x2B,0x81,0x04,0x00,0x1E}
sPymbed 0:1387ff3eed4a 291 #define CODED_SECP160R2_SZ 5
sPymbed 0:1387ff3eed4a 292 #endif
sPymbed 0:1387ff3eed4a 293 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 294 static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
sPymbed 0:1387ff3eed4a 295 #else
sPymbed 0:1387ff3eed4a 296 #define ecc_oid_secp160r2 CODED_SECP160R2
sPymbed 0:1387ff3eed4a 297 #endif
sPymbed 0:1387ff3eed4a 298 #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
sPymbed 0:1387ff3eed4a 299 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 300 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 301 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 302 #define CODED_SECP160K1 {1,3,132,0,9}
sPymbed 0:1387ff3eed4a 303 #define CODED_SECP160K1_SZ 5
sPymbed 0:1387ff3eed4a 304 #else
sPymbed 0:1387ff3eed4a 305 #define CODED_SECP160K1 {0x2B,0x81,0x04,0x00,0x09}
sPymbed 0:1387ff3eed4a 306 #define CODED_SECP160K1_SZ 5
sPymbed 0:1387ff3eed4a 307 #endif
sPymbed 0:1387ff3eed4a 308 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 309 static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
sPymbed 0:1387ff3eed4a 310 #else
sPymbed 0:1387ff3eed4a 311 #define ecc_oid_secp160k1 CODED_SECP160K1
sPymbed 0:1387ff3eed4a 312 #endif
sPymbed 0:1387ff3eed4a 313 #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
sPymbed 0:1387ff3eed4a 314 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 315 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 316 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 317 #define CODED_BRAINPOOLP160R1 {1,3,36,3,3,2,8,1,1,1}
sPymbed 0:1387ff3eed4a 318 #define CODED_BRAINPOOLP160R1_SZ 10
sPymbed 0:1387ff3eed4a 319 #else
sPymbed 0:1387ff3eed4a 320 #define CODED_BRAINPOOLP160R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
sPymbed 0:1387ff3eed4a 321 #define CODED_BRAINPOOLP160R1_SZ 9
sPymbed 0:1387ff3eed4a 322 #endif
sPymbed 0:1387ff3eed4a 323 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 324 static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
sPymbed 0:1387ff3eed4a 325 #else
sPymbed 0:1387ff3eed4a 326 #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
sPymbed 0:1387ff3eed4a 327 #endif
sPymbed 0:1387ff3eed4a 328 #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
sPymbed 0:1387ff3eed4a 329 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 330 #endif /* ECC160 */
sPymbed 0:1387ff3eed4a 331 #ifdef ECC192
sPymbed 0:1387ff3eed4a 332 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 333 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 334 #define CODED_SECP192R1 {1,2,840,10045,3,1,1}
sPymbed 0:1387ff3eed4a 335 #define CODED_SECP192R1_SZ 7
sPymbed 0:1387ff3eed4a 336 #else
sPymbed 0:1387ff3eed4a 337 #define CODED_SECP192R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
sPymbed 0:1387ff3eed4a 338 #define CODED_SECP192R1_SZ 8
sPymbed 0:1387ff3eed4a 339 #endif
sPymbed 0:1387ff3eed4a 340 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 341 static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
sPymbed 0:1387ff3eed4a 342 #else
sPymbed 0:1387ff3eed4a 343 #define ecc_oid_secp192r1 CODED_SECP192R1
sPymbed 0:1387ff3eed4a 344 #endif
sPymbed 0:1387ff3eed4a 345 #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
sPymbed 0:1387ff3eed4a 346 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 347 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 348 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 349 #define CODED_PRIME192V2 {1,2,840,10045,3,1,2}
sPymbed 0:1387ff3eed4a 350 #define CODED_PRIME192V2_SZ 7
sPymbed 0:1387ff3eed4a 351 #else
sPymbed 0:1387ff3eed4a 352 #define CODED_PRIME192V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
sPymbed 0:1387ff3eed4a 353 #define CODED_PRIME192V2_SZ 8
sPymbed 0:1387ff3eed4a 354 #endif
sPymbed 0:1387ff3eed4a 355 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 356 static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
sPymbed 0:1387ff3eed4a 357 #else
sPymbed 0:1387ff3eed4a 358 #define ecc_oid_prime192v2 CODED_PRIME192V2
sPymbed 0:1387ff3eed4a 359 #endif
sPymbed 0:1387ff3eed4a 360 #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
sPymbed 0:1387ff3eed4a 361 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 362 #ifdef HAVE_ECC_SECPR3
sPymbed 0:1387ff3eed4a 363 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 364 #define CODED_PRIME192V3 {1,2,840,10045,3,1,3}
sPymbed 0:1387ff3eed4a 365 #define CODED_PRIME192V3_SZ 7
sPymbed 0:1387ff3eed4a 366 #else
sPymbed 0:1387ff3eed4a 367 #define CODED_PRIME192V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
sPymbed 0:1387ff3eed4a 368 #define CODED_PRIME192V3_SZ 8
sPymbed 0:1387ff3eed4a 369 #endif
sPymbed 0:1387ff3eed4a 370 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 371 static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
sPymbed 0:1387ff3eed4a 372 #else
sPymbed 0:1387ff3eed4a 373 #define ecc_oid_prime192v3 CODED_PRIME192V3
sPymbed 0:1387ff3eed4a 374 #endif
sPymbed 0:1387ff3eed4a 375 #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
sPymbed 0:1387ff3eed4a 376 #endif /* HAVE_ECC_SECPR3 */
sPymbed 0:1387ff3eed4a 377 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 378 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 379 #define CODED_SECP192K1 {1,3,132,0,31}
sPymbed 0:1387ff3eed4a 380 #define CODED_SECP192K1_SZ 5
sPymbed 0:1387ff3eed4a 381 #else
sPymbed 0:1387ff3eed4a 382 #define CODED_SECP192K1 {0x2B,0x81,0x04,0x00,0x1F}
sPymbed 0:1387ff3eed4a 383 #define CODED_SECP192K1_SZ 5
sPymbed 0:1387ff3eed4a 384 #endif
sPymbed 0:1387ff3eed4a 385 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 386 static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
sPymbed 0:1387ff3eed4a 387 #else
sPymbed 0:1387ff3eed4a 388 #define ecc_oid_secp192k1 CODED_SECP192K1
sPymbed 0:1387ff3eed4a 389 #endif
sPymbed 0:1387ff3eed4a 390 #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
sPymbed 0:1387ff3eed4a 391 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 392 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 393 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 394 #define CODED_BRAINPOOLP192R1 {1,3,36,3,3,2,8,1,1,3}
sPymbed 0:1387ff3eed4a 395 #define CODED_BRAINPOOLP192R1_SZ 10
sPymbed 0:1387ff3eed4a 396 #else
sPymbed 0:1387ff3eed4a 397 #define CODED_BRAINPOOLP192R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
sPymbed 0:1387ff3eed4a 398 #define CODED_BRAINPOOLP192R1_SZ 9
sPymbed 0:1387ff3eed4a 399 #endif
sPymbed 0:1387ff3eed4a 400 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 401 static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
sPymbed 0:1387ff3eed4a 402 #else
sPymbed 0:1387ff3eed4a 403 #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
sPymbed 0:1387ff3eed4a 404 #endif
sPymbed 0:1387ff3eed4a 405 #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
sPymbed 0:1387ff3eed4a 406 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 407 #endif /* ECC192 */
sPymbed 0:1387ff3eed4a 408 #ifdef ECC224
sPymbed 0:1387ff3eed4a 409 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 410 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 411 #define CODED_SECP224R1 {1,3,132,0,33}
sPymbed 0:1387ff3eed4a 412 #define CODED_SECP224R1_SZ 5
sPymbed 0:1387ff3eed4a 413 #else
sPymbed 0:1387ff3eed4a 414 #define CODED_SECP224R1 {0x2B,0x81,0x04,0x00,0x21}
sPymbed 0:1387ff3eed4a 415 #define CODED_SECP224R1_SZ 5
sPymbed 0:1387ff3eed4a 416 #endif
sPymbed 0:1387ff3eed4a 417 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 418 static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
sPymbed 0:1387ff3eed4a 419 #else
sPymbed 0:1387ff3eed4a 420 #define ecc_oid_secp224r1 CODED_SECP224R1
sPymbed 0:1387ff3eed4a 421 #endif
sPymbed 0:1387ff3eed4a 422 #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
sPymbed 0:1387ff3eed4a 423 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 424 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 425 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 426 #define CODED_SECP224K1 {1,3,132,0,32}
sPymbed 0:1387ff3eed4a 427 #define CODED_SECP224K1_SZ 5
sPymbed 0:1387ff3eed4a 428 #else
sPymbed 0:1387ff3eed4a 429 #define CODED_SECP224K1 {0x2B,0x81,0x04,0x00,0x20}
sPymbed 0:1387ff3eed4a 430 #define CODED_SECP224K1_SZ 5
sPymbed 0:1387ff3eed4a 431 #endif
sPymbed 0:1387ff3eed4a 432 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 433 static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
sPymbed 0:1387ff3eed4a 434 #else
sPymbed 0:1387ff3eed4a 435 #define ecc_oid_secp224k1 CODED_SECP224K1
sPymbed 0:1387ff3eed4a 436 #endif
sPymbed 0:1387ff3eed4a 437 #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
sPymbed 0:1387ff3eed4a 438 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 439 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 440 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 441 #define CODED_BRAINPOOLP224R1 {1,3,36,3,3,2,8,1,1,5}
sPymbed 0:1387ff3eed4a 442 #define CODED_BRAINPOOLP224R1_SZ 10
sPymbed 0:1387ff3eed4a 443 #else
sPymbed 0:1387ff3eed4a 444 #define CODED_BRAINPOOLP224R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
sPymbed 0:1387ff3eed4a 445 #define CODED_BRAINPOOLP224R1_SZ 9
sPymbed 0:1387ff3eed4a 446 #endif
sPymbed 0:1387ff3eed4a 447 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 448 static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
sPymbed 0:1387ff3eed4a 449 #else
sPymbed 0:1387ff3eed4a 450 #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
sPymbed 0:1387ff3eed4a 451 #endif
sPymbed 0:1387ff3eed4a 452 #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
sPymbed 0:1387ff3eed4a 453 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 454 #endif /* ECC224 */
sPymbed 0:1387ff3eed4a 455 #ifdef ECC239
sPymbed 0:1387ff3eed4a 456 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 457 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 458 #define CODED_PRIME239V1 {1,2,840,10045,3,1,4}
sPymbed 0:1387ff3eed4a 459 #define CODED_PRIME239V1_SZ 7
sPymbed 0:1387ff3eed4a 460 #else
sPymbed 0:1387ff3eed4a 461 #define CODED_PRIME239V1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
sPymbed 0:1387ff3eed4a 462 #define CODED_PRIME239V1_SZ 8
sPymbed 0:1387ff3eed4a 463 #endif
sPymbed 0:1387ff3eed4a 464 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 465 static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
sPymbed 0:1387ff3eed4a 466 #else
sPymbed 0:1387ff3eed4a 467 #define ecc_oid_prime239v1 CODED_PRIME239V1
sPymbed 0:1387ff3eed4a 468 #endif
sPymbed 0:1387ff3eed4a 469 #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
sPymbed 0:1387ff3eed4a 470 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 471 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 472 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 473 #define CODED_PRIME239V2 {1,2,840,10045,3,1,5}
sPymbed 0:1387ff3eed4a 474 #define CODED_PRIME239V2_SZ 7
sPymbed 0:1387ff3eed4a 475 #else
sPymbed 0:1387ff3eed4a 476 #define CODED_PRIME239V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
sPymbed 0:1387ff3eed4a 477 #define CODED_PRIME239V2_SZ 8
sPymbed 0:1387ff3eed4a 478 #endif
sPymbed 0:1387ff3eed4a 479 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 480 static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
sPymbed 0:1387ff3eed4a 481 #else
sPymbed 0:1387ff3eed4a 482 #define ecc_oid_prime239v2 CODED_PRIME239V2
sPymbed 0:1387ff3eed4a 483 #endif
sPymbed 0:1387ff3eed4a 484 #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
sPymbed 0:1387ff3eed4a 485 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 486 #ifdef HAVE_ECC_SECPR3
sPymbed 0:1387ff3eed4a 487 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 488 #define CODED_PRIME239V3 {1,2,840,10045,3,1,6}
sPymbed 0:1387ff3eed4a 489 #define CODED_PRIME239V3_SZ 7
sPymbed 0:1387ff3eed4a 490 #else
sPymbed 0:1387ff3eed4a 491 #define CODED_PRIME239V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
sPymbed 0:1387ff3eed4a 492 #define CODED_PRIME239V3_SZ 8
sPymbed 0:1387ff3eed4a 493 #endif
sPymbed 0:1387ff3eed4a 494 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 495 static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
sPymbed 0:1387ff3eed4a 496 #else
sPymbed 0:1387ff3eed4a 497 #define ecc_oid_prime239v3 CODED_PRIME239V3
sPymbed 0:1387ff3eed4a 498 #endif
sPymbed 0:1387ff3eed4a 499 #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
sPymbed 0:1387ff3eed4a 500 #endif /* HAVE_ECC_SECPR3 */
sPymbed 0:1387ff3eed4a 501 #endif /* ECC239 */
sPymbed 0:1387ff3eed4a 502 #ifdef ECC256
sPymbed 0:1387ff3eed4a 503 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 504 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 505 #define CODED_SECP256R1 {1,2,840,10045,3,1,7}
sPymbed 0:1387ff3eed4a 506 #define CODED_SECP256R1_SZ 7
sPymbed 0:1387ff3eed4a 507 #else
sPymbed 0:1387ff3eed4a 508 #define CODED_SECP256R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
sPymbed 0:1387ff3eed4a 509 #define CODED_SECP256R1_SZ 8
sPymbed 0:1387ff3eed4a 510 #endif
sPymbed 0:1387ff3eed4a 511 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 512 static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
sPymbed 0:1387ff3eed4a 513 #else
sPymbed 0:1387ff3eed4a 514 #define ecc_oid_secp256r1 CODED_SECP256R1
sPymbed 0:1387ff3eed4a 515 #endif
sPymbed 0:1387ff3eed4a 516 #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
sPymbed 0:1387ff3eed4a 517 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 518 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 519 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 520 #define CODED_SECP256K1 {1,3,132,0,10}
sPymbed 0:1387ff3eed4a 521 #define CODED_SECP256K1_SZ 5
sPymbed 0:1387ff3eed4a 522 #else
sPymbed 0:1387ff3eed4a 523 #define CODED_SECP256K1 {0x2B,0x81,0x04,0x00,0x0A}
sPymbed 0:1387ff3eed4a 524 #define CODED_SECP256K1_SZ 5
sPymbed 0:1387ff3eed4a 525 #endif
sPymbed 0:1387ff3eed4a 526 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 527 static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
sPymbed 0:1387ff3eed4a 528 #else
sPymbed 0:1387ff3eed4a 529 #define ecc_oid_secp256k1 CODED_SECP256K1
sPymbed 0:1387ff3eed4a 530 #endif
sPymbed 0:1387ff3eed4a 531 #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
sPymbed 0:1387ff3eed4a 532 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 533 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 534 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 535 #define CODED_BRAINPOOLP256R1 {1,3,36,3,3,2,8,1,1,7}
sPymbed 0:1387ff3eed4a 536 #define CODED_BRAINPOOLP256R1_SZ 10
sPymbed 0:1387ff3eed4a 537 #else
sPymbed 0:1387ff3eed4a 538 #define CODED_BRAINPOOLP256R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
sPymbed 0:1387ff3eed4a 539 #define CODED_BRAINPOOLP256R1_SZ 9
sPymbed 0:1387ff3eed4a 540 #endif
sPymbed 0:1387ff3eed4a 541 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 542 static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
sPymbed 0:1387ff3eed4a 543 #else
sPymbed 0:1387ff3eed4a 544 #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
sPymbed 0:1387ff3eed4a 545 #endif
sPymbed 0:1387ff3eed4a 546 #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
sPymbed 0:1387ff3eed4a 547 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 548 #endif /* ECC256 */
sPymbed 0:1387ff3eed4a 549 #ifdef ECC320
sPymbed 0:1387ff3eed4a 550 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 551 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 552 #define CODED_BRAINPOOLP320R1 {1,3,36,3,3,2,8,1,1,9}
sPymbed 0:1387ff3eed4a 553 #define CODED_BRAINPOOLP320R1_SZ 10
sPymbed 0:1387ff3eed4a 554 #else
sPymbed 0:1387ff3eed4a 555 #define CODED_BRAINPOOLP320R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
sPymbed 0:1387ff3eed4a 556 #define CODED_BRAINPOOLP320R1_SZ 9
sPymbed 0:1387ff3eed4a 557 #endif
sPymbed 0:1387ff3eed4a 558 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 559 static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
sPymbed 0:1387ff3eed4a 560 #else
sPymbed 0:1387ff3eed4a 561 #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
sPymbed 0:1387ff3eed4a 562 #endif
sPymbed 0:1387ff3eed4a 563 #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
sPymbed 0:1387ff3eed4a 564 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 565 #endif /* ECC320 */
sPymbed 0:1387ff3eed4a 566 #ifdef ECC384
sPymbed 0:1387ff3eed4a 567 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 568 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 569 #define CODED_SECP384R1 {1,3,132,0,34}
sPymbed 0:1387ff3eed4a 570 #define CODED_SECP384R1_SZ 5
sPymbed 0:1387ff3eed4a 571 #else
sPymbed 0:1387ff3eed4a 572 #define CODED_SECP384R1 {0x2B,0x81,0x04,0x00,0x22}
sPymbed 0:1387ff3eed4a 573 #define CODED_SECP384R1_SZ 5
sPymbed 0:1387ff3eed4a 574 #endif
sPymbed 0:1387ff3eed4a 575 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 576 static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
sPymbed 0:1387ff3eed4a 577 #define CODED_SECP384R1_OID ecc_oid_secp384r1
sPymbed 0:1387ff3eed4a 578 #else
sPymbed 0:1387ff3eed4a 579 #define ecc_oid_secp384r1 CODED_SECP384R1
sPymbed 0:1387ff3eed4a 580 #endif
sPymbed 0:1387ff3eed4a 581 #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
sPymbed 0:1387ff3eed4a 582 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 583 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 584 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 585 #define CODED_BRAINPOOLP384R1 {1,3,36,3,3,2,8,1,1,11}
sPymbed 0:1387ff3eed4a 586 #define CODED_BRAINPOOLP384R1_SZ 10
sPymbed 0:1387ff3eed4a 587 #else
sPymbed 0:1387ff3eed4a 588 #define CODED_BRAINPOOLP384R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
sPymbed 0:1387ff3eed4a 589 #define CODED_BRAINPOOLP384R1_SZ 9
sPymbed 0:1387ff3eed4a 590 #endif
sPymbed 0:1387ff3eed4a 591 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 592 static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
sPymbed 0:1387ff3eed4a 593 #else
sPymbed 0:1387ff3eed4a 594 #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
sPymbed 0:1387ff3eed4a 595 #endif
sPymbed 0:1387ff3eed4a 596 #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
sPymbed 0:1387ff3eed4a 597 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 598 #endif /* ECC384 */
sPymbed 0:1387ff3eed4a 599 #ifdef ECC512
sPymbed 0:1387ff3eed4a 600 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 601 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 602 #define CODED_BRAINPOOLP512R1 {1,3,36,3,3,2,8,1,1,13}
sPymbed 0:1387ff3eed4a 603 #define CODED_BRAINPOOLP512R1_SZ 10
sPymbed 0:1387ff3eed4a 604 #else
sPymbed 0:1387ff3eed4a 605 #define CODED_BRAINPOOLP512R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
sPymbed 0:1387ff3eed4a 606 #define CODED_BRAINPOOLP512R1_SZ 9
sPymbed 0:1387ff3eed4a 607 #endif
sPymbed 0:1387ff3eed4a 608 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 609 static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
sPymbed 0:1387ff3eed4a 610 #else
sPymbed 0:1387ff3eed4a 611 #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
sPymbed 0:1387ff3eed4a 612 #endif
sPymbed 0:1387ff3eed4a 613 #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
sPymbed 0:1387ff3eed4a 614 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 615 #endif /* ECC512 */
sPymbed 0:1387ff3eed4a 616 #ifdef ECC521
sPymbed 0:1387ff3eed4a 617 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 618 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 619 #define CODED_SECP521R1 {1,3,132,0,35}
sPymbed 0:1387ff3eed4a 620 #define CODED_SECP521R1_SZ 5
sPymbed 0:1387ff3eed4a 621 #else
sPymbed 0:1387ff3eed4a 622 #define CODED_SECP521R1 {0x2B,0x81,0x04,0x00,0x23}
sPymbed 0:1387ff3eed4a 623 #define CODED_SECP521R1_SZ 5
sPymbed 0:1387ff3eed4a 624 #endif
sPymbed 0:1387ff3eed4a 625 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 626 static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
sPymbed 0:1387ff3eed4a 627 #else
sPymbed 0:1387ff3eed4a 628 #define ecc_oid_secp521r1 CODED_SECP521R1
sPymbed 0:1387ff3eed4a 629 #endif
sPymbed 0:1387ff3eed4a 630 #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
sPymbed 0:1387ff3eed4a 631 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 632 #endif /* ECC521 */
sPymbed 0:1387ff3eed4a 633
sPymbed 0:1387ff3eed4a 634
sPymbed 0:1387ff3eed4a 635 /* This holds the key settings.
sPymbed 0:1387ff3eed4a 636 ***MUST*** be organized by size from smallest to largest. */
sPymbed 0:1387ff3eed4a 637
sPymbed 0:1387ff3eed4a 638 const ecc_set_type ecc_sets[] = {
sPymbed 0:1387ff3eed4a 639 #ifdef ECC112
sPymbed 0:1387ff3eed4a 640 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 641 {
sPymbed 0:1387ff3eed4a 642 14, /* size/bytes */
sPymbed 0:1387ff3eed4a 643 ECC_SECP112R1, /* ID */
sPymbed 0:1387ff3eed4a 644 "SECP112R1", /* curve name */
sPymbed 0:1387ff3eed4a 645 "DB7C2ABF62E35E668076BEAD208B", /* prime */
sPymbed 0:1387ff3eed4a 646 "DB7C2ABF62E35E668076BEAD2088", /* A */
sPymbed 0:1387ff3eed4a 647 "659EF8BA043916EEDE8911702B22", /* B */
sPymbed 0:1387ff3eed4a 648 "DB7C2ABF62E35E7628DFAC6561C5", /* order */
sPymbed 0:1387ff3eed4a 649 "9487239995A5EE76B55F9C2F098", /* Gx */
sPymbed 0:1387ff3eed4a 650 "A89CE5AF8724C0A23E0E0FF77500", /* Gy */
sPymbed 0:1387ff3eed4a 651 ecc_oid_secp112r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 652 ecc_oid_secp112r1_sz,
sPymbed 0:1387ff3eed4a 653 ECC_SECP112R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 654 1, /* cofactor */
sPymbed 0:1387ff3eed4a 655 },
sPymbed 0:1387ff3eed4a 656 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 657 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 658 {
sPymbed 0:1387ff3eed4a 659 14, /* size/bytes */
sPymbed 0:1387ff3eed4a 660 ECC_SECP112R2, /* ID */
sPymbed 0:1387ff3eed4a 661 "SECP112R2", /* curve name */
sPymbed 0:1387ff3eed4a 662 "DB7C2ABF62E35E668076BEAD208B", /* prime */
sPymbed 0:1387ff3eed4a 663 "6127C24C05F38A0AAAF65C0EF02C", /* A */
sPymbed 0:1387ff3eed4a 664 "51DEF1815DB5ED74FCC34C85D709", /* B */
sPymbed 0:1387ff3eed4a 665 "36DF0AAFD8B8D7597CA10520D04B", /* order */
sPymbed 0:1387ff3eed4a 666 "4BA30AB5E892B4E1649DD0928643", /* Gx */
sPymbed 0:1387ff3eed4a 667 "ADCD46F5882E3747DEF36E956E97", /* Gy */
sPymbed 0:1387ff3eed4a 668 ecc_oid_secp112r2, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 669 ecc_oid_secp112r2_sz,
sPymbed 0:1387ff3eed4a 670 ECC_SECP112R2_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 671 4, /* cofactor */
sPymbed 0:1387ff3eed4a 672 },
sPymbed 0:1387ff3eed4a 673 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 674 #endif /* ECC112 */
sPymbed 0:1387ff3eed4a 675 #ifdef ECC128
sPymbed 0:1387ff3eed4a 676 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 677 {
sPymbed 0:1387ff3eed4a 678 16, /* size/bytes */
sPymbed 0:1387ff3eed4a 679 ECC_SECP128R1, /* ID */
sPymbed 0:1387ff3eed4a 680 "SECP128R1", /* curve name */
sPymbed 0:1387ff3eed4a 681 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 682 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 683 "E87579C11079F43DD824993C2CEE5ED3", /* B */
sPymbed 0:1387ff3eed4a 684 "FFFFFFFE0000000075A30D1B9038A115", /* order */
sPymbed 0:1387ff3eed4a 685 "161FF7528B899B2D0C28607CA52C5B86", /* Gx */
sPymbed 0:1387ff3eed4a 686 "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */
sPymbed 0:1387ff3eed4a 687 ecc_oid_secp128r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 688 ecc_oid_secp128r1_sz,
sPymbed 0:1387ff3eed4a 689 ECC_SECP128R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 690 1, /* cofactor */
sPymbed 0:1387ff3eed4a 691 },
sPymbed 0:1387ff3eed4a 692 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 693 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 694 {
sPymbed 0:1387ff3eed4a 695 16, /* size/bytes */
sPymbed 0:1387ff3eed4a 696 ECC_SECP128R2, /* ID */
sPymbed 0:1387ff3eed4a 697 "SECP128R2", /* curve name */
sPymbed 0:1387ff3eed4a 698 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 699 "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */
sPymbed 0:1387ff3eed4a 700 "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */
sPymbed 0:1387ff3eed4a 701 "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */
sPymbed 0:1387ff3eed4a 702 "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */
sPymbed 0:1387ff3eed4a 703 "27B6916A894D3AEE7106FE805FC34B44", /* Gy */
sPymbed 0:1387ff3eed4a 704 ecc_oid_secp128r2, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 705 ecc_oid_secp128r2_sz,
sPymbed 0:1387ff3eed4a 706 ECC_SECP128R2_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 707 4, /* cofactor */
sPymbed 0:1387ff3eed4a 708 },
sPymbed 0:1387ff3eed4a 709 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 710 #endif /* ECC128 */
sPymbed 0:1387ff3eed4a 711 #ifdef ECC160
sPymbed 0:1387ff3eed4a 712 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 713 {
sPymbed 0:1387ff3eed4a 714 20, /* size/bytes */
sPymbed 0:1387ff3eed4a 715 ECC_SECP160R1, /* ID */
sPymbed 0:1387ff3eed4a 716 "SECP160R1", /* curve name */
sPymbed 0:1387ff3eed4a 717 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 718 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 719 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */
sPymbed 0:1387ff3eed4a 720 "100000000000000000001F4C8F927AED3CA752257",/* order */
sPymbed 0:1387ff3eed4a 721 "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */
sPymbed 0:1387ff3eed4a 722 "23A628553168947D59DCC912042351377AC5FB32", /* Gy */
sPymbed 0:1387ff3eed4a 723 ecc_oid_secp160r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 724 ecc_oid_secp160r1_sz,
sPymbed 0:1387ff3eed4a 725 ECC_SECP160R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 726 1, /* cofactor */
sPymbed 0:1387ff3eed4a 727 },
sPymbed 0:1387ff3eed4a 728 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 729 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 730 {
sPymbed 0:1387ff3eed4a 731 20, /* size/bytes */
sPymbed 0:1387ff3eed4a 732 ECC_SECP160R2, /* ID */
sPymbed 0:1387ff3eed4a 733 "SECP160R2", /* curve name */
sPymbed 0:1387ff3eed4a 734 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */
sPymbed 0:1387ff3eed4a 735 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */
sPymbed 0:1387ff3eed4a 736 "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */
sPymbed 0:1387ff3eed4a 737 "100000000000000000000351EE786A818F3A1A16B",/* order */
sPymbed 0:1387ff3eed4a 738 "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */
sPymbed 0:1387ff3eed4a 739 "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */
sPymbed 0:1387ff3eed4a 740 ecc_oid_secp160r2, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 741 ecc_oid_secp160r2_sz,
sPymbed 0:1387ff3eed4a 742 ECC_SECP160R2_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 743 1, /* cofactor */
sPymbed 0:1387ff3eed4a 744 },
sPymbed 0:1387ff3eed4a 745 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 746 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 747 {
sPymbed 0:1387ff3eed4a 748 20, /* size/bytes */
sPymbed 0:1387ff3eed4a 749 ECC_SECP160K1, /* ID */
sPymbed 0:1387ff3eed4a 750 "SECP160K1", /* curve name */
sPymbed 0:1387ff3eed4a 751 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */
sPymbed 0:1387ff3eed4a 752 "0000000000000000000000000000000000000000", /* A */
sPymbed 0:1387ff3eed4a 753 "0000000000000000000000000000000000000007", /* B */
sPymbed 0:1387ff3eed4a 754 "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */
sPymbed 0:1387ff3eed4a 755 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */
sPymbed 0:1387ff3eed4a 756 "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */
sPymbed 0:1387ff3eed4a 757 ecc_oid_secp160k1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 758 ecc_oid_secp160k1_sz,
sPymbed 0:1387ff3eed4a 759 ECC_SECP160K1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 760 1, /* cofactor */
sPymbed 0:1387ff3eed4a 761 },
sPymbed 0:1387ff3eed4a 762 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 763 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 764 {
sPymbed 0:1387ff3eed4a 765 20, /* size/bytes */
sPymbed 0:1387ff3eed4a 766 ECC_BRAINPOOLP160R1, /* ID */
sPymbed 0:1387ff3eed4a 767 "BRAINPOOLP160R1", /* curve name */
sPymbed 0:1387ff3eed4a 768 "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */
sPymbed 0:1387ff3eed4a 769 "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */
sPymbed 0:1387ff3eed4a 770 "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */
sPymbed 0:1387ff3eed4a 771 "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */
sPymbed 0:1387ff3eed4a 772 "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */
sPymbed 0:1387ff3eed4a 773 "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */
sPymbed 0:1387ff3eed4a 774 ecc_oid_brainpoolp160r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 775 ecc_oid_brainpoolp160r1_sz,
sPymbed 0:1387ff3eed4a 776 ECC_BRAINPOOLP160R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 777 1, /* cofactor */
sPymbed 0:1387ff3eed4a 778 },
sPymbed 0:1387ff3eed4a 779 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 780 #endif /* ECC160 */
sPymbed 0:1387ff3eed4a 781 #ifdef ECC192
sPymbed 0:1387ff3eed4a 782 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 783 {
sPymbed 0:1387ff3eed4a 784 24, /* size/bytes */
sPymbed 0:1387ff3eed4a 785 ECC_SECP192R1, /* ID */
sPymbed 0:1387ff3eed4a 786 "SECP192R1", /* curve name */
sPymbed 0:1387ff3eed4a 787 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 788 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 789 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B */
sPymbed 0:1387ff3eed4a 790 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */
sPymbed 0:1387ff3eed4a 791 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */
sPymbed 0:1387ff3eed4a 792 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */
sPymbed 0:1387ff3eed4a 793 ecc_oid_secp192r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 794 ecc_oid_secp192r1_sz,
sPymbed 0:1387ff3eed4a 795 ECC_SECP192R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 796 1, /* cofactor */
sPymbed 0:1387ff3eed4a 797 },
sPymbed 0:1387ff3eed4a 798 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 799 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 800 {
sPymbed 0:1387ff3eed4a 801 24, /* size/bytes */
sPymbed 0:1387ff3eed4a 802 ECC_PRIME192V2, /* ID */
sPymbed 0:1387ff3eed4a 803 "PRIME192V2", /* curve name */
sPymbed 0:1387ff3eed4a 804 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 805 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 806 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */
sPymbed 0:1387ff3eed4a 807 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */
sPymbed 0:1387ff3eed4a 808 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */
sPymbed 0:1387ff3eed4a 809 "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */
sPymbed 0:1387ff3eed4a 810 ecc_oid_prime192v2, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 811 ecc_oid_prime192v2_sz,
sPymbed 0:1387ff3eed4a 812 ECC_PRIME192V2_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 813 1, /* cofactor */
sPymbed 0:1387ff3eed4a 814 },
sPymbed 0:1387ff3eed4a 815 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 816 #ifdef HAVE_ECC_SECPR3
sPymbed 0:1387ff3eed4a 817 {
sPymbed 0:1387ff3eed4a 818 24, /* size/bytes */
sPymbed 0:1387ff3eed4a 819 ECC_PRIME192V3, /* ID */
sPymbed 0:1387ff3eed4a 820 "PRIME192V3", /* curve name */
sPymbed 0:1387ff3eed4a 821 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 822 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 823 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */
sPymbed 0:1387ff3eed4a 824 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */
sPymbed 0:1387ff3eed4a 825 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */
sPymbed 0:1387ff3eed4a 826 "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */
sPymbed 0:1387ff3eed4a 827 ecc_oid_prime192v3, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 828 ecc_oid_prime192v3_sz,
sPymbed 0:1387ff3eed4a 829 ECC_PRIME192V3_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 830 1, /* cofactor */
sPymbed 0:1387ff3eed4a 831 },
sPymbed 0:1387ff3eed4a 832 #endif /* HAVE_ECC_SECPR3 */
sPymbed 0:1387ff3eed4a 833 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 834 {
sPymbed 0:1387ff3eed4a 835 24, /* size/bytes */
sPymbed 0:1387ff3eed4a 836 ECC_SECP192K1, /* ID */
sPymbed 0:1387ff3eed4a 837 "SECP192K1", /* curve name */
sPymbed 0:1387ff3eed4a 838 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */
sPymbed 0:1387ff3eed4a 839 "000000000000000000000000000000000000000000000000", /* A */
sPymbed 0:1387ff3eed4a 840 "000000000000000000000000000000000000000000000003", /* B */
sPymbed 0:1387ff3eed4a 841 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */
sPymbed 0:1387ff3eed4a 842 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */
sPymbed 0:1387ff3eed4a 843 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */
sPymbed 0:1387ff3eed4a 844 ecc_oid_secp192k1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 845 ecc_oid_secp192k1_sz,
sPymbed 0:1387ff3eed4a 846 ECC_SECP192K1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 847 1, /* cofactor */
sPymbed 0:1387ff3eed4a 848 },
sPymbed 0:1387ff3eed4a 849 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 850 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 851 {
sPymbed 0:1387ff3eed4a 852 24, /* size/bytes */
sPymbed 0:1387ff3eed4a 853 ECC_BRAINPOOLP192R1, /* ID */
sPymbed 0:1387ff3eed4a 854 "BRAINPOOLP192R1", /* curve name */
sPymbed 0:1387ff3eed4a 855 "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */
sPymbed 0:1387ff3eed4a 856 "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */
sPymbed 0:1387ff3eed4a 857 "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */
sPymbed 0:1387ff3eed4a 858 "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */
sPymbed 0:1387ff3eed4a 859 "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */
sPymbed 0:1387ff3eed4a 860 "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */
sPymbed 0:1387ff3eed4a 861 ecc_oid_brainpoolp192r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 862 ecc_oid_brainpoolp192r1_sz,
sPymbed 0:1387ff3eed4a 863 ECC_BRAINPOOLP192R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 864 1, /* cofactor */
sPymbed 0:1387ff3eed4a 865 },
sPymbed 0:1387ff3eed4a 866 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 867 #endif /* ECC192 */
sPymbed 0:1387ff3eed4a 868 #ifdef ECC224
sPymbed 0:1387ff3eed4a 869 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 870 {
sPymbed 0:1387ff3eed4a 871 28, /* size/bytes */
sPymbed 0:1387ff3eed4a 872 ECC_SECP224R1, /* ID */
sPymbed 0:1387ff3eed4a 873 "SECP224R1", /* curve name */
sPymbed 0:1387ff3eed4a 874 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */
sPymbed 0:1387ff3eed4a 875 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */
sPymbed 0:1387ff3eed4a 876 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B */
sPymbed 0:1387ff3eed4a 877 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */
sPymbed 0:1387ff3eed4a 878 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */
sPymbed 0:1387ff3eed4a 879 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */
sPymbed 0:1387ff3eed4a 880 ecc_oid_secp224r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 881 ecc_oid_secp224r1_sz,
sPymbed 0:1387ff3eed4a 882 ECC_SECP224R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 883 1, /* cofactor */
sPymbed 0:1387ff3eed4a 884 },
sPymbed 0:1387ff3eed4a 885 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 886 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 887 {
sPymbed 0:1387ff3eed4a 888 28, /* size/bytes */
sPymbed 0:1387ff3eed4a 889 ECC_SECP224K1, /* ID */
sPymbed 0:1387ff3eed4a 890 "SECP224K1", /* curve name */
sPymbed 0:1387ff3eed4a 891 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */
sPymbed 0:1387ff3eed4a 892 "00000000000000000000000000000000000000000000000000000000", /* A */
sPymbed 0:1387ff3eed4a 893 "00000000000000000000000000000000000000000000000000000005", /* B */
sPymbed 0:1387ff3eed4a 894 "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */
sPymbed 0:1387ff3eed4a 895 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */
sPymbed 0:1387ff3eed4a 896 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */
sPymbed 0:1387ff3eed4a 897 ecc_oid_secp224k1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 898 ecc_oid_secp224k1_sz,
sPymbed 0:1387ff3eed4a 899 ECC_SECP224K1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 900 1, /* cofactor */
sPymbed 0:1387ff3eed4a 901 },
sPymbed 0:1387ff3eed4a 902 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 903 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 904 {
sPymbed 0:1387ff3eed4a 905 28, /* size/bytes */
sPymbed 0:1387ff3eed4a 906 ECC_BRAINPOOLP224R1, /* ID */
sPymbed 0:1387ff3eed4a 907 "BRAINPOOLP224R1", /* curve name */
sPymbed 0:1387ff3eed4a 908 "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */
sPymbed 0:1387ff3eed4a 909 "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */
sPymbed 0:1387ff3eed4a 910 "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */
sPymbed 0:1387ff3eed4a 911 "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */
sPymbed 0:1387ff3eed4a 912 "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */
sPymbed 0:1387ff3eed4a 913 "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */
sPymbed 0:1387ff3eed4a 914 ecc_oid_brainpoolp224r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 915 ecc_oid_brainpoolp224r1_sz,
sPymbed 0:1387ff3eed4a 916 ECC_BRAINPOOLP224R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 917 1, /* cofactor */
sPymbed 0:1387ff3eed4a 918 },
sPymbed 0:1387ff3eed4a 919 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 920 #endif /* ECC224 */
sPymbed 0:1387ff3eed4a 921 #ifdef ECC239
sPymbed 0:1387ff3eed4a 922 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 923 {
sPymbed 0:1387ff3eed4a 924 30, /* size/bytes */
sPymbed 0:1387ff3eed4a 925 ECC_PRIME239V1, /* ID */
sPymbed 0:1387ff3eed4a 926 "PRIME239V1", /* curve name */
sPymbed 0:1387ff3eed4a 927 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 928 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 929 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */
sPymbed 0:1387ff3eed4a 930 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */
sPymbed 0:1387ff3eed4a 931 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */
sPymbed 0:1387ff3eed4a 932 "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */
sPymbed 0:1387ff3eed4a 933 ecc_oid_prime239v1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 934 ecc_oid_prime239v1_sz,
sPymbed 0:1387ff3eed4a 935 ECC_PRIME239V1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 936 1, /* cofactor */
sPymbed 0:1387ff3eed4a 937 },
sPymbed 0:1387ff3eed4a 938 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 939 #ifdef HAVE_ECC_SECPR2
sPymbed 0:1387ff3eed4a 940 {
sPymbed 0:1387ff3eed4a 941 30, /* size/bytes */
sPymbed 0:1387ff3eed4a 942 ECC_PRIME239V2, /* ID */
sPymbed 0:1387ff3eed4a 943 "PRIME239V2", /* curve name */
sPymbed 0:1387ff3eed4a 944 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 945 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 946 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */
sPymbed 0:1387ff3eed4a 947 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */
sPymbed 0:1387ff3eed4a 948 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */
sPymbed 0:1387ff3eed4a 949 "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */
sPymbed 0:1387ff3eed4a 950 ecc_oid_prime239v2, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 951 ecc_oid_prime239v2_sz,
sPymbed 0:1387ff3eed4a 952 ECC_PRIME239V2_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 953 1, /* cofactor */
sPymbed 0:1387ff3eed4a 954 },
sPymbed 0:1387ff3eed4a 955 #endif /* HAVE_ECC_SECPR2 */
sPymbed 0:1387ff3eed4a 956 #ifdef HAVE_ECC_SECPR3
sPymbed 0:1387ff3eed4a 957 {
sPymbed 0:1387ff3eed4a 958 30, /* size/bytes */
sPymbed 0:1387ff3eed4a 959 ECC_PRIME239V3, /* ID */
sPymbed 0:1387ff3eed4a 960 "PRIME239V3", /* curve name */
sPymbed 0:1387ff3eed4a 961 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 962 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 963 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */
sPymbed 0:1387ff3eed4a 964 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */
sPymbed 0:1387ff3eed4a 965 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */
sPymbed 0:1387ff3eed4a 966 "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */
sPymbed 0:1387ff3eed4a 967 ecc_oid_prime239v3, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 968 ecc_oid_prime239v3_sz,
sPymbed 0:1387ff3eed4a 969 ECC_PRIME239V3_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 970 1, /* cofactor */
sPymbed 0:1387ff3eed4a 971 },
sPymbed 0:1387ff3eed4a 972 #endif /* HAVE_ECC_SECPR3 */
sPymbed 0:1387ff3eed4a 973 #endif /* ECC239 */
sPymbed 0:1387ff3eed4a 974 #ifdef ECC256
sPymbed 0:1387ff3eed4a 975 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 976 {
sPymbed 0:1387ff3eed4a 977 32, /* size/bytes */
sPymbed 0:1387ff3eed4a 978 ECC_SECP256R1, /* ID */
sPymbed 0:1387ff3eed4a 979 "SECP256R1", /* curve name */
sPymbed 0:1387ff3eed4a 980 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 981 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 982 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B */
sPymbed 0:1387ff3eed4a 983 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */
sPymbed 0:1387ff3eed4a 984 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */
sPymbed 0:1387ff3eed4a 985 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */
sPymbed 0:1387ff3eed4a 986 ecc_oid_secp256r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 987 ecc_oid_secp256r1_sz,
sPymbed 0:1387ff3eed4a 988 ECC_SECP256R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 989 1, /* cofactor */
sPymbed 0:1387ff3eed4a 990 },
sPymbed 0:1387ff3eed4a 991 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 992 #ifdef HAVE_ECC_KOBLITZ
sPymbed 0:1387ff3eed4a 993 {
sPymbed 0:1387ff3eed4a 994 32, /* size/bytes */
sPymbed 0:1387ff3eed4a 995 ECC_SECP256K1, /* ID */
sPymbed 0:1387ff3eed4a 996 "SECP256K1", /* curve name */
sPymbed 0:1387ff3eed4a 997 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */
sPymbed 0:1387ff3eed4a 998 "0000000000000000000000000000000000000000000000000000000000000000", /* A */
sPymbed 0:1387ff3eed4a 999 "0000000000000000000000000000000000000000000000000000000000000007", /* B */
sPymbed 0:1387ff3eed4a 1000 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */
sPymbed 0:1387ff3eed4a 1001 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */
sPymbed 0:1387ff3eed4a 1002 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */
sPymbed 0:1387ff3eed4a 1003 ecc_oid_secp256k1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1004 ecc_oid_secp256k1_sz,
sPymbed 0:1387ff3eed4a 1005 ECC_SECP256K1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1006 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1007 },
sPymbed 0:1387ff3eed4a 1008 #endif /* HAVE_ECC_KOBLITZ */
sPymbed 0:1387ff3eed4a 1009 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 1010 {
sPymbed 0:1387ff3eed4a 1011 32, /* size/bytes */
sPymbed 0:1387ff3eed4a 1012 ECC_BRAINPOOLP256R1, /* ID */
sPymbed 0:1387ff3eed4a 1013 "BRAINPOOLP256R1", /* curve name */
sPymbed 0:1387ff3eed4a 1014 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */
sPymbed 0:1387ff3eed4a 1015 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
sPymbed 0:1387ff3eed4a 1016 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
sPymbed 0:1387ff3eed4a 1017 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */
sPymbed 0:1387ff3eed4a 1018 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */
sPymbed 0:1387ff3eed4a 1019 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */
sPymbed 0:1387ff3eed4a 1020 ecc_oid_brainpoolp256r1, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1021 ecc_oid_brainpoolp256r1_sz,
sPymbed 0:1387ff3eed4a 1022 ECC_BRAINPOOLP256R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1023 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1024 },
sPymbed 0:1387ff3eed4a 1025 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 1026 #endif /* ECC256 */
sPymbed 0:1387ff3eed4a 1027 #ifdef ECC320
sPymbed 0:1387ff3eed4a 1028 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 1029 {
sPymbed 0:1387ff3eed4a 1030 40, /* size/bytes */
sPymbed 0:1387ff3eed4a 1031 ECC_BRAINPOOLP320R1, /* ID */
sPymbed 0:1387ff3eed4a 1032 "BRAINPOOLP320R1", /* curve name */
sPymbed 0:1387ff3eed4a 1033 "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */
sPymbed 0:1387ff3eed4a 1034 "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */
sPymbed 0:1387ff3eed4a 1035 "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */
sPymbed 0:1387ff3eed4a 1036 "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */
sPymbed 0:1387ff3eed4a 1037 "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */
sPymbed 0:1387ff3eed4a 1038 "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */
sPymbed 0:1387ff3eed4a 1039 ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1040 ECC_BRAINPOOLP320R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1041 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1042 },
sPymbed 0:1387ff3eed4a 1043 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 1044 #endif /* ECC320 */
sPymbed 0:1387ff3eed4a 1045 #ifdef ECC384
sPymbed 0:1387ff3eed4a 1046 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 1047 {
sPymbed 0:1387ff3eed4a 1048 48, /* size/bytes */
sPymbed 0:1387ff3eed4a 1049 ECC_SECP384R1, /* ID */
sPymbed 0:1387ff3eed4a 1050 "SECP384R1", /* curve name */
sPymbed 0:1387ff3eed4a 1051 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 1052 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 1053 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B */
sPymbed 0:1387ff3eed4a 1054 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */
sPymbed 0:1387ff3eed4a 1055 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */
sPymbed 0:1387ff3eed4a 1056 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */
sPymbed 0:1387ff3eed4a 1057 ecc_oid_secp384r1, ecc_oid_secp384r1_sz, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1058 ECC_SECP384R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1059 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1060 },
sPymbed 0:1387ff3eed4a 1061 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 1062 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 1063 {
sPymbed 0:1387ff3eed4a 1064 48, /* size/bytes */
sPymbed 0:1387ff3eed4a 1065 ECC_BRAINPOOLP384R1, /* ID */
sPymbed 0:1387ff3eed4a 1066 "BRAINPOOLP384R1", /* curve name */
sPymbed 0:1387ff3eed4a 1067 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */
sPymbed 0:1387ff3eed4a 1068 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */
sPymbed 0:1387ff3eed4a 1069 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */
sPymbed 0:1387ff3eed4a 1070 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */
sPymbed 0:1387ff3eed4a 1071 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */
sPymbed 0:1387ff3eed4a 1072 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */
sPymbed 0:1387ff3eed4a 1073 ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1074 ECC_BRAINPOOLP384R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1075 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1076 },
sPymbed 0:1387ff3eed4a 1077 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 1078 #endif /* ECC384 */
sPymbed 0:1387ff3eed4a 1079 #ifdef ECC512
sPymbed 0:1387ff3eed4a 1080 #ifdef HAVE_ECC_BRAINPOOL
sPymbed 0:1387ff3eed4a 1081 {
sPymbed 0:1387ff3eed4a 1082 64, /* size/bytes */
sPymbed 0:1387ff3eed4a 1083 ECC_BRAINPOOLP512R1, /* ID */
sPymbed 0:1387ff3eed4a 1084 "BRAINPOOLP512R1", /* curve name */
sPymbed 0:1387ff3eed4a 1085 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */
sPymbed 0:1387ff3eed4a 1086 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */
sPymbed 0:1387ff3eed4a 1087 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */
sPymbed 0:1387ff3eed4a 1088 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */
sPymbed 0:1387ff3eed4a 1089 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */
sPymbed 0:1387ff3eed4a 1090 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */
sPymbed 0:1387ff3eed4a 1091 ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1092 ECC_BRAINPOOLP512R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1093 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1094 },
sPymbed 0:1387ff3eed4a 1095 #endif /* HAVE_ECC_BRAINPOOL */
sPymbed 0:1387ff3eed4a 1096 #endif /* ECC512 */
sPymbed 0:1387ff3eed4a 1097 #ifdef ECC521
sPymbed 0:1387ff3eed4a 1098 #ifndef NO_ECC_SECP
sPymbed 0:1387ff3eed4a 1099 {
sPymbed 0:1387ff3eed4a 1100 66, /* size/bytes */
sPymbed 0:1387ff3eed4a 1101 ECC_SECP521R1, /* ID */
sPymbed 0:1387ff3eed4a 1102 "SECP521R1", /* curve name */
sPymbed 0:1387ff3eed4a 1103 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */
sPymbed 0:1387ff3eed4a 1104 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */
sPymbed 0:1387ff3eed4a 1105 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */
sPymbed 0:1387ff3eed4a 1106 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */
sPymbed 0:1387ff3eed4a 1107 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */
sPymbed 0:1387ff3eed4a 1108 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */
sPymbed 0:1387ff3eed4a 1109 ecc_oid_secp521r1, ecc_oid_secp521r1_sz, /* oid/oidSz */
sPymbed 0:1387ff3eed4a 1110 ECC_SECP521R1_OID, /* oid sum */
sPymbed 0:1387ff3eed4a 1111 1, /* cofactor */
sPymbed 0:1387ff3eed4a 1112 },
sPymbed 0:1387ff3eed4a 1113 #endif /* !NO_ECC_SECP */
sPymbed 0:1387ff3eed4a 1114 #endif /* ECC521 */
sPymbed 0:1387ff3eed4a 1115 #if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
sPymbed 0:1387ff3eed4a 1116 /* place holder for custom curve index for cache */
sPymbed 0:1387ff3eed4a 1117 {
sPymbed 0:1387ff3eed4a 1118 1, /* non-zero */
sPymbed 0:1387ff3eed4a 1119 ECC_CURVE_CUSTOM,
sPymbed 0:1387ff3eed4a 1120 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 1121 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
sPymbed 0:1387ff3eed4a 1122 #else
sPymbed 0:1387ff3eed4a 1123 0, 0, 0, 0, 0, 0, 0, 0,
sPymbed 0:1387ff3eed4a 1124 #endif
sPymbed 0:1387ff3eed4a 1125 0, 0, 0
sPymbed 0:1387ff3eed4a 1126 },
sPymbed 0:1387ff3eed4a 1127 #endif
sPymbed 0:1387ff3eed4a 1128 {
sPymbed 0:1387ff3eed4a 1129 0, -1,
sPymbed 0:1387ff3eed4a 1130 #ifndef USE_WINDOWS_API
sPymbed 0:1387ff3eed4a 1131 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
sPymbed 0:1387ff3eed4a 1132 #else
sPymbed 0:1387ff3eed4a 1133 0, 0, 0, 0, 0, 0, 0, 0,
sPymbed 0:1387ff3eed4a 1134 #endif
sPymbed 0:1387ff3eed4a 1135 0, 0, 0
sPymbed 0:1387ff3eed4a 1136 }
sPymbed 0:1387ff3eed4a 1137 };
sPymbed 0:1387ff3eed4a 1138 #define ECC_SET_COUNT (sizeof(ecc_sets)/sizeof(ecc_set_type))
sPymbed 0:1387ff3eed4a 1139
sPymbed 0:1387ff3eed4a 1140
sPymbed 0:1387ff3eed4a 1141 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 1142 /* encoded OID cache */
sPymbed 0:1387ff3eed4a 1143 typedef struct {
sPymbed 0:1387ff3eed4a 1144 word32 oidSz;
sPymbed 0:1387ff3eed4a 1145 byte oid[ECC_MAX_OID_LEN];
sPymbed 0:1387ff3eed4a 1146 } oid_cache_t;
sPymbed 0:1387ff3eed4a 1147 static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
sPymbed 0:1387ff3eed4a 1148 #endif
sPymbed 0:1387ff3eed4a 1149
sPymbed 0:1387ff3eed4a 1150
sPymbed 0:1387ff3eed4a 1151 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 1152 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
sPymbed 0:1387ff3eed4a 1153 #endif
sPymbed 0:1387ff3eed4a 1154
sPymbed 0:1387ff3eed4a 1155 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 1156 typedef void* ecc_curve_spec;
sPymbed 0:1387ff3eed4a 1157 #else
sPymbed 0:1387ff3eed4a 1158
sPymbed 0:1387ff3eed4a 1159 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
sPymbed 0:1387ff3eed4a 1160 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
sPymbed 0:1387ff3eed4a 1161 mp_int* prime, mp_int* order);
sPymbed 0:1387ff3eed4a 1162 #endif
sPymbed 0:1387ff3eed4a 1163
sPymbed 0:1387ff3eed4a 1164 int mp_jacobi(mp_int* a, mp_int* n, int* c);
sPymbed 0:1387ff3eed4a 1165 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
sPymbed 0:1387ff3eed4a 1166
sPymbed 0:1387ff3eed4a 1167
sPymbed 0:1387ff3eed4a 1168 /* Curve Specs */
sPymbed 0:1387ff3eed4a 1169 typedef struct ecc_curve_spec {
sPymbed 0:1387ff3eed4a 1170 const ecc_set_type* dp;
sPymbed 0:1387ff3eed4a 1171
sPymbed 0:1387ff3eed4a 1172 mp_int* prime;
sPymbed 0:1387ff3eed4a 1173 mp_int* Af;
sPymbed 0:1387ff3eed4a 1174 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1175 mp_int* Bf;
sPymbed 0:1387ff3eed4a 1176 #endif
sPymbed 0:1387ff3eed4a 1177 mp_int* order;
sPymbed 0:1387ff3eed4a 1178 mp_int* Gx;
sPymbed 0:1387ff3eed4a 1179 mp_int* Gy;
sPymbed 0:1387ff3eed4a 1180
sPymbed 0:1387ff3eed4a 1181 #ifdef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1182 mp_int prime_lcl;
sPymbed 0:1387ff3eed4a 1183 mp_int Af_lcl;
sPymbed 0:1387ff3eed4a 1184 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1185 mp_int Bf_lcl;
sPymbed 0:1387ff3eed4a 1186 #endif
sPymbed 0:1387ff3eed4a 1187 mp_int order_lcl;
sPymbed 0:1387ff3eed4a 1188 mp_int Gx_lcl;
sPymbed 0:1387ff3eed4a 1189 mp_int Gy_lcl;
sPymbed 0:1387ff3eed4a 1190 #else
sPymbed 0:1387ff3eed4a 1191 mp_int* spec_ints;
sPymbed 0:1387ff3eed4a 1192 word32 spec_count;
sPymbed 0:1387ff3eed4a 1193 word32 spec_use;
sPymbed 0:1387ff3eed4a 1194 #endif
sPymbed 0:1387ff3eed4a 1195
sPymbed 0:1387ff3eed4a 1196 byte load_mask;
sPymbed 0:1387ff3eed4a 1197 } ecc_curve_spec;
sPymbed 0:1387ff3eed4a 1198
sPymbed 0:1387ff3eed4a 1199 enum ecc_curve_load_mask {
sPymbed 0:1387ff3eed4a 1200 ECC_CURVE_FIELD_NONE = 0x00,
sPymbed 0:1387ff3eed4a 1201 ECC_CURVE_FIELD_PRIME = 0x01,
sPymbed 0:1387ff3eed4a 1202 ECC_CURVE_FIELD_AF = 0x02,
sPymbed 0:1387ff3eed4a 1203 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1204 ECC_CURVE_FIELD_BF = 0x04,
sPymbed 0:1387ff3eed4a 1205 #endif
sPymbed 0:1387ff3eed4a 1206 ECC_CURVE_FIELD_ORDER = 0x08,
sPymbed 0:1387ff3eed4a 1207 ECC_CURVE_FIELD_GX = 0x10,
sPymbed 0:1387ff3eed4a 1208 ECC_CURVE_FIELD_GY = 0x20,
sPymbed 0:1387ff3eed4a 1209 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1210 ECC_CURVE_FIELD_ALL = 0x3F,
sPymbed 0:1387ff3eed4a 1211 ECC_CURVE_FIELD_COUNT = 6,
sPymbed 0:1387ff3eed4a 1212 #else
sPymbed 0:1387ff3eed4a 1213 ECC_CURVE_FIELD_ALL = 0x3B,
sPymbed 0:1387ff3eed4a 1214 ECC_CURVE_FIELD_COUNT = 5,
sPymbed 0:1387ff3eed4a 1215 #endif
sPymbed 0:1387ff3eed4a 1216 };
sPymbed 0:1387ff3eed4a 1217
sPymbed 0:1387ff3eed4a 1218 #ifdef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1219 /* cache (mp_int) of the curve parameters */
sPymbed 0:1387ff3eed4a 1220 static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
sPymbed 0:1387ff3eed4a 1221 #ifndef SINGLE_THREADED
sPymbed 0:1387ff3eed4a 1222 static wolfSSL_Mutex ecc_curve_cache_mutex;
sPymbed 0:1387ff3eed4a 1223 #endif
sPymbed 0:1387ff3eed4a 1224
sPymbed 0:1387ff3eed4a 1225 #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL
sPymbed 0:1387ff3eed4a 1226 #define ALLOC_CURVE_SPECS(intcount)
sPymbed 0:1387ff3eed4a 1227 #define FREE_CURVE_SPECS()
sPymbed 0:1387ff3eed4a 1228 #elif defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 1229 #define DECLARE_CURVE_SPECS(curve, intcount) \
sPymbed 0:1387ff3eed4a 1230 mp_int* spec_ints = NULL; \
sPymbed 0:1387ff3eed4a 1231 ecc_curve_spec curve_lcl; \
sPymbed 0:1387ff3eed4a 1232 ecc_curve_spec* curve = &curve_lcl; \
sPymbed 0:1387ff3eed4a 1233 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
sPymbed 0:1387ff3eed4a 1234 curve->spec_count = intcount
sPymbed 0:1387ff3eed4a 1235
sPymbed 0:1387ff3eed4a 1236 #define ALLOC_CURVE_SPECS(intcount) \
sPymbed 0:1387ff3eed4a 1237 spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
sPymbed 0:1387ff3eed4a 1238 DYNAMIC_TYPE_ECC); \
sPymbed 0:1387ff3eed4a 1239 if (spec_ints == NULL) \
sPymbed 0:1387ff3eed4a 1240 return MEMORY_E; \
sPymbed 0:1387ff3eed4a 1241 curve->spec_ints = spec_ints
sPymbed 0:1387ff3eed4a 1242 #define FREE_CURVE_SPECS() \
sPymbed 0:1387ff3eed4a 1243 XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
sPymbed 0:1387ff3eed4a 1244 #else
sPymbed 0:1387ff3eed4a 1245 #define DECLARE_CURVE_SPECS(curve, intcount) \
sPymbed 0:1387ff3eed4a 1246 mp_int spec_ints[(intcount)]; \
sPymbed 0:1387ff3eed4a 1247 ecc_curve_spec curve_lcl; \
sPymbed 0:1387ff3eed4a 1248 ecc_curve_spec* curve = &curve_lcl; \
sPymbed 0:1387ff3eed4a 1249 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \
sPymbed 0:1387ff3eed4a 1250 curve->spec_ints = spec_ints; \
sPymbed 0:1387ff3eed4a 1251 curve->spec_count = intcount
sPymbed 0:1387ff3eed4a 1252 #define ALLOC_CURVE_SPECS(intcount)
sPymbed 0:1387ff3eed4a 1253 #define FREE_CURVE_SPECS()
sPymbed 0:1387ff3eed4a 1254 #endif /* ECC_CACHE_CURVE */
sPymbed 0:1387ff3eed4a 1255
sPymbed 0:1387ff3eed4a 1256 static void _wc_ecc_curve_free(ecc_curve_spec* curve)
sPymbed 0:1387ff3eed4a 1257 {
sPymbed 0:1387ff3eed4a 1258 if (curve == NULL) {
sPymbed 0:1387ff3eed4a 1259 return;
sPymbed 0:1387ff3eed4a 1260 }
sPymbed 0:1387ff3eed4a 1261
sPymbed 0:1387ff3eed4a 1262 if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
sPymbed 0:1387ff3eed4a 1263 mp_clear(curve->prime);
sPymbed 0:1387ff3eed4a 1264 if (curve->load_mask & ECC_CURVE_FIELD_AF)
sPymbed 0:1387ff3eed4a 1265 mp_clear(curve->Af);
sPymbed 0:1387ff3eed4a 1266 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1267 if (curve->load_mask & ECC_CURVE_FIELD_BF)
sPymbed 0:1387ff3eed4a 1268 mp_clear(curve->Bf);
sPymbed 0:1387ff3eed4a 1269 #endif
sPymbed 0:1387ff3eed4a 1270 if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
sPymbed 0:1387ff3eed4a 1271 mp_clear(curve->order);
sPymbed 0:1387ff3eed4a 1272 if (curve->load_mask & ECC_CURVE_FIELD_GX)
sPymbed 0:1387ff3eed4a 1273 mp_clear(curve->Gx);
sPymbed 0:1387ff3eed4a 1274 if (curve->load_mask & ECC_CURVE_FIELD_GY)
sPymbed 0:1387ff3eed4a 1275 mp_clear(curve->Gy);
sPymbed 0:1387ff3eed4a 1276
sPymbed 0:1387ff3eed4a 1277 curve->load_mask = 0;
sPymbed 0:1387ff3eed4a 1278 }
sPymbed 0:1387ff3eed4a 1279
sPymbed 0:1387ff3eed4a 1280 static void wc_ecc_curve_free(ecc_curve_spec* curve)
sPymbed 0:1387ff3eed4a 1281 {
sPymbed 0:1387ff3eed4a 1282 /* don't free cached curves */
sPymbed 0:1387ff3eed4a 1283 #ifndef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1284 _wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 1285 #endif
sPymbed 0:1387ff3eed4a 1286 (void)curve;
sPymbed 0:1387ff3eed4a 1287 }
sPymbed 0:1387ff3eed4a 1288
sPymbed 0:1387ff3eed4a 1289 static int wc_ecc_curve_load_item(const char* src, mp_int** dst,
sPymbed 0:1387ff3eed4a 1290 ecc_curve_spec* curve, byte mask)
sPymbed 0:1387ff3eed4a 1291 {
sPymbed 0:1387ff3eed4a 1292 int err;
sPymbed 0:1387ff3eed4a 1293
sPymbed 0:1387ff3eed4a 1294 #ifndef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1295 /* get mp_int from temp */
sPymbed 0:1387ff3eed4a 1296 if (curve->spec_use >= curve->spec_count) {
sPymbed 0:1387ff3eed4a 1297 WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
sPymbed 0:1387ff3eed4a 1298 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1299 }
sPymbed 0:1387ff3eed4a 1300 *dst = &curve->spec_ints[curve->spec_use++];
sPymbed 0:1387ff3eed4a 1301 #endif
sPymbed 0:1387ff3eed4a 1302
sPymbed 0:1387ff3eed4a 1303 err = mp_init(*dst);
sPymbed 0:1387ff3eed4a 1304 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1305 curve->load_mask |= mask;
sPymbed 0:1387ff3eed4a 1306
sPymbed 0:1387ff3eed4a 1307 err = mp_read_radix(*dst, src, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 1308
sPymbed 0:1387ff3eed4a 1309 #ifdef HAVE_WOLF_BIGINT
sPymbed 0:1387ff3eed4a 1310 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1311 err = wc_mp_to_bigint(*dst, &(*dst)->raw);
sPymbed 0:1387ff3eed4a 1312 #endif
sPymbed 0:1387ff3eed4a 1313 }
sPymbed 0:1387ff3eed4a 1314 return err;
sPymbed 0:1387ff3eed4a 1315 }
sPymbed 0:1387ff3eed4a 1316
sPymbed 0:1387ff3eed4a 1317 static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
sPymbed 0:1387ff3eed4a 1318 byte load_mask)
sPymbed 0:1387ff3eed4a 1319 {
sPymbed 0:1387ff3eed4a 1320 int ret = 0, x;
sPymbed 0:1387ff3eed4a 1321 ecc_curve_spec* curve;
sPymbed 0:1387ff3eed4a 1322 byte load_items = 0; /* mask of items to load */
sPymbed 0:1387ff3eed4a 1323
sPymbed 0:1387ff3eed4a 1324 if (dp == NULL || pCurve == NULL)
sPymbed 0:1387ff3eed4a 1325 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 1326
sPymbed 0:1387ff3eed4a 1327 #ifdef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1328 x = wc_ecc_get_curve_idx(dp->id);
sPymbed 0:1387ff3eed4a 1329 if (x == ECC_CURVE_INVALID)
sPymbed 0:1387ff3eed4a 1330 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1331
sPymbed 0:1387ff3eed4a 1332 #if !defined(SINGLE_THREADED)
sPymbed 0:1387ff3eed4a 1333 ret = wc_LockMutex(&ecc_curve_cache_mutex);
sPymbed 0:1387ff3eed4a 1334 if (ret != 0) {
sPymbed 0:1387ff3eed4a 1335 return ret;
sPymbed 0:1387ff3eed4a 1336 }
sPymbed 0:1387ff3eed4a 1337 #endif
sPymbed 0:1387ff3eed4a 1338
sPymbed 0:1387ff3eed4a 1339 /* make sure cache has been allocated */
sPymbed 0:1387ff3eed4a 1340 if (ecc_curve_spec_cache[x] == NULL) {
sPymbed 0:1387ff3eed4a 1341 ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC(
sPymbed 0:1387ff3eed4a 1342 sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1343 if (ecc_curve_spec_cache[x] == NULL) {
sPymbed 0:1387ff3eed4a 1344 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
sPymbed 0:1387ff3eed4a 1345 wc_UnLockMutex(&ecc_curve_cache_mutex);
sPymbed 0:1387ff3eed4a 1346 #endif
sPymbed 0:1387ff3eed4a 1347 return MEMORY_E;
sPymbed 0:1387ff3eed4a 1348 }
sPymbed 0:1387ff3eed4a 1349 XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec));
sPymbed 0:1387ff3eed4a 1350 }
sPymbed 0:1387ff3eed4a 1351
sPymbed 0:1387ff3eed4a 1352 /* set curve pointer to cache */
sPymbed 0:1387ff3eed4a 1353 *pCurve = ecc_curve_spec_cache[x];
sPymbed 0:1387ff3eed4a 1354
sPymbed 0:1387ff3eed4a 1355 #endif /* ECC_CACHE_CURVE */
sPymbed 0:1387ff3eed4a 1356 curve = *pCurve;
sPymbed 0:1387ff3eed4a 1357
sPymbed 0:1387ff3eed4a 1358 /* make sure the curve is initialized */
sPymbed 0:1387ff3eed4a 1359 if (curve->dp != dp) {
sPymbed 0:1387ff3eed4a 1360 curve->load_mask = 0;
sPymbed 0:1387ff3eed4a 1361
sPymbed 0:1387ff3eed4a 1362 #ifdef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1363 curve->prime = &curve->prime_lcl;
sPymbed 0:1387ff3eed4a 1364 curve->Af = &curve->Af_lcl;
sPymbed 0:1387ff3eed4a 1365 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1366 curve->Bf = &curve->Bf_lcl;
sPymbed 0:1387ff3eed4a 1367 #endif
sPymbed 0:1387ff3eed4a 1368 curve->order = &curve->order_lcl;
sPymbed 0:1387ff3eed4a 1369 curve->Gx = &curve->Gx_lcl;
sPymbed 0:1387ff3eed4a 1370 curve->Gy = &curve->Gy_lcl;
sPymbed 0:1387ff3eed4a 1371 #endif
sPymbed 0:1387ff3eed4a 1372 }
sPymbed 0:1387ff3eed4a 1373 curve->dp = dp; /* set dp info */
sPymbed 0:1387ff3eed4a 1374
sPymbed 0:1387ff3eed4a 1375 /* determine items to load */
sPymbed 0:1387ff3eed4a 1376 load_items = (((byte)~(word32)curve->load_mask) & load_mask);
sPymbed 0:1387ff3eed4a 1377 curve->load_mask |= load_items;
sPymbed 0:1387ff3eed4a 1378
sPymbed 0:1387ff3eed4a 1379 /* load items */
sPymbed 0:1387ff3eed4a 1380 x = 0;
sPymbed 0:1387ff3eed4a 1381 if (load_items & ECC_CURVE_FIELD_PRIME)
sPymbed 0:1387ff3eed4a 1382 x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve,
sPymbed 0:1387ff3eed4a 1383 ECC_CURVE_FIELD_PRIME);
sPymbed 0:1387ff3eed4a 1384 if (load_items & ECC_CURVE_FIELD_AF)
sPymbed 0:1387ff3eed4a 1385 x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve,
sPymbed 0:1387ff3eed4a 1386 ECC_CURVE_FIELD_AF);
sPymbed 0:1387ff3eed4a 1387 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 1388 if (load_items & ECC_CURVE_FIELD_BF)
sPymbed 0:1387ff3eed4a 1389 x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve,
sPymbed 0:1387ff3eed4a 1390 ECC_CURVE_FIELD_BF);
sPymbed 0:1387ff3eed4a 1391 #endif
sPymbed 0:1387ff3eed4a 1392 if (load_items & ECC_CURVE_FIELD_ORDER)
sPymbed 0:1387ff3eed4a 1393 x += wc_ecc_curve_load_item(dp->order, &curve->order, curve,
sPymbed 0:1387ff3eed4a 1394 ECC_CURVE_FIELD_ORDER);
sPymbed 0:1387ff3eed4a 1395 if (load_items & ECC_CURVE_FIELD_GX)
sPymbed 0:1387ff3eed4a 1396 x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve,
sPymbed 0:1387ff3eed4a 1397 ECC_CURVE_FIELD_GX);
sPymbed 0:1387ff3eed4a 1398 if (load_items & ECC_CURVE_FIELD_GY)
sPymbed 0:1387ff3eed4a 1399 x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve,
sPymbed 0:1387ff3eed4a 1400 ECC_CURVE_FIELD_GY);
sPymbed 0:1387ff3eed4a 1401
sPymbed 0:1387ff3eed4a 1402 /* check for error */
sPymbed 0:1387ff3eed4a 1403 if (x != 0) {
sPymbed 0:1387ff3eed4a 1404 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 1405 ret = MP_READ_E;
sPymbed 0:1387ff3eed4a 1406 }
sPymbed 0:1387ff3eed4a 1407
sPymbed 0:1387ff3eed4a 1408 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
sPymbed 0:1387ff3eed4a 1409 wc_UnLockMutex(&ecc_curve_cache_mutex);
sPymbed 0:1387ff3eed4a 1410 #endif
sPymbed 0:1387ff3eed4a 1411
sPymbed 0:1387ff3eed4a 1412 return ret;
sPymbed 0:1387ff3eed4a 1413 }
sPymbed 0:1387ff3eed4a 1414
sPymbed 0:1387ff3eed4a 1415 #ifdef ECC_CACHE_CURVE
sPymbed 0:1387ff3eed4a 1416 int wc_ecc_curve_cache_init(void)
sPymbed 0:1387ff3eed4a 1417 {
sPymbed 0:1387ff3eed4a 1418 int ret = 0;
sPymbed 0:1387ff3eed4a 1419 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
sPymbed 0:1387ff3eed4a 1420 ret = wc_InitMutex(&ecc_curve_cache_mutex);
sPymbed 0:1387ff3eed4a 1421 #endif
sPymbed 0:1387ff3eed4a 1422 return ret;
sPymbed 0:1387ff3eed4a 1423 }
sPymbed 0:1387ff3eed4a 1424
sPymbed 0:1387ff3eed4a 1425 void wc_ecc_curve_cache_free(void)
sPymbed 0:1387ff3eed4a 1426 {
sPymbed 0:1387ff3eed4a 1427 int x;
sPymbed 0:1387ff3eed4a 1428
sPymbed 0:1387ff3eed4a 1429 /* free all ECC curve caches */
sPymbed 0:1387ff3eed4a 1430 for (x = 0; x < (int)ECC_SET_COUNT; x++) {
sPymbed 0:1387ff3eed4a 1431 if (ecc_curve_spec_cache[x]) {
sPymbed 0:1387ff3eed4a 1432 _wc_ecc_curve_free(ecc_curve_spec_cache[x]);
sPymbed 0:1387ff3eed4a 1433 XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1434 ecc_curve_spec_cache[x] = NULL;
sPymbed 0:1387ff3eed4a 1435 }
sPymbed 0:1387ff3eed4a 1436 }
sPymbed 0:1387ff3eed4a 1437
sPymbed 0:1387ff3eed4a 1438 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
sPymbed 0:1387ff3eed4a 1439 wc_FreeMutex(&ecc_curve_cache_mutex);
sPymbed 0:1387ff3eed4a 1440 #endif
sPymbed 0:1387ff3eed4a 1441 }
sPymbed 0:1387ff3eed4a 1442 #endif /* ECC_CACHE_CURVE */
sPymbed 0:1387ff3eed4a 1443
sPymbed 0:1387ff3eed4a 1444 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 1445
sPymbed 0:1387ff3eed4a 1446
sPymbed 0:1387ff3eed4a 1447 /* Retrieve the curve name for the ECC curve id.
sPymbed 0:1387ff3eed4a 1448 *
sPymbed 0:1387ff3eed4a 1449 * curve_id The id of the curve.
sPymbed 0:1387ff3eed4a 1450 * returns the name stored from the curve if available, otherwise NULL.
sPymbed 0:1387ff3eed4a 1451 */
sPymbed 0:1387ff3eed4a 1452 const char* wc_ecc_get_name(int curve_id)
sPymbed 0:1387ff3eed4a 1453 {
sPymbed 0:1387ff3eed4a 1454 int curve_idx = wc_ecc_get_curve_idx(curve_id);
sPymbed 0:1387ff3eed4a 1455 if (curve_idx == ECC_CURVE_INVALID)
sPymbed 0:1387ff3eed4a 1456 return NULL;
sPymbed 0:1387ff3eed4a 1457 return ecc_sets[curve_idx].name;
sPymbed 0:1387ff3eed4a 1458 }
sPymbed 0:1387ff3eed4a 1459
sPymbed 0:1387ff3eed4a 1460 int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
sPymbed 0:1387ff3eed4a 1461 {
sPymbed 0:1387ff3eed4a 1462 if (keysize <= 0 && curve_id < 0) {
sPymbed 0:1387ff3eed4a 1463 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 1464 }
sPymbed 0:1387ff3eed4a 1465
sPymbed 0:1387ff3eed4a 1466 if (keysize > ECC_MAXSIZE) {
sPymbed 0:1387ff3eed4a 1467 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1468 }
sPymbed 0:1387ff3eed4a 1469
sPymbed 0:1387ff3eed4a 1470 /* handle custom case */
sPymbed 0:1387ff3eed4a 1471 if (key->idx != ECC_CUSTOM_IDX) {
sPymbed 0:1387ff3eed4a 1472 int x;
sPymbed 0:1387ff3eed4a 1473
sPymbed 0:1387ff3eed4a 1474 /* default values */
sPymbed 0:1387ff3eed4a 1475 key->idx = 0;
sPymbed 0:1387ff3eed4a 1476 key->dp = NULL;
sPymbed 0:1387ff3eed4a 1477
sPymbed 0:1387ff3eed4a 1478 /* find ecc_set based on curve_id or key size */
sPymbed 0:1387ff3eed4a 1479 for (x = 0; ecc_sets[x].size != 0; x++) {
sPymbed 0:1387ff3eed4a 1480 if (curve_id > ECC_CURVE_DEF) {
sPymbed 0:1387ff3eed4a 1481 if (curve_id == ecc_sets[x].id)
sPymbed 0:1387ff3eed4a 1482 break;
sPymbed 0:1387ff3eed4a 1483 }
sPymbed 0:1387ff3eed4a 1484 else if (keysize <= ecc_sets[x].size) {
sPymbed 0:1387ff3eed4a 1485 break;
sPymbed 0:1387ff3eed4a 1486 }
sPymbed 0:1387ff3eed4a 1487 }
sPymbed 0:1387ff3eed4a 1488 if (ecc_sets[x].size == 0) {
sPymbed 0:1387ff3eed4a 1489 WOLFSSL_MSG("ECC Curve not found");
sPymbed 0:1387ff3eed4a 1490 return ECC_CURVE_OID_E;
sPymbed 0:1387ff3eed4a 1491 }
sPymbed 0:1387ff3eed4a 1492
sPymbed 0:1387ff3eed4a 1493 key->idx = x;
sPymbed 0:1387ff3eed4a 1494 key->dp = &ecc_sets[x];
sPymbed 0:1387ff3eed4a 1495 }
sPymbed 0:1387ff3eed4a 1496
sPymbed 0:1387ff3eed4a 1497 return 0;
sPymbed 0:1387ff3eed4a 1498 }
sPymbed 0:1387ff3eed4a 1499
sPymbed 0:1387ff3eed4a 1500
sPymbed 0:1387ff3eed4a 1501 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1502 static void alt_fp_init(fp_int* a)
sPymbed 0:1387ff3eed4a 1503 {
sPymbed 0:1387ff3eed4a 1504 a->size = FP_SIZE_ECC;
sPymbed 0:1387ff3eed4a 1505 fp_zero(a);
sPymbed 0:1387ff3eed4a 1506 }
sPymbed 0:1387ff3eed4a 1507 #endif /* ALT_ECC_SIZE */
sPymbed 0:1387ff3eed4a 1508
sPymbed 0:1387ff3eed4a 1509
sPymbed 0:1387ff3eed4a 1510 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 1511
sPymbed 0:1387ff3eed4a 1512 #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
sPymbed 0:1387ff3eed4a 1513
sPymbed 0:1387ff3eed4a 1514 /**
sPymbed 0:1387ff3eed4a 1515 Add two ECC points
sPymbed 0:1387ff3eed4a 1516 P The point to add
sPymbed 0:1387ff3eed4a 1517 Q The point to add
sPymbed 0:1387ff3eed4a 1518 R [out] The destination of the double
sPymbed 0:1387ff3eed4a 1519 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 1520 modulus The modulus of the field the ECC curve is in
sPymbed 0:1387ff3eed4a 1521 mp The "b" value from montgomery_setup()
sPymbed 0:1387ff3eed4a 1522 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 1523 */
sPymbed 0:1387ff3eed4a 1524 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
sPymbed 0:1387ff3eed4a 1525 mp_int* a, mp_int* modulus, mp_digit mp)
sPymbed 0:1387ff3eed4a 1526 {
sPymbed 0:1387ff3eed4a 1527 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 1528 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1529 mp_int* t1 = NULL;
sPymbed 0:1387ff3eed4a 1530 mp_int* t2 = NULL;
sPymbed 0:1387ff3eed4a 1531 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1532 mp_int* rx = NULL;
sPymbed 0:1387ff3eed4a 1533 mp_int* ry = NULL;
sPymbed 0:1387ff3eed4a 1534 mp_int* rz = NULL;
sPymbed 0:1387ff3eed4a 1535 #endif
sPymbed 0:1387ff3eed4a 1536 #else
sPymbed 0:1387ff3eed4a 1537 mp_int t1[1], t2[1];
sPymbed 0:1387ff3eed4a 1538 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1539 mp_int rx[1], ry[1], rz[1];
sPymbed 0:1387ff3eed4a 1540 #endif
sPymbed 0:1387ff3eed4a 1541 #endif
sPymbed 0:1387ff3eed4a 1542 mp_int *x, *y, *z;
sPymbed 0:1387ff3eed4a 1543 int err;
sPymbed 0:1387ff3eed4a 1544
sPymbed 0:1387ff3eed4a 1545 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 1546 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1547 }
sPymbed 0:1387ff3eed4a 1548
sPymbed 0:1387ff3eed4a 1549 /* if Q == R then swap P and Q, so we don't require a local x,y,z */
sPymbed 0:1387ff3eed4a 1550 if (Q == R) {
sPymbed 0:1387ff3eed4a 1551 ecc_point* tPt = P;
sPymbed 0:1387ff3eed4a 1552 P = Q;
sPymbed 0:1387ff3eed4a 1553 Q = tPt;
sPymbed 0:1387ff3eed4a 1554 }
sPymbed 0:1387ff3eed4a 1555
sPymbed 0:1387ff3eed4a 1556 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1557 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1558 if (R->key != NULL) {
sPymbed 0:1387ff3eed4a 1559 t1 = R->key->t1;
sPymbed 0:1387ff3eed4a 1560 t2 = R->key->t2;
sPymbed 0:1387ff3eed4a 1561 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1562 rx = R->key->x;
sPymbed 0:1387ff3eed4a 1563 ry = R->key->y;
sPymbed 0:1387ff3eed4a 1564 rz = R->key->z;
sPymbed 0:1387ff3eed4a 1565 #endif
sPymbed 0:1387ff3eed4a 1566 }
sPymbed 0:1387ff3eed4a 1567 else
sPymbed 0:1387ff3eed4a 1568 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 1569 {
sPymbed 0:1387ff3eed4a 1570 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1571 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1572 if (t1 == NULL || t2 == NULL) {
sPymbed 0:1387ff3eed4a 1573 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1574 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1575 return MEMORY_E;
sPymbed 0:1387ff3eed4a 1576 }
sPymbed 0:1387ff3eed4a 1577 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1578 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1579 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1580 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1581 if (rx == NULL || ry == NULL || rz == NULL) {
sPymbed 0:1387ff3eed4a 1582 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1583 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1584 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1585 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1586 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1587 return MEMORY_E;
sPymbed 0:1387ff3eed4a 1588 }
sPymbed 0:1387ff3eed4a 1589 #endif
sPymbed 0:1387ff3eed4a 1590 }
sPymbed 0:1387ff3eed4a 1591 #endif /* WOLFSSL_SMALL_STACK */
sPymbed 0:1387ff3eed4a 1592
sPymbed 0:1387ff3eed4a 1593 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 1594 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1595 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1596 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 1597 #endif
sPymbed 0:1387ff3eed4a 1598 {
sPymbed 0:1387ff3eed4a 1599 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1600 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1601 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1602 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1603 #endif
sPymbed 0:1387ff3eed4a 1604 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1605 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1606 }
sPymbed 0:1387ff3eed4a 1607 #endif
sPymbed 0:1387ff3eed4a 1608 return err;
sPymbed 0:1387ff3eed4a 1609 }
sPymbed 0:1387ff3eed4a 1610
sPymbed 0:1387ff3eed4a 1611 /* should we dbl instead? */
sPymbed 0:1387ff3eed4a 1612 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1613 err = mp_sub(modulus, Q->y, t1);
sPymbed 0:1387ff3eed4a 1614 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1615 if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 1616 (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 1617 (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
sPymbed 0:1387ff3eed4a 1618 mp_clear(t1);
sPymbed 0:1387ff3eed4a 1619 mp_clear(t2);
sPymbed 0:1387ff3eed4a 1620 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1621 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1622 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 1623 #endif
sPymbed 0:1387ff3eed4a 1624 {
sPymbed 0:1387ff3eed4a 1625 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1626 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1627 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1628 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1629 #endif
sPymbed 0:1387ff3eed4a 1630 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1631 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1632 }
sPymbed 0:1387ff3eed4a 1633 #endif
sPymbed 0:1387ff3eed4a 1634 return ecc_projective_dbl_point(P, R, a, modulus, mp);
sPymbed 0:1387ff3eed4a 1635 }
sPymbed 0:1387ff3eed4a 1636 }
sPymbed 0:1387ff3eed4a 1637
sPymbed 0:1387ff3eed4a 1638 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 1639 goto done;
sPymbed 0:1387ff3eed4a 1640 }
sPymbed 0:1387ff3eed4a 1641
sPymbed 0:1387ff3eed4a 1642 /* If use ALT_ECC_SIZE we need to use local stack variable since
sPymbed 0:1387ff3eed4a 1643 ecc_point x,y,z is reduced size */
sPymbed 0:1387ff3eed4a 1644 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1645 /* Use local stack variable */
sPymbed 0:1387ff3eed4a 1646 x = rx;
sPymbed 0:1387ff3eed4a 1647 y = ry;
sPymbed 0:1387ff3eed4a 1648 z = rz;
sPymbed 0:1387ff3eed4a 1649
sPymbed 0:1387ff3eed4a 1650 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 1651 goto done;
sPymbed 0:1387ff3eed4a 1652 }
sPymbed 0:1387ff3eed4a 1653 #else
sPymbed 0:1387ff3eed4a 1654 /* Use destination directly */
sPymbed 0:1387ff3eed4a 1655 x = R->x;
sPymbed 0:1387ff3eed4a 1656 y = R->y;
sPymbed 0:1387ff3eed4a 1657 z = R->z;
sPymbed 0:1387ff3eed4a 1658 #endif
sPymbed 0:1387ff3eed4a 1659
sPymbed 0:1387ff3eed4a 1660 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1661 err = mp_copy(P->x, x);
sPymbed 0:1387ff3eed4a 1662 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1663 err = mp_copy(P->y, y);
sPymbed 0:1387ff3eed4a 1664 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1665 err = mp_copy(P->z, z);
sPymbed 0:1387ff3eed4a 1666
sPymbed 0:1387ff3eed4a 1667 /* if Z is one then these are no-operations */
sPymbed 0:1387ff3eed4a 1668 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1669 if (!mp_iszero(Q->z)) {
sPymbed 0:1387ff3eed4a 1670 /* T1 = Z' * Z' */
sPymbed 0:1387ff3eed4a 1671 err = mp_sqr(Q->z, t1);
sPymbed 0:1387ff3eed4a 1672 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1673 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1674
sPymbed 0:1387ff3eed4a 1675 /* X = X * T1 */
sPymbed 0:1387ff3eed4a 1676 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1677 err = mp_mul(t1, x, x);
sPymbed 0:1387ff3eed4a 1678 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1679 err = mp_montgomery_reduce(x, modulus, mp);
sPymbed 0:1387ff3eed4a 1680
sPymbed 0:1387ff3eed4a 1681 /* T1 = Z' * T1 */
sPymbed 0:1387ff3eed4a 1682 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1683 err = mp_mul(Q->z, t1, t1);
sPymbed 0:1387ff3eed4a 1684 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1685 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1686
sPymbed 0:1387ff3eed4a 1687 /* Y = Y * T1 */
sPymbed 0:1387ff3eed4a 1688 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1689 err = mp_mul(t1, y, y);
sPymbed 0:1387ff3eed4a 1690 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1691 err = mp_montgomery_reduce(y, modulus, mp);
sPymbed 0:1387ff3eed4a 1692 }
sPymbed 0:1387ff3eed4a 1693 }
sPymbed 0:1387ff3eed4a 1694
sPymbed 0:1387ff3eed4a 1695 /* T1 = Z*Z */
sPymbed 0:1387ff3eed4a 1696 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1697 err = mp_sqr(z, t1);
sPymbed 0:1387ff3eed4a 1698 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1699 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1700
sPymbed 0:1387ff3eed4a 1701 /* T2 = X' * T1 */
sPymbed 0:1387ff3eed4a 1702 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1703 err = mp_mul(Q->x, t1, t2);
sPymbed 0:1387ff3eed4a 1704 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1705 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 1706
sPymbed 0:1387ff3eed4a 1707 /* T1 = Z * T1 */
sPymbed 0:1387ff3eed4a 1708 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1709 err = mp_mul(z, t1, t1);
sPymbed 0:1387ff3eed4a 1710 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1711 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1712
sPymbed 0:1387ff3eed4a 1713 /* T1 = Y' * T1 */
sPymbed 0:1387ff3eed4a 1714 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1715 err = mp_mul(Q->y, t1, t1);
sPymbed 0:1387ff3eed4a 1716 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1717 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1718
sPymbed 0:1387ff3eed4a 1719 /* Y = Y - T1 */
sPymbed 0:1387ff3eed4a 1720 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1721 err = mp_sub(y, t1, y);
sPymbed 0:1387ff3eed4a 1722 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1723 if (mp_isneg(y))
sPymbed 0:1387ff3eed4a 1724 err = mp_add(y, modulus, y);
sPymbed 0:1387ff3eed4a 1725 }
sPymbed 0:1387ff3eed4a 1726 /* T1 = 2T1 */
sPymbed 0:1387ff3eed4a 1727 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1728 err = mp_add(t1, t1, t1);
sPymbed 0:1387ff3eed4a 1729 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1730 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 1731 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 1732 }
sPymbed 0:1387ff3eed4a 1733 /* T1 = Y + T1 */
sPymbed 0:1387ff3eed4a 1734 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1735 err = mp_add(t1, y, t1);
sPymbed 0:1387ff3eed4a 1736 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1737 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 1738 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 1739 }
sPymbed 0:1387ff3eed4a 1740 /* X = X - T2 */
sPymbed 0:1387ff3eed4a 1741 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1742 err = mp_sub(x, t2, x);
sPymbed 0:1387ff3eed4a 1743 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1744 if (mp_isneg(x))
sPymbed 0:1387ff3eed4a 1745 err = mp_add(x, modulus, x);
sPymbed 0:1387ff3eed4a 1746 }
sPymbed 0:1387ff3eed4a 1747 /* T2 = 2T2 */
sPymbed 0:1387ff3eed4a 1748 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1749 err = mp_add(t2, t2, t2);
sPymbed 0:1387ff3eed4a 1750 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1751 if (mp_cmp(t2, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 1752 err = mp_sub(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 1753 }
sPymbed 0:1387ff3eed4a 1754 /* T2 = X + T2 */
sPymbed 0:1387ff3eed4a 1755 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1756 err = mp_add(t2, x, t2);
sPymbed 0:1387ff3eed4a 1757 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1758 if (mp_cmp(t2, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 1759 err = mp_sub(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 1760 }
sPymbed 0:1387ff3eed4a 1761
sPymbed 0:1387ff3eed4a 1762 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1763 if (!mp_iszero(Q->z)) {
sPymbed 0:1387ff3eed4a 1764 /* Z = Z * Z' */
sPymbed 0:1387ff3eed4a 1765 err = mp_mul(z, Q->z, z);
sPymbed 0:1387ff3eed4a 1766 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1767 err = mp_montgomery_reduce(z, modulus, mp);
sPymbed 0:1387ff3eed4a 1768 }
sPymbed 0:1387ff3eed4a 1769 }
sPymbed 0:1387ff3eed4a 1770
sPymbed 0:1387ff3eed4a 1771 /* Z = Z * X */
sPymbed 0:1387ff3eed4a 1772 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1773 err = mp_mul(z, x, z);
sPymbed 0:1387ff3eed4a 1774 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1775 err = mp_montgomery_reduce(z, modulus, mp);
sPymbed 0:1387ff3eed4a 1776
sPymbed 0:1387ff3eed4a 1777 /* T1 = T1 * X */
sPymbed 0:1387ff3eed4a 1778 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1779 err = mp_mul(t1, x, t1);
sPymbed 0:1387ff3eed4a 1780 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1781 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1782
sPymbed 0:1387ff3eed4a 1783 /* X = X * X */
sPymbed 0:1387ff3eed4a 1784 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1785 err = mp_sqr(x, x);
sPymbed 0:1387ff3eed4a 1786 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1787 err = mp_montgomery_reduce(x, modulus, mp);
sPymbed 0:1387ff3eed4a 1788
sPymbed 0:1387ff3eed4a 1789 /* T2 = T2 * x */
sPymbed 0:1387ff3eed4a 1790 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1791 err = mp_mul(t2, x, t2);
sPymbed 0:1387ff3eed4a 1792 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1793 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 1794
sPymbed 0:1387ff3eed4a 1795 /* T1 = T1 * X */
sPymbed 0:1387ff3eed4a 1796 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1797 err = mp_mul(t1, x, t1);
sPymbed 0:1387ff3eed4a 1798 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1799 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 1800
sPymbed 0:1387ff3eed4a 1801 /* X = Y*Y */
sPymbed 0:1387ff3eed4a 1802 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1803 err = mp_sqr(y, x);
sPymbed 0:1387ff3eed4a 1804 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1805 err = mp_montgomery_reduce(x, modulus, mp);
sPymbed 0:1387ff3eed4a 1806
sPymbed 0:1387ff3eed4a 1807 /* X = X - T2 */
sPymbed 0:1387ff3eed4a 1808 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1809 err = mp_sub(x, t2, x);
sPymbed 0:1387ff3eed4a 1810 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1811 if (mp_isneg(x))
sPymbed 0:1387ff3eed4a 1812 err = mp_add(x, modulus, x);
sPymbed 0:1387ff3eed4a 1813 }
sPymbed 0:1387ff3eed4a 1814 /* T2 = T2 - X */
sPymbed 0:1387ff3eed4a 1815 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1816 err = mp_sub(t2, x, t2);
sPymbed 0:1387ff3eed4a 1817 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1818 if (mp_isneg(t2))
sPymbed 0:1387ff3eed4a 1819 err = mp_add(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 1820 }
sPymbed 0:1387ff3eed4a 1821 /* T2 = T2 - X */
sPymbed 0:1387ff3eed4a 1822 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1823 err = mp_sub(t2, x, t2);
sPymbed 0:1387ff3eed4a 1824 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1825 if (mp_isneg(t2))
sPymbed 0:1387ff3eed4a 1826 err = mp_add(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 1827 }
sPymbed 0:1387ff3eed4a 1828 /* T2 = T2 * Y */
sPymbed 0:1387ff3eed4a 1829 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1830 err = mp_mul(t2, y, t2);
sPymbed 0:1387ff3eed4a 1831 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1832 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 1833
sPymbed 0:1387ff3eed4a 1834 /* Y = T2 - T1 */
sPymbed 0:1387ff3eed4a 1835 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1836 err = mp_sub(t2, t1, y);
sPymbed 0:1387ff3eed4a 1837 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1838 if (mp_isneg(y))
sPymbed 0:1387ff3eed4a 1839 err = mp_add(y, modulus, y);
sPymbed 0:1387ff3eed4a 1840 }
sPymbed 0:1387ff3eed4a 1841 /* Y = Y/2 */
sPymbed 0:1387ff3eed4a 1842 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 1843 if (mp_isodd(y) == MP_YES)
sPymbed 0:1387ff3eed4a 1844 err = mp_add(y, modulus, y);
sPymbed 0:1387ff3eed4a 1845 }
sPymbed 0:1387ff3eed4a 1846 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1847 err = mp_div_2(y, y);
sPymbed 0:1387ff3eed4a 1848
sPymbed 0:1387ff3eed4a 1849 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1850 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1851 err = mp_copy(x, R->x);
sPymbed 0:1387ff3eed4a 1852 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1853 err = mp_copy(y, R->y);
sPymbed 0:1387ff3eed4a 1854 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 1855 err = mp_copy(z, R->z);
sPymbed 0:1387ff3eed4a 1856 #endif
sPymbed 0:1387ff3eed4a 1857
sPymbed 0:1387ff3eed4a 1858 done:
sPymbed 0:1387ff3eed4a 1859
sPymbed 0:1387ff3eed4a 1860 /* clean up */
sPymbed 0:1387ff3eed4a 1861 mp_clear(t1);
sPymbed 0:1387ff3eed4a 1862 mp_clear(t2);
sPymbed 0:1387ff3eed4a 1863 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1864 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1865 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 1866 #endif
sPymbed 0:1387ff3eed4a 1867 {
sPymbed 0:1387ff3eed4a 1868 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1869 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1870 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1871 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1872 #endif
sPymbed 0:1387ff3eed4a 1873 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1874 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1875 }
sPymbed 0:1387ff3eed4a 1876 #endif
sPymbed 0:1387ff3eed4a 1877
sPymbed 0:1387ff3eed4a 1878 return err;
sPymbed 0:1387ff3eed4a 1879 #else
sPymbed 0:1387ff3eed4a 1880 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 1881 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1882 }
sPymbed 0:1387ff3eed4a 1883
sPymbed 0:1387ff3eed4a 1884 (void)a;
sPymbed 0:1387ff3eed4a 1885 (void)mp;
sPymbed 0:1387ff3eed4a 1886
sPymbed 0:1387ff3eed4a 1887 return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
sPymbed 0:1387ff3eed4a 1888 R->x, R->y, R->z);
sPymbed 0:1387ff3eed4a 1889 #endif
sPymbed 0:1387ff3eed4a 1890 }
sPymbed 0:1387ff3eed4a 1891
sPymbed 0:1387ff3eed4a 1892 /* ### Point doubling in Jacobian coordinate system ###
sPymbed 0:1387ff3eed4a 1893 *
sPymbed 0:1387ff3eed4a 1894 * let us have a curve: y^2 = x^3 + a*x + b
sPymbed 0:1387ff3eed4a 1895 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6
sPymbed 0:1387ff3eed4a 1896 *
sPymbed 0:1387ff3eed4a 1897 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
sPymbed 0:1387ff3eed4a 1898 * Xr = M^2 - 2*S
sPymbed 0:1387ff3eed4a 1899 * Yr = M * (S - Xr) - 8*T
sPymbed 0:1387ff3eed4a 1900 * Zr = 2 * Yp * Zp
sPymbed 0:1387ff3eed4a 1901 *
sPymbed 0:1387ff3eed4a 1902 * M = 3 * Xp^2 + a*Zp^4
sPymbed 0:1387ff3eed4a 1903 * T = Yp^4
sPymbed 0:1387ff3eed4a 1904 * S = 4 * Xp * Yp^2
sPymbed 0:1387ff3eed4a 1905 *
sPymbed 0:1387ff3eed4a 1906 * SPECIAL CASE: when a == 3 we can compute M as
sPymbed 0:1387ff3eed4a 1907 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
sPymbed 0:1387ff3eed4a 1908 */
sPymbed 0:1387ff3eed4a 1909
sPymbed 0:1387ff3eed4a 1910 /**
sPymbed 0:1387ff3eed4a 1911 Double an ECC point
sPymbed 0:1387ff3eed4a 1912 P The point to double
sPymbed 0:1387ff3eed4a 1913 R [out] The destination of the double
sPymbed 0:1387ff3eed4a 1914 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 1915 modulus The modulus of the field the ECC curve is in
sPymbed 0:1387ff3eed4a 1916 mp The "b" value from montgomery_setup()
sPymbed 0:1387ff3eed4a 1917 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 1918 */
sPymbed 0:1387ff3eed4a 1919 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
sPymbed 0:1387ff3eed4a 1920 mp_int* modulus, mp_digit mp)
sPymbed 0:1387ff3eed4a 1921 {
sPymbed 0:1387ff3eed4a 1922 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 1923 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1924 mp_int* t1 = NULL;
sPymbed 0:1387ff3eed4a 1925 mp_int* t2 = NULL;
sPymbed 0:1387ff3eed4a 1926 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1927 mp_int* rx = NULL;
sPymbed 0:1387ff3eed4a 1928 mp_int* ry = NULL;
sPymbed 0:1387ff3eed4a 1929 mp_int* rz = NULL;
sPymbed 0:1387ff3eed4a 1930 #endif
sPymbed 0:1387ff3eed4a 1931 #else
sPymbed 0:1387ff3eed4a 1932 mp_int t1[1], t2[1];
sPymbed 0:1387ff3eed4a 1933 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1934 mp_int rx[1], ry[1], rz[1];
sPymbed 0:1387ff3eed4a 1935 #endif
sPymbed 0:1387ff3eed4a 1936 #endif
sPymbed 0:1387ff3eed4a 1937 mp_int *x, *y, *z;
sPymbed 0:1387ff3eed4a 1938 int err;
sPymbed 0:1387ff3eed4a 1939
sPymbed 0:1387ff3eed4a 1940 if (P == NULL || R == NULL || modulus == NULL)
sPymbed 0:1387ff3eed4a 1941 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 1942
sPymbed 0:1387ff3eed4a 1943 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1944 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1945 if (R->key != NULL) {
sPymbed 0:1387ff3eed4a 1946 t1 = R->key->t1;
sPymbed 0:1387ff3eed4a 1947 t2 = R->key->t2;
sPymbed 0:1387ff3eed4a 1948 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1949 rx = R->key->x;
sPymbed 0:1387ff3eed4a 1950 ry = R->key->y;
sPymbed 0:1387ff3eed4a 1951 rz = R->key->z;
sPymbed 0:1387ff3eed4a 1952 #endif
sPymbed 0:1387ff3eed4a 1953 }
sPymbed 0:1387ff3eed4a 1954 else
sPymbed 0:1387ff3eed4a 1955 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 1956 {
sPymbed 0:1387ff3eed4a 1957 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1958 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1959 if (t1 == NULL || t2 == NULL) {
sPymbed 0:1387ff3eed4a 1960 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1961 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1962 return MEMORY_E;
sPymbed 0:1387ff3eed4a 1963 }
sPymbed 0:1387ff3eed4a 1964 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1965 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1966 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1967 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1968 if (rx == NULL || ry == NULL || rz == NULL) {
sPymbed 0:1387ff3eed4a 1969 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1970 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1971 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1972 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1973 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1974 return MEMORY_E;
sPymbed 0:1387ff3eed4a 1975 }
sPymbed 0:1387ff3eed4a 1976 #endif
sPymbed 0:1387ff3eed4a 1977 }
sPymbed 0:1387ff3eed4a 1978 #endif
sPymbed 0:1387ff3eed4a 1979
sPymbed 0:1387ff3eed4a 1980 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 1981 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 1982 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 1983 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 1984 #endif
sPymbed 0:1387ff3eed4a 1985 {
sPymbed 0:1387ff3eed4a 1986 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 1987 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1988 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1989 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1990 #endif
sPymbed 0:1387ff3eed4a 1991 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1992 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 1993 }
sPymbed 0:1387ff3eed4a 1994 #endif
sPymbed 0:1387ff3eed4a 1995 return err;
sPymbed 0:1387ff3eed4a 1996 }
sPymbed 0:1387ff3eed4a 1997
sPymbed 0:1387ff3eed4a 1998 /* If use ALT_ECC_SIZE we need to use local stack variable since
sPymbed 0:1387ff3eed4a 1999 ecc_point x,y,z is reduced size */
sPymbed 0:1387ff3eed4a 2000 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2001 /* Use local stack variable */
sPymbed 0:1387ff3eed4a 2002 x = rx;
sPymbed 0:1387ff3eed4a 2003 y = ry;
sPymbed 0:1387ff3eed4a 2004 z = rz;
sPymbed 0:1387ff3eed4a 2005
sPymbed 0:1387ff3eed4a 2006 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2007 mp_clear(t1);
sPymbed 0:1387ff3eed4a 2008 mp_clear(t2);
sPymbed 0:1387ff3eed4a 2009 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2010 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2011 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 2012 #endif
sPymbed 0:1387ff3eed4a 2013 {
sPymbed 0:1387ff3eed4a 2014 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2015 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2016 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2017 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2018 #endif
sPymbed 0:1387ff3eed4a 2019 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2020 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2021 }
sPymbed 0:1387ff3eed4a 2022 #endif
sPymbed 0:1387ff3eed4a 2023 return err;
sPymbed 0:1387ff3eed4a 2024 }
sPymbed 0:1387ff3eed4a 2025 #else
sPymbed 0:1387ff3eed4a 2026 /* Use destination directly */
sPymbed 0:1387ff3eed4a 2027 x = R->x;
sPymbed 0:1387ff3eed4a 2028 y = R->y;
sPymbed 0:1387ff3eed4a 2029 z = R->z;
sPymbed 0:1387ff3eed4a 2030 #endif
sPymbed 0:1387ff3eed4a 2031
sPymbed 0:1387ff3eed4a 2032 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2033 err = mp_copy(P->x, x);
sPymbed 0:1387ff3eed4a 2034 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2035 err = mp_copy(P->y, y);
sPymbed 0:1387ff3eed4a 2036 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2037 err = mp_copy(P->z, z);
sPymbed 0:1387ff3eed4a 2038
sPymbed 0:1387ff3eed4a 2039 /* T1 = Z * Z */
sPymbed 0:1387ff3eed4a 2040 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2041 err = mp_sqr(z, t1);
sPymbed 0:1387ff3eed4a 2042 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2043 err = mp_montgomery_reduce(t1, modulus, mp);
sPymbed 0:1387ff3eed4a 2044
sPymbed 0:1387ff3eed4a 2045 /* Z = Y * Z */
sPymbed 0:1387ff3eed4a 2046 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2047 err = mp_mul(z, y, z);
sPymbed 0:1387ff3eed4a 2048 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2049 err = mp_montgomery_reduce(z, modulus, mp);
sPymbed 0:1387ff3eed4a 2050
sPymbed 0:1387ff3eed4a 2051 /* Z = 2Z */
sPymbed 0:1387ff3eed4a 2052 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2053 err = mp_add(z, z, z);
sPymbed 0:1387ff3eed4a 2054 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2055 if (mp_cmp(z, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2056 err = mp_sub(z, modulus, z);
sPymbed 0:1387ff3eed4a 2057 }
sPymbed 0:1387ff3eed4a 2058
sPymbed 0:1387ff3eed4a 2059 /* Determine if curve "a" should be used in calc */
sPymbed 0:1387ff3eed4a 2060 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 2061 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2062 /* Use a and prime to determine if a == 3 */
sPymbed 0:1387ff3eed4a 2063 err = mp_submod(modulus, a, modulus, t2);
sPymbed 0:1387ff3eed4a 2064 }
sPymbed 0:1387ff3eed4a 2065 if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
sPymbed 0:1387ff3eed4a 2066 /* use "a" in calc */
sPymbed 0:1387ff3eed4a 2067
sPymbed 0:1387ff3eed4a 2068 /* T2 = T1 * T1 */
sPymbed 0:1387ff3eed4a 2069 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2070 err = mp_sqr(t1, t2);
sPymbed 0:1387ff3eed4a 2071 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2072 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 2073 /* T1 = T2 * a */
sPymbed 0:1387ff3eed4a 2074 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2075 err = mp_mulmod(t2, a, modulus, t1);
sPymbed 0:1387ff3eed4a 2076 /* T2 = X * X */
sPymbed 0:1387ff3eed4a 2077 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2078 err = mp_sqr(x, t2);
sPymbed 0:1387ff3eed4a 2079 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2080 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 2081 /* T1 = T2 + T1 */
sPymbed 0:1387ff3eed4a 2082 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2083 err = mp_add(t1, t2, t1);
sPymbed 0:1387ff3eed4a 2084 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2085 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2086 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2087 }
sPymbed 0:1387ff3eed4a 2088 /* T1 = T2 + T1 */
sPymbed 0:1387ff3eed4a 2089 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2090 err = mp_add(t1, t2, t1);
sPymbed 0:1387ff3eed4a 2091 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2092 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2093 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2094 }
sPymbed 0:1387ff3eed4a 2095 /* T1 = T2 + T1 */
sPymbed 0:1387ff3eed4a 2096 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2097 err = mp_add(t1, t2, t1);
sPymbed 0:1387ff3eed4a 2098 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2099 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2100 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2101 }
sPymbed 0:1387ff3eed4a 2102 }
sPymbed 0:1387ff3eed4a 2103 else
sPymbed 0:1387ff3eed4a 2104 #endif /* WOLFSSL_CUSTOM_CURVES */
sPymbed 0:1387ff3eed4a 2105 {
sPymbed 0:1387ff3eed4a 2106 /* assumes "a" == 3 */
sPymbed 0:1387ff3eed4a 2107 (void)a;
sPymbed 0:1387ff3eed4a 2108
sPymbed 0:1387ff3eed4a 2109 /* T2 = X - T1 */
sPymbed 0:1387ff3eed4a 2110 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2111 err = mp_sub(x, t1, t2);
sPymbed 0:1387ff3eed4a 2112 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2113 if (mp_isneg(t2))
sPymbed 0:1387ff3eed4a 2114 err = mp_add(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 2115 }
sPymbed 0:1387ff3eed4a 2116 /* T1 = X + T1 */
sPymbed 0:1387ff3eed4a 2117 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2118 err = mp_add(t1, x, t1);
sPymbed 0:1387ff3eed4a 2119 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2120 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2121 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2122 }
sPymbed 0:1387ff3eed4a 2123 /* T2 = T1 * T2 */
sPymbed 0:1387ff3eed4a 2124 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2125 err = mp_mul(t1, t2, t2);
sPymbed 0:1387ff3eed4a 2126 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2127 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 2128
sPymbed 0:1387ff3eed4a 2129 /* T1 = 2T2 */
sPymbed 0:1387ff3eed4a 2130 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2131 err = mp_add(t2, t2, t1);
sPymbed 0:1387ff3eed4a 2132 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2133 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2134 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2135 }
sPymbed 0:1387ff3eed4a 2136 /* T1 = T1 + T2 */
sPymbed 0:1387ff3eed4a 2137 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2138 err = mp_add(t1, t2, t1);
sPymbed 0:1387ff3eed4a 2139 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2140 if (mp_cmp(t1, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2141 err = mp_sub(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2142 }
sPymbed 0:1387ff3eed4a 2143 }
sPymbed 0:1387ff3eed4a 2144
sPymbed 0:1387ff3eed4a 2145 /* Y = 2Y */
sPymbed 0:1387ff3eed4a 2146 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2147 err = mp_add(y, y, y);
sPymbed 0:1387ff3eed4a 2148 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2149 if (mp_cmp(y, modulus) != MP_LT)
sPymbed 0:1387ff3eed4a 2150 err = mp_sub(y, modulus, y);
sPymbed 0:1387ff3eed4a 2151 }
sPymbed 0:1387ff3eed4a 2152 /* Y = Y * Y */
sPymbed 0:1387ff3eed4a 2153 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2154 err = mp_sqr(y, y);
sPymbed 0:1387ff3eed4a 2155 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2156 err = mp_montgomery_reduce(y, modulus, mp);
sPymbed 0:1387ff3eed4a 2157
sPymbed 0:1387ff3eed4a 2158 /* T2 = Y * Y */
sPymbed 0:1387ff3eed4a 2159 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2160 err = mp_sqr(y, t2);
sPymbed 0:1387ff3eed4a 2161 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2162 err = mp_montgomery_reduce(t2, modulus, mp);
sPymbed 0:1387ff3eed4a 2163
sPymbed 0:1387ff3eed4a 2164 /* T2 = T2/2 */
sPymbed 0:1387ff3eed4a 2165 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2166 if (mp_isodd(t2) == MP_YES)
sPymbed 0:1387ff3eed4a 2167 err = mp_add(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 2168 }
sPymbed 0:1387ff3eed4a 2169 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2170 err = mp_div_2(t2, t2);
sPymbed 0:1387ff3eed4a 2171
sPymbed 0:1387ff3eed4a 2172 /* Y = Y * X */
sPymbed 0:1387ff3eed4a 2173 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2174 err = mp_mul(y, x, y);
sPymbed 0:1387ff3eed4a 2175 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2176 err = mp_montgomery_reduce(y, modulus, mp);
sPymbed 0:1387ff3eed4a 2177
sPymbed 0:1387ff3eed4a 2178 /* X = T1 * T1 */
sPymbed 0:1387ff3eed4a 2179 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2180 err = mp_sqr(t1, x);
sPymbed 0:1387ff3eed4a 2181 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2182 err = mp_montgomery_reduce(x, modulus, mp);
sPymbed 0:1387ff3eed4a 2183
sPymbed 0:1387ff3eed4a 2184 /* X = X - Y */
sPymbed 0:1387ff3eed4a 2185 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2186 err = mp_sub(x, y, x);
sPymbed 0:1387ff3eed4a 2187 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2188 if (mp_isneg(x))
sPymbed 0:1387ff3eed4a 2189 err = mp_add(x, modulus, x);
sPymbed 0:1387ff3eed4a 2190 }
sPymbed 0:1387ff3eed4a 2191 /* X = X - Y */
sPymbed 0:1387ff3eed4a 2192 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2193 err = mp_sub(x, y, x);
sPymbed 0:1387ff3eed4a 2194 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2195 if (mp_isneg(x))
sPymbed 0:1387ff3eed4a 2196 err = mp_add(x, modulus, x);
sPymbed 0:1387ff3eed4a 2197 }
sPymbed 0:1387ff3eed4a 2198
sPymbed 0:1387ff3eed4a 2199 /* Y = Y - X */
sPymbed 0:1387ff3eed4a 2200 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2201 err = mp_sub(y, x, y);
sPymbed 0:1387ff3eed4a 2202 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2203 if (mp_isneg(y))
sPymbed 0:1387ff3eed4a 2204 err = mp_add(y, modulus, y);
sPymbed 0:1387ff3eed4a 2205 }
sPymbed 0:1387ff3eed4a 2206 /* Y = Y * T1 */
sPymbed 0:1387ff3eed4a 2207 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2208 err = mp_mul(y, t1, y);
sPymbed 0:1387ff3eed4a 2209 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2210 err = mp_montgomery_reduce(y, modulus, mp);
sPymbed 0:1387ff3eed4a 2211
sPymbed 0:1387ff3eed4a 2212 /* Y = Y - T2 */
sPymbed 0:1387ff3eed4a 2213 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2214 err = mp_sub(y, t2, y);
sPymbed 0:1387ff3eed4a 2215 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2216 if (mp_isneg(y))
sPymbed 0:1387ff3eed4a 2217 err = mp_add(y, modulus, y);
sPymbed 0:1387ff3eed4a 2218 }
sPymbed 0:1387ff3eed4a 2219
sPymbed 0:1387ff3eed4a 2220 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2221 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2222 err = mp_copy(x, R->x);
sPymbed 0:1387ff3eed4a 2223 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2224 err = mp_copy(y, R->y);
sPymbed 0:1387ff3eed4a 2225 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2226 err = mp_copy(z, R->z);
sPymbed 0:1387ff3eed4a 2227 #endif
sPymbed 0:1387ff3eed4a 2228
sPymbed 0:1387ff3eed4a 2229 /* clean up */
sPymbed 0:1387ff3eed4a 2230 mp_clear(t1);
sPymbed 0:1387ff3eed4a 2231 mp_clear(t2);
sPymbed 0:1387ff3eed4a 2232
sPymbed 0:1387ff3eed4a 2233 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2234 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2235 if (R->key == NULL)
sPymbed 0:1387ff3eed4a 2236 #endif
sPymbed 0:1387ff3eed4a 2237 {
sPymbed 0:1387ff3eed4a 2238 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2239 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2240 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2241 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2242 #endif
sPymbed 0:1387ff3eed4a 2243 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2244 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2245 }
sPymbed 0:1387ff3eed4a 2246 #endif
sPymbed 0:1387ff3eed4a 2247
sPymbed 0:1387ff3eed4a 2248 return err;
sPymbed 0:1387ff3eed4a 2249 #else
sPymbed 0:1387ff3eed4a 2250 if (P == NULL || R == NULL || modulus == NULL)
sPymbed 0:1387ff3eed4a 2251 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 2252
sPymbed 0:1387ff3eed4a 2253 (void)a;
sPymbed 0:1387ff3eed4a 2254 (void)mp;
sPymbed 0:1387ff3eed4a 2255
sPymbed 0:1387ff3eed4a 2256 return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
sPymbed 0:1387ff3eed4a 2257 #endif
sPymbed 0:1387ff3eed4a 2258 }
sPymbed 0:1387ff3eed4a 2259
sPymbed 0:1387ff3eed4a 2260
sPymbed 0:1387ff3eed4a 2261 /**
sPymbed 0:1387ff3eed4a 2262 Map a projective jacbobian point back to affine space
sPymbed 0:1387ff3eed4a 2263 P [in/out] The point to map
sPymbed 0:1387ff3eed4a 2264 modulus The modulus of the field the ECC curve is in
sPymbed 0:1387ff3eed4a 2265 mp The "b" value from montgomery_setup()
sPymbed 0:1387ff3eed4a 2266 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 2267 */
sPymbed 0:1387ff3eed4a 2268 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
sPymbed 0:1387ff3eed4a 2269 {
sPymbed 0:1387ff3eed4a 2270 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 2271 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2272 mp_int* t1 = NULL;
sPymbed 0:1387ff3eed4a 2273 mp_int* t2 = NULL;
sPymbed 0:1387ff3eed4a 2274 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2275 mp_int* rx = NULL;
sPymbed 0:1387ff3eed4a 2276 mp_int* ry = NULL;
sPymbed 0:1387ff3eed4a 2277 mp_int* rz = NULL;
sPymbed 0:1387ff3eed4a 2278 #endif
sPymbed 0:1387ff3eed4a 2279 #else
sPymbed 0:1387ff3eed4a 2280 mp_int t1[1], t2[1];
sPymbed 0:1387ff3eed4a 2281 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2282 mp_int rx[1], ry[1], rz[1];
sPymbed 0:1387ff3eed4a 2283 #endif
sPymbed 0:1387ff3eed4a 2284 #endif /* WOLFSSL_SMALL_STACK */
sPymbed 0:1387ff3eed4a 2285 mp_int *x, *y, *z;
sPymbed 0:1387ff3eed4a 2286 int err;
sPymbed 0:1387ff3eed4a 2287
sPymbed 0:1387ff3eed4a 2288 if (P == NULL || modulus == NULL)
sPymbed 0:1387ff3eed4a 2289 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 2290
sPymbed 0:1387ff3eed4a 2291 /* special case for point at infinity */
sPymbed 0:1387ff3eed4a 2292 if (mp_cmp_d(P->z, 0) == MP_EQ) {
sPymbed 0:1387ff3eed4a 2293 err = mp_set(P->x, 0);
sPymbed 0:1387ff3eed4a 2294 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2295 err = mp_set(P->y, 0);
sPymbed 0:1387ff3eed4a 2296 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2297 err = mp_set(P->z, 1);
sPymbed 0:1387ff3eed4a 2298 return err;
sPymbed 0:1387ff3eed4a 2299 }
sPymbed 0:1387ff3eed4a 2300
sPymbed 0:1387ff3eed4a 2301 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2302 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2303 if (P->key != NULL) {
sPymbed 0:1387ff3eed4a 2304 t1 = P->key->t1;
sPymbed 0:1387ff3eed4a 2305 t2 = P->key->t2;
sPymbed 0:1387ff3eed4a 2306 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2307 rx = P->key->x;
sPymbed 0:1387ff3eed4a 2308 ry = P->key->y;
sPymbed 0:1387ff3eed4a 2309 rz = P->key->z;
sPymbed 0:1387ff3eed4a 2310 #endif
sPymbed 0:1387ff3eed4a 2311 }
sPymbed 0:1387ff3eed4a 2312 else
sPymbed 0:1387ff3eed4a 2313 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2314 {
sPymbed 0:1387ff3eed4a 2315 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2316 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2317 if (t1 == NULL || t2 == NULL) {
sPymbed 0:1387ff3eed4a 2318 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2319 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2320 return MEMORY_E;
sPymbed 0:1387ff3eed4a 2321 }
sPymbed 0:1387ff3eed4a 2322 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2323 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2324 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2325 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2326 if (rx == NULL || ry == NULL || rz == NULL) {
sPymbed 0:1387ff3eed4a 2327 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2328 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2329 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2330 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2331 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2332 return MEMORY_E;
sPymbed 0:1387ff3eed4a 2333 }
sPymbed 0:1387ff3eed4a 2334 #endif
sPymbed 0:1387ff3eed4a 2335 }
sPymbed 0:1387ff3eed4a 2336 #endif /* WOLFSSL_SMALL_STACK */
sPymbed 0:1387ff3eed4a 2337
sPymbed 0:1387ff3eed4a 2338 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2339 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2340 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2341 if (P->key == NULL)
sPymbed 0:1387ff3eed4a 2342 #endif
sPymbed 0:1387ff3eed4a 2343 {
sPymbed 0:1387ff3eed4a 2344 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2345 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2346 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2347 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2348 #endif
sPymbed 0:1387ff3eed4a 2349 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2350 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2351 }
sPymbed 0:1387ff3eed4a 2352 #endif
sPymbed 0:1387ff3eed4a 2353 return MEMORY_E;
sPymbed 0:1387ff3eed4a 2354 }
sPymbed 0:1387ff3eed4a 2355
sPymbed 0:1387ff3eed4a 2356 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2357 /* Use local stack variable */
sPymbed 0:1387ff3eed4a 2358 x = rx;
sPymbed 0:1387ff3eed4a 2359 y = ry;
sPymbed 0:1387ff3eed4a 2360 z = rz;
sPymbed 0:1387ff3eed4a 2361
sPymbed 0:1387ff3eed4a 2362 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2363 goto done;
sPymbed 0:1387ff3eed4a 2364 }
sPymbed 0:1387ff3eed4a 2365
sPymbed 0:1387ff3eed4a 2366 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2367 err = mp_copy(P->x, x);
sPymbed 0:1387ff3eed4a 2368 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2369 err = mp_copy(P->y, y);
sPymbed 0:1387ff3eed4a 2370 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2371 err = mp_copy(P->z, z);
sPymbed 0:1387ff3eed4a 2372
sPymbed 0:1387ff3eed4a 2373 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2374 goto done;
sPymbed 0:1387ff3eed4a 2375 }
sPymbed 0:1387ff3eed4a 2376 #else
sPymbed 0:1387ff3eed4a 2377 /* Use destination directly */
sPymbed 0:1387ff3eed4a 2378 x = P->x;
sPymbed 0:1387ff3eed4a 2379 y = P->y;
sPymbed 0:1387ff3eed4a 2380 z = P->z;
sPymbed 0:1387ff3eed4a 2381 #endif
sPymbed 0:1387ff3eed4a 2382
sPymbed 0:1387ff3eed4a 2383 /* first map z back to normal */
sPymbed 0:1387ff3eed4a 2384 err = mp_montgomery_reduce(z, modulus, mp);
sPymbed 0:1387ff3eed4a 2385
sPymbed 0:1387ff3eed4a 2386 /* get 1/z */
sPymbed 0:1387ff3eed4a 2387 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2388 err = mp_invmod(z, modulus, t1);
sPymbed 0:1387ff3eed4a 2389
sPymbed 0:1387ff3eed4a 2390 /* get 1/z^2 and 1/z^3 */
sPymbed 0:1387ff3eed4a 2391 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2392 err = mp_sqr(t1, t2);
sPymbed 0:1387ff3eed4a 2393 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2394 err = mp_mod(t2, modulus, t2);
sPymbed 0:1387ff3eed4a 2395 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2396 err = mp_mul(t1, t2, t1);
sPymbed 0:1387ff3eed4a 2397 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2398 err = mp_mod(t1, modulus, t1);
sPymbed 0:1387ff3eed4a 2399
sPymbed 0:1387ff3eed4a 2400 /* multiply against x/y */
sPymbed 0:1387ff3eed4a 2401 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2402 err = mp_mul(x, t2, x);
sPymbed 0:1387ff3eed4a 2403 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2404 err = mp_montgomery_reduce(x, modulus, mp);
sPymbed 0:1387ff3eed4a 2405 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2406 err = mp_mul(y, t1, y);
sPymbed 0:1387ff3eed4a 2407 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2408 err = mp_montgomery_reduce(y, modulus, mp);
sPymbed 0:1387ff3eed4a 2409
sPymbed 0:1387ff3eed4a 2410 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2411 err = mp_set(z, 1);
sPymbed 0:1387ff3eed4a 2412
sPymbed 0:1387ff3eed4a 2413 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2414 /* return result */
sPymbed 0:1387ff3eed4a 2415 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2416 err = mp_copy(x, P->x);
sPymbed 0:1387ff3eed4a 2417 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2418 err = mp_copy(y, P->y);
sPymbed 0:1387ff3eed4a 2419 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2420 err = mp_copy(z, P->z);
sPymbed 0:1387ff3eed4a 2421
sPymbed 0:1387ff3eed4a 2422 done:
sPymbed 0:1387ff3eed4a 2423 #endif
sPymbed 0:1387ff3eed4a 2424
sPymbed 0:1387ff3eed4a 2425 /* clean up */
sPymbed 0:1387ff3eed4a 2426 mp_clear(t1);
sPymbed 0:1387ff3eed4a 2427 mp_clear(t2);
sPymbed 0:1387ff3eed4a 2428
sPymbed 0:1387ff3eed4a 2429 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2430 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2431 if (P->key == NULL)
sPymbed 0:1387ff3eed4a 2432 #endif
sPymbed 0:1387ff3eed4a 2433 {
sPymbed 0:1387ff3eed4a 2434 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2435 XFREE(rz, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2436 XFREE(ry, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2437 XFREE(rx, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2438 #endif
sPymbed 0:1387ff3eed4a 2439 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2440 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2441 }
sPymbed 0:1387ff3eed4a 2442 #endif
sPymbed 0:1387ff3eed4a 2443
sPymbed 0:1387ff3eed4a 2444 return err;
sPymbed 0:1387ff3eed4a 2445 #else
sPymbed 0:1387ff3eed4a 2446 if (P == NULL || modulus == NULL)
sPymbed 0:1387ff3eed4a 2447 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 2448
sPymbed 0:1387ff3eed4a 2449 (void)mp;
sPymbed 0:1387ff3eed4a 2450
sPymbed 0:1387ff3eed4a 2451 return sp_ecc_map_256(P->x, P->y, P->z);
sPymbed 0:1387ff3eed4a 2452 #endif
sPymbed 0:1387ff3eed4a 2453 }
sPymbed 0:1387ff3eed4a 2454
sPymbed 0:1387ff3eed4a 2455 #endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
sPymbed 0:1387ff3eed4a 2456
sPymbed 0:1387ff3eed4a 2457 #if !defined(FREESCALE_LTC_ECC)
sPymbed 0:1387ff3eed4a 2458
sPymbed 0:1387ff3eed4a 2459 #if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH)
sPymbed 0:1387ff3eed4a 2460 /**
sPymbed 0:1387ff3eed4a 2461 Perform a point multiplication
sPymbed 0:1387ff3eed4a 2462 k The scalar to multiply by
sPymbed 0:1387ff3eed4a 2463 G The base point
sPymbed 0:1387ff3eed4a 2464 R [out] Destination for kG
sPymbed 0:1387ff3eed4a 2465 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 2466 modulus The modulus of the field the ECC curve is in
sPymbed 0:1387ff3eed4a 2467 map Boolean whether to map back to affine or not
sPymbed 0:1387ff3eed4a 2468 (1==map, 0 == leave in projective)
sPymbed 0:1387ff3eed4a 2469 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 2470 */
sPymbed 0:1387ff3eed4a 2471 #ifdef FP_ECC
sPymbed 0:1387ff3eed4a 2472 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R,
sPymbed 0:1387ff3eed4a 2473 mp_int* a, mp_int* modulus, int map,
sPymbed 0:1387ff3eed4a 2474 void* heap)
sPymbed 0:1387ff3eed4a 2475 #else
sPymbed 0:1387ff3eed4a 2476 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
sPymbed 0:1387ff3eed4a 2477 mp_int* a, mp_int* modulus, int map,
sPymbed 0:1387ff3eed4a 2478 void* heap)
sPymbed 0:1387ff3eed4a 2479 #endif
sPymbed 0:1387ff3eed4a 2480 {
sPymbed 0:1387ff3eed4a 2481 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 2482 #ifndef ECC_TIMING_RESISTANT
sPymbed 0:1387ff3eed4a 2483 /* size of sliding window, don't change this! */
sPymbed 0:1387ff3eed4a 2484 #define WINSIZE 4
sPymbed 0:1387ff3eed4a 2485 #define M_POINTS 8
sPymbed 0:1387ff3eed4a 2486 int first = 1, bitbuf = 0, bitcpy = 0, j;
sPymbed 0:1387ff3eed4a 2487 #else
sPymbed 0:1387ff3eed4a 2488 #define M_POINTS 3
sPymbed 0:1387ff3eed4a 2489 #endif
sPymbed 0:1387ff3eed4a 2490
sPymbed 0:1387ff3eed4a 2491 ecc_point *tG, *M[M_POINTS];
sPymbed 0:1387ff3eed4a 2492 int i, err;
sPymbed 0:1387ff3eed4a 2493 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2494 mp_int* mu = NULL;
sPymbed 0:1387ff3eed4a 2495 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2496 ecc_key key;
sPymbed 0:1387ff3eed4a 2497 #endif
sPymbed 0:1387ff3eed4a 2498 #else
sPymbed 0:1387ff3eed4a 2499 mp_int mu[1];
sPymbed 0:1387ff3eed4a 2500 #endif
sPymbed 0:1387ff3eed4a 2501 mp_digit mp;
sPymbed 0:1387ff3eed4a 2502 mp_digit buf;
sPymbed 0:1387ff3eed4a 2503 int bitcnt = 0, mode = 0, digidx = 0;
sPymbed 0:1387ff3eed4a 2504
sPymbed 0:1387ff3eed4a 2505 if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 2506 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 2507 }
sPymbed 0:1387ff3eed4a 2508
sPymbed 0:1387ff3eed4a 2509 /* init variables */
sPymbed 0:1387ff3eed4a 2510 tG = NULL;
sPymbed 0:1387ff3eed4a 2511 XMEMSET(M, 0, sizeof(M));
sPymbed 0:1387ff3eed4a 2512 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2513 mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2514 if (mu == NULL)
sPymbed 0:1387ff3eed4a 2515 return MEMORY_E;
sPymbed 0:1387ff3eed4a 2516 #endif
sPymbed 0:1387ff3eed4a 2517 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2518 key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2519 key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2520 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2521 key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2522 key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2523 key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2524 #endif
sPymbed 0:1387ff3eed4a 2525 if (key.t1 == NULL || key.t2 == NULL
sPymbed 0:1387ff3eed4a 2526 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2527 || key.x == NULL || key.y == NULL || key.z == NULL
sPymbed 0:1387ff3eed4a 2528 #endif
sPymbed 0:1387ff3eed4a 2529 ) {
sPymbed 0:1387ff3eed4a 2530 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2531 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2532 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2533 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2534 #endif
sPymbed 0:1387ff3eed4a 2535 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2536 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2537 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2538 return MEMORY_E;
sPymbed 0:1387ff3eed4a 2539 }
sPymbed 0:1387ff3eed4a 2540 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2541
sPymbed 0:1387ff3eed4a 2542 /* init montgomery reduction */
sPymbed 0:1387ff3eed4a 2543 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2544 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2545 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2546 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2547 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2548 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2549 #endif
sPymbed 0:1387ff3eed4a 2550 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2551 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2552 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2553 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2554 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2555 #endif
sPymbed 0:1387ff3eed4a 2556 return err;
sPymbed 0:1387ff3eed4a 2557 }
sPymbed 0:1387ff3eed4a 2558
sPymbed 0:1387ff3eed4a 2559 if ((err = mp_init(mu)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2560 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2561 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2562 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2563 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2564 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2565 #endif
sPymbed 0:1387ff3eed4a 2566 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2567 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2568 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2569 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2570 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2571 #endif
sPymbed 0:1387ff3eed4a 2572 return err;
sPymbed 0:1387ff3eed4a 2573 }
sPymbed 0:1387ff3eed4a 2574 if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2575 mp_clear(mu);
sPymbed 0:1387ff3eed4a 2576 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2577 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2578 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2579 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2580 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2581 #endif
sPymbed 0:1387ff3eed4a 2582 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2583 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2584 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2585 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2586 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2587 #endif
sPymbed 0:1387ff3eed4a 2588 return err;
sPymbed 0:1387ff3eed4a 2589 }
sPymbed 0:1387ff3eed4a 2590
sPymbed 0:1387ff3eed4a 2591 /* alloc ram for window temps */
sPymbed 0:1387ff3eed4a 2592 for (i = 0; i < M_POINTS; i++) {
sPymbed 0:1387ff3eed4a 2593 M[i] = wc_ecc_new_point_h(heap);
sPymbed 0:1387ff3eed4a 2594 if (M[i] == NULL) {
sPymbed 0:1387ff3eed4a 2595 mp_clear(mu);
sPymbed 0:1387ff3eed4a 2596 err = MEMORY_E; goto exit;
sPymbed 0:1387ff3eed4a 2597 }
sPymbed 0:1387ff3eed4a 2598 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2599 M[i]->key = &key;
sPymbed 0:1387ff3eed4a 2600 #endif
sPymbed 0:1387ff3eed4a 2601 }
sPymbed 0:1387ff3eed4a 2602
sPymbed 0:1387ff3eed4a 2603 /* make a copy of G in case R==G */
sPymbed 0:1387ff3eed4a 2604 tG = wc_ecc_new_point_h(heap);
sPymbed 0:1387ff3eed4a 2605 if (tG == NULL)
sPymbed 0:1387ff3eed4a 2606 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 2607
sPymbed 0:1387ff3eed4a 2608 /* tG = G and convert to montgomery */
sPymbed 0:1387ff3eed4a 2609 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2610 if (mp_cmp_d(mu, 1) == MP_EQ) {
sPymbed 0:1387ff3eed4a 2611 err = mp_copy(G->x, tG->x);
sPymbed 0:1387ff3eed4a 2612 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2613 err = mp_copy(G->y, tG->y);
sPymbed 0:1387ff3eed4a 2614 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2615 err = mp_copy(G->z, tG->z);
sPymbed 0:1387ff3eed4a 2616 } else {
sPymbed 0:1387ff3eed4a 2617 err = mp_mulmod(G->x, mu, modulus, tG->x);
sPymbed 0:1387ff3eed4a 2618 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2619 err = mp_mulmod(G->y, mu, modulus, tG->y);
sPymbed 0:1387ff3eed4a 2620 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2621 err = mp_mulmod(G->z, mu, modulus, tG->z);
sPymbed 0:1387ff3eed4a 2622 }
sPymbed 0:1387ff3eed4a 2623 }
sPymbed 0:1387ff3eed4a 2624
sPymbed 0:1387ff3eed4a 2625 /* done with mu */
sPymbed 0:1387ff3eed4a 2626 mp_clear(mu);
sPymbed 0:1387ff3eed4a 2627
sPymbed 0:1387ff3eed4a 2628 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2629 R->key = &key;
sPymbed 0:1387ff3eed4a 2630 #endif
sPymbed 0:1387ff3eed4a 2631 #ifndef ECC_TIMING_RESISTANT
sPymbed 0:1387ff3eed4a 2632
sPymbed 0:1387ff3eed4a 2633 /* calc the M tab, which holds kG for k==8..15 */
sPymbed 0:1387ff3eed4a 2634 /* M[0] == 8G */
sPymbed 0:1387ff3eed4a 2635 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2636 err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2637 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2638 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2639 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2640 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2641
sPymbed 0:1387ff3eed4a 2642 /* now find (8+k)G for k=1..7 */
sPymbed 0:1387ff3eed4a 2643 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2644 for (j = 9; j < 16; j++) {
sPymbed 0:1387ff3eed4a 2645 err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a,
sPymbed 0:1387ff3eed4a 2646 modulus, mp);
sPymbed 0:1387ff3eed4a 2647 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2648 }
sPymbed 0:1387ff3eed4a 2649
sPymbed 0:1387ff3eed4a 2650 /* setup sliding window */
sPymbed 0:1387ff3eed4a 2651 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2652 mode = 0;
sPymbed 0:1387ff3eed4a 2653 bitcnt = 1;
sPymbed 0:1387ff3eed4a 2654 buf = 0;
sPymbed 0:1387ff3eed4a 2655 digidx = get_digit_count(k) - 1;
sPymbed 0:1387ff3eed4a 2656 bitcpy = bitbuf = 0;
sPymbed 0:1387ff3eed4a 2657 first = 1;
sPymbed 0:1387ff3eed4a 2658
sPymbed 0:1387ff3eed4a 2659 /* perform ops */
sPymbed 0:1387ff3eed4a 2660 for (;;) {
sPymbed 0:1387ff3eed4a 2661 /* grab next digit as required */
sPymbed 0:1387ff3eed4a 2662 if (--bitcnt == 0) {
sPymbed 0:1387ff3eed4a 2663 if (digidx == -1) {
sPymbed 0:1387ff3eed4a 2664 break;
sPymbed 0:1387ff3eed4a 2665 }
sPymbed 0:1387ff3eed4a 2666 buf = get_digit(k, digidx);
sPymbed 0:1387ff3eed4a 2667 bitcnt = (int) DIGIT_BIT;
sPymbed 0:1387ff3eed4a 2668 --digidx;
sPymbed 0:1387ff3eed4a 2669 }
sPymbed 0:1387ff3eed4a 2670
sPymbed 0:1387ff3eed4a 2671 /* grab the next msb from the ltiplicand */
sPymbed 0:1387ff3eed4a 2672 i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
sPymbed 0:1387ff3eed4a 2673 buf <<= 1;
sPymbed 0:1387ff3eed4a 2674
sPymbed 0:1387ff3eed4a 2675 /* skip leading zero bits */
sPymbed 0:1387ff3eed4a 2676 if (mode == 0 && i == 0)
sPymbed 0:1387ff3eed4a 2677 continue;
sPymbed 0:1387ff3eed4a 2678
sPymbed 0:1387ff3eed4a 2679 /* if the bit is zero and mode == 1 then we double */
sPymbed 0:1387ff3eed4a 2680 if (mode == 1 && i == 0) {
sPymbed 0:1387ff3eed4a 2681 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
sPymbed 0:1387ff3eed4a 2682 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2683 continue;
sPymbed 0:1387ff3eed4a 2684 }
sPymbed 0:1387ff3eed4a 2685
sPymbed 0:1387ff3eed4a 2686 /* else we add it to the window */
sPymbed 0:1387ff3eed4a 2687 bitbuf |= (i << (WINSIZE - ++bitcpy));
sPymbed 0:1387ff3eed4a 2688 mode = 2;
sPymbed 0:1387ff3eed4a 2689
sPymbed 0:1387ff3eed4a 2690 if (bitcpy == WINSIZE) {
sPymbed 0:1387ff3eed4a 2691 /* if this is the first window we do a simple copy */
sPymbed 0:1387ff3eed4a 2692 if (first == 1) {
sPymbed 0:1387ff3eed4a 2693 /* R = kG [k = first window] */
sPymbed 0:1387ff3eed4a 2694 err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
sPymbed 0:1387ff3eed4a 2695 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2696
sPymbed 0:1387ff3eed4a 2697 err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
sPymbed 0:1387ff3eed4a 2698 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2699
sPymbed 0:1387ff3eed4a 2700 err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
sPymbed 0:1387ff3eed4a 2701 first = 0;
sPymbed 0:1387ff3eed4a 2702 } else {
sPymbed 0:1387ff3eed4a 2703 /* normal window */
sPymbed 0:1387ff3eed4a 2704 /* ok window is filled so double as required and add */
sPymbed 0:1387ff3eed4a 2705 /* double first */
sPymbed 0:1387ff3eed4a 2706 for (j = 0; j < WINSIZE; j++) {
sPymbed 0:1387ff3eed4a 2707 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
sPymbed 0:1387ff3eed4a 2708 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2709 }
sPymbed 0:1387ff3eed4a 2710 if (err != MP_OKAY) break; /* out of first for(;;) */
sPymbed 0:1387ff3eed4a 2711
sPymbed 0:1387ff3eed4a 2712 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
sPymbed 0:1387ff3eed4a 2713 err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
sPymbed 0:1387ff3eed4a 2714 modulus, mp);
sPymbed 0:1387ff3eed4a 2715 }
sPymbed 0:1387ff3eed4a 2716 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2717 /* empty window and reset */
sPymbed 0:1387ff3eed4a 2718 bitcpy = bitbuf = 0;
sPymbed 0:1387ff3eed4a 2719 mode = 1;
sPymbed 0:1387ff3eed4a 2720 }
sPymbed 0:1387ff3eed4a 2721 }
sPymbed 0:1387ff3eed4a 2722 }
sPymbed 0:1387ff3eed4a 2723
sPymbed 0:1387ff3eed4a 2724 /* if bits remain then double/add */
sPymbed 0:1387ff3eed4a 2725 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2726 if (mode == 2 && bitcpy > 0) {
sPymbed 0:1387ff3eed4a 2727 /* double then add */
sPymbed 0:1387ff3eed4a 2728 for (j = 0; j < bitcpy; j++) {
sPymbed 0:1387ff3eed4a 2729 /* only double if we have had at least one add first */
sPymbed 0:1387ff3eed4a 2730 if (first == 0) {
sPymbed 0:1387ff3eed4a 2731 err = ecc_projective_dbl_point(R, R, a, modulus, mp);
sPymbed 0:1387ff3eed4a 2732 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2733 }
sPymbed 0:1387ff3eed4a 2734
sPymbed 0:1387ff3eed4a 2735 bitbuf <<= 1;
sPymbed 0:1387ff3eed4a 2736 if ((bitbuf & (1 << WINSIZE)) != 0) {
sPymbed 0:1387ff3eed4a 2737 if (first == 1) {
sPymbed 0:1387ff3eed4a 2738 /* first add, so copy */
sPymbed 0:1387ff3eed4a 2739 err = mp_copy(tG->x, R->x);
sPymbed 0:1387ff3eed4a 2740 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2741
sPymbed 0:1387ff3eed4a 2742 err = mp_copy(tG->y, R->y);
sPymbed 0:1387ff3eed4a 2743 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2744
sPymbed 0:1387ff3eed4a 2745 err = mp_copy(tG->z, R->z);
sPymbed 0:1387ff3eed4a 2746 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2747 first = 0;
sPymbed 0:1387ff3eed4a 2748 } else {
sPymbed 0:1387ff3eed4a 2749 /* then add */
sPymbed 0:1387ff3eed4a 2750 err = ecc_projective_add_point(R, tG, R, a, modulus,
sPymbed 0:1387ff3eed4a 2751 mp);
sPymbed 0:1387ff3eed4a 2752 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 2753 }
sPymbed 0:1387ff3eed4a 2754 }
sPymbed 0:1387ff3eed4a 2755 }
sPymbed 0:1387ff3eed4a 2756 }
sPymbed 0:1387ff3eed4a 2757 }
sPymbed 0:1387ff3eed4a 2758
sPymbed 0:1387ff3eed4a 2759 #undef WINSIZE
sPymbed 0:1387ff3eed4a 2760
sPymbed 0:1387ff3eed4a 2761 #else /* ECC_TIMING_RESISTANT */
sPymbed 0:1387ff3eed4a 2762
sPymbed 0:1387ff3eed4a 2763 /* calc the M tab */
sPymbed 0:1387ff3eed4a 2764 /* M[0] == G */
sPymbed 0:1387ff3eed4a 2765 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2766 err = mp_copy(tG->x, M[0]->x);
sPymbed 0:1387ff3eed4a 2767 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2768 err = mp_copy(tG->y, M[0]->y);
sPymbed 0:1387ff3eed4a 2769 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2770 err = mp_copy(tG->z, M[0]->z);
sPymbed 0:1387ff3eed4a 2771
sPymbed 0:1387ff3eed4a 2772 /* M[1] == 2G */
sPymbed 0:1387ff3eed4a 2773 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2774 err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2775
sPymbed 0:1387ff3eed4a 2776 /* setup sliding window */
sPymbed 0:1387ff3eed4a 2777 mode = 0;
sPymbed 0:1387ff3eed4a 2778 bitcnt = 1;
sPymbed 0:1387ff3eed4a 2779 buf = 0;
sPymbed 0:1387ff3eed4a 2780 digidx = get_digit_count(k) - 1;
sPymbed 0:1387ff3eed4a 2781
sPymbed 0:1387ff3eed4a 2782 /* perform ops */
sPymbed 0:1387ff3eed4a 2783 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 2784 for (;;) {
sPymbed 0:1387ff3eed4a 2785 /* grab next digit as required */
sPymbed 0:1387ff3eed4a 2786 if (--bitcnt == 0) {
sPymbed 0:1387ff3eed4a 2787 if (digidx == -1) {
sPymbed 0:1387ff3eed4a 2788 break;
sPymbed 0:1387ff3eed4a 2789 }
sPymbed 0:1387ff3eed4a 2790 buf = get_digit(k, digidx);
sPymbed 0:1387ff3eed4a 2791 bitcnt = (int)DIGIT_BIT;
sPymbed 0:1387ff3eed4a 2792 --digidx;
sPymbed 0:1387ff3eed4a 2793 }
sPymbed 0:1387ff3eed4a 2794
sPymbed 0:1387ff3eed4a 2795 /* grab the next msb from the multiplicand */
sPymbed 0:1387ff3eed4a 2796 i = (buf >> (DIGIT_BIT - 1)) & 1;
sPymbed 0:1387ff3eed4a 2797 buf <<= 1;
sPymbed 0:1387ff3eed4a 2798
sPymbed 0:1387ff3eed4a 2799 if (mode == 0 && i == 0) {
sPymbed 0:1387ff3eed4a 2800 /* timing resistant - dummy operations */
sPymbed 0:1387ff3eed4a 2801 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2802 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
sPymbed 0:1387ff3eed4a 2803 mp);
sPymbed 0:1387ff3eed4a 2804 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2805 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2806 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2807 continue;
sPymbed 0:1387ff3eed4a 2808 }
sPymbed 0:1387ff3eed4a 2809
sPymbed 0:1387ff3eed4a 2810 if (mode == 0 && i == 1) {
sPymbed 0:1387ff3eed4a 2811 mode = 1;
sPymbed 0:1387ff3eed4a 2812 /* timing resistant - dummy operations */
sPymbed 0:1387ff3eed4a 2813 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2814 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
sPymbed 0:1387ff3eed4a 2815 mp);
sPymbed 0:1387ff3eed4a 2816 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2817 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2818 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2819 continue;
sPymbed 0:1387ff3eed4a 2820 }
sPymbed 0:1387ff3eed4a 2821
sPymbed 0:1387ff3eed4a 2822 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2823 err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus,
sPymbed 0:1387ff3eed4a 2824 mp);
sPymbed 0:1387ff3eed4a 2825 #ifdef WC_NO_CACHE_RESISTANT
sPymbed 0:1387ff3eed4a 2826 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2827 err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2828 #else
sPymbed 0:1387ff3eed4a 2829 /* instead of using M[i] for double, which leaks key bit to cache
sPymbed 0:1387ff3eed4a 2830 * monitor, use M[2] as temp, make sure address calc is constant,
sPymbed 0:1387ff3eed4a 2831 * keep M[0] and M[1] in cache */
sPymbed 0:1387ff3eed4a 2832 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2833 err = mp_copy((mp_int*)
sPymbed 0:1387ff3eed4a 2834 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2835 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
sPymbed 0:1387ff3eed4a 2836 M[2]->x);
sPymbed 0:1387ff3eed4a 2837 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2838 err = mp_copy((mp_int*)
sPymbed 0:1387ff3eed4a 2839 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2840 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
sPymbed 0:1387ff3eed4a 2841 M[2]->y);
sPymbed 0:1387ff3eed4a 2842 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2843 err = mp_copy((mp_int*)
sPymbed 0:1387ff3eed4a 2844 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2845 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
sPymbed 0:1387ff3eed4a 2846 M[2]->z);
sPymbed 0:1387ff3eed4a 2847 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2848 err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp);
sPymbed 0:1387ff3eed4a 2849 /* copy M[2] back to M[i] */
sPymbed 0:1387ff3eed4a 2850 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2851 err = mp_copy(M[2]->x,
sPymbed 0:1387ff3eed4a 2852 (mp_int*)
sPymbed 0:1387ff3eed4a 2853 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2854 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
sPymbed 0:1387ff3eed4a 2855 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2856 err = mp_copy(M[2]->y,
sPymbed 0:1387ff3eed4a 2857 (mp_int*)
sPymbed 0:1387ff3eed4a 2858 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2859 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
sPymbed 0:1387ff3eed4a 2860 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2861 err = mp_copy(M[2]->z,
sPymbed 0:1387ff3eed4a 2862 (mp_int*)
sPymbed 0:1387ff3eed4a 2863 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
sPymbed 0:1387ff3eed4a 2864 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
sPymbed 0:1387ff3eed4a 2865 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 2866 break;
sPymbed 0:1387ff3eed4a 2867 #endif /* WC_NO_CACHE_RESISTANT */
sPymbed 0:1387ff3eed4a 2868 } /* end for */
sPymbed 0:1387ff3eed4a 2869 }
sPymbed 0:1387ff3eed4a 2870
sPymbed 0:1387ff3eed4a 2871 /* copy result out */
sPymbed 0:1387ff3eed4a 2872 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2873 err = mp_copy(M[0]->x, R->x);
sPymbed 0:1387ff3eed4a 2874 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2875 err = mp_copy(M[0]->y, R->y);
sPymbed 0:1387ff3eed4a 2876 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 2877 err = mp_copy(M[0]->z, R->z);
sPymbed 0:1387ff3eed4a 2878
sPymbed 0:1387ff3eed4a 2879 #endif /* ECC_TIMING_RESISTANT */
sPymbed 0:1387ff3eed4a 2880
sPymbed 0:1387ff3eed4a 2881 /* map R back from projective space */
sPymbed 0:1387ff3eed4a 2882 if (err == MP_OKAY && map)
sPymbed 0:1387ff3eed4a 2883 err = ecc_map(R, modulus, mp);
sPymbed 0:1387ff3eed4a 2884
sPymbed 0:1387ff3eed4a 2885 exit:
sPymbed 0:1387ff3eed4a 2886
sPymbed 0:1387ff3eed4a 2887 /* done */
sPymbed 0:1387ff3eed4a 2888 wc_ecc_del_point_h(tG, heap);
sPymbed 0:1387ff3eed4a 2889 for (i = 0; i < M_POINTS; i++) {
sPymbed 0:1387ff3eed4a 2890 wc_ecc_del_point_h(M[i], heap);
sPymbed 0:1387ff3eed4a 2891 }
sPymbed 0:1387ff3eed4a 2892 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 2893 R->key = NULL;
sPymbed 0:1387ff3eed4a 2894 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2895 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2896 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2897 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2898 #endif
sPymbed 0:1387ff3eed4a 2899 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2900 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2901 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 2902 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 2903 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2904 #endif
sPymbed 0:1387ff3eed4a 2905
sPymbed 0:1387ff3eed4a 2906 return err;
sPymbed 0:1387ff3eed4a 2907 #else
sPymbed 0:1387ff3eed4a 2908 if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 2909 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 2910 }
sPymbed 0:1387ff3eed4a 2911
sPymbed 0:1387ff3eed4a 2912 (void)a;
sPymbed 0:1387ff3eed4a 2913
sPymbed 0:1387ff3eed4a 2914 return sp_ecc_mulmod_256(k, G, R, map, heap);
sPymbed 0:1387ff3eed4a 2915 #endif
sPymbed 0:1387ff3eed4a 2916 }
sPymbed 0:1387ff3eed4a 2917
sPymbed 0:1387ff3eed4a 2918 #endif /* !FP_ECC || !WOLFSSL_SP_MATH */
sPymbed 0:1387ff3eed4a 2919
sPymbed 0:1387ff3eed4a 2920 #endif /* !FREESCALE_LTC_ECC */
sPymbed 0:1387ff3eed4a 2921
sPymbed 0:1387ff3eed4a 2922 /** ECC Fixed Point mulmod global
sPymbed 0:1387ff3eed4a 2923 k The multiplicand
sPymbed 0:1387ff3eed4a 2924 G Base point to multiply
sPymbed 0:1387ff3eed4a 2925 R [out] Destination of product
sPymbed 0:1387ff3eed4a 2926 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 2927 modulus The modulus for the curve
sPymbed 0:1387ff3eed4a 2928 map [boolean] If non-zero maps the point back to affine co-ordinates,
sPymbed 0:1387ff3eed4a 2929 otherwise it's left in jacobian-montgomery form
sPymbed 0:1387ff3eed4a 2930 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 2931 */
sPymbed 0:1387ff3eed4a 2932 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
sPymbed 0:1387ff3eed4a 2933 mp_int* modulus, int map)
sPymbed 0:1387ff3eed4a 2934 {
sPymbed 0:1387ff3eed4a 2935 return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
sPymbed 0:1387ff3eed4a 2936 }
sPymbed 0:1387ff3eed4a 2937
sPymbed 0:1387ff3eed4a 2938 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 2939
sPymbed 0:1387ff3eed4a 2940 /**
sPymbed 0:1387ff3eed4a 2941 * use a heap hint when creating new ecc_point
sPymbed 0:1387ff3eed4a 2942 * return an allocated point on success or NULL on failure
sPymbed 0:1387ff3eed4a 2943 */
sPymbed 0:1387ff3eed4a 2944 ecc_point* wc_ecc_new_point_h(void* heap)
sPymbed 0:1387ff3eed4a 2945 {
sPymbed 0:1387ff3eed4a 2946 ecc_point* p;
sPymbed 0:1387ff3eed4a 2947
sPymbed 0:1387ff3eed4a 2948 (void)heap;
sPymbed 0:1387ff3eed4a 2949
sPymbed 0:1387ff3eed4a 2950 p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2951 if (p == NULL) {
sPymbed 0:1387ff3eed4a 2952 return NULL;
sPymbed 0:1387ff3eed4a 2953 }
sPymbed 0:1387ff3eed4a 2954 XMEMSET(p, 0, sizeof(ecc_point));
sPymbed 0:1387ff3eed4a 2955
sPymbed 0:1387ff3eed4a 2956 #ifndef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 2957 if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 2958 XFREE(p, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2959 return NULL;
sPymbed 0:1387ff3eed4a 2960 }
sPymbed 0:1387ff3eed4a 2961 #else
sPymbed 0:1387ff3eed4a 2962 p->x = (mp_int*)&p->xyz[0];
sPymbed 0:1387ff3eed4a 2963 p->y = (mp_int*)&p->xyz[1];
sPymbed 0:1387ff3eed4a 2964 p->z = (mp_int*)&p->xyz[2];
sPymbed 0:1387ff3eed4a 2965 alt_fp_init(p->x);
sPymbed 0:1387ff3eed4a 2966 alt_fp_init(p->y);
sPymbed 0:1387ff3eed4a 2967 alt_fp_init(p->z);
sPymbed 0:1387ff3eed4a 2968 #endif
sPymbed 0:1387ff3eed4a 2969
sPymbed 0:1387ff3eed4a 2970 return p;
sPymbed 0:1387ff3eed4a 2971 }
sPymbed 0:1387ff3eed4a 2972
sPymbed 0:1387ff3eed4a 2973
sPymbed 0:1387ff3eed4a 2974 /**
sPymbed 0:1387ff3eed4a 2975 Allocate a new ECC point
sPymbed 0:1387ff3eed4a 2976 return A newly allocated point or NULL on error
sPymbed 0:1387ff3eed4a 2977 */
sPymbed 0:1387ff3eed4a 2978 ecc_point* wc_ecc_new_point(void)
sPymbed 0:1387ff3eed4a 2979 {
sPymbed 0:1387ff3eed4a 2980 return wc_ecc_new_point_h(NULL);
sPymbed 0:1387ff3eed4a 2981 }
sPymbed 0:1387ff3eed4a 2982
sPymbed 0:1387ff3eed4a 2983
sPymbed 0:1387ff3eed4a 2984 void wc_ecc_del_point_h(ecc_point* p, void* heap)
sPymbed 0:1387ff3eed4a 2985 {
sPymbed 0:1387ff3eed4a 2986 /* prevents free'ing null arguments */
sPymbed 0:1387ff3eed4a 2987 if (p != NULL) {
sPymbed 0:1387ff3eed4a 2988 mp_clear(p->x);
sPymbed 0:1387ff3eed4a 2989 mp_clear(p->y);
sPymbed 0:1387ff3eed4a 2990 mp_clear(p->z);
sPymbed 0:1387ff3eed4a 2991 XFREE(p, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 2992 }
sPymbed 0:1387ff3eed4a 2993 (void)heap;
sPymbed 0:1387ff3eed4a 2994 }
sPymbed 0:1387ff3eed4a 2995
sPymbed 0:1387ff3eed4a 2996
sPymbed 0:1387ff3eed4a 2997 /** Free an ECC point from memory
sPymbed 0:1387ff3eed4a 2998 p The point to free
sPymbed 0:1387ff3eed4a 2999 */
sPymbed 0:1387ff3eed4a 3000 void wc_ecc_del_point(ecc_point* p)
sPymbed 0:1387ff3eed4a 3001 {
sPymbed 0:1387ff3eed4a 3002 wc_ecc_del_point_h(p, NULL);
sPymbed 0:1387ff3eed4a 3003 }
sPymbed 0:1387ff3eed4a 3004
sPymbed 0:1387ff3eed4a 3005
sPymbed 0:1387ff3eed4a 3006 /** Copy the value of a point to an other one
sPymbed 0:1387ff3eed4a 3007 p The point to copy
sPymbed 0:1387ff3eed4a 3008 r The created point
sPymbed 0:1387ff3eed4a 3009 */
sPymbed 0:1387ff3eed4a 3010 int wc_ecc_copy_point(ecc_point* p, ecc_point *r)
sPymbed 0:1387ff3eed4a 3011 {
sPymbed 0:1387ff3eed4a 3012 int ret;
sPymbed 0:1387ff3eed4a 3013
sPymbed 0:1387ff3eed4a 3014 /* prevents null arguments */
sPymbed 0:1387ff3eed4a 3015 if (p == NULL || r == NULL)
sPymbed 0:1387ff3eed4a 3016 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3017
sPymbed 0:1387ff3eed4a 3018 ret = mp_copy(p->x, r->x);
sPymbed 0:1387ff3eed4a 3019 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 3020 return ret;
sPymbed 0:1387ff3eed4a 3021 ret = mp_copy(p->y, r->y);
sPymbed 0:1387ff3eed4a 3022 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 3023 return ret;
sPymbed 0:1387ff3eed4a 3024 ret = mp_copy(p->z, r->z);
sPymbed 0:1387ff3eed4a 3025 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 3026 return ret;
sPymbed 0:1387ff3eed4a 3027
sPymbed 0:1387ff3eed4a 3028 return MP_OKAY;
sPymbed 0:1387ff3eed4a 3029 }
sPymbed 0:1387ff3eed4a 3030
sPymbed 0:1387ff3eed4a 3031 /** Compare the value of a point with an other one
sPymbed 0:1387ff3eed4a 3032 a The point to compare
sPymbed 0:1387ff3eed4a 3033 b The other point to compare
sPymbed 0:1387ff3eed4a 3034
sPymbed 0:1387ff3eed4a 3035 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
sPymbed 0:1387ff3eed4a 3036 */
sPymbed 0:1387ff3eed4a 3037 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
sPymbed 0:1387ff3eed4a 3038 {
sPymbed 0:1387ff3eed4a 3039 int ret;
sPymbed 0:1387ff3eed4a 3040
sPymbed 0:1387ff3eed4a 3041 /* prevents null arguments */
sPymbed 0:1387ff3eed4a 3042 if (a == NULL || b == NULL)
sPymbed 0:1387ff3eed4a 3043 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3044
sPymbed 0:1387ff3eed4a 3045 ret = mp_cmp(a->x, b->x);
sPymbed 0:1387ff3eed4a 3046 if (ret != MP_EQ)
sPymbed 0:1387ff3eed4a 3047 return ret;
sPymbed 0:1387ff3eed4a 3048 ret = mp_cmp(a->y, b->y);
sPymbed 0:1387ff3eed4a 3049 if (ret != MP_EQ)
sPymbed 0:1387ff3eed4a 3050 return ret;
sPymbed 0:1387ff3eed4a 3051 ret = mp_cmp(a->z, b->z);
sPymbed 0:1387ff3eed4a 3052 if (ret != MP_EQ)
sPymbed 0:1387ff3eed4a 3053 return ret;
sPymbed 0:1387ff3eed4a 3054
sPymbed 0:1387ff3eed4a 3055 return MP_EQ;
sPymbed 0:1387ff3eed4a 3056 }
sPymbed 0:1387ff3eed4a 3057
sPymbed 0:1387ff3eed4a 3058
sPymbed 0:1387ff3eed4a 3059 /** Returns whether an ECC idx is valid or not
sPymbed 0:1387ff3eed4a 3060 n The idx number to check
sPymbed 0:1387ff3eed4a 3061 return 1 if valid, 0 if not
sPymbed 0:1387ff3eed4a 3062 */
sPymbed 0:1387ff3eed4a 3063 int wc_ecc_is_valid_idx(int n)
sPymbed 0:1387ff3eed4a 3064 {
sPymbed 0:1387ff3eed4a 3065 int x;
sPymbed 0:1387ff3eed4a 3066
sPymbed 0:1387ff3eed4a 3067 for (x = 0; ecc_sets[x].size != 0; x++)
sPymbed 0:1387ff3eed4a 3068 ;
sPymbed 0:1387ff3eed4a 3069 /* -1 is a valid index --- indicating that the domain params
sPymbed 0:1387ff3eed4a 3070 were supplied by the user */
sPymbed 0:1387ff3eed4a 3071 if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
sPymbed 0:1387ff3eed4a 3072 return 1;
sPymbed 0:1387ff3eed4a 3073 }
sPymbed 0:1387ff3eed4a 3074
sPymbed 0:1387ff3eed4a 3075 return 0;
sPymbed 0:1387ff3eed4a 3076 }
sPymbed 0:1387ff3eed4a 3077
sPymbed 0:1387ff3eed4a 3078 int wc_ecc_get_curve_idx(int curve_id)
sPymbed 0:1387ff3eed4a 3079 {
sPymbed 0:1387ff3eed4a 3080 int curve_idx;
sPymbed 0:1387ff3eed4a 3081 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
sPymbed 0:1387ff3eed4a 3082 if (curve_id == ecc_sets[curve_idx].id)
sPymbed 0:1387ff3eed4a 3083 break;
sPymbed 0:1387ff3eed4a 3084 }
sPymbed 0:1387ff3eed4a 3085 if (ecc_sets[curve_idx].size == 0) {
sPymbed 0:1387ff3eed4a 3086 return ECC_CURVE_INVALID;
sPymbed 0:1387ff3eed4a 3087 }
sPymbed 0:1387ff3eed4a 3088 return curve_idx;
sPymbed 0:1387ff3eed4a 3089 }
sPymbed 0:1387ff3eed4a 3090
sPymbed 0:1387ff3eed4a 3091 int wc_ecc_get_curve_id(int curve_idx)
sPymbed 0:1387ff3eed4a 3092 {
sPymbed 0:1387ff3eed4a 3093 if (wc_ecc_is_valid_idx(curve_idx)) {
sPymbed 0:1387ff3eed4a 3094 return ecc_sets[curve_idx].id;
sPymbed 0:1387ff3eed4a 3095 }
sPymbed 0:1387ff3eed4a 3096 return ECC_CURVE_INVALID;
sPymbed 0:1387ff3eed4a 3097 }
sPymbed 0:1387ff3eed4a 3098
sPymbed 0:1387ff3eed4a 3099 /* Returns the curve size that corresponds to a given ecc_curve_id identifier
sPymbed 0:1387ff3eed4a 3100 *
sPymbed 0:1387ff3eed4a 3101 * id curve id, from ecc_curve_id enum in ecc.h
sPymbed 0:1387ff3eed4a 3102 * return curve size, from ecc_sets[] on success, negative on error
sPymbed 0:1387ff3eed4a 3103 */
sPymbed 0:1387ff3eed4a 3104 int wc_ecc_get_curve_size_from_id(int curve_id)
sPymbed 0:1387ff3eed4a 3105 {
sPymbed 0:1387ff3eed4a 3106 int curve_idx = wc_ecc_get_curve_idx(curve_id);
sPymbed 0:1387ff3eed4a 3107 if (curve_idx == ECC_CURVE_INVALID)
sPymbed 0:1387ff3eed4a 3108 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3109 return ecc_sets[curve_idx].size;
sPymbed 0:1387ff3eed4a 3110 }
sPymbed 0:1387ff3eed4a 3111
sPymbed 0:1387ff3eed4a 3112 /* Returns the curve index that corresponds to a given curve name in
sPymbed 0:1387ff3eed4a 3113 * ecc_sets[] of ecc.c
sPymbed 0:1387ff3eed4a 3114 *
sPymbed 0:1387ff3eed4a 3115 * name curve name, from ecc_sets[].name in ecc.c
sPymbed 0:1387ff3eed4a 3116 * return curve index in ecc_sets[] on success, negative on error
sPymbed 0:1387ff3eed4a 3117 */
sPymbed 0:1387ff3eed4a 3118 int wc_ecc_get_curve_idx_from_name(const char* curveName)
sPymbed 0:1387ff3eed4a 3119 {
sPymbed 0:1387ff3eed4a 3120 int curve_idx;
sPymbed 0:1387ff3eed4a 3121 word32 len;
sPymbed 0:1387ff3eed4a 3122
sPymbed 0:1387ff3eed4a 3123 if (curveName == NULL)
sPymbed 0:1387ff3eed4a 3124 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3125
sPymbed 0:1387ff3eed4a 3126 len = (word32)XSTRLEN(curveName);
sPymbed 0:1387ff3eed4a 3127
sPymbed 0:1387ff3eed4a 3128 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
sPymbed 0:1387ff3eed4a 3129 if (ecc_sets[curve_idx].name &&
sPymbed 0:1387ff3eed4a 3130 XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) {
sPymbed 0:1387ff3eed4a 3131 break;
sPymbed 0:1387ff3eed4a 3132 }
sPymbed 0:1387ff3eed4a 3133 }
sPymbed 0:1387ff3eed4a 3134 if (ecc_sets[curve_idx].size == 0) {
sPymbed 0:1387ff3eed4a 3135 WOLFSSL_MSG("ecc_set curve name not found");
sPymbed 0:1387ff3eed4a 3136 return ECC_CURVE_INVALID;
sPymbed 0:1387ff3eed4a 3137 }
sPymbed 0:1387ff3eed4a 3138 return curve_idx;
sPymbed 0:1387ff3eed4a 3139 }
sPymbed 0:1387ff3eed4a 3140
sPymbed 0:1387ff3eed4a 3141 /* Returns the curve size that corresponds to a given curve name,
sPymbed 0:1387ff3eed4a 3142 * as listed in ecc_sets[] of ecc.c.
sPymbed 0:1387ff3eed4a 3143 *
sPymbed 0:1387ff3eed4a 3144 * name curve name, from ecc_sets[].name in ecc.c
sPymbed 0:1387ff3eed4a 3145 * return curve size, from ecc_sets[] on success, negative on error
sPymbed 0:1387ff3eed4a 3146 */
sPymbed 0:1387ff3eed4a 3147 int wc_ecc_get_curve_size_from_name(const char* curveName)
sPymbed 0:1387ff3eed4a 3148 {
sPymbed 0:1387ff3eed4a 3149 int curve_idx;
sPymbed 0:1387ff3eed4a 3150
sPymbed 0:1387ff3eed4a 3151 if (curveName == NULL)
sPymbed 0:1387ff3eed4a 3152 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3153
sPymbed 0:1387ff3eed4a 3154 curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
sPymbed 0:1387ff3eed4a 3155 if (curve_idx < 0)
sPymbed 0:1387ff3eed4a 3156 return curve_idx;
sPymbed 0:1387ff3eed4a 3157
sPymbed 0:1387ff3eed4a 3158 return ecc_sets[curve_idx].size;
sPymbed 0:1387ff3eed4a 3159 }
sPymbed 0:1387ff3eed4a 3160
sPymbed 0:1387ff3eed4a 3161 /* Returns the curve id that corresponds to a given curve name,
sPymbed 0:1387ff3eed4a 3162 * as listed in ecc_sets[] of ecc.c.
sPymbed 0:1387ff3eed4a 3163 *
sPymbed 0:1387ff3eed4a 3164 * name curve name, from ecc_sets[].name in ecc.c
sPymbed 0:1387ff3eed4a 3165 * return curve id, from ecc_sets[] on success, negative on error
sPymbed 0:1387ff3eed4a 3166 */
sPymbed 0:1387ff3eed4a 3167 int wc_ecc_get_curve_id_from_name(const char* curveName)
sPymbed 0:1387ff3eed4a 3168 {
sPymbed 0:1387ff3eed4a 3169 int curve_idx;
sPymbed 0:1387ff3eed4a 3170
sPymbed 0:1387ff3eed4a 3171 if (curveName == NULL)
sPymbed 0:1387ff3eed4a 3172 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3173
sPymbed 0:1387ff3eed4a 3174 curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
sPymbed 0:1387ff3eed4a 3175 if (curve_idx < 0)
sPymbed 0:1387ff3eed4a 3176 return curve_idx;
sPymbed 0:1387ff3eed4a 3177
sPymbed 0:1387ff3eed4a 3178 return ecc_sets[curve_idx].id;
sPymbed 0:1387ff3eed4a 3179 }
sPymbed 0:1387ff3eed4a 3180
sPymbed 0:1387ff3eed4a 3181 /* Compares a curve parameter (hex, from ecc_sets[]) to given input
sPymbed 0:1387ff3eed4a 3182 * parameter (byte array) for equality.
sPymbed 0:1387ff3eed4a 3183 *
sPymbed 0:1387ff3eed4a 3184 * Returns MP_EQ on success, negative on error */
sPymbed 0:1387ff3eed4a 3185 static int wc_ecc_cmp_param(const char* curveParam,
sPymbed 0:1387ff3eed4a 3186 const byte* param, word32 paramSz)
sPymbed 0:1387ff3eed4a 3187 {
sPymbed 0:1387ff3eed4a 3188 int err = MP_OKAY;
sPymbed 0:1387ff3eed4a 3189 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 3190 mp_int* a = NULL;
sPymbed 0:1387ff3eed4a 3191 mp_int* b = NULL;
sPymbed 0:1387ff3eed4a 3192 #else
sPymbed 0:1387ff3eed4a 3193 mp_int a[1], b[1];
sPymbed 0:1387ff3eed4a 3194 #endif
sPymbed 0:1387ff3eed4a 3195
sPymbed 0:1387ff3eed4a 3196 if (param == NULL || curveParam == NULL)
sPymbed 0:1387ff3eed4a 3197 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3198
sPymbed 0:1387ff3eed4a 3199 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 3200 a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 3201 if (a == NULL)
sPymbed 0:1387ff3eed4a 3202 return MEMORY_E;
sPymbed 0:1387ff3eed4a 3203 b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 3204 if (b == NULL) {
sPymbed 0:1387ff3eed4a 3205 XFREE(a, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 3206 return MEMORY_E;
sPymbed 0:1387ff3eed4a 3207 }
sPymbed 0:1387ff3eed4a 3208 #endif
sPymbed 0:1387ff3eed4a 3209
sPymbed 0:1387ff3eed4a 3210 if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY)
sPymbed 0:1387ff3eed4a 3211 return err;
sPymbed 0:1387ff3eed4a 3212
sPymbed 0:1387ff3eed4a 3213 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3214 err = mp_read_unsigned_bin(a, param, paramSz);
sPymbed 0:1387ff3eed4a 3215
sPymbed 0:1387ff3eed4a 3216 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3217 err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 3218
sPymbed 0:1387ff3eed4a 3219 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3220 if (mp_cmp(a, b) != MP_EQ) {
sPymbed 0:1387ff3eed4a 3221 err = -1;
sPymbed 0:1387ff3eed4a 3222 } else {
sPymbed 0:1387ff3eed4a 3223 err = MP_EQ;
sPymbed 0:1387ff3eed4a 3224 }
sPymbed 0:1387ff3eed4a 3225 }
sPymbed 0:1387ff3eed4a 3226
sPymbed 0:1387ff3eed4a 3227 mp_clear(a);
sPymbed 0:1387ff3eed4a 3228 mp_clear(b);
sPymbed 0:1387ff3eed4a 3229 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 3230 XFREE(b, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 3231 XFREE(a, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 3232 #endif
sPymbed 0:1387ff3eed4a 3233
sPymbed 0:1387ff3eed4a 3234 return err;
sPymbed 0:1387ff3eed4a 3235 }
sPymbed 0:1387ff3eed4a 3236
sPymbed 0:1387ff3eed4a 3237 /* Returns the curve id in ecc_sets[] that corresponds to a given set of
sPymbed 0:1387ff3eed4a 3238 * curve parameters.
sPymbed 0:1387ff3eed4a 3239 *
sPymbed 0:1387ff3eed4a 3240 * fieldSize the field size in bits
sPymbed 0:1387ff3eed4a 3241 * prime prime of the finite field
sPymbed 0:1387ff3eed4a 3242 * primeSz size of prime in octets
sPymbed 0:1387ff3eed4a 3243 * Af first coefficient a of the curve
sPymbed 0:1387ff3eed4a 3244 * AfSz size of Af in octets
sPymbed 0:1387ff3eed4a 3245 * Bf second coefficient b of the curve
sPymbed 0:1387ff3eed4a 3246 * BfSz size of Bf in octets
sPymbed 0:1387ff3eed4a 3247 * order curve order
sPymbed 0:1387ff3eed4a 3248 * orderSz size of curve in octets
sPymbed 0:1387ff3eed4a 3249 * Gx affine x coordinate of base point
sPymbed 0:1387ff3eed4a 3250 * GxSz size of Gx in octets
sPymbed 0:1387ff3eed4a 3251 * Gy affine y coordinate of base point
sPymbed 0:1387ff3eed4a 3252 * GySz size of Gy in octets
sPymbed 0:1387ff3eed4a 3253 * cofactor curve cofactor
sPymbed 0:1387ff3eed4a 3254 *
sPymbed 0:1387ff3eed4a 3255 * return curve id, from ecc_sets[] on success, negative on error
sPymbed 0:1387ff3eed4a 3256 */
sPymbed 0:1387ff3eed4a 3257 int wc_ecc_get_curve_id_from_params(int fieldSize,
sPymbed 0:1387ff3eed4a 3258 const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
sPymbed 0:1387ff3eed4a 3259 const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
sPymbed 0:1387ff3eed4a 3260 const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
sPymbed 0:1387ff3eed4a 3261 {
sPymbed 0:1387ff3eed4a 3262 int idx;
sPymbed 0:1387ff3eed4a 3263 int curveSz;
sPymbed 0:1387ff3eed4a 3264
sPymbed 0:1387ff3eed4a 3265 if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
sPymbed 0:1387ff3eed4a 3266 Gx == NULL || Gy == NULL)
sPymbed 0:1387ff3eed4a 3267 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3268
sPymbed 0:1387ff3eed4a 3269 curveSz = (fieldSize + 1) / 8; /* round up */
sPymbed 0:1387ff3eed4a 3270
sPymbed 0:1387ff3eed4a 3271 for (idx = 0; ecc_sets[idx].size != 0; idx++) {
sPymbed 0:1387ff3eed4a 3272 if (curveSz == ecc_sets[idx].size) {
sPymbed 0:1387ff3eed4a 3273 if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
sPymbed 0:1387ff3eed4a 3274 primeSz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3275 (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3276 (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3277 (wc_ecc_cmp_param(ecc_sets[idx].order, order,
sPymbed 0:1387ff3eed4a 3278 orderSz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3279 (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3280 (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz) == MP_EQ) &&
sPymbed 0:1387ff3eed4a 3281 (cofactor == ecc_sets[idx].cofactor)) {
sPymbed 0:1387ff3eed4a 3282 break;
sPymbed 0:1387ff3eed4a 3283 }
sPymbed 0:1387ff3eed4a 3284 }
sPymbed 0:1387ff3eed4a 3285 }
sPymbed 0:1387ff3eed4a 3286
sPymbed 0:1387ff3eed4a 3287 if (ecc_sets[idx].size == 0)
sPymbed 0:1387ff3eed4a 3288 return ECC_CURVE_INVALID;
sPymbed 0:1387ff3eed4a 3289
sPymbed 0:1387ff3eed4a 3290 return ecc_sets[idx].id;
sPymbed 0:1387ff3eed4a 3291 }
sPymbed 0:1387ff3eed4a 3292
sPymbed 0:1387ff3eed4a 3293
sPymbed 0:1387ff3eed4a 3294 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 3295 static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
sPymbed 0:1387ff3eed4a 3296 {
sPymbed 0:1387ff3eed4a 3297 if (key == NULL || mp == NULL)
sPymbed 0:1387ff3eed4a 3298 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3299 if (*mp == NULL) {
sPymbed 0:1387ff3eed4a 3300 *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
sPymbed 0:1387ff3eed4a 3301 if (*mp == NULL) {
sPymbed 0:1387ff3eed4a 3302 return MEMORY_E;
sPymbed 0:1387ff3eed4a 3303 }
sPymbed 0:1387ff3eed4a 3304 XMEMSET(*mp, 0, sizeof(mp_int));
sPymbed 0:1387ff3eed4a 3305 }
sPymbed 0:1387ff3eed4a 3306 return 0;
sPymbed 0:1387ff3eed4a 3307 }
sPymbed 0:1387ff3eed4a 3308 static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
sPymbed 0:1387ff3eed4a 3309 {
sPymbed 0:1387ff3eed4a 3310 if (key && mp && *mp) {
sPymbed 0:1387ff3eed4a 3311 mp_clear(*mp);
sPymbed 0:1387ff3eed4a 3312 XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
sPymbed 0:1387ff3eed4a 3313 *mp = NULL;
sPymbed 0:1387ff3eed4a 3314 }
sPymbed 0:1387ff3eed4a 3315 }
sPymbed 0:1387ff3eed4a 3316
sPymbed 0:1387ff3eed4a 3317 static int wc_ecc_alloc_async(ecc_key* key)
sPymbed 0:1387ff3eed4a 3318 {
sPymbed 0:1387ff3eed4a 3319 int err = wc_ecc_alloc_mpint(key, &key->r);
sPymbed 0:1387ff3eed4a 3320 if (err == 0)
sPymbed 0:1387ff3eed4a 3321 err = wc_ecc_alloc_mpint(key, &key->s);
sPymbed 0:1387ff3eed4a 3322 return err;
sPymbed 0:1387ff3eed4a 3323 }
sPymbed 0:1387ff3eed4a 3324
sPymbed 0:1387ff3eed4a 3325 static void wc_ecc_free_async(ecc_key* key)
sPymbed 0:1387ff3eed4a 3326 {
sPymbed 0:1387ff3eed4a 3327 wc_ecc_free_mpint(key, &key->r);
sPymbed 0:1387ff3eed4a 3328 wc_ecc_free_mpint(key, &key->s);
sPymbed 0:1387ff3eed4a 3329 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 3330 wc_ecc_free_mpint(key, &key->e);
sPymbed 0:1387ff3eed4a 3331 wc_ecc_free_mpint(key, &key->signK);
sPymbed 0:1387ff3eed4a 3332 #endif /* HAVE_CAVIUM_V */
sPymbed 0:1387ff3eed4a 3333 }
sPymbed 0:1387ff3eed4a 3334 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 3335
sPymbed 0:1387ff3eed4a 3336
sPymbed 0:1387ff3eed4a 3337 #ifdef HAVE_ECC_DHE
sPymbed 0:1387ff3eed4a 3338 /**
sPymbed 0:1387ff3eed4a 3339 Create an ECC shared secret between two keys
sPymbed 0:1387ff3eed4a 3340 private_key The private ECC key (heap hint based off of private key)
sPymbed 0:1387ff3eed4a 3341 public_key The public key
sPymbed 0:1387ff3eed4a 3342 out [out] Destination of the shared secret
sPymbed 0:1387ff3eed4a 3343 Conforms to EC-DH from ANSI X9.63
sPymbed 0:1387ff3eed4a 3344 outlen [in/out] The max size and resulting size of the shared secret
sPymbed 0:1387ff3eed4a 3345 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 3346 */
sPymbed 0:1387ff3eed4a 3347 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
sPymbed 0:1387ff3eed4a 3348 word32* outlen)
sPymbed 0:1387ff3eed4a 3349 {
sPymbed 0:1387ff3eed4a 3350 int err;
sPymbed 0:1387ff3eed4a 3351
sPymbed 0:1387ff3eed4a 3352 if (private_key == NULL || public_key == NULL || out == NULL ||
sPymbed 0:1387ff3eed4a 3353 outlen == NULL) {
sPymbed 0:1387ff3eed4a 3354 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3355 }
sPymbed 0:1387ff3eed4a 3356
sPymbed 0:1387ff3eed4a 3357 #ifdef WOLF_CRYPTO_DEV
sPymbed 0:1387ff3eed4a 3358 if (private_key->devId != INVALID_DEVID) {
sPymbed 0:1387ff3eed4a 3359 err = wc_CryptoDev_Ecdh(private_key, public_key, out, outlen);
sPymbed 0:1387ff3eed4a 3360 if (err != NOT_COMPILED_IN)
sPymbed 0:1387ff3eed4a 3361 return err;
sPymbed 0:1387ff3eed4a 3362 }
sPymbed 0:1387ff3eed4a 3363 #endif
sPymbed 0:1387ff3eed4a 3364
sPymbed 0:1387ff3eed4a 3365 /* type valid? */
sPymbed 0:1387ff3eed4a 3366 if (private_key->type != ECC_PRIVATEKEY &&
sPymbed 0:1387ff3eed4a 3367 private_key->type != ECC_PRIVATEKEY_ONLY) {
sPymbed 0:1387ff3eed4a 3368 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3369 }
sPymbed 0:1387ff3eed4a 3370
sPymbed 0:1387ff3eed4a 3371 /* Verify domain params supplied */
sPymbed 0:1387ff3eed4a 3372 if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
sPymbed 0:1387ff3eed4a 3373 wc_ecc_is_valid_idx(public_key->idx) == 0) {
sPymbed 0:1387ff3eed4a 3374 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3375 }
sPymbed 0:1387ff3eed4a 3376
sPymbed 0:1387ff3eed4a 3377 /* Verify curve id matches */
sPymbed 0:1387ff3eed4a 3378 if (private_key->dp->id != public_key->dp->id) {
sPymbed 0:1387ff3eed4a 3379 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3380 }
sPymbed 0:1387ff3eed4a 3381
sPymbed 0:1387ff3eed4a 3382 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3383 err = atcatls_ecdh(private_key->slot, public_key->pubkey_raw, out);
sPymbed 0:1387ff3eed4a 3384 if (err != ATCA_SUCCESS) {
sPymbed 0:1387ff3eed4a 3385 err = BAD_COND_E;
sPymbed 0:1387ff3eed4a 3386 }
sPymbed 0:1387ff3eed4a 3387 *outlen = private_key->dp->size;
sPymbed 0:1387ff3eed4a 3388 #else
sPymbed 0:1387ff3eed4a 3389 err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
sPymbed 0:1387ff3eed4a 3390 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 3391
sPymbed 0:1387ff3eed4a 3392 return err;
sPymbed 0:1387ff3eed4a 3393 }
sPymbed 0:1387ff3eed4a 3394
sPymbed 0:1387ff3eed4a 3395
sPymbed 0:1387ff3eed4a 3396 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3397
sPymbed 0:1387ff3eed4a 3398 static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
sPymbed 0:1387ff3eed4a 3399 byte* out, word32* outlen, ecc_curve_spec* curve)
sPymbed 0:1387ff3eed4a 3400 {
sPymbed 0:1387ff3eed4a 3401 int err;
sPymbed 0:1387ff3eed4a 3402 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3403 ecc_point* result = NULL;
sPymbed 0:1387ff3eed4a 3404 word32 x = 0;
sPymbed 0:1387ff3eed4a 3405 #endif
sPymbed 0:1387ff3eed4a 3406 mp_int* k = &private_key->k;
sPymbed 0:1387ff3eed4a 3407 #ifdef HAVE_ECC_CDH
sPymbed 0:1387ff3eed4a 3408 mp_int k_lcl;
sPymbed 0:1387ff3eed4a 3409
sPymbed 0:1387ff3eed4a 3410 /* if cofactor flag has been set */
sPymbed 0:1387ff3eed4a 3411 if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
sPymbed 0:1387ff3eed4a 3412 mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
sPymbed 0:1387ff3eed4a 3413 /* only perform cofactor calc if not equal to 1 */
sPymbed 0:1387ff3eed4a 3414 if (cofactor != 1) {
sPymbed 0:1387ff3eed4a 3415 k = &k_lcl;
sPymbed 0:1387ff3eed4a 3416 if (mp_init(k) != MP_OKAY)
sPymbed 0:1387ff3eed4a 3417 return MEMORY_E;
sPymbed 0:1387ff3eed4a 3418 /* multiply cofactor times private key "k" */
sPymbed 0:1387ff3eed4a 3419 err = mp_mul_d(&private_key->k, cofactor, k);
sPymbed 0:1387ff3eed4a 3420 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 3421 mp_clear(k);
sPymbed 0:1387ff3eed4a 3422 return err;
sPymbed 0:1387ff3eed4a 3423 }
sPymbed 0:1387ff3eed4a 3424 }
sPymbed 0:1387ff3eed4a 3425 }
sPymbed 0:1387ff3eed4a 3426 #endif
sPymbed 0:1387ff3eed4a 3427
sPymbed 0:1387ff3eed4a 3428 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 3429 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 3430 if (private_key->idx != ECC_CUSTOM_IDX &&
sPymbed 0:1387ff3eed4a 3431 ecc_sets[private_key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 3432 err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
sPymbed 0:1387ff3eed4a 3433 }
sPymbed 0:1387ff3eed4a 3434 else
sPymbed 0:1387ff3eed4a 3435 #endif
sPymbed 0:1387ff3eed4a 3436 #endif
sPymbed 0:1387ff3eed4a 3437 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3438 {
sPymbed 0:1387ff3eed4a 3439 err = WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 3440
sPymbed 0:1387ff3eed4a 3441 (void)curve;
sPymbed 0:1387ff3eed4a 3442 }
sPymbed 0:1387ff3eed4a 3443 #else
sPymbed 0:1387ff3eed4a 3444 {
sPymbed 0:1387ff3eed4a 3445 /* make new point */
sPymbed 0:1387ff3eed4a 3446 result = wc_ecc_new_point_h(private_key->heap);
sPymbed 0:1387ff3eed4a 3447 if (result == NULL) {
sPymbed 0:1387ff3eed4a 3448 #ifdef HAVE_ECC_CDH
sPymbed 0:1387ff3eed4a 3449 if (k == &k_lcl)
sPymbed 0:1387ff3eed4a 3450 mp_clear(k);
sPymbed 0:1387ff3eed4a 3451 #endif
sPymbed 0:1387ff3eed4a 3452 return MEMORY_E;
sPymbed 0:1387ff3eed4a 3453 }
sPymbed 0:1387ff3eed4a 3454
sPymbed 0:1387ff3eed4a 3455 err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 1,
sPymbed 0:1387ff3eed4a 3456 private_key->heap);
sPymbed 0:1387ff3eed4a 3457 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3458 x = mp_unsigned_bin_size(curve->prime);
sPymbed 0:1387ff3eed4a 3459 if (*outlen < x) {
sPymbed 0:1387ff3eed4a 3460 err = BUFFER_E;
sPymbed 0:1387ff3eed4a 3461 }
sPymbed 0:1387ff3eed4a 3462 }
sPymbed 0:1387ff3eed4a 3463
sPymbed 0:1387ff3eed4a 3464 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3465 XMEMSET(out, 0, x);
sPymbed 0:1387ff3eed4a 3466 err = mp_to_unsigned_bin(result->x,out +
sPymbed 0:1387ff3eed4a 3467 (x - mp_unsigned_bin_size(result->x)));
sPymbed 0:1387ff3eed4a 3468 }
sPymbed 0:1387ff3eed4a 3469 *outlen = x;
sPymbed 0:1387ff3eed4a 3470
sPymbed 0:1387ff3eed4a 3471 wc_ecc_del_point_h(result, private_key->heap);
sPymbed 0:1387ff3eed4a 3472 }
sPymbed 0:1387ff3eed4a 3473 #endif
sPymbed 0:1387ff3eed4a 3474 #ifdef HAVE_ECC_CDH
sPymbed 0:1387ff3eed4a 3475 if (k == &k_lcl)
sPymbed 0:1387ff3eed4a 3476 mp_clear(k);
sPymbed 0:1387ff3eed4a 3477 #endif
sPymbed 0:1387ff3eed4a 3478
sPymbed 0:1387ff3eed4a 3479 return err;
sPymbed 0:1387ff3eed4a 3480 }
sPymbed 0:1387ff3eed4a 3481
sPymbed 0:1387ff3eed4a 3482 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 3483 static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
sPymbed 0:1387ff3eed4a 3484 ecc_point* point, byte* out, word32 *outlen,
sPymbed 0:1387ff3eed4a 3485 ecc_curve_spec* curve)
sPymbed 0:1387ff3eed4a 3486 {
sPymbed 0:1387ff3eed4a 3487 int err;
sPymbed 0:1387ff3eed4a 3488
sPymbed 0:1387ff3eed4a 3489 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
sPymbed 0:1387ff3eed4a 3490 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 3491 /* verify the curve is supported by hardware */
sPymbed 0:1387ff3eed4a 3492 if (NitroxEccIsCurveSupported(private_key))
sPymbed 0:1387ff3eed4a 3493 #endif
sPymbed 0:1387ff3eed4a 3494 {
sPymbed 0:1387ff3eed4a 3495 word32 keySz = private_key->dp->size;
sPymbed 0:1387ff3eed4a 3496
sPymbed 0:1387ff3eed4a 3497 /* sync public key x/y */
sPymbed 0:1387ff3eed4a 3498 err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz);
sPymbed 0:1387ff3eed4a 3499 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3500 err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
sPymbed 0:1387ff3eed4a 3501 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3502 err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
sPymbed 0:1387ff3eed4a 3503 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 3504 /* allocate buffer for output */
sPymbed 0:1387ff3eed4a 3505 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3506 err = wc_ecc_alloc_mpint(private_key, &private_key->e);
sPymbed 0:1387ff3eed4a 3507 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3508 err = wc_bigint_alloc(&private_key->e->raw,
sPymbed 0:1387ff3eed4a 3509 NitroxEccGetSize(private_key)*2);
sPymbed 0:1387ff3eed4a 3510 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3511 err = NitroxEcdh(private_key,
sPymbed 0:1387ff3eed4a 3512 &private_key->k.raw, &point->x->raw, &point->y->raw,
sPymbed 0:1387ff3eed4a 3513 private_key->e->raw.buf, &private_key->e->raw.len,
sPymbed 0:1387ff3eed4a 3514 &curve->prime->raw);
sPymbed 0:1387ff3eed4a 3515 #else
sPymbed 0:1387ff3eed4a 3516 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3517 err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
sPymbed 0:1387ff3eed4a 3518 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3519 err = IntelQaEcdh(&private_key->asyncDev,
sPymbed 0:1387ff3eed4a 3520 &private_key->k.raw, &point->x->raw, &point->y->raw,
sPymbed 0:1387ff3eed4a 3521 out, outlen,
sPymbed 0:1387ff3eed4a 3522 &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
sPymbed 0:1387ff3eed4a 3523 private_key->dp->cofactor);
sPymbed 0:1387ff3eed4a 3524 #endif
sPymbed 0:1387ff3eed4a 3525 return err;
sPymbed 0:1387ff3eed4a 3526 }
sPymbed 0:1387ff3eed4a 3527 #elif defined(WOLFSSL_ASYNC_CRYPT_TEST)
sPymbed 0:1387ff3eed4a 3528 if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) {
sPymbed 0:1387ff3eed4a 3529 WC_ASYNC_TEST* testDev = &private_key->asyncDev.test;
sPymbed 0:1387ff3eed4a 3530 testDev->eccSharedSec.private_key = private_key;
sPymbed 0:1387ff3eed4a 3531 testDev->eccSharedSec.public_point = point;
sPymbed 0:1387ff3eed4a 3532 testDev->eccSharedSec.out = out;
sPymbed 0:1387ff3eed4a 3533 testDev->eccSharedSec.outLen = outlen;
sPymbed 0:1387ff3eed4a 3534 return WC_PENDING_E;
sPymbed 0:1387ff3eed4a 3535 }
sPymbed 0:1387ff3eed4a 3536 #endif
sPymbed 0:1387ff3eed4a 3537
sPymbed 0:1387ff3eed4a 3538 /* use sync in other cases */
sPymbed 0:1387ff3eed4a 3539 err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve);
sPymbed 0:1387ff3eed4a 3540
sPymbed 0:1387ff3eed4a 3541 return err;
sPymbed 0:1387ff3eed4a 3542 }
sPymbed 0:1387ff3eed4a 3543 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 3544
sPymbed 0:1387ff3eed4a 3545 int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point,
sPymbed 0:1387ff3eed4a 3546 byte* out, word32 *outlen)
sPymbed 0:1387ff3eed4a 3547 {
sPymbed 0:1387ff3eed4a 3548 int err;
sPymbed 0:1387ff3eed4a 3549 DECLARE_CURVE_SPECS(curve, 2);
sPymbed 0:1387ff3eed4a 3550
sPymbed 0:1387ff3eed4a 3551 if (private_key == NULL || point == NULL || out == NULL ||
sPymbed 0:1387ff3eed4a 3552 outlen == NULL) {
sPymbed 0:1387ff3eed4a 3553 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3554 }
sPymbed 0:1387ff3eed4a 3555
sPymbed 0:1387ff3eed4a 3556 ALLOC_CURVE_SPECS(2);
sPymbed 0:1387ff3eed4a 3557
sPymbed 0:1387ff3eed4a 3558 /* load curve info */
sPymbed 0:1387ff3eed4a 3559 err = wc_ecc_curve_load(private_key->dp, &curve,
sPymbed 0:1387ff3eed4a 3560 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
sPymbed 0:1387ff3eed4a 3561 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 3562 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 3563 return err;
sPymbed 0:1387ff3eed4a 3564 }
sPymbed 0:1387ff3eed4a 3565
sPymbed 0:1387ff3eed4a 3566 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 3567 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 3568 err = wc_ecc_shared_secret_gen_async(private_key, point,
sPymbed 0:1387ff3eed4a 3569 out, outlen, curve);
sPymbed 0:1387ff3eed4a 3570 }
sPymbed 0:1387ff3eed4a 3571 else
sPymbed 0:1387ff3eed4a 3572 #endif
sPymbed 0:1387ff3eed4a 3573 {
sPymbed 0:1387ff3eed4a 3574 err = wc_ecc_shared_secret_gen_sync(private_key, point,
sPymbed 0:1387ff3eed4a 3575 out, outlen, curve);
sPymbed 0:1387ff3eed4a 3576 }
sPymbed 0:1387ff3eed4a 3577
sPymbed 0:1387ff3eed4a 3578 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 3579 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 3580
sPymbed 0:1387ff3eed4a 3581 return err;
sPymbed 0:1387ff3eed4a 3582 }
sPymbed 0:1387ff3eed4a 3583
sPymbed 0:1387ff3eed4a 3584 /**
sPymbed 0:1387ff3eed4a 3585 Create an ECC shared secret between private key and public point
sPymbed 0:1387ff3eed4a 3586 private_key The private ECC key (heap hint based on private key)
sPymbed 0:1387ff3eed4a 3587 point The point to use (public key)
sPymbed 0:1387ff3eed4a 3588 out [out] Destination of the shared secret
sPymbed 0:1387ff3eed4a 3589 Conforms to EC-DH from ANSI X9.63
sPymbed 0:1387ff3eed4a 3590 outlen [in/out] The max size and resulting size of the shared secret
sPymbed 0:1387ff3eed4a 3591 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 3592 */
sPymbed 0:1387ff3eed4a 3593 int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
sPymbed 0:1387ff3eed4a 3594 byte* out, word32 *outlen)
sPymbed 0:1387ff3eed4a 3595 {
sPymbed 0:1387ff3eed4a 3596 int err;
sPymbed 0:1387ff3eed4a 3597
sPymbed 0:1387ff3eed4a 3598 if (private_key == NULL || point == NULL || out == NULL ||
sPymbed 0:1387ff3eed4a 3599 outlen == NULL) {
sPymbed 0:1387ff3eed4a 3600 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3601 }
sPymbed 0:1387ff3eed4a 3602
sPymbed 0:1387ff3eed4a 3603 /* type valid? */
sPymbed 0:1387ff3eed4a 3604 if (private_key->type != ECC_PRIVATEKEY &&
sPymbed 0:1387ff3eed4a 3605 private_key->type != ECC_PRIVATEKEY_ONLY) {
sPymbed 0:1387ff3eed4a 3606 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3607 }
sPymbed 0:1387ff3eed4a 3608
sPymbed 0:1387ff3eed4a 3609 /* Verify domain params supplied */
sPymbed 0:1387ff3eed4a 3610 if (wc_ecc_is_valid_idx(private_key->idx) == 0)
sPymbed 0:1387ff3eed4a 3611 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 3612
sPymbed 0:1387ff3eed4a 3613 switch(private_key->state) {
sPymbed 0:1387ff3eed4a 3614 case ECC_STATE_NONE:
sPymbed 0:1387ff3eed4a 3615 case ECC_STATE_SHARED_SEC_GEN:
sPymbed 0:1387ff3eed4a 3616 private_key->state = ECC_STATE_SHARED_SEC_GEN;
sPymbed 0:1387ff3eed4a 3617
sPymbed 0:1387ff3eed4a 3618 err = wc_ecc_shared_secret_gen(private_key, point, out, outlen);
sPymbed 0:1387ff3eed4a 3619 if (err < 0) {
sPymbed 0:1387ff3eed4a 3620 break;
sPymbed 0:1387ff3eed4a 3621 }
sPymbed 0:1387ff3eed4a 3622 FALL_THROUGH;
sPymbed 0:1387ff3eed4a 3623
sPymbed 0:1387ff3eed4a 3624 case ECC_STATE_SHARED_SEC_RES:
sPymbed 0:1387ff3eed4a 3625 private_key->state = ECC_STATE_SHARED_SEC_RES;
sPymbed 0:1387ff3eed4a 3626 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 3627 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 3628 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 3629 /* verify the curve is supported by hardware */
sPymbed 0:1387ff3eed4a 3630 if (NitroxEccIsCurveSupported(private_key)) {
sPymbed 0:1387ff3eed4a 3631 /* copy output */
sPymbed 0:1387ff3eed4a 3632 *outlen = private_key->dp->size;
sPymbed 0:1387ff3eed4a 3633 XMEMCPY(out, private_key->e->raw.buf, *outlen);
sPymbed 0:1387ff3eed4a 3634 }
sPymbed 0:1387ff3eed4a 3635 #endif /* HAVE_CAVIUM_V */
sPymbed 0:1387ff3eed4a 3636 }
sPymbed 0:1387ff3eed4a 3637 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 3638 err = 0;
sPymbed 0:1387ff3eed4a 3639 break;
sPymbed 0:1387ff3eed4a 3640
sPymbed 0:1387ff3eed4a 3641 default:
sPymbed 0:1387ff3eed4a 3642 err = BAD_STATE_E;
sPymbed 0:1387ff3eed4a 3643 } /* switch */
sPymbed 0:1387ff3eed4a 3644
sPymbed 0:1387ff3eed4a 3645 /* if async pending then return and skip done cleanup below */
sPymbed 0:1387ff3eed4a 3646 if (err == WC_PENDING_E) {
sPymbed 0:1387ff3eed4a 3647 private_key->state++;
sPymbed 0:1387ff3eed4a 3648 return err;
sPymbed 0:1387ff3eed4a 3649 }
sPymbed 0:1387ff3eed4a 3650
sPymbed 0:1387ff3eed4a 3651 /* cleanup */
sPymbed 0:1387ff3eed4a 3652 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 3653 wc_ecc_free_async(private_key);
sPymbed 0:1387ff3eed4a 3654 #endif
sPymbed 0:1387ff3eed4a 3655 private_key->state = ECC_STATE_NONE;
sPymbed 0:1387ff3eed4a 3656
sPymbed 0:1387ff3eed4a 3657 return err;
sPymbed 0:1387ff3eed4a 3658 }
sPymbed 0:1387ff3eed4a 3659 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 3660 #endif /* HAVE_ECC_DHE */
sPymbed 0:1387ff3eed4a 3661
sPymbed 0:1387ff3eed4a 3662
sPymbed 0:1387ff3eed4a 3663 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3664 /* return 1 if point is at infinity, 0 if not, < 0 on error */
sPymbed 0:1387ff3eed4a 3665 int wc_ecc_point_is_at_infinity(ecc_point* p)
sPymbed 0:1387ff3eed4a 3666 {
sPymbed 0:1387ff3eed4a 3667 if (p == NULL)
sPymbed 0:1387ff3eed4a 3668 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3669
sPymbed 0:1387ff3eed4a 3670 if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0)
sPymbed 0:1387ff3eed4a 3671 return 1;
sPymbed 0:1387ff3eed4a 3672
sPymbed 0:1387ff3eed4a 3673 return 0;
sPymbed 0:1387ff3eed4a 3674 }
sPymbed 0:1387ff3eed4a 3675
sPymbed 0:1387ff3eed4a 3676 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3677 /* generate random and ensure its greater than 0 and less than order */
sPymbed 0:1387ff3eed4a 3678 static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
sPymbed 0:1387ff3eed4a 3679 {
sPymbed 0:1387ff3eed4a 3680 int err;
sPymbed 0:1387ff3eed4a 3681 DECLARE_VAR(buf, byte, ECC_MAXSIZE_GEN, rng->heap);
sPymbed 0:1387ff3eed4a 3682
sPymbed 0:1387ff3eed4a 3683 /*generate 8 extra bytes to mitigate bias from the modulo operation below*/
sPymbed 0:1387ff3eed4a 3684 /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/
sPymbed 0:1387ff3eed4a 3685 size += 8;
sPymbed 0:1387ff3eed4a 3686
sPymbed 0:1387ff3eed4a 3687 /* make up random string */
sPymbed 0:1387ff3eed4a 3688 err = wc_RNG_GenerateBlock(rng, buf, size);
sPymbed 0:1387ff3eed4a 3689
sPymbed 0:1387ff3eed4a 3690 /* load random buffer data into k */
sPymbed 0:1387ff3eed4a 3691 if (err == 0)
sPymbed 0:1387ff3eed4a 3692 err = mp_read_unsigned_bin(k, (byte*)buf, size);
sPymbed 0:1387ff3eed4a 3693
sPymbed 0:1387ff3eed4a 3694 /* the key should be smaller than the order of base point */
sPymbed 0:1387ff3eed4a 3695 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3696 if (mp_cmp(k, order) != MP_LT) {
sPymbed 0:1387ff3eed4a 3697 err = mp_mod(k, order, k);
sPymbed 0:1387ff3eed4a 3698 }
sPymbed 0:1387ff3eed4a 3699 }
sPymbed 0:1387ff3eed4a 3700
sPymbed 0:1387ff3eed4a 3701 /* quick sanity check to make sure we're not dealing with a 0 key */
sPymbed 0:1387ff3eed4a 3702 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3703 if (mp_iszero(k) == MP_YES)
sPymbed 0:1387ff3eed4a 3704 err = MP_ZERO_E;
sPymbed 0:1387ff3eed4a 3705 }
sPymbed 0:1387ff3eed4a 3706
sPymbed 0:1387ff3eed4a 3707 ForceZero(buf, ECC_MAXSIZE);
sPymbed 0:1387ff3eed4a 3708 FREE_VAR(buf, rng->heap);
sPymbed 0:1387ff3eed4a 3709
sPymbed 0:1387ff3eed4a 3710 return err;
sPymbed 0:1387ff3eed4a 3711 }
sPymbed 0:1387ff3eed4a 3712 #endif
sPymbed 0:1387ff3eed4a 3713 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 3714
sPymbed 0:1387ff3eed4a 3715 static WC_INLINE void wc_ecc_reset(ecc_key* key)
sPymbed 0:1387ff3eed4a 3716 {
sPymbed 0:1387ff3eed4a 3717 /* make sure required key variables are reset */
sPymbed 0:1387ff3eed4a 3718 key->state = ECC_STATE_NONE;
sPymbed 0:1387ff3eed4a 3719 }
sPymbed 0:1387ff3eed4a 3720
sPymbed 0:1387ff3eed4a 3721
sPymbed 0:1387ff3eed4a 3722 /* create the public ECC key from a private key
sPymbed 0:1387ff3eed4a 3723 *
sPymbed 0:1387ff3eed4a 3724 * key an initialized private key to generate public part from
sPymbed 0:1387ff3eed4a 3725 * curveIn [in]curve for key, can be NULL
sPymbed 0:1387ff3eed4a 3726 * pubOut [out]ecc_point holding the public key, if NULL then public key part
sPymbed 0:1387ff3eed4a 3727 * is cached in key instead.
sPymbed 0:1387ff3eed4a 3728 *
sPymbed 0:1387ff3eed4a 3729 * Note this function is local to the file because of the argument type
sPymbed 0:1387ff3eed4a 3730 * ecc_curve_spec. Having this argument allows for not having to load the
sPymbed 0:1387ff3eed4a 3731 * curve type multiple times when generating a key with wc_ecc_make_key().
sPymbed 0:1387ff3eed4a 3732 *
sPymbed 0:1387ff3eed4a 3733 * returns MP_OKAY on success
sPymbed 0:1387ff3eed4a 3734 */
sPymbed 0:1387ff3eed4a 3735 static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
sPymbed 0:1387ff3eed4a 3736 ecc_point* pubOut)
sPymbed 0:1387ff3eed4a 3737 {
sPymbed 0:1387ff3eed4a 3738 int err = MP_OKAY;
sPymbed 0:1387ff3eed4a 3739 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3740 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3741 ecc_point* base = NULL;
sPymbed 0:1387ff3eed4a 3742 #endif
sPymbed 0:1387ff3eed4a 3743 ecc_point* pub;
sPymbed 0:1387ff3eed4a 3744 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 3745 #endif
sPymbed 0:1387ff3eed4a 3746
sPymbed 0:1387ff3eed4a 3747 if (key == NULL) {
sPymbed 0:1387ff3eed4a 3748 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3749 }
sPymbed 0:1387ff3eed4a 3750
sPymbed 0:1387ff3eed4a 3751 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3752
sPymbed 0:1387ff3eed4a 3753 /* if ecc_point passed in then use it as output for public key point */
sPymbed 0:1387ff3eed4a 3754 if (pubOut != NULL) {
sPymbed 0:1387ff3eed4a 3755 pub = pubOut;
sPymbed 0:1387ff3eed4a 3756 }
sPymbed 0:1387ff3eed4a 3757 else {
sPymbed 0:1387ff3eed4a 3758 /* caching public key making it a ECC_PRIVATEKEY instead of
sPymbed 0:1387ff3eed4a 3759 ECC_PRIVATEKEY_ONLY */
sPymbed 0:1387ff3eed4a 3760 pub = &key->pubkey;
sPymbed 0:1387ff3eed4a 3761 key->type = ECC_PRIVATEKEY_ONLY;
sPymbed 0:1387ff3eed4a 3762 }
sPymbed 0:1387ff3eed4a 3763
sPymbed 0:1387ff3eed4a 3764 /* avoid loading the curve unless it is not passed in */
sPymbed 0:1387ff3eed4a 3765 if (curveIn != NULL) {
sPymbed 0:1387ff3eed4a 3766 curve = curveIn;
sPymbed 0:1387ff3eed4a 3767 }
sPymbed 0:1387ff3eed4a 3768 else {
sPymbed 0:1387ff3eed4a 3769 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 3770
sPymbed 0:1387ff3eed4a 3771 /* load curve info */
sPymbed 0:1387ff3eed4a 3772 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3773 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
sPymbed 0:1387ff3eed4a 3774 }
sPymbed 0:1387ff3eed4a 3775
sPymbed 0:1387ff3eed4a 3776 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3777 #ifndef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 3778 err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
sPymbed 0:1387ff3eed4a 3779 #else
sPymbed 0:1387ff3eed4a 3780 pub->x = (mp_int*)&pub->xyz[0];
sPymbed 0:1387ff3eed4a 3781 pub->y = (mp_int*)&pub->xyz[1];
sPymbed 0:1387ff3eed4a 3782 pub->z = (mp_int*)&pub->xyz[2];
sPymbed 0:1387ff3eed4a 3783 alt_fp_init(pub->x);
sPymbed 0:1387ff3eed4a 3784 alt_fp_init(pub->y);
sPymbed 0:1387ff3eed4a 3785 alt_fp_init(pub->z);
sPymbed 0:1387ff3eed4a 3786 #endif
sPymbed 0:1387ff3eed4a 3787 }
sPymbed 0:1387ff3eed4a 3788
sPymbed 0:1387ff3eed4a 3789
sPymbed 0:1387ff3eed4a 3790 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 3791 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 3792 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 3793 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3794 err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap);
sPymbed 0:1387ff3eed4a 3795 }
sPymbed 0:1387ff3eed4a 3796 else
sPymbed 0:1387ff3eed4a 3797 #endif
sPymbed 0:1387ff3eed4a 3798 #endif
sPymbed 0:1387ff3eed4a 3799 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3800 err = WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 3801 #else
sPymbed 0:1387ff3eed4a 3802 {
sPymbed 0:1387ff3eed4a 3803 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3804 base = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 3805 if (base == NULL)
sPymbed 0:1387ff3eed4a 3806 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 3807 }
sPymbed 0:1387ff3eed4a 3808 /* read in the x/y for this key */
sPymbed 0:1387ff3eed4a 3809 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3810 err = mp_copy(curve->Gx, base->x);
sPymbed 0:1387ff3eed4a 3811 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3812 err = mp_copy(curve->Gy, base->y);
sPymbed 0:1387ff3eed4a 3813 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3814 err = mp_set(base->z, 1);
sPymbed 0:1387ff3eed4a 3815
sPymbed 0:1387ff3eed4a 3816 /* make the public key */
sPymbed 0:1387ff3eed4a 3817 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 3818 err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime,
sPymbed 0:1387ff3eed4a 3819 1, key->heap);
sPymbed 0:1387ff3eed4a 3820 }
sPymbed 0:1387ff3eed4a 3821
sPymbed 0:1387ff3eed4a 3822 wc_ecc_del_point_h(base, key->heap);
sPymbed 0:1387ff3eed4a 3823 }
sPymbed 0:1387ff3eed4a 3824 #endif
sPymbed 0:1387ff3eed4a 3825
sPymbed 0:1387ff3eed4a 3826 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
sPymbed 0:1387ff3eed4a 3827 /* validate the public key, order * pubkey = point at infinity */
sPymbed 0:1387ff3eed4a 3828 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3829 err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime,
sPymbed 0:1387ff3eed4a 3830 curve->order);
sPymbed 0:1387ff3eed4a 3831 #endif /* WOLFSSL_VALIDATE_KEYGEN */
sPymbed 0:1387ff3eed4a 3832
sPymbed 0:1387ff3eed4a 3833 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 3834 /* clean up if failed */
sPymbed 0:1387ff3eed4a 3835 #ifndef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 3836 mp_clear(pub->x);
sPymbed 0:1387ff3eed4a 3837 mp_clear(pub->y);
sPymbed 0:1387ff3eed4a 3838 mp_clear(pub->z);
sPymbed 0:1387ff3eed4a 3839 #endif
sPymbed 0:1387ff3eed4a 3840 }
sPymbed 0:1387ff3eed4a 3841
sPymbed 0:1387ff3eed4a 3842 /* free up local curve */
sPymbed 0:1387ff3eed4a 3843 if (curveIn == NULL) {
sPymbed 0:1387ff3eed4a 3844 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 3845 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3846 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 3847 #endif
sPymbed 0:1387ff3eed4a 3848 }
sPymbed 0:1387ff3eed4a 3849
sPymbed 0:1387ff3eed4a 3850 #else
sPymbed 0:1387ff3eed4a 3851 (void)curveIn;
sPymbed 0:1387ff3eed4a 3852 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 3853
sPymbed 0:1387ff3eed4a 3854 /* change key state if public part is cached */
sPymbed 0:1387ff3eed4a 3855 if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
sPymbed 0:1387ff3eed4a 3856 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 3857 }
sPymbed 0:1387ff3eed4a 3858
sPymbed 0:1387ff3eed4a 3859 return err;
sPymbed 0:1387ff3eed4a 3860 }
sPymbed 0:1387ff3eed4a 3861
sPymbed 0:1387ff3eed4a 3862
sPymbed 0:1387ff3eed4a 3863 /* create the public ECC key from a private key
sPymbed 0:1387ff3eed4a 3864 *
sPymbed 0:1387ff3eed4a 3865 * key an initialized private key to generate public part from
sPymbed 0:1387ff3eed4a 3866 * pubOut [out]ecc_point holding the public key, if NULL then public key part
sPymbed 0:1387ff3eed4a 3867 * is cached in key instead.
sPymbed 0:1387ff3eed4a 3868 *
sPymbed 0:1387ff3eed4a 3869 *
sPymbed 0:1387ff3eed4a 3870 * returns MP_OKAY on success
sPymbed 0:1387ff3eed4a 3871 */
sPymbed 0:1387ff3eed4a 3872 int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
sPymbed 0:1387ff3eed4a 3873 {
sPymbed 0:1387ff3eed4a 3874 WOLFSSL_ENTER("wc_ecc_make_pub");
sPymbed 0:1387ff3eed4a 3875
sPymbed 0:1387ff3eed4a 3876 return wc_ecc_make_pub_ex(key, NULL, pubOut);
sPymbed 0:1387ff3eed4a 3877 }
sPymbed 0:1387ff3eed4a 3878
sPymbed 0:1387ff3eed4a 3879
sPymbed 0:1387ff3eed4a 3880 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
sPymbed 0:1387ff3eed4a 3881 {
sPymbed 0:1387ff3eed4a 3882 int err;
sPymbed 0:1387ff3eed4a 3883 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3884 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3885 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 3886 #endif
sPymbed 0:1387ff3eed4a 3887 #endif
sPymbed 0:1387ff3eed4a 3888
sPymbed 0:1387ff3eed4a 3889 if (key == NULL || rng == NULL) {
sPymbed 0:1387ff3eed4a 3890 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 3891 }
sPymbed 0:1387ff3eed4a 3892
sPymbed 0:1387ff3eed4a 3893 /* make sure required variables are reset */
sPymbed 0:1387ff3eed4a 3894 wc_ecc_reset(key);
sPymbed 0:1387ff3eed4a 3895
sPymbed 0:1387ff3eed4a 3896 err = wc_ecc_set_curve(key, keysize, curve_id);
sPymbed 0:1387ff3eed4a 3897 if (err != 0) {
sPymbed 0:1387ff3eed4a 3898 return err;
sPymbed 0:1387ff3eed4a 3899 }
sPymbed 0:1387ff3eed4a 3900
sPymbed 0:1387ff3eed4a 3901 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 3902 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 3903 #ifdef HAVE_CAVIUM
sPymbed 0:1387ff3eed4a 3904 /* TODO: Not implemented */
sPymbed 0:1387ff3eed4a 3905 #elif defined(HAVE_INTEL_QA)
sPymbed 0:1387ff3eed4a 3906 /* TODO: Not implemented */
sPymbed 0:1387ff3eed4a 3907 #else
sPymbed 0:1387ff3eed4a 3908 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) {
sPymbed 0:1387ff3eed4a 3909 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
sPymbed 0:1387ff3eed4a 3910 testDev->eccMake.rng = rng;
sPymbed 0:1387ff3eed4a 3911 testDev->eccMake.key = key;
sPymbed 0:1387ff3eed4a 3912 testDev->eccMake.size = keysize;
sPymbed 0:1387ff3eed4a 3913 testDev->eccMake.curve_id = curve_id;
sPymbed 0:1387ff3eed4a 3914 return WC_PENDING_E;
sPymbed 0:1387ff3eed4a 3915 }
sPymbed 0:1387ff3eed4a 3916 #endif
sPymbed 0:1387ff3eed4a 3917 }
sPymbed 0:1387ff3eed4a 3918 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 3919
sPymbed 0:1387ff3eed4a 3920 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3921 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 3922 err = atcatls_create_key(key->slot, key->pubkey_raw);
sPymbed 0:1387ff3eed4a 3923 if (err != ATCA_SUCCESS) {
sPymbed 0:1387ff3eed4a 3924 err = BAD_COND_E;
sPymbed 0:1387ff3eed4a 3925 }
sPymbed 0:1387ff3eed4a 3926
sPymbed 0:1387ff3eed4a 3927 /* populate key->pubkey */
sPymbed 0:1387ff3eed4a 3928 err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
sPymbed 0:1387ff3eed4a 3929 ECC_MAX_CRYPTO_HW_SIZE);
sPymbed 0:1387ff3eed4a 3930 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3931 err = mp_read_unsigned_bin(key->pubkey.y,
sPymbed 0:1387ff3eed4a 3932 key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE,
sPymbed 0:1387ff3eed4a 3933 ECC_MAX_CRYPTO_HW_SIZE);
sPymbed 0:1387ff3eed4a 3934 #else
sPymbed 0:1387ff3eed4a 3935
sPymbed 0:1387ff3eed4a 3936 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 3937 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 3938 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 3939 err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap);
sPymbed 0:1387ff3eed4a 3940 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3941 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 3942 }
sPymbed 0:1387ff3eed4a 3943 else
sPymbed 0:1387ff3eed4a 3944 #endif
sPymbed 0:1387ff3eed4a 3945 #endif
sPymbed 0:1387ff3eed4a 3946 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 3947 err = WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 3948 #else
sPymbed 0:1387ff3eed4a 3949 {
sPymbed 0:1387ff3eed4a 3950 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 3951
sPymbed 0:1387ff3eed4a 3952 /* setup the key variables */
sPymbed 0:1387ff3eed4a 3953 err = mp_init(&key->k);
sPymbed 0:1387ff3eed4a 3954
sPymbed 0:1387ff3eed4a 3955 /* load curve info */
sPymbed 0:1387ff3eed4a 3956 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3957 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
sPymbed 0:1387ff3eed4a 3958
sPymbed 0:1387ff3eed4a 3959 /* generate k */
sPymbed 0:1387ff3eed4a 3960 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3961 err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order);
sPymbed 0:1387ff3eed4a 3962
sPymbed 0:1387ff3eed4a 3963 /* generate public key from k */
sPymbed 0:1387ff3eed4a 3964 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3965 err = wc_ecc_make_pub_ex(key, curve, NULL);
sPymbed 0:1387ff3eed4a 3966
sPymbed 0:1387ff3eed4a 3967 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 3968 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 3969
sPymbed 0:1387ff3eed4a 3970 /* cleanup these on failure case only */
sPymbed 0:1387ff3eed4a 3971 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 3972 /* clean up */
sPymbed 0:1387ff3eed4a 3973 mp_forcezero(&key->k);
sPymbed 0:1387ff3eed4a 3974 }
sPymbed 0:1387ff3eed4a 3975
sPymbed 0:1387ff3eed4a 3976 /* cleanup allocations */
sPymbed 0:1387ff3eed4a 3977 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 3978 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 3979 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 3980 #endif
sPymbed 0:1387ff3eed4a 3981 }
sPymbed 0:1387ff3eed4a 3982 #endif
sPymbed 0:1387ff3eed4a 3983
sPymbed 0:1387ff3eed4a 3984 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 3985
sPymbed 0:1387ff3eed4a 3986 return err;
sPymbed 0:1387ff3eed4a 3987 }
sPymbed 0:1387ff3eed4a 3988
sPymbed 0:1387ff3eed4a 3989 #ifdef ECC_DUMP_OID
sPymbed 0:1387ff3eed4a 3990 /* Optional dump of encoded OID for adding new curves */
sPymbed 0:1387ff3eed4a 3991 static int mOidDumpDone;
sPymbed 0:1387ff3eed4a 3992 static void wc_ecc_dump_oids(void)
sPymbed 0:1387ff3eed4a 3993 {
sPymbed 0:1387ff3eed4a 3994 int x;
sPymbed 0:1387ff3eed4a 3995
sPymbed 0:1387ff3eed4a 3996 if (mOidDumpDone) {
sPymbed 0:1387ff3eed4a 3997 return;
sPymbed 0:1387ff3eed4a 3998 }
sPymbed 0:1387ff3eed4a 3999
sPymbed 0:1387ff3eed4a 4000 /* find matching OID sum (based on encoded value) */
sPymbed 0:1387ff3eed4a 4001 for (x = 0; ecc_sets[x].size != 0; x++) {
sPymbed 0:1387ff3eed4a 4002 int i;
sPymbed 0:1387ff3eed4a 4003 byte* oid;
sPymbed 0:1387ff3eed4a 4004 word32 oidSz, sum = 0;
sPymbed 0:1387ff3eed4a 4005
sPymbed 0:1387ff3eed4a 4006 printf("ECC %s (%d):\n", ecc_sets[x].name, x);
sPymbed 0:1387ff3eed4a 4007
sPymbed 0:1387ff3eed4a 4008 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 4009 byte oidEnc[ECC_MAX_OID_LEN];
sPymbed 0:1387ff3eed4a 4010
sPymbed 0:1387ff3eed4a 4011 oid = oidEnc;
sPymbed 0:1387ff3eed4a 4012 oidSz = ECC_MAX_OID_LEN;
sPymbed 0:1387ff3eed4a 4013
sPymbed 0:1387ff3eed4a 4014 printf("OID: ");
sPymbed 0:1387ff3eed4a 4015 for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
sPymbed 0:1387ff3eed4a 4016 printf("%d.", ecc_sets[x].oid[i]);
sPymbed 0:1387ff3eed4a 4017 }
sPymbed 0:1387ff3eed4a 4018 printf("\n");
sPymbed 0:1387ff3eed4a 4019
sPymbed 0:1387ff3eed4a 4020 EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
sPymbed 0:1387ff3eed4a 4021 #else
sPymbed 0:1387ff3eed4a 4022 oid = (byte*)ecc_sets[x].oid;
sPymbed 0:1387ff3eed4a 4023 oidSz = ecc_sets[x].oidSz;
sPymbed 0:1387ff3eed4a 4024 #endif
sPymbed 0:1387ff3eed4a 4025
sPymbed 0:1387ff3eed4a 4026 printf("OID Encoded: ");
sPymbed 0:1387ff3eed4a 4027 for (i = 0; i < (int)oidSz; i++) {
sPymbed 0:1387ff3eed4a 4028 printf("0x%02X,", oid[i]);
sPymbed 0:1387ff3eed4a 4029 }
sPymbed 0:1387ff3eed4a 4030 printf("\n");
sPymbed 0:1387ff3eed4a 4031
sPymbed 0:1387ff3eed4a 4032 for (i = 0; i < (int)oidSz; i++) {
sPymbed 0:1387ff3eed4a 4033 sum += oid[i];
sPymbed 0:1387ff3eed4a 4034 }
sPymbed 0:1387ff3eed4a 4035 printf("Sum: %d\n", sum);
sPymbed 0:1387ff3eed4a 4036
sPymbed 0:1387ff3eed4a 4037 /* validate sum */
sPymbed 0:1387ff3eed4a 4038 if (ecc_sets[x].oidSum != sum) {
sPymbed 0:1387ff3eed4a 4039 printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum);
sPymbed 0:1387ff3eed4a 4040 }
sPymbed 0:1387ff3eed4a 4041 }
sPymbed 0:1387ff3eed4a 4042 mOidDumpDone = 1;
sPymbed 0:1387ff3eed4a 4043 }
sPymbed 0:1387ff3eed4a 4044 #endif /* ECC_DUMP_OID */
sPymbed 0:1387ff3eed4a 4045
sPymbed 0:1387ff3eed4a 4046 /**
sPymbed 0:1387ff3eed4a 4047 Make a new ECC key
sPymbed 0:1387ff3eed4a 4048 rng An active RNG state
sPymbed 0:1387ff3eed4a 4049 keysize The keysize for the new key (in octets from 20 to 65 bytes)
sPymbed 0:1387ff3eed4a 4050 key [out] Destination of the newly created key
sPymbed 0:1387ff3eed4a 4051 return MP_OKAY if successful,
sPymbed 0:1387ff3eed4a 4052 upon error all allocated memory will be freed
sPymbed 0:1387ff3eed4a 4053 */
sPymbed 0:1387ff3eed4a 4054 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
sPymbed 0:1387ff3eed4a 4055 {
sPymbed 0:1387ff3eed4a 4056 return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
sPymbed 0:1387ff3eed4a 4057 }
sPymbed 0:1387ff3eed4a 4058
sPymbed 0:1387ff3eed4a 4059 /* Setup dynamic pointers if using normal math for proper freeing */
sPymbed 0:1387ff3eed4a 4060 int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
sPymbed 0:1387ff3eed4a 4061 {
sPymbed 0:1387ff3eed4a 4062 int ret = 0;
sPymbed 0:1387ff3eed4a 4063
sPymbed 0:1387ff3eed4a 4064 if (key == NULL) {
sPymbed 0:1387ff3eed4a 4065 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 4066 }
sPymbed 0:1387ff3eed4a 4067
sPymbed 0:1387ff3eed4a 4068 #ifdef ECC_DUMP_OID
sPymbed 0:1387ff3eed4a 4069 wc_ecc_dump_oids();
sPymbed 0:1387ff3eed4a 4070 #endif
sPymbed 0:1387ff3eed4a 4071
sPymbed 0:1387ff3eed4a 4072 XMEMSET(key, 0, sizeof(ecc_key));
sPymbed 0:1387ff3eed4a 4073 key->state = ECC_STATE_NONE;
sPymbed 0:1387ff3eed4a 4074
sPymbed 0:1387ff3eed4a 4075 #if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV)
sPymbed 0:1387ff3eed4a 4076 key->devId = devId;
sPymbed 0:1387ff3eed4a 4077 #else
sPymbed 0:1387ff3eed4a 4078 (void)devId;
sPymbed 0:1387ff3eed4a 4079 #endif
sPymbed 0:1387ff3eed4a 4080
sPymbed 0:1387ff3eed4a 4081 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 4082 key->slot = atmel_ecc_alloc();
sPymbed 0:1387ff3eed4a 4083 if (key->slot == ATECC_INVALID_SLOT) {
sPymbed 0:1387ff3eed4a 4084 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4085 }
sPymbed 0:1387ff3eed4a 4086 #else
sPymbed 0:1387ff3eed4a 4087 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 4088 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
sPymbed 0:1387ff3eed4a 4089 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
sPymbed 0:1387ff3eed4a 4090 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
sPymbed 0:1387ff3eed4a 4091 alt_fp_init(key->pubkey.x);
sPymbed 0:1387ff3eed4a 4092 alt_fp_init(key->pubkey.y);
sPymbed 0:1387ff3eed4a 4093 alt_fp_init(key->pubkey.z);
sPymbed 0:1387ff3eed4a 4094 ret = mp_init(&key->k);
sPymbed 0:1387ff3eed4a 4095 #else
sPymbed 0:1387ff3eed4a 4096 ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
sPymbed 0:1387ff3eed4a 4097 NULL, NULL);
sPymbed 0:1387ff3eed4a 4098 #endif /* ALT_ECC_SIZE */
sPymbed 0:1387ff3eed4a 4099 if (ret != MP_OKAY) {
sPymbed 0:1387ff3eed4a 4100 return MEMORY_E;
sPymbed 0:1387ff3eed4a 4101 }
sPymbed 0:1387ff3eed4a 4102 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 4103
sPymbed 0:1387ff3eed4a 4104 #ifdef WOLFSSL_HEAP_TEST
sPymbed 0:1387ff3eed4a 4105 key->heap = (void*)WOLFSSL_HEAP_TEST;
sPymbed 0:1387ff3eed4a 4106 #else
sPymbed 0:1387ff3eed4a 4107 key->heap = heap;
sPymbed 0:1387ff3eed4a 4108 #endif
sPymbed 0:1387ff3eed4a 4109
sPymbed 0:1387ff3eed4a 4110 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 4111 /* handle as async */
sPymbed 0:1387ff3eed4a 4112 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
sPymbed 0:1387ff3eed4a 4113 key->heap, devId);
sPymbed 0:1387ff3eed4a 4114 #endif
sPymbed 0:1387ff3eed4a 4115
sPymbed 0:1387ff3eed4a 4116 return ret;
sPymbed 0:1387ff3eed4a 4117 }
sPymbed 0:1387ff3eed4a 4118
sPymbed 0:1387ff3eed4a 4119 int wc_ecc_init(ecc_key* key)
sPymbed 0:1387ff3eed4a 4120 {
sPymbed 0:1387ff3eed4a 4121 return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
sPymbed 0:1387ff3eed4a 4122 }
sPymbed 0:1387ff3eed4a 4123
sPymbed 0:1387ff3eed4a 4124 int wc_ecc_set_flags(ecc_key* key, word32 flags)
sPymbed 0:1387ff3eed4a 4125 {
sPymbed 0:1387ff3eed4a 4126 if (key == NULL) {
sPymbed 0:1387ff3eed4a 4127 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 4128 }
sPymbed 0:1387ff3eed4a 4129 key->flags |= flags;
sPymbed 0:1387ff3eed4a 4130 return 0;
sPymbed 0:1387ff3eed4a 4131 }
sPymbed 0:1387ff3eed4a 4132
sPymbed 0:1387ff3eed4a 4133 #ifdef HAVE_ECC_SIGN
sPymbed 0:1387ff3eed4a 4134
sPymbed 0:1387ff3eed4a 4135 #ifndef NO_ASN
sPymbed 0:1387ff3eed4a 4136
sPymbed 0:1387ff3eed4a 4137 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
sPymbed 0:1387ff3eed4a 4138 static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
sPymbed 0:1387ff3eed4a 4139 mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
sPymbed 0:1387ff3eed4a 4140 ecc_key* key)
sPymbed 0:1387ff3eed4a 4141 {
sPymbed 0:1387ff3eed4a 4142 int err;
sPymbed 0:1387ff3eed4a 4143
sPymbed 0:1387ff3eed4a 4144 #ifdef PLUTON_CRYPTO_ECC
sPymbed 0:1387ff3eed4a 4145 if (key->devId != INVALID_DEVID) /* use hardware */
sPymbed 0:1387ff3eed4a 4146 #endif
sPymbed 0:1387ff3eed4a 4147 {
sPymbed 0:1387ff3eed4a 4148 word32 keysize = (word32)key->dp->size;
sPymbed 0:1387ff3eed4a 4149
sPymbed 0:1387ff3eed4a 4150 /* Check args */
sPymbed 0:1387ff3eed4a 4151 if (keysize > ECC_MAX_CRYPTO_HW_SIZE || inlen != keysize ||
sPymbed 0:1387ff3eed4a 4152 *outlen < keysize*2) {
sPymbed 0:1387ff3eed4a 4153 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4154 }
sPymbed 0:1387ff3eed4a 4155
sPymbed 0:1387ff3eed4a 4156 #if defined(WOLFSSL_ATECC508A)
sPymbed 0:1387ff3eed4a 4157 /* Sign: Result is 32-bytes of R then 32-bytes of S */
sPymbed 0:1387ff3eed4a 4158 err = atcatls_sign(key->slot, in, out);
sPymbed 0:1387ff3eed4a 4159 if (err != ATCA_SUCCESS) {
sPymbed 0:1387ff3eed4a 4160 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 4161 }
sPymbed 0:1387ff3eed4a 4162 #elif defined(PLUTON_CRYPTO_ECC)
sPymbed 0:1387ff3eed4a 4163 {
sPymbed 0:1387ff3eed4a 4164 /* perform ECC sign */
sPymbed 0:1387ff3eed4a 4165 word32 raw_sig_size = *outlen;
sPymbed 0:1387ff3eed4a 4166 err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
sPymbed 0:1387ff3eed4a 4167 if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
sPymbed 0:1387ff3eed4a 4168 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 4169 }
sPymbed 0:1387ff3eed4a 4170 }
sPymbed 0:1387ff3eed4a 4171 #endif
sPymbed 0:1387ff3eed4a 4172
sPymbed 0:1387ff3eed4a 4173 /* Load R and S */
sPymbed 0:1387ff3eed4a 4174 err = mp_read_unsigned_bin(r, &out[0], keysize);
sPymbed 0:1387ff3eed4a 4175 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 4176 return err;
sPymbed 0:1387ff3eed4a 4177 }
sPymbed 0:1387ff3eed4a 4178 err = mp_read_unsigned_bin(s, &out[keysize], keysize);
sPymbed 0:1387ff3eed4a 4179 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 4180 return err;
sPymbed 0:1387ff3eed4a 4181 }
sPymbed 0:1387ff3eed4a 4182
sPymbed 0:1387ff3eed4a 4183 /* Check for zeros */
sPymbed 0:1387ff3eed4a 4184 if (mp_iszero(r) || mp_iszero(s)) {
sPymbed 0:1387ff3eed4a 4185 return MP_ZERO_E;
sPymbed 0:1387ff3eed4a 4186 }
sPymbed 0:1387ff3eed4a 4187 }
sPymbed 0:1387ff3eed4a 4188 #ifdef PLUTON_CRYPTO_ECC
sPymbed 0:1387ff3eed4a 4189 else {
sPymbed 0:1387ff3eed4a 4190 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
sPymbed 0:1387ff3eed4a 4191 }
sPymbed 0:1387ff3eed4a 4192 #endif
sPymbed 0:1387ff3eed4a 4193 (void)rng;
sPymbed 0:1387ff3eed4a 4194
sPymbed 0:1387ff3eed4a 4195 return err;
sPymbed 0:1387ff3eed4a 4196 }
sPymbed 0:1387ff3eed4a 4197 #endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */
sPymbed 0:1387ff3eed4a 4198
sPymbed 0:1387ff3eed4a 4199 /**
sPymbed 0:1387ff3eed4a 4200 Sign a message digest
sPymbed 0:1387ff3eed4a 4201 in The message digest to sign
sPymbed 0:1387ff3eed4a 4202 inlen The length of the digest
sPymbed 0:1387ff3eed4a 4203 out [out] The destination for the signature
sPymbed 0:1387ff3eed4a 4204 outlen [in/out] The max size and resulting size of the signature
sPymbed 0:1387ff3eed4a 4205 key A private ECC key
sPymbed 0:1387ff3eed4a 4206 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 4207 */
sPymbed 0:1387ff3eed4a 4208 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
sPymbed 0:1387ff3eed4a 4209 WC_RNG* rng, ecc_key* key)
sPymbed 0:1387ff3eed4a 4210 {
sPymbed 0:1387ff3eed4a 4211 int err;
sPymbed 0:1387ff3eed4a 4212 mp_int *r = NULL, *s = NULL;
sPymbed 0:1387ff3eed4a 4213 #if !defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 4214 mp_int r_lcl, s_lcl;
sPymbed 0:1387ff3eed4a 4215 #endif
sPymbed 0:1387ff3eed4a 4216
sPymbed 0:1387ff3eed4a 4217 if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
sPymbed 0:1387ff3eed4a 4218 rng == NULL) {
sPymbed 0:1387ff3eed4a 4219 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4220 }
sPymbed 0:1387ff3eed4a 4221
sPymbed 0:1387ff3eed4a 4222 #ifdef WOLF_CRYPTO_DEV
sPymbed 0:1387ff3eed4a 4223 if (key->devId != INVALID_DEVID) {
sPymbed 0:1387ff3eed4a 4224 err = wc_CryptoDev_EccSign(in, inlen, out, outlen, rng, key);
sPymbed 0:1387ff3eed4a 4225 if (err != NOT_COMPILED_IN)
sPymbed 0:1387ff3eed4a 4226 return err;
sPymbed 0:1387ff3eed4a 4227 }
sPymbed 0:1387ff3eed4a 4228 #endif
sPymbed 0:1387ff3eed4a 4229
sPymbed 0:1387ff3eed4a 4230 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 4231 err = wc_ecc_alloc_async(key);
sPymbed 0:1387ff3eed4a 4232 if (err != 0)
sPymbed 0:1387ff3eed4a 4233 return err;
sPymbed 0:1387ff3eed4a 4234 r = key->r;
sPymbed 0:1387ff3eed4a 4235 s = key->s;
sPymbed 0:1387ff3eed4a 4236 #elif !defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 4237 r = &r_lcl;
sPymbed 0:1387ff3eed4a 4238 s = &s_lcl;
sPymbed 0:1387ff3eed4a 4239 #else
sPymbed 0:1387ff3eed4a 4240 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4241 if (r == NULL)
sPymbed 0:1387ff3eed4a 4242 return MEMORY_E;
sPymbed 0:1387ff3eed4a 4243 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4244 if (s == NULL) {
sPymbed 0:1387ff3eed4a 4245 XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4246 return MEMORY_E;
sPymbed 0:1387ff3eed4a 4247 }
sPymbed 0:1387ff3eed4a 4248 #endif
sPymbed 0:1387ff3eed4a 4249
sPymbed 0:1387ff3eed4a 4250 switch(key->state) {
sPymbed 0:1387ff3eed4a 4251 case ECC_STATE_NONE:
sPymbed 0:1387ff3eed4a 4252 case ECC_STATE_SIGN_DO:
sPymbed 0:1387ff3eed4a 4253 key->state = ECC_STATE_SIGN_DO;
sPymbed 0:1387ff3eed4a 4254
sPymbed 0:1387ff3eed4a 4255 if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
sPymbed 0:1387ff3eed4a 4256 break;
sPymbed 0:1387ff3eed4a 4257 }
sPymbed 0:1387ff3eed4a 4258
sPymbed 0:1387ff3eed4a 4259 /* hardware crypto */
sPymbed 0:1387ff3eed4a 4260 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC)
sPymbed 0:1387ff3eed4a 4261 err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
sPymbed 0:1387ff3eed4a 4262 #else
sPymbed 0:1387ff3eed4a 4263 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
sPymbed 0:1387ff3eed4a 4264 #endif
sPymbed 0:1387ff3eed4a 4265 if (err < 0) {
sPymbed 0:1387ff3eed4a 4266 break;
sPymbed 0:1387ff3eed4a 4267 }
sPymbed 0:1387ff3eed4a 4268
sPymbed 0:1387ff3eed4a 4269 FALL_THROUGH;
sPymbed 0:1387ff3eed4a 4270
sPymbed 0:1387ff3eed4a 4271 case ECC_STATE_SIGN_ENCODE:
sPymbed 0:1387ff3eed4a 4272 key->state = ECC_STATE_SIGN_ENCODE;
sPymbed 0:1387ff3eed4a 4273
sPymbed 0:1387ff3eed4a 4274 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 4275 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 4276 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4277 /* Nitrox requires r and s in sep buffer, so split it */
sPymbed 0:1387ff3eed4a 4278 NitroxEccRsSplit(key, &r->raw, &s->raw);
sPymbed 0:1387ff3eed4a 4279 #endif
sPymbed 0:1387ff3eed4a 4280 #ifndef WOLFSSL_ASYNC_CRYPT_TEST
sPymbed 0:1387ff3eed4a 4281 /* only do this if not simulator, since it overwrites result */
sPymbed 0:1387ff3eed4a 4282 wc_bigint_to_mp(&r->raw, r);
sPymbed 0:1387ff3eed4a 4283 wc_bigint_to_mp(&s->raw, s);
sPymbed 0:1387ff3eed4a 4284 #endif
sPymbed 0:1387ff3eed4a 4285 }
sPymbed 0:1387ff3eed4a 4286 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 4287
sPymbed 0:1387ff3eed4a 4288 /* encoded with DSA header */
sPymbed 0:1387ff3eed4a 4289 err = StoreECC_DSA_Sig(out, outlen, r, s);
sPymbed 0:1387ff3eed4a 4290
sPymbed 0:1387ff3eed4a 4291 /* done with R/S */
sPymbed 0:1387ff3eed4a 4292 mp_clear(r);
sPymbed 0:1387ff3eed4a 4293 mp_clear(s);
sPymbed 0:1387ff3eed4a 4294 #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 4295 XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4296 XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4297 #endif
sPymbed 0:1387ff3eed4a 4298 break;
sPymbed 0:1387ff3eed4a 4299
sPymbed 0:1387ff3eed4a 4300 default:
sPymbed 0:1387ff3eed4a 4301 err = BAD_STATE_E;
sPymbed 0:1387ff3eed4a 4302 break;
sPymbed 0:1387ff3eed4a 4303 }
sPymbed 0:1387ff3eed4a 4304
sPymbed 0:1387ff3eed4a 4305 /* if async pending then return and skip done cleanup below */
sPymbed 0:1387ff3eed4a 4306 if (err == WC_PENDING_E) {
sPymbed 0:1387ff3eed4a 4307 key->state++;
sPymbed 0:1387ff3eed4a 4308 return err;
sPymbed 0:1387ff3eed4a 4309 }
sPymbed 0:1387ff3eed4a 4310
sPymbed 0:1387ff3eed4a 4311 /* cleanup */
sPymbed 0:1387ff3eed4a 4312 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 4313 wc_ecc_free_async(key);
sPymbed 0:1387ff3eed4a 4314 #endif
sPymbed 0:1387ff3eed4a 4315 key->state = ECC_STATE_NONE;
sPymbed 0:1387ff3eed4a 4316
sPymbed 0:1387ff3eed4a 4317 return err;
sPymbed 0:1387ff3eed4a 4318 }
sPymbed 0:1387ff3eed4a 4319 #endif /* !NO_ASN */
sPymbed 0:1387ff3eed4a 4320
sPymbed 0:1387ff3eed4a 4321 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 4322 /**
sPymbed 0:1387ff3eed4a 4323 Sign a message digest
sPymbed 0:1387ff3eed4a 4324 in The message digest to sign
sPymbed 0:1387ff3eed4a 4325 inlen The length of the digest
sPymbed 0:1387ff3eed4a 4326 key A private ECC key
sPymbed 0:1387ff3eed4a 4327 r [out] The destination for r component of the signature
sPymbed 0:1387ff3eed4a 4328 s [out] The destination for s component of the signature
sPymbed 0:1387ff3eed4a 4329 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 4330 */
sPymbed 0:1387ff3eed4a 4331 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
sPymbed 0:1387ff3eed4a 4332 ecc_key* key, mp_int *r, mp_int *s)
sPymbed 0:1387ff3eed4a 4333 {
sPymbed 0:1387ff3eed4a 4334 int err;
sPymbed 0:1387ff3eed4a 4335 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 4336 mp_int* e;
sPymbed 0:1387ff3eed4a 4337 #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \
sPymbed 0:1387ff3eed4a 4338 !defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 4339 mp_int e_lcl;
sPymbed 0:1387ff3eed4a 4340 #endif
sPymbed 0:1387ff3eed4a 4341 DECLARE_CURVE_SPECS(curve, 1);
sPymbed 0:1387ff3eed4a 4342 #endif /* !WOLFSSL_SP_MATH */
sPymbed 0:1387ff3eed4a 4343
sPymbed 0:1387ff3eed4a 4344 if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
sPymbed 0:1387ff3eed4a 4345 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4346
sPymbed 0:1387ff3eed4a 4347 /* is this a private key? */
sPymbed 0:1387ff3eed4a 4348 if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
sPymbed 0:1387ff3eed4a 4349 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4350 }
sPymbed 0:1387ff3eed4a 4351
sPymbed 0:1387ff3eed4a 4352 /* is the IDX valid ? */
sPymbed 0:1387ff3eed4a 4353 if (wc_ecc_is_valid_idx(key->idx) != 1) {
sPymbed 0:1387ff3eed4a 4354 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4355 }
sPymbed 0:1387ff3eed4a 4356
sPymbed 0:1387ff3eed4a 4357 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 4358 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
sPymbed 0:1387ff3eed4a 4359 return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
sPymbed 0:1387ff3eed4a 4360 else
sPymbed 0:1387ff3eed4a 4361 return WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 4362 #else
sPymbed 0:1387ff3eed4a 4363 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 4364 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
sPymbed 0:1387ff3eed4a 4365 defined(WOLFSSL_ASYNC_CRYPT_TEST)
sPymbed 0:1387ff3eed4a 4366 if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
sPymbed 0:1387ff3eed4a 4367 #endif
sPymbed 0:1387ff3eed4a 4368 {
sPymbed 0:1387ff3eed4a 4369 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 4370 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
sPymbed 0:1387ff3eed4a 4371 return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
sPymbed 0:1387ff3eed4a 4372 #endif
sPymbed 0:1387ff3eed4a 4373 }
sPymbed 0:1387ff3eed4a 4374 #endif /* WOLFSSL_HAVE_SP_ECC */
sPymbed 0:1387ff3eed4a 4375
sPymbed 0:1387ff3eed4a 4376
sPymbed 0:1387ff3eed4a 4377 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
sPymbed 0:1387ff3eed4a 4378 defined(WOLFSSL_ASYNC_CRYPT_TEST)
sPymbed 0:1387ff3eed4a 4379 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 4380 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) {
sPymbed 0:1387ff3eed4a 4381 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
sPymbed 0:1387ff3eed4a 4382 testDev->eccSign.in = in;
sPymbed 0:1387ff3eed4a 4383 testDev->eccSign.inSz = inlen;
sPymbed 0:1387ff3eed4a 4384 testDev->eccSign.rng = rng;
sPymbed 0:1387ff3eed4a 4385 testDev->eccSign.key = key;
sPymbed 0:1387ff3eed4a 4386 testDev->eccSign.r = r;
sPymbed 0:1387ff3eed4a 4387 testDev->eccSign.s = s;
sPymbed 0:1387ff3eed4a 4388 return WC_PENDING_E;
sPymbed 0:1387ff3eed4a 4389 }
sPymbed 0:1387ff3eed4a 4390 }
sPymbed 0:1387ff3eed4a 4391 #endif
sPymbed 0:1387ff3eed4a 4392
sPymbed 0:1387ff3eed4a 4393 ALLOC_CURVE_SPECS(1);
sPymbed 0:1387ff3eed4a 4394
sPymbed 0:1387ff3eed4a 4395 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
sPymbed 0:1387ff3eed4a 4396 err = wc_ecc_alloc_mpint(key, &key->e);
sPymbed 0:1387ff3eed4a 4397 if (err != 0) {
sPymbed 0:1387ff3eed4a 4398 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 4399 return err;
sPymbed 0:1387ff3eed4a 4400 }
sPymbed 0:1387ff3eed4a 4401 e = key->e;
sPymbed 0:1387ff3eed4a 4402 #elif !defined(WOLFSSL_SMALL_STACK)
sPymbed 0:1387ff3eed4a 4403 e = &e_lcl;
sPymbed 0:1387ff3eed4a 4404 #else
sPymbed 0:1387ff3eed4a 4405 e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4406 if (e == NULL) {
sPymbed 0:1387ff3eed4a 4407 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 4408 return MEMORY_E;
sPymbed 0:1387ff3eed4a 4409 }
sPymbed 0:1387ff3eed4a 4410 #endif
sPymbed 0:1387ff3eed4a 4411
sPymbed 0:1387ff3eed4a 4412 /* get the hash and load it as a bignum into 'e' */
sPymbed 0:1387ff3eed4a 4413 /* init the bignums */
sPymbed 0:1387ff3eed4a 4414 if ((err = mp_init(e)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 4415 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4416 XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4417 #endif
sPymbed 0:1387ff3eed4a 4418 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 4419 return err;
sPymbed 0:1387ff3eed4a 4420 }
sPymbed 0:1387ff3eed4a 4421
sPymbed 0:1387ff3eed4a 4422 /* load curve info */
sPymbed 0:1387ff3eed4a 4423 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
sPymbed 0:1387ff3eed4a 4424
sPymbed 0:1387ff3eed4a 4425 /* load digest into e */
sPymbed 0:1387ff3eed4a 4426 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4427 /* we may need to truncate if hash is longer than key size */
sPymbed 0:1387ff3eed4a 4428 word32 orderBits = mp_count_bits(curve->order);
sPymbed 0:1387ff3eed4a 4429
sPymbed 0:1387ff3eed4a 4430 /* truncate down to byte size, may be all that's needed */
sPymbed 0:1387ff3eed4a 4431 if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
sPymbed 0:1387ff3eed4a 4432 inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
sPymbed 0:1387ff3eed4a 4433 err = mp_read_unsigned_bin(e, (byte*)in, inlen);
sPymbed 0:1387ff3eed4a 4434
sPymbed 0:1387ff3eed4a 4435 /* may still need bit truncation too */
sPymbed 0:1387ff3eed4a 4436 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
sPymbed 0:1387ff3eed4a 4437 mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
sPymbed 0:1387ff3eed4a 4438 }
sPymbed 0:1387ff3eed4a 4439
sPymbed 0:1387ff3eed4a 4440 /* make up a key and export the public copy */
sPymbed 0:1387ff3eed4a 4441 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4442 int loop_check = 0;
sPymbed 0:1387ff3eed4a 4443 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4444 ecc_key* pubkey = NULL;
sPymbed 0:1387ff3eed4a 4445 #else
sPymbed 0:1387ff3eed4a 4446 ecc_key pubkey[1];
sPymbed 0:1387ff3eed4a 4447 #endif
sPymbed 0:1387ff3eed4a 4448
sPymbed 0:1387ff3eed4a 4449 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 4450 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 4451 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
sPymbed 0:1387ff3eed4a 4452 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4453 if (NitroxEccIsCurveSupported(key))
sPymbed 0:1387ff3eed4a 4454 #endif
sPymbed 0:1387ff3eed4a 4455 {
sPymbed 0:1387ff3eed4a 4456 word32 keySz = key->dp->size;
sPymbed 0:1387ff3eed4a 4457 mp_int* k;
sPymbed 0:1387ff3eed4a 4458 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4459 err = wc_ecc_alloc_mpint(key, &key->signK);
sPymbed 0:1387ff3eed4a 4460 if (err != 0)
sPymbed 0:1387ff3eed4a 4461 return err;
sPymbed 0:1387ff3eed4a 4462 k = key->signK;
sPymbed 0:1387ff3eed4a 4463 #else
sPymbed 0:1387ff3eed4a 4464 mp_int k_lcl;
sPymbed 0:1387ff3eed4a 4465 k = &k_lcl;
sPymbed 0:1387ff3eed4a 4466 #endif
sPymbed 0:1387ff3eed4a 4467
sPymbed 0:1387ff3eed4a 4468 err = mp_init(k);
sPymbed 0:1387ff3eed4a 4469
sPymbed 0:1387ff3eed4a 4470 /* make sure r and s are allocated */
sPymbed 0:1387ff3eed4a 4471 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4472 /* Nitrox V needs single buffer for R and S */
sPymbed 0:1387ff3eed4a 4473 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4474 err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
sPymbed 0:1387ff3eed4a 4475 /* Nitrox V only needs Prime and Order */
sPymbed 0:1387ff3eed4a 4476 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4477 err = wc_ecc_curve_load(key->dp, &curve,
sPymbed 0:1387ff3eed4a 4478 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
sPymbed 0:1387ff3eed4a 4479 #else
sPymbed 0:1387ff3eed4a 4480 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4481 err = wc_bigint_alloc(&key->r->raw, key->dp->size);
sPymbed 0:1387ff3eed4a 4482 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4483 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
sPymbed 0:1387ff3eed4a 4484 #endif
sPymbed 0:1387ff3eed4a 4485 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4486 err = wc_bigint_alloc(&key->s->raw, key->dp->size);
sPymbed 0:1387ff3eed4a 4487
sPymbed 0:1387ff3eed4a 4488 /* load e and k */
sPymbed 0:1387ff3eed4a 4489 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4490 err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
sPymbed 0:1387ff3eed4a 4491 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4492 err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz);
sPymbed 0:1387ff3eed4a 4493 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4494 err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
sPymbed 0:1387ff3eed4a 4495 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4496 err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
sPymbed 0:1387ff3eed4a 4497
sPymbed 0:1387ff3eed4a 4498 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4499 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4500 err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw,
sPymbed 0:1387ff3eed4a 4501 &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
sPymbed 0:1387ff3eed4a 4502 #else
sPymbed 0:1387ff3eed4a 4503 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4504 err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw,
sPymbed 0:1387ff3eed4a 4505 &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
sPymbed 0:1387ff3eed4a 4506 &curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
sPymbed 0:1387ff3eed4a 4507 &curve->Gy->raw);
sPymbed 0:1387ff3eed4a 4508 #endif
sPymbed 0:1387ff3eed4a 4509
sPymbed 0:1387ff3eed4a 4510 #ifndef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 4511 mp_clear(e);
sPymbed 0:1387ff3eed4a 4512 mp_clear(k);
sPymbed 0:1387ff3eed4a 4513 #endif
sPymbed 0:1387ff3eed4a 4514 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 4515 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 4516
sPymbed 0:1387ff3eed4a 4517 return err;
sPymbed 0:1387ff3eed4a 4518 }
sPymbed 0:1387ff3eed4a 4519 #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
sPymbed 0:1387ff3eed4a 4520 }
sPymbed 0:1387ff3eed4a 4521 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 4522
sPymbed 0:1387ff3eed4a 4523 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4524 pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4525 if (pubkey == NULL)
sPymbed 0:1387ff3eed4a 4526 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 4527 #endif
sPymbed 0:1387ff3eed4a 4528
sPymbed 0:1387ff3eed4a 4529 /* don't use async for key, since we don't support async return here */
sPymbed 0:1387ff3eed4a 4530 if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap,
sPymbed 0:1387ff3eed4a 4531 INVALID_DEVID)) == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4532 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4533 mp_int* b = NULL;
sPymbed 0:1387ff3eed4a 4534 #else
sPymbed 0:1387ff3eed4a 4535 mp_int b[1];
sPymbed 0:1387ff3eed4a 4536 #endif
sPymbed 0:1387ff3eed4a 4537
sPymbed 0:1387ff3eed4a 4538 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4539 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4540 b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
sPymbed 0:1387ff3eed4a 4541 DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4542 if (b == NULL)
sPymbed 0:1387ff3eed4a 4543 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 4544 }
sPymbed 0:1387ff3eed4a 4545 #endif
sPymbed 0:1387ff3eed4a 4546
sPymbed 0:1387ff3eed4a 4547 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4548 err = mp_init(b);
sPymbed 0:1387ff3eed4a 4549 }
sPymbed 0:1387ff3eed4a 4550
sPymbed 0:1387ff3eed4a 4551 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 4552 /* if custom curve, apply params to pubkey */
sPymbed 0:1387ff3eed4a 4553 if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
sPymbed 0:1387ff3eed4a 4554 err = wc_ecc_set_custom_curve(pubkey, key->dp);
sPymbed 0:1387ff3eed4a 4555 }
sPymbed 0:1387ff3eed4a 4556 #endif
sPymbed 0:1387ff3eed4a 4557
sPymbed 0:1387ff3eed4a 4558 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4559 /* Generate blinding value - non-zero value. */
sPymbed 0:1387ff3eed4a 4560 do {
sPymbed 0:1387ff3eed4a 4561 if (++loop_check > 64) {
sPymbed 0:1387ff3eed4a 4562 err = RNG_FAILURE_E;
sPymbed 0:1387ff3eed4a 4563 break;
sPymbed 0:1387ff3eed4a 4564 }
sPymbed 0:1387ff3eed4a 4565
sPymbed 0:1387ff3eed4a 4566 err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
sPymbed 0:1387ff3eed4a 4567 }
sPymbed 0:1387ff3eed4a 4568 while (err == MP_ZERO_E);
sPymbed 0:1387ff3eed4a 4569 loop_check = 0;
sPymbed 0:1387ff3eed4a 4570 }
sPymbed 0:1387ff3eed4a 4571
sPymbed 0:1387ff3eed4a 4572 for (; err == MP_OKAY;) {
sPymbed 0:1387ff3eed4a 4573 if (++loop_check > 64) {
sPymbed 0:1387ff3eed4a 4574 err = RNG_FAILURE_E;
sPymbed 0:1387ff3eed4a 4575 break;
sPymbed 0:1387ff3eed4a 4576 }
sPymbed 0:1387ff3eed4a 4577 err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
sPymbed 0:1387ff3eed4a 4578 key->dp->id);
sPymbed 0:1387ff3eed4a 4579 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4580
sPymbed 0:1387ff3eed4a 4581 /* find r = x1 mod n */
sPymbed 0:1387ff3eed4a 4582 err = mp_mod(pubkey->pubkey.x, curve->order, r);
sPymbed 0:1387ff3eed4a 4583 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4584
sPymbed 0:1387ff3eed4a 4585 if (mp_iszero(r) == MP_YES) {
sPymbed 0:1387ff3eed4a 4586 #ifndef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 4587 mp_clear(pubkey->pubkey.x);
sPymbed 0:1387ff3eed4a 4588 mp_clear(pubkey->pubkey.y);
sPymbed 0:1387ff3eed4a 4589 mp_clear(pubkey->pubkey.z);
sPymbed 0:1387ff3eed4a 4590 #endif
sPymbed 0:1387ff3eed4a 4591 mp_forcezero(&pubkey->k);
sPymbed 0:1387ff3eed4a 4592 }
sPymbed 0:1387ff3eed4a 4593 else {
sPymbed 0:1387ff3eed4a 4594 /* find s = (e + xr)/k
sPymbed 0:1387ff3eed4a 4595 = b.(e/k.b + x.r/k.b) */
sPymbed 0:1387ff3eed4a 4596
sPymbed 0:1387ff3eed4a 4597 /* k = k.b */
sPymbed 0:1387ff3eed4a 4598 err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k);
sPymbed 0:1387ff3eed4a 4599 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4600
sPymbed 0:1387ff3eed4a 4601 /* k = 1/k.b */
sPymbed 0:1387ff3eed4a 4602 err = mp_invmod(&pubkey->k, curve->order, &pubkey->k);
sPymbed 0:1387ff3eed4a 4603 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4604
sPymbed 0:1387ff3eed4a 4605 /* s = x.r */
sPymbed 0:1387ff3eed4a 4606 err = mp_mulmod(&key->k, r, curve->order, s);
sPymbed 0:1387ff3eed4a 4607 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4608
sPymbed 0:1387ff3eed4a 4609 /* s = x.r/k.b */
sPymbed 0:1387ff3eed4a 4610 err = mp_mulmod(&pubkey->k, s, curve->order, s);
sPymbed 0:1387ff3eed4a 4611 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4612
sPymbed 0:1387ff3eed4a 4613 /* e = e/k.b */
sPymbed 0:1387ff3eed4a 4614 err = mp_mulmod(&pubkey->k, e, curve->order, e);
sPymbed 0:1387ff3eed4a 4615 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4616
sPymbed 0:1387ff3eed4a 4617 /* s = e/k.b + x.r/k.b
sPymbed 0:1387ff3eed4a 4618 = (e + x.r)/k.b */
sPymbed 0:1387ff3eed4a 4619 err = mp_add(e, s, s);
sPymbed 0:1387ff3eed4a 4620 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4621
sPymbed 0:1387ff3eed4a 4622 /* s = b.(e + x.r)/k.b
sPymbed 0:1387ff3eed4a 4623 = (e + x.r)/k */
sPymbed 0:1387ff3eed4a 4624 err = mp_mulmod(s, b, curve->order, s);
sPymbed 0:1387ff3eed4a 4625 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4626
sPymbed 0:1387ff3eed4a 4627 /* s = (e + xr)/k */
sPymbed 0:1387ff3eed4a 4628 err = mp_mod(s, curve->order, s);
sPymbed 0:1387ff3eed4a 4629 if (err != MP_OKAY) break;
sPymbed 0:1387ff3eed4a 4630
sPymbed 0:1387ff3eed4a 4631 if (mp_iszero(s) == MP_NO)
sPymbed 0:1387ff3eed4a 4632 break;
sPymbed 0:1387ff3eed4a 4633 }
sPymbed 0:1387ff3eed4a 4634 }
sPymbed 0:1387ff3eed4a 4635 mp_clear(b);
sPymbed 0:1387ff3eed4a 4636 mp_free(b);
sPymbed 0:1387ff3eed4a 4637 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4638 XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4639 #endif
sPymbed 0:1387ff3eed4a 4640 wc_ecc_free(pubkey);
sPymbed 0:1387ff3eed4a 4641 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4642 XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4643 #endif
sPymbed 0:1387ff3eed4a 4644 }
sPymbed 0:1387ff3eed4a 4645 }
sPymbed 0:1387ff3eed4a 4646
sPymbed 0:1387ff3eed4a 4647 mp_clear(e);
sPymbed 0:1387ff3eed4a 4648 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 4649 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4650 XFREE(e, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4651 #endif
sPymbed 0:1387ff3eed4a 4652 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 4653 #endif /* WOLFSSL_SP_MATH */
sPymbed 0:1387ff3eed4a 4654
sPymbed 0:1387ff3eed4a 4655 return err;
sPymbed 0:1387ff3eed4a 4656 }
sPymbed 0:1387ff3eed4a 4657 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 4658 #endif /* HAVE_ECC_SIGN */
sPymbed 0:1387ff3eed4a 4659
sPymbed 0:1387ff3eed4a 4660 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 4661 void wc_ecc_free_curve(const ecc_set_type* curve, void* heap)
sPymbed 0:1387ff3eed4a 4662 {
sPymbed 0:1387ff3eed4a 4663 if (curve->prime != NULL)
sPymbed 0:1387ff3eed4a 4664 XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4665 if (curve->Af != NULL)
sPymbed 0:1387ff3eed4a 4666 XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4667 if (curve->Bf != NULL)
sPymbed 0:1387ff3eed4a 4668 XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4669 if (curve->order != NULL)
sPymbed 0:1387ff3eed4a 4670 XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4671 if (curve->Gx != NULL)
sPymbed 0:1387ff3eed4a 4672 XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4673 if (curve->Gy != NULL)
sPymbed 0:1387ff3eed4a 4674 XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4675
sPymbed 0:1387ff3eed4a 4676 XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4677
sPymbed 0:1387ff3eed4a 4678 (void)heap;
sPymbed 0:1387ff3eed4a 4679 }
sPymbed 0:1387ff3eed4a 4680 #endif /* WOLFSSL_CUSTOM_CURVES */
sPymbed 0:1387ff3eed4a 4681
sPymbed 0:1387ff3eed4a 4682 /**
sPymbed 0:1387ff3eed4a 4683 Free an ECC key from memory
sPymbed 0:1387ff3eed4a 4684 key The key you wish to free
sPymbed 0:1387ff3eed4a 4685 */
sPymbed 0:1387ff3eed4a 4686 int wc_ecc_free(ecc_key* key)
sPymbed 0:1387ff3eed4a 4687 {
sPymbed 0:1387ff3eed4a 4688 if (key == NULL) {
sPymbed 0:1387ff3eed4a 4689 return 0;
sPymbed 0:1387ff3eed4a 4690 }
sPymbed 0:1387ff3eed4a 4691
sPymbed 0:1387ff3eed4a 4692 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 4693 #ifdef WC_ASYNC_ENABLE_ECC
sPymbed 0:1387ff3eed4a 4694 wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
sPymbed 0:1387ff3eed4a 4695 #endif
sPymbed 0:1387ff3eed4a 4696 wc_ecc_free_async(key);
sPymbed 0:1387ff3eed4a 4697 #endif
sPymbed 0:1387ff3eed4a 4698
sPymbed 0:1387ff3eed4a 4699 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 4700 atmel_ecc_free(key->slot);
sPymbed 0:1387ff3eed4a 4701 key->slot = -1;
sPymbed 0:1387ff3eed4a 4702 #else
sPymbed 0:1387ff3eed4a 4703
sPymbed 0:1387ff3eed4a 4704 mp_clear(key->pubkey.x);
sPymbed 0:1387ff3eed4a 4705 mp_clear(key->pubkey.y);
sPymbed 0:1387ff3eed4a 4706 mp_clear(key->pubkey.z);
sPymbed 0:1387ff3eed4a 4707
sPymbed 0:1387ff3eed4a 4708 mp_forcezero(&key->k);
sPymbed 0:1387ff3eed4a 4709 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 4710
sPymbed 0:1387ff3eed4a 4711 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 4712 if (key->deallocSet && key->dp != NULL)
sPymbed 0:1387ff3eed4a 4713 wc_ecc_free_curve(key->dp, key->heap);
sPymbed 0:1387ff3eed4a 4714 #endif
sPymbed 0:1387ff3eed4a 4715
sPymbed 0:1387ff3eed4a 4716 return 0;
sPymbed 0:1387ff3eed4a 4717 }
sPymbed 0:1387ff3eed4a 4718
sPymbed 0:1387ff3eed4a 4719 #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A)
sPymbed 0:1387ff3eed4a 4720 #ifdef ECC_SHAMIR
sPymbed 0:1387ff3eed4a 4721
sPymbed 0:1387ff3eed4a 4722 /** Computes kA*A + kB*B = C using Shamir's Trick
sPymbed 0:1387ff3eed4a 4723 A First point to multiply
sPymbed 0:1387ff3eed4a 4724 kA What to multiple A by
sPymbed 0:1387ff3eed4a 4725 B Second point to multiply
sPymbed 0:1387ff3eed4a 4726 kB What to multiple B by
sPymbed 0:1387ff3eed4a 4727 C [out] Destination point (can overlap with A or B)
sPymbed 0:1387ff3eed4a 4728 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 4729 modulus Modulus for curve
sPymbed 0:1387ff3eed4a 4730 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 4731 */
sPymbed 0:1387ff3eed4a 4732 #ifdef FP_ECC
sPymbed 0:1387ff3eed4a 4733 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
sPymbed 0:1387ff3eed4a 4734 ecc_point* B, mp_int* kB,
sPymbed 0:1387ff3eed4a 4735 ecc_point* C, mp_int* a, mp_int* modulus,
sPymbed 0:1387ff3eed4a 4736 void* heap)
sPymbed 0:1387ff3eed4a 4737 #else
sPymbed 0:1387ff3eed4a 4738 int ecc_mul2add(ecc_point* A, mp_int* kA,
sPymbed 0:1387ff3eed4a 4739 ecc_point* B, mp_int* kB,
sPymbed 0:1387ff3eed4a 4740 ecc_point* C, mp_int* a, mp_int* modulus,
sPymbed 0:1387ff3eed4a 4741 void* heap)
sPymbed 0:1387ff3eed4a 4742 #endif
sPymbed 0:1387ff3eed4a 4743 {
sPymbed 0:1387ff3eed4a 4744 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4745 ecc_point** precomp = NULL;
sPymbed 0:1387ff3eed4a 4746 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 4747 ecc_key key;
sPymbed 0:1387ff3eed4a 4748 #endif
sPymbed 0:1387ff3eed4a 4749 #else
sPymbed 0:1387ff3eed4a 4750 ecc_point* precomp[SHAMIR_PRECOMP_SZ];
sPymbed 0:1387ff3eed4a 4751 #endif
sPymbed 0:1387ff3eed4a 4752 unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
sPymbed 0:1387ff3eed4a 4753 unsigned char* tA;
sPymbed 0:1387ff3eed4a 4754 unsigned char* tB;
sPymbed 0:1387ff3eed4a 4755 int err = MP_OKAY, first, x, y;
sPymbed 0:1387ff3eed4a 4756 mp_digit mp = 0;
sPymbed 0:1387ff3eed4a 4757
sPymbed 0:1387ff3eed4a 4758 /* argchks */
sPymbed 0:1387ff3eed4a 4759 if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
sPymbed 0:1387ff3eed4a 4760 modulus == NULL) {
sPymbed 0:1387ff3eed4a 4761 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 4762 }
sPymbed 0:1387ff3eed4a 4763
sPymbed 0:1387ff3eed4a 4764 /* allocate memory */
sPymbed 0:1387ff3eed4a 4765 tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4766 if (tA == NULL) {
sPymbed 0:1387ff3eed4a 4767 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 4768 }
sPymbed 0:1387ff3eed4a 4769 tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4770 if (tB == NULL) {
sPymbed 0:1387ff3eed4a 4771 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4772 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 4773 }
sPymbed 0:1387ff3eed4a 4774 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4775 precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
sPymbed 0:1387ff3eed4a 4776 DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4777 if (precomp == NULL) {
sPymbed 0:1387ff3eed4a 4778 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4779 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4780 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 4781 }
sPymbed 0:1387ff3eed4a 4782 #endif
sPymbed 0:1387ff3eed4a 4783 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 4784 key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4785 key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4786 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 4787 key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4788 key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4789 key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4790 #endif
sPymbed 0:1387ff3eed4a 4791 if (key.t1 == NULL || key.t2 == NULL
sPymbed 0:1387ff3eed4a 4792 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 4793 || key.x == NULL || key.y == NULL || key.z == NULL
sPymbed 0:1387ff3eed4a 4794 #endif
sPymbed 0:1387ff3eed4a 4795 ) {
sPymbed 0:1387ff3eed4a 4796 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 4797 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4798 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4799 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4800 #endif
sPymbed 0:1387ff3eed4a 4801 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4802 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4803 XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4804 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4805 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 4806 return MEMORY_E;
sPymbed 0:1387ff3eed4a 4807 }
sPymbed 0:1387ff3eed4a 4808 C->key = &key;
sPymbed 0:1387ff3eed4a 4809 #endif /* WOLFSSL_SMALL_STACK_CACHE */
sPymbed 0:1387ff3eed4a 4810
sPymbed 0:1387ff3eed4a 4811 /* init variables */
sPymbed 0:1387ff3eed4a 4812 XMEMSET(tA, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 4813 XMEMSET(tB, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 4814 #ifndef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4815 XMEMSET(precomp, 0, sizeof(precomp));
sPymbed 0:1387ff3eed4a 4816 #else
sPymbed 0:1387ff3eed4a 4817 XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
sPymbed 0:1387ff3eed4a 4818 #endif
sPymbed 0:1387ff3eed4a 4819
sPymbed 0:1387ff3eed4a 4820 /* get sizes */
sPymbed 0:1387ff3eed4a 4821 lenA = mp_unsigned_bin_size(kA);
sPymbed 0:1387ff3eed4a 4822 lenB = mp_unsigned_bin_size(kB);
sPymbed 0:1387ff3eed4a 4823 len = MAX(lenA, lenB);
sPymbed 0:1387ff3eed4a 4824
sPymbed 0:1387ff3eed4a 4825 /* sanity check */
sPymbed 0:1387ff3eed4a 4826 if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
sPymbed 0:1387ff3eed4a 4827 err = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 4828 }
sPymbed 0:1387ff3eed4a 4829
sPymbed 0:1387ff3eed4a 4830 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4831 /* extract and justify kA */
sPymbed 0:1387ff3eed4a 4832 err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
sPymbed 0:1387ff3eed4a 4833
sPymbed 0:1387ff3eed4a 4834 /* extract and justify kB */
sPymbed 0:1387ff3eed4a 4835 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4836 err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
sPymbed 0:1387ff3eed4a 4837
sPymbed 0:1387ff3eed4a 4838 /* allocate the table */
sPymbed 0:1387ff3eed4a 4839 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4840 for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
sPymbed 0:1387ff3eed4a 4841 precomp[x] = wc_ecc_new_point_h(heap);
sPymbed 0:1387ff3eed4a 4842 if (precomp[x] == NULL) {
sPymbed 0:1387ff3eed4a 4843 err = GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 4844 break;
sPymbed 0:1387ff3eed4a 4845 }
sPymbed 0:1387ff3eed4a 4846 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 4847 precomp[x]->key = &key;
sPymbed 0:1387ff3eed4a 4848 #endif
sPymbed 0:1387ff3eed4a 4849 }
sPymbed 0:1387ff3eed4a 4850 }
sPymbed 0:1387ff3eed4a 4851 }
sPymbed 0:1387ff3eed4a 4852
sPymbed 0:1387ff3eed4a 4853 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4854 /* init montgomery reduction */
sPymbed 0:1387ff3eed4a 4855 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 4856
sPymbed 0:1387ff3eed4a 4857 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4858 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4859 mp_int* mu = NULL;
sPymbed 0:1387ff3eed4a 4860 #else
sPymbed 0:1387ff3eed4a 4861 mp_int mu[1];
sPymbed 0:1387ff3eed4a 4862 #endif
sPymbed 0:1387ff3eed4a 4863 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4864 mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4865 if (mu == NULL)
sPymbed 0:1387ff3eed4a 4866 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 4867 #endif
sPymbed 0:1387ff3eed4a 4868 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4869 err = mp_init(mu);
sPymbed 0:1387ff3eed4a 4870 }
sPymbed 0:1387ff3eed4a 4871 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4872 err = mp_montgomery_calc_normalization(mu, modulus);
sPymbed 0:1387ff3eed4a 4873
sPymbed 0:1387ff3eed4a 4874 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4875 /* copy ones ... */
sPymbed 0:1387ff3eed4a 4876 err = mp_mulmod(A->x, mu, modulus, precomp[1]->x);
sPymbed 0:1387ff3eed4a 4877
sPymbed 0:1387ff3eed4a 4878 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4879 err = mp_mulmod(A->y, mu, modulus, precomp[1]->y);
sPymbed 0:1387ff3eed4a 4880 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4881 err = mp_mulmod(A->z, mu, modulus, precomp[1]->z);
sPymbed 0:1387ff3eed4a 4882
sPymbed 0:1387ff3eed4a 4883 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4884 err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x);
sPymbed 0:1387ff3eed4a 4885 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4886 err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y);
sPymbed 0:1387ff3eed4a 4887 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4888 err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z);
sPymbed 0:1387ff3eed4a 4889
sPymbed 0:1387ff3eed4a 4890 /* done with mu */
sPymbed 0:1387ff3eed4a 4891 mp_clear(mu);
sPymbed 0:1387ff3eed4a 4892 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 4893 XFREE(mu, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 4894 #endif
sPymbed 0:1387ff3eed4a 4895 }
sPymbed 0:1387ff3eed4a 4896 }
sPymbed 0:1387ff3eed4a 4897
sPymbed 0:1387ff3eed4a 4898 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4899 /* precomp [i,0](A + B) table */
sPymbed 0:1387ff3eed4a 4900 err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp);
sPymbed 0:1387ff3eed4a 4901
sPymbed 0:1387ff3eed4a 4902 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4903 err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3],
sPymbed 0:1387ff3eed4a 4904 a, modulus, mp);
sPymbed 0:1387ff3eed4a 4905 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4906 /* precomp [0,i](A + B) table */
sPymbed 0:1387ff3eed4a 4907 err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp);
sPymbed 0:1387ff3eed4a 4908
sPymbed 0:1387ff3eed4a 4909 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4910 err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2],
sPymbed 0:1387ff3eed4a 4911 a, modulus, mp);
sPymbed 0:1387ff3eed4a 4912
sPymbed 0:1387ff3eed4a 4913 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4914 /* precomp [i,j](A + B) table (i != 0, j != 0) */
sPymbed 0:1387ff3eed4a 4915 for (x = 1; x < 4; x++) {
sPymbed 0:1387ff3eed4a 4916 for (y = 1; y < 4; y++) {
sPymbed 0:1387ff3eed4a 4917 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4918 err = ecc_projective_add_point(precomp[x], precomp[(y<<2)],
sPymbed 0:1387ff3eed4a 4919 precomp[x+(y<<2)], a, modulus, mp);
sPymbed 0:1387ff3eed4a 4920 }
sPymbed 0:1387ff3eed4a 4921 }
sPymbed 0:1387ff3eed4a 4922 }
sPymbed 0:1387ff3eed4a 4923 }
sPymbed 0:1387ff3eed4a 4924
sPymbed 0:1387ff3eed4a 4925 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 4926 nibble = 3;
sPymbed 0:1387ff3eed4a 4927 first = 1;
sPymbed 0:1387ff3eed4a 4928 bitbufA = tA[0];
sPymbed 0:1387ff3eed4a 4929 bitbufB = tB[0];
sPymbed 0:1387ff3eed4a 4930
sPymbed 0:1387ff3eed4a 4931 /* for every byte of the multiplicands */
sPymbed 0:1387ff3eed4a 4932 for (x = 0;; ) {
sPymbed 0:1387ff3eed4a 4933 /* grab a nibble */
sPymbed 0:1387ff3eed4a 4934 if (++nibble == 4) {
sPymbed 0:1387ff3eed4a 4935 if (x == (int)len) break;
sPymbed 0:1387ff3eed4a 4936 bitbufA = tA[x];
sPymbed 0:1387ff3eed4a 4937 bitbufB = tB[x];
sPymbed 0:1387ff3eed4a 4938 nibble = 0;
sPymbed 0:1387ff3eed4a 4939 x++;
sPymbed 0:1387ff3eed4a 4940 }
sPymbed 0:1387ff3eed4a 4941
sPymbed 0:1387ff3eed4a 4942 /* extract two bits from both, shift/update */
sPymbed 0:1387ff3eed4a 4943 nA = (bitbufA >> 6) & 0x03;
sPymbed 0:1387ff3eed4a 4944 nB = (bitbufB >> 6) & 0x03;
sPymbed 0:1387ff3eed4a 4945 bitbufA = (bitbufA << 2) & 0xFF;
sPymbed 0:1387ff3eed4a 4946 bitbufB = (bitbufB << 2) & 0xFF;
sPymbed 0:1387ff3eed4a 4947
sPymbed 0:1387ff3eed4a 4948 /* if both zero, if first, continue */
sPymbed 0:1387ff3eed4a 4949 if ((nA == 0) && (nB == 0) && (first == 1)) {
sPymbed 0:1387ff3eed4a 4950 continue;
sPymbed 0:1387ff3eed4a 4951 }
sPymbed 0:1387ff3eed4a 4952
sPymbed 0:1387ff3eed4a 4953 /* double twice, only if this isn't the first */
sPymbed 0:1387ff3eed4a 4954 if (first == 0) {
sPymbed 0:1387ff3eed4a 4955 /* double twice */
sPymbed 0:1387ff3eed4a 4956 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4957 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
sPymbed 0:1387ff3eed4a 4958 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4959 err = ecc_projective_dbl_point(C, C, a, modulus, mp);
sPymbed 0:1387ff3eed4a 4960 else
sPymbed 0:1387ff3eed4a 4961 break;
sPymbed 0:1387ff3eed4a 4962 }
sPymbed 0:1387ff3eed4a 4963
sPymbed 0:1387ff3eed4a 4964 /* if not both zero */
sPymbed 0:1387ff3eed4a 4965 if ((nA != 0) || (nB != 0)) {
sPymbed 0:1387ff3eed4a 4966 if (first == 1) {
sPymbed 0:1387ff3eed4a 4967 /* if first, copy from table */
sPymbed 0:1387ff3eed4a 4968 first = 0;
sPymbed 0:1387ff3eed4a 4969 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4970 err = mp_copy(precomp[nA + (nB<<2)]->x, C->x);
sPymbed 0:1387ff3eed4a 4971
sPymbed 0:1387ff3eed4a 4972 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4973 err = mp_copy(precomp[nA + (nB<<2)]->y, C->y);
sPymbed 0:1387ff3eed4a 4974
sPymbed 0:1387ff3eed4a 4975 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4976 err = mp_copy(precomp[nA + (nB<<2)]->z, C->z);
sPymbed 0:1387ff3eed4a 4977 else
sPymbed 0:1387ff3eed4a 4978 break;
sPymbed 0:1387ff3eed4a 4979 } else {
sPymbed 0:1387ff3eed4a 4980 /* if not first, add from table */
sPymbed 0:1387ff3eed4a 4981 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4982 err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
sPymbed 0:1387ff3eed4a 4983 a, modulus, mp);
sPymbed 0:1387ff3eed4a 4984 else
sPymbed 0:1387ff3eed4a 4985 break;
sPymbed 0:1387ff3eed4a 4986 }
sPymbed 0:1387ff3eed4a 4987 }
sPymbed 0:1387ff3eed4a 4988 }
sPymbed 0:1387ff3eed4a 4989 }
sPymbed 0:1387ff3eed4a 4990
sPymbed 0:1387ff3eed4a 4991 /* reduce to affine */
sPymbed 0:1387ff3eed4a 4992 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 4993 err = ecc_map(C, modulus, mp);
sPymbed 0:1387ff3eed4a 4994
sPymbed 0:1387ff3eed4a 4995 /* clean up */
sPymbed 0:1387ff3eed4a 4996 for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
sPymbed 0:1387ff3eed4a 4997 wc_ecc_del_point_h(precomp[x], heap);
sPymbed 0:1387ff3eed4a 4998 }
sPymbed 0:1387ff3eed4a 4999
sPymbed 0:1387ff3eed4a 5000 ForceZero(tA, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5001 ForceZero(tB, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5002 #ifdef WOLFSSL_SMALL_STACK_CACHE
sPymbed 0:1387ff3eed4a 5003 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 5004 XFREE(key.z, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5005 XFREE(key.y, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5006 XFREE(key.x, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5007 #endif
sPymbed 0:1387ff3eed4a 5008 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5009 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5010 C->key = NULL;
sPymbed 0:1387ff3eed4a 5011 #endif
sPymbed 0:1387ff3eed4a 5012 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5013 XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5014 #endif
sPymbed 0:1387ff3eed4a 5015 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5016 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5017
sPymbed 0:1387ff3eed4a 5018 return err;
sPymbed 0:1387ff3eed4a 5019 }
sPymbed 0:1387ff3eed4a 5020
sPymbed 0:1387ff3eed4a 5021 #endif /* ECC_SHAMIR */
sPymbed 0:1387ff3eed4a 5022 #endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 5023
sPymbed 0:1387ff3eed4a 5024
sPymbed 0:1387ff3eed4a 5025 #ifdef HAVE_ECC_VERIFY
sPymbed 0:1387ff3eed4a 5026 #ifndef NO_ASN
sPymbed 0:1387ff3eed4a 5027 /* verify
sPymbed 0:1387ff3eed4a 5028 *
sPymbed 0:1387ff3eed4a 5029 * w = s^-1 mod n
sPymbed 0:1387ff3eed4a 5030 * u1 = xw
sPymbed 0:1387ff3eed4a 5031 * u2 = rw
sPymbed 0:1387ff3eed4a 5032 * X = u1*G + u2*Q
sPymbed 0:1387ff3eed4a 5033 * v = X_x1 mod n
sPymbed 0:1387ff3eed4a 5034 * accept if v == r
sPymbed 0:1387ff3eed4a 5035 */
sPymbed 0:1387ff3eed4a 5036
sPymbed 0:1387ff3eed4a 5037 /**
sPymbed 0:1387ff3eed4a 5038 Verify an ECC signature
sPymbed 0:1387ff3eed4a 5039 sig The signature to verify
sPymbed 0:1387ff3eed4a 5040 siglen The length of the signature (octets)
sPymbed 0:1387ff3eed4a 5041 hash The hash (message digest) that was signed
sPymbed 0:1387ff3eed4a 5042 hashlen The length of the hash (octets)
sPymbed 0:1387ff3eed4a 5043 res Result of signature, 1==valid, 0==invalid
sPymbed 0:1387ff3eed4a 5044 key The corresponding public ECC key
sPymbed 0:1387ff3eed4a 5045 return MP_OKAY if successful (even if the signature is not valid)
sPymbed 0:1387ff3eed4a 5046 */
sPymbed 0:1387ff3eed4a 5047 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
sPymbed 0:1387ff3eed4a 5048 word32 hashlen, int* res, ecc_key* key)
sPymbed 0:1387ff3eed4a 5049 {
sPymbed 0:1387ff3eed4a 5050 int err;
sPymbed 0:1387ff3eed4a 5051 mp_int *r = NULL, *s = NULL;
sPymbed 0:1387ff3eed4a 5052 #ifndef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 5053 #ifndef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5054 mp_int r_lcl[1], s_lcl[1];
sPymbed 0:1387ff3eed4a 5055 #endif
sPymbed 0:1387ff3eed4a 5056 #endif
sPymbed 0:1387ff3eed4a 5057
sPymbed 0:1387ff3eed4a 5058 if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
sPymbed 0:1387ff3eed4a 5059 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5060 }
sPymbed 0:1387ff3eed4a 5061
sPymbed 0:1387ff3eed4a 5062 #ifdef WOLF_CRYPTO_DEV
sPymbed 0:1387ff3eed4a 5063 if (key->devId != INVALID_DEVID) {
sPymbed 0:1387ff3eed4a 5064 err = wc_CryptoDev_EccVerify(sig, siglen, hash, hashlen, res, key);
sPymbed 0:1387ff3eed4a 5065 if (err != NOT_COMPILED_IN)
sPymbed 0:1387ff3eed4a 5066 return err;
sPymbed 0:1387ff3eed4a 5067 }
sPymbed 0:1387ff3eed4a 5068 #endif
sPymbed 0:1387ff3eed4a 5069
sPymbed 0:1387ff3eed4a 5070 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 5071 err = wc_ecc_alloc_async(key);
sPymbed 0:1387ff3eed4a 5072 if (err != 0)
sPymbed 0:1387ff3eed4a 5073 return err;
sPymbed 0:1387ff3eed4a 5074 r = key->r;
sPymbed 0:1387ff3eed4a 5075 s = key->s;
sPymbed 0:1387ff3eed4a 5076 #else
sPymbed 0:1387ff3eed4a 5077 #ifndef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5078 r = r_lcl;
sPymbed 0:1387ff3eed4a 5079 s = s_lcl;
sPymbed 0:1387ff3eed4a 5080 #else
sPymbed 0:1387ff3eed4a 5081 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5082 if (r == NULL)
sPymbed 0:1387ff3eed4a 5083 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5084 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5085 if (s == NULL) {
sPymbed 0:1387ff3eed4a 5086 XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5087 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5088 }
sPymbed 0:1387ff3eed4a 5089 #endif
sPymbed 0:1387ff3eed4a 5090 #endif
sPymbed 0:1387ff3eed4a 5091
sPymbed 0:1387ff3eed4a 5092 switch(key->state) {
sPymbed 0:1387ff3eed4a 5093 case ECC_STATE_NONE:
sPymbed 0:1387ff3eed4a 5094 case ECC_STATE_VERIFY_DECODE:
sPymbed 0:1387ff3eed4a 5095 key->state = ECC_STATE_VERIFY_DECODE;
sPymbed 0:1387ff3eed4a 5096
sPymbed 0:1387ff3eed4a 5097 /* default to invalid signature */
sPymbed 0:1387ff3eed4a 5098 *res = 0;
sPymbed 0:1387ff3eed4a 5099
sPymbed 0:1387ff3eed4a 5100 /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
sPymbed 0:1387ff3eed4a 5101 * If either of those don't allocate correctly, none of
sPymbed 0:1387ff3eed4a 5102 * the rest of this function will execute, and everything
sPymbed 0:1387ff3eed4a 5103 * gets cleaned up at the end. */
sPymbed 0:1387ff3eed4a 5104 /* decode DSA header */
sPymbed 0:1387ff3eed4a 5105 err = DecodeECC_DSA_Sig(sig, siglen, r, s);
sPymbed 0:1387ff3eed4a 5106 if (err < 0) {
sPymbed 0:1387ff3eed4a 5107 break;
sPymbed 0:1387ff3eed4a 5108 }
sPymbed 0:1387ff3eed4a 5109 FALL_THROUGH;
sPymbed 0:1387ff3eed4a 5110
sPymbed 0:1387ff3eed4a 5111 case ECC_STATE_VERIFY_DO:
sPymbed 0:1387ff3eed4a 5112 key->state = ECC_STATE_VERIFY_DO;
sPymbed 0:1387ff3eed4a 5113
sPymbed 0:1387ff3eed4a 5114 err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
sPymbed 0:1387ff3eed4a 5115
sPymbed 0:1387ff3eed4a 5116 #ifndef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 5117 /* done with R/S */
sPymbed 0:1387ff3eed4a 5118 mp_clear(r);
sPymbed 0:1387ff3eed4a 5119 mp_clear(s);
sPymbed 0:1387ff3eed4a 5120 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5121 XFREE(s, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5122 XFREE(r, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5123 #endif
sPymbed 0:1387ff3eed4a 5124 #endif
sPymbed 0:1387ff3eed4a 5125
sPymbed 0:1387ff3eed4a 5126 if (err < 0) {
sPymbed 0:1387ff3eed4a 5127 break;
sPymbed 0:1387ff3eed4a 5128 }
sPymbed 0:1387ff3eed4a 5129 FALL_THROUGH;
sPymbed 0:1387ff3eed4a 5130
sPymbed 0:1387ff3eed4a 5131 case ECC_STATE_VERIFY_RES:
sPymbed 0:1387ff3eed4a 5132 key->state = ECC_STATE_VERIFY_RES;
sPymbed 0:1387ff3eed4a 5133 err = 0;
sPymbed 0:1387ff3eed4a 5134 break;
sPymbed 0:1387ff3eed4a 5135
sPymbed 0:1387ff3eed4a 5136 default:
sPymbed 0:1387ff3eed4a 5137 err = BAD_STATE_E;
sPymbed 0:1387ff3eed4a 5138 }
sPymbed 0:1387ff3eed4a 5139
sPymbed 0:1387ff3eed4a 5140 /* if async pending then return and skip done cleanup below */
sPymbed 0:1387ff3eed4a 5141 if (err == WC_PENDING_E) {
sPymbed 0:1387ff3eed4a 5142 key->state++;
sPymbed 0:1387ff3eed4a 5143 return err;
sPymbed 0:1387ff3eed4a 5144 }
sPymbed 0:1387ff3eed4a 5145
sPymbed 0:1387ff3eed4a 5146 /* cleanup */
sPymbed 0:1387ff3eed4a 5147 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 0:1387ff3eed4a 5148 wc_ecc_free_async(key);
sPymbed 0:1387ff3eed4a 5149 #endif
sPymbed 0:1387ff3eed4a 5150 key->state = ECC_STATE_NONE;
sPymbed 0:1387ff3eed4a 5151
sPymbed 0:1387ff3eed4a 5152 return err;
sPymbed 0:1387ff3eed4a 5153 }
sPymbed 0:1387ff3eed4a 5154 #endif /* !NO_ASN */
sPymbed 0:1387ff3eed4a 5155
sPymbed 0:1387ff3eed4a 5156
sPymbed 0:1387ff3eed4a 5157 /**
sPymbed 0:1387ff3eed4a 5158 Verify an ECC signature
sPymbed 0:1387ff3eed4a 5159 r The signature R component to verify
sPymbed 0:1387ff3eed4a 5160 s The signature S component to verify
sPymbed 0:1387ff3eed4a 5161 hash The hash (message digest) that was signed
sPymbed 0:1387ff3eed4a 5162 hashlen The length of the hash (octets)
sPymbed 0:1387ff3eed4a 5163 res Result of signature, 1==valid, 0==invalid
sPymbed 0:1387ff3eed4a 5164 key The corresponding public ECC key
sPymbed 0:1387ff3eed4a 5165 return MP_OKAY if successful (even if the signature is not valid)
sPymbed 0:1387ff3eed4a 5166 */
sPymbed 0:1387ff3eed4a 5167 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
sPymbed 0:1387ff3eed4a 5168 word32 hashlen, int* res, ecc_key* key)
sPymbed 0:1387ff3eed4a 5169 {
sPymbed 0:1387ff3eed4a 5170 int err;
sPymbed 0:1387ff3eed4a 5171 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5172 byte sigRS[ATECC_KEY_SIZE*2];
sPymbed 0:1387ff3eed4a 5173 #elif !defined(WOLFSSL_SP_MATH)
sPymbed 0:1387ff3eed4a 5174 int did_init = 0;
sPymbed 0:1387ff3eed4a 5175 ecc_point *mG = NULL, *mQ = NULL;
sPymbed 0:1387ff3eed4a 5176 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5177 mp_int* v = NULL;
sPymbed 0:1387ff3eed4a 5178 mp_int* w = NULL;
sPymbed 0:1387ff3eed4a 5179 mp_int* u1 = NULL;
sPymbed 0:1387ff3eed4a 5180 mp_int* u2 = NULL;
sPymbed 0:1387ff3eed4a 5181 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
sPymbed 0:1387ff3eed4a 5182 mp_int* e_lcl = NULL;
sPymbed 0:1387ff3eed4a 5183 #endif
sPymbed 0:1387ff3eed4a 5184 #else /* WOLFSSL_SMALL_STACK */
sPymbed 0:1387ff3eed4a 5185 mp_int v[1];
sPymbed 0:1387ff3eed4a 5186 mp_int w[1];
sPymbed 0:1387ff3eed4a 5187 mp_int u1[1];
sPymbed 0:1387ff3eed4a 5188 mp_int u2[1];
sPymbed 0:1387ff3eed4a 5189 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
sPymbed 0:1387ff3eed4a 5190 mp_int e_lcl[1];
sPymbed 0:1387ff3eed4a 5191 #endif
sPymbed 0:1387ff3eed4a 5192 #endif /* WOLFSSL_SMALL_STACK */
sPymbed 0:1387ff3eed4a 5193 mp_int* e;
sPymbed 0:1387ff3eed4a 5194 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 5195 #endif
sPymbed 0:1387ff3eed4a 5196
sPymbed 0:1387ff3eed4a 5197 if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
sPymbed 0:1387ff3eed4a 5198 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5199
sPymbed 0:1387ff3eed4a 5200 /* default to invalid signature */
sPymbed 0:1387ff3eed4a 5201 *res = 0;
sPymbed 0:1387ff3eed4a 5202
sPymbed 0:1387ff3eed4a 5203 /* is the IDX valid ? */
sPymbed 0:1387ff3eed4a 5204 if (wc_ecc_is_valid_idx(key->idx) != 1) {
sPymbed 0:1387ff3eed4a 5205 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5206 }
sPymbed 0:1387ff3eed4a 5207
sPymbed 0:1387ff3eed4a 5208 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
sPymbed 0:1387ff3eed4a 5209 defined(WOLFSSL_ASYNC_CRYPT_TEST)
sPymbed 0:1387ff3eed4a 5210 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 5211 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) {
sPymbed 0:1387ff3eed4a 5212 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
sPymbed 0:1387ff3eed4a 5213 testDev->eccVerify.r = r;
sPymbed 0:1387ff3eed4a 5214 testDev->eccVerify.s = s;
sPymbed 0:1387ff3eed4a 5215 testDev->eccVerify.hash = hash;
sPymbed 0:1387ff3eed4a 5216 testDev->eccVerify.hashlen = hashlen;
sPymbed 0:1387ff3eed4a 5217 testDev->eccVerify.stat = res;
sPymbed 0:1387ff3eed4a 5218 testDev->eccVerify.key = key;
sPymbed 0:1387ff3eed4a 5219 return WC_PENDING_E;
sPymbed 0:1387ff3eed4a 5220 }
sPymbed 0:1387ff3eed4a 5221 }
sPymbed 0:1387ff3eed4a 5222 #endif
sPymbed 0:1387ff3eed4a 5223
sPymbed 0:1387ff3eed4a 5224 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5225 /* Extract R and S */
sPymbed 0:1387ff3eed4a 5226 err = mp_to_unsigned_bin(r, &sigRS[0]);
sPymbed 0:1387ff3eed4a 5227 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5228 return err;
sPymbed 0:1387ff3eed4a 5229 }
sPymbed 0:1387ff3eed4a 5230 err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]);
sPymbed 0:1387ff3eed4a 5231 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5232 return err;
sPymbed 0:1387ff3eed4a 5233 }
sPymbed 0:1387ff3eed4a 5234
sPymbed 0:1387ff3eed4a 5235 err = atcatls_verify(hash, sigRS, key->pubkey_raw, (bool*)res);
sPymbed 0:1387ff3eed4a 5236 if (err != ATCA_SUCCESS) {
sPymbed 0:1387ff3eed4a 5237 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 5238 }
sPymbed 0:1387ff3eed4a 5239 (void)hashlen;
sPymbed 0:1387ff3eed4a 5240
sPymbed 0:1387ff3eed4a 5241 #else
sPymbed 0:1387ff3eed4a 5242 /* checking if private key with no public part */
sPymbed 0:1387ff3eed4a 5243 if (key->type == ECC_PRIVATEKEY_ONLY) {
sPymbed 0:1387ff3eed4a 5244 WOLFSSL_MSG("Verify called with private key, generating public part");
sPymbed 0:1387ff3eed4a 5245 err = wc_ecc_make_pub_ex(key, NULL, NULL);
sPymbed 0:1387ff3eed4a 5246 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5247 WOLFSSL_MSG("Unable to extract public key");
sPymbed 0:1387ff3eed4a 5248 return err;
sPymbed 0:1387ff3eed4a 5249 }
sPymbed 0:1387ff3eed4a 5250 }
sPymbed 0:1387ff3eed4a 5251
sPymbed 0:1387ff3eed4a 5252 #ifdef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 5253 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 5254 return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
sPymbed 0:1387ff3eed4a 5255 key->pubkey.z, r, s, res, key->heap);
sPymbed 0:1387ff3eed4a 5256 }
sPymbed 0:1387ff3eed4a 5257 else
sPymbed 0:1387ff3eed4a 5258 return WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 5259 #else
sPymbed 0:1387ff3eed4a 5260 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 5261 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 5262 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
sPymbed 0:1387ff3eed4a 5263 defined(WOLFSSL_ASYNC_CRYPT_TEST)
sPymbed 0:1387ff3eed4a 5264 if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
sPymbed 0:1387ff3eed4a 5265 #endif
sPymbed 0:1387ff3eed4a 5266 {
sPymbed 0:1387ff3eed4a 5267 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
sPymbed 0:1387ff3eed4a 5268 return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y,
sPymbed 0:1387ff3eed4a 5269 key->pubkey.z,r, s, res, key->heap);
sPymbed 0:1387ff3eed4a 5270 }
sPymbed 0:1387ff3eed4a 5271 #endif /* WOLFSSL_SP_NO_256 */
sPymbed 0:1387ff3eed4a 5272 #endif /* WOLFSSL_HAVE_SP_ECC */
sPymbed 0:1387ff3eed4a 5273
sPymbed 0:1387ff3eed4a 5274 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
sPymbed 0:1387ff3eed4a 5275
sPymbed 0:1387ff3eed4a 5276 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
sPymbed 0:1387ff3eed4a 5277 err = wc_ecc_alloc_mpint(key, &key->e);
sPymbed 0:1387ff3eed4a 5278 if (err != 0) {
sPymbed 0:1387ff3eed4a 5279 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 5280 return err;
sPymbed 0:1387ff3eed4a 5281 }
sPymbed 0:1387ff3eed4a 5282 e = key->e;
sPymbed 0:1387ff3eed4a 5283 #else
sPymbed 0:1387ff3eed4a 5284 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5285 e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5286 if (e_lcl == NULL) {
sPymbed 0:1387ff3eed4a 5287 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 5288 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5289 }
sPymbed 0:1387ff3eed4a 5290 #endif
sPymbed 0:1387ff3eed4a 5291 e = e_lcl;
sPymbed 0:1387ff3eed4a 5292 #endif
sPymbed 0:1387ff3eed4a 5293
sPymbed 0:1387ff3eed4a 5294 err = mp_init(e);
sPymbed 0:1387ff3eed4a 5295 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 5296 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5297
sPymbed 0:1387ff3eed4a 5298 /* read in the specs for this curve */
sPymbed 0:1387ff3eed4a 5299 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
sPymbed 0:1387ff3eed4a 5300
sPymbed 0:1387ff3eed4a 5301 /* check for zero */
sPymbed 0:1387ff3eed4a 5302 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5303 if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES ||
sPymbed 0:1387ff3eed4a 5304 mp_cmp(r, curve->order) != MP_LT ||
sPymbed 0:1387ff3eed4a 5305 mp_cmp(s, curve->order) != MP_LT) {
sPymbed 0:1387ff3eed4a 5306 err = MP_ZERO_E;
sPymbed 0:1387ff3eed4a 5307 }
sPymbed 0:1387ff3eed4a 5308 }
sPymbed 0:1387ff3eed4a 5309
sPymbed 0:1387ff3eed4a 5310 /* read hash */
sPymbed 0:1387ff3eed4a 5311 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5312 /* we may need to truncate if hash is longer than key size */
sPymbed 0:1387ff3eed4a 5313 unsigned int orderBits = mp_count_bits(curve->order);
sPymbed 0:1387ff3eed4a 5314
sPymbed 0:1387ff3eed4a 5315 /* truncate down to byte size, may be all that's needed */
sPymbed 0:1387ff3eed4a 5316 if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
sPymbed 0:1387ff3eed4a 5317 hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
sPymbed 0:1387ff3eed4a 5318 err = mp_read_unsigned_bin(e, hash, hashlen);
sPymbed 0:1387ff3eed4a 5319
sPymbed 0:1387ff3eed4a 5320 /* may still need bit truncation too */
sPymbed 0:1387ff3eed4a 5321 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
sPymbed 0:1387ff3eed4a 5322 mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7));
sPymbed 0:1387ff3eed4a 5323 }
sPymbed 0:1387ff3eed4a 5324
sPymbed 0:1387ff3eed4a 5325 /* check for async hardware acceleration */
sPymbed 0:1387ff3eed4a 5326 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
sPymbed 0:1387ff3eed4a 5327 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
sPymbed 0:1387ff3eed4a 5328 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
sPymbed 0:1387ff3eed4a 5329 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 5330 if (NitroxEccIsCurveSupported(key))
sPymbed 0:1387ff3eed4a 5331 #endif
sPymbed 0:1387ff3eed4a 5332 {
sPymbed 0:1387ff3eed4a 5333 word32 keySz = key->dp->size;
sPymbed 0:1387ff3eed4a 5334
sPymbed 0:1387ff3eed4a 5335 err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
sPymbed 0:1387ff3eed4a 5336 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5337 err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
sPymbed 0:1387ff3eed4a 5338 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5339 err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
sPymbed 0:1387ff3eed4a 5340 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5341 #ifdef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 5342 err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
sPymbed 0:1387ff3eed4a 5343 &key->pubkey.y->raw, &r->raw, &s->raw,
sPymbed 0:1387ff3eed4a 5344 &curve->prime->raw, &curve->order->raw, res);
sPymbed 0:1387ff3eed4a 5345 #else
sPymbed 0:1387ff3eed4a 5346 err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
sPymbed 0:1387ff3eed4a 5347 &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
sPymbed 0:1387ff3eed4a 5348 &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
sPymbed 0:1387ff3eed4a 5349 &curve->Gx->raw, &curve->Gy->raw, res);
sPymbed 0:1387ff3eed4a 5350 #endif
sPymbed 0:1387ff3eed4a 5351
sPymbed 0:1387ff3eed4a 5352 #ifndef HAVE_CAVIUM_V
sPymbed 0:1387ff3eed4a 5353 mp_clear(e);
sPymbed 0:1387ff3eed4a 5354 #endif
sPymbed 0:1387ff3eed4a 5355 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 5356 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 5357
sPymbed 0:1387ff3eed4a 5358 return err;
sPymbed 0:1387ff3eed4a 5359 }
sPymbed 0:1387ff3eed4a 5360 #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
sPymbed 0:1387ff3eed4a 5361 }
sPymbed 0:1387ff3eed4a 5362 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 0:1387ff3eed4a 5363
sPymbed 0:1387ff3eed4a 5364 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5365 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5366 v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5367 if (v == NULL)
sPymbed 0:1387ff3eed4a 5368 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5369 }
sPymbed 0:1387ff3eed4a 5370 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5371 w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5372 if (w == NULL)
sPymbed 0:1387ff3eed4a 5373 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5374 }
sPymbed 0:1387ff3eed4a 5375 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5376 u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5377 if (u1 == NULL)
sPymbed 0:1387ff3eed4a 5378 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5379 }
sPymbed 0:1387ff3eed4a 5380 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5381 u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5382 if (u2 == NULL)
sPymbed 0:1387ff3eed4a 5383 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5384 }
sPymbed 0:1387ff3eed4a 5385 #endif
sPymbed 0:1387ff3eed4a 5386
sPymbed 0:1387ff3eed4a 5387 /* allocate ints */
sPymbed 0:1387ff3eed4a 5388 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5389 if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5390 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5391 }
sPymbed 0:1387ff3eed4a 5392 did_init = 1;
sPymbed 0:1387ff3eed4a 5393 }
sPymbed 0:1387ff3eed4a 5394
sPymbed 0:1387ff3eed4a 5395 /* allocate points */
sPymbed 0:1387ff3eed4a 5396 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5397 mG = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 5398 mQ = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 5399 if (mQ == NULL || mG == NULL)
sPymbed 0:1387ff3eed4a 5400 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5401 }
sPymbed 0:1387ff3eed4a 5402
sPymbed 0:1387ff3eed4a 5403 /* w = s^-1 mod n */
sPymbed 0:1387ff3eed4a 5404 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5405 err = mp_invmod(s, curve->order, w);
sPymbed 0:1387ff3eed4a 5406
sPymbed 0:1387ff3eed4a 5407 /* u1 = ew */
sPymbed 0:1387ff3eed4a 5408 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5409 err = mp_mulmod(e, w, curve->order, u1);
sPymbed 0:1387ff3eed4a 5410
sPymbed 0:1387ff3eed4a 5411 /* u2 = rw */
sPymbed 0:1387ff3eed4a 5412 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5413 err = mp_mulmod(r, w, curve->order, u2);
sPymbed 0:1387ff3eed4a 5414
sPymbed 0:1387ff3eed4a 5415 /* find mG and mQ */
sPymbed 0:1387ff3eed4a 5416 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5417 err = mp_copy(curve->Gx, mG->x);
sPymbed 0:1387ff3eed4a 5418 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5419 err = mp_copy(curve->Gy, mG->y);
sPymbed 0:1387ff3eed4a 5420 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5421 err = mp_set(mG->z, 1);
sPymbed 0:1387ff3eed4a 5422
sPymbed 0:1387ff3eed4a 5423 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5424 err = mp_copy(key->pubkey.x, mQ->x);
sPymbed 0:1387ff3eed4a 5425 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5426 err = mp_copy(key->pubkey.y, mQ->y);
sPymbed 0:1387ff3eed4a 5427 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5428 err = mp_copy(key->pubkey.z, mQ->z);
sPymbed 0:1387ff3eed4a 5429
sPymbed 0:1387ff3eed4a 5430 #ifdef FREESCALE_LTC_ECC
sPymbed 0:1387ff3eed4a 5431 /* use PKHA to compute u1*mG + u2*mQ */
sPymbed 0:1387ff3eed4a 5432 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5433 err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
sPymbed 0:1387ff3eed4a 5434 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5435 err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
sPymbed 0:1387ff3eed4a 5436 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5437 err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
sPymbed 0:1387ff3eed4a 5438 #else
sPymbed 0:1387ff3eed4a 5439 #ifndef ECC_SHAMIR
sPymbed 0:1387ff3eed4a 5440 {
sPymbed 0:1387ff3eed4a 5441 mp_digit mp = 0;
sPymbed 0:1387ff3eed4a 5442
sPymbed 0:1387ff3eed4a 5443 /* compute u1*mG + u2*mQ = mG */
sPymbed 0:1387ff3eed4a 5444 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5445 err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
sPymbed 0:1387ff3eed4a 5446 key->heap);
sPymbed 0:1387ff3eed4a 5447 }
sPymbed 0:1387ff3eed4a 5448 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5449 err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
sPymbed 0:1387ff3eed4a 5450 key->heap);
sPymbed 0:1387ff3eed4a 5451 }
sPymbed 0:1387ff3eed4a 5452
sPymbed 0:1387ff3eed4a 5453 /* find the montgomery mp */
sPymbed 0:1387ff3eed4a 5454 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5455 err = mp_montgomery_setup(curve->prime, &mp);
sPymbed 0:1387ff3eed4a 5456
sPymbed 0:1387ff3eed4a 5457 /* add them */
sPymbed 0:1387ff3eed4a 5458 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5459 err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
sPymbed 0:1387ff3eed4a 5460 curve->prime, mp);
sPymbed 0:1387ff3eed4a 5461
sPymbed 0:1387ff3eed4a 5462 /* reduce */
sPymbed 0:1387ff3eed4a 5463 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5464 err = ecc_map(mG, curve->prime, mp);
sPymbed 0:1387ff3eed4a 5465 }
sPymbed 0:1387ff3eed4a 5466 #else
sPymbed 0:1387ff3eed4a 5467 /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
sPymbed 0:1387ff3eed4a 5468 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5469 err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
sPymbed 0:1387ff3eed4a 5470 key->heap);
sPymbed 0:1387ff3eed4a 5471 }
sPymbed 0:1387ff3eed4a 5472 #endif /* ECC_SHAMIR */
sPymbed 0:1387ff3eed4a 5473 #endif /* FREESCALE_LTC_ECC */
sPymbed 0:1387ff3eed4a 5474 /* v = X_x1 mod n */
sPymbed 0:1387ff3eed4a 5475 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5476 err = mp_mod(mG->x, curve->order, v);
sPymbed 0:1387ff3eed4a 5477
sPymbed 0:1387ff3eed4a 5478 /* does v == r */
sPymbed 0:1387ff3eed4a 5479 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5480 if (mp_cmp(v, r) == MP_EQ)
sPymbed 0:1387ff3eed4a 5481 *res = 1;
sPymbed 0:1387ff3eed4a 5482 }
sPymbed 0:1387ff3eed4a 5483
sPymbed 0:1387ff3eed4a 5484 /* cleanup */
sPymbed 0:1387ff3eed4a 5485 wc_ecc_del_point_h(mG, key->heap);
sPymbed 0:1387ff3eed4a 5486 wc_ecc_del_point_h(mQ, key->heap);
sPymbed 0:1387ff3eed4a 5487
sPymbed 0:1387ff3eed4a 5488 mp_clear(e);
sPymbed 0:1387ff3eed4a 5489 if (did_init) {
sPymbed 0:1387ff3eed4a 5490 mp_clear(v);
sPymbed 0:1387ff3eed4a 5491 mp_clear(w);
sPymbed 0:1387ff3eed4a 5492 mp_clear(u1);
sPymbed 0:1387ff3eed4a 5493 mp_clear(u2);
sPymbed 0:1387ff3eed4a 5494 }
sPymbed 0:1387ff3eed4a 5495 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5496 XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5497 XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5498 XFREE(w, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5499 XFREE(v, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5500 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
sPymbed 0:1387ff3eed4a 5501 XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5502 #endif
sPymbed 0:1387ff3eed4a 5503 #endif
sPymbed 0:1387ff3eed4a 5504
sPymbed 0:1387ff3eed4a 5505 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 5506 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 5507
sPymbed 0:1387ff3eed4a 5508 #endif /* WOLFSSL_SP_MATH */
sPymbed 0:1387ff3eed4a 5509 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 5510
sPymbed 0:1387ff3eed4a 5511 return err;
sPymbed 0:1387ff3eed4a 5512 }
sPymbed 0:1387ff3eed4a 5513 #endif /* HAVE_ECC_VERIFY */
sPymbed 0:1387ff3eed4a 5514
sPymbed 0:1387ff3eed4a 5515 #ifdef HAVE_ECC_KEY_IMPORT
sPymbed 0:1387ff3eed4a 5516 /* import point from der */
sPymbed 0:1387ff3eed4a 5517 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
sPymbed 0:1387ff3eed4a 5518 ecc_point* point)
sPymbed 0:1387ff3eed4a 5519 {
sPymbed 0:1387ff3eed4a 5520 int err = 0;
sPymbed 0:1387ff3eed4a 5521 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5522 int compressed = 0;
sPymbed 0:1387ff3eed4a 5523 int keysize;
sPymbed 0:1387ff3eed4a 5524 byte pointType;
sPymbed 0:1387ff3eed4a 5525
sPymbed 0:1387ff3eed4a 5526 if (in == NULL || point == NULL || (curve_idx < 0) ||
sPymbed 0:1387ff3eed4a 5527 (wc_ecc_is_valid_idx(curve_idx) == 0))
sPymbed 0:1387ff3eed4a 5528 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5529
sPymbed 0:1387ff3eed4a 5530 /* must be odd */
sPymbed 0:1387ff3eed4a 5531 if ((inLen & 1) == 0) {
sPymbed 0:1387ff3eed4a 5532 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5533 }
sPymbed 0:1387ff3eed4a 5534
sPymbed 0:1387ff3eed4a 5535 /* init point */
sPymbed 0:1387ff3eed4a 5536 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 5537 point->x = (mp_int*)&point->xyz[0];
sPymbed 0:1387ff3eed4a 5538 point->y = (mp_int*)&point->xyz[1];
sPymbed 0:1387ff3eed4a 5539 point->z = (mp_int*)&point->xyz[2];
sPymbed 0:1387ff3eed4a 5540 alt_fp_init(point->x);
sPymbed 0:1387ff3eed4a 5541 alt_fp_init(point->y);
sPymbed 0:1387ff3eed4a 5542 alt_fp_init(point->z);
sPymbed 0:1387ff3eed4a 5543 #else
sPymbed 0:1387ff3eed4a 5544 err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
sPymbed 0:1387ff3eed4a 5545 #endif
sPymbed 0:1387ff3eed4a 5546 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 5547 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5548
sPymbed 0:1387ff3eed4a 5549 /* check for point type (4, 2, or 3) */
sPymbed 0:1387ff3eed4a 5550 pointType = in[0];
sPymbed 0:1387ff3eed4a 5551 if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
sPymbed 0:1387ff3eed4a 5552 pointType != ECC_POINT_COMP_ODD) {
sPymbed 0:1387ff3eed4a 5553 err = ASN_PARSE_E;
sPymbed 0:1387ff3eed4a 5554 }
sPymbed 0:1387ff3eed4a 5555
sPymbed 0:1387ff3eed4a 5556 if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
sPymbed 0:1387ff3eed4a 5557 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 5558 compressed = 1;
sPymbed 0:1387ff3eed4a 5559 #else
sPymbed 0:1387ff3eed4a 5560 err = NOT_COMPILED_IN;
sPymbed 0:1387ff3eed4a 5561 #endif
sPymbed 0:1387ff3eed4a 5562 }
sPymbed 0:1387ff3eed4a 5563
sPymbed 0:1387ff3eed4a 5564 /* adjust to skip first byte */
sPymbed 0:1387ff3eed4a 5565 inLen -= 1;
sPymbed 0:1387ff3eed4a 5566 in += 1;
sPymbed 0:1387ff3eed4a 5567
sPymbed 0:1387ff3eed4a 5568 /* calculate key size based on inLen / 2 */
sPymbed 0:1387ff3eed4a 5569 keysize = inLen>>1;
sPymbed 0:1387ff3eed4a 5570
sPymbed 0:1387ff3eed4a 5571 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5572 /* populate key->pubkey_raw */
sPymbed 0:1387ff3eed4a 5573 XMEMCPY(key->pubkey_raw, (byte*)in, sizeof(key->pubkey_raw));
sPymbed 0:1387ff3eed4a 5574 #endif
sPymbed 0:1387ff3eed4a 5575
sPymbed 0:1387ff3eed4a 5576 /* read data */
sPymbed 0:1387ff3eed4a 5577 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5578 err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);
sPymbed 0:1387ff3eed4a 5579
sPymbed 0:1387ff3eed4a 5580 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 5581 if (err == MP_OKAY && compressed == 1) { /* build y */
sPymbed 0:1387ff3eed4a 5582 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 5583 int did_init = 0;
sPymbed 0:1387ff3eed4a 5584 mp_int t1, t2;
sPymbed 0:1387ff3eed4a 5585 DECLARE_CURVE_SPECS(curve, 3);
sPymbed 0:1387ff3eed4a 5586
sPymbed 0:1387ff3eed4a 5587 ALLOC_CURVE_SPECS(3);
sPymbed 0:1387ff3eed4a 5588
sPymbed 0:1387ff3eed4a 5589 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
sPymbed 0:1387ff3eed4a 5590 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5591 else
sPymbed 0:1387ff3eed4a 5592 did_init = 1;
sPymbed 0:1387ff3eed4a 5593
sPymbed 0:1387ff3eed4a 5594 /* load curve info */
sPymbed 0:1387ff3eed4a 5595 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5596 err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
sPymbed 0:1387ff3eed4a 5597 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
sPymbed 0:1387ff3eed4a 5598 ECC_CURVE_FIELD_BF));
sPymbed 0:1387ff3eed4a 5599
sPymbed 0:1387ff3eed4a 5600 /* compute x^3 */
sPymbed 0:1387ff3eed4a 5601 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5602 err = mp_sqr(point->x, &t1);
sPymbed 0:1387ff3eed4a 5603 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5604 err = mp_mulmod(&t1, point->x, curve->prime, &t1);
sPymbed 0:1387ff3eed4a 5605
sPymbed 0:1387ff3eed4a 5606 /* compute x^3 + a*x */
sPymbed 0:1387ff3eed4a 5607 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5608 err = mp_mulmod(curve->Af, point->x, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 5609 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5610 err = mp_add(&t1, &t2, &t1);
sPymbed 0:1387ff3eed4a 5611
sPymbed 0:1387ff3eed4a 5612 /* compute x^3 + a*x + b */
sPymbed 0:1387ff3eed4a 5613 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5614 err = mp_add(&t1, curve->Bf, &t1);
sPymbed 0:1387ff3eed4a 5615
sPymbed 0:1387ff3eed4a 5616 /* compute sqrt(x^3 + a*x + b) */
sPymbed 0:1387ff3eed4a 5617 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5618 err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 5619
sPymbed 0:1387ff3eed4a 5620 /* adjust y */
sPymbed 0:1387ff3eed4a 5621 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5622 if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
sPymbed 0:1387ff3eed4a 5623 (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) {
sPymbed 0:1387ff3eed4a 5624 err = mp_mod(&t2, curve->prime, point->y);
sPymbed 0:1387ff3eed4a 5625 }
sPymbed 0:1387ff3eed4a 5626 else {
sPymbed 0:1387ff3eed4a 5627 err = mp_submod(curve->prime, &t2, curve->prime, point->y);
sPymbed 0:1387ff3eed4a 5628 }
sPymbed 0:1387ff3eed4a 5629 }
sPymbed 0:1387ff3eed4a 5630
sPymbed 0:1387ff3eed4a 5631 if (did_init) {
sPymbed 0:1387ff3eed4a 5632 mp_clear(&t2);
sPymbed 0:1387ff3eed4a 5633 mp_clear(&t1);
sPymbed 0:1387ff3eed4a 5634 }
sPymbed 0:1387ff3eed4a 5635
sPymbed 0:1387ff3eed4a 5636 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 5637 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 5638 #else
sPymbed 0:1387ff3eed4a 5639 sp_ecc_uncompress_256(point->x, pointType, point->y);
sPymbed 0:1387ff3eed4a 5640 #endif
sPymbed 0:1387ff3eed4a 5641 }
sPymbed 0:1387ff3eed4a 5642 #endif
sPymbed 0:1387ff3eed4a 5643
sPymbed 0:1387ff3eed4a 5644 if (err == MP_OKAY && compressed == 0)
sPymbed 0:1387ff3eed4a 5645 err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize);
sPymbed 0:1387ff3eed4a 5646 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5647 err = mp_set(point->z, 1);
sPymbed 0:1387ff3eed4a 5648
sPymbed 0:1387ff3eed4a 5649 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5650 mp_clear(point->x);
sPymbed 0:1387ff3eed4a 5651 mp_clear(point->y);
sPymbed 0:1387ff3eed4a 5652 mp_clear(point->z);
sPymbed 0:1387ff3eed4a 5653 }
sPymbed 0:1387ff3eed4a 5654
sPymbed 0:1387ff3eed4a 5655 #else
sPymbed 0:1387ff3eed4a 5656 err = NOT_COMPILED_IN;
sPymbed 0:1387ff3eed4a 5657 (void)in;
sPymbed 0:1387ff3eed4a 5658 (void)inLen;
sPymbed 0:1387ff3eed4a 5659 (void)curve_idx;
sPymbed 0:1387ff3eed4a 5660 (void)point;
sPymbed 0:1387ff3eed4a 5661 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 5662
sPymbed 0:1387ff3eed4a 5663 return err;
sPymbed 0:1387ff3eed4a 5664 }
sPymbed 0:1387ff3eed4a 5665 #endif /* HAVE_ECC_KEY_IMPORT */
sPymbed 0:1387ff3eed4a 5666
sPymbed 0:1387ff3eed4a 5667 #ifdef HAVE_ECC_KEY_EXPORT
sPymbed 0:1387ff3eed4a 5668 /* export point to der */
sPymbed 0:1387ff3eed4a 5669 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
sPymbed 0:1387ff3eed4a 5670 word32* outLen)
sPymbed 0:1387ff3eed4a 5671 {
sPymbed 0:1387ff3eed4a 5672 int ret = MP_OKAY;
sPymbed 0:1387ff3eed4a 5673 word32 numlen;
sPymbed 0:1387ff3eed4a 5674 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5675 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5676 byte* buf;
sPymbed 0:1387ff3eed4a 5677 #else
sPymbed 0:1387ff3eed4a 5678 byte buf[ECC_BUFSIZE];
sPymbed 0:1387ff3eed4a 5679 #endif
sPymbed 0:1387ff3eed4a 5680 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 5681
sPymbed 0:1387ff3eed4a 5682 if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
sPymbed 0:1387ff3eed4a 5683 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5684
sPymbed 0:1387ff3eed4a 5685 /* return length needed only */
sPymbed 0:1387ff3eed4a 5686 if (point != NULL && out == NULL && outLen != NULL) {
sPymbed 0:1387ff3eed4a 5687 numlen = ecc_sets[curve_idx].size;
sPymbed 0:1387ff3eed4a 5688 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5689 return LENGTH_ONLY_E;
sPymbed 0:1387ff3eed4a 5690 }
sPymbed 0:1387ff3eed4a 5691
sPymbed 0:1387ff3eed4a 5692 if (point == NULL || out == NULL || outLen == NULL)
sPymbed 0:1387ff3eed4a 5693 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5694
sPymbed 0:1387ff3eed4a 5695 numlen = ecc_sets[curve_idx].size;
sPymbed 0:1387ff3eed4a 5696
sPymbed 0:1387ff3eed4a 5697 if (*outLen < (1 + 2*numlen)) {
sPymbed 0:1387ff3eed4a 5698 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5699 return BUFFER_E;
sPymbed 0:1387ff3eed4a 5700 }
sPymbed 0:1387ff3eed4a 5701
sPymbed 0:1387ff3eed4a 5702 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5703 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 5704 ret = BAD_COND_E;
sPymbed 0:1387ff3eed4a 5705
sPymbed 0:1387ff3eed4a 5706 #else
sPymbed 0:1387ff3eed4a 5707
sPymbed 0:1387ff3eed4a 5708 /* store byte point type */
sPymbed 0:1387ff3eed4a 5709 out[0] = ECC_POINT_UNCOMP;
sPymbed 0:1387ff3eed4a 5710
sPymbed 0:1387ff3eed4a 5711 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5712 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5713 if (buf == NULL)
sPymbed 0:1387ff3eed4a 5714 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5715 #endif
sPymbed 0:1387ff3eed4a 5716
sPymbed 0:1387ff3eed4a 5717 /* pad and store x */
sPymbed 0:1387ff3eed4a 5718 XMEMSET(buf, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5719 ret = mp_to_unsigned_bin(point->x, buf +
sPymbed 0:1387ff3eed4a 5720 (numlen - mp_unsigned_bin_size(point->x)));
sPymbed 0:1387ff3eed4a 5721 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 5722 goto done;
sPymbed 0:1387ff3eed4a 5723 XMEMCPY(out+1, buf, numlen);
sPymbed 0:1387ff3eed4a 5724
sPymbed 0:1387ff3eed4a 5725 /* pad and store y */
sPymbed 0:1387ff3eed4a 5726 XMEMSET(buf, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5727 ret = mp_to_unsigned_bin(point->y, buf +
sPymbed 0:1387ff3eed4a 5728 (numlen - mp_unsigned_bin_size(point->y)));
sPymbed 0:1387ff3eed4a 5729 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 5730 goto done;
sPymbed 0:1387ff3eed4a 5731 XMEMCPY(out+1+numlen, buf, numlen);
sPymbed 0:1387ff3eed4a 5732
sPymbed 0:1387ff3eed4a 5733 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5734
sPymbed 0:1387ff3eed4a 5735 done:
sPymbed 0:1387ff3eed4a 5736 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5737 XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5738 #endif
sPymbed 0:1387ff3eed4a 5739 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 5740
sPymbed 0:1387ff3eed4a 5741 return ret;
sPymbed 0:1387ff3eed4a 5742 }
sPymbed 0:1387ff3eed4a 5743
sPymbed 0:1387ff3eed4a 5744
sPymbed 0:1387ff3eed4a 5745 /* export public ECC key in ANSI X9.63 format */
sPymbed 0:1387ff3eed4a 5746 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
sPymbed 0:1387ff3eed4a 5747 {
sPymbed 0:1387ff3eed4a 5748 int ret = MP_OKAY;
sPymbed 0:1387ff3eed4a 5749 word32 numlen;
sPymbed 0:1387ff3eed4a 5750 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5751 byte* buf;
sPymbed 0:1387ff3eed4a 5752 #else
sPymbed 0:1387ff3eed4a 5753 byte buf[ECC_BUFSIZE];
sPymbed 0:1387ff3eed4a 5754 #endif
sPymbed 0:1387ff3eed4a 5755 word32 pubxlen, pubylen;
sPymbed 0:1387ff3eed4a 5756
sPymbed 0:1387ff3eed4a 5757 /* return length needed only */
sPymbed 0:1387ff3eed4a 5758 if (key != NULL && out == NULL && outLen != NULL) {
sPymbed 0:1387ff3eed4a 5759 numlen = key->dp->size;
sPymbed 0:1387ff3eed4a 5760 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5761 return LENGTH_ONLY_E;
sPymbed 0:1387ff3eed4a 5762 }
sPymbed 0:1387ff3eed4a 5763
sPymbed 0:1387ff3eed4a 5764 if (key == NULL || out == NULL || outLen == NULL)
sPymbed 0:1387ff3eed4a 5765 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5766
sPymbed 0:1387ff3eed4a 5767 if (key->type == ECC_PRIVATEKEY_ONLY)
sPymbed 0:1387ff3eed4a 5768 return ECC_PRIVATEONLY_E;
sPymbed 0:1387ff3eed4a 5769
sPymbed 0:1387ff3eed4a 5770 if (wc_ecc_is_valid_idx(key->idx) == 0) {
sPymbed 0:1387ff3eed4a 5771 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 5772 }
sPymbed 0:1387ff3eed4a 5773 numlen = key->dp->size;
sPymbed 0:1387ff3eed4a 5774
sPymbed 0:1387ff3eed4a 5775 /* verify room in out buffer */
sPymbed 0:1387ff3eed4a 5776 if (*outLen < (1 + 2*numlen)) {
sPymbed 0:1387ff3eed4a 5777 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5778 return BUFFER_E;
sPymbed 0:1387ff3eed4a 5779 }
sPymbed 0:1387ff3eed4a 5780
sPymbed 0:1387ff3eed4a 5781 /* verify public key length is less than key size */
sPymbed 0:1387ff3eed4a 5782 pubxlen = mp_unsigned_bin_size(key->pubkey.x);
sPymbed 0:1387ff3eed4a 5783 pubylen = mp_unsigned_bin_size(key->pubkey.y);
sPymbed 0:1387ff3eed4a 5784 if ((pubxlen > numlen) || (pubylen > numlen)) {
sPymbed 0:1387ff3eed4a 5785 WOLFSSL_MSG("Public key x/y invalid!");
sPymbed 0:1387ff3eed4a 5786 return BUFFER_E;
sPymbed 0:1387ff3eed4a 5787 }
sPymbed 0:1387ff3eed4a 5788
sPymbed 0:1387ff3eed4a 5789 /* store byte point type */
sPymbed 0:1387ff3eed4a 5790 out[0] = ECC_POINT_UNCOMP;
sPymbed 0:1387ff3eed4a 5791
sPymbed 0:1387ff3eed4a 5792 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5793 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5794 if (buf == NULL)
sPymbed 0:1387ff3eed4a 5795 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5796 #endif
sPymbed 0:1387ff3eed4a 5797
sPymbed 0:1387ff3eed4a 5798 /* pad and store x */
sPymbed 0:1387ff3eed4a 5799 XMEMSET(buf, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5800 ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
sPymbed 0:1387ff3eed4a 5801 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 5802 goto done;
sPymbed 0:1387ff3eed4a 5803 XMEMCPY(out+1, buf, numlen);
sPymbed 0:1387ff3eed4a 5804
sPymbed 0:1387ff3eed4a 5805 /* pad and store y */
sPymbed 0:1387ff3eed4a 5806 XMEMSET(buf, 0, ECC_BUFSIZE);
sPymbed 0:1387ff3eed4a 5807 ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
sPymbed 0:1387ff3eed4a 5808 if (ret != MP_OKAY)
sPymbed 0:1387ff3eed4a 5809 goto done;
sPymbed 0:1387ff3eed4a 5810 XMEMCPY(out+1+numlen, buf, numlen);
sPymbed 0:1387ff3eed4a 5811
sPymbed 0:1387ff3eed4a 5812 *outLen = 1 + 2*numlen;
sPymbed 0:1387ff3eed4a 5813
sPymbed 0:1387ff3eed4a 5814 done:
sPymbed 0:1387ff3eed4a 5815 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5816 XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 5817 #endif
sPymbed 0:1387ff3eed4a 5818
sPymbed 0:1387ff3eed4a 5819 return ret;
sPymbed 0:1387ff3eed4a 5820 }
sPymbed 0:1387ff3eed4a 5821
sPymbed 0:1387ff3eed4a 5822
sPymbed 0:1387ff3eed4a 5823 /* export public ECC key in ANSI X9.63 format, extended with
sPymbed 0:1387ff3eed4a 5824 * compression option */
sPymbed 0:1387ff3eed4a 5825 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
sPymbed 0:1387ff3eed4a 5826 int compressed)
sPymbed 0:1387ff3eed4a 5827 {
sPymbed 0:1387ff3eed4a 5828 if (compressed == 0)
sPymbed 0:1387ff3eed4a 5829 return wc_ecc_export_x963(key, out, outLen);
sPymbed 0:1387ff3eed4a 5830 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 5831 else
sPymbed 0:1387ff3eed4a 5832 return wc_ecc_export_x963_compressed(key, out, outLen);
sPymbed 0:1387ff3eed4a 5833 #else
sPymbed 0:1387ff3eed4a 5834 return NOT_COMPILED_IN;
sPymbed 0:1387ff3eed4a 5835 #endif
sPymbed 0:1387ff3eed4a 5836 }
sPymbed 0:1387ff3eed4a 5837 #endif /* HAVE_ECC_KEY_EXPORT */
sPymbed 0:1387ff3eed4a 5838
sPymbed 0:1387ff3eed4a 5839
sPymbed 0:1387ff3eed4a 5840 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 5841
sPymbed 0:1387ff3eed4a 5842 /* is ecc point on curve described by dp ? */
sPymbed 0:1387ff3eed4a 5843 int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
sPymbed 0:1387ff3eed4a 5844 {
sPymbed 0:1387ff3eed4a 5845 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 5846 int err;
sPymbed 0:1387ff3eed4a 5847 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5848 mp_int* t1 = NULL;
sPymbed 0:1387ff3eed4a 5849 mp_int* t2 = NULL;
sPymbed 0:1387ff3eed4a 5850 #else
sPymbed 0:1387ff3eed4a 5851 mp_int t1[1], t2[1];
sPymbed 0:1387ff3eed4a 5852 #endif
sPymbed 0:1387ff3eed4a 5853
sPymbed 0:1387ff3eed4a 5854 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5855 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5856 if (t1 == NULL)
sPymbed 0:1387ff3eed4a 5857 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5858 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5859 if (t2 == NULL) {
sPymbed 0:1387ff3eed4a 5860 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5861 return MEMORY_E;
sPymbed 0:1387ff3eed4a 5862 }
sPymbed 0:1387ff3eed4a 5863 #endif
sPymbed 0:1387ff3eed4a 5864
sPymbed 0:1387ff3eed4a 5865 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 5866 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5867 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5868 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5869 #endif
sPymbed 0:1387ff3eed4a 5870 return err;
sPymbed 0:1387ff3eed4a 5871 }
sPymbed 0:1387ff3eed4a 5872
sPymbed 0:1387ff3eed4a 5873 /* compute y^2 */
sPymbed 0:1387ff3eed4a 5874 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5875 err = mp_sqr(ecp->y, t1);
sPymbed 0:1387ff3eed4a 5876
sPymbed 0:1387ff3eed4a 5877 /* compute x^3 */
sPymbed 0:1387ff3eed4a 5878 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5879 err = mp_sqr(ecp->x, t2);
sPymbed 0:1387ff3eed4a 5880 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5881 err = mp_mod(t2, prime, t2);
sPymbed 0:1387ff3eed4a 5882 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5883 err = mp_mul(ecp->x, t2, t2);
sPymbed 0:1387ff3eed4a 5884
sPymbed 0:1387ff3eed4a 5885 /* compute y^2 - x^3 */
sPymbed 0:1387ff3eed4a 5886 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5887 err = mp_sub(t1, t2, t1);
sPymbed 0:1387ff3eed4a 5888
sPymbed 0:1387ff3eed4a 5889 /* Determine if curve "a" should be used in calc */
sPymbed 0:1387ff3eed4a 5890 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 5891 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5892 /* Use a and prime to determine if a == 3 */
sPymbed 0:1387ff3eed4a 5893 err = mp_set(t2, 0);
sPymbed 0:1387ff3eed4a 5894 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5895 err = mp_submod(prime, a, prime, t2);
sPymbed 0:1387ff3eed4a 5896 }
sPymbed 0:1387ff3eed4a 5897 if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
sPymbed 0:1387ff3eed4a 5898 /* compute y^2 - x^3 + a*x */
sPymbed 0:1387ff3eed4a 5899 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5900 err = mp_mulmod(t2, ecp->x, prime, t2);
sPymbed 0:1387ff3eed4a 5901 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5902 err = mp_addmod(t1, t2, prime, t1);
sPymbed 0:1387ff3eed4a 5903 }
sPymbed 0:1387ff3eed4a 5904 else
sPymbed 0:1387ff3eed4a 5905 #endif /* WOLFSSL_CUSTOM_CURVES */
sPymbed 0:1387ff3eed4a 5906 {
sPymbed 0:1387ff3eed4a 5907 /* assumes "a" == 3 */
sPymbed 0:1387ff3eed4a 5908 (void)a;
sPymbed 0:1387ff3eed4a 5909
sPymbed 0:1387ff3eed4a 5910 /* compute y^2 - x^3 + 3x */
sPymbed 0:1387ff3eed4a 5911 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5912 err = mp_add(t1, ecp->x, t1);
sPymbed 0:1387ff3eed4a 5913 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5914 err = mp_add(t1, ecp->x, t1);
sPymbed 0:1387ff3eed4a 5915 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5916 err = mp_add(t1, ecp->x, t1);
sPymbed 0:1387ff3eed4a 5917 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5918 err = mp_mod(t1, prime, t1);
sPymbed 0:1387ff3eed4a 5919 }
sPymbed 0:1387ff3eed4a 5920
sPymbed 0:1387ff3eed4a 5921 /* adjust range (0, prime) */
sPymbed 0:1387ff3eed4a 5922 while (err == MP_OKAY && mp_isneg(t1)) {
sPymbed 0:1387ff3eed4a 5923 err = mp_add(t1, prime, t1);
sPymbed 0:1387ff3eed4a 5924 }
sPymbed 0:1387ff3eed4a 5925 while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
sPymbed 0:1387ff3eed4a 5926 err = mp_sub(t1, prime, t1);
sPymbed 0:1387ff3eed4a 5927 }
sPymbed 0:1387ff3eed4a 5928
sPymbed 0:1387ff3eed4a 5929 /* compare to b */
sPymbed 0:1387ff3eed4a 5930 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5931 if (mp_cmp(t1, b) != MP_EQ) {
sPymbed 0:1387ff3eed4a 5932 err = MP_VAL;
sPymbed 0:1387ff3eed4a 5933 } else {
sPymbed 0:1387ff3eed4a 5934 err = MP_OKAY;
sPymbed 0:1387ff3eed4a 5935 }
sPymbed 0:1387ff3eed4a 5936 }
sPymbed 0:1387ff3eed4a 5937
sPymbed 0:1387ff3eed4a 5938 mp_clear(t1);
sPymbed 0:1387ff3eed4a 5939 mp_clear(t2);
sPymbed 0:1387ff3eed4a 5940 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 5941 XFREE(t2, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5942 XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 5943 #endif
sPymbed 0:1387ff3eed4a 5944
sPymbed 0:1387ff3eed4a 5945 return err;
sPymbed 0:1387ff3eed4a 5946 #else
sPymbed 0:1387ff3eed4a 5947 (void)a;
sPymbed 0:1387ff3eed4a 5948 (void)b;
sPymbed 0:1387ff3eed4a 5949 (void)prime;
sPymbed 0:1387ff3eed4a 5950
sPymbed 0:1387ff3eed4a 5951 return sp_ecc_is_point_256(ecp->x, ecp->y);
sPymbed 0:1387ff3eed4a 5952 #endif
sPymbed 0:1387ff3eed4a 5953 }
sPymbed 0:1387ff3eed4a 5954
sPymbed 0:1387ff3eed4a 5955 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 5956 /* validate privkey * generator == pubkey, 0 on success */
sPymbed 0:1387ff3eed4a 5957 static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
sPymbed 0:1387ff3eed4a 5958 {
sPymbed 0:1387ff3eed4a 5959 int err = MP_OKAY;
sPymbed 0:1387ff3eed4a 5960 ecc_point* base = NULL;
sPymbed 0:1387ff3eed4a 5961 ecc_point* res = NULL;
sPymbed 0:1387ff3eed4a 5962 DECLARE_CURVE_SPECS(curve, 2);
sPymbed 0:1387ff3eed4a 5963
sPymbed 0:1387ff3eed4a 5964 if (key == NULL)
sPymbed 0:1387ff3eed4a 5965 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 5966
sPymbed 0:1387ff3eed4a 5967 ALLOC_CURVE_SPECS(2);
sPymbed 0:1387ff3eed4a 5968
sPymbed 0:1387ff3eed4a 5969 res = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 5970 if (res == NULL)
sPymbed 0:1387ff3eed4a 5971 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5972
sPymbed 0:1387ff3eed4a 5973 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 5974 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 5975 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 5976 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5977 err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap);
sPymbed 0:1387ff3eed4a 5978 }
sPymbed 0:1387ff3eed4a 5979 else
sPymbed 0:1387ff3eed4a 5980 #endif
sPymbed 0:1387ff3eed4a 5981 #endif
sPymbed 0:1387ff3eed4a 5982 {
sPymbed 0:1387ff3eed4a 5983 base = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 5984 if (base == NULL)
sPymbed 0:1387ff3eed4a 5985 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 5986
sPymbed 0:1387ff3eed4a 5987 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 5988 /* load curve info */
sPymbed 0:1387ff3eed4a 5989 err = wc_ecc_curve_load(key->dp, &curve,
sPymbed 0:1387ff3eed4a 5990 (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
sPymbed 0:1387ff3eed4a 5991 }
sPymbed 0:1387ff3eed4a 5992
sPymbed 0:1387ff3eed4a 5993 /* set up base generator */
sPymbed 0:1387ff3eed4a 5994 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5995 err = mp_copy(curve->Gx, base->x);
sPymbed 0:1387ff3eed4a 5996 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5997 err = mp_copy(curve->Gy, base->y);
sPymbed 0:1387ff3eed4a 5998 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 5999 err = mp_set(base->z, 1);
sPymbed 0:1387ff3eed4a 6000
sPymbed 0:1387ff3eed4a 6001 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6002 err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap);
sPymbed 0:1387ff3eed4a 6003 }
sPymbed 0:1387ff3eed4a 6004
sPymbed 0:1387ff3eed4a 6005 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6006 /* compare result to public key */
sPymbed 0:1387ff3eed4a 6007 if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
sPymbed 0:1387ff3eed4a 6008 mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
sPymbed 0:1387ff3eed4a 6009 mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
sPymbed 0:1387ff3eed4a 6010 /* didn't match */
sPymbed 0:1387ff3eed4a 6011 err = ECC_PRIV_KEY_E;
sPymbed 0:1387ff3eed4a 6012 }
sPymbed 0:1387ff3eed4a 6013 }
sPymbed 0:1387ff3eed4a 6014
sPymbed 0:1387ff3eed4a 6015 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 6016 wc_ecc_del_point_h(res, key->heap);
sPymbed 0:1387ff3eed4a 6017 wc_ecc_del_point_h(base, key->heap);
sPymbed 0:1387ff3eed4a 6018 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6019
sPymbed 0:1387ff3eed4a 6020 return err;
sPymbed 0:1387ff3eed4a 6021 }
sPymbed 0:1387ff3eed4a 6022 #endif
sPymbed 0:1387ff3eed4a 6023
sPymbed 0:1387ff3eed4a 6024 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
sPymbed 0:1387ff3eed4a 6025
sPymbed 0:1387ff3eed4a 6026 /* check privkey generator helper, creates prime needed */
sPymbed 0:1387ff3eed4a 6027 static int ecc_check_privkey_gen_helper(ecc_key* key)
sPymbed 0:1387ff3eed4a 6028 {
sPymbed 0:1387ff3eed4a 6029 int err;
sPymbed 0:1387ff3eed4a 6030 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6031 DECLARE_CURVE_SPECS(curve, 2);
sPymbed 0:1387ff3eed4a 6032 #endif
sPymbed 0:1387ff3eed4a 6033
sPymbed 0:1387ff3eed4a 6034 if (key == NULL)
sPymbed 0:1387ff3eed4a 6035 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6036
sPymbed 0:1387ff3eed4a 6037 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6038 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 6039 err = BAD_COND_E;
sPymbed 0:1387ff3eed4a 6040
sPymbed 0:1387ff3eed4a 6041 #else
sPymbed 0:1387ff3eed4a 6042 ALLOC_CURVE_SPECS(2);
sPymbed 0:1387ff3eed4a 6043
sPymbed 0:1387ff3eed4a 6044 /* load curve info */
sPymbed 0:1387ff3eed4a 6045 err = wc_ecc_curve_load(key->dp, &curve,
sPymbed 0:1387ff3eed4a 6046 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
sPymbed 0:1387ff3eed4a 6047
sPymbed 0:1387ff3eed4a 6048 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6049 err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
sPymbed 0:1387ff3eed4a 6050
sPymbed 0:1387ff3eed4a 6051 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 6052 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6053
sPymbed 0:1387ff3eed4a 6054 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6055
sPymbed 0:1387ff3eed4a 6056 return err;
sPymbed 0:1387ff3eed4a 6057 }
sPymbed 0:1387ff3eed4a 6058
sPymbed 0:1387ff3eed4a 6059 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
sPymbed 0:1387ff3eed4a 6060
sPymbed 0:1387ff3eed4a 6061
sPymbed 0:1387ff3eed4a 6062 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)
sPymbed 0:1387ff3eed4a 6063 /* validate order * pubkey = point at infinity, 0 on success */
sPymbed 0:1387ff3eed4a 6064 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
sPymbed 0:1387ff3eed4a 6065 mp_int* prime, mp_int* order)
sPymbed 0:1387ff3eed4a 6066 {
sPymbed 0:1387ff3eed4a 6067 ecc_point* inf = NULL;
sPymbed 0:1387ff3eed4a 6068 int err;
sPymbed 0:1387ff3eed4a 6069
sPymbed 0:1387ff3eed4a 6070 if (key == NULL)
sPymbed 0:1387ff3eed4a 6071 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6072
sPymbed 0:1387ff3eed4a 6073 inf = wc_ecc_new_point_h(key->heap);
sPymbed 0:1387ff3eed4a 6074 if (inf == NULL)
sPymbed 0:1387ff3eed4a 6075 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 6076 else {
sPymbed 0:1387ff3eed4a 6077 #ifdef WOLFSSL_HAVE_SP_ECC
sPymbed 0:1387ff3eed4a 6078 #ifndef WOLFSSL_SP_NO_256
sPymbed 0:1387ff3eed4a 6079 if (key->idx != ECC_CUSTOM_IDX &&
sPymbed 0:1387ff3eed4a 6080 ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 6081 err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
sPymbed 0:1387ff3eed4a 6082 }
sPymbed 0:1387ff3eed4a 6083 else
sPymbed 0:1387ff3eed4a 6084 #endif
sPymbed 0:1387ff3eed4a 6085 #endif
sPymbed 0:1387ff3eed4a 6086 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 6087 err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
sPymbed 0:1387ff3eed4a 6088 if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
sPymbed 0:1387ff3eed4a 6089 err = ECC_INF_E;
sPymbed 0:1387ff3eed4a 6090 #else
sPymbed 0:1387ff3eed4a 6091 (void)a;
sPymbed 0:1387ff3eed4a 6092 (void)prime;
sPymbed 0:1387ff3eed4a 6093
sPymbed 0:1387ff3eed4a 6094 err = WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 6095 #endif
sPymbed 0:1387ff3eed4a 6096 }
sPymbed 0:1387ff3eed4a 6097
sPymbed 0:1387ff3eed4a 6098 wc_ecc_del_point_h(inf, key->heap);
sPymbed 0:1387ff3eed4a 6099
sPymbed 0:1387ff3eed4a 6100 return err;
sPymbed 0:1387ff3eed4a 6101 }
sPymbed 0:1387ff3eed4a 6102 #endif
sPymbed 0:1387ff3eed4a 6103 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6104
sPymbed 0:1387ff3eed4a 6105
sPymbed 0:1387ff3eed4a 6106 /* perform sanity checks on ecc key validity, 0 on success */
sPymbed 0:1387ff3eed4a 6107 int wc_ecc_check_key(ecc_key* key)
sPymbed 0:1387ff3eed4a 6108 {
sPymbed 0:1387ff3eed4a 6109 int err;
sPymbed 0:1387ff3eed4a 6110 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 6111 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6112 mp_int* b = NULL;
sPymbed 0:1387ff3eed4a 6113 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 6114 DECLARE_CURVE_SPECS(curve, 4);
sPymbed 0:1387ff3eed4a 6115 #else
sPymbed 0:1387ff3eed4a 6116 #ifndef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6117 mp_int b_lcl;
sPymbed 0:1387ff3eed4a 6118 #endif
sPymbed 0:1387ff3eed4a 6119 DECLARE_CURVE_SPECS(curve, 3);
sPymbed 0:1387ff3eed4a 6120 #endif /* USE_ECC_B_PARAM */
sPymbed 0:1387ff3eed4a 6121 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6122
sPymbed 0:1387ff3eed4a 6123 if (key == NULL)
sPymbed 0:1387ff3eed4a 6124 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6125
sPymbed 0:1387ff3eed4a 6126 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6127
sPymbed 0:1387ff3eed4a 6128 if (key->slot == ATECC_INVALID_SLOT)
sPymbed 0:1387ff3eed4a 6129 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6130
sPymbed 0:1387ff3eed4a 6131 err = 0; /* consider key check success on ECC508A */
sPymbed 0:1387ff3eed4a 6132
sPymbed 0:1387ff3eed4a 6133 #else
sPymbed 0:1387ff3eed4a 6134 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 6135 ALLOC_CURVE_SPECS(4);
sPymbed 0:1387ff3eed4a 6136 #else
sPymbed 0:1387ff3eed4a 6137 ALLOC_CURVE_SPECS(3);
sPymbed 0:1387ff3eed4a 6138 #ifndef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6139 b = &b_lcl;
sPymbed 0:1387ff3eed4a 6140 #else
sPymbed 0:1387ff3eed4a 6141 b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6142 if (b == NULL) {
sPymbed 0:1387ff3eed4a 6143 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6144 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6145 }
sPymbed 0:1387ff3eed4a 6146 #endif
sPymbed 0:1387ff3eed4a 6147 XMEMSET(b, 0, sizeof(mp_int));
sPymbed 0:1387ff3eed4a 6148 #endif
sPymbed 0:1387ff3eed4a 6149
sPymbed 0:1387ff3eed4a 6150 /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
sPymbed 0:1387ff3eed4a 6151 /* pubkey point cannot be at infinity */
sPymbed 0:1387ff3eed4a 6152 if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
sPymbed 0:1387ff3eed4a 6153 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6154 XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6155 #endif
sPymbed 0:1387ff3eed4a 6156 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6157 return ECC_INF_E;
sPymbed 0:1387ff3eed4a 6158 }
sPymbed 0:1387ff3eed4a 6159
sPymbed 0:1387ff3eed4a 6160 /* load curve info */
sPymbed 0:1387ff3eed4a 6161 err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
sPymbed 0:1387ff3eed4a 6162 ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER
sPymbed 0:1387ff3eed4a 6163 #ifdef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 6164 | ECC_CURVE_FIELD_BF
sPymbed 0:1387ff3eed4a 6165 #endif
sPymbed 0:1387ff3eed4a 6166 ));
sPymbed 0:1387ff3eed4a 6167
sPymbed 0:1387ff3eed4a 6168 #ifndef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 6169 /* load curve b parameter */
sPymbed 0:1387ff3eed4a 6170 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6171 err = mp_init(b);
sPymbed 0:1387ff3eed4a 6172 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6173 err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6174 #else
sPymbed 0:1387ff3eed4a 6175 b = curve->Bf;
sPymbed 0:1387ff3eed4a 6176 #endif
sPymbed 0:1387ff3eed4a 6177
sPymbed 0:1387ff3eed4a 6178 /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
sPymbed 0:1387ff3eed4a 6179 /* Qx must be in the range [0, p-1] */
sPymbed 0:1387ff3eed4a 6180 if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT)
sPymbed 0:1387ff3eed4a 6181 err = ECC_OUT_OF_RANGE_E;
sPymbed 0:1387ff3eed4a 6182
sPymbed 0:1387ff3eed4a 6183 /* Qy must be in the range [0, p-1] */
sPymbed 0:1387ff3eed4a 6184 if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT)
sPymbed 0:1387ff3eed4a 6185 err = ECC_OUT_OF_RANGE_E;
sPymbed 0:1387ff3eed4a 6186
sPymbed 0:1387ff3eed4a 6187 /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */
sPymbed 0:1387ff3eed4a 6188 /* make sure point is actually on curve */
sPymbed 0:1387ff3eed4a 6189 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6190 err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
sPymbed 0:1387ff3eed4a 6191
sPymbed 0:1387ff3eed4a 6192 /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */
sPymbed 0:1387ff3eed4a 6193 /* pubkey * order must be at infinity */
sPymbed 0:1387ff3eed4a 6194 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6195 err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime,
sPymbed 0:1387ff3eed4a 6196 curve->order);
sPymbed 0:1387ff3eed4a 6197
sPymbed 0:1387ff3eed4a 6198 /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
sPymbed 0:1387ff3eed4a 6199 /* private * base generator must equal pubkey */
sPymbed 0:1387ff3eed4a 6200 if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
sPymbed 0:1387ff3eed4a 6201 err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
sPymbed 0:1387ff3eed4a 6202
sPymbed 0:1387ff3eed4a 6203 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 6204
sPymbed 0:1387ff3eed4a 6205 #ifndef USE_ECC_B_PARAM
sPymbed 0:1387ff3eed4a 6206 mp_clear(b);
sPymbed 0:1387ff3eed4a 6207 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6208 XFREE(b, key->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6209 #endif
sPymbed 0:1387ff3eed4a 6210 #endif
sPymbed 0:1387ff3eed4a 6211
sPymbed 0:1387ff3eed4a 6212 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6213
sPymbed 0:1387ff3eed4a 6214 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6215 #else
sPymbed 0:1387ff3eed4a 6216 if (key == NULL)
sPymbed 0:1387ff3eed4a 6217 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6218
sPymbed 0:1387ff3eed4a 6219 /* pubkey point cannot be at infinity */
sPymbed 0:1387ff3eed4a 6220 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
sPymbed 0:1387ff3eed4a 6221 err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k,
sPymbed 0:1387ff3eed4a 6222 key->heap);
sPymbed 0:1387ff3eed4a 6223 }
sPymbed 0:1387ff3eed4a 6224 else
sPymbed 0:1387ff3eed4a 6225 err = WC_KEY_SIZE_E;
sPymbed 0:1387ff3eed4a 6226 #endif
sPymbed 0:1387ff3eed4a 6227
sPymbed 0:1387ff3eed4a 6228 return err;
sPymbed 0:1387ff3eed4a 6229 }
sPymbed 0:1387ff3eed4a 6230
sPymbed 0:1387ff3eed4a 6231 #ifdef HAVE_ECC_KEY_IMPORT
sPymbed 0:1387ff3eed4a 6232 /* import public ECC key in ANSI X9.63 format */
sPymbed 0:1387ff3eed4a 6233 int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
sPymbed 0:1387ff3eed4a 6234 int curve_id)
sPymbed 0:1387ff3eed4a 6235 {
sPymbed 0:1387ff3eed4a 6236 int err = MP_OKAY;
sPymbed 0:1387ff3eed4a 6237 int compressed = 0;
sPymbed 0:1387ff3eed4a 6238 int keysize = 0;
sPymbed 0:1387ff3eed4a 6239 byte pointType;
sPymbed 0:1387ff3eed4a 6240
sPymbed 0:1387ff3eed4a 6241 if (in == NULL || key == NULL)
sPymbed 0:1387ff3eed4a 6242 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6243
sPymbed 0:1387ff3eed4a 6244 /* must be odd */
sPymbed 0:1387ff3eed4a 6245 if ((inLen & 1) == 0) {
sPymbed 0:1387ff3eed4a 6246 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6247 }
sPymbed 0:1387ff3eed4a 6248
sPymbed 0:1387ff3eed4a 6249 /* make sure required variables are reset */
sPymbed 0:1387ff3eed4a 6250 wc_ecc_reset(key);
sPymbed 0:1387ff3eed4a 6251
sPymbed 0:1387ff3eed4a 6252 /* init key */
sPymbed 0:1387ff3eed4a 6253 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 6254 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
sPymbed 0:1387ff3eed4a 6255 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
sPymbed 0:1387ff3eed4a 6256 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
sPymbed 0:1387ff3eed4a 6257 alt_fp_init(key->pubkey.x);
sPymbed 0:1387ff3eed4a 6258 alt_fp_init(key->pubkey.y);
sPymbed 0:1387ff3eed4a 6259 alt_fp_init(key->pubkey.z);
sPymbed 0:1387ff3eed4a 6260 err = mp_init(&key->k);
sPymbed 0:1387ff3eed4a 6261 #else
sPymbed 0:1387ff3eed4a 6262 err = mp_init_multi(&key->k,
sPymbed 0:1387ff3eed4a 6263 key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
sPymbed 0:1387ff3eed4a 6264 #endif
sPymbed 0:1387ff3eed4a 6265 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 6266 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6267
sPymbed 0:1387ff3eed4a 6268 /* check for point type (4, 2, or 3) */
sPymbed 0:1387ff3eed4a 6269 pointType = in[0];
sPymbed 0:1387ff3eed4a 6270 if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
sPymbed 0:1387ff3eed4a 6271 pointType != ECC_POINT_COMP_ODD) {
sPymbed 0:1387ff3eed4a 6272 err = ASN_PARSE_E;
sPymbed 0:1387ff3eed4a 6273 }
sPymbed 0:1387ff3eed4a 6274
sPymbed 0:1387ff3eed4a 6275 if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
sPymbed 0:1387ff3eed4a 6276 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 6277 compressed = 1;
sPymbed 0:1387ff3eed4a 6278 #else
sPymbed 0:1387ff3eed4a 6279 err = NOT_COMPILED_IN;
sPymbed 0:1387ff3eed4a 6280 #endif
sPymbed 0:1387ff3eed4a 6281 }
sPymbed 0:1387ff3eed4a 6282
sPymbed 0:1387ff3eed4a 6283 /* adjust to skip first byte */
sPymbed 0:1387ff3eed4a 6284 inLen -= 1;
sPymbed 0:1387ff3eed4a 6285 in += 1;
sPymbed 0:1387ff3eed4a 6286
sPymbed 0:1387ff3eed4a 6287 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6288 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 6289 /* adjust inLen if compressed */
sPymbed 0:1387ff3eed4a 6290 if (compressed)
sPymbed 0:1387ff3eed4a 6291 inLen = inLen*2 + 1; /* used uncompressed len */
sPymbed 0:1387ff3eed4a 6292 #endif
sPymbed 0:1387ff3eed4a 6293
sPymbed 0:1387ff3eed4a 6294 /* determine key size */
sPymbed 0:1387ff3eed4a 6295 keysize = (inLen>>1);
sPymbed 0:1387ff3eed4a 6296 err = wc_ecc_set_curve(key, keysize, curve_id);
sPymbed 0:1387ff3eed4a 6297 key->type = ECC_PUBLICKEY;
sPymbed 0:1387ff3eed4a 6298 }
sPymbed 0:1387ff3eed4a 6299
sPymbed 0:1387ff3eed4a 6300 /* read data */
sPymbed 0:1387ff3eed4a 6301 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6302 err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize);
sPymbed 0:1387ff3eed4a 6303
sPymbed 0:1387ff3eed4a 6304 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 6305 if (err == MP_OKAY && compressed == 1) { /* build y */
sPymbed 0:1387ff3eed4a 6306 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 6307 mp_int t1, t2;
sPymbed 0:1387ff3eed4a 6308 int did_init = 0;
sPymbed 0:1387ff3eed4a 6309
sPymbed 0:1387ff3eed4a 6310 DECLARE_CURVE_SPECS(curve, 3);
sPymbed 0:1387ff3eed4a 6311 ALLOC_CURVE_SPECS(3);
sPymbed 0:1387ff3eed4a 6312
sPymbed 0:1387ff3eed4a 6313 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY)
sPymbed 0:1387ff3eed4a 6314 err = MEMORY_E;
sPymbed 0:1387ff3eed4a 6315 else
sPymbed 0:1387ff3eed4a 6316 did_init = 1;
sPymbed 0:1387ff3eed4a 6317
sPymbed 0:1387ff3eed4a 6318 /* load curve info */
sPymbed 0:1387ff3eed4a 6319 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6320 err = wc_ecc_curve_load(key->dp, &curve,
sPymbed 0:1387ff3eed4a 6321 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
sPymbed 0:1387ff3eed4a 6322 ECC_CURVE_FIELD_BF));
sPymbed 0:1387ff3eed4a 6323
sPymbed 0:1387ff3eed4a 6324 /* compute x^3 */
sPymbed 0:1387ff3eed4a 6325 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6326 err = mp_sqr(key->pubkey.x, &t1);
sPymbed 0:1387ff3eed4a 6327 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6328 err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1);
sPymbed 0:1387ff3eed4a 6329
sPymbed 0:1387ff3eed4a 6330 /* compute x^3 + a*x */
sPymbed 0:1387ff3eed4a 6331 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6332 err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 6333 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6334 err = mp_add(&t1, &t2, &t1);
sPymbed 0:1387ff3eed4a 6335
sPymbed 0:1387ff3eed4a 6336 /* compute x^3 + a*x + b */
sPymbed 0:1387ff3eed4a 6337 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6338 err = mp_add(&t1, curve->Bf, &t1);
sPymbed 0:1387ff3eed4a 6339
sPymbed 0:1387ff3eed4a 6340 /* compute sqrt(x^3 + a*x + b) */
sPymbed 0:1387ff3eed4a 6341 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6342 err = mp_sqrtmod_prime(&t1, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 6343
sPymbed 0:1387ff3eed4a 6344 /* adjust y */
sPymbed 0:1387ff3eed4a 6345 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6346 if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
sPymbed 0:1387ff3eed4a 6347 (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) {
sPymbed 0:1387ff3eed4a 6348 err = mp_mod(&t2, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 6349 }
sPymbed 0:1387ff3eed4a 6350 else {
sPymbed 0:1387ff3eed4a 6351 err = mp_submod(curve->prime, &t2, curve->prime, &t2);
sPymbed 0:1387ff3eed4a 6352 }
sPymbed 0:1387ff3eed4a 6353 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6354 err = mp_copy(&t2, key->pubkey.y);
sPymbed 0:1387ff3eed4a 6355 }
sPymbed 0:1387ff3eed4a 6356
sPymbed 0:1387ff3eed4a 6357 if (did_init) {
sPymbed 0:1387ff3eed4a 6358 mp_clear(&t2);
sPymbed 0:1387ff3eed4a 6359 mp_clear(&t1);
sPymbed 0:1387ff3eed4a 6360 }
sPymbed 0:1387ff3eed4a 6361
sPymbed 0:1387ff3eed4a 6362 wc_ecc_curve_free(curve);
sPymbed 0:1387ff3eed4a 6363 FREE_CURVE_SPECS();
sPymbed 0:1387ff3eed4a 6364 #else
sPymbed 0:1387ff3eed4a 6365 sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y);
sPymbed 0:1387ff3eed4a 6366 #endif
sPymbed 0:1387ff3eed4a 6367 }
sPymbed 0:1387ff3eed4a 6368 #endif /* HAVE_COMP_KEY */
sPymbed 0:1387ff3eed4a 6369
sPymbed 0:1387ff3eed4a 6370 if (err == MP_OKAY && compressed == 0)
sPymbed 0:1387ff3eed4a 6371 err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, keysize);
sPymbed 0:1387ff3eed4a 6372 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6373 err = mp_set(key->pubkey.z, 1);
sPymbed 0:1387ff3eed4a 6374
sPymbed 0:1387ff3eed4a 6375 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
sPymbed 0:1387ff3eed4a 6376 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6377 err = wc_ecc_check_key(key);
sPymbed 0:1387ff3eed4a 6378 #endif
sPymbed 0:1387ff3eed4a 6379
sPymbed 0:1387ff3eed4a 6380 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 6381 mp_clear(key->pubkey.x);
sPymbed 0:1387ff3eed4a 6382 mp_clear(key->pubkey.y);
sPymbed 0:1387ff3eed4a 6383 mp_clear(key->pubkey.z);
sPymbed 0:1387ff3eed4a 6384 mp_clear(&key->k);
sPymbed 0:1387ff3eed4a 6385 }
sPymbed 0:1387ff3eed4a 6386
sPymbed 0:1387ff3eed4a 6387 return err;
sPymbed 0:1387ff3eed4a 6388 }
sPymbed 0:1387ff3eed4a 6389
sPymbed 0:1387ff3eed4a 6390 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
sPymbed 0:1387ff3eed4a 6391 {
sPymbed 0:1387ff3eed4a 6392 return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
sPymbed 0:1387ff3eed4a 6393 }
sPymbed 0:1387ff3eed4a 6394 #endif /* HAVE_ECC_KEY_IMPORT */
sPymbed 0:1387ff3eed4a 6395
sPymbed 0:1387ff3eed4a 6396 #ifdef HAVE_ECC_KEY_EXPORT
sPymbed 0:1387ff3eed4a 6397 /* export ecc private key only raw, outLen is in/out size
sPymbed 0:1387ff3eed4a 6398 return MP_OKAY on success */
sPymbed 0:1387ff3eed4a 6399 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
sPymbed 0:1387ff3eed4a 6400 {
sPymbed 0:1387ff3eed4a 6401 word32 numlen;
sPymbed 0:1387ff3eed4a 6402
sPymbed 0:1387ff3eed4a 6403 if (key == NULL || out == NULL || outLen == NULL) {
sPymbed 0:1387ff3eed4a 6404 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6405 }
sPymbed 0:1387ff3eed4a 6406
sPymbed 0:1387ff3eed4a 6407 if (wc_ecc_is_valid_idx(key->idx) == 0) {
sPymbed 0:1387ff3eed4a 6408 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6409 }
sPymbed 0:1387ff3eed4a 6410 numlen = key->dp->size;
sPymbed 0:1387ff3eed4a 6411
sPymbed 0:1387ff3eed4a 6412 if (*outLen < numlen) {
sPymbed 0:1387ff3eed4a 6413 *outLen = numlen;
sPymbed 0:1387ff3eed4a 6414 return BUFFER_E;
sPymbed 0:1387ff3eed4a 6415 }
sPymbed 0:1387ff3eed4a 6416 *outLen = numlen;
sPymbed 0:1387ff3eed4a 6417 XMEMSET(out, 0, *outLen);
sPymbed 0:1387ff3eed4a 6418
sPymbed 0:1387ff3eed4a 6419 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6420 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 6421 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 6422
sPymbed 0:1387ff3eed4a 6423 #else
sPymbed 0:1387ff3eed4a 6424
sPymbed 0:1387ff3eed4a 6425 return mp_to_unsigned_bin(&key->k, out + (numlen -
sPymbed 0:1387ff3eed4a 6426 mp_unsigned_bin_size(&key->k)));
sPymbed 0:1387ff3eed4a 6427 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6428 }
sPymbed 0:1387ff3eed4a 6429
sPymbed 0:1387ff3eed4a 6430
sPymbed 0:1387ff3eed4a 6431 /* export ecc key to component form, d is optional if only exporting public
sPymbed 0:1387ff3eed4a 6432 * return MP_OKAY on success */
sPymbed 0:1387ff3eed4a 6433 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen,
sPymbed 0:1387ff3eed4a 6434 byte* qy, word32* qyLen, byte* d, word32* dLen)
sPymbed 0:1387ff3eed4a 6435 {
sPymbed 0:1387ff3eed4a 6436 int err;
sPymbed 0:1387ff3eed4a 6437 byte exportPriv = 0;
sPymbed 0:1387ff3eed4a 6438 word32 numLen;
sPymbed 0:1387ff3eed4a 6439
sPymbed 0:1387ff3eed4a 6440 if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL ||
sPymbed 0:1387ff3eed4a 6441 qyLen == NULL) {
sPymbed 0:1387ff3eed4a 6442 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6443 }
sPymbed 0:1387ff3eed4a 6444
sPymbed 0:1387ff3eed4a 6445 if (key->type == ECC_PRIVATEKEY_ONLY) {
sPymbed 0:1387ff3eed4a 6446 return ECC_PRIVATEONLY_E;
sPymbed 0:1387ff3eed4a 6447 }
sPymbed 0:1387ff3eed4a 6448
sPymbed 0:1387ff3eed4a 6449 if (wc_ecc_is_valid_idx(key->idx) == 0) {
sPymbed 0:1387ff3eed4a 6450 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6451 }
sPymbed 0:1387ff3eed4a 6452 numLen = key->dp->size;
sPymbed 0:1387ff3eed4a 6453
sPymbed 0:1387ff3eed4a 6454 if (d != NULL) {
sPymbed 0:1387ff3eed4a 6455 if (dLen == NULL || key->type != ECC_PRIVATEKEY)
sPymbed 0:1387ff3eed4a 6456 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6457 exportPriv = 1;
sPymbed 0:1387ff3eed4a 6458 }
sPymbed 0:1387ff3eed4a 6459
sPymbed 0:1387ff3eed4a 6460 /* check public buffer sizes */
sPymbed 0:1387ff3eed4a 6461 if ((*qxLen < numLen) || (*qyLen < numLen)) {
sPymbed 0:1387ff3eed4a 6462 *qxLen = numLen;
sPymbed 0:1387ff3eed4a 6463 *qyLen = numLen;
sPymbed 0:1387ff3eed4a 6464 return BUFFER_E;
sPymbed 0:1387ff3eed4a 6465 }
sPymbed 0:1387ff3eed4a 6466
sPymbed 0:1387ff3eed4a 6467 *qxLen = numLen;
sPymbed 0:1387ff3eed4a 6468 *qyLen = numLen;
sPymbed 0:1387ff3eed4a 6469
sPymbed 0:1387ff3eed4a 6470 XMEMSET(qx, 0, *qxLen);
sPymbed 0:1387ff3eed4a 6471 XMEMSET(qy, 0, *qyLen);
sPymbed 0:1387ff3eed4a 6472
sPymbed 0:1387ff3eed4a 6473 /* private d component */
sPymbed 0:1387ff3eed4a 6474 if (exportPriv == 1) {
sPymbed 0:1387ff3eed4a 6475
sPymbed 0:1387ff3eed4a 6476 /* check private buffer size */
sPymbed 0:1387ff3eed4a 6477 if (*dLen < numLen) {
sPymbed 0:1387ff3eed4a 6478 *dLen = numLen;
sPymbed 0:1387ff3eed4a 6479 return BUFFER_E;
sPymbed 0:1387ff3eed4a 6480 }
sPymbed 0:1387ff3eed4a 6481
sPymbed 0:1387ff3eed4a 6482 *dLen = numLen;
sPymbed 0:1387ff3eed4a 6483 XMEMSET(d, 0, *dLen);
sPymbed 0:1387ff3eed4a 6484
sPymbed 0:1387ff3eed4a 6485 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6486 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 6487 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 6488
sPymbed 0:1387ff3eed4a 6489 #else
sPymbed 0:1387ff3eed4a 6490
sPymbed 0:1387ff3eed4a 6491 /* private key, d */
sPymbed 0:1387ff3eed4a 6492 err = mp_to_unsigned_bin(&key->k, d +
sPymbed 0:1387ff3eed4a 6493 (numLen - mp_unsigned_bin_size(&key->k)));
sPymbed 0:1387ff3eed4a 6494 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 6495 return err;
sPymbed 0:1387ff3eed4a 6496 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6497 }
sPymbed 0:1387ff3eed4a 6498
sPymbed 0:1387ff3eed4a 6499 /* public x component */
sPymbed 0:1387ff3eed4a 6500 err = mp_to_unsigned_bin(key->pubkey.x, qx +
sPymbed 0:1387ff3eed4a 6501 (numLen - mp_unsigned_bin_size(key->pubkey.x)));
sPymbed 0:1387ff3eed4a 6502 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 6503 return err;
sPymbed 0:1387ff3eed4a 6504
sPymbed 0:1387ff3eed4a 6505 /* public y component */
sPymbed 0:1387ff3eed4a 6506 err = mp_to_unsigned_bin(key->pubkey.y, qy +
sPymbed 0:1387ff3eed4a 6507 (numLen - mp_unsigned_bin_size(key->pubkey.y)));
sPymbed 0:1387ff3eed4a 6508 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 6509 return err;
sPymbed 0:1387ff3eed4a 6510
sPymbed 0:1387ff3eed4a 6511 return 0;
sPymbed 0:1387ff3eed4a 6512 }
sPymbed 0:1387ff3eed4a 6513
sPymbed 0:1387ff3eed4a 6514
sPymbed 0:1387ff3eed4a 6515 /* export public key to raw elements including public (Qx,Qy)
sPymbed 0:1387ff3eed4a 6516 * return MP_OKAY on success, negative on error */
sPymbed 0:1387ff3eed4a 6517 int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
sPymbed 0:1387ff3eed4a 6518 byte* qy, word32* qyLen)
sPymbed 0:1387ff3eed4a 6519 {
sPymbed 0:1387ff3eed4a 6520 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL);
sPymbed 0:1387ff3eed4a 6521 }
sPymbed 0:1387ff3eed4a 6522
sPymbed 0:1387ff3eed4a 6523
sPymbed 0:1387ff3eed4a 6524 /* export ecc key to raw elements including public (Qx,Qy) and private (d)
sPymbed 0:1387ff3eed4a 6525 * return MP_OKAY on success, negative on error */
sPymbed 0:1387ff3eed4a 6526 int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
sPymbed 0:1387ff3eed4a 6527 byte* qy, word32* qyLen, byte* d, word32* dLen)
sPymbed 0:1387ff3eed4a 6528 {
sPymbed 0:1387ff3eed4a 6529 /* sanitize d and dLen, other args are checked later */
sPymbed 0:1387ff3eed4a 6530 if (d == NULL || dLen == NULL)
sPymbed 0:1387ff3eed4a 6531 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6532
sPymbed 0:1387ff3eed4a 6533 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen);
sPymbed 0:1387ff3eed4a 6534 }
sPymbed 0:1387ff3eed4a 6535
sPymbed 0:1387ff3eed4a 6536 #endif /* HAVE_ECC_KEY_EXPORT */
sPymbed 0:1387ff3eed4a 6537
sPymbed 0:1387ff3eed4a 6538 #ifdef HAVE_ECC_KEY_IMPORT
sPymbed 0:1387ff3eed4a 6539 /* import private key, public part optional if (pub) passed as NULL */
sPymbed 0:1387ff3eed4a 6540 int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
sPymbed 0:1387ff3eed4a 6541 const byte* pub, word32 pubSz, ecc_key* key,
sPymbed 0:1387ff3eed4a 6542 int curve_id)
sPymbed 0:1387ff3eed4a 6543 {
sPymbed 0:1387ff3eed4a 6544 int ret;
sPymbed 0:1387ff3eed4a 6545 word32 idx = 0;
sPymbed 0:1387ff3eed4a 6546
sPymbed 0:1387ff3eed4a 6547 if (key == NULL || priv == NULL)
sPymbed 0:1387ff3eed4a 6548 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6549
sPymbed 0:1387ff3eed4a 6550 /* public optional, NULL if only importing private */
sPymbed 0:1387ff3eed4a 6551 if (pub != NULL) {
sPymbed 0:1387ff3eed4a 6552 ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
sPymbed 0:1387ff3eed4a 6553 if (ret < 0)
sPymbed 0:1387ff3eed4a 6554 ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
sPymbed 0:1387ff3eed4a 6555 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 6556 }
sPymbed 0:1387ff3eed4a 6557 else {
sPymbed 0:1387ff3eed4a 6558 /* make sure required variables are reset */
sPymbed 0:1387ff3eed4a 6559 wc_ecc_reset(key);
sPymbed 0:1387ff3eed4a 6560
sPymbed 0:1387ff3eed4a 6561 /* set key size */
sPymbed 0:1387ff3eed4a 6562 ret = wc_ecc_set_curve(key, privSz, curve_id);
sPymbed 0:1387ff3eed4a 6563 key->type = ECC_PRIVATEKEY_ONLY;
sPymbed 0:1387ff3eed4a 6564 }
sPymbed 0:1387ff3eed4a 6565
sPymbed 0:1387ff3eed4a 6566 if (ret != 0)
sPymbed 0:1387ff3eed4a 6567 return ret;
sPymbed 0:1387ff3eed4a 6568
sPymbed 0:1387ff3eed4a 6569 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6570 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 6571 return BAD_COND_E;
sPymbed 0:1387ff3eed4a 6572
sPymbed 0:1387ff3eed4a 6573 #else
sPymbed 0:1387ff3eed4a 6574
sPymbed 0:1387ff3eed4a 6575 ret = mp_read_unsigned_bin(&key->k, priv, privSz);
sPymbed 0:1387ff3eed4a 6576
sPymbed 0:1387ff3eed4a 6577 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6578
sPymbed 0:1387ff3eed4a 6579 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
sPymbed 0:1387ff3eed4a 6580 if ((pub != NULL) && (ret == MP_OKAY))
sPymbed 0:1387ff3eed4a 6581 /* public key needed to perform key validation */
sPymbed 0:1387ff3eed4a 6582 ret = ecc_check_privkey_gen_helper(key);
sPymbed 0:1387ff3eed4a 6583 #endif
sPymbed 0:1387ff3eed4a 6584
sPymbed 0:1387ff3eed4a 6585 return ret;
sPymbed 0:1387ff3eed4a 6586 }
sPymbed 0:1387ff3eed4a 6587
sPymbed 0:1387ff3eed4a 6588 /* ecc private key import, public key in ANSI X9.63 format, private raw */
sPymbed 0:1387ff3eed4a 6589 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
sPymbed 0:1387ff3eed4a 6590 word32 pubSz, ecc_key* key)
sPymbed 0:1387ff3eed4a 6591 {
sPymbed 0:1387ff3eed4a 6592 return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
sPymbed 0:1387ff3eed4a 6593 ECC_CURVE_DEF);
sPymbed 0:1387ff3eed4a 6594 }
sPymbed 0:1387ff3eed4a 6595 #endif /* HAVE_ECC_KEY_IMPORT */
sPymbed 0:1387ff3eed4a 6596
sPymbed 0:1387ff3eed4a 6597 #ifndef NO_ASN
sPymbed 0:1387ff3eed4a 6598 /**
sPymbed 0:1387ff3eed4a 6599 Convert ECC R,S to signature
sPymbed 0:1387ff3eed4a 6600 r R component of signature
sPymbed 0:1387ff3eed4a 6601 s S component of signature
sPymbed 0:1387ff3eed4a 6602 out DER-encoded ECDSA signature
sPymbed 0:1387ff3eed4a 6603 outlen [in/out] output buffer size, output signature size
sPymbed 0:1387ff3eed4a 6604 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 6605 */
sPymbed 0:1387ff3eed4a 6606 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
sPymbed 0:1387ff3eed4a 6607 {
sPymbed 0:1387ff3eed4a 6608 int err;
sPymbed 0:1387ff3eed4a 6609 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6610 mp_int* rtmp = NULL;
sPymbed 0:1387ff3eed4a 6611 mp_int* stmp = NULL;
sPymbed 0:1387ff3eed4a 6612 #else
sPymbed 0:1387ff3eed4a 6613 mp_int rtmp[1];
sPymbed 0:1387ff3eed4a 6614 mp_int stmp[1];
sPymbed 0:1387ff3eed4a 6615 #endif
sPymbed 0:1387ff3eed4a 6616
sPymbed 0:1387ff3eed4a 6617 if (r == NULL || s == NULL || out == NULL || outlen == NULL)
sPymbed 0:1387ff3eed4a 6618 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6619
sPymbed 0:1387ff3eed4a 6620 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6621 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6622 if (rtmp == NULL)
sPymbed 0:1387ff3eed4a 6623 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6624 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6625 if (stmp == NULL) {
sPymbed 0:1387ff3eed4a 6626 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6627 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6628 }
sPymbed 0:1387ff3eed4a 6629 #endif
sPymbed 0:1387ff3eed4a 6630
sPymbed 0:1387ff3eed4a 6631 err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
sPymbed 0:1387ff3eed4a 6632 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 6633 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6634 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6635 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6636 #endif
sPymbed 0:1387ff3eed4a 6637 return err;
sPymbed 0:1387ff3eed4a 6638 }
sPymbed 0:1387ff3eed4a 6639
sPymbed 0:1387ff3eed4a 6640 err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6641 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6642 err = mp_read_radix(stmp, s, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6643
sPymbed 0:1387ff3eed4a 6644 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
sPymbed 0:1387ff3eed4a 6645 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6646 err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
sPymbed 0:1387ff3eed4a 6647
sPymbed 0:1387ff3eed4a 6648 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6649 if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
sPymbed 0:1387ff3eed4a 6650 err = MP_ZERO_E;
sPymbed 0:1387ff3eed4a 6651 }
sPymbed 0:1387ff3eed4a 6652
sPymbed 0:1387ff3eed4a 6653 mp_clear(rtmp);
sPymbed 0:1387ff3eed4a 6654 mp_clear(stmp);
sPymbed 0:1387ff3eed4a 6655 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6656 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6657 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6658 #endif
sPymbed 0:1387ff3eed4a 6659
sPymbed 0:1387ff3eed4a 6660 return err;
sPymbed 0:1387ff3eed4a 6661 }
sPymbed 0:1387ff3eed4a 6662
sPymbed 0:1387ff3eed4a 6663 /**
sPymbed 0:1387ff3eed4a 6664 Convert ECC R,S raw unsigned bin to signature
sPymbed 0:1387ff3eed4a 6665 r R component of signature
sPymbed 0:1387ff3eed4a 6666 rSz R size
sPymbed 0:1387ff3eed4a 6667 s S component of signature
sPymbed 0:1387ff3eed4a 6668 sSz S size
sPymbed 0:1387ff3eed4a 6669 out DER-encoded ECDSA signature
sPymbed 0:1387ff3eed4a 6670 outlen [in/out] output buffer size, output signature size
sPymbed 0:1387ff3eed4a 6671 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 6672 */
sPymbed 0:1387ff3eed4a 6673 int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
sPymbed 0:1387ff3eed4a 6674 byte* out, word32* outlen)
sPymbed 0:1387ff3eed4a 6675 {
sPymbed 0:1387ff3eed4a 6676 int err;
sPymbed 0:1387ff3eed4a 6677 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6678 mp_int* rtmp = NULL;
sPymbed 0:1387ff3eed4a 6679 mp_int* stmp = NULL;
sPymbed 0:1387ff3eed4a 6680 #else
sPymbed 0:1387ff3eed4a 6681 mp_int rtmp[1];
sPymbed 0:1387ff3eed4a 6682 mp_int stmp[1];
sPymbed 0:1387ff3eed4a 6683 #endif
sPymbed 0:1387ff3eed4a 6684
sPymbed 0:1387ff3eed4a 6685 if (r == NULL || s == NULL || out == NULL || outlen == NULL)
sPymbed 0:1387ff3eed4a 6686 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6687
sPymbed 0:1387ff3eed4a 6688 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6689 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6690 if (rtmp == NULL)
sPymbed 0:1387ff3eed4a 6691 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6692 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6693 if (stmp == NULL) {
sPymbed 0:1387ff3eed4a 6694 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6695 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6696 }
sPymbed 0:1387ff3eed4a 6697 #endif
sPymbed 0:1387ff3eed4a 6698
sPymbed 0:1387ff3eed4a 6699 err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
sPymbed 0:1387ff3eed4a 6700 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 6701 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6702 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6703 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6704 #endif
sPymbed 0:1387ff3eed4a 6705 return err;
sPymbed 0:1387ff3eed4a 6706 }
sPymbed 0:1387ff3eed4a 6707
sPymbed 0:1387ff3eed4a 6708 err = mp_read_unsigned_bin(rtmp, r, rSz);
sPymbed 0:1387ff3eed4a 6709 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6710 err = mp_read_unsigned_bin(stmp, s, sSz);
sPymbed 0:1387ff3eed4a 6711
sPymbed 0:1387ff3eed4a 6712 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
sPymbed 0:1387ff3eed4a 6713 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6714 err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
sPymbed 0:1387ff3eed4a 6715
sPymbed 0:1387ff3eed4a 6716 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6717 if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
sPymbed 0:1387ff3eed4a 6718 err = MP_ZERO_E;
sPymbed 0:1387ff3eed4a 6719 }
sPymbed 0:1387ff3eed4a 6720
sPymbed 0:1387ff3eed4a 6721 mp_clear(rtmp);
sPymbed 0:1387ff3eed4a 6722 mp_clear(stmp);
sPymbed 0:1387ff3eed4a 6723 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6724 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6725 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6726 #endif
sPymbed 0:1387ff3eed4a 6727
sPymbed 0:1387ff3eed4a 6728 return err;
sPymbed 0:1387ff3eed4a 6729 }
sPymbed 0:1387ff3eed4a 6730
sPymbed 0:1387ff3eed4a 6731 /**
sPymbed 0:1387ff3eed4a 6732 Convert ECC signature to R,S
sPymbed 0:1387ff3eed4a 6733 sig DER-encoded ECDSA signature
sPymbed 0:1387ff3eed4a 6734 sigLen length of signature in octets
sPymbed 0:1387ff3eed4a 6735 r R component of signature
sPymbed 0:1387ff3eed4a 6736 rLen [in/out] output "r" buffer size, output "r" size
sPymbed 0:1387ff3eed4a 6737 s S component of signature
sPymbed 0:1387ff3eed4a 6738 sLen [in/out] output "s" buffer size, output "s" size
sPymbed 0:1387ff3eed4a 6739 return MP_OKAY on success, negative on error
sPymbed 0:1387ff3eed4a 6740 */
sPymbed 0:1387ff3eed4a 6741 int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
sPymbed 0:1387ff3eed4a 6742 byte* s, word32* sLen)
sPymbed 0:1387ff3eed4a 6743 {
sPymbed 0:1387ff3eed4a 6744 int err;
sPymbed 0:1387ff3eed4a 6745 word32 x = 0;
sPymbed 0:1387ff3eed4a 6746 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6747 mp_int* rtmp = NULL;
sPymbed 0:1387ff3eed4a 6748 mp_int* stmp = NULL;
sPymbed 0:1387ff3eed4a 6749 #else
sPymbed 0:1387ff3eed4a 6750 mp_int rtmp[1];
sPymbed 0:1387ff3eed4a 6751 mp_int stmp[1];
sPymbed 0:1387ff3eed4a 6752 #endif
sPymbed 0:1387ff3eed4a 6753
sPymbed 0:1387ff3eed4a 6754 if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
sPymbed 0:1387ff3eed4a 6755 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 6756
sPymbed 0:1387ff3eed4a 6757 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6758 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6759 if (rtmp == NULL)
sPymbed 0:1387ff3eed4a 6760 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6761 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6762 if (stmp == NULL) {
sPymbed 0:1387ff3eed4a 6763 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6764 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6765 }
sPymbed 0:1387ff3eed4a 6766 #endif
sPymbed 0:1387ff3eed4a 6767
sPymbed 0:1387ff3eed4a 6768 err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp);
sPymbed 0:1387ff3eed4a 6769
sPymbed 0:1387ff3eed4a 6770 /* extract r */
sPymbed 0:1387ff3eed4a 6771 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6772 x = mp_unsigned_bin_size(rtmp);
sPymbed 0:1387ff3eed4a 6773 if (*rLen < x)
sPymbed 0:1387ff3eed4a 6774 err = BUFFER_E;
sPymbed 0:1387ff3eed4a 6775
sPymbed 0:1387ff3eed4a 6776 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6777 *rLen = x;
sPymbed 0:1387ff3eed4a 6778 err = mp_to_unsigned_bin(rtmp, r);
sPymbed 0:1387ff3eed4a 6779 }
sPymbed 0:1387ff3eed4a 6780 }
sPymbed 0:1387ff3eed4a 6781
sPymbed 0:1387ff3eed4a 6782 /* extract s */
sPymbed 0:1387ff3eed4a 6783 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6784 x = mp_unsigned_bin_size(stmp);
sPymbed 0:1387ff3eed4a 6785 if (*sLen < x)
sPymbed 0:1387ff3eed4a 6786 err = BUFFER_E;
sPymbed 0:1387ff3eed4a 6787
sPymbed 0:1387ff3eed4a 6788 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6789 *sLen = x;
sPymbed 0:1387ff3eed4a 6790 err = mp_to_unsigned_bin(stmp, s);
sPymbed 0:1387ff3eed4a 6791 }
sPymbed 0:1387ff3eed4a 6792 }
sPymbed 0:1387ff3eed4a 6793
sPymbed 0:1387ff3eed4a 6794 mp_clear(rtmp);
sPymbed 0:1387ff3eed4a 6795 mp_clear(stmp);
sPymbed 0:1387ff3eed4a 6796 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 6797 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6798 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 6799 #endif
sPymbed 0:1387ff3eed4a 6800
sPymbed 0:1387ff3eed4a 6801 return err;
sPymbed 0:1387ff3eed4a 6802 }
sPymbed 0:1387ff3eed4a 6803 #endif /* !NO_ASN */
sPymbed 0:1387ff3eed4a 6804
sPymbed 0:1387ff3eed4a 6805 #ifdef HAVE_ECC_KEY_IMPORT
sPymbed 0:1387ff3eed4a 6806 static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
sPymbed 0:1387ff3eed4a 6807 const char* qy, const char* d, int curve_id, int encType)
sPymbed 0:1387ff3eed4a 6808 {
sPymbed 0:1387ff3eed4a 6809 int err = MP_OKAY;
sPymbed 0:1387ff3eed4a 6810
sPymbed 0:1387ff3eed4a 6811 /* if d is NULL, only import as public key using Qx,Qy */
sPymbed 0:1387ff3eed4a 6812 if (key == NULL || qx == NULL || qy == NULL) {
sPymbed 0:1387ff3eed4a 6813 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6814 }
sPymbed 0:1387ff3eed4a 6815
sPymbed 0:1387ff3eed4a 6816 /* make sure required variables are reset */
sPymbed 0:1387ff3eed4a 6817 wc_ecc_reset(key);
sPymbed 0:1387ff3eed4a 6818
sPymbed 0:1387ff3eed4a 6819 /* set curve type and index */
sPymbed 0:1387ff3eed4a 6820 err = wc_ecc_set_curve(key, 0, curve_id);
sPymbed 0:1387ff3eed4a 6821 if (err != 0) {
sPymbed 0:1387ff3eed4a 6822 return err;
sPymbed 0:1387ff3eed4a 6823 }
sPymbed 0:1387ff3eed4a 6824
sPymbed 0:1387ff3eed4a 6825 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 6826 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 6827 err = BAD_COND_E;
sPymbed 0:1387ff3eed4a 6828 (void)d;
sPymbed 0:1387ff3eed4a 6829 (void)encType;
sPymbed 0:1387ff3eed4a 6830
sPymbed 0:1387ff3eed4a 6831 #else
sPymbed 0:1387ff3eed4a 6832
sPymbed 0:1387ff3eed4a 6833 /* init key */
sPymbed 0:1387ff3eed4a 6834 #ifdef ALT_ECC_SIZE
sPymbed 0:1387ff3eed4a 6835 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
sPymbed 0:1387ff3eed4a 6836 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
sPymbed 0:1387ff3eed4a 6837 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
sPymbed 0:1387ff3eed4a 6838 alt_fp_init(key->pubkey.x);
sPymbed 0:1387ff3eed4a 6839 alt_fp_init(key->pubkey.y);
sPymbed 0:1387ff3eed4a 6840 alt_fp_init(key->pubkey.z);
sPymbed 0:1387ff3eed4a 6841 err = mp_init(&key->k);
sPymbed 0:1387ff3eed4a 6842 #else
sPymbed 0:1387ff3eed4a 6843 err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
sPymbed 0:1387ff3eed4a 6844 NULL, NULL);
sPymbed 0:1387ff3eed4a 6845 #endif
sPymbed 0:1387ff3eed4a 6846 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 6847 return MEMORY_E;
sPymbed 0:1387ff3eed4a 6848
sPymbed 0:1387ff3eed4a 6849 /* read Qx */
sPymbed 0:1387ff3eed4a 6850 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6851 if (encType == ECC_TYPE_HEX_STR)
sPymbed 0:1387ff3eed4a 6852 err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6853 else
sPymbed 0:1387ff3eed4a 6854 err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
sPymbed 0:1387ff3eed4a 6855 key->dp->size);
sPymbed 0:1387ff3eed4a 6856 }
sPymbed 0:1387ff3eed4a 6857
sPymbed 0:1387ff3eed4a 6858 /* read Qy */
sPymbed 0:1387ff3eed4a 6859 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6860 if (encType == ECC_TYPE_HEX_STR)
sPymbed 0:1387ff3eed4a 6861 err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6862 else
sPymbed 0:1387ff3eed4a 6863 err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
sPymbed 0:1387ff3eed4a 6864 key->dp->size);
sPymbed 0:1387ff3eed4a 6865
sPymbed 0:1387ff3eed4a 6866 }
sPymbed 0:1387ff3eed4a 6867
sPymbed 0:1387ff3eed4a 6868 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6869 err = mp_set(key->pubkey.z, 1);
sPymbed 0:1387ff3eed4a 6870
sPymbed 0:1387ff3eed4a 6871 /* import private key */
sPymbed 0:1387ff3eed4a 6872 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 6873 if (d != NULL) {
sPymbed 0:1387ff3eed4a 6874 key->type = ECC_PRIVATEKEY;
sPymbed 0:1387ff3eed4a 6875
sPymbed 0:1387ff3eed4a 6876 if (encType == ECC_TYPE_HEX_STR)
sPymbed 0:1387ff3eed4a 6877 err = mp_read_radix(&key->k, d, MP_RADIX_HEX);
sPymbed 0:1387ff3eed4a 6878 else
sPymbed 0:1387ff3eed4a 6879 err = mp_read_unsigned_bin(&key->k, (const byte*)d,
sPymbed 0:1387ff3eed4a 6880 key->dp->size);
sPymbed 0:1387ff3eed4a 6881
sPymbed 0:1387ff3eed4a 6882 } else {
sPymbed 0:1387ff3eed4a 6883 key->type = ECC_PUBLICKEY;
sPymbed 0:1387ff3eed4a 6884 }
sPymbed 0:1387ff3eed4a 6885 }
sPymbed 0:1387ff3eed4a 6886
sPymbed 0:1387ff3eed4a 6887 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT
sPymbed 0:1387ff3eed4a 6888 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 6889 err = wc_ecc_check_key(key);
sPymbed 0:1387ff3eed4a 6890 #endif
sPymbed 0:1387ff3eed4a 6891
sPymbed 0:1387ff3eed4a 6892 if (err != MP_OKAY) {
sPymbed 0:1387ff3eed4a 6893 mp_clear(key->pubkey.x);
sPymbed 0:1387ff3eed4a 6894 mp_clear(key->pubkey.y);
sPymbed 0:1387ff3eed4a 6895 mp_clear(key->pubkey.z);
sPymbed 0:1387ff3eed4a 6896 mp_clear(&key->k);
sPymbed 0:1387ff3eed4a 6897 }
sPymbed 0:1387ff3eed4a 6898 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 6899
sPymbed 0:1387ff3eed4a 6900 return err;
sPymbed 0:1387ff3eed4a 6901 }
sPymbed 0:1387ff3eed4a 6902
sPymbed 0:1387ff3eed4a 6903 /**
sPymbed 0:1387ff3eed4a 6904 Import raw ECC key
sPymbed 0:1387ff3eed4a 6905 key The destination ecc_key structure
sPymbed 0:1387ff3eed4a 6906 qx x component of the public key, as ASCII hex string
sPymbed 0:1387ff3eed4a 6907 qy y component of the public key, as ASCII hex string
sPymbed 0:1387ff3eed4a 6908 d private key, as ASCII hex string, optional if importing public
sPymbed 0:1387ff3eed4a 6909 key only
sPymbed 0:1387ff3eed4a 6910 dp Custom ecc_set_type
sPymbed 0:1387ff3eed4a 6911 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 6912 */
sPymbed 0:1387ff3eed4a 6913 int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
sPymbed 0:1387ff3eed4a 6914 const char* d, int curve_id)
sPymbed 0:1387ff3eed4a 6915 {
sPymbed 0:1387ff3eed4a 6916 return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
sPymbed 0:1387ff3eed4a 6917 ECC_TYPE_HEX_STR);
sPymbed 0:1387ff3eed4a 6918
sPymbed 0:1387ff3eed4a 6919 }
sPymbed 0:1387ff3eed4a 6920
sPymbed 0:1387ff3eed4a 6921 /* Import x, y and optional private (d) as unsigned binary */
sPymbed 0:1387ff3eed4a 6922 int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy,
sPymbed 0:1387ff3eed4a 6923 byte* d, int curve_id)
sPymbed 0:1387ff3eed4a 6924 {
sPymbed 0:1387ff3eed4a 6925 return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
sPymbed 0:1387ff3eed4a 6926 (const char*)d, curve_id, ECC_TYPE_UNSIGNED_BIN);
sPymbed 0:1387ff3eed4a 6927 }
sPymbed 0:1387ff3eed4a 6928
sPymbed 0:1387ff3eed4a 6929 /**
sPymbed 0:1387ff3eed4a 6930 Import raw ECC key
sPymbed 0:1387ff3eed4a 6931 key The destination ecc_key structure
sPymbed 0:1387ff3eed4a 6932 qx x component of the public key, as ASCII hex string
sPymbed 0:1387ff3eed4a 6933 qy y component of the public key, as ASCII hex string
sPymbed 0:1387ff3eed4a 6934 d private key, as ASCII hex string, optional if importing public
sPymbed 0:1387ff3eed4a 6935 key only
sPymbed 0:1387ff3eed4a 6936 curveName ECC curve name, from ecc_sets[]
sPymbed 0:1387ff3eed4a 6937 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 6938 */
sPymbed 0:1387ff3eed4a 6939 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
sPymbed 0:1387ff3eed4a 6940 const char* d, const char* curveName)
sPymbed 0:1387ff3eed4a 6941 {
sPymbed 0:1387ff3eed4a 6942 int err, x;
sPymbed 0:1387ff3eed4a 6943
sPymbed 0:1387ff3eed4a 6944 /* if d is NULL, only import as public key using Qx,Qy */
sPymbed 0:1387ff3eed4a 6945 if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
sPymbed 0:1387ff3eed4a 6946 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 6947 }
sPymbed 0:1387ff3eed4a 6948
sPymbed 0:1387ff3eed4a 6949 /* set curve type and index */
sPymbed 0:1387ff3eed4a 6950 for (x = 0; ecc_sets[x].size != 0; x++) {
sPymbed 0:1387ff3eed4a 6951 if (XSTRNCMP(ecc_sets[x].name, curveName,
sPymbed 0:1387ff3eed4a 6952 XSTRLEN(curveName)) == 0) {
sPymbed 0:1387ff3eed4a 6953 break;
sPymbed 0:1387ff3eed4a 6954 }
sPymbed 0:1387ff3eed4a 6955 }
sPymbed 0:1387ff3eed4a 6956
sPymbed 0:1387ff3eed4a 6957 if (ecc_sets[x].size == 0) {
sPymbed 0:1387ff3eed4a 6958 WOLFSSL_MSG("ecc_set curve name not found");
sPymbed 0:1387ff3eed4a 6959 err = ASN_PARSE_E;
sPymbed 0:1387ff3eed4a 6960 } else {
sPymbed 0:1387ff3eed4a 6961 return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
sPymbed 0:1387ff3eed4a 6962 ECC_TYPE_HEX_STR);
sPymbed 0:1387ff3eed4a 6963 }
sPymbed 0:1387ff3eed4a 6964
sPymbed 0:1387ff3eed4a 6965 return err;
sPymbed 0:1387ff3eed4a 6966 }
sPymbed 0:1387ff3eed4a 6967 #endif /* HAVE_ECC_KEY_IMPORT */
sPymbed 0:1387ff3eed4a 6968
sPymbed 0:1387ff3eed4a 6969 /* key size in octets */
sPymbed 0:1387ff3eed4a 6970 int wc_ecc_size(ecc_key* key)
sPymbed 0:1387ff3eed4a 6971 {
sPymbed 0:1387ff3eed4a 6972 if (key == NULL) return 0;
sPymbed 0:1387ff3eed4a 6973
sPymbed 0:1387ff3eed4a 6974 return key->dp->size;
sPymbed 0:1387ff3eed4a 6975 }
sPymbed 0:1387ff3eed4a 6976
sPymbed 0:1387ff3eed4a 6977 int wc_ecc_sig_size_calc(int sz)
sPymbed 0:1387ff3eed4a 6978 {
sPymbed 0:1387ff3eed4a 6979 return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
sPymbed 0:1387ff3eed4a 6980 }
sPymbed 0:1387ff3eed4a 6981
sPymbed 0:1387ff3eed4a 6982 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual
sPymbed 0:1387ff3eed4a 6983 value of signature size in octets */
sPymbed 0:1387ff3eed4a 6984 int wc_ecc_sig_size(ecc_key* key)
sPymbed 0:1387ff3eed4a 6985 {
sPymbed 0:1387ff3eed4a 6986 int sz = wc_ecc_size(key);
sPymbed 0:1387ff3eed4a 6987 if (sz <= 0)
sPymbed 0:1387ff3eed4a 6988 return sz;
sPymbed 0:1387ff3eed4a 6989
sPymbed 0:1387ff3eed4a 6990 return wc_ecc_sig_size_calc(sz);
sPymbed 0:1387ff3eed4a 6991 }
sPymbed 0:1387ff3eed4a 6992
sPymbed 0:1387ff3eed4a 6993
sPymbed 0:1387ff3eed4a 6994 #ifdef FP_ECC
sPymbed 0:1387ff3eed4a 6995
sPymbed 0:1387ff3eed4a 6996 /* fixed point ECC cache */
sPymbed 0:1387ff3eed4a 6997 /* number of entries in the cache */
sPymbed 0:1387ff3eed4a 6998 #ifndef FP_ENTRIES
sPymbed 0:1387ff3eed4a 6999 #define FP_ENTRIES 15
sPymbed 0:1387ff3eed4a 7000 #endif
sPymbed 0:1387ff3eed4a 7001
sPymbed 0:1387ff3eed4a 7002 /* number of bits in LUT */
sPymbed 0:1387ff3eed4a 7003 #ifndef FP_LUT
sPymbed 0:1387ff3eed4a 7004 #define FP_LUT 8U
sPymbed 0:1387ff3eed4a 7005 #endif
sPymbed 0:1387ff3eed4a 7006
sPymbed 0:1387ff3eed4a 7007 #ifdef ECC_SHAMIR
sPymbed 0:1387ff3eed4a 7008 /* Sharmir requires a bigger LUT, TAO */
sPymbed 0:1387ff3eed4a 7009 #if (FP_LUT > 12) || (FP_LUT < 4)
sPymbed 0:1387ff3eed4a 7010 #error FP_LUT must be between 4 and 12 inclusively
sPymbed 0:1387ff3eed4a 7011 #endif
sPymbed 0:1387ff3eed4a 7012 #else
sPymbed 0:1387ff3eed4a 7013 #if (FP_LUT > 12) || (FP_LUT < 2)
sPymbed 0:1387ff3eed4a 7014 #error FP_LUT must be between 2 and 12 inclusively
sPymbed 0:1387ff3eed4a 7015 #endif
sPymbed 0:1387ff3eed4a 7016 #endif
sPymbed 0:1387ff3eed4a 7017
sPymbed 0:1387ff3eed4a 7018
sPymbed 0:1387ff3eed4a 7019 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 7020
sPymbed 0:1387ff3eed4a 7021 /** Our FP cache */
sPymbed 0:1387ff3eed4a 7022 typedef struct {
sPymbed 0:1387ff3eed4a 7023 ecc_point* g; /* cached COPY of base point */
sPymbed 0:1387ff3eed4a 7024 ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
sPymbed 0:1387ff3eed4a 7025 mp_int mu; /* copy of the montgomery constant */
sPymbed 0:1387ff3eed4a 7026 int lru_count; /* amount of times this entry has been used */
sPymbed 0:1387ff3eed4a 7027 int lock; /* flag to indicate cache eviction */
sPymbed 0:1387ff3eed4a 7028 /* permitted (0) or not (1) */
sPymbed 0:1387ff3eed4a 7029 } fp_cache_t;
sPymbed 0:1387ff3eed4a 7030
sPymbed 0:1387ff3eed4a 7031 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */
sPymbed 0:1387ff3eed4a 7032 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
sPymbed 0:1387ff3eed4a 7033
sPymbed 0:1387ff3eed4a 7034 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 7035 static volatile int initMutex = 0; /* prevent multiple mutex inits */
sPymbed 0:1387ff3eed4a 7036 static wolfSSL_Mutex ecc_fp_lock;
sPymbed 0:1387ff3eed4a 7037 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 7038
sPymbed 0:1387ff3eed4a 7039 /* simple table to help direct the generation of the LUT */
sPymbed 0:1387ff3eed4a 7040 static const struct {
sPymbed 0:1387ff3eed4a 7041 int ham, terma, termb;
sPymbed 0:1387ff3eed4a 7042 } lut_orders[] = {
sPymbed 0:1387ff3eed4a 7043 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
sPymbed 0:1387ff3eed4a 7044 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
sPymbed 0:1387ff3eed4a 7045 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
sPymbed 0:1387ff3eed4a 7046 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
sPymbed 0:1387ff3eed4a 7047 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
sPymbed 0:1387ff3eed4a 7048 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
sPymbed 0:1387ff3eed4a 7049 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
sPymbed 0:1387ff3eed4a 7050 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
sPymbed 0:1387ff3eed4a 7051 #if FP_LUT > 6
sPymbed 0:1387ff3eed4a 7052 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
sPymbed 0:1387ff3eed4a 7053 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
sPymbed 0:1387ff3eed4a 7054 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
sPymbed 0:1387ff3eed4a 7055 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
sPymbed 0:1387ff3eed4a 7056 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
sPymbed 0:1387ff3eed4a 7057 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
sPymbed 0:1387ff3eed4a 7058 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
sPymbed 0:1387ff3eed4a 7059 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
sPymbed 0:1387ff3eed4a 7060 #if FP_LUT > 7
sPymbed 0:1387ff3eed4a 7061 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
sPymbed 0:1387ff3eed4a 7062 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
sPymbed 0:1387ff3eed4a 7063 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
sPymbed 0:1387ff3eed4a 7064 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
sPymbed 0:1387ff3eed4a 7065 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
sPymbed 0:1387ff3eed4a 7066 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
sPymbed 0:1387ff3eed4a 7067 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
sPymbed 0:1387ff3eed4a 7068 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
sPymbed 0:1387ff3eed4a 7069 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
sPymbed 0:1387ff3eed4a 7070 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
sPymbed 0:1387ff3eed4a 7071 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
sPymbed 0:1387ff3eed4a 7072 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
sPymbed 0:1387ff3eed4a 7073 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
sPymbed 0:1387ff3eed4a 7074 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
sPymbed 0:1387ff3eed4a 7075 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
sPymbed 0:1387ff3eed4a 7076 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
sPymbed 0:1387ff3eed4a 7077 #if FP_LUT > 8
sPymbed 0:1387ff3eed4a 7078 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
sPymbed 0:1387ff3eed4a 7079 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
sPymbed 0:1387ff3eed4a 7080 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
sPymbed 0:1387ff3eed4a 7081 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
sPymbed 0:1387ff3eed4a 7082 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
sPymbed 0:1387ff3eed4a 7083 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
sPymbed 0:1387ff3eed4a 7084 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
sPymbed 0:1387ff3eed4a 7085 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
sPymbed 0:1387ff3eed4a 7086 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
sPymbed 0:1387ff3eed4a 7087 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
sPymbed 0:1387ff3eed4a 7088 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
sPymbed 0:1387ff3eed4a 7089 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
sPymbed 0:1387ff3eed4a 7090 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
sPymbed 0:1387ff3eed4a 7091 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
sPymbed 0:1387ff3eed4a 7092 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
sPymbed 0:1387ff3eed4a 7093 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
sPymbed 0:1387ff3eed4a 7094 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
sPymbed 0:1387ff3eed4a 7095 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
sPymbed 0:1387ff3eed4a 7096 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
sPymbed 0:1387ff3eed4a 7097 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
sPymbed 0:1387ff3eed4a 7098 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
sPymbed 0:1387ff3eed4a 7099 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
sPymbed 0:1387ff3eed4a 7100 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
sPymbed 0:1387ff3eed4a 7101 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
sPymbed 0:1387ff3eed4a 7102 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
sPymbed 0:1387ff3eed4a 7103 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
sPymbed 0:1387ff3eed4a 7104 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
sPymbed 0:1387ff3eed4a 7105 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
sPymbed 0:1387ff3eed4a 7106 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
sPymbed 0:1387ff3eed4a 7107 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
sPymbed 0:1387ff3eed4a 7108 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
sPymbed 0:1387ff3eed4a 7109 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
sPymbed 0:1387ff3eed4a 7110 #if FP_LUT > 9
sPymbed 0:1387ff3eed4a 7111 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
sPymbed 0:1387ff3eed4a 7112 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
sPymbed 0:1387ff3eed4a 7113 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
sPymbed 0:1387ff3eed4a 7114 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
sPymbed 0:1387ff3eed4a 7115 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
sPymbed 0:1387ff3eed4a 7116 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
sPymbed 0:1387ff3eed4a 7117 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
sPymbed 0:1387ff3eed4a 7118 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
sPymbed 0:1387ff3eed4a 7119 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
sPymbed 0:1387ff3eed4a 7120 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
sPymbed 0:1387ff3eed4a 7121 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
sPymbed 0:1387ff3eed4a 7122 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
sPymbed 0:1387ff3eed4a 7123 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
sPymbed 0:1387ff3eed4a 7124 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
sPymbed 0:1387ff3eed4a 7125 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
sPymbed 0:1387ff3eed4a 7126 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
sPymbed 0:1387ff3eed4a 7127 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
sPymbed 0:1387ff3eed4a 7128 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
sPymbed 0:1387ff3eed4a 7129 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
sPymbed 0:1387ff3eed4a 7130 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
sPymbed 0:1387ff3eed4a 7131 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
sPymbed 0:1387ff3eed4a 7132 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
sPymbed 0:1387ff3eed4a 7133 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
sPymbed 0:1387ff3eed4a 7134 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
sPymbed 0:1387ff3eed4a 7135 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
sPymbed 0:1387ff3eed4a 7136 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
sPymbed 0:1387ff3eed4a 7137 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
sPymbed 0:1387ff3eed4a 7138 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
sPymbed 0:1387ff3eed4a 7139 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
sPymbed 0:1387ff3eed4a 7140 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
sPymbed 0:1387ff3eed4a 7141 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
sPymbed 0:1387ff3eed4a 7142 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
sPymbed 0:1387ff3eed4a 7143 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
sPymbed 0:1387ff3eed4a 7144 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
sPymbed 0:1387ff3eed4a 7145 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
sPymbed 0:1387ff3eed4a 7146 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
sPymbed 0:1387ff3eed4a 7147 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
sPymbed 0:1387ff3eed4a 7148 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
sPymbed 0:1387ff3eed4a 7149 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
sPymbed 0:1387ff3eed4a 7150 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
sPymbed 0:1387ff3eed4a 7151 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
sPymbed 0:1387ff3eed4a 7152 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
sPymbed 0:1387ff3eed4a 7153 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
sPymbed 0:1387ff3eed4a 7154 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
sPymbed 0:1387ff3eed4a 7155 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
sPymbed 0:1387ff3eed4a 7156 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
sPymbed 0:1387ff3eed4a 7157 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
sPymbed 0:1387ff3eed4a 7158 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
sPymbed 0:1387ff3eed4a 7159 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
sPymbed 0:1387ff3eed4a 7160 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
sPymbed 0:1387ff3eed4a 7161 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
sPymbed 0:1387ff3eed4a 7162 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
sPymbed 0:1387ff3eed4a 7163 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
sPymbed 0:1387ff3eed4a 7164 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
sPymbed 0:1387ff3eed4a 7165 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
sPymbed 0:1387ff3eed4a 7166 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
sPymbed 0:1387ff3eed4a 7167 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
sPymbed 0:1387ff3eed4a 7168 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
sPymbed 0:1387ff3eed4a 7169 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
sPymbed 0:1387ff3eed4a 7170 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
sPymbed 0:1387ff3eed4a 7171 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
sPymbed 0:1387ff3eed4a 7172 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
sPymbed 0:1387ff3eed4a 7173 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
sPymbed 0:1387ff3eed4a 7174 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
sPymbed 0:1387ff3eed4a 7175 #if FP_LUT > 10
sPymbed 0:1387ff3eed4a 7176 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
sPymbed 0:1387ff3eed4a 7177 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
sPymbed 0:1387ff3eed4a 7178 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
sPymbed 0:1387ff3eed4a 7179 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
sPymbed 0:1387ff3eed4a 7180 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
sPymbed 0:1387ff3eed4a 7181 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
sPymbed 0:1387ff3eed4a 7182 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
sPymbed 0:1387ff3eed4a 7183 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
sPymbed 0:1387ff3eed4a 7184 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
sPymbed 0:1387ff3eed4a 7185 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
sPymbed 0:1387ff3eed4a 7186 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
sPymbed 0:1387ff3eed4a 7187 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
sPymbed 0:1387ff3eed4a 7188 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
sPymbed 0:1387ff3eed4a 7189 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
sPymbed 0:1387ff3eed4a 7190 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
sPymbed 0:1387ff3eed4a 7191 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
sPymbed 0:1387ff3eed4a 7192 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
sPymbed 0:1387ff3eed4a 7193 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
sPymbed 0:1387ff3eed4a 7194 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
sPymbed 0:1387ff3eed4a 7195 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
sPymbed 0:1387ff3eed4a 7196 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
sPymbed 0:1387ff3eed4a 7197 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
sPymbed 0:1387ff3eed4a 7198 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
sPymbed 0:1387ff3eed4a 7199 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
sPymbed 0:1387ff3eed4a 7200 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
sPymbed 0:1387ff3eed4a 7201 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
sPymbed 0:1387ff3eed4a 7202 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
sPymbed 0:1387ff3eed4a 7203 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
sPymbed 0:1387ff3eed4a 7204 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
sPymbed 0:1387ff3eed4a 7205 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
sPymbed 0:1387ff3eed4a 7206 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
sPymbed 0:1387ff3eed4a 7207 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
sPymbed 0:1387ff3eed4a 7208 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
sPymbed 0:1387ff3eed4a 7209 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
sPymbed 0:1387ff3eed4a 7210 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
sPymbed 0:1387ff3eed4a 7211 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
sPymbed 0:1387ff3eed4a 7212 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
sPymbed 0:1387ff3eed4a 7213 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
sPymbed 0:1387ff3eed4a 7214 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
sPymbed 0:1387ff3eed4a 7215 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
sPymbed 0:1387ff3eed4a 7216 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
sPymbed 0:1387ff3eed4a 7217 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
sPymbed 0:1387ff3eed4a 7218 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
sPymbed 0:1387ff3eed4a 7219 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
sPymbed 0:1387ff3eed4a 7220 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
sPymbed 0:1387ff3eed4a 7221 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
sPymbed 0:1387ff3eed4a 7222 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
sPymbed 0:1387ff3eed4a 7223 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
sPymbed 0:1387ff3eed4a 7224 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
sPymbed 0:1387ff3eed4a 7225 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
sPymbed 0:1387ff3eed4a 7226 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
sPymbed 0:1387ff3eed4a 7227 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
sPymbed 0:1387ff3eed4a 7228 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
sPymbed 0:1387ff3eed4a 7229 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
sPymbed 0:1387ff3eed4a 7230 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
sPymbed 0:1387ff3eed4a 7231 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
sPymbed 0:1387ff3eed4a 7232 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
sPymbed 0:1387ff3eed4a 7233 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
sPymbed 0:1387ff3eed4a 7234 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
sPymbed 0:1387ff3eed4a 7235 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
sPymbed 0:1387ff3eed4a 7236 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
sPymbed 0:1387ff3eed4a 7237 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
sPymbed 0:1387ff3eed4a 7238 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
sPymbed 0:1387ff3eed4a 7239 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
sPymbed 0:1387ff3eed4a 7240 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
sPymbed 0:1387ff3eed4a 7241 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
sPymbed 0:1387ff3eed4a 7242 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
sPymbed 0:1387ff3eed4a 7243 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
sPymbed 0:1387ff3eed4a 7244 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
sPymbed 0:1387ff3eed4a 7245 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
sPymbed 0:1387ff3eed4a 7246 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
sPymbed 0:1387ff3eed4a 7247 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
sPymbed 0:1387ff3eed4a 7248 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
sPymbed 0:1387ff3eed4a 7249 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
sPymbed 0:1387ff3eed4a 7250 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
sPymbed 0:1387ff3eed4a 7251 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
sPymbed 0:1387ff3eed4a 7252 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
sPymbed 0:1387ff3eed4a 7253 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
sPymbed 0:1387ff3eed4a 7254 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
sPymbed 0:1387ff3eed4a 7255 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
sPymbed 0:1387ff3eed4a 7256 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
sPymbed 0:1387ff3eed4a 7257 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
sPymbed 0:1387ff3eed4a 7258 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
sPymbed 0:1387ff3eed4a 7259 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
sPymbed 0:1387ff3eed4a 7260 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
sPymbed 0:1387ff3eed4a 7261 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
sPymbed 0:1387ff3eed4a 7262 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
sPymbed 0:1387ff3eed4a 7263 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
sPymbed 0:1387ff3eed4a 7264 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
sPymbed 0:1387ff3eed4a 7265 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
sPymbed 0:1387ff3eed4a 7266 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
sPymbed 0:1387ff3eed4a 7267 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
sPymbed 0:1387ff3eed4a 7268 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
sPymbed 0:1387ff3eed4a 7269 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
sPymbed 0:1387ff3eed4a 7270 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
sPymbed 0:1387ff3eed4a 7271 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
sPymbed 0:1387ff3eed4a 7272 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
sPymbed 0:1387ff3eed4a 7273 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
sPymbed 0:1387ff3eed4a 7274 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
sPymbed 0:1387ff3eed4a 7275 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
sPymbed 0:1387ff3eed4a 7276 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
sPymbed 0:1387ff3eed4a 7277 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
sPymbed 0:1387ff3eed4a 7278 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
sPymbed 0:1387ff3eed4a 7279 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
sPymbed 0:1387ff3eed4a 7280 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
sPymbed 0:1387ff3eed4a 7281 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
sPymbed 0:1387ff3eed4a 7282 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
sPymbed 0:1387ff3eed4a 7283 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
sPymbed 0:1387ff3eed4a 7284 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
sPymbed 0:1387ff3eed4a 7285 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
sPymbed 0:1387ff3eed4a 7286 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
sPymbed 0:1387ff3eed4a 7287 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
sPymbed 0:1387ff3eed4a 7288 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
sPymbed 0:1387ff3eed4a 7289 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
sPymbed 0:1387ff3eed4a 7290 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
sPymbed 0:1387ff3eed4a 7291 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
sPymbed 0:1387ff3eed4a 7292 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
sPymbed 0:1387ff3eed4a 7293 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
sPymbed 0:1387ff3eed4a 7294 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
sPymbed 0:1387ff3eed4a 7295 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
sPymbed 0:1387ff3eed4a 7296 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
sPymbed 0:1387ff3eed4a 7297 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
sPymbed 0:1387ff3eed4a 7298 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
sPymbed 0:1387ff3eed4a 7299 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
sPymbed 0:1387ff3eed4a 7300 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
sPymbed 0:1387ff3eed4a 7301 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
sPymbed 0:1387ff3eed4a 7302 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
sPymbed 0:1387ff3eed4a 7303 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
sPymbed 0:1387ff3eed4a 7304 #if FP_LUT > 11
sPymbed 0:1387ff3eed4a 7305 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
sPymbed 0:1387ff3eed4a 7306 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
sPymbed 0:1387ff3eed4a 7307 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
sPymbed 0:1387ff3eed4a 7308 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
sPymbed 0:1387ff3eed4a 7309 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
sPymbed 0:1387ff3eed4a 7310 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
sPymbed 0:1387ff3eed4a 7311 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
sPymbed 0:1387ff3eed4a 7312 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
sPymbed 0:1387ff3eed4a 7313 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
sPymbed 0:1387ff3eed4a 7314 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
sPymbed 0:1387ff3eed4a 7315 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
sPymbed 0:1387ff3eed4a 7316 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
sPymbed 0:1387ff3eed4a 7317 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
sPymbed 0:1387ff3eed4a 7318 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
sPymbed 0:1387ff3eed4a 7319 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
sPymbed 0:1387ff3eed4a 7320 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
sPymbed 0:1387ff3eed4a 7321 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
sPymbed 0:1387ff3eed4a 7322 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
sPymbed 0:1387ff3eed4a 7323 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
sPymbed 0:1387ff3eed4a 7324 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
sPymbed 0:1387ff3eed4a 7325 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
sPymbed 0:1387ff3eed4a 7326 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
sPymbed 0:1387ff3eed4a 7327 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
sPymbed 0:1387ff3eed4a 7328 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
sPymbed 0:1387ff3eed4a 7329 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
sPymbed 0:1387ff3eed4a 7330 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
sPymbed 0:1387ff3eed4a 7331 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
sPymbed 0:1387ff3eed4a 7332 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
sPymbed 0:1387ff3eed4a 7333 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
sPymbed 0:1387ff3eed4a 7334 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
sPymbed 0:1387ff3eed4a 7335 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
sPymbed 0:1387ff3eed4a 7336 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
sPymbed 0:1387ff3eed4a 7337 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
sPymbed 0:1387ff3eed4a 7338 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
sPymbed 0:1387ff3eed4a 7339 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
sPymbed 0:1387ff3eed4a 7340 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
sPymbed 0:1387ff3eed4a 7341 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
sPymbed 0:1387ff3eed4a 7342 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
sPymbed 0:1387ff3eed4a 7343 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
sPymbed 0:1387ff3eed4a 7344 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
sPymbed 0:1387ff3eed4a 7345 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
sPymbed 0:1387ff3eed4a 7346 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
sPymbed 0:1387ff3eed4a 7347 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
sPymbed 0:1387ff3eed4a 7348 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
sPymbed 0:1387ff3eed4a 7349 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
sPymbed 0:1387ff3eed4a 7350 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
sPymbed 0:1387ff3eed4a 7351 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
sPymbed 0:1387ff3eed4a 7352 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
sPymbed 0:1387ff3eed4a 7353 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
sPymbed 0:1387ff3eed4a 7354 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
sPymbed 0:1387ff3eed4a 7355 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
sPymbed 0:1387ff3eed4a 7356 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
sPymbed 0:1387ff3eed4a 7357 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
sPymbed 0:1387ff3eed4a 7358 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
sPymbed 0:1387ff3eed4a 7359 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
sPymbed 0:1387ff3eed4a 7360 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
sPymbed 0:1387ff3eed4a 7361 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
sPymbed 0:1387ff3eed4a 7362 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
sPymbed 0:1387ff3eed4a 7363 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
sPymbed 0:1387ff3eed4a 7364 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
sPymbed 0:1387ff3eed4a 7365 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
sPymbed 0:1387ff3eed4a 7366 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
sPymbed 0:1387ff3eed4a 7367 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
sPymbed 0:1387ff3eed4a 7368 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
sPymbed 0:1387ff3eed4a 7369 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
sPymbed 0:1387ff3eed4a 7370 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
sPymbed 0:1387ff3eed4a 7371 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
sPymbed 0:1387ff3eed4a 7372 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
sPymbed 0:1387ff3eed4a 7373 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
sPymbed 0:1387ff3eed4a 7374 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
sPymbed 0:1387ff3eed4a 7375 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
sPymbed 0:1387ff3eed4a 7376 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
sPymbed 0:1387ff3eed4a 7377 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
sPymbed 0:1387ff3eed4a 7378 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
sPymbed 0:1387ff3eed4a 7379 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
sPymbed 0:1387ff3eed4a 7380 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
sPymbed 0:1387ff3eed4a 7381 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
sPymbed 0:1387ff3eed4a 7382 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
sPymbed 0:1387ff3eed4a 7383 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
sPymbed 0:1387ff3eed4a 7384 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
sPymbed 0:1387ff3eed4a 7385 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
sPymbed 0:1387ff3eed4a 7386 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
sPymbed 0:1387ff3eed4a 7387 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
sPymbed 0:1387ff3eed4a 7388 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
sPymbed 0:1387ff3eed4a 7389 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
sPymbed 0:1387ff3eed4a 7390 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
sPymbed 0:1387ff3eed4a 7391 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
sPymbed 0:1387ff3eed4a 7392 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
sPymbed 0:1387ff3eed4a 7393 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
sPymbed 0:1387ff3eed4a 7394 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
sPymbed 0:1387ff3eed4a 7395 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
sPymbed 0:1387ff3eed4a 7396 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
sPymbed 0:1387ff3eed4a 7397 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
sPymbed 0:1387ff3eed4a 7398 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
sPymbed 0:1387ff3eed4a 7399 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
sPymbed 0:1387ff3eed4a 7400 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
sPymbed 0:1387ff3eed4a 7401 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
sPymbed 0:1387ff3eed4a 7402 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
sPymbed 0:1387ff3eed4a 7403 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
sPymbed 0:1387ff3eed4a 7404 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
sPymbed 0:1387ff3eed4a 7405 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
sPymbed 0:1387ff3eed4a 7406 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
sPymbed 0:1387ff3eed4a 7407 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
sPymbed 0:1387ff3eed4a 7408 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
sPymbed 0:1387ff3eed4a 7409 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
sPymbed 0:1387ff3eed4a 7410 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
sPymbed 0:1387ff3eed4a 7411 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
sPymbed 0:1387ff3eed4a 7412 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
sPymbed 0:1387ff3eed4a 7413 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
sPymbed 0:1387ff3eed4a 7414 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
sPymbed 0:1387ff3eed4a 7415 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
sPymbed 0:1387ff3eed4a 7416 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
sPymbed 0:1387ff3eed4a 7417 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
sPymbed 0:1387ff3eed4a 7418 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
sPymbed 0:1387ff3eed4a 7419 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
sPymbed 0:1387ff3eed4a 7420 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
sPymbed 0:1387ff3eed4a 7421 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
sPymbed 0:1387ff3eed4a 7422 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
sPymbed 0:1387ff3eed4a 7423 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
sPymbed 0:1387ff3eed4a 7424 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
sPymbed 0:1387ff3eed4a 7425 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
sPymbed 0:1387ff3eed4a 7426 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
sPymbed 0:1387ff3eed4a 7427 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
sPymbed 0:1387ff3eed4a 7428 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
sPymbed 0:1387ff3eed4a 7429 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
sPymbed 0:1387ff3eed4a 7430 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
sPymbed 0:1387ff3eed4a 7431 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
sPymbed 0:1387ff3eed4a 7432 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
sPymbed 0:1387ff3eed4a 7433 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
sPymbed 0:1387ff3eed4a 7434 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
sPymbed 0:1387ff3eed4a 7435 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
sPymbed 0:1387ff3eed4a 7436 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
sPymbed 0:1387ff3eed4a 7437 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
sPymbed 0:1387ff3eed4a 7438 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
sPymbed 0:1387ff3eed4a 7439 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
sPymbed 0:1387ff3eed4a 7440 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
sPymbed 0:1387ff3eed4a 7441 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
sPymbed 0:1387ff3eed4a 7442 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
sPymbed 0:1387ff3eed4a 7443 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
sPymbed 0:1387ff3eed4a 7444 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
sPymbed 0:1387ff3eed4a 7445 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
sPymbed 0:1387ff3eed4a 7446 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
sPymbed 0:1387ff3eed4a 7447 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
sPymbed 0:1387ff3eed4a 7448 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
sPymbed 0:1387ff3eed4a 7449 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
sPymbed 0:1387ff3eed4a 7450 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
sPymbed 0:1387ff3eed4a 7451 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
sPymbed 0:1387ff3eed4a 7452 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
sPymbed 0:1387ff3eed4a 7453 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
sPymbed 0:1387ff3eed4a 7454 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
sPymbed 0:1387ff3eed4a 7455 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
sPymbed 0:1387ff3eed4a 7456 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
sPymbed 0:1387ff3eed4a 7457 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
sPymbed 0:1387ff3eed4a 7458 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
sPymbed 0:1387ff3eed4a 7459 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
sPymbed 0:1387ff3eed4a 7460 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
sPymbed 0:1387ff3eed4a 7461 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
sPymbed 0:1387ff3eed4a 7462 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
sPymbed 0:1387ff3eed4a 7463 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
sPymbed 0:1387ff3eed4a 7464 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
sPymbed 0:1387ff3eed4a 7465 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
sPymbed 0:1387ff3eed4a 7466 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
sPymbed 0:1387ff3eed4a 7467 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
sPymbed 0:1387ff3eed4a 7468 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
sPymbed 0:1387ff3eed4a 7469 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
sPymbed 0:1387ff3eed4a 7470 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
sPymbed 0:1387ff3eed4a 7471 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
sPymbed 0:1387ff3eed4a 7472 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
sPymbed 0:1387ff3eed4a 7473 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
sPymbed 0:1387ff3eed4a 7474 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
sPymbed 0:1387ff3eed4a 7475 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
sPymbed 0:1387ff3eed4a 7476 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
sPymbed 0:1387ff3eed4a 7477 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
sPymbed 0:1387ff3eed4a 7478 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
sPymbed 0:1387ff3eed4a 7479 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
sPymbed 0:1387ff3eed4a 7480 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
sPymbed 0:1387ff3eed4a 7481 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
sPymbed 0:1387ff3eed4a 7482 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
sPymbed 0:1387ff3eed4a 7483 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
sPymbed 0:1387ff3eed4a 7484 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
sPymbed 0:1387ff3eed4a 7485 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
sPymbed 0:1387ff3eed4a 7486 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
sPymbed 0:1387ff3eed4a 7487 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
sPymbed 0:1387ff3eed4a 7488 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
sPymbed 0:1387ff3eed4a 7489 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
sPymbed 0:1387ff3eed4a 7490 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
sPymbed 0:1387ff3eed4a 7491 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
sPymbed 0:1387ff3eed4a 7492 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
sPymbed 0:1387ff3eed4a 7493 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
sPymbed 0:1387ff3eed4a 7494 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
sPymbed 0:1387ff3eed4a 7495 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
sPymbed 0:1387ff3eed4a 7496 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
sPymbed 0:1387ff3eed4a 7497 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
sPymbed 0:1387ff3eed4a 7498 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
sPymbed 0:1387ff3eed4a 7499 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
sPymbed 0:1387ff3eed4a 7500 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
sPymbed 0:1387ff3eed4a 7501 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
sPymbed 0:1387ff3eed4a 7502 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
sPymbed 0:1387ff3eed4a 7503 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
sPymbed 0:1387ff3eed4a 7504 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
sPymbed 0:1387ff3eed4a 7505 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
sPymbed 0:1387ff3eed4a 7506 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
sPymbed 0:1387ff3eed4a 7507 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
sPymbed 0:1387ff3eed4a 7508 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
sPymbed 0:1387ff3eed4a 7509 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
sPymbed 0:1387ff3eed4a 7510 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
sPymbed 0:1387ff3eed4a 7511 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
sPymbed 0:1387ff3eed4a 7512 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
sPymbed 0:1387ff3eed4a 7513 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
sPymbed 0:1387ff3eed4a 7514 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
sPymbed 0:1387ff3eed4a 7515 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
sPymbed 0:1387ff3eed4a 7516 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
sPymbed 0:1387ff3eed4a 7517 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
sPymbed 0:1387ff3eed4a 7518 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
sPymbed 0:1387ff3eed4a 7519 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
sPymbed 0:1387ff3eed4a 7520 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
sPymbed 0:1387ff3eed4a 7521 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
sPymbed 0:1387ff3eed4a 7522 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
sPymbed 0:1387ff3eed4a 7523 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
sPymbed 0:1387ff3eed4a 7524 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
sPymbed 0:1387ff3eed4a 7525 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
sPymbed 0:1387ff3eed4a 7526 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
sPymbed 0:1387ff3eed4a 7527 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
sPymbed 0:1387ff3eed4a 7528 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
sPymbed 0:1387ff3eed4a 7529 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
sPymbed 0:1387ff3eed4a 7530 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
sPymbed 0:1387ff3eed4a 7531 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
sPymbed 0:1387ff3eed4a 7532 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
sPymbed 0:1387ff3eed4a 7533 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
sPymbed 0:1387ff3eed4a 7534 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
sPymbed 0:1387ff3eed4a 7535 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
sPymbed 0:1387ff3eed4a 7536 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
sPymbed 0:1387ff3eed4a 7537 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
sPymbed 0:1387ff3eed4a 7538 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
sPymbed 0:1387ff3eed4a 7539 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
sPymbed 0:1387ff3eed4a 7540 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
sPymbed 0:1387ff3eed4a 7541 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
sPymbed 0:1387ff3eed4a 7542 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
sPymbed 0:1387ff3eed4a 7543 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
sPymbed 0:1387ff3eed4a 7544 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
sPymbed 0:1387ff3eed4a 7545 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
sPymbed 0:1387ff3eed4a 7546 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
sPymbed 0:1387ff3eed4a 7547 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
sPymbed 0:1387ff3eed4a 7548 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
sPymbed 0:1387ff3eed4a 7549 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
sPymbed 0:1387ff3eed4a 7550 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
sPymbed 0:1387ff3eed4a 7551 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
sPymbed 0:1387ff3eed4a 7552 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
sPymbed 0:1387ff3eed4a 7553 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
sPymbed 0:1387ff3eed4a 7554 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
sPymbed 0:1387ff3eed4a 7555 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
sPymbed 0:1387ff3eed4a 7556 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
sPymbed 0:1387ff3eed4a 7557 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
sPymbed 0:1387ff3eed4a 7558 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
sPymbed 0:1387ff3eed4a 7559 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
sPymbed 0:1387ff3eed4a 7560 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
sPymbed 0:1387ff3eed4a 7561 #endif
sPymbed 0:1387ff3eed4a 7562 #endif
sPymbed 0:1387ff3eed4a 7563 #endif
sPymbed 0:1387ff3eed4a 7564 #endif
sPymbed 0:1387ff3eed4a 7565 #endif
sPymbed 0:1387ff3eed4a 7566 #endif
sPymbed 0:1387ff3eed4a 7567 };
sPymbed 0:1387ff3eed4a 7568
sPymbed 0:1387ff3eed4a 7569
sPymbed 0:1387ff3eed4a 7570 /* find a hole and free as required, return -1 if no hole found */
sPymbed 0:1387ff3eed4a 7571 static int find_hole(void)
sPymbed 0:1387ff3eed4a 7572 {
sPymbed 0:1387ff3eed4a 7573 unsigned x;
sPymbed 0:1387ff3eed4a 7574 int y, z;
sPymbed 0:1387ff3eed4a 7575 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
sPymbed 0:1387ff3eed4a 7576 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
sPymbed 0:1387ff3eed4a 7577 z = x;
sPymbed 0:1387ff3eed4a 7578 y = fp_cache[x].lru_count;
sPymbed 0:1387ff3eed4a 7579 }
sPymbed 0:1387ff3eed4a 7580 }
sPymbed 0:1387ff3eed4a 7581
sPymbed 0:1387ff3eed4a 7582 /* decrease all */
sPymbed 0:1387ff3eed4a 7583 for (x = 0; x < FP_ENTRIES; x++) {
sPymbed 0:1387ff3eed4a 7584 if (fp_cache[x].lru_count > 3) {
sPymbed 0:1387ff3eed4a 7585 --(fp_cache[x].lru_count);
sPymbed 0:1387ff3eed4a 7586 }
sPymbed 0:1387ff3eed4a 7587 }
sPymbed 0:1387ff3eed4a 7588
sPymbed 0:1387ff3eed4a 7589 /* free entry z */
sPymbed 0:1387ff3eed4a 7590 if (z >= 0 && fp_cache[z].g) {
sPymbed 0:1387ff3eed4a 7591 mp_clear(&fp_cache[z].mu);
sPymbed 0:1387ff3eed4a 7592 wc_ecc_del_point(fp_cache[z].g);
sPymbed 0:1387ff3eed4a 7593 fp_cache[z].g = NULL;
sPymbed 0:1387ff3eed4a 7594 for (x = 0; x < (1U<<FP_LUT); x++) {
sPymbed 0:1387ff3eed4a 7595 wc_ecc_del_point(fp_cache[z].LUT[x]);
sPymbed 0:1387ff3eed4a 7596 fp_cache[z].LUT[x] = NULL;
sPymbed 0:1387ff3eed4a 7597 }
sPymbed 0:1387ff3eed4a 7598 fp_cache[z].lru_count = 0;
sPymbed 0:1387ff3eed4a 7599 }
sPymbed 0:1387ff3eed4a 7600 return z;
sPymbed 0:1387ff3eed4a 7601 }
sPymbed 0:1387ff3eed4a 7602
sPymbed 0:1387ff3eed4a 7603 /* determine if a base is already in the cache and if so, where */
sPymbed 0:1387ff3eed4a 7604 static int find_base(ecc_point* g)
sPymbed 0:1387ff3eed4a 7605 {
sPymbed 0:1387ff3eed4a 7606 int x;
sPymbed 0:1387ff3eed4a 7607 for (x = 0; x < FP_ENTRIES; x++) {
sPymbed 0:1387ff3eed4a 7608 if (fp_cache[x].g != NULL &&
sPymbed 0:1387ff3eed4a 7609 mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
sPymbed 0:1387ff3eed4a 7610 mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
sPymbed 0:1387ff3eed4a 7611 mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
sPymbed 0:1387ff3eed4a 7612 break;
sPymbed 0:1387ff3eed4a 7613 }
sPymbed 0:1387ff3eed4a 7614 }
sPymbed 0:1387ff3eed4a 7615 if (x == FP_ENTRIES) {
sPymbed 0:1387ff3eed4a 7616 x = -1;
sPymbed 0:1387ff3eed4a 7617 }
sPymbed 0:1387ff3eed4a 7618 return x;
sPymbed 0:1387ff3eed4a 7619 }
sPymbed 0:1387ff3eed4a 7620
sPymbed 0:1387ff3eed4a 7621 /* add a new base to the cache */
sPymbed 0:1387ff3eed4a 7622 static int add_entry(int idx, ecc_point *g)
sPymbed 0:1387ff3eed4a 7623 {
sPymbed 0:1387ff3eed4a 7624 unsigned x, y;
sPymbed 0:1387ff3eed4a 7625
sPymbed 0:1387ff3eed4a 7626 /* allocate base and LUT */
sPymbed 0:1387ff3eed4a 7627 fp_cache[idx].g = wc_ecc_new_point();
sPymbed 0:1387ff3eed4a 7628 if (fp_cache[idx].g == NULL) {
sPymbed 0:1387ff3eed4a 7629 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 7630 }
sPymbed 0:1387ff3eed4a 7631
sPymbed 0:1387ff3eed4a 7632 /* copy x and y */
sPymbed 0:1387ff3eed4a 7633 if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7634 (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7635 (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
sPymbed 0:1387ff3eed4a 7636 wc_ecc_del_point(fp_cache[idx].g);
sPymbed 0:1387ff3eed4a 7637 fp_cache[idx].g = NULL;
sPymbed 0:1387ff3eed4a 7638 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 7639 }
sPymbed 0:1387ff3eed4a 7640
sPymbed 0:1387ff3eed4a 7641 for (x = 0; x < (1U<<FP_LUT); x++) {
sPymbed 0:1387ff3eed4a 7642 fp_cache[idx].LUT[x] = wc_ecc_new_point();
sPymbed 0:1387ff3eed4a 7643 if (fp_cache[idx].LUT[x] == NULL) {
sPymbed 0:1387ff3eed4a 7644 for (y = 0; y < x; y++) {
sPymbed 0:1387ff3eed4a 7645 wc_ecc_del_point(fp_cache[idx].LUT[y]);
sPymbed 0:1387ff3eed4a 7646 fp_cache[idx].LUT[y] = NULL;
sPymbed 0:1387ff3eed4a 7647 }
sPymbed 0:1387ff3eed4a 7648 wc_ecc_del_point(fp_cache[idx].g);
sPymbed 0:1387ff3eed4a 7649 fp_cache[idx].g = NULL;
sPymbed 0:1387ff3eed4a 7650 fp_cache[idx].lru_count = 0;
sPymbed 0:1387ff3eed4a 7651 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 7652 }
sPymbed 0:1387ff3eed4a 7653 }
sPymbed 0:1387ff3eed4a 7654
sPymbed 0:1387ff3eed4a 7655 fp_cache[idx].lru_count = 0;
sPymbed 0:1387ff3eed4a 7656
sPymbed 0:1387ff3eed4a 7657 return MP_OKAY;
sPymbed 0:1387ff3eed4a 7658 }
sPymbed 0:1387ff3eed4a 7659 #endif
sPymbed 0:1387ff3eed4a 7660
sPymbed 0:1387ff3eed4a 7661 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 7662 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
sPymbed 0:1387ff3eed4a 7663 *
sPymbed 0:1387ff3eed4a 7664 * The algorithm builds patterns in increasing bit order by first making all
sPymbed 0:1387ff3eed4a 7665 * single bit input patterns, then all two bit input patterns and so on
sPymbed 0:1387ff3eed4a 7666 */
sPymbed 0:1387ff3eed4a 7667 static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
sPymbed 0:1387ff3eed4a 7668 mp_int* mu)
sPymbed 0:1387ff3eed4a 7669 {
sPymbed 0:1387ff3eed4a 7670 int err;
sPymbed 0:1387ff3eed4a 7671 unsigned x, y, bitlen, lut_gap;
sPymbed 0:1387ff3eed4a 7672 mp_int tmp;
sPymbed 0:1387ff3eed4a 7673
sPymbed 0:1387ff3eed4a 7674 if (mp_init(&tmp) != MP_OKAY)
sPymbed 0:1387ff3eed4a 7675 return GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 7676
sPymbed 0:1387ff3eed4a 7677 /* sanity check to make sure lut_order table is of correct size,
sPymbed 0:1387ff3eed4a 7678 should compile out to a NOP if true */
sPymbed 0:1387ff3eed4a 7679 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
sPymbed 0:1387ff3eed4a 7680 err = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 7681 }
sPymbed 0:1387ff3eed4a 7682 else {
sPymbed 0:1387ff3eed4a 7683 /* get bitlen and round up to next multiple of FP_LUT */
sPymbed 0:1387ff3eed4a 7684 bitlen = mp_unsigned_bin_size(modulus) << 3;
sPymbed 0:1387ff3eed4a 7685 x = bitlen % FP_LUT;
sPymbed 0:1387ff3eed4a 7686 if (x) {
sPymbed 0:1387ff3eed4a 7687 bitlen += FP_LUT - x;
sPymbed 0:1387ff3eed4a 7688 }
sPymbed 0:1387ff3eed4a 7689 lut_gap = bitlen / FP_LUT;
sPymbed 0:1387ff3eed4a 7690
sPymbed 0:1387ff3eed4a 7691 /* init the mu */
sPymbed 0:1387ff3eed4a 7692 err = mp_init_copy(&fp_cache[idx].mu, mu);
sPymbed 0:1387ff3eed4a 7693 }
sPymbed 0:1387ff3eed4a 7694
sPymbed 0:1387ff3eed4a 7695 /* copy base */
sPymbed 0:1387ff3eed4a 7696 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 7697 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
sPymbed 0:1387ff3eed4a 7698 fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7699 (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
sPymbed 0:1387ff3eed4a 7700 fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7701 (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
sPymbed 0:1387ff3eed4a 7702 fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
sPymbed 0:1387ff3eed4a 7703 err = MP_MULMOD_E;
sPymbed 0:1387ff3eed4a 7704 }
sPymbed 0:1387ff3eed4a 7705 }
sPymbed 0:1387ff3eed4a 7706
sPymbed 0:1387ff3eed4a 7707 /* make all single bit entries */
sPymbed 0:1387ff3eed4a 7708 for (x = 1; x < FP_LUT; x++) {
sPymbed 0:1387ff3eed4a 7709 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 7710 break;
sPymbed 0:1387ff3eed4a 7711 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x,
sPymbed 0:1387ff3eed4a 7712 fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7713 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y,
sPymbed 0:1387ff3eed4a 7714 fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7715 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z,
sPymbed 0:1387ff3eed4a 7716 fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){
sPymbed 0:1387ff3eed4a 7717 err = MP_INIT_E;
sPymbed 0:1387ff3eed4a 7718 break;
sPymbed 0:1387ff3eed4a 7719 } else {
sPymbed 0:1387ff3eed4a 7720
sPymbed 0:1387ff3eed4a 7721 /* now double it bitlen/FP_LUT times */
sPymbed 0:1387ff3eed4a 7722 for (y = 0; y < lut_gap; y++) {
sPymbed 0:1387ff3eed4a 7723 if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x],
sPymbed 0:1387ff3eed4a 7724 fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7725 break;
sPymbed 0:1387ff3eed4a 7726 }
sPymbed 0:1387ff3eed4a 7727 }
sPymbed 0:1387ff3eed4a 7728 }
sPymbed 0:1387ff3eed4a 7729 }
sPymbed 0:1387ff3eed4a 7730
sPymbed 0:1387ff3eed4a 7731 /* now make all entries in increase order of hamming weight */
sPymbed 0:1387ff3eed4a 7732 for (x = 2; x <= FP_LUT; x++) {
sPymbed 0:1387ff3eed4a 7733 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 7734 break;
sPymbed 0:1387ff3eed4a 7735 for (y = 0; y < (1UL<<FP_LUT); y++) {
sPymbed 0:1387ff3eed4a 7736 if (lut_orders[y].ham != (int)x) continue;
sPymbed 0:1387ff3eed4a 7737
sPymbed 0:1387ff3eed4a 7738 /* perform the add */
sPymbed 0:1387ff3eed4a 7739 if ((err = ecc_projective_add_point(
sPymbed 0:1387ff3eed4a 7740 fp_cache[idx].LUT[lut_orders[y].terma],
sPymbed 0:1387ff3eed4a 7741 fp_cache[idx].LUT[lut_orders[y].termb],
sPymbed 0:1387ff3eed4a 7742 fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7743 break;
sPymbed 0:1387ff3eed4a 7744 }
sPymbed 0:1387ff3eed4a 7745 }
sPymbed 0:1387ff3eed4a 7746 }
sPymbed 0:1387ff3eed4a 7747
sPymbed 0:1387ff3eed4a 7748 /* now map all entries back to affine space to make point addition faster */
sPymbed 0:1387ff3eed4a 7749 for (x = 1; x < (1UL<<FP_LUT); x++) {
sPymbed 0:1387ff3eed4a 7750 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 7751 break;
sPymbed 0:1387ff3eed4a 7752
sPymbed 0:1387ff3eed4a 7753 /* convert z to normal from montgomery */
sPymbed 0:1387ff3eed4a 7754 err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
sPymbed 0:1387ff3eed4a 7755
sPymbed 0:1387ff3eed4a 7756 /* invert it */
sPymbed 0:1387ff3eed4a 7757 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7758 err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
sPymbed 0:1387ff3eed4a 7759 fp_cache[idx].LUT[x]->z);
sPymbed 0:1387ff3eed4a 7760
sPymbed 0:1387ff3eed4a 7761 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7762 /* now square it */
sPymbed 0:1387ff3eed4a 7763 err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp);
sPymbed 0:1387ff3eed4a 7764
sPymbed 0:1387ff3eed4a 7765 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7766 /* fix x */
sPymbed 0:1387ff3eed4a 7767 err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus,
sPymbed 0:1387ff3eed4a 7768 fp_cache[idx].LUT[x]->x);
sPymbed 0:1387ff3eed4a 7769
sPymbed 0:1387ff3eed4a 7770 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7771 /* get 1/z^3 */
sPymbed 0:1387ff3eed4a 7772 err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp);
sPymbed 0:1387ff3eed4a 7773
sPymbed 0:1387ff3eed4a 7774 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7775 /* fix y */
sPymbed 0:1387ff3eed4a 7776 err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus,
sPymbed 0:1387ff3eed4a 7777 fp_cache[idx].LUT[x]->y);
sPymbed 0:1387ff3eed4a 7778
sPymbed 0:1387ff3eed4a 7779 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7780 /* free z */
sPymbed 0:1387ff3eed4a 7781 mp_clear(fp_cache[idx].LUT[x]->z);
sPymbed 0:1387ff3eed4a 7782 }
sPymbed 0:1387ff3eed4a 7783
sPymbed 0:1387ff3eed4a 7784 mp_clear(&tmp);
sPymbed 0:1387ff3eed4a 7785
sPymbed 0:1387ff3eed4a 7786 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 7787 return MP_OKAY;
sPymbed 0:1387ff3eed4a 7788
sPymbed 0:1387ff3eed4a 7789 /* err cleanup */
sPymbed 0:1387ff3eed4a 7790 for (y = 0; y < (1U<<FP_LUT); y++) {
sPymbed 0:1387ff3eed4a 7791 wc_ecc_del_point(fp_cache[idx].LUT[y]);
sPymbed 0:1387ff3eed4a 7792 fp_cache[idx].LUT[y] = NULL;
sPymbed 0:1387ff3eed4a 7793 }
sPymbed 0:1387ff3eed4a 7794 wc_ecc_del_point(fp_cache[idx].g);
sPymbed 0:1387ff3eed4a 7795 fp_cache[idx].g = NULL;
sPymbed 0:1387ff3eed4a 7796 fp_cache[idx].lru_count = 0;
sPymbed 0:1387ff3eed4a 7797 mp_clear(&fp_cache[idx].mu);
sPymbed 0:1387ff3eed4a 7798
sPymbed 0:1387ff3eed4a 7799 return err;
sPymbed 0:1387ff3eed4a 7800 }
sPymbed 0:1387ff3eed4a 7801
sPymbed 0:1387ff3eed4a 7802 /* perform a fixed point ECC mulmod */
sPymbed 0:1387ff3eed4a 7803 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
sPymbed 0:1387ff3eed4a 7804 mp_int* modulus, mp_digit mp, int map)
sPymbed 0:1387ff3eed4a 7805 {
sPymbed 0:1387ff3eed4a 7806 #define KB_SIZE 128
sPymbed 0:1387ff3eed4a 7807
sPymbed 0:1387ff3eed4a 7808 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 7809 unsigned char* kb = NULL;
sPymbed 0:1387ff3eed4a 7810 #else
sPymbed 0:1387ff3eed4a 7811 unsigned char kb[KB_SIZE];
sPymbed 0:1387ff3eed4a 7812 #endif
sPymbed 0:1387ff3eed4a 7813 int x, err;
sPymbed 0:1387ff3eed4a 7814 unsigned y, z = 0, bitlen, bitpos, lut_gap, first;
sPymbed 0:1387ff3eed4a 7815 mp_int tk, order;
sPymbed 0:1387ff3eed4a 7816
sPymbed 0:1387ff3eed4a 7817 if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY)
sPymbed 0:1387ff3eed4a 7818 return MP_INIT_E;
sPymbed 0:1387ff3eed4a 7819
sPymbed 0:1387ff3eed4a 7820 /* if it's smaller than modulus we fine */
sPymbed 0:1387ff3eed4a 7821 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
sPymbed 0:1387ff3eed4a 7822 /* find order */
sPymbed 0:1387ff3eed4a 7823 y = mp_unsigned_bin_size(modulus);
sPymbed 0:1387ff3eed4a 7824 for (x = 0; ecc_sets[x].size; x++) {
sPymbed 0:1387ff3eed4a 7825 if (y <= (unsigned)ecc_sets[x].size) break;
sPymbed 0:1387ff3eed4a 7826 }
sPymbed 0:1387ff3eed4a 7827
sPymbed 0:1387ff3eed4a 7828 /* back off if we are on the 521 bit curve */
sPymbed 0:1387ff3eed4a 7829 if (y == 66) --x;
sPymbed 0:1387ff3eed4a 7830
sPymbed 0:1387ff3eed4a 7831 if ((err = mp_read_radix(&order, ecc_sets[x].order,
sPymbed 0:1387ff3eed4a 7832 MP_RADIX_HEX)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7833 goto done;
sPymbed 0:1387ff3eed4a 7834 }
sPymbed 0:1387ff3eed4a 7835
sPymbed 0:1387ff3eed4a 7836 /* k must be less than modulus */
sPymbed 0:1387ff3eed4a 7837 if (mp_cmp(k, &order) != MP_LT) {
sPymbed 0:1387ff3eed4a 7838 if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7839 goto done;
sPymbed 0:1387ff3eed4a 7840 }
sPymbed 0:1387ff3eed4a 7841 } else {
sPymbed 0:1387ff3eed4a 7842 if ((err = mp_copy(k, &tk)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7843 goto done;
sPymbed 0:1387ff3eed4a 7844 }
sPymbed 0:1387ff3eed4a 7845 }
sPymbed 0:1387ff3eed4a 7846 } else {
sPymbed 0:1387ff3eed4a 7847 if ((err = mp_copy(k, &tk)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7848 goto done;
sPymbed 0:1387ff3eed4a 7849 }
sPymbed 0:1387ff3eed4a 7850 }
sPymbed 0:1387ff3eed4a 7851
sPymbed 0:1387ff3eed4a 7852 /* get bitlen and round up to next multiple of FP_LUT */
sPymbed 0:1387ff3eed4a 7853 bitlen = mp_unsigned_bin_size(modulus) << 3;
sPymbed 0:1387ff3eed4a 7854 x = bitlen % FP_LUT;
sPymbed 0:1387ff3eed4a 7855 if (x) {
sPymbed 0:1387ff3eed4a 7856 bitlen += FP_LUT - x;
sPymbed 0:1387ff3eed4a 7857 }
sPymbed 0:1387ff3eed4a 7858 lut_gap = bitlen / FP_LUT;
sPymbed 0:1387ff3eed4a 7859
sPymbed 0:1387ff3eed4a 7860 /* get the k value */
sPymbed 0:1387ff3eed4a 7861 if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) {
sPymbed 0:1387ff3eed4a 7862 err = BUFFER_E; goto done;
sPymbed 0:1387ff3eed4a 7863 }
sPymbed 0:1387ff3eed4a 7864
sPymbed 0:1387ff3eed4a 7865 /* store k */
sPymbed 0:1387ff3eed4a 7866 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 7867 kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 7868 if (kb == NULL) {
sPymbed 0:1387ff3eed4a 7869 err = MEMORY_E; goto done;
sPymbed 0:1387ff3eed4a 7870 }
sPymbed 0:1387ff3eed4a 7871 #endif
sPymbed 0:1387ff3eed4a 7872
sPymbed 0:1387ff3eed4a 7873 XMEMSET(kb, 0, KB_SIZE);
sPymbed 0:1387ff3eed4a 7874 if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) {
sPymbed 0:1387ff3eed4a 7875 /* let's reverse kb so it's little endian */
sPymbed 0:1387ff3eed4a 7876 x = 0;
sPymbed 0:1387ff3eed4a 7877 y = mp_unsigned_bin_size(&tk);
sPymbed 0:1387ff3eed4a 7878 if (y > 0) {
sPymbed 0:1387ff3eed4a 7879 y -= 1;
sPymbed 0:1387ff3eed4a 7880 }
sPymbed 0:1387ff3eed4a 7881
sPymbed 0:1387ff3eed4a 7882 while ((unsigned)x < y) {
sPymbed 0:1387ff3eed4a 7883 z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
sPymbed 0:1387ff3eed4a 7884 ++x; --y;
sPymbed 0:1387ff3eed4a 7885 }
sPymbed 0:1387ff3eed4a 7886
sPymbed 0:1387ff3eed4a 7887 /* at this point we can start, yipee */
sPymbed 0:1387ff3eed4a 7888 first = 1;
sPymbed 0:1387ff3eed4a 7889 for (x = lut_gap-1; x >= 0; x--) {
sPymbed 0:1387ff3eed4a 7890 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
sPymbed 0:1387ff3eed4a 7891 by x bits from the start */
sPymbed 0:1387ff3eed4a 7892 bitpos = x;
sPymbed 0:1387ff3eed4a 7893 for (y = z = 0; y < FP_LUT; y++) {
sPymbed 0:1387ff3eed4a 7894 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y;
sPymbed 0:1387ff3eed4a 7895 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid
sPymbed 0:1387ff3eed4a 7896 the mult in each loop */
sPymbed 0:1387ff3eed4a 7897 }
sPymbed 0:1387ff3eed4a 7898
sPymbed 0:1387ff3eed4a 7899 /* double if not first */
sPymbed 0:1387ff3eed4a 7900 if (!first) {
sPymbed 0:1387ff3eed4a 7901 if ((err = ecc_projective_dbl_point(R, R, a, modulus,
sPymbed 0:1387ff3eed4a 7902 mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7903 break;
sPymbed 0:1387ff3eed4a 7904 }
sPymbed 0:1387ff3eed4a 7905 }
sPymbed 0:1387ff3eed4a 7906
sPymbed 0:1387ff3eed4a 7907 /* add if not first, otherwise copy */
sPymbed 0:1387ff3eed4a 7908 if (!first && z) {
sPymbed 0:1387ff3eed4a 7909 if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
sPymbed 0:1387ff3eed4a 7910 a, modulus, mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7911 break;
sPymbed 0:1387ff3eed4a 7912 }
sPymbed 0:1387ff3eed4a 7913 } else if (z) {
sPymbed 0:1387ff3eed4a 7914 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7915 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 7916 (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) {
sPymbed 0:1387ff3eed4a 7917 err = GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 7918 break;
sPymbed 0:1387ff3eed4a 7919 }
sPymbed 0:1387ff3eed4a 7920 first = 0;
sPymbed 0:1387ff3eed4a 7921 }
sPymbed 0:1387ff3eed4a 7922 }
sPymbed 0:1387ff3eed4a 7923 }
sPymbed 0:1387ff3eed4a 7924
sPymbed 0:1387ff3eed4a 7925 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 7926 (void) z; /* Acknowledge the unused assignment */
sPymbed 0:1387ff3eed4a 7927 ForceZero(kb, KB_SIZE);
sPymbed 0:1387ff3eed4a 7928
sPymbed 0:1387ff3eed4a 7929 /* map R back from projective space */
sPymbed 0:1387ff3eed4a 7930 if (map) {
sPymbed 0:1387ff3eed4a 7931 err = ecc_map(R, modulus, mp);
sPymbed 0:1387ff3eed4a 7932 } else {
sPymbed 0:1387ff3eed4a 7933 err = MP_OKAY;
sPymbed 0:1387ff3eed4a 7934 }
sPymbed 0:1387ff3eed4a 7935 }
sPymbed 0:1387ff3eed4a 7936
sPymbed 0:1387ff3eed4a 7937 done:
sPymbed 0:1387ff3eed4a 7938 /* cleanup */
sPymbed 0:1387ff3eed4a 7939 mp_clear(&order);
sPymbed 0:1387ff3eed4a 7940 mp_clear(&tk);
sPymbed 0:1387ff3eed4a 7941
sPymbed 0:1387ff3eed4a 7942 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 7943 XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 7944 #endif
sPymbed 0:1387ff3eed4a 7945
sPymbed 0:1387ff3eed4a 7946 #undef KB_SIZE
sPymbed 0:1387ff3eed4a 7947
sPymbed 0:1387ff3eed4a 7948 return err;
sPymbed 0:1387ff3eed4a 7949 }
sPymbed 0:1387ff3eed4a 7950 #endif
sPymbed 0:1387ff3eed4a 7951
sPymbed 0:1387ff3eed4a 7952 #ifdef ECC_SHAMIR
sPymbed 0:1387ff3eed4a 7953 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 7954 /* perform a fixed point ECC mulmod */
sPymbed 0:1387ff3eed4a 7955 static int accel_fp_mul2add(int idx1, int idx2,
sPymbed 0:1387ff3eed4a 7956 mp_int* kA, mp_int* kB,
sPymbed 0:1387ff3eed4a 7957 ecc_point *R, mp_int* a,
sPymbed 0:1387ff3eed4a 7958 mp_int* modulus, mp_digit mp)
sPymbed 0:1387ff3eed4a 7959 {
sPymbed 0:1387ff3eed4a 7960 #define KB_SIZE 128
sPymbed 0:1387ff3eed4a 7961
sPymbed 0:1387ff3eed4a 7962 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 7963 unsigned char* kb[2] = {NULL, NULL};
sPymbed 0:1387ff3eed4a 7964 #else
sPymbed 0:1387ff3eed4a 7965 unsigned char kb[2][KB_SIZE];
sPymbed 0:1387ff3eed4a 7966 #endif
sPymbed 0:1387ff3eed4a 7967 int x, err;
sPymbed 0:1387ff3eed4a 7968 unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB;
sPymbed 0:1387ff3eed4a 7969 mp_int tka, tkb, order;
sPymbed 0:1387ff3eed4a 7970
sPymbed 0:1387ff3eed4a 7971 if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY)
sPymbed 0:1387ff3eed4a 7972 return MP_INIT_E;
sPymbed 0:1387ff3eed4a 7973
sPymbed 0:1387ff3eed4a 7974 /* if it's smaller than modulus we fine */
sPymbed 0:1387ff3eed4a 7975 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
sPymbed 0:1387ff3eed4a 7976 /* find order */
sPymbed 0:1387ff3eed4a 7977 y = mp_unsigned_bin_size(modulus);
sPymbed 0:1387ff3eed4a 7978 for (x = 0; ecc_sets[x].size; x++) {
sPymbed 0:1387ff3eed4a 7979 if (y <= (unsigned)ecc_sets[x].size) break;
sPymbed 0:1387ff3eed4a 7980 }
sPymbed 0:1387ff3eed4a 7981
sPymbed 0:1387ff3eed4a 7982 /* back off if we are on the 521 bit curve */
sPymbed 0:1387ff3eed4a 7983 if (y == 66) --x;
sPymbed 0:1387ff3eed4a 7984
sPymbed 0:1387ff3eed4a 7985 if ((err = mp_read_radix(&order, ecc_sets[x].order,
sPymbed 0:1387ff3eed4a 7986 MP_RADIX_HEX)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7987 goto done;
sPymbed 0:1387ff3eed4a 7988 }
sPymbed 0:1387ff3eed4a 7989
sPymbed 0:1387ff3eed4a 7990 /* kA must be less than modulus */
sPymbed 0:1387ff3eed4a 7991 if (mp_cmp(kA, &order) != MP_LT) {
sPymbed 0:1387ff3eed4a 7992 if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7993 goto done;
sPymbed 0:1387ff3eed4a 7994 }
sPymbed 0:1387ff3eed4a 7995 } else {
sPymbed 0:1387ff3eed4a 7996 if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 7997 goto done;
sPymbed 0:1387ff3eed4a 7998 }
sPymbed 0:1387ff3eed4a 7999 }
sPymbed 0:1387ff3eed4a 8000 } else {
sPymbed 0:1387ff3eed4a 8001 if ((err = mp_copy(kA, &tka)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8002 goto done;
sPymbed 0:1387ff3eed4a 8003 }
sPymbed 0:1387ff3eed4a 8004 }
sPymbed 0:1387ff3eed4a 8005
sPymbed 0:1387ff3eed4a 8006 /* if it's smaller than modulus we fine */
sPymbed 0:1387ff3eed4a 8007 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
sPymbed 0:1387ff3eed4a 8008 /* find order */
sPymbed 0:1387ff3eed4a 8009 y = mp_unsigned_bin_size(modulus);
sPymbed 0:1387ff3eed4a 8010 for (x = 0; ecc_sets[x].size; x++) {
sPymbed 0:1387ff3eed4a 8011 if (y <= (unsigned)ecc_sets[x].size) break;
sPymbed 0:1387ff3eed4a 8012 }
sPymbed 0:1387ff3eed4a 8013
sPymbed 0:1387ff3eed4a 8014 /* back off if we are on the 521 bit curve */
sPymbed 0:1387ff3eed4a 8015 if (y == 66) --x;
sPymbed 0:1387ff3eed4a 8016
sPymbed 0:1387ff3eed4a 8017 if ((err = mp_read_radix(&order, ecc_sets[x].order,
sPymbed 0:1387ff3eed4a 8018 MP_RADIX_HEX)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8019 goto done;
sPymbed 0:1387ff3eed4a 8020 }
sPymbed 0:1387ff3eed4a 8021
sPymbed 0:1387ff3eed4a 8022 /* kB must be less than modulus */
sPymbed 0:1387ff3eed4a 8023 if (mp_cmp(kB, &order) != MP_LT) {
sPymbed 0:1387ff3eed4a 8024 if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8025 goto done;
sPymbed 0:1387ff3eed4a 8026 }
sPymbed 0:1387ff3eed4a 8027 } else {
sPymbed 0:1387ff3eed4a 8028 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8029 goto done;
sPymbed 0:1387ff3eed4a 8030 }
sPymbed 0:1387ff3eed4a 8031 }
sPymbed 0:1387ff3eed4a 8032 } else {
sPymbed 0:1387ff3eed4a 8033 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8034 goto done;
sPymbed 0:1387ff3eed4a 8035 }
sPymbed 0:1387ff3eed4a 8036 }
sPymbed 0:1387ff3eed4a 8037
sPymbed 0:1387ff3eed4a 8038 /* get bitlen and round up to next multiple of FP_LUT */
sPymbed 0:1387ff3eed4a 8039 bitlen = mp_unsigned_bin_size(modulus) << 3;
sPymbed 0:1387ff3eed4a 8040 x = bitlen % FP_LUT;
sPymbed 0:1387ff3eed4a 8041 if (x) {
sPymbed 0:1387ff3eed4a 8042 bitlen += FP_LUT - x;
sPymbed 0:1387ff3eed4a 8043 }
sPymbed 0:1387ff3eed4a 8044 lut_gap = bitlen / FP_LUT;
sPymbed 0:1387ff3eed4a 8045
sPymbed 0:1387ff3eed4a 8046 /* get the k value */
sPymbed 0:1387ff3eed4a 8047 if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) ||
sPymbed 0:1387ff3eed4a 8048 (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) {
sPymbed 0:1387ff3eed4a 8049 err = BUFFER_E; goto done;
sPymbed 0:1387ff3eed4a 8050 }
sPymbed 0:1387ff3eed4a 8051
sPymbed 0:1387ff3eed4a 8052 /* store k */
sPymbed 0:1387ff3eed4a 8053 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8054 kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8055 if (kb[0] == NULL) {
sPymbed 0:1387ff3eed4a 8056 err = MEMORY_E; goto done;
sPymbed 0:1387ff3eed4a 8057 }
sPymbed 0:1387ff3eed4a 8058 #endif
sPymbed 0:1387ff3eed4a 8059
sPymbed 0:1387ff3eed4a 8060 XMEMSET(kb[0], 0, KB_SIZE);
sPymbed 0:1387ff3eed4a 8061 if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8062 goto done;
sPymbed 0:1387ff3eed4a 8063 }
sPymbed 0:1387ff3eed4a 8064
sPymbed 0:1387ff3eed4a 8065 /* let's reverse kb so it's little endian */
sPymbed 0:1387ff3eed4a 8066 x = 0;
sPymbed 0:1387ff3eed4a 8067 y = mp_unsigned_bin_size(&tka);
sPymbed 0:1387ff3eed4a 8068 if (y > 0) {
sPymbed 0:1387ff3eed4a 8069 y -= 1;
sPymbed 0:1387ff3eed4a 8070 }
sPymbed 0:1387ff3eed4a 8071 mp_clear(&tka);
sPymbed 0:1387ff3eed4a 8072 while ((unsigned)x < y) {
sPymbed 0:1387ff3eed4a 8073 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
sPymbed 0:1387ff3eed4a 8074 ++x; --y;
sPymbed 0:1387ff3eed4a 8075 }
sPymbed 0:1387ff3eed4a 8076
sPymbed 0:1387ff3eed4a 8077 /* store b */
sPymbed 0:1387ff3eed4a 8078 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8079 kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8080 if (kb[1] == NULL) {
sPymbed 0:1387ff3eed4a 8081 err = MEMORY_E; goto done;
sPymbed 0:1387ff3eed4a 8082 }
sPymbed 0:1387ff3eed4a 8083 #endif
sPymbed 0:1387ff3eed4a 8084
sPymbed 0:1387ff3eed4a 8085 XMEMSET(kb[1], 0, KB_SIZE);
sPymbed 0:1387ff3eed4a 8086 if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8087 x = 0;
sPymbed 0:1387ff3eed4a 8088 y = mp_unsigned_bin_size(&tkb);
sPymbed 0:1387ff3eed4a 8089 if (y > 0) {
sPymbed 0:1387ff3eed4a 8090 y -= 1;
sPymbed 0:1387ff3eed4a 8091 }
sPymbed 0:1387ff3eed4a 8092
sPymbed 0:1387ff3eed4a 8093 while ((unsigned)x < y) {
sPymbed 0:1387ff3eed4a 8094 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
sPymbed 0:1387ff3eed4a 8095 ++x; --y;
sPymbed 0:1387ff3eed4a 8096 }
sPymbed 0:1387ff3eed4a 8097
sPymbed 0:1387ff3eed4a 8098 /* at this point we can start, yipee */
sPymbed 0:1387ff3eed4a 8099 first = 1;
sPymbed 0:1387ff3eed4a 8100 for (x = lut_gap-1; x >= 0; x--) {
sPymbed 0:1387ff3eed4a 8101 /* extract FP_LUT bits from kb spread out by lut_gap bits and
sPymbed 0:1387ff3eed4a 8102 offset by x bits from the start */
sPymbed 0:1387ff3eed4a 8103 bitpos = x;
sPymbed 0:1387ff3eed4a 8104 for (y = zA = zB = 0; y < FP_LUT; y++) {
sPymbed 0:1387ff3eed4a 8105 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
sPymbed 0:1387ff3eed4a 8106 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
sPymbed 0:1387ff3eed4a 8107 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid
sPymbed 0:1387ff3eed4a 8108 the mult in each loop */
sPymbed 0:1387ff3eed4a 8109 }
sPymbed 0:1387ff3eed4a 8110
sPymbed 0:1387ff3eed4a 8111 /* double if not first */
sPymbed 0:1387ff3eed4a 8112 if (!first) {
sPymbed 0:1387ff3eed4a 8113 if ((err = ecc_projective_dbl_point(R, R, a, modulus,
sPymbed 0:1387ff3eed4a 8114 mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8115 break;
sPymbed 0:1387ff3eed4a 8116 }
sPymbed 0:1387ff3eed4a 8117 }
sPymbed 0:1387ff3eed4a 8118
sPymbed 0:1387ff3eed4a 8119 /* add if not first, otherwise copy */
sPymbed 0:1387ff3eed4a 8120 if (!first) {
sPymbed 0:1387ff3eed4a 8121 if (zA) {
sPymbed 0:1387ff3eed4a 8122 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
sPymbed 0:1387ff3eed4a 8123 R, a, modulus, mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8124 break;
sPymbed 0:1387ff3eed4a 8125 }
sPymbed 0:1387ff3eed4a 8126 }
sPymbed 0:1387ff3eed4a 8127 if (zB) {
sPymbed 0:1387ff3eed4a 8128 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
sPymbed 0:1387ff3eed4a 8129 R, a, modulus, mp)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 8130 break;
sPymbed 0:1387ff3eed4a 8131 }
sPymbed 0:1387ff3eed4a 8132 }
sPymbed 0:1387ff3eed4a 8133 } else {
sPymbed 0:1387ff3eed4a 8134 if (zA) {
sPymbed 0:1387ff3eed4a 8135 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 8136 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 8137 (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) {
sPymbed 0:1387ff3eed4a 8138 err = GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 8139 break;
sPymbed 0:1387ff3eed4a 8140 }
sPymbed 0:1387ff3eed4a 8141 first = 0;
sPymbed 0:1387ff3eed4a 8142 }
sPymbed 0:1387ff3eed4a 8143 if (zB && first == 0) {
sPymbed 0:1387ff3eed4a 8144 if (zB) {
sPymbed 0:1387ff3eed4a 8145 if ((err = ecc_projective_add_point(R,
sPymbed 0:1387ff3eed4a 8146 fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
sPymbed 0:1387ff3eed4a 8147 break;
sPymbed 0:1387ff3eed4a 8148 }
sPymbed 0:1387ff3eed4a 8149 }
sPymbed 0:1387ff3eed4a 8150 } else if (zB && first == 1) {
sPymbed 0:1387ff3eed4a 8151 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 8152 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
sPymbed 0:1387ff3eed4a 8153 (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) {
sPymbed 0:1387ff3eed4a 8154 err = GEN_MEM_ERR;
sPymbed 0:1387ff3eed4a 8155 break;
sPymbed 0:1387ff3eed4a 8156 }
sPymbed 0:1387ff3eed4a 8157 first = 0;
sPymbed 0:1387ff3eed4a 8158 }
sPymbed 0:1387ff3eed4a 8159 }
sPymbed 0:1387ff3eed4a 8160 }
sPymbed 0:1387ff3eed4a 8161 }
sPymbed 0:1387ff3eed4a 8162
sPymbed 0:1387ff3eed4a 8163 done:
sPymbed 0:1387ff3eed4a 8164 /* cleanup */
sPymbed 0:1387ff3eed4a 8165 mp_clear(&tkb);
sPymbed 0:1387ff3eed4a 8166 mp_clear(&tka);
sPymbed 0:1387ff3eed4a 8167 mp_clear(&order);
sPymbed 0:1387ff3eed4a 8168
sPymbed 0:1387ff3eed4a 8169 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8170 if (kb[0])
sPymbed 0:1387ff3eed4a 8171 #endif
sPymbed 0:1387ff3eed4a 8172 ForceZero(kb[0], KB_SIZE);
sPymbed 0:1387ff3eed4a 8173 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8174 if (kb[1])
sPymbed 0:1387ff3eed4a 8175 #endif
sPymbed 0:1387ff3eed4a 8176 ForceZero(kb[1], KB_SIZE);
sPymbed 0:1387ff3eed4a 8177
sPymbed 0:1387ff3eed4a 8178 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8179 XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8180 XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8181 #endif
sPymbed 0:1387ff3eed4a 8182
sPymbed 0:1387ff3eed4a 8183 #undef KB_SIZE
sPymbed 0:1387ff3eed4a 8184
sPymbed 0:1387ff3eed4a 8185 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 8186 return err;
sPymbed 0:1387ff3eed4a 8187
sPymbed 0:1387ff3eed4a 8188 return ecc_map(R, modulus, mp);
sPymbed 0:1387ff3eed4a 8189 }
sPymbed 0:1387ff3eed4a 8190
sPymbed 0:1387ff3eed4a 8191
sPymbed 0:1387ff3eed4a 8192 /** ECC Fixed Point mulmod global with heap hint used
sPymbed 0:1387ff3eed4a 8193 Computes kA*A + kB*B = C using Shamir's Trick
sPymbed 0:1387ff3eed4a 8194 A First point to multiply
sPymbed 0:1387ff3eed4a 8195 kA What to multiple A by
sPymbed 0:1387ff3eed4a 8196 B Second point to multiply
sPymbed 0:1387ff3eed4a 8197 kB What to multiple B by
sPymbed 0:1387ff3eed4a 8198 C [out] Destination point (can overlap with A or B)
sPymbed 0:1387ff3eed4a 8199 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 8200 modulus Modulus for curve
sPymbed 0:1387ff3eed4a 8201 return MP_OKAY on success
sPymbed 0:1387ff3eed4a 8202 */
sPymbed 0:1387ff3eed4a 8203 int ecc_mul2add(ecc_point* A, mp_int* kA,
sPymbed 0:1387ff3eed4a 8204 ecc_point* B, mp_int* kB,
sPymbed 0:1387ff3eed4a 8205 ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
sPymbed 0:1387ff3eed4a 8206 {
sPymbed 0:1387ff3eed4a 8207 int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0;
sPymbed 0:1387ff3eed4a 8208 mp_digit mp;
sPymbed 0:1387ff3eed4a 8209 mp_int mu;
sPymbed 0:1387ff3eed4a 8210
sPymbed 0:1387ff3eed4a 8211 err = mp_init(&mu);
sPymbed 0:1387ff3eed4a 8212 if (err != MP_OKAY)
sPymbed 0:1387ff3eed4a 8213 return err;
sPymbed 0:1387ff3eed4a 8214
sPymbed 0:1387ff3eed4a 8215 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8216 if (initMutex == 0) {
sPymbed 0:1387ff3eed4a 8217 wc_InitMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8218 initMutex = 1;
sPymbed 0:1387ff3eed4a 8219 }
sPymbed 0:1387ff3eed4a 8220 if (wc_LockMutex(&ecc_fp_lock) != 0)
sPymbed 0:1387ff3eed4a 8221 return BAD_MUTEX_E;
sPymbed 0:1387ff3eed4a 8222 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8223
sPymbed 0:1387ff3eed4a 8224 /* find point */
sPymbed 0:1387ff3eed4a 8225 idx1 = find_base(A);
sPymbed 0:1387ff3eed4a 8226
sPymbed 0:1387ff3eed4a 8227 /* no entry? */
sPymbed 0:1387ff3eed4a 8228 if (idx1 == -1) {
sPymbed 0:1387ff3eed4a 8229 /* find hole and add it */
sPymbed 0:1387ff3eed4a 8230 if ((idx1 = find_hole()) >= 0) {
sPymbed 0:1387ff3eed4a 8231 err = add_entry(idx1, A);
sPymbed 0:1387ff3eed4a 8232 }
sPymbed 0:1387ff3eed4a 8233 }
sPymbed 0:1387ff3eed4a 8234 if (err == MP_OKAY && idx1 != -1) {
sPymbed 0:1387ff3eed4a 8235 /* increment LRU */
sPymbed 0:1387ff3eed4a 8236 ++(fp_cache[idx1].lru_count);
sPymbed 0:1387ff3eed4a 8237 }
sPymbed 0:1387ff3eed4a 8238
sPymbed 0:1387ff3eed4a 8239 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8240 /* find point */
sPymbed 0:1387ff3eed4a 8241 idx2 = find_base(B);
sPymbed 0:1387ff3eed4a 8242
sPymbed 0:1387ff3eed4a 8243 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8244 /* no entry? */
sPymbed 0:1387ff3eed4a 8245 if (idx2 == -1) {
sPymbed 0:1387ff3eed4a 8246 /* find hole and add it */
sPymbed 0:1387ff3eed4a 8247 if ((idx2 = find_hole()) >= 0)
sPymbed 0:1387ff3eed4a 8248 err = add_entry(idx2, B);
sPymbed 0:1387ff3eed4a 8249 }
sPymbed 0:1387ff3eed4a 8250 }
sPymbed 0:1387ff3eed4a 8251
sPymbed 0:1387ff3eed4a 8252 if (err == MP_OKAY && idx2 != -1) {
sPymbed 0:1387ff3eed4a 8253 /* increment LRU */
sPymbed 0:1387ff3eed4a 8254 ++(fp_cache[idx2].lru_count);
sPymbed 0:1387ff3eed4a 8255 }
sPymbed 0:1387ff3eed4a 8256
sPymbed 0:1387ff3eed4a 8257 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8258 /* if it's 2 build the LUT, if it's higher just use the LUT */
sPymbed 0:1387ff3eed4a 8259 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
sPymbed 0:1387ff3eed4a 8260 /* compute mp */
sPymbed 0:1387ff3eed4a 8261 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 8262
sPymbed 0:1387ff3eed4a 8263 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8264 mpInit = 1;
sPymbed 0:1387ff3eed4a 8265 err = mp_montgomery_calc_normalization(&mu, modulus);
sPymbed 0:1387ff3eed4a 8266 }
sPymbed 0:1387ff3eed4a 8267
sPymbed 0:1387ff3eed4a 8268 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8269 /* build the LUT */
sPymbed 0:1387ff3eed4a 8270 err = build_lut(idx1, a, modulus, mp, &mu);
sPymbed 0:1387ff3eed4a 8271 }
sPymbed 0:1387ff3eed4a 8272 }
sPymbed 0:1387ff3eed4a 8273
sPymbed 0:1387ff3eed4a 8274 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8275 /* if it's 2 build the LUT, if it's higher just use the LUT */
sPymbed 0:1387ff3eed4a 8276 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
sPymbed 0:1387ff3eed4a 8277 if (mpInit == 0) {
sPymbed 0:1387ff3eed4a 8278 /* compute mp */
sPymbed 0:1387ff3eed4a 8279 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 8280 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8281 mpInit = 1;
sPymbed 0:1387ff3eed4a 8282 err = mp_montgomery_calc_normalization(&mu, modulus);
sPymbed 0:1387ff3eed4a 8283 }
sPymbed 0:1387ff3eed4a 8284 }
sPymbed 0:1387ff3eed4a 8285
sPymbed 0:1387ff3eed4a 8286 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8287 /* build the LUT */
sPymbed 0:1387ff3eed4a 8288 err = build_lut(idx2, a, modulus, mp, &mu);
sPymbed 0:1387ff3eed4a 8289 }
sPymbed 0:1387ff3eed4a 8290 }
sPymbed 0:1387ff3eed4a 8291
sPymbed 0:1387ff3eed4a 8292
sPymbed 0:1387ff3eed4a 8293 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8294 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 &&
sPymbed 0:1387ff3eed4a 8295 fp_cache[idx2].lru_count >= 2) {
sPymbed 0:1387ff3eed4a 8296 if (mpInit == 0) {
sPymbed 0:1387ff3eed4a 8297 /* compute mp */
sPymbed 0:1387ff3eed4a 8298 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 8299 }
sPymbed 0:1387ff3eed4a 8300 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8301 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
sPymbed 0:1387ff3eed4a 8302 } else {
sPymbed 0:1387ff3eed4a 8303 err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
sPymbed 0:1387ff3eed4a 8304 }
sPymbed 0:1387ff3eed4a 8305 }
sPymbed 0:1387ff3eed4a 8306
sPymbed 0:1387ff3eed4a 8307 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8308 wc_UnLockMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8309 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8310 mp_clear(&mu);
sPymbed 0:1387ff3eed4a 8311
sPymbed 0:1387ff3eed4a 8312 return err;
sPymbed 0:1387ff3eed4a 8313 }
sPymbed 0:1387ff3eed4a 8314 #endif
sPymbed 0:1387ff3eed4a 8315 #endif /* ECC_SHAMIR */
sPymbed 0:1387ff3eed4a 8316
sPymbed 0:1387ff3eed4a 8317 /** ECC Fixed Point mulmod global
sPymbed 0:1387ff3eed4a 8318 k The multiplicand
sPymbed 0:1387ff3eed4a 8319 G Base point to multiply
sPymbed 0:1387ff3eed4a 8320 R [out] Destination of product
sPymbed 0:1387ff3eed4a 8321 a ECC curve parameter a
sPymbed 0:1387ff3eed4a 8322 modulus The modulus for the curve
sPymbed 0:1387ff3eed4a 8323 map [boolean] If non-zero maps the point back to affine co-ordinates,
sPymbed 0:1387ff3eed4a 8324 otherwise it's left in jacobian-montgomery form
sPymbed 0:1387ff3eed4a 8325 return MP_OKAY if successful
sPymbed 0:1387ff3eed4a 8326 */
sPymbed 0:1387ff3eed4a 8327 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
sPymbed 0:1387ff3eed4a 8328 mp_int* modulus, int map, void* heap)
sPymbed 0:1387ff3eed4a 8329 {
sPymbed 0:1387ff3eed4a 8330 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 8331 int idx, err = MP_OKAY;
sPymbed 0:1387ff3eed4a 8332 mp_digit mp;
sPymbed 0:1387ff3eed4a 8333 mp_int mu;
sPymbed 0:1387ff3eed4a 8334 int mpSetup = 0;
sPymbed 0:1387ff3eed4a 8335
sPymbed 0:1387ff3eed4a 8336 if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 8337 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 8338 }
sPymbed 0:1387ff3eed4a 8339
sPymbed 0:1387ff3eed4a 8340 if (mp_init(&mu) != MP_OKAY)
sPymbed 0:1387ff3eed4a 8341 return MP_INIT_E;
sPymbed 0:1387ff3eed4a 8342
sPymbed 0:1387ff3eed4a 8343 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8344 if (initMutex == 0) {
sPymbed 0:1387ff3eed4a 8345 wc_InitMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8346 initMutex = 1;
sPymbed 0:1387ff3eed4a 8347 }
sPymbed 0:1387ff3eed4a 8348
sPymbed 0:1387ff3eed4a 8349 if (wc_LockMutex(&ecc_fp_lock) != 0)
sPymbed 0:1387ff3eed4a 8350 return BAD_MUTEX_E;
sPymbed 0:1387ff3eed4a 8351 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8352
sPymbed 0:1387ff3eed4a 8353 /* find point */
sPymbed 0:1387ff3eed4a 8354 idx = find_base(G);
sPymbed 0:1387ff3eed4a 8355
sPymbed 0:1387ff3eed4a 8356 /* no entry? */
sPymbed 0:1387ff3eed4a 8357 if (idx == -1) {
sPymbed 0:1387ff3eed4a 8358 /* find hole and add it */
sPymbed 0:1387ff3eed4a 8359 idx = find_hole();
sPymbed 0:1387ff3eed4a 8360
sPymbed 0:1387ff3eed4a 8361 if (idx >= 0)
sPymbed 0:1387ff3eed4a 8362 err = add_entry(idx, G);
sPymbed 0:1387ff3eed4a 8363 }
sPymbed 0:1387ff3eed4a 8364 if (err == MP_OKAY && idx >= 0) {
sPymbed 0:1387ff3eed4a 8365 /* increment LRU */
sPymbed 0:1387ff3eed4a 8366 ++(fp_cache[idx].lru_count);
sPymbed 0:1387ff3eed4a 8367 }
sPymbed 0:1387ff3eed4a 8368
sPymbed 0:1387ff3eed4a 8369
sPymbed 0:1387ff3eed4a 8370 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8371 /* if it's 2 build the LUT, if it's higher just use the LUT */
sPymbed 0:1387ff3eed4a 8372 if (idx >= 0 && fp_cache[idx].lru_count == 2) {
sPymbed 0:1387ff3eed4a 8373 /* compute mp */
sPymbed 0:1387ff3eed4a 8374 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 8375
sPymbed 0:1387ff3eed4a 8376 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8377 /* compute mu */
sPymbed 0:1387ff3eed4a 8378 mpSetup = 1;
sPymbed 0:1387ff3eed4a 8379 err = mp_montgomery_calc_normalization(&mu, modulus);
sPymbed 0:1387ff3eed4a 8380 }
sPymbed 0:1387ff3eed4a 8381
sPymbed 0:1387ff3eed4a 8382 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8383 /* build the LUT */
sPymbed 0:1387ff3eed4a 8384 err = build_lut(idx, a, modulus, mp, &mu);
sPymbed 0:1387ff3eed4a 8385 }
sPymbed 0:1387ff3eed4a 8386 }
sPymbed 0:1387ff3eed4a 8387
sPymbed 0:1387ff3eed4a 8388 if (err == MP_OKAY) {
sPymbed 0:1387ff3eed4a 8389 if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
sPymbed 0:1387ff3eed4a 8390 if (mpSetup == 0) {
sPymbed 0:1387ff3eed4a 8391 /* compute mp */
sPymbed 0:1387ff3eed4a 8392 err = mp_montgomery_setup(modulus, &mp);
sPymbed 0:1387ff3eed4a 8393 }
sPymbed 0:1387ff3eed4a 8394 if (err == MP_OKAY)
sPymbed 0:1387ff3eed4a 8395 err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
sPymbed 0:1387ff3eed4a 8396 } else {
sPymbed 0:1387ff3eed4a 8397 err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap);
sPymbed 0:1387ff3eed4a 8398 }
sPymbed 0:1387ff3eed4a 8399 }
sPymbed 0:1387ff3eed4a 8400
sPymbed 0:1387ff3eed4a 8401 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8402 wc_UnLockMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8403 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8404 mp_clear(&mu);
sPymbed 0:1387ff3eed4a 8405
sPymbed 0:1387ff3eed4a 8406 return err;
sPymbed 0:1387ff3eed4a 8407 #else
sPymbed 0:1387ff3eed4a 8408 if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
sPymbed 0:1387ff3eed4a 8409 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 8410 }
sPymbed 0:1387ff3eed4a 8411
sPymbed 0:1387ff3eed4a 8412 return sp_ecc_mulmod_256(k, G, R, map, heap);
sPymbed 0:1387ff3eed4a 8413 #endif
sPymbed 0:1387ff3eed4a 8414 }
sPymbed 0:1387ff3eed4a 8415
sPymbed 0:1387ff3eed4a 8416 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 8417 /* helper function for freeing the cache ...
sPymbed 0:1387ff3eed4a 8418 must be called with the cache mutex locked */
sPymbed 0:1387ff3eed4a 8419 static void wc_ecc_fp_free_cache(void)
sPymbed 0:1387ff3eed4a 8420 {
sPymbed 0:1387ff3eed4a 8421 unsigned x, y;
sPymbed 0:1387ff3eed4a 8422 for (x = 0; x < FP_ENTRIES; x++) {
sPymbed 0:1387ff3eed4a 8423 if (fp_cache[x].g != NULL) {
sPymbed 0:1387ff3eed4a 8424 for (y = 0; y < (1U<<FP_LUT); y++) {
sPymbed 0:1387ff3eed4a 8425 wc_ecc_del_point(fp_cache[x].LUT[y]);
sPymbed 0:1387ff3eed4a 8426 fp_cache[x].LUT[y] = NULL;
sPymbed 0:1387ff3eed4a 8427 }
sPymbed 0:1387ff3eed4a 8428 wc_ecc_del_point(fp_cache[x].g);
sPymbed 0:1387ff3eed4a 8429 fp_cache[x].g = NULL;
sPymbed 0:1387ff3eed4a 8430 mp_clear(&fp_cache[x].mu);
sPymbed 0:1387ff3eed4a 8431 fp_cache[x].lru_count = 0;
sPymbed 0:1387ff3eed4a 8432 fp_cache[x].lock = 0;
sPymbed 0:1387ff3eed4a 8433 }
sPymbed 0:1387ff3eed4a 8434 }
sPymbed 0:1387ff3eed4a 8435 }
sPymbed 0:1387ff3eed4a 8436 #endif
sPymbed 0:1387ff3eed4a 8437
sPymbed 0:1387ff3eed4a 8438 /** Free the Fixed Point cache */
sPymbed 0:1387ff3eed4a 8439 void wc_ecc_fp_free(void)
sPymbed 0:1387ff3eed4a 8440 {
sPymbed 0:1387ff3eed4a 8441 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 8442 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8443 if (initMutex == 0) {
sPymbed 0:1387ff3eed4a 8444 wc_InitMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8445 initMutex = 1;
sPymbed 0:1387ff3eed4a 8446 }
sPymbed 0:1387ff3eed4a 8447
sPymbed 0:1387ff3eed4a 8448 if (wc_LockMutex(&ecc_fp_lock) == 0) {
sPymbed 0:1387ff3eed4a 8449 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8450
sPymbed 0:1387ff3eed4a 8451 wc_ecc_fp_free_cache();
sPymbed 0:1387ff3eed4a 8452
sPymbed 0:1387ff3eed4a 8453 #ifndef HAVE_THREAD_LS
sPymbed 0:1387ff3eed4a 8454 wc_UnLockMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8455 wc_FreeMutex(&ecc_fp_lock);
sPymbed 0:1387ff3eed4a 8456 initMutex = 0;
sPymbed 0:1387ff3eed4a 8457 }
sPymbed 0:1387ff3eed4a 8458 #endif /* HAVE_THREAD_LS */
sPymbed 0:1387ff3eed4a 8459 #endif
sPymbed 0:1387ff3eed4a 8460 }
sPymbed 0:1387ff3eed4a 8461
sPymbed 0:1387ff3eed4a 8462
sPymbed 0:1387ff3eed4a 8463 #endif /* FP_ECC */
sPymbed 0:1387ff3eed4a 8464
sPymbed 0:1387ff3eed4a 8465 #ifdef HAVE_ECC_ENCRYPT
sPymbed 0:1387ff3eed4a 8466
sPymbed 0:1387ff3eed4a 8467
sPymbed 0:1387ff3eed4a 8468 enum ecCliState {
sPymbed 0:1387ff3eed4a 8469 ecCLI_INIT = 1,
sPymbed 0:1387ff3eed4a 8470 ecCLI_SALT_GET = 2,
sPymbed 0:1387ff3eed4a 8471 ecCLI_SALT_SET = 3,
sPymbed 0:1387ff3eed4a 8472 ecCLI_SENT_REQ = 4,
sPymbed 0:1387ff3eed4a 8473 ecCLI_RECV_RESP = 5,
sPymbed 0:1387ff3eed4a 8474 ecCLI_BAD_STATE = 99
sPymbed 0:1387ff3eed4a 8475 };
sPymbed 0:1387ff3eed4a 8476
sPymbed 0:1387ff3eed4a 8477 enum ecSrvState {
sPymbed 0:1387ff3eed4a 8478 ecSRV_INIT = 1,
sPymbed 0:1387ff3eed4a 8479 ecSRV_SALT_GET = 2,
sPymbed 0:1387ff3eed4a 8480 ecSRV_SALT_SET = 3,
sPymbed 0:1387ff3eed4a 8481 ecSRV_RECV_REQ = 4,
sPymbed 0:1387ff3eed4a 8482 ecSRV_SENT_RESP = 5,
sPymbed 0:1387ff3eed4a 8483 ecSRV_BAD_STATE = 99
sPymbed 0:1387ff3eed4a 8484 };
sPymbed 0:1387ff3eed4a 8485
sPymbed 0:1387ff3eed4a 8486
sPymbed 0:1387ff3eed4a 8487 struct ecEncCtx {
sPymbed 0:1387ff3eed4a 8488 const byte* kdfSalt; /* optional salt for kdf */
sPymbed 0:1387ff3eed4a 8489 const byte* kdfInfo; /* optional info for kdf */
sPymbed 0:1387ff3eed4a 8490 const byte* macSalt; /* optional salt for mac */
sPymbed 0:1387ff3eed4a 8491 word32 kdfSaltSz; /* size of kdfSalt */
sPymbed 0:1387ff3eed4a 8492 word32 kdfInfoSz; /* size of kdfInfo */
sPymbed 0:1387ff3eed4a 8493 word32 macSaltSz; /* size of macSalt */
sPymbed 0:1387ff3eed4a 8494 void* heap; /* heap hint for memory used */
sPymbed 0:1387ff3eed4a 8495 byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
sPymbed 0:1387ff3eed4a 8496 byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */
sPymbed 0:1387ff3eed4a 8497 byte encAlgo; /* which encryption type */
sPymbed 0:1387ff3eed4a 8498 byte kdfAlgo; /* which key derivation function type */
sPymbed 0:1387ff3eed4a 8499 byte macAlgo; /* which mac function type */
sPymbed 0:1387ff3eed4a 8500 byte protocol; /* are we REQ_RESP client or server ? */
sPymbed 0:1387ff3eed4a 8501 byte cliSt; /* protocol state, for sanity checks */
sPymbed 0:1387ff3eed4a 8502 byte srvSt; /* protocol state, for sanity checks */
sPymbed 0:1387ff3eed4a 8503 };
sPymbed 0:1387ff3eed4a 8504
sPymbed 0:1387ff3eed4a 8505
sPymbed 0:1387ff3eed4a 8506 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
sPymbed 0:1387ff3eed4a 8507 {
sPymbed 0:1387ff3eed4a 8508 if (ctx == NULL || ctx->protocol == 0)
sPymbed 0:1387ff3eed4a 8509 return NULL;
sPymbed 0:1387ff3eed4a 8510
sPymbed 0:1387ff3eed4a 8511 if (ctx->protocol == REQ_RESP_CLIENT) {
sPymbed 0:1387ff3eed4a 8512 if (ctx->cliSt == ecCLI_INIT) {
sPymbed 0:1387ff3eed4a 8513 ctx->cliSt = ecCLI_SALT_GET;
sPymbed 0:1387ff3eed4a 8514 return ctx->clientSalt;
sPymbed 0:1387ff3eed4a 8515 }
sPymbed 0:1387ff3eed4a 8516 else {
sPymbed 0:1387ff3eed4a 8517 ctx->cliSt = ecCLI_BAD_STATE;
sPymbed 0:1387ff3eed4a 8518 return NULL;
sPymbed 0:1387ff3eed4a 8519 }
sPymbed 0:1387ff3eed4a 8520 }
sPymbed 0:1387ff3eed4a 8521 else if (ctx->protocol == REQ_RESP_SERVER) {
sPymbed 0:1387ff3eed4a 8522 if (ctx->srvSt == ecSRV_INIT) {
sPymbed 0:1387ff3eed4a 8523 ctx->srvSt = ecSRV_SALT_GET;
sPymbed 0:1387ff3eed4a 8524 return ctx->serverSalt;
sPymbed 0:1387ff3eed4a 8525 }
sPymbed 0:1387ff3eed4a 8526 else {
sPymbed 0:1387ff3eed4a 8527 ctx->srvSt = ecSRV_BAD_STATE;
sPymbed 0:1387ff3eed4a 8528 return NULL;
sPymbed 0:1387ff3eed4a 8529 }
sPymbed 0:1387ff3eed4a 8530 }
sPymbed 0:1387ff3eed4a 8531
sPymbed 0:1387ff3eed4a 8532 return NULL;
sPymbed 0:1387ff3eed4a 8533 }
sPymbed 0:1387ff3eed4a 8534
sPymbed 0:1387ff3eed4a 8535
sPymbed 0:1387ff3eed4a 8536 /* optional set info, can be called before or after set_peer_salt */
sPymbed 0:1387ff3eed4a 8537 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
sPymbed 0:1387ff3eed4a 8538 {
sPymbed 0:1387ff3eed4a 8539 if (ctx == NULL || info == 0 || sz < 0)
sPymbed 0:1387ff3eed4a 8540 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8541
sPymbed 0:1387ff3eed4a 8542 ctx->kdfInfo = info;
sPymbed 0:1387ff3eed4a 8543 ctx->kdfInfoSz = sz;
sPymbed 0:1387ff3eed4a 8544
sPymbed 0:1387ff3eed4a 8545 return 0;
sPymbed 0:1387ff3eed4a 8546 }
sPymbed 0:1387ff3eed4a 8547
sPymbed 0:1387ff3eed4a 8548
sPymbed 0:1387ff3eed4a 8549 static const char* exchange_info = "Secure Message Exchange";
sPymbed 0:1387ff3eed4a 8550
sPymbed 0:1387ff3eed4a 8551 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
sPymbed 0:1387ff3eed4a 8552 {
sPymbed 0:1387ff3eed4a 8553 byte tmp[EXCHANGE_SALT_SZ/2];
sPymbed 0:1387ff3eed4a 8554 int halfSz = EXCHANGE_SALT_SZ/2;
sPymbed 0:1387ff3eed4a 8555
sPymbed 0:1387ff3eed4a 8556 if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
sPymbed 0:1387ff3eed4a 8557 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8558
sPymbed 0:1387ff3eed4a 8559 if (ctx->protocol == REQ_RESP_CLIENT) {
sPymbed 0:1387ff3eed4a 8560 XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
sPymbed 0:1387ff3eed4a 8561 if (ctx->cliSt == ecCLI_SALT_GET)
sPymbed 0:1387ff3eed4a 8562 ctx->cliSt = ecCLI_SALT_SET;
sPymbed 0:1387ff3eed4a 8563 else {
sPymbed 0:1387ff3eed4a 8564 ctx->cliSt = ecCLI_BAD_STATE;
sPymbed 0:1387ff3eed4a 8565 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8566 }
sPymbed 0:1387ff3eed4a 8567 }
sPymbed 0:1387ff3eed4a 8568 else {
sPymbed 0:1387ff3eed4a 8569 XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
sPymbed 0:1387ff3eed4a 8570 if (ctx->srvSt == ecSRV_SALT_GET)
sPymbed 0:1387ff3eed4a 8571 ctx->srvSt = ecSRV_SALT_SET;
sPymbed 0:1387ff3eed4a 8572 else {
sPymbed 0:1387ff3eed4a 8573 ctx->srvSt = ecSRV_BAD_STATE;
sPymbed 0:1387ff3eed4a 8574 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8575 }
sPymbed 0:1387ff3eed4a 8576 }
sPymbed 0:1387ff3eed4a 8577
sPymbed 0:1387ff3eed4a 8578 /* mix half and half */
sPymbed 0:1387ff3eed4a 8579 /* tmp stores 2nd half of client before overwrite */
sPymbed 0:1387ff3eed4a 8580 XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz);
sPymbed 0:1387ff3eed4a 8581 XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz);
sPymbed 0:1387ff3eed4a 8582 XMEMCPY(ctx->serverSalt, tmp, halfSz);
sPymbed 0:1387ff3eed4a 8583
sPymbed 0:1387ff3eed4a 8584 ctx->kdfSalt = ctx->clientSalt;
sPymbed 0:1387ff3eed4a 8585 ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
sPymbed 0:1387ff3eed4a 8586
sPymbed 0:1387ff3eed4a 8587 ctx->macSalt = ctx->serverSalt;
sPymbed 0:1387ff3eed4a 8588 ctx->macSaltSz = EXCHANGE_SALT_SZ;
sPymbed 0:1387ff3eed4a 8589
sPymbed 0:1387ff3eed4a 8590 if (ctx->kdfInfo == NULL) {
sPymbed 0:1387ff3eed4a 8591 /* default info */
sPymbed 0:1387ff3eed4a 8592 ctx->kdfInfo = (const byte*)exchange_info;
sPymbed 0:1387ff3eed4a 8593 ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
sPymbed 0:1387ff3eed4a 8594 }
sPymbed 0:1387ff3eed4a 8595
sPymbed 0:1387ff3eed4a 8596 return 0;
sPymbed 0:1387ff3eed4a 8597 }
sPymbed 0:1387ff3eed4a 8598
sPymbed 0:1387ff3eed4a 8599
sPymbed 0:1387ff3eed4a 8600 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng)
sPymbed 0:1387ff3eed4a 8601 {
sPymbed 0:1387ff3eed4a 8602 byte* saltBuffer = NULL;
sPymbed 0:1387ff3eed4a 8603
sPymbed 0:1387ff3eed4a 8604 if (ctx == NULL || rng == NULL || flags == 0)
sPymbed 0:1387ff3eed4a 8605 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8606
sPymbed 0:1387ff3eed4a 8607 saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
sPymbed 0:1387ff3eed4a 8608
sPymbed 0:1387ff3eed4a 8609 return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ);
sPymbed 0:1387ff3eed4a 8610 }
sPymbed 0:1387ff3eed4a 8611
sPymbed 0:1387ff3eed4a 8612
sPymbed 0:1387ff3eed4a 8613 static void ecc_ctx_init(ecEncCtx* ctx, int flags)
sPymbed 0:1387ff3eed4a 8614 {
sPymbed 0:1387ff3eed4a 8615 if (ctx) {
sPymbed 0:1387ff3eed4a 8616 XMEMSET(ctx, 0, sizeof(ecEncCtx));
sPymbed 0:1387ff3eed4a 8617
sPymbed 0:1387ff3eed4a 8618 ctx->encAlgo = ecAES_128_CBC;
sPymbed 0:1387ff3eed4a 8619 ctx->kdfAlgo = ecHKDF_SHA256;
sPymbed 0:1387ff3eed4a 8620 ctx->macAlgo = ecHMAC_SHA256;
sPymbed 0:1387ff3eed4a 8621 ctx->protocol = (byte)flags;
sPymbed 0:1387ff3eed4a 8622
sPymbed 0:1387ff3eed4a 8623 if (flags == REQ_RESP_CLIENT)
sPymbed 0:1387ff3eed4a 8624 ctx->cliSt = ecCLI_INIT;
sPymbed 0:1387ff3eed4a 8625 if (flags == REQ_RESP_SERVER)
sPymbed 0:1387ff3eed4a 8626 ctx->srvSt = ecSRV_INIT;
sPymbed 0:1387ff3eed4a 8627 }
sPymbed 0:1387ff3eed4a 8628 }
sPymbed 0:1387ff3eed4a 8629
sPymbed 0:1387ff3eed4a 8630
sPymbed 0:1387ff3eed4a 8631 /* allow ecc context reset so user doesn't have to init/free for reuse */
sPymbed 0:1387ff3eed4a 8632 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
sPymbed 0:1387ff3eed4a 8633 {
sPymbed 0:1387ff3eed4a 8634 if (ctx == NULL || rng == NULL)
sPymbed 0:1387ff3eed4a 8635 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8636
sPymbed 0:1387ff3eed4a 8637 ecc_ctx_init(ctx, ctx->protocol);
sPymbed 0:1387ff3eed4a 8638 return ecc_ctx_set_salt(ctx, ctx->protocol, rng);
sPymbed 0:1387ff3eed4a 8639 }
sPymbed 0:1387ff3eed4a 8640
sPymbed 0:1387ff3eed4a 8641
sPymbed 0:1387ff3eed4a 8642 ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
sPymbed 0:1387ff3eed4a 8643 {
sPymbed 0:1387ff3eed4a 8644 int ret = 0;
sPymbed 0:1387ff3eed4a 8645 ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
sPymbed 0:1387ff3eed4a 8646 DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 8647
sPymbed 0:1387ff3eed4a 8648 if (ctx) {
sPymbed 0:1387ff3eed4a 8649 ctx->protocol = (byte)flags;
sPymbed 0:1387ff3eed4a 8650 ctx->heap = heap;
sPymbed 0:1387ff3eed4a 8651 }
sPymbed 0:1387ff3eed4a 8652
sPymbed 0:1387ff3eed4a 8653 ret = wc_ecc_ctx_reset(ctx, rng);
sPymbed 0:1387ff3eed4a 8654 if (ret != 0) {
sPymbed 0:1387ff3eed4a 8655 wc_ecc_ctx_free(ctx);
sPymbed 0:1387ff3eed4a 8656 ctx = NULL;
sPymbed 0:1387ff3eed4a 8657 }
sPymbed 0:1387ff3eed4a 8658
sPymbed 0:1387ff3eed4a 8659 return ctx;
sPymbed 0:1387ff3eed4a 8660 }
sPymbed 0:1387ff3eed4a 8661
sPymbed 0:1387ff3eed4a 8662
sPymbed 0:1387ff3eed4a 8663 /* alloc/init and set defaults, return new Context */
sPymbed 0:1387ff3eed4a 8664 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
sPymbed 0:1387ff3eed4a 8665 {
sPymbed 0:1387ff3eed4a 8666 return wc_ecc_ctx_new_ex(flags, rng, NULL);
sPymbed 0:1387ff3eed4a 8667 }
sPymbed 0:1387ff3eed4a 8668
sPymbed 0:1387ff3eed4a 8669
sPymbed 0:1387ff3eed4a 8670 /* free any resources, clear any keys */
sPymbed 0:1387ff3eed4a 8671 void wc_ecc_ctx_free(ecEncCtx* ctx)
sPymbed 0:1387ff3eed4a 8672 {
sPymbed 0:1387ff3eed4a 8673 if (ctx) {
sPymbed 0:1387ff3eed4a 8674 ForceZero(ctx, sizeof(ecEncCtx));
sPymbed 0:1387ff3eed4a 8675 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC);
sPymbed 0:1387ff3eed4a 8676 }
sPymbed 0:1387ff3eed4a 8677 }
sPymbed 0:1387ff3eed4a 8678
sPymbed 0:1387ff3eed4a 8679
sPymbed 0:1387ff3eed4a 8680 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
sPymbed 0:1387ff3eed4a 8681 int* keysLen, word32* digestSz, word32* blockSz)
sPymbed 0:1387ff3eed4a 8682 {
sPymbed 0:1387ff3eed4a 8683 if (ctx) {
sPymbed 0:1387ff3eed4a 8684 switch (ctx->encAlgo) {
sPymbed 0:1387ff3eed4a 8685 case ecAES_128_CBC:
sPymbed 0:1387ff3eed4a 8686 *encKeySz = KEY_SIZE_128;
sPymbed 0:1387ff3eed4a 8687 *ivSz = IV_SIZE_128;
sPymbed 0:1387ff3eed4a 8688 *blockSz = AES_BLOCK_SIZE;
sPymbed 0:1387ff3eed4a 8689 break;
sPymbed 0:1387ff3eed4a 8690 default:
sPymbed 0:1387ff3eed4a 8691 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8692 }
sPymbed 0:1387ff3eed4a 8693
sPymbed 0:1387ff3eed4a 8694 switch (ctx->macAlgo) {
sPymbed 0:1387ff3eed4a 8695 case ecHMAC_SHA256:
sPymbed 0:1387ff3eed4a 8696 *digestSz = WC_SHA256_DIGEST_SIZE;
sPymbed 0:1387ff3eed4a 8697 break;
sPymbed 0:1387ff3eed4a 8698 default:
sPymbed 0:1387ff3eed4a 8699 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8700 }
sPymbed 0:1387ff3eed4a 8701 } else
sPymbed 0:1387ff3eed4a 8702 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8703
sPymbed 0:1387ff3eed4a 8704 *keysLen = *encKeySz + *ivSz + *digestSz;
sPymbed 0:1387ff3eed4a 8705
sPymbed 0:1387ff3eed4a 8706 return 0;
sPymbed 0:1387ff3eed4a 8707 }
sPymbed 0:1387ff3eed4a 8708
sPymbed 0:1387ff3eed4a 8709
sPymbed 0:1387ff3eed4a 8710 /* ecc encrypt with shared secret run through kdf
sPymbed 0:1387ff3eed4a 8711 ctx holds non default algos and inputs
sPymbed 0:1387ff3eed4a 8712 msgSz should be the right size for encAlgo, i.e., already padded
sPymbed 0:1387ff3eed4a 8713 return 0 on success */
sPymbed 0:1387ff3eed4a 8714 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
sPymbed 0:1387ff3eed4a 8715 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
sPymbed 0:1387ff3eed4a 8716 {
sPymbed 0:1387ff3eed4a 8717 int ret = 0;
sPymbed 0:1387ff3eed4a 8718 word32 blockSz;
sPymbed 0:1387ff3eed4a 8719 word32 digestSz;
sPymbed 0:1387ff3eed4a 8720 ecEncCtx localCtx;
sPymbed 0:1387ff3eed4a 8721 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8722 byte* sharedSecret;
sPymbed 0:1387ff3eed4a 8723 byte* keys;
sPymbed 0:1387ff3eed4a 8724 #else
sPymbed 0:1387ff3eed4a 8725 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
sPymbed 0:1387ff3eed4a 8726 byte keys[ECC_BUFSIZE]; /* max size */
sPymbed 0:1387ff3eed4a 8727 #endif
sPymbed 0:1387ff3eed4a 8728 word32 sharedSz = ECC_MAXSIZE;
sPymbed 0:1387ff3eed4a 8729 int keysLen;
sPymbed 0:1387ff3eed4a 8730 int encKeySz;
sPymbed 0:1387ff3eed4a 8731 int ivSz;
sPymbed 0:1387ff3eed4a 8732 int offset = 0; /* keys offset if doing msg exchange */
sPymbed 0:1387ff3eed4a 8733 byte* encKey;
sPymbed 0:1387ff3eed4a 8734 byte* encIv;
sPymbed 0:1387ff3eed4a 8735 byte* macKey;
sPymbed 0:1387ff3eed4a 8736
sPymbed 0:1387ff3eed4a 8737 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
sPymbed 0:1387ff3eed4a 8738 outSz == NULL)
sPymbed 0:1387ff3eed4a 8739 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8740
sPymbed 0:1387ff3eed4a 8741 if (ctx == NULL) { /* use defaults */
sPymbed 0:1387ff3eed4a 8742 ecc_ctx_init(&localCtx, 0);
sPymbed 0:1387ff3eed4a 8743 ctx = &localCtx;
sPymbed 0:1387ff3eed4a 8744 }
sPymbed 0:1387ff3eed4a 8745
sPymbed 0:1387ff3eed4a 8746 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
sPymbed 0:1387ff3eed4a 8747 &blockSz);
sPymbed 0:1387ff3eed4a 8748 if (ret != 0)
sPymbed 0:1387ff3eed4a 8749 return ret;
sPymbed 0:1387ff3eed4a 8750
sPymbed 0:1387ff3eed4a 8751 if (ctx->protocol == REQ_RESP_SERVER) {
sPymbed 0:1387ff3eed4a 8752 offset = keysLen;
sPymbed 0:1387ff3eed4a 8753 keysLen *= 2;
sPymbed 0:1387ff3eed4a 8754
sPymbed 0:1387ff3eed4a 8755 if (ctx->srvSt != ecSRV_RECV_REQ)
sPymbed 0:1387ff3eed4a 8756 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8757
sPymbed 0:1387ff3eed4a 8758 ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
sPymbed 0:1387ff3eed4a 8759 }
sPymbed 0:1387ff3eed4a 8760 else if (ctx->protocol == REQ_RESP_CLIENT) {
sPymbed 0:1387ff3eed4a 8761 if (ctx->cliSt != ecCLI_SALT_SET)
sPymbed 0:1387ff3eed4a 8762 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8763
sPymbed 0:1387ff3eed4a 8764 ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
sPymbed 0:1387ff3eed4a 8765 }
sPymbed 0:1387ff3eed4a 8766
sPymbed 0:1387ff3eed4a 8767 if (keysLen > ECC_BUFSIZE) /* keys size */
sPymbed 0:1387ff3eed4a 8768 return BUFFER_E;
sPymbed 0:1387ff3eed4a 8769
sPymbed 0:1387ff3eed4a 8770 if ( (msgSz%blockSz) != 0)
sPymbed 0:1387ff3eed4a 8771 return BAD_PADDING_E;
sPymbed 0:1387ff3eed4a 8772
sPymbed 0:1387ff3eed4a 8773 if (*outSz < (msgSz + digestSz))
sPymbed 0:1387ff3eed4a 8774 return BUFFER_E;
sPymbed 0:1387ff3eed4a 8775
sPymbed 0:1387ff3eed4a 8776 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8777 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8778 if (sharedSecret == NULL)
sPymbed 0:1387ff3eed4a 8779 return MEMORY_E;
sPymbed 0:1387ff3eed4a 8780
sPymbed 0:1387ff3eed4a 8781 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8782 if (keys == NULL) {
sPymbed 0:1387ff3eed4a 8783 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8784 return MEMORY_E;
sPymbed 0:1387ff3eed4a 8785 }
sPymbed 0:1387ff3eed4a 8786 #endif
sPymbed 0:1387ff3eed4a 8787
sPymbed 0:1387ff3eed4a 8788 do {
sPymbed 0:1387ff3eed4a 8789 #if defined(WOLFSSL_ASYNC_CRYPT)
sPymbed 0:1387ff3eed4a 8790 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
sPymbed 0:1387ff3eed4a 8791 if (ret != 0)
sPymbed 0:1387ff3eed4a 8792 break;
sPymbed 0:1387ff3eed4a 8793 #endif
sPymbed 0:1387ff3eed4a 8794 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
sPymbed 0:1387ff3eed4a 8795 } while (ret == WC_PENDING_E);
sPymbed 0:1387ff3eed4a 8796 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8797 switch (ctx->kdfAlgo) {
sPymbed 0:1387ff3eed4a 8798 case ecHKDF_SHA256 :
sPymbed 0:1387ff3eed4a 8799 ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
sPymbed 0:1387ff3eed4a 8800 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
sPymbed 0:1387ff3eed4a 8801 keys, keysLen);
sPymbed 0:1387ff3eed4a 8802 break;
sPymbed 0:1387ff3eed4a 8803
sPymbed 0:1387ff3eed4a 8804 default:
sPymbed 0:1387ff3eed4a 8805 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8806 break;
sPymbed 0:1387ff3eed4a 8807 }
sPymbed 0:1387ff3eed4a 8808 }
sPymbed 0:1387ff3eed4a 8809
sPymbed 0:1387ff3eed4a 8810 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8811 encKey = keys + offset;
sPymbed 0:1387ff3eed4a 8812 encIv = encKey + encKeySz;
sPymbed 0:1387ff3eed4a 8813 macKey = encKey + encKeySz + ivSz;
sPymbed 0:1387ff3eed4a 8814
sPymbed 0:1387ff3eed4a 8815 switch (ctx->encAlgo) {
sPymbed 0:1387ff3eed4a 8816 case ecAES_128_CBC:
sPymbed 0:1387ff3eed4a 8817 {
sPymbed 0:1387ff3eed4a 8818 Aes aes;
sPymbed 0:1387ff3eed4a 8819 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
sPymbed 0:1387ff3eed4a 8820 AES_ENCRYPTION);
sPymbed 0:1387ff3eed4a 8821 if (ret != 0)
sPymbed 0:1387ff3eed4a 8822 break;
sPymbed 0:1387ff3eed4a 8823 ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz);
sPymbed 0:1387ff3eed4a 8824 #if defined(WOLFSSL_ASYNC_CRYPT)
sPymbed 0:1387ff3eed4a 8825 ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
sPymbed 0:1387ff3eed4a 8826 #endif
sPymbed 0:1387ff3eed4a 8827 }
sPymbed 0:1387ff3eed4a 8828 break;
sPymbed 0:1387ff3eed4a 8829
sPymbed 0:1387ff3eed4a 8830 default:
sPymbed 0:1387ff3eed4a 8831 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8832 break;
sPymbed 0:1387ff3eed4a 8833 }
sPymbed 0:1387ff3eed4a 8834 }
sPymbed 0:1387ff3eed4a 8835
sPymbed 0:1387ff3eed4a 8836 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8837 switch (ctx->macAlgo) {
sPymbed 0:1387ff3eed4a 8838 case ecHMAC_SHA256:
sPymbed 0:1387ff3eed4a 8839 {
sPymbed 0:1387ff3eed4a 8840 Hmac hmac;
sPymbed 0:1387ff3eed4a 8841 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
sPymbed 0:1387ff3eed4a 8842 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8843 ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
sPymbed 0:1387ff3eed4a 8844 if (ret == 0)
sPymbed 0:1387ff3eed4a 8845 ret = wc_HmacUpdate(&hmac, out, msgSz);
sPymbed 0:1387ff3eed4a 8846 if (ret == 0)
sPymbed 0:1387ff3eed4a 8847 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
sPymbed 0:1387ff3eed4a 8848 if (ret == 0)
sPymbed 0:1387ff3eed4a 8849 ret = wc_HmacFinal(&hmac, out+msgSz);
sPymbed 0:1387ff3eed4a 8850 wc_HmacFree(&hmac);
sPymbed 0:1387ff3eed4a 8851 }
sPymbed 0:1387ff3eed4a 8852 }
sPymbed 0:1387ff3eed4a 8853 break;
sPymbed 0:1387ff3eed4a 8854
sPymbed 0:1387ff3eed4a 8855 default:
sPymbed 0:1387ff3eed4a 8856 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8857 break;
sPymbed 0:1387ff3eed4a 8858 }
sPymbed 0:1387ff3eed4a 8859 }
sPymbed 0:1387ff3eed4a 8860
sPymbed 0:1387ff3eed4a 8861 if (ret == 0)
sPymbed 0:1387ff3eed4a 8862 *outSz = msgSz + digestSz;
sPymbed 0:1387ff3eed4a 8863
sPymbed 0:1387ff3eed4a 8864 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8865 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8866 XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8867 #endif
sPymbed 0:1387ff3eed4a 8868
sPymbed 0:1387ff3eed4a 8869 return ret;
sPymbed 0:1387ff3eed4a 8870 }
sPymbed 0:1387ff3eed4a 8871
sPymbed 0:1387ff3eed4a 8872
sPymbed 0:1387ff3eed4a 8873 /* ecc decrypt with shared secret run through kdf
sPymbed 0:1387ff3eed4a 8874 ctx holds non default algos and inputs
sPymbed 0:1387ff3eed4a 8875 return 0 on success */
sPymbed 0:1387ff3eed4a 8876 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
sPymbed 0:1387ff3eed4a 8877 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
sPymbed 0:1387ff3eed4a 8878 {
sPymbed 0:1387ff3eed4a 8879 int ret = 0;
sPymbed 0:1387ff3eed4a 8880 word32 blockSz;
sPymbed 0:1387ff3eed4a 8881 word32 digestSz;
sPymbed 0:1387ff3eed4a 8882 ecEncCtx localCtx;
sPymbed 0:1387ff3eed4a 8883 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8884 byte* sharedSecret;
sPymbed 0:1387ff3eed4a 8885 byte* keys;
sPymbed 0:1387ff3eed4a 8886 #else
sPymbed 0:1387ff3eed4a 8887 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */
sPymbed 0:1387ff3eed4a 8888 byte keys[ECC_BUFSIZE]; /* max size */
sPymbed 0:1387ff3eed4a 8889 #endif
sPymbed 0:1387ff3eed4a 8890 word32 sharedSz = ECC_MAXSIZE;
sPymbed 0:1387ff3eed4a 8891 int keysLen;
sPymbed 0:1387ff3eed4a 8892 int encKeySz;
sPymbed 0:1387ff3eed4a 8893 int ivSz;
sPymbed 0:1387ff3eed4a 8894 int offset = 0; /* in case using msg exchange */
sPymbed 0:1387ff3eed4a 8895 byte* encKey;
sPymbed 0:1387ff3eed4a 8896 byte* encIv;
sPymbed 0:1387ff3eed4a 8897 byte* macKey;
sPymbed 0:1387ff3eed4a 8898
sPymbed 0:1387ff3eed4a 8899 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
sPymbed 0:1387ff3eed4a 8900 outSz == NULL)
sPymbed 0:1387ff3eed4a 8901 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8902
sPymbed 0:1387ff3eed4a 8903 if (ctx == NULL) { /* use defaults */
sPymbed 0:1387ff3eed4a 8904 ecc_ctx_init(&localCtx, 0);
sPymbed 0:1387ff3eed4a 8905 ctx = &localCtx;
sPymbed 0:1387ff3eed4a 8906 }
sPymbed 0:1387ff3eed4a 8907
sPymbed 0:1387ff3eed4a 8908 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
sPymbed 0:1387ff3eed4a 8909 &blockSz);
sPymbed 0:1387ff3eed4a 8910 if (ret != 0)
sPymbed 0:1387ff3eed4a 8911 return ret;
sPymbed 0:1387ff3eed4a 8912
sPymbed 0:1387ff3eed4a 8913 if (ctx->protocol == REQ_RESP_CLIENT) {
sPymbed 0:1387ff3eed4a 8914 offset = keysLen;
sPymbed 0:1387ff3eed4a 8915 keysLen *= 2;
sPymbed 0:1387ff3eed4a 8916
sPymbed 0:1387ff3eed4a 8917 if (ctx->cliSt != ecCLI_SENT_REQ)
sPymbed 0:1387ff3eed4a 8918 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8919
sPymbed 0:1387ff3eed4a 8920 ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
sPymbed 0:1387ff3eed4a 8921 }
sPymbed 0:1387ff3eed4a 8922 else if (ctx->protocol == REQ_RESP_SERVER) {
sPymbed 0:1387ff3eed4a 8923 if (ctx->srvSt != ecSRV_SALT_SET)
sPymbed 0:1387ff3eed4a 8924 return BAD_STATE_E;
sPymbed 0:1387ff3eed4a 8925
sPymbed 0:1387ff3eed4a 8926 ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
sPymbed 0:1387ff3eed4a 8927 }
sPymbed 0:1387ff3eed4a 8928
sPymbed 0:1387ff3eed4a 8929 if (keysLen > ECC_BUFSIZE) /* keys size */
sPymbed 0:1387ff3eed4a 8930 return BUFFER_E;
sPymbed 0:1387ff3eed4a 8931
sPymbed 0:1387ff3eed4a 8932 if ( ((msgSz-digestSz) % blockSz) != 0)
sPymbed 0:1387ff3eed4a 8933 return BAD_PADDING_E;
sPymbed 0:1387ff3eed4a 8934
sPymbed 0:1387ff3eed4a 8935 if (*outSz < (msgSz - digestSz))
sPymbed 0:1387ff3eed4a 8936 return BUFFER_E;
sPymbed 0:1387ff3eed4a 8937
sPymbed 0:1387ff3eed4a 8938 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 8939 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8940 if (sharedSecret == NULL)
sPymbed 0:1387ff3eed4a 8941 return MEMORY_E;
sPymbed 0:1387ff3eed4a 8942
sPymbed 0:1387ff3eed4a 8943 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8944 if (keys == NULL) {
sPymbed 0:1387ff3eed4a 8945 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 8946 return MEMORY_E;
sPymbed 0:1387ff3eed4a 8947 }
sPymbed 0:1387ff3eed4a 8948 #endif
sPymbed 0:1387ff3eed4a 8949
sPymbed 0:1387ff3eed4a 8950 do {
sPymbed 0:1387ff3eed4a 8951 #if defined(WOLFSSL_ASYNC_CRYPT)
sPymbed 0:1387ff3eed4a 8952 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
sPymbed 0:1387ff3eed4a 8953 if (ret != 0)
sPymbed 0:1387ff3eed4a 8954 break;
sPymbed 0:1387ff3eed4a 8955 #endif
sPymbed 0:1387ff3eed4a 8956 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
sPymbed 0:1387ff3eed4a 8957 } while (ret == WC_PENDING_E);
sPymbed 0:1387ff3eed4a 8958 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8959 switch (ctx->kdfAlgo) {
sPymbed 0:1387ff3eed4a 8960 case ecHKDF_SHA256 :
sPymbed 0:1387ff3eed4a 8961 ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
sPymbed 0:1387ff3eed4a 8962 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
sPymbed 0:1387ff3eed4a 8963 keys, keysLen);
sPymbed 0:1387ff3eed4a 8964 break;
sPymbed 0:1387ff3eed4a 8965
sPymbed 0:1387ff3eed4a 8966 default:
sPymbed 0:1387ff3eed4a 8967 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 8968 break;
sPymbed 0:1387ff3eed4a 8969 }
sPymbed 0:1387ff3eed4a 8970 }
sPymbed 0:1387ff3eed4a 8971
sPymbed 0:1387ff3eed4a 8972 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8973 encKey = keys + offset;
sPymbed 0:1387ff3eed4a 8974 encIv = encKey + encKeySz;
sPymbed 0:1387ff3eed4a 8975 macKey = encKey + encKeySz + ivSz;
sPymbed 0:1387ff3eed4a 8976
sPymbed 0:1387ff3eed4a 8977 switch (ctx->macAlgo) {
sPymbed 0:1387ff3eed4a 8978 case ecHMAC_SHA256:
sPymbed 0:1387ff3eed4a 8979 {
sPymbed 0:1387ff3eed4a 8980 byte verify[WC_SHA256_DIGEST_SIZE];
sPymbed 0:1387ff3eed4a 8981 Hmac hmac;
sPymbed 0:1387ff3eed4a 8982
sPymbed 0:1387ff3eed4a 8983 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
sPymbed 0:1387ff3eed4a 8984 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8985 ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE);
sPymbed 0:1387ff3eed4a 8986 if (ret == 0)
sPymbed 0:1387ff3eed4a 8987 ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz);
sPymbed 0:1387ff3eed4a 8988 if (ret == 0)
sPymbed 0:1387ff3eed4a 8989 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz);
sPymbed 0:1387ff3eed4a 8990 if (ret == 0)
sPymbed 0:1387ff3eed4a 8991 ret = wc_HmacFinal(&hmac, verify);
sPymbed 0:1387ff3eed4a 8992 if (ret == 0) {
sPymbed 0:1387ff3eed4a 8993 if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0)
sPymbed 0:1387ff3eed4a 8994 ret = -1;
sPymbed 0:1387ff3eed4a 8995 }
sPymbed 0:1387ff3eed4a 8996
sPymbed 0:1387ff3eed4a 8997 wc_HmacFree(&hmac);
sPymbed 0:1387ff3eed4a 8998 }
sPymbed 0:1387ff3eed4a 8999 break;
sPymbed 0:1387ff3eed4a 9000 }
sPymbed 0:1387ff3eed4a 9001
sPymbed 0:1387ff3eed4a 9002 default:
sPymbed 0:1387ff3eed4a 9003 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9004 break;
sPymbed 0:1387ff3eed4a 9005 }
sPymbed 0:1387ff3eed4a 9006 }
sPymbed 0:1387ff3eed4a 9007
sPymbed 0:1387ff3eed4a 9008 if (ret == 0) {
sPymbed 0:1387ff3eed4a 9009 switch (ctx->encAlgo) {
sPymbed 0:1387ff3eed4a 9010 #ifdef HAVE_AES_CBC
sPymbed 0:1387ff3eed4a 9011 case ecAES_128_CBC:
sPymbed 0:1387ff3eed4a 9012 {
sPymbed 0:1387ff3eed4a 9013 Aes aes;
sPymbed 0:1387ff3eed4a 9014 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv,
sPymbed 0:1387ff3eed4a 9015 AES_DECRYPTION);
sPymbed 0:1387ff3eed4a 9016 if (ret != 0)
sPymbed 0:1387ff3eed4a 9017 break;
sPymbed 0:1387ff3eed4a 9018 ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz);
sPymbed 0:1387ff3eed4a 9019 #if defined(WOLFSSL_ASYNC_CRYPT)
sPymbed 0:1387ff3eed4a 9020 ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE);
sPymbed 0:1387ff3eed4a 9021 #endif
sPymbed 0:1387ff3eed4a 9022 }
sPymbed 0:1387ff3eed4a 9023 break;
sPymbed 0:1387ff3eed4a 9024 #endif
sPymbed 0:1387ff3eed4a 9025 default:
sPymbed 0:1387ff3eed4a 9026 ret = BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9027 break;
sPymbed 0:1387ff3eed4a 9028 }
sPymbed 0:1387ff3eed4a 9029 }
sPymbed 0:1387ff3eed4a 9030
sPymbed 0:1387ff3eed4a 9031 if (ret == 0)
sPymbed 0:1387ff3eed4a 9032 *outSz = msgSz - digestSz;
sPymbed 0:1387ff3eed4a 9033
sPymbed 0:1387ff3eed4a 9034 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9035 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 9036 XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 0:1387ff3eed4a 9037 #endif
sPymbed 0:1387ff3eed4a 9038
sPymbed 0:1387ff3eed4a 9039 return ret;
sPymbed 0:1387ff3eed4a 9040 }
sPymbed 0:1387ff3eed4a 9041
sPymbed 0:1387ff3eed4a 9042
sPymbed 0:1387ff3eed4a 9043 #endif /* HAVE_ECC_ENCRYPT */
sPymbed 0:1387ff3eed4a 9044
sPymbed 0:1387ff3eed4a 9045
sPymbed 0:1387ff3eed4a 9046 #ifdef HAVE_COMP_KEY
sPymbed 0:1387ff3eed4a 9047 #ifndef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 9048
sPymbed 0:1387ff3eed4a 9049 #ifndef WOLFSSL_SP_MATH
sPymbed 0:1387ff3eed4a 9050 int do_mp_jacobi(mp_int* a, mp_int* n, int* c);
sPymbed 0:1387ff3eed4a 9051
sPymbed 0:1387ff3eed4a 9052 int do_mp_jacobi(mp_int* a, mp_int* n, int* c)
sPymbed 0:1387ff3eed4a 9053 {
sPymbed 0:1387ff3eed4a 9054 int k, s, res;
sPymbed 0:1387ff3eed4a 9055 int r = 0; /* initialize to help static analysis out */
sPymbed 0:1387ff3eed4a 9056 mp_digit residue;
sPymbed 0:1387ff3eed4a 9057
sPymbed 0:1387ff3eed4a 9058 /* if a < 0 return MP_VAL */
sPymbed 0:1387ff3eed4a 9059 if (mp_isneg(a) == MP_YES) {
sPymbed 0:1387ff3eed4a 9060 return MP_VAL;
sPymbed 0:1387ff3eed4a 9061 }
sPymbed 0:1387ff3eed4a 9062
sPymbed 0:1387ff3eed4a 9063 /* if n <= 0 return MP_VAL */
sPymbed 0:1387ff3eed4a 9064 if (mp_cmp_d(n, 0) != MP_GT) {
sPymbed 0:1387ff3eed4a 9065 return MP_VAL;
sPymbed 0:1387ff3eed4a 9066 }
sPymbed 0:1387ff3eed4a 9067
sPymbed 0:1387ff3eed4a 9068 /* step 1. handle case of a == 0 */
sPymbed 0:1387ff3eed4a 9069 if (mp_iszero (a) == MP_YES) {
sPymbed 0:1387ff3eed4a 9070 /* special case of a == 0 and n == 1 */
sPymbed 0:1387ff3eed4a 9071 if (mp_cmp_d (n, 1) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9072 *c = 1;
sPymbed 0:1387ff3eed4a 9073 } else {
sPymbed 0:1387ff3eed4a 9074 *c = 0;
sPymbed 0:1387ff3eed4a 9075 }
sPymbed 0:1387ff3eed4a 9076 return MP_OKAY;
sPymbed 0:1387ff3eed4a 9077 }
sPymbed 0:1387ff3eed4a 9078
sPymbed 0:1387ff3eed4a 9079 /* step 2. if a == 1, return 1 */
sPymbed 0:1387ff3eed4a 9080 if (mp_cmp_d (a, 1) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9081 *c = 1;
sPymbed 0:1387ff3eed4a 9082 return MP_OKAY;
sPymbed 0:1387ff3eed4a 9083 }
sPymbed 0:1387ff3eed4a 9084
sPymbed 0:1387ff3eed4a 9085 /* default */
sPymbed 0:1387ff3eed4a 9086 s = 0;
sPymbed 0:1387ff3eed4a 9087
sPymbed 0:1387ff3eed4a 9088 /* divide out larger power of two */
sPymbed 0:1387ff3eed4a 9089 k = mp_cnt_lsb(a);
sPymbed 0:1387ff3eed4a 9090 res = mp_div_2d(a, k, a, NULL);
sPymbed 0:1387ff3eed4a 9091
sPymbed 0:1387ff3eed4a 9092 if (res == MP_OKAY) {
sPymbed 0:1387ff3eed4a 9093 /* step 4. if e is even set s=1 */
sPymbed 0:1387ff3eed4a 9094 if ((k & 1) == 0) {
sPymbed 0:1387ff3eed4a 9095 s = 1;
sPymbed 0:1387ff3eed4a 9096 } else {
sPymbed 0:1387ff3eed4a 9097 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
sPymbed 0:1387ff3eed4a 9098 residue = n->dp[0] & 7;
sPymbed 0:1387ff3eed4a 9099
sPymbed 0:1387ff3eed4a 9100 if (residue == 1 || residue == 7) {
sPymbed 0:1387ff3eed4a 9101 s = 1;
sPymbed 0:1387ff3eed4a 9102 } else if (residue == 3 || residue == 5) {
sPymbed 0:1387ff3eed4a 9103 s = -1;
sPymbed 0:1387ff3eed4a 9104 }
sPymbed 0:1387ff3eed4a 9105 }
sPymbed 0:1387ff3eed4a 9106
sPymbed 0:1387ff3eed4a 9107 /* step 5. if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */
sPymbed 0:1387ff3eed4a 9108 if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) {
sPymbed 0:1387ff3eed4a 9109 s = -s;
sPymbed 0:1387ff3eed4a 9110 }
sPymbed 0:1387ff3eed4a 9111 }
sPymbed 0:1387ff3eed4a 9112
sPymbed 0:1387ff3eed4a 9113 if (res == MP_OKAY) {
sPymbed 0:1387ff3eed4a 9114 /* if a == 1 we're done */
sPymbed 0:1387ff3eed4a 9115 if (mp_cmp_d(a, 1) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9116 *c = s;
sPymbed 0:1387ff3eed4a 9117 } else {
sPymbed 0:1387ff3eed4a 9118 /* n1 = n mod a */
sPymbed 0:1387ff3eed4a 9119 res = mp_mod (n, a, n);
sPymbed 0:1387ff3eed4a 9120 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9121 res = do_mp_jacobi(n, a, &r);
sPymbed 0:1387ff3eed4a 9122
sPymbed 0:1387ff3eed4a 9123 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9124 *c = s * r;
sPymbed 0:1387ff3eed4a 9125 }
sPymbed 0:1387ff3eed4a 9126 }
sPymbed 0:1387ff3eed4a 9127
sPymbed 0:1387ff3eed4a 9128 return res;
sPymbed 0:1387ff3eed4a 9129 }
sPymbed 0:1387ff3eed4a 9130
sPymbed 0:1387ff3eed4a 9131
sPymbed 0:1387ff3eed4a 9132 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
sPymbed 0:1387ff3eed4a 9133 * HAC pp. 73 Algorithm 2.149
sPymbed 0:1387ff3eed4a 9134 * HAC is wrong here, as the special case of (0 | 1) is not
sPymbed 0:1387ff3eed4a 9135 * handled correctly.
sPymbed 0:1387ff3eed4a 9136 */
sPymbed 0:1387ff3eed4a 9137 int mp_jacobi(mp_int* a, mp_int* n, int* c)
sPymbed 0:1387ff3eed4a 9138 {
sPymbed 0:1387ff3eed4a 9139 mp_int a1, n1;
sPymbed 0:1387ff3eed4a 9140 int res;
sPymbed 0:1387ff3eed4a 9141
sPymbed 0:1387ff3eed4a 9142 /* step 3. write a = a1 * 2**k */
sPymbed 0:1387ff3eed4a 9143 if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 9144 return res;
sPymbed 0:1387ff3eed4a 9145 }
sPymbed 0:1387ff3eed4a 9146
sPymbed 0:1387ff3eed4a 9147 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 9148 goto done;
sPymbed 0:1387ff3eed4a 9149 }
sPymbed 0:1387ff3eed4a 9150
sPymbed 0:1387ff3eed4a 9151 if ((res = mp_copy(n, &n1)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 9152 goto done;
sPymbed 0:1387ff3eed4a 9153 }
sPymbed 0:1387ff3eed4a 9154
sPymbed 0:1387ff3eed4a 9155 res = do_mp_jacobi(&a1, &n1, c);
sPymbed 0:1387ff3eed4a 9156
sPymbed 0:1387ff3eed4a 9157 done:
sPymbed 0:1387ff3eed4a 9158 /* cleanup */
sPymbed 0:1387ff3eed4a 9159 mp_clear(&n1);
sPymbed 0:1387ff3eed4a 9160 mp_clear(&a1);
sPymbed 0:1387ff3eed4a 9161
sPymbed 0:1387ff3eed4a 9162 return res;
sPymbed 0:1387ff3eed4a 9163 }
sPymbed 0:1387ff3eed4a 9164
sPymbed 0:1387ff3eed4a 9165
sPymbed 0:1387ff3eed4a 9166 /* Solves the modular equation x^2 = n (mod p)
sPymbed 0:1387ff3eed4a 9167 * where prime number is greater than 2 (odd prime).
sPymbed 0:1387ff3eed4a 9168 * The result is returned in the third argument x
sPymbed 0:1387ff3eed4a 9169 * the function returns MP_OKAY on success, MP_VAL or another error on failure
sPymbed 0:1387ff3eed4a 9170 */
sPymbed 0:1387ff3eed4a 9171 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
sPymbed 0:1387ff3eed4a 9172 {
sPymbed 0:1387ff3eed4a 9173 #ifdef SQRTMOD_USE_MOD_EXP
sPymbed 0:1387ff3eed4a 9174 int res;
sPymbed 0:1387ff3eed4a 9175
sPymbed 0:1387ff3eed4a 9176 mp_int e;
sPymbed 0:1387ff3eed4a 9177
sPymbed 0:1387ff3eed4a 9178 res = mp_init(&e);
sPymbed 0:1387ff3eed4a 9179 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9180 res = mp_add_d(prime, 1, &e);
sPymbed 0:1387ff3eed4a 9181 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9182 res = mp_div_2d(&e, 2, &e, NULL);
sPymbed 0:1387ff3eed4a 9183 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9184 res = mp_exptmod(n, &e, prime, ret);
sPymbed 0:1387ff3eed4a 9185
sPymbed 0:1387ff3eed4a 9186 mp_clear(&e);
sPymbed 0:1387ff3eed4a 9187
sPymbed 0:1387ff3eed4a 9188 return res;
sPymbed 0:1387ff3eed4a 9189 #else
sPymbed 0:1387ff3eed4a 9190 int res, legendre, done = 0;
sPymbed 0:1387ff3eed4a 9191 mp_int t1, C, Q, S, Z, M, T, R, two;
sPymbed 0:1387ff3eed4a 9192 mp_digit i;
sPymbed 0:1387ff3eed4a 9193
sPymbed 0:1387ff3eed4a 9194 /* first handle the simple cases n = 0 or n = 1 */
sPymbed 0:1387ff3eed4a 9195 if (mp_cmp_d(n, 0) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9196 mp_zero(ret);
sPymbed 0:1387ff3eed4a 9197 return MP_OKAY;
sPymbed 0:1387ff3eed4a 9198 }
sPymbed 0:1387ff3eed4a 9199 if (mp_cmp_d(n, 1) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9200 return mp_set(ret, 1);
sPymbed 0:1387ff3eed4a 9201 }
sPymbed 0:1387ff3eed4a 9202
sPymbed 0:1387ff3eed4a 9203 /* prime must be odd */
sPymbed 0:1387ff3eed4a 9204 if (mp_cmp_d(prime, 2) == MP_EQ) {
sPymbed 0:1387ff3eed4a 9205 return MP_VAL;
sPymbed 0:1387ff3eed4a 9206 }
sPymbed 0:1387ff3eed4a 9207
sPymbed 0:1387ff3eed4a 9208 /* is quadratic non-residue mod prime */
sPymbed 0:1387ff3eed4a 9209 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) {
sPymbed 0:1387ff3eed4a 9210 return res;
sPymbed 0:1387ff3eed4a 9211 }
sPymbed 0:1387ff3eed4a 9212 if (legendre == -1) {
sPymbed 0:1387ff3eed4a 9213 return MP_VAL;
sPymbed 0:1387ff3eed4a 9214 }
sPymbed 0:1387ff3eed4a 9215
sPymbed 0:1387ff3eed4a 9216 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
sPymbed 0:1387ff3eed4a 9217 return res;
sPymbed 0:1387ff3eed4a 9218
sPymbed 0:1387ff3eed4a 9219 if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
sPymbed 0:1387ff3eed4a 9220 != MP_OKAY) {
sPymbed 0:1387ff3eed4a 9221 mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
sPymbed 0:1387ff3eed4a 9222 mp_clear(&M);
sPymbed 0:1387ff3eed4a 9223 return res;
sPymbed 0:1387ff3eed4a 9224 }
sPymbed 0:1387ff3eed4a 9225
sPymbed 0:1387ff3eed4a 9226 /* SPECIAL CASE: if prime mod 4 == 3
sPymbed 0:1387ff3eed4a 9227 * compute directly: res = n^(prime+1)/4 mod prime
sPymbed 0:1387ff3eed4a 9228 * Handbook of Applied Cryptography algorithm 3.36
sPymbed 0:1387ff3eed4a 9229 */
sPymbed 0:1387ff3eed4a 9230 res = mp_mod_d(prime, 4, &i);
sPymbed 0:1387ff3eed4a 9231 if (res == MP_OKAY && i == 3) {
sPymbed 0:1387ff3eed4a 9232 res = mp_add_d(prime, 1, &t1);
sPymbed 0:1387ff3eed4a 9233
sPymbed 0:1387ff3eed4a 9234 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9235 res = mp_div_2(&t1, &t1);
sPymbed 0:1387ff3eed4a 9236 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9237 res = mp_div_2(&t1, &t1);
sPymbed 0:1387ff3eed4a 9238 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9239 res = mp_exptmod(n, &t1, prime, ret);
sPymbed 0:1387ff3eed4a 9240
sPymbed 0:1387ff3eed4a 9241 done = 1;
sPymbed 0:1387ff3eed4a 9242 }
sPymbed 0:1387ff3eed4a 9243
sPymbed 0:1387ff3eed4a 9244 /* NOW: TonelliShanks algorithm */
sPymbed 0:1387ff3eed4a 9245 if (res == MP_OKAY && done == 0) {
sPymbed 0:1387ff3eed4a 9246
sPymbed 0:1387ff3eed4a 9247 /* factor out powers of 2 from prime-1, defining Q and S
sPymbed 0:1387ff3eed4a 9248 * as: prime-1 = Q*2^S */
sPymbed 0:1387ff3eed4a 9249 /* Q = prime - 1 */
sPymbed 0:1387ff3eed4a 9250 res = mp_copy(prime, &Q);
sPymbed 0:1387ff3eed4a 9251 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9252 res = mp_sub_d(&Q, 1, &Q);
sPymbed 0:1387ff3eed4a 9253
sPymbed 0:1387ff3eed4a 9254 /* S = 0 */
sPymbed 0:1387ff3eed4a 9255 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9256 mp_zero(&S);
sPymbed 0:1387ff3eed4a 9257
sPymbed 0:1387ff3eed4a 9258 while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) {
sPymbed 0:1387ff3eed4a 9259 /* Q = Q / 2 */
sPymbed 0:1387ff3eed4a 9260 res = mp_div_2(&Q, &Q);
sPymbed 0:1387ff3eed4a 9261
sPymbed 0:1387ff3eed4a 9262 /* S = S + 1 */
sPymbed 0:1387ff3eed4a 9263 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9264 res = mp_add_d(&S, 1, &S);
sPymbed 0:1387ff3eed4a 9265 }
sPymbed 0:1387ff3eed4a 9266
sPymbed 0:1387ff3eed4a 9267 /* find a Z such that the Legendre symbol (Z|prime) == -1 */
sPymbed 0:1387ff3eed4a 9268 /* Z = 2 */
sPymbed 0:1387ff3eed4a 9269 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9270 res = mp_set_int(&Z, 2);
sPymbed 0:1387ff3eed4a 9271
sPymbed 0:1387ff3eed4a 9272 while (res == MP_OKAY) {
sPymbed 0:1387ff3eed4a 9273 res = mp_jacobi(&Z, prime, &legendre);
sPymbed 0:1387ff3eed4a 9274 if (res == MP_OKAY && legendre == -1)
sPymbed 0:1387ff3eed4a 9275 break;
sPymbed 0:1387ff3eed4a 9276
sPymbed 0:1387ff3eed4a 9277 /* Z = Z + 1 */
sPymbed 0:1387ff3eed4a 9278 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9279 res = mp_add_d(&Z, 1, &Z);
sPymbed 0:1387ff3eed4a 9280 }
sPymbed 0:1387ff3eed4a 9281
sPymbed 0:1387ff3eed4a 9282 /* C = Z ^ Q mod prime */
sPymbed 0:1387ff3eed4a 9283 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9284 res = mp_exptmod(&Z, &Q, prime, &C);
sPymbed 0:1387ff3eed4a 9285
sPymbed 0:1387ff3eed4a 9286 /* t1 = (Q + 1) / 2 */
sPymbed 0:1387ff3eed4a 9287 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9288 res = mp_add_d(&Q, 1, &t1);
sPymbed 0:1387ff3eed4a 9289 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9290 res = mp_div_2(&t1, &t1);
sPymbed 0:1387ff3eed4a 9291
sPymbed 0:1387ff3eed4a 9292 /* R = n ^ ((Q + 1) / 2) mod prime */
sPymbed 0:1387ff3eed4a 9293 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9294 res = mp_exptmod(n, &t1, prime, &R);
sPymbed 0:1387ff3eed4a 9295
sPymbed 0:1387ff3eed4a 9296 /* T = n ^ Q mod prime */
sPymbed 0:1387ff3eed4a 9297 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9298 res = mp_exptmod(n, &Q, prime, &T);
sPymbed 0:1387ff3eed4a 9299
sPymbed 0:1387ff3eed4a 9300 /* M = S */
sPymbed 0:1387ff3eed4a 9301 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9302 res = mp_copy(&S, &M);
sPymbed 0:1387ff3eed4a 9303
sPymbed 0:1387ff3eed4a 9304 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9305 res = mp_set_int(&two, 2);
sPymbed 0:1387ff3eed4a 9306
sPymbed 0:1387ff3eed4a 9307 while (res == MP_OKAY && done == 0) {
sPymbed 0:1387ff3eed4a 9308 res = mp_copy(&T, &t1);
sPymbed 0:1387ff3eed4a 9309
sPymbed 0:1387ff3eed4a 9310 /* reduce to 1 and count */
sPymbed 0:1387ff3eed4a 9311 i = 0;
sPymbed 0:1387ff3eed4a 9312 while (res == MP_OKAY) {
sPymbed 0:1387ff3eed4a 9313 if (mp_cmp_d(&t1, 1) == MP_EQ)
sPymbed 0:1387ff3eed4a 9314 break;
sPymbed 0:1387ff3eed4a 9315 res = mp_exptmod(&t1, &two, prime, &t1);
sPymbed 0:1387ff3eed4a 9316 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9317 i++;
sPymbed 0:1387ff3eed4a 9318 }
sPymbed 0:1387ff3eed4a 9319 if (res == MP_OKAY && i == 0) {
sPymbed 0:1387ff3eed4a 9320 res = mp_copy(&R, ret);
sPymbed 0:1387ff3eed4a 9321 done = 1;
sPymbed 0:1387ff3eed4a 9322 }
sPymbed 0:1387ff3eed4a 9323
sPymbed 0:1387ff3eed4a 9324 if (done == 0) {
sPymbed 0:1387ff3eed4a 9325 /* t1 = 2 ^ (M - i - 1) */
sPymbed 0:1387ff3eed4a 9326 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9327 res = mp_sub_d(&M, i, &t1);
sPymbed 0:1387ff3eed4a 9328 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9329 res = mp_sub_d(&t1, 1, &t1);
sPymbed 0:1387ff3eed4a 9330 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9331 res = mp_exptmod(&two, &t1, prime, &t1);
sPymbed 0:1387ff3eed4a 9332
sPymbed 0:1387ff3eed4a 9333 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
sPymbed 0:1387ff3eed4a 9334 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9335 res = mp_exptmod(&C, &t1, prime, &t1);
sPymbed 0:1387ff3eed4a 9336
sPymbed 0:1387ff3eed4a 9337 /* C = (t1 * t1) mod prime */
sPymbed 0:1387ff3eed4a 9338 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9339 res = mp_sqrmod(&t1, prime, &C);
sPymbed 0:1387ff3eed4a 9340
sPymbed 0:1387ff3eed4a 9341 /* R = (R * t1) mod prime */
sPymbed 0:1387ff3eed4a 9342 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9343 res = mp_mulmod(&R, &t1, prime, &R);
sPymbed 0:1387ff3eed4a 9344
sPymbed 0:1387ff3eed4a 9345 /* T = (T * C) mod prime */
sPymbed 0:1387ff3eed4a 9346 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9347 res = mp_mulmod(&T, &C, prime, &T);
sPymbed 0:1387ff3eed4a 9348
sPymbed 0:1387ff3eed4a 9349 /* M = i */
sPymbed 0:1387ff3eed4a 9350 if (res == MP_OKAY)
sPymbed 0:1387ff3eed4a 9351 res = mp_set(&M, i);
sPymbed 0:1387ff3eed4a 9352 }
sPymbed 0:1387ff3eed4a 9353 }
sPymbed 0:1387ff3eed4a 9354 }
sPymbed 0:1387ff3eed4a 9355
sPymbed 0:1387ff3eed4a 9356 /* done */
sPymbed 0:1387ff3eed4a 9357 mp_clear(&t1);
sPymbed 0:1387ff3eed4a 9358 mp_clear(&C);
sPymbed 0:1387ff3eed4a 9359 mp_clear(&Q);
sPymbed 0:1387ff3eed4a 9360 mp_clear(&S);
sPymbed 0:1387ff3eed4a 9361 mp_clear(&Z);
sPymbed 0:1387ff3eed4a 9362 mp_clear(&M);
sPymbed 0:1387ff3eed4a 9363 mp_clear(&T);
sPymbed 0:1387ff3eed4a 9364 mp_clear(&R);
sPymbed 0:1387ff3eed4a 9365 mp_clear(&two);
sPymbed 0:1387ff3eed4a 9366
sPymbed 0:1387ff3eed4a 9367 return res;
sPymbed 0:1387ff3eed4a 9368 #endif
sPymbed 0:1387ff3eed4a 9369 }
sPymbed 0:1387ff3eed4a 9370 #endif
sPymbed 0:1387ff3eed4a 9371 #endif /* !WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 9372
sPymbed 0:1387ff3eed4a 9373
sPymbed 0:1387ff3eed4a 9374 /* export public ECC key in ANSI X9.63 format compressed */
sPymbed 0:1387ff3eed4a 9375 static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
sPymbed 0:1387ff3eed4a 9376 {
sPymbed 0:1387ff3eed4a 9377 word32 numlen;
sPymbed 0:1387ff3eed4a 9378 int ret = MP_OKAY;
sPymbed 0:1387ff3eed4a 9379
sPymbed 0:1387ff3eed4a 9380 if (key == NULL || out == NULL || outLen == NULL)
sPymbed 0:1387ff3eed4a 9381 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9382
sPymbed 0:1387ff3eed4a 9383 if (wc_ecc_is_valid_idx(key->idx) == 0) {
sPymbed 0:1387ff3eed4a 9384 return ECC_BAD_ARG_E;
sPymbed 0:1387ff3eed4a 9385 }
sPymbed 0:1387ff3eed4a 9386 numlen = key->dp->size;
sPymbed 0:1387ff3eed4a 9387
sPymbed 0:1387ff3eed4a 9388 if (*outLen < (1 + numlen)) {
sPymbed 0:1387ff3eed4a 9389 *outLen = 1 + numlen;
sPymbed 0:1387ff3eed4a 9390 return BUFFER_E;
sPymbed 0:1387ff3eed4a 9391 }
sPymbed 0:1387ff3eed4a 9392
sPymbed 0:1387ff3eed4a 9393 #ifdef WOLFSSL_ATECC508A
sPymbed 0:1387ff3eed4a 9394 /* TODO: Implement equiv call to ATECC508A */
sPymbed 0:1387ff3eed4a 9395 ret = BAD_COND_E;
sPymbed 0:1387ff3eed4a 9396
sPymbed 0:1387ff3eed4a 9397 #else
sPymbed 0:1387ff3eed4a 9398
sPymbed 0:1387ff3eed4a 9399 /* store first byte */
sPymbed 0:1387ff3eed4a 9400 out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
sPymbed 0:1387ff3eed4a 9401
sPymbed 0:1387ff3eed4a 9402 /* pad and store x */
sPymbed 0:1387ff3eed4a 9403 XMEMSET(out+1, 0, numlen);
sPymbed 0:1387ff3eed4a 9404 ret = mp_to_unsigned_bin(key->pubkey.x,
sPymbed 0:1387ff3eed4a 9405 out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
sPymbed 0:1387ff3eed4a 9406 *outLen = 1 + numlen;
sPymbed 0:1387ff3eed4a 9407
sPymbed 0:1387ff3eed4a 9408 #endif /* WOLFSSL_ATECC508A */
sPymbed 0:1387ff3eed4a 9409
sPymbed 0:1387ff3eed4a 9410 return ret;
sPymbed 0:1387ff3eed4a 9411 }
sPymbed 0:1387ff3eed4a 9412
sPymbed 0:1387ff3eed4a 9413 #endif /* HAVE_COMP_KEY */
sPymbed 0:1387ff3eed4a 9414
sPymbed 0:1387ff3eed4a 9415
sPymbed 0:1387ff3eed4a 9416 int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
sPymbed 0:1387ff3eed4a 9417 {
sPymbed 0:1387ff3eed4a 9418 int x;
sPymbed 0:1387ff3eed4a 9419
sPymbed 0:1387ff3eed4a 9420 if (oidSum == 0) {
sPymbed 0:1387ff3eed4a 9421 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9422 }
sPymbed 0:1387ff3eed4a 9423
sPymbed 0:1387ff3eed4a 9424 /* find matching OID sum (based on encoded value) */
sPymbed 0:1387ff3eed4a 9425 for (x = 0; ecc_sets[x].size != 0; x++) {
sPymbed 0:1387ff3eed4a 9426 if (ecc_sets[x].oidSum == oidSum) {
sPymbed 0:1387ff3eed4a 9427 int ret = 0;
sPymbed 0:1387ff3eed4a 9428 #ifdef HAVE_OID_ENCODING
sPymbed 0:1387ff3eed4a 9429 /* check cache */
sPymbed 0:1387ff3eed4a 9430 oid_cache_t* o = &ecc_oid_cache[x];
sPymbed 0:1387ff3eed4a 9431 if (o->oidSz == 0) {
sPymbed 0:1387ff3eed4a 9432 o->oidSz = sizeof(o->oid);
sPymbed 0:1387ff3eed4a 9433 ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
sPymbed 0:1387ff3eed4a 9434 o->oid, &o->oidSz);
sPymbed 0:1387ff3eed4a 9435 }
sPymbed 0:1387ff3eed4a 9436 if (oidSz) {
sPymbed 0:1387ff3eed4a 9437 *oidSz = o->oidSz;
sPymbed 0:1387ff3eed4a 9438 }
sPymbed 0:1387ff3eed4a 9439 if (oid) {
sPymbed 0:1387ff3eed4a 9440 *oid = o->oid;
sPymbed 0:1387ff3eed4a 9441 }
sPymbed 0:1387ff3eed4a 9442 #else
sPymbed 0:1387ff3eed4a 9443 if (oidSz) {
sPymbed 0:1387ff3eed4a 9444 *oidSz = ecc_sets[x].oidSz;
sPymbed 0:1387ff3eed4a 9445 }
sPymbed 0:1387ff3eed4a 9446 if (oid) {
sPymbed 0:1387ff3eed4a 9447 *oid = ecc_sets[x].oid;
sPymbed 0:1387ff3eed4a 9448 }
sPymbed 0:1387ff3eed4a 9449 #endif
sPymbed 0:1387ff3eed4a 9450 /* on success return curve id */
sPymbed 0:1387ff3eed4a 9451 if (ret == 0) {
sPymbed 0:1387ff3eed4a 9452 ret = ecc_sets[x].id;
sPymbed 0:1387ff3eed4a 9453 }
sPymbed 0:1387ff3eed4a 9454 return ret;
sPymbed 0:1387ff3eed4a 9455 }
sPymbed 0:1387ff3eed4a 9456 }
sPymbed 0:1387ff3eed4a 9457
sPymbed 0:1387ff3eed4a 9458 return NOT_COMPILED_IN;
sPymbed 0:1387ff3eed4a 9459 }
sPymbed 0:1387ff3eed4a 9460
sPymbed 0:1387ff3eed4a 9461 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 0:1387ff3eed4a 9462 int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
sPymbed 0:1387ff3eed4a 9463 {
sPymbed 0:1387ff3eed4a 9464 if (key == NULL || dp == NULL) {
sPymbed 0:1387ff3eed4a 9465 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9466 }
sPymbed 0:1387ff3eed4a 9467
sPymbed 0:1387ff3eed4a 9468 key->idx = ECC_CUSTOM_IDX;
sPymbed 0:1387ff3eed4a 9469 key->dp = dp;
sPymbed 0:1387ff3eed4a 9470
sPymbed 0:1387ff3eed4a 9471 return 0;
sPymbed 0:1387ff3eed4a 9472 }
sPymbed 0:1387ff3eed4a 9473 #endif /* WOLFSSL_CUSTOM_CURVES */
sPymbed 0:1387ff3eed4a 9474
sPymbed 0:1387ff3eed4a 9475 #ifdef HAVE_X963_KDF
sPymbed 0:1387ff3eed4a 9476
sPymbed 0:1387ff3eed4a 9477 static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
sPymbed 0:1387ff3eed4a 9478 {
sPymbed 0:1387ff3eed4a 9479 int i;
sPymbed 0:1387ff3eed4a 9480
sPymbed 0:1387ff3eed4a 9481 /* in network byte order so start at end and work back */
sPymbed 0:1387ff3eed4a 9482 for (i = 3; i >= 0; i--) {
sPymbed 0:1387ff3eed4a 9483 if (++inOutCtr[i]) /* we're done unless we overflow */
sPymbed 0:1387ff3eed4a 9484 return;
sPymbed 0:1387ff3eed4a 9485 }
sPymbed 0:1387ff3eed4a 9486 }
sPymbed 0:1387ff3eed4a 9487
sPymbed 0:1387ff3eed4a 9488 /* ASN X9.63 Key Derivation Function (SEC1) */
sPymbed 0:1387ff3eed4a 9489 int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
sPymbed 0:1387ff3eed4a 9490 const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
sPymbed 0:1387ff3eed4a 9491 {
sPymbed 0:1387ff3eed4a 9492 int ret, i;
sPymbed 0:1387ff3eed4a 9493 int digestSz, copySz;
sPymbed 0:1387ff3eed4a 9494 int remaining = outSz;
sPymbed 0:1387ff3eed4a 9495 byte* outIdx;
sPymbed 0:1387ff3eed4a 9496 byte counter[4];
sPymbed 0:1387ff3eed4a 9497 byte tmp[WC_MAX_DIGEST_SIZE];
sPymbed 0:1387ff3eed4a 9498
sPymbed 0:1387ff3eed4a 9499 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9500 wc_HashAlg* hash;
sPymbed 0:1387ff3eed4a 9501 #else
sPymbed 0:1387ff3eed4a 9502 wc_HashAlg hash[1];
sPymbed 0:1387ff3eed4a 9503 #endif
sPymbed 0:1387ff3eed4a 9504
sPymbed 0:1387ff3eed4a 9505 if (secret == NULL || secretSz == 0 || out == NULL)
sPymbed 0:1387ff3eed4a 9506 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9507
sPymbed 0:1387ff3eed4a 9508 /* X9.63 allowed algos only */
sPymbed 0:1387ff3eed4a 9509 if (type != WC_HASH_TYPE_SHA && type != WC_HASH_TYPE_SHA224 &&
sPymbed 0:1387ff3eed4a 9510 type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
sPymbed 0:1387ff3eed4a 9511 type != WC_HASH_TYPE_SHA512)
sPymbed 0:1387ff3eed4a 9512 return BAD_FUNC_ARG;
sPymbed 0:1387ff3eed4a 9513
sPymbed 0:1387ff3eed4a 9514 digestSz = wc_HashGetDigestSize(type);
sPymbed 0:1387ff3eed4a 9515 if (digestSz < 0)
sPymbed 0:1387ff3eed4a 9516 return digestSz;
sPymbed 0:1387ff3eed4a 9517
sPymbed 0:1387ff3eed4a 9518 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9519 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
sPymbed 0:1387ff3eed4a 9520 DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9521 if (hash == NULL)
sPymbed 0:1387ff3eed4a 9522 return MEMORY_E;
sPymbed 0:1387ff3eed4a 9523 #endif
sPymbed 0:1387ff3eed4a 9524
sPymbed 0:1387ff3eed4a 9525 ret = wc_HashInit(hash, type);
sPymbed 0:1387ff3eed4a 9526 if (ret != 0) {
sPymbed 0:1387ff3eed4a 9527 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9528 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9529 #endif
sPymbed 0:1387ff3eed4a 9530 return ret;
sPymbed 0:1387ff3eed4a 9531 }
sPymbed 0:1387ff3eed4a 9532
sPymbed 0:1387ff3eed4a 9533 outIdx = out;
sPymbed 0:1387ff3eed4a 9534 XMEMSET(counter, 0, sizeof(counter));
sPymbed 0:1387ff3eed4a 9535
sPymbed 0:1387ff3eed4a 9536 for (i = 1; remaining > 0; i++) {
sPymbed 0:1387ff3eed4a 9537
sPymbed 0:1387ff3eed4a 9538 IncrementX963KdfCounter(counter);
sPymbed 0:1387ff3eed4a 9539
sPymbed 0:1387ff3eed4a 9540 ret = wc_HashUpdate(hash, type, secret, secretSz);
sPymbed 0:1387ff3eed4a 9541 if (ret != 0) {
sPymbed 0:1387ff3eed4a 9542 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9543 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9544 #endif
sPymbed 0:1387ff3eed4a 9545 return ret;
sPymbed 0:1387ff3eed4a 9546 }
sPymbed 0:1387ff3eed4a 9547
sPymbed 0:1387ff3eed4a 9548 ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
sPymbed 0:1387ff3eed4a 9549 if (ret != 0) {
sPymbed 0:1387ff3eed4a 9550 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9551 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9552 #endif
sPymbed 0:1387ff3eed4a 9553 return ret;
sPymbed 0:1387ff3eed4a 9554 }
sPymbed 0:1387ff3eed4a 9555
sPymbed 0:1387ff3eed4a 9556 if (sinfo) {
sPymbed 0:1387ff3eed4a 9557 ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
sPymbed 0:1387ff3eed4a 9558 if (ret != 0) {
sPymbed 0:1387ff3eed4a 9559 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9560 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9561 #endif
sPymbed 0:1387ff3eed4a 9562 return ret;
sPymbed 0:1387ff3eed4a 9563 }
sPymbed 0:1387ff3eed4a 9564 }
sPymbed 0:1387ff3eed4a 9565
sPymbed 0:1387ff3eed4a 9566 ret = wc_HashFinal(hash, type, tmp);
sPymbed 0:1387ff3eed4a 9567 if (ret != 0) {
sPymbed 0:1387ff3eed4a 9568 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9569 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9570 #endif
sPymbed 0:1387ff3eed4a 9571 return ret;
sPymbed 0:1387ff3eed4a 9572 }
sPymbed 0:1387ff3eed4a 9573
sPymbed 0:1387ff3eed4a 9574 copySz = min(remaining, digestSz);
sPymbed 0:1387ff3eed4a 9575 XMEMCPY(outIdx, tmp, copySz);
sPymbed 0:1387ff3eed4a 9576
sPymbed 0:1387ff3eed4a 9577 remaining -= copySz;
sPymbed 0:1387ff3eed4a 9578 outIdx += copySz;
sPymbed 0:1387ff3eed4a 9579 }
sPymbed 0:1387ff3eed4a 9580
sPymbed 0:1387ff3eed4a 9581 #ifdef WOLFSSL_SMALL_STACK
sPymbed 0:1387ff3eed4a 9582 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES);
sPymbed 0:1387ff3eed4a 9583 #endif
sPymbed 0:1387ff3eed4a 9584
sPymbed 0:1387ff3eed4a 9585 return 0;
sPymbed 0:1387ff3eed4a 9586 }
sPymbed 0:1387ff3eed4a 9587 #endif /* HAVE_X963_KDF */
sPymbed 0:1387ff3eed4a 9588
sPymbed 0:1387ff3eed4a 9589 #endif /* HAVE_ECC */
sPymbed 0:1387ff3eed4a 9590