Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ecc.c
00001 /* ecc.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 /* in case user set HAVE_ECC there */ 00029 #include <wolfcrypt/settings.h> 00030 00031 /* 00032 Possible ECC enable options: 00033 * HAVE_ECC: Overall control of ECC default: on 00034 * HAVE_ECC_ENCRYPT: ECC encrypt/decrypt w/AES and HKDF default: off 00035 * HAVE_ECC_SIGN: ECC sign default: on 00036 * HAVE_ECC_VERIFY: ECC verify default: on 00037 * HAVE_ECC_DHE: ECC build shared secret default: on 00038 * HAVE_ECC_CDH: ECC cofactor DH shared secret default: off 00039 * HAVE_ECC_KEY_IMPORT: ECC Key import default: on 00040 * HAVE_ECC_KEY_EXPORT: ECC Key export default: on 00041 * ECC_SHAMIR: Enables Shamir calc method default: on 00042 * HAVE_COMP_KEY: Enables compressed key default: off 00043 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import default: off 00044 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen default: off 00045 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves. default: off 00046 * Includes the curve "a" variable in calculation 00047 * ECC_DUMP_OID: Enables dump of OID encoding and sum default: off 00048 * ECC_CACHE_CURVE: Enables cache of curve info to improve perofrmance 00049 default: off 00050 * FP_ECC: ECC Fixed Point Cache default: off 00051 * USE_ECC_B_PARAM: Enable ECC curve B param default: off 00052 (on for HAVE_COMP_KEY) 00053 */ 00054 00055 /* 00056 ECC Curve Types: 00057 * NO_ECC_SECP Disables SECP curves default: off (not defined) 00058 * HAVE_ECC_SECPR2 Enables SECP R2 curves default: off 00059 * HAVE_ECC_SECPR3 Enables SECP R3 curves default: off 00060 * HAVE_ECC_BRAINPOOL Enables Brainpool curves default: off 00061 * HAVE_ECC_KOBLITZ Enables Koblitz curves default: off 00062 */ 00063 00064 /* 00065 ECC Curve Sizes: 00066 * ECC_USER_CURVES: Allows custom combination of key sizes below 00067 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined) 00068 * HAVE_ECC112: 112 bit key 00069 * HAVE_ECC128: 128 bit key 00070 * HAVE_ECC160: 160 bit key 00071 * HAVE_ECC192: 192 bit key 00072 * HAVE_ECC224: 224 bit key 00073 * HAVE_ECC239: 239 bit key 00074 * NO_ECC256: Disables 256 bit key (on by default) 00075 * HAVE_ECC320: 320 bit key 00076 * HAVE_ECC384: 384 bit key 00077 * HAVE_ECC512: 512 bit key 00078 * HAVE_ECC521: 521 bit key 00079 */ 00080 00081 00082 #ifdef HAVE_ECC 00083 00084 /* Make sure custom curves is enabled for Brainpool or Koblitz curve types */ 00085 #if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\ 00086 !defined(WOLFSSL_CUSTOM_CURVES) 00087 #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES 00088 #endif 00089 00090 /* Make sure ASN is enabled for ECC sign/verify */ 00091 #if (defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY)) && defined(NO_ASN) 00092 #error ASN must be enabled for ECC sign/verify 00093 #endif 00094 00095 00096 #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 00097 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00098 #define FIPS_NO_WRAPPERS 00099 00100 #ifdef USE_WINDOWS_API 00101 #pragma code_seg(".fipsA$f") 00102 #pragma const_seg(".fipsB$f") 00103 #endif 00104 #endif 00105 00106 #include <wolfcrypt/ecc.h> 00107 #include <wolfcrypt/asn.h> 00108 #include <wolfcrypt/error-crypt.h> 00109 #include <wolfcrypt/logging.h> 00110 #include <wolfcrypt/types.h> 00111 00112 #ifdef WOLFSSL_HAVE_SP_ECC 00113 #include <wolfcrypt/sp.h> 00114 #endif 00115 00116 #ifdef HAVE_ECC_ENCRYPT 00117 #include <wolfcrypt/hmac.h> 00118 #include <wolfcrypt/aes.h> 00119 #endif 00120 00121 #ifdef HAVE_X963_KDF 00122 #include <wolfcrypt/hash.h> 00123 #endif 00124 00125 #ifdef WOLF_CRYPTO_DEV 00126 #include <wolfcrypt/cryptodev.h> 00127 #endif 00128 00129 #ifdef NO_INLINE 00130 #include <wolfcrypt/misc.h> 00131 #else 00132 #define WOLFSSL_MISC_INCLUDED 00133 #include <wolfcrypt/src/misc.c> 00134 #endif 00135 00136 #if defined(FREESCALE_LTC_ECC) 00137 #include <wolfcrypt/port/nxp/ksdk_port.h> 00138 #endif 00139 00140 #ifdef WOLFSSL_SP_MATH 00141 #define GEN_MEM_ERR MP_MEM 00142 #elif defined(USE_FAST_MATH) 00143 #define GEN_MEM_ERR FP_MEM 00144 #else 00145 #define GEN_MEM_ERR MP_MEM 00146 #endif 00147 00148 00149 /* internal ECC states */ 00150 enum { 00151 ECC_STATE_NONE = 0, 00152 00153 ECC_STATE_SHARED_SEC_GEN, 00154 ECC_STATE_SHARED_SEC_RES, 00155 00156 ECC_STATE_SIGN_DO, 00157 ECC_STATE_SIGN_ENCODE, 00158 00159 ECC_STATE_VERIFY_DECODE, 00160 ECC_STATE_VERIFY_DO, 00161 ECC_STATE_VERIFY_RES, 00162 }; 00163 00164 00165 /* map 00166 ptmul -> mulmod 00167 */ 00168 00169 /* 256-bit curve on by default whether user curves or not */ 00170 #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) 00171 #define ECC112 00172 #endif 00173 #if defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES) 00174 #define ECC128 00175 #endif 00176 #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) 00177 #define ECC160 00178 #endif 00179 #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) 00180 #define ECC192 00181 #endif 00182 #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) 00183 #define ECC224 00184 #endif 00185 #if defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES) 00186 #define ECC239 00187 #endif 00188 #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) 00189 #define ECC256 00190 #endif 00191 #if defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES) 00192 #define ECC320 00193 #endif 00194 #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) 00195 #define ECC384 00196 #endif 00197 #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) 00198 #define ECC512 00199 #endif 00200 #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) 00201 #define ECC521 00202 #endif 00203 00204 /* The encoded OID's for ECC curves */ 00205 #ifdef ECC112 00206 #ifndef NO_ECC_SECP 00207 #ifdef HAVE_OID_ENCODING 00208 #define CODED_SECP112R1 {1,3,132,0,6} 00209 #define CODED_SECP112R1_SZ 5 00210 #else 00211 #define CODED_SECP112R1 {0x2B,0x81,0x04,0x00,0x06} 00212 #define CODED_SECP112R1_SZ 5 00213 #endif 00214 #ifndef USE_WINDOWS_API 00215 static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1; 00216 #else 00217 #define ecc_oid_secp112r1 CODED_SECP112R1 00218 #endif 00219 #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ 00220 #endif /* !NO_ECC_SECP */ 00221 #ifdef HAVE_ECC_SECPR2 00222 #ifdef HAVE_OID_ENCODING 00223 #define CODED_SECP112R2 {1,3,132,0,7} 00224 #define CODED_SECP112R2_SZ 5 00225 #else 00226 #define CODED_SECP112R2 {0x2B,0x81,0x04,0x00,0x07} 00227 #define CODED_SECP112R2_SZ 5 00228 #endif 00229 #ifndef USE_WINDOWS_API 00230 static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2; 00231 #else 00232 #define ecc_oid_secp112r2 CODED_SECP112R2 00233 #endif 00234 #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ 00235 #endif /* HAVE_ECC_SECPR2 */ 00236 #endif /* ECC112 */ 00237 #ifdef ECC128 00238 #ifndef NO_ECC_SECP 00239 #ifdef HAVE_OID_ENCODING 00240 #define CODED_SECP128R1 {1,3,132,0,28} 00241 #define CODED_SECP128R1_SZ 5 00242 #else 00243 #define CODED_SECP128R1 {0x2B,0x81,0x04,0x00,0x1C} 00244 #define CODED_SECP128R1_SZ 5 00245 #endif 00246 #ifndef USE_WINDOWS_API 00247 static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1; 00248 #else 00249 #define ecc_oid_secp128r1 CODED_SECP128R1 00250 #endif 00251 #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ 00252 #endif /* !NO_ECC_SECP */ 00253 #ifdef HAVE_ECC_SECPR2 00254 #ifdef HAVE_OID_ENCODING 00255 #define CODED_SECP128R2 {1,3,132,0,29} 00256 #define CODED_SECP128R2_SZ 5 00257 #else 00258 #define CODED_SECP128R2 {0x2B,0x81,0x04,0x00,0x1D} 00259 #define CODED_SECP128R2_SZ 5 00260 #endif 00261 #ifndef USE_WINDOWS_API 00262 static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2; 00263 #else 00264 #define ecc_oid_secp128r2 CODED_SECP128R2 00265 #endif 00266 #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ 00267 #endif /* HAVE_ECC_SECPR2 */ 00268 #endif /* ECC128 */ 00269 #ifdef ECC160 00270 #ifndef NO_ECC_SECP 00271 #ifdef HAVE_OID_ENCODING 00272 #define CODED_SECP160R1 {1,3,132,0,8} 00273 #define CODED_SECP160R1_SZ 5 00274 #else 00275 #define CODED_SECP160R1 {0x2B,0x81,0x04,0x00,0x08} 00276 #define CODED_SECP160R1_SZ 5 00277 #endif 00278 #ifndef USE_WINDOWS_API 00279 static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1; 00280 #else 00281 #define ecc_oid_secp160r1 CODED_SECP160R1 00282 #endif 00283 #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ 00284 #endif /* !NO_ECC_SECP */ 00285 #ifdef HAVE_ECC_SECPR2 00286 #ifdef HAVE_OID_ENCODING 00287 #define CODED_SECP160R2 {1,3,132,0,30} 00288 #define CODED_SECP160R1_SZ 5 00289 #else 00290 #define CODED_SECP160R2 {0x2B,0x81,0x04,0x00,0x1E} 00291 #define CODED_SECP160R2_SZ 5 00292 #endif 00293 #ifndef USE_WINDOWS_API 00294 static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2; 00295 #else 00296 #define ecc_oid_secp160r2 CODED_SECP160R2 00297 #endif 00298 #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ 00299 #endif /* HAVE_ECC_SECPR2 */ 00300 #ifdef HAVE_ECC_KOBLITZ 00301 #ifdef HAVE_OID_ENCODING 00302 #define CODED_SECP160K1 {1,3,132,0,9} 00303 #define CODED_SECP160K1_SZ 5 00304 #else 00305 #define CODED_SECP160K1 {0x2B,0x81,0x04,0x00,0x09} 00306 #define CODED_SECP160K1_SZ 5 00307 #endif 00308 #ifndef USE_WINDOWS_API 00309 static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1; 00310 #else 00311 #define ecc_oid_secp160k1 CODED_SECP160K1 00312 #endif 00313 #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ 00314 #endif /* HAVE_ECC_KOBLITZ */ 00315 #ifdef HAVE_ECC_BRAINPOOL 00316 #ifdef HAVE_OID_ENCODING 00317 #define CODED_BRAINPOOLP160R1 {1,3,36,3,3,2,8,1,1,1} 00318 #define CODED_BRAINPOOLP160R1_SZ 10 00319 #else 00320 #define CODED_BRAINPOOLP160R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01} 00321 #define CODED_BRAINPOOLP160R1_SZ 9 00322 #endif 00323 #ifndef USE_WINDOWS_API 00324 static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1; 00325 #else 00326 #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1 00327 #endif 00328 #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ 00329 #endif /* HAVE_ECC_BRAINPOOL */ 00330 #endif /* ECC160 */ 00331 #ifdef ECC192 00332 #ifndef NO_ECC_SECP 00333 #ifdef HAVE_OID_ENCODING 00334 #define CODED_SECP192R1 {1,2,840,10045,3,1,1} 00335 #define CODED_SECP192R1_SZ 7 00336 #else 00337 #define CODED_SECP192R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01} 00338 #define CODED_SECP192R1_SZ 8 00339 #endif 00340 #ifndef USE_WINDOWS_API 00341 static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1; 00342 #else 00343 #define ecc_oid_secp192r1 CODED_SECP192R1 00344 #endif 00345 #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ 00346 #endif /* !NO_ECC_SECP */ 00347 #ifdef HAVE_ECC_SECPR2 00348 #ifdef HAVE_OID_ENCODING 00349 #define CODED_PRIME192V2 {1,2,840,10045,3,1,2} 00350 #define CODED_PRIME192V2_SZ 7 00351 #else 00352 #define CODED_PRIME192V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02} 00353 #define CODED_PRIME192V2_SZ 8 00354 #endif 00355 #ifndef USE_WINDOWS_API 00356 static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2; 00357 #else 00358 #define ecc_oid_prime192v2 CODED_PRIME192V2 00359 #endif 00360 #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ 00361 #endif /* HAVE_ECC_SECPR2 */ 00362 #ifdef HAVE_ECC_SECPR3 00363 #ifdef HAVE_OID_ENCODING 00364 #define CODED_PRIME192V3 {1,2,840,10045,3,1,3} 00365 #define CODED_PRIME192V3_SZ 7 00366 #else 00367 #define CODED_PRIME192V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03} 00368 #define CODED_PRIME192V3_SZ 8 00369 #endif 00370 #ifndef USE_WINDOWS_API 00371 static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3; 00372 #else 00373 #define ecc_oid_prime192v3 CODED_PRIME192V3 00374 #endif 00375 #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ 00376 #endif /* HAVE_ECC_SECPR3 */ 00377 #ifdef HAVE_ECC_KOBLITZ 00378 #ifdef HAVE_OID_ENCODING 00379 #define CODED_SECP192K1 {1,3,132,0,31} 00380 #define CODED_SECP192K1_SZ 5 00381 #else 00382 #define CODED_SECP192K1 {0x2B,0x81,0x04,0x00,0x1F} 00383 #define CODED_SECP192K1_SZ 5 00384 #endif 00385 #ifndef USE_WINDOWS_API 00386 static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1; 00387 #else 00388 #define ecc_oid_secp192k1 CODED_SECP192K1 00389 #endif 00390 #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ 00391 #endif /* HAVE_ECC_KOBLITZ */ 00392 #ifdef HAVE_ECC_BRAINPOOL 00393 #ifdef HAVE_OID_ENCODING 00394 #define CODED_BRAINPOOLP192R1 {1,3,36,3,3,2,8,1,1,3} 00395 #define CODED_BRAINPOOLP192R1_SZ 10 00396 #else 00397 #define CODED_BRAINPOOLP192R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03} 00398 #define CODED_BRAINPOOLP192R1_SZ 9 00399 #endif 00400 #ifndef USE_WINDOWS_API 00401 static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1; 00402 #else 00403 #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1 00404 #endif 00405 #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ 00406 #endif /* HAVE_ECC_BRAINPOOL */ 00407 #endif /* ECC192 */ 00408 #ifdef ECC224 00409 #ifndef NO_ECC_SECP 00410 #ifdef HAVE_OID_ENCODING 00411 #define CODED_SECP224R1 {1,3,132,0,33} 00412 #define CODED_SECP224R1_SZ 5 00413 #else 00414 #define CODED_SECP224R1 {0x2B,0x81,0x04,0x00,0x21} 00415 #define CODED_SECP224R1_SZ 5 00416 #endif 00417 #ifndef USE_WINDOWS_API 00418 static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1; 00419 #else 00420 #define ecc_oid_secp224r1 CODED_SECP224R1 00421 #endif 00422 #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ 00423 #endif /* !NO_ECC_SECP */ 00424 #ifdef HAVE_ECC_KOBLITZ 00425 #ifdef HAVE_OID_ENCODING 00426 #define CODED_SECP224K1 {1,3,132,0,32} 00427 #define CODED_SECP224K1_SZ 5 00428 #else 00429 #define CODED_SECP224K1 {0x2B,0x81,0x04,0x00,0x20} 00430 #define CODED_SECP224K1_SZ 5 00431 #endif 00432 #ifndef USE_WINDOWS_API 00433 static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1; 00434 #else 00435 #define ecc_oid_secp224k1 CODED_SECP224K1 00436 #endif 00437 #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ 00438 #endif /* HAVE_ECC_KOBLITZ */ 00439 #ifdef HAVE_ECC_BRAINPOOL 00440 #ifdef HAVE_OID_ENCODING 00441 #define CODED_BRAINPOOLP224R1 {1,3,36,3,3,2,8,1,1,5} 00442 #define CODED_BRAINPOOLP224R1_SZ 10 00443 #else 00444 #define CODED_BRAINPOOLP224R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05} 00445 #define CODED_BRAINPOOLP224R1_SZ 9 00446 #endif 00447 #ifndef USE_WINDOWS_API 00448 static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1; 00449 #else 00450 #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1 00451 #endif 00452 #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ 00453 #endif /* HAVE_ECC_BRAINPOOL */ 00454 #endif /* ECC224 */ 00455 #ifdef ECC239 00456 #ifndef NO_ECC_SECP 00457 #ifdef HAVE_OID_ENCODING 00458 #define CODED_PRIME239V1 {1,2,840,10045,3,1,4} 00459 #define CODED_PRIME239V1_SZ 7 00460 #else 00461 #define CODED_PRIME239V1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04} 00462 #define CODED_PRIME239V1_SZ 8 00463 #endif 00464 #ifndef USE_WINDOWS_API 00465 static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1; 00466 #else 00467 #define ecc_oid_prime239v1 CODED_PRIME239V1 00468 #endif 00469 #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ 00470 #endif /* !NO_ECC_SECP */ 00471 #ifdef HAVE_ECC_SECPR2 00472 #ifdef HAVE_OID_ENCODING 00473 #define CODED_PRIME239V2 {1,2,840,10045,3,1,5} 00474 #define CODED_PRIME239V2_SZ 7 00475 #else 00476 #define CODED_PRIME239V2 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05} 00477 #define CODED_PRIME239V2_SZ 8 00478 #endif 00479 #ifndef USE_WINDOWS_API 00480 static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2; 00481 #else 00482 #define ecc_oid_prime239v2 CODED_PRIME239V2 00483 #endif 00484 #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ 00485 #endif /* HAVE_ECC_SECPR2 */ 00486 #ifdef HAVE_ECC_SECPR3 00487 #ifdef HAVE_OID_ENCODING 00488 #define CODED_PRIME239V3 {1,2,840,10045,3,1,6} 00489 #define CODED_PRIME239V3_SZ 7 00490 #else 00491 #define CODED_PRIME239V3 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06} 00492 #define CODED_PRIME239V3_SZ 8 00493 #endif 00494 #ifndef USE_WINDOWS_API 00495 static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3; 00496 #else 00497 #define ecc_oid_prime239v3 CODED_PRIME239V3 00498 #endif 00499 #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ 00500 #endif /* HAVE_ECC_SECPR3 */ 00501 #endif /* ECC239 */ 00502 #ifdef ECC256 00503 #ifndef NO_ECC_SECP 00504 #ifdef HAVE_OID_ENCODING 00505 #define CODED_SECP256R1 {1,2,840,10045,3,1,7} 00506 #define CODED_SECP256R1_SZ 7 00507 #else 00508 #define CODED_SECP256R1 {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07} 00509 #define CODED_SECP256R1_SZ 8 00510 #endif 00511 #ifndef USE_WINDOWS_API 00512 static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1; 00513 #else 00514 #define ecc_oid_secp256r1 CODED_SECP256R1 00515 #endif 00516 #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ 00517 #endif /* !NO_ECC_SECP */ 00518 #ifdef HAVE_ECC_KOBLITZ 00519 #ifdef HAVE_OID_ENCODING 00520 #define CODED_SECP256K1 {1,3,132,0,10} 00521 #define CODED_SECP256K1_SZ 5 00522 #else 00523 #define CODED_SECP256K1 {0x2B,0x81,0x04,0x00,0x0A} 00524 #define CODED_SECP256K1_SZ 5 00525 #endif 00526 #ifndef USE_WINDOWS_API 00527 static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1; 00528 #else 00529 #define ecc_oid_secp256k1 CODED_SECP256K1 00530 #endif 00531 #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ 00532 #endif /* HAVE_ECC_KOBLITZ */ 00533 #ifdef HAVE_ECC_BRAINPOOL 00534 #ifdef HAVE_OID_ENCODING 00535 #define CODED_BRAINPOOLP256R1 {1,3,36,3,3,2,8,1,1,7} 00536 #define CODED_BRAINPOOLP256R1_SZ 10 00537 #else 00538 #define CODED_BRAINPOOLP256R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07} 00539 #define CODED_BRAINPOOLP256R1_SZ 9 00540 #endif 00541 #ifndef USE_WINDOWS_API 00542 static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1; 00543 #else 00544 #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1 00545 #endif 00546 #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ 00547 #endif /* HAVE_ECC_BRAINPOOL */ 00548 #endif /* ECC256 */ 00549 #ifdef ECC320 00550 #ifdef HAVE_ECC_BRAINPOOL 00551 #ifdef HAVE_OID_ENCODING 00552 #define CODED_BRAINPOOLP320R1 {1,3,36,3,3,2,8,1,1,9} 00553 #define CODED_BRAINPOOLP320R1_SZ 10 00554 #else 00555 #define CODED_BRAINPOOLP320R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09} 00556 #define CODED_BRAINPOOLP320R1_SZ 9 00557 #endif 00558 #ifndef USE_WINDOWS_API 00559 static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1; 00560 #else 00561 #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1 00562 #endif 00563 #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ 00564 #endif /* HAVE_ECC_BRAINPOOL */ 00565 #endif /* ECC320 */ 00566 #ifdef ECC384 00567 #ifndef NO_ECC_SECP 00568 #ifdef HAVE_OID_ENCODING 00569 #define CODED_SECP384R1 {1,3,132,0,34} 00570 #define CODED_SECP384R1_SZ 5 00571 #else 00572 #define CODED_SECP384R1 {0x2B,0x81,0x04,0x00,0x22} 00573 #define CODED_SECP384R1_SZ 5 00574 #endif 00575 #ifndef USE_WINDOWS_API 00576 static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1; 00577 #define CODED_SECP384R1_OID ecc_oid_secp384r1 00578 #else 00579 #define ecc_oid_secp384r1 CODED_SECP384R1 00580 #endif 00581 #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ 00582 #endif /* !NO_ECC_SECP */ 00583 #ifdef HAVE_ECC_BRAINPOOL 00584 #ifdef HAVE_OID_ENCODING 00585 #define CODED_BRAINPOOLP384R1 {1,3,36,3,3,2,8,1,1,11} 00586 #define CODED_BRAINPOOLP384R1_SZ 10 00587 #else 00588 #define CODED_BRAINPOOLP384R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B} 00589 #define CODED_BRAINPOOLP384R1_SZ 9 00590 #endif 00591 #ifndef USE_WINDOWS_API 00592 static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1; 00593 #else 00594 #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1 00595 #endif 00596 #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ 00597 #endif /* HAVE_ECC_BRAINPOOL */ 00598 #endif /* ECC384 */ 00599 #ifdef ECC512 00600 #ifdef HAVE_ECC_BRAINPOOL 00601 #ifdef HAVE_OID_ENCODING 00602 #define CODED_BRAINPOOLP512R1 {1,3,36,3,3,2,8,1,1,13} 00603 #define CODED_BRAINPOOLP512R1_SZ 10 00604 #else 00605 #define CODED_BRAINPOOLP512R1 {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D} 00606 #define CODED_BRAINPOOLP512R1_SZ 9 00607 #endif 00608 #ifndef USE_WINDOWS_API 00609 static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1; 00610 #else 00611 #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1 00612 #endif 00613 #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ 00614 #endif /* HAVE_ECC_BRAINPOOL */ 00615 #endif /* ECC512 */ 00616 #ifdef ECC521 00617 #ifndef NO_ECC_SECP 00618 #ifdef HAVE_OID_ENCODING 00619 #define CODED_SECP521R1 {1,3,132,0,35} 00620 #define CODED_SECP521R1_SZ 5 00621 #else 00622 #define CODED_SECP521R1 {0x2B,0x81,0x04,0x00,0x23} 00623 #define CODED_SECP521R1_SZ 5 00624 #endif 00625 #ifndef USE_WINDOWS_API 00626 static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1; 00627 #else 00628 #define ecc_oid_secp521r1 CODED_SECP521R1 00629 #endif 00630 #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ 00631 #endif /* !NO_ECC_SECP */ 00632 #endif /* ECC521 */ 00633 00634 00635 /* This holds the key settings. 00636 ***MUST*** be organized by size from smallest to largest. */ 00637 00638 const ecc_set_type ecc_sets[] = { 00639 #ifdef ECC112 00640 #ifndef NO_ECC_SECP 00641 { 00642 14, /* size/bytes */ 00643 ECC_SECP112R1, /* ID */ 00644 "SECP112R1", /* curve name */ 00645 "DB7C2ABF62E35E668076BEAD208B", /* prime */ 00646 "DB7C2ABF62E35E668076BEAD2088", /* A */ 00647 "659EF8BA043916EEDE8911702B22", /* B */ 00648 "DB7C2ABF62E35E7628DFAC6561C5", /* order */ 00649 "9487239995A5EE76B55F9C2F098", /* Gx */ 00650 "A89CE5AF8724C0A23E0E0FF77500", /* Gy */ 00651 ecc_oid_secp112r1, /* oid/oidSz */ 00652 ecc_oid_secp112r1_sz, 00653 ECC_SECP112R1_OID, /* oid sum */ 00654 1, /* cofactor */ 00655 }, 00656 #endif /* !NO_ECC_SECP */ 00657 #ifdef HAVE_ECC_SECPR2 00658 { 00659 14, /* size/bytes */ 00660 ECC_SECP112R2, /* ID */ 00661 "SECP112R2", /* curve name */ 00662 "DB7C2ABF62E35E668076BEAD208B", /* prime */ 00663 "6127C24C05F38A0AAAF65C0EF02C", /* A */ 00664 "51DEF1815DB5ED74FCC34C85D709", /* B */ 00665 "36DF0AAFD8B8D7597CA10520D04B", /* order */ 00666 "4BA30AB5E892B4E1649DD0928643", /* Gx */ 00667 "ADCD46F5882E3747DEF36E956E97", /* Gy */ 00668 ecc_oid_secp112r2, /* oid/oidSz */ 00669 ecc_oid_secp112r2_sz, 00670 ECC_SECP112R2_OID, /* oid sum */ 00671 4, /* cofactor */ 00672 }, 00673 #endif /* HAVE_ECC_SECPR2 */ 00674 #endif /* ECC112 */ 00675 #ifdef ECC128 00676 #ifndef NO_ECC_SECP 00677 { 00678 16, /* size/bytes */ 00679 ECC_SECP128R1, /* ID */ 00680 "SECP128R1", /* curve name */ 00681 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00682 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 00683 "E87579C11079F43DD824993C2CEE5ED3", /* B */ 00684 "FFFFFFFE0000000075A30D1B9038A115", /* order */ 00685 "161FF7528B899B2D0C28607CA52C5B86", /* Gx */ 00686 "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy */ 00687 ecc_oid_secp128r1, /* oid/oidSz */ 00688 ecc_oid_secp128r1_sz, 00689 ECC_SECP128R1_OID, /* oid sum */ 00690 1, /* cofactor */ 00691 }, 00692 #endif /* !NO_ECC_SECP */ 00693 #ifdef HAVE_ECC_SECPR2 00694 { 00695 16, /* size/bytes */ 00696 ECC_SECP128R2, /* ID */ 00697 "SECP128R2", /* curve name */ 00698 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00699 "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A */ 00700 "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B */ 00701 "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order */ 00702 "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx */ 00703 "27B6916A894D3AEE7106FE805FC34B44", /* Gy */ 00704 ecc_oid_secp128r2, /* oid/oidSz */ 00705 ecc_oid_secp128r2_sz, 00706 ECC_SECP128R2_OID, /* oid sum */ 00707 4, /* cofactor */ 00708 }, 00709 #endif /* HAVE_ECC_SECPR2 */ 00710 #endif /* ECC128 */ 00711 #ifdef ECC160 00712 #ifndef NO_ECC_SECP 00713 { 00714 20, /* size/bytes */ 00715 ECC_SECP160R1, /* ID */ 00716 "SECP160R1", /* curve name */ 00717 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime */ 00718 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A */ 00719 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B */ 00720 "100000000000000000001F4C8F927AED3CA752257",/* order */ 00721 "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx */ 00722 "23A628553168947D59DCC912042351377AC5FB32", /* Gy */ 00723 ecc_oid_secp160r1, /* oid/oidSz */ 00724 ecc_oid_secp160r1_sz, 00725 ECC_SECP160R1_OID, /* oid sum */ 00726 1, /* cofactor */ 00727 }, 00728 #endif /* !NO_ECC_SECP */ 00729 #ifdef HAVE_ECC_SECPR2 00730 { 00731 20, /* size/bytes */ 00732 ECC_SECP160R2, /* ID */ 00733 "SECP160R2", /* curve name */ 00734 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ 00735 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A */ 00736 "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B */ 00737 "100000000000000000000351EE786A818F3A1A16B",/* order */ 00738 "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx */ 00739 "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy */ 00740 ecc_oid_secp160r2, /* oid/oidSz */ 00741 ecc_oid_secp160r2_sz, 00742 ECC_SECP160R2_OID, /* oid sum */ 00743 1, /* cofactor */ 00744 }, 00745 #endif /* HAVE_ECC_SECPR2 */ 00746 #ifdef HAVE_ECC_KOBLITZ 00747 { 00748 20, /* size/bytes */ 00749 ECC_SECP160K1, /* ID */ 00750 "SECP160K1", /* curve name */ 00751 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime */ 00752 "0000000000000000000000000000000000000000", /* A */ 00753 "0000000000000000000000000000000000000007", /* B */ 00754 "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order */ 00755 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx */ 00756 "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy */ 00757 ecc_oid_secp160k1, /* oid/oidSz */ 00758 ecc_oid_secp160k1_sz, 00759 ECC_SECP160K1_OID, /* oid sum */ 00760 1, /* cofactor */ 00761 }, 00762 #endif /* HAVE_ECC_KOBLITZ */ 00763 #ifdef HAVE_ECC_BRAINPOOL 00764 { 00765 20, /* size/bytes */ 00766 ECC_BRAINPOOLP160R1, /* ID */ 00767 "BRAINPOOLP160R1", /* curve name */ 00768 "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime */ 00769 "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A */ 00770 "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B */ 00771 "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order */ 00772 "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx */ 00773 "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy */ 00774 ecc_oid_brainpoolp160r1, /* oid/oidSz */ 00775 ecc_oid_brainpoolp160r1_sz, 00776 ECC_BRAINPOOLP160R1_OID, /* oid sum */ 00777 1, /* cofactor */ 00778 }, 00779 #endif /* HAVE_ECC_BRAINPOOL */ 00780 #endif /* ECC160 */ 00781 #ifdef ECC192 00782 #ifndef NO_ECC_SECP 00783 { 00784 24, /* size/bytes */ 00785 ECC_SECP192R1, /* ID */ 00786 "SECP192R1", /* curve name */ 00787 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00788 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00789 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B */ 00790 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order */ 00791 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx */ 00792 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", /* Gy */ 00793 ecc_oid_secp192r1, /* oid/oidSz */ 00794 ecc_oid_secp192r1_sz, 00795 ECC_SECP192R1_OID, /* oid sum */ 00796 1, /* cofactor */ 00797 }, 00798 #endif /* !NO_ECC_SECP */ 00799 #ifdef HAVE_ECC_SECPR2 00800 { 00801 24, /* size/bytes */ 00802 ECC_PRIME192V2, /* ID */ 00803 "PRIME192V2", /* curve name */ 00804 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00805 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00806 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B */ 00807 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order */ 00808 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx */ 00809 "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy */ 00810 ecc_oid_prime192v2, /* oid/oidSz */ 00811 ecc_oid_prime192v2_sz, 00812 ECC_PRIME192V2_OID, /* oid sum */ 00813 1, /* cofactor */ 00814 }, 00815 #endif /* HAVE_ECC_SECPR2 */ 00816 #ifdef HAVE_ECC_SECPR3 00817 { 00818 24, /* size/bytes */ 00819 ECC_PRIME192V3, /* ID */ 00820 "PRIME192V3", /* curve name */ 00821 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime */ 00822 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A */ 00823 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B */ 00824 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order */ 00825 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx */ 00826 "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy */ 00827 ecc_oid_prime192v3, /* oid/oidSz */ 00828 ecc_oid_prime192v3_sz, 00829 ECC_PRIME192V3_OID, /* oid sum */ 00830 1, /* cofactor */ 00831 }, 00832 #endif /* HAVE_ECC_SECPR3 */ 00833 #ifdef HAVE_ECC_KOBLITZ 00834 { 00835 24, /* size/bytes */ 00836 ECC_SECP192K1, /* ID */ 00837 "SECP192K1", /* curve name */ 00838 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime */ 00839 "000000000000000000000000000000000000000000000000", /* A */ 00840 "000000000000000000000000000000000000000000000003", /* B */ 00841 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order */ 00842 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx */ 00843 "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy */ 00844 ecc_oid_secp192k1, /* oid/oidSz */ 00845 ecc_oid_secp192k1_sz, 00846 ECC_SECP192K1_OID, /* oid sum */ 00847 1, /* cofactor */ 00848 }, 00849 #endif /* HAVE_ECC_KOBLITZ */ 00850 #ifdef HAVE_ECC_BRAINPOOL 00851 { 00852 24, /* size/bytes */ 00853 ECC_BRAINPOOLP192R1, /* ID */ 00854 "BRAINPOOLP192R1", /* curve name */ 00855 "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime */ 00856 "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A */ 00857 "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B */ 00858 "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order */ 00859 "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx */ 00860 "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy */ 00861 ecc_oid_brainpoolp192r1, /* oid/oidSz */ 00862 ecc_oid_brainpoolp192r1_sz, 00863 ECC_BRAINPOOLP192R1_OID, /* oid sum */ 00864 1, /* cofactor */ 00865 }, 00866 #endif /* HAVE_ECC_BRAINPOOL */ 00867 #endif /* ECC192 */ 00868 #ifdef ECC224 00869 #ifndef NO_ECC_SECP 00870 { 00871 28, /* size/bytes */ 00872 ECC_SECP224R1, /* ID */ 00873 "SECP224R1", /* curve name */ 00874 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime */ 00875 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A */ 00876 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B */ 00877 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order */ 00878 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx */ 00879 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy */ 00880 ecc_oid_secp224r1, /* oid/oidSz */ 00881 ecc_oid_secp224r1_sz, 00882 ECC_SECP224R1_OID, /* oid sum */ 00883 1, /* cofactor */ 00884 }, 00885 #endif /* !NO_ECC_SECP */ 00886 #ifdef HAVE_ECC_KOBLITZ 00887 { 00888 28, /* size/bytes */ 00889 ECC_SECP224K1, /* ID */ 00890 "SECP224K1", /* curve name */ 00891 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime */ 00892 "00000000000000000000000000000000000000000000000000000000", /* A */ 00893 "00000000000000000000000000000000000000000000000000000005", /* B */ 00894 "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order */ 00895 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx */ 00896 "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy */ 00897 ecc_oid_secp224k1, /* oid/oidSz */ 00898 ecc_oid_secp224k1_sz, 00899 ECC_SECP224K1_OID, /* oid sum */ 00900 1, /* cofactor */ 00901 }, 00902 #endif /* HAVE_ECC_KOBLITZ */ 00903 #ifdef HAVE_ECC_BRAINPOOL 00904 { 00905 28, /* size/bytes */ 00906 ECC_BRAINPOOLP224R1, /* ID */ 00907 "BRAINPOOLP224R1", /* curve name */ 00908 "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime */ 00909 "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A */ 00910 "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B */ 00911 "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order */ 00912 "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx */ 00913 "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy */ 00914 ecc_oid_brainpoolp224r1, /* oid/oidSz */ 00915 ecc_oid_brainpoolp224r1_sz, 00916 ECC_BRAINPOOLP224R1_OID, /* oid sum */ 00917 1, /* cofactor */ 00918 }, 00919 #endif /* HAVE_ECC_BRAINPOOL */ 00920 #endif /* ECC224 */ 00921 #ifdef ECC239 00922 #ifndef NO_ECC_SECP 00923 { 00924 30, /* size/bytes */ 00925 ECC_PRIME239V1, /* ID */ 00926 "PRIME239V1", /* curve name */ 00927 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00928 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00929 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B */ 00930 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order */ 00931 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx */ 00932 "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy */ 00933 ecc_oid_prime239v1, /* oid/oidSz */ 00934 ecc_oid_prime239v1_sz, 00935 ECC_PRIME239V1_OID, /* oid sum */ 00936 1, /* cofactor */ 00937 }, 00938 #endif /* !NO_ECC_SECP */ 00939 #ifdef HAVE_ECC_SECPR2 00940 { 00941 30, /* size/bytes */ 00942 ECC_PRIME239V2, /* ID */ 00943 "PRIME239V2", /* curve name */ 00944 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00945 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00946 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B */ 00947 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order */ 00948 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx */ 00949 "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy */ 00950 ecc_oid_prime239v2, /* oid/oidSz */ 00951 ecc_oid_prime239v2_sz, 00952 ECC_PRIME239V2_OID, /* oid sum */ 00953 1, /* cofactor */ 00954 }, 00955 #endif /* HAVE_ECC_SECPR2 */ 00956 #ifdef HAVE_ECC_SECPR3 00957 { 00958 30, /* size/bytes */ 00959 ECC_PRIME239V3, /* ID */ 00960 "PRIME239V3", /* curve name */ 00961 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime */ 00962 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A */ 00963 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B */ 00964 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order */ 00965 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx */ 00966 "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy */ 00967 ecc_oid_prime239v3, /* oid/oidSz */ 00968 ecc_oid_prime239v3_sz, 00969 ECC_PRIME239V3_OID, /* oid sum */ 00970 1, /* cofactor */ 00971 }, 00972 #endif /* HAVE_ECC_SECPR3 */ 00973 #endif /* ECC239 */ 00974 #ifdef ECC256 00975 #ifndef NO_ECC_SECP 00976 { 00977 32, /* size/bytes */ 00978 ECC_SECP256R1, /* ID */ 00979 "SECP256R1", /* curve name */ 00980 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 00981 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 00982 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B */ 00983 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order */ 00984 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx */ 00985 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy */ 00986 ecc_oid_secp256r1, /* oid/oidSz */ 00987 ecc_oid_secp256r1_sz, 00988 ECC_SECP256R1_OID, /* oid sum */ 00989 1, /* cofactor */ 00990 }, 00991 #endif /* !NO_ECC_SECP */ 00992 #ifdef HAVE_ECC_KOBLITZ 00993 { 00994 32, /* size/bytes */ 00995 ECC_SECP256K1, /* ID */ 00996 "SECP256K1", /* curve name */ 00997 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime */ 00998 "0000000000000000000000000000000000000000000000000000000000000000", /* A */ 00999 "0000000000000000000000000000000000000000000000000000000000000007", /* B */ 01000 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order */ 01001 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx */ 01002 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy */ 01003 ecc_oid_secp256k1, /* oid/oidSz */ 01004 ecc_oid_secp256k1_sz, 01005 ECC_SECP256K1_OID, /* oid sum */ 01006 1, /* cofactor */ 01007 }, 01008 #endif /* HAVE_ECC_KOBLITZ */ 01009 #ifdef HAVE_ECC_BRAINPOOL 01010 { 01011 32, /* size/bytes */ 01012 ECC_BRAINPOOLP256R1, /* ID */ 01013 "BRAINPOOLP256R1", /* curve name */ 01014 "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime */ 01015 "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */ 01016 "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */ 01017 "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order */ 01018 "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx */ 01019 "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy */ 01020 ecc_oid_brainpoolp256r1, /* oid/oidSz */ 01021 ecc_oid_brainpoolp256r1_sz, 01022 ECC_BRAINPOOLP256R1_OID, /* oid sum */ 01023 1, /* cofactor */ 01024 }, 01025 #endif /* HAVE_ECC_BRAINPOOL */ 01026 #endif /* ECC256 */ 01027 #ifdef ECC320 01028 #ifdef HAVE_ECC_BRAINPOOL 01029 { 01030 40, /* size/bytes */ 01031 ECC_BRAINPOOLP320R1, /* ID */ 01032 "BRAINPOOLP320R1", /* curve name */ 01033 "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime */ 01034 "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A */ 01035 "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B */ 01036 "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order */ 01037 "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx */ 01038 "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy */ 01039 ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz, /* oid/oidSz */ 01040 ECC_BRAINPOOLP320R1_OID, /* oid sum */ 01041 1, /* cofactor */ 01042 }, 01043 #endif /* HAVE_ECC_BRAINPOOL */ 01044 #endif /* ECC320 */ 01045 #ifdef ECC384 01046 #ifndef NO_ECC_SECP 01047 { 01048 48, /* size/bytes */ 01049 ECC_SECP384R1, /* ID */ 01050 "SECP384R1", /* curve name */ 01051 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime */ 01052 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A */ 01053 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B */ 01054 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order */ 01055 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx */ 01056 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy */ 01057 ecc_oid_secp384r1, ecc_oid_secp384r1_sz, /* oid/oidSz */ 01058 ECC_SECP384R1_OID, /* oid sum */ 01059 1, /* cofactor */ 01060 }, 01061 #endif /* !NO_ECC_SECP */ 01062 #ifdef HAVE_ECC_BRAINPOOL 01063 { 01064 48, /* size/bytes */ 01065 ECC_BRAINPOOLP384R1, /* ID */ 01066 "BRAINPOOLP384R1", /* curve name */ 01067 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime */ 01068 "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */ 01069 "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */ 01070 "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order */ 01071 "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx */ 01072 "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy */ 01073 ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz, /* oid/oidSz */ 01074 ECC_BRAINPOOLP384R1_OID, /* oid sum */ 01075 1, /* cofactor */ 01076 }, 01077 #endif /* HAVE_ECC_BRAINPOOL */ 01078 #endif /* ECC384 */ 01079 #ifdef ECC512 01080 #ifdef HAVE_ECC_BRAINPOOL 01081 { 01082 64, /* size/bytes */ 01083 ECC_BRAINPOOLP512R1, /* ID */ 01084 "BRAINPOOLP512R1", /* curve name */ 01085 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime */ 01086 "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */ 01087 "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */ 01088 "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order */ 01089 "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx */ 01090 "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy */ 01091 ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz, /* oid/oidSz */ 01092 ECC_BRAINPOOLP512R1_OID, /* oid sum */ 01093 1, /* cofactor */ 01094 }, 01095 #endif /* HAVE_ECC_BRAINPOOL */ 01096 #endif /* ECC512 */ 01097 #ifdef ECC521 01098 #ifndef NO_ECC_SECP 01099 { 01100 66, /* size/bytes */ 01101 ECC_SECP521R1, /* ID */ 01102 "SECP521R1", /* curve name */ 01103 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime */ 01104 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A */ 01105 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", /* B */ 01106 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order */ 01107 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", /* Gx */ 01108 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy */ 01109 ecc_oid_secp521r1, ecc_oid_secp521r1_sz, /* oid/oidSz */ 01110 ECC_SECP521R1_OID, /* oid sum */ 01111 1, /* cofactor */ 01112 }, 01113 #endif /* !NO_ECC_SECP */ 01114 #endif /* ECC521 */ 01115 #if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE) 01116 /* place holder for custom curve index for cache */ 01117 { 01118 1, /* non-zero */ 01119 ECC_CURVE_CUSTOM, 01120 #ifndef USE_WINDOWS_API 01121 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 01122 #else 01123 0, 0, 0, 0, 0, 0, 0, 0, 01124 #endif 01125 0, 0, 0 01126 }, 01127 #endif 01128 { 01129 0, -1, 01130 #ifndef USE_WINDOWS_API 01131 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 01132 #else 01133 0, 0, 0, 0, 0, 0, 0, 0, 01134 #endif 01135 0, 0, 0 01136 } 01137 }; 01138 #define ECC_SET_COUNT (sizeof(ecc_sets)/sizeof(ecc_set_type)) 01139 01140 01141 #ifdef HAVE_OID_ENCODING 01142 /* encoded OID cache */ 01143 typedef struct { 01144 word32 oidSz; 01145 byte oid[ECC_MAX_OID_LEN]; 01146 } oid_cache_t; 01147 static oid_cache_t ecc_oid_cache[ECC_SET_COUNT]; 01148 #endif 01149 01150 01151 #ifdef HAVE_COMP_KEY 01152 static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); 01153 #endif 01154 01155 #ifdef WOLFSSL_ATECC508A 01156 typedef void* ecc_curve_spec; 01157 #else 01158 01159 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH) 01160 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, 01161 mp_int* prime, mp_int* order); 01162 #endif 01163 01164 int mp_jacobi(mp_int* a, mp_int* n, int* c); 01165 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); 01166 01167 01168 /* Curve Specs */ 01169 typedef struct ecc_curve_spec { 01170 const ecc_set_type* dp; 01171 01172 mp_int* prime; 01173 mp_int* Af; 01174 #ifdef USE_ECC_B_PARAM 01175 mp_int* Bf; 01176 #endif 01177 mp_int* order; 01178 mp_int* Gx; 01179 mp_int* Gy; 01180 01181 #ifdef ECC_CACHE_CURVE 01182 mp_int prime_lcl; 01183 mp_int Af_lcl; 01184 #ifdef USE_ECC_B_PARAM 01185 mp_int Bf_lcl; 01186 #endif 01187 mp_int order_lcl; 01188 mp_int Gx_lcl; 01189 mp_int Gy_lcl; 01190 #else 01191 mp_int* spec_ints; 01192 word32 spec_count; 01193 word32 spec_use; 01194 #endif 01195 01196 byte load_mask; 01197 } ecc_curve_spec; 01198 01199 enum ecc_curve_load_mask { 01200 ECC_CURVE_FIELD_NONE = 0x00, 01201 ECC_CURVE_FIELD_PRIME = 0x01, 01202 ECC_CURVE_FIELD_AF = 0x02, 01203 #ifdef USE_ECC_B_PARAM 01204 ECC_CURVE_FIELD_BF = 0x04, 01205 #endif 01206 ECC_CURVE_FIELD_ORDER = 0x08, 01207 ECC_CURVE_FIELD_GX = 0x10, 01208 ECC_CURVE_FIELD_GY = 0x20, 01209 #ifdef USE_ECC_B_PARAM 01210 ECC_CURVE_FIELD_ALL = 0x3F, 01211 ECC_CURVE_FIELD_COUNT = 6, 01212 #else 01213 ECC_CURVE_FIELD_ALL = 0x3B, 01214 ECC_CURVE_FIELD_COUNT = 5, 01215 #endif 01216 }; 01217 01218 #ifdef ECC_CACHE_CURVE 01219 /* cache (mp_int) of the curve parameters */ 01220 static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT]; 01221 #ifndef SINGLE_THREADED 01222 static wolfSSL_Mutex ecc_curve_cache_mutex; 01223 #endif 01224 01225 #define DECLARE_CURVE_SPECS(curve, intcount) ecc_curve_spec* curve = NULL 01226 #define ALLOC_CURVE_SPECS(intcount) 01227 #define FREE_CURVE_SPECS() 01228 #elif defined(WOLFSSL_SMALL_STACK) 01229 #define DECLARE_CURVE_SPECS(curve, intcount) \ 01230 mp_int* spec_ints = NULL; \ 01231 ecc_curve_spec curve_lcl; \ 01232 ecc_curve_spec* curve = &curve_lcl; \ 01233 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \ 01234 curve->spec_count = intcount 01235 01236 #define ALLOC_CURVE_SPECS(intcount) \ 01237 spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \ 01238 DYNAMIC_TYPE_ECC); \ 01239 if (spec_ints == NULL) \ 01240 return MEMORY_E; \ 01241 curve->spec_ints = spec_ints 01242 #define FREE_CURVE_SPECS() \ 01243 XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC) 01244 #else 01245 #define DECLARE_CURVE_SPECS(curve, intcount) \ 01246 mp_int spec_ints[(intcount)]; \ 01247 ecc_curve_spec curve_lcl; \ 01248 ecc_curve_spec* curve = &curve_lcl; \ 01249 XMEMSET(curve, 0, sizeof(ecc_curve_spec)); \ 01250 curve->spec_ints = spec_ints; \ 01251 curve->spec_count = intcount 01252 #define ALLOC_CURVE_SPECS(intcount) 01253 #define FREE_CURVE_SPECS() 01254 #endif /* ECC_CACHE_CURVE */ 01255 01256 static void _wc_ecc_curve_free(ecc_curve_spec* curve) 01257 { 01258 if (curve == NULL) { 01259 return; 01260 } 01261 01262 if (curve->load_mask & ECC_CURVE_FIELD_PRIME) 01263 mp_clear(curve->prime); 01264 if (curve->load_mask & ECC_CURVE_FIELD_AF) 01265 mp_clear(curve->Af); 01266 #ifdef USE_ECC_B_PARAM 01267 if (curve->load_mask & ECC_CURVE_FIELD_BF) 01268 mp_clear(curve->Bf); 01269 #endif 01270 if (curve->load_mask & ECC_CURVE_FIELD_ORDER) 01271 mp_clear(curve->order); 01272 if (curve->load_mask & ECC_CURVE_FIELD_GX) 01273 mp_clear(curve->Gx); 01274 if (curve->load_mask & ECC_CURVE_FIELD_GY) 01275 mp_clear(curve->Gy); 01276 01277 curve->load_mask = 0; 01278 } 01279 01280 static void wc_ecc_curve_free(ecc_curve_spec* curve) 01281 { 01282 /* don't free cached curves */ 01283 #ifndef ECC_CACHE_CURVE 01284 _wc_ecc_curve_free(curve); 01285 #endif 01286 (void)curve; 01287 } 01288 01289 static int wc_ecc_curve_load_item(const char* src, mp_int** dst, 01290 ecc_curve_spec* curve, byte mask) 01291 { 01292 int err; 01293 01294 #ifndef ECC_CACHE_CURVE 01295 /* get mp_int from temp */ 01296 if (curve->spec_use >= curve->spec_count) { 01297 WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count"); 01298 return ECC_BAD_ARG_E; 01299 } 01300 *dst = &curve->spec_ints[curve->spec_use++]; 01301 #endif 01302 01303 err = mp_init(*dst); 01304 if (err == MP_OKAY) { 01305 curve->load_mask |= mask; 01306 01307 err = mp_read_radix(*dst, src, MP_RADIX_HEX); 01308 01309 #ifdef HAVE_WOLF_BIGINT 01310 if (err == MP_OKAY) 01311 err = wc_mp_to_bigint(*dst, &(*dst)->raw); 01312 #endif 01313 } 01314 return err; 01315 } 01316 01317 static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve, 01318 byte load_mask) 01319 { 01320 int ret = 0, x; 01321 ecc_curve_spec* curve; 01322 byte load_items = 0; /* mask of items to load */ 01323 01324 if (dp == NULL || pCurve == NULL) 01325 return BAD_FUNC_ARG; 01326 01327 #ifdef ECC_CACHE_CURVE 01328 x = wc_ecc_get_curve_idx(dp->id); 01329 if (x == ECC_CURVE_INVALID) 01330 return ECC_BAD_ARG_E; 01331 01332 #if !defined(SINGLE_THREADED) 01333 ret = wc_LockMutex(&ecc_curve_cache_mutex); 01334 if (ret != 0) { 01335 return ret; 01336 } 01337 #endif 01338 01339 /* make sure cache has been allocated */ 01340 if (ecc_curve_spec_cache[x] == NULL) { 01341 ecc_curve_spec_cache[x] = (ecc_curve_spec*)XMALLOC( 01342 sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC); 01343 if (ecc_curve_spec_cache[x] == NULL) { 01344 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01345 wc_UnLockMutex(&ecc_curve_cache_mutex); 01346 #endif 01347 return MEMORY_E; 01348 } 01349 XMEMSET(ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec)); 01350 } 01351 01352 /* set curve pointer to cache */ 01353 *pCurve = ecc_curve_spec_cache[x]; 01354 01355 #endif /* ECC_CACHE_CURVE */ 01356 curve = *pCurve; 01357 01358 /* make sure the curve is initialized */ 01359 if (curve->dp != dp) { 01360 curve->load_mask = 0; 01361 01362 #ifdef ECC_CACHE_CURVE 01363 curve->prime = &curve->prime_lcl; 01364 curve->Af = &curve->Af_lcl; 01365 #ifdef USE_ECC_B_PARAM 01366 curve->Bf = &curve->Bf_lcl; 01367 #endif 01368 curve->order = &curve->order_lcl; 01369 curve->Gx = &curve->Gx_lcl; 01370 curve->Gy = &curve->Gy_lcl; 01371 #endif 01372 } 01373 curve->dp = dp; /* set dp info */ 01374 01375 /* determine items to load */ 01376 load_items = (((byte)~(word32)curve->load_mask) & load_mask); 01377 curve->load_mask |= load_items; 01378 01379 /* load items */ 01380 x = 0; 01381 if (load_items & ECC_CURVE_FIELD_PRIME) 01382 x += wc_ecc_curve_load_item(dp->prime, &curve->prime, curve, 01383 ECC_CURVE_FIELD_PRIME); 01384 if (load_items & ECC_CURVE_FIELD_AF) 01385 x += wc_ecc_curve_load_item(dp->Af, &curve->Af, curve, 01386 ECC_CURVE_FIELD_AF); 01387 #ifdef USE_ECC_B_PARAM 01388 if (load_items & ECC_CURVE_FIELD_BF) 01389 x += wc_ecc_curve_load_item(dp->Bf, &curve->Bf, curve, 01390 ECC_CURVE_FIELD_BF); 01391 #endif 01392 if (load_items & ECC_CURVE_FIELD_ORDER) 01393 x += wc_ecc_curve_load_item(dp->order, &curve->order, curve, 01394 ECC_CURVE_FIELD_ORDER); 01395 if (load_items & ECC_CURVE_FIELD_GX) 01396 x += wc_ecc_curve_load_item(dp->Gx, &curve->Gx, curve, 01397 ECC_CURVE_FIELD_GX); 01398 if (load_items & ECC_CURVE_FIELD_GY) 01399 x += wc_ecc_curve_load_item(dp->Gy, &curve->Gy, curve, 01400 ECC_CURVE_FIELD_GY); 01401 01402 /* check for error */ 01403 if (x != 0) { 01404 wc_ecc_curve_free(curve); 01405 ret = MP_READ_E; 01406 } 01407 01408 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01409 wc_UnLockMutex(&ecc_curve_cache_mutex); 01410 #endif 01411 01412 return ret; 01413 } 01414 01415 #ifdef ECC_CACHE_CURVE 01416 int wc_ecc_curve_cache_init(void) 01417 { 01418 int ret = 0; 01419 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01420 ret = wc_InitMutex(&ecc_curve_cache_mutex); 01421 #endif 01422 return ret; 01423 } 01424 01425 void wc_ecc_curve_cache_free(void) 01426 { 01427 int x; 01428 01429 /* free all ECC curve caches */ 01430 for (x = 0; x < (int)ECC_SET_COUNT; x++) { 01431 if (ecc_curve_spec_cache[x]) { 01432 _wc_ecc_curve_free(ecc_curve_spec_cache[x]); 01433 XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC); 01434 ecc_curve_spec_cache[x] = NULL; 01435 } 01436 } 01437 01438 #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) 01439 wc_FreeMutex(&ecc_curve_cache_mutex); 01440 #endif 01441 } 01442 #endif /* ECC_CACHE_CURVE */ 01443 01444 #endif /* WOLFSSL_ATECC508A */ 01445 01446 01447 /* Retrieve the curve name for the ECC curve id. 01448 * 01449 * curve_id The id of the curve. 01450 * returns the name stored from the curve if available, otherwise NULL. 01451 */ 01452 const char* wc_ecc_get_name(int curve_id) 01453 { 01454 int curve_idx = wc_ecc_get_curve_idx(curve_id); 01455 if (curve_idx == ECC_CURVE_INVALID) 01456 return NULL; 01457 return ecc_sets[curve_idx].name; 01458 } 01459 01460 int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) 01461 { 01462 if (keysize <= 0 && curve_id < 0) { 01463 return BAD_FUNC_ARG; 01464 } 01465 01466 if (keysize > ECC_MAXSIZE) { 01467 return ECC_BAD_ARG_E; 01468 } 01469 01470 /* handle custom case */ 01471 if (key->idx != ECC_CUSTOM_IDX) { 01472 int x; 01473 01474 /* default values */ 01475 key->idx = 0; 01476 key->dp = NULL; 01477 01478 /* find ecc_set based on curve_id or key size */ 01479 for (x = 0; ecc_sets[x].size != 0; x++) { 01480 if (curve_id > ECC_CURVE_DEF) { 01481 if (curve_id == ecc_sets[x].id) 01482 break; 01483 } 01484 else if (keysize <= ecc_sets[x].size) { 01485 break; 01486 } 01487 } 01488 if (ecc_sets[x].size == 0) { 01489 WOLFSSL_MSG("ECC Curve not found"); 01490 return ECC_CURVE_OID_E; 01491 } 01492 01493 key->idx = x; 01494 key->dp = &ecc_sets[x]; 01495 } 01496 01497 return 0; 01498 } 01499 01500 01501 #ifdef ALT_ECC_SIZE 01502 static void alt_fp_init(fp_int* a) 01503 { 01504 a->size = FP_SIZE_ECC; 01505 fp_zero(a); 01506 } 01507 #endif /* ALT_ECC_SIZE */ 01508 01509 01510 #ifndef WOLFSSL_ATECC508A 01511 01512 #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL) 01513 01514 /** 01515 Add two ECC points 01516 P The point to add 01517 Q The point to add 01518 R [out] The destination of the double 01519 a ECC curve parameter a 01520 modulus The modulus of the field the ECC curve is in 01521 mp The "b" value from montgomery_setup() 01522 return MP_OKAY on success 01523 */ 01524 int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, 01525 mp_int* a, mp_int* modulus, mp_digit mp) 01526 { 01527 #ifndef WOLFSSL_SP_MATH 01528 #ifdef WOLFSSL_SMALL_STACK 01529 mp_int* t1 = NULL; 01530 mp_int* t2 = NULL; 01531 #ifdef ALT_ECC_SIZE 01532 mp_int* rx = NULL; 01533 mp_int* ry = NULL; 01534 mp_int* rz = NULL; 01535 #endif 01536 #else 01537 mp_int t1[1], t2[1]; 01538 #ifdef ALT_ECC_SIZE 01539 mp_int rx[1], ry[1], rz[1]; 01540 #endif 01541 #endif 01542 mp_int *x, *y, *z; 01543 int err; 01544 01545 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) { 01546 return ECC_BAD_ARG_E; 01547 } 01548 01549 /* if Q == R then swap P and Q, so we don't require a local x,y,z */ 01550 if (Q == R) { 01551 ecc_point* tPt = P; 01552 P = Q; 01553 Q = tPt; 01554 } 01555 01556 #ifdef WOLFSSL_SMALL_STACK 01557 #ifdef WOLFSSL_SMALL_STACK_CACHE 01558 if (R->key != NULL) { 01559 t1 = R->key->t1; 01560 t2 = R->key->t2; 01561 #ifdef ALT_ECC_SIZE 01562 rx = R->key->x; 01563 ry = R->key->y; 01564 rz = R->key->z; 01565 #endif 01566 } 01567 else 01568 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 01569 { 01570 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01571 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01572 if (t1 == NULL || t2 == NULL) { 01573 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01574 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01575 return MEMORY_E; 01576 } 01577 #ifdef ALT_ECC_SIZE 01578 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01579 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01580 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01581 if (rx == NULL || ry == NULL || rz == NULL) { 01582 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01583 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01584 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01585 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01586 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01587 return MEMORY_E; 01588 } 01589 #endif 01590 } 01591 #endif /* WOLFSSL_SMALL_STACK */ 01592 01593 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01594 #ifdef WOLFSSL_SMALL_STACK 01595 #ifdef WOLFSSL_SMALL_STACK_CACHE 01596 if (R->key == NULL) 01597 #endif 01598 { 01599 #ifdef ALT_ECC_SIZE 01600 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01601 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01602 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01603 #endif 01604 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01605 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01606 } 01607 #endif 01608 return err; 01609 } 01610 01611 /* should we dbl instead? */ 01612 if (err == MP_OKAY) 01613 err = mp_sub(modulus, Q->y, t1); 01614 if (err == MP_OKAY) { 01615 if ( (mp_cmp(P->x, Q->x) == MP_EQ) && 01616 (get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) && 01617 (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) { 01618 mp_clear(t1); 01619 mp_clear(t2); 01620 #ifdef WOLFSSL_SMALL_STACK 01621 #ifdef WOLFSSL_SMALL_STACK_CACHE 01622 if (R->key == NULL) 01623 #endif 01624 { 01625 #ifdef ALT_ECC_SIZE 01626 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01627 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01628 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01629 #endif 01630 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01631 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01632 } 01633 #endif 01634 return ecc_projective_dbl_point(P, R, a, modulus, mp); 01635 } 01636 } 01637 01638 if (err != MP_OKAY) { 01639 goto done; 01640 } 01641 01642 /* If use ALT_ECC_SIZE we need to use local stack variable since 01643 ecc_point x,y,z is reduced size */ 01644 #ifdef ALT_ECC_SIZE 01645 /* Use local stack variable */ 01646 x = rx; 01647 y = ry; 01648 z = rz; 01649 01650 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 01651 goto done; 01652 } 01653 #else 01654 /* Use destination directly */ 01655 x = R->x; 01656 y = R->y; 01657 z = R->z; 01658 #endif 01659 01660 if (err == MP_OKAY) 01661 err = mp_copy(P->x, x); 01662 if (err == MP_OKAY) 01663 err = mp_copy(P->y, y); 01664 if (err == MP_OKAY) 01665 err = mp_copy(P->z, z); 01666 01667 /* if Z is one then these are no-operations */ 01668 if (err == MP_OKAY) { 01669 if (!mp_iszero(Q->z)) { 01670 /* T1 = Z' * Z' */ 01671 err = mp_sqr(Q->z, t1); 01672 if (err == MP_OKAY) 01673 err = mp_montgomery_reduce(t1, modulus, mp); 01674 01675 /* X = X * T1 */ 01676 if (err == MP_OKAY) 01677 err = mp_mul(t1, x, x); 01678 if (err == MP_OKAY) 01679 err = mp_montgomery_reduce(x, modulus, mp); 01680 01681 /* T1 = Z' * T1 */ 01682 if (err == MP_OKAY) 01683 err = mp_mul(Q->z, t1, t1); 01684 if (err == MP_OKAY) 01685 err = mp_montgomery_reduce(t1, modulus, mp); 01686 01687 /* Y = Y * T1 */ 01688 if (err == MP_OKAY) 01689 err = mp_mul(t1, y, y); 01690 if (err == MP_OKAY) 01691 err = mp_montgomery_reduce(y, modulus, mp); 01692 } 01693 } 01694 01695 /* T1 = Z*Z */ 01696 if (err == MP_OKAY) 01697 err = mp_sqr(z, t1); 01698 if (err == MP_OKAY) 01699 err = mp_montgomery_reduce(t1, modulus, mp); 01700 01701 /* T2 = X' * T1 */ 01702 if (err == MP_OKAY) 01703 err = mp_mul(Q->x, t1, t2); 01704 if (err == MP_OKAY) 01705 err = mp_montgomery_reduce(t2, modulus, mp); 01706 01707 /* T1 = Z * T1 */ 01708 if (err == MP_OKAY) 01709 err = mp_mul(z, t1, t1); 01710 if (err == MP_OKAY) 01711 err = mp_montgomery_reduce(t1, modulus, mp); 01712 01713 /* T1 = Y' * T1 */ 01714 if (err == MP_OKAY) 01715 err = mp_mul(Q->y, t1, t1); 01716 if (err == MP_OKAY) 01717 err = mp_montgomery_reduce(t1, modulus, mp); 01718 01719 /* Y = Y - T1 */ 01720 if (err == MP_OKAY) 01721 err = mp_sub(y, t1, y); 01722 if (err == MP_OKAY) { 01723 if (mp_isneg(y)) 01724 err = mp_add(y, modulus, y); 01725 } 01726 /* T1 = 2T1 */ 01727 if (err == MP_OKAY) 01728 err = mp_add(t1, t1, t1); 01729 if (err == MP_OKAY) { 01730 if (mp_cmp(t1, modulus) != MP_LT) 01731 err = mp_sub(t1, modulus, t1); 01732 } 01733 /* T1 = Y + T1 */ 01734 if (err == MP_OKAY) 01735 err = mp_add(t1, y, t1); 01736 if (err == MP_OKAY) { 01737 if (mp_cmp(t1, modulus) != MP_LT) 01738 err = mp_sub(t1, modulus, t1); 01739 } 01740 /* X = X - T2 */ 01741 if (err == MP_OKAY) 01742 err = mp_sub(x, t2, x); 01743 if (err == MP_OKAY) { 01744 if (mp_isneg(x)) 01745 err = mp_add(x, modulus, x); 01746 } 01747 /* T2 = 2T2 */ 01748 if (err == MP_OKAY) 01749 err = mp_add(t2, t2, t2); 01750 if (err == MP_OKAY) { 01751 if (mp_cmp(t2, modulus) != MP_LT) 01752 err = mp_sub(t2, modulus, t2); 01753 } 01754 /* T2 = X + T2 */ 01755 if (err == MP_OKAY) 01756 err = mp_add(t2, x, t2); 01757 if (err == MP_OKAY) { 01758 if (mp_cmp(t2, modulus) != MP_LT) 01759 err = mp_sub(t2, modulus, t2); 01760 } 01761 01762 if (err == MP_OKAY) { 01763 if (!mp_iszero(Q->z)) { 01764 /* Z = Z * Z' */ 01765 err = mp_mul(z, Q->z, z); 01766 if (err == MP_OKAY) 01767 err = mp_montgomery_reduce(z, modulus, mp); 01768 } 01769 } 01770 01771 /* Z = Z * X */ 01772 if (err == MP_OKAY) 01773 err = mp_mul(z, x, z); 01774 if (err == MP_OKAY) 01775 err = mp_montgomery_reduce(z, modulus, mp); 01776 01777 /* T1 = T1 * X */ 01778 if (err == MP_OKAY) 01779 err = mp_mul(t1, x, t1); 01780 if (err == MP_OKAY) 01781 err = mp_montgomery_reduce(t1, modulus, mp); 01782 01783 /* X = X * X */ 01784 if (err == MP_OKAY) 01785 err = mp_sqr(x, x); 01786 if (err == MP_OKAY) 01787 err = mp_montgomery_reduce(x, modulus, mp); 01788 01789 /* T2 = T2 * x */ 01790 if (err == MP_OKAY) 01791 err = mp_mul(t2, x, t2); 01792 if (err == MP_OKAY) 01793 err = mp_montgomery_reduce(t2, modulus, mp); 01794 01795 /* T1 = T1 * X */ 01796 if (err == MP_OKAY) 01797 err = mp_mul(t1, x, t1); 01798 if (err == MP_OKAY) 01799 err = mp_montgomery_reduce(t1, modulus, mp); 01800 01801 /* X = Y*Y */ 01802 if (err == MP_OKAY) 01803 err = mp_sqr(y, x); 01804 if (err == MP_OKAY) 01805 err = mp_montgomery_reduce(x, modulus, mp); 01806 01807 /* X = X - T2 */ 01808 if (err == MP_OKAY) 01809 err = mp_sub(x, t2, x); 01810 if (err == MP_OKAY) { 01811 if (mp_isneg(x)) 01812 err = mp_add(x, modulus, x); 01813 } 01814 /* T2 = T2 - X */ 01815 if (err == MP_OKAY) 01816 err = mp_sub(t2, x, t2); 01817 if (err == MP_OKAY) { 01818 if (mp_isneg(t2)) 01819 err = mp_add(t2, modulus, t2); 01820 } 01821 /* T2 = T2 - X */ 01822 if (err == MP_OKAY) 01823 err = mp_sub(t2, x, t2); 01824 if (err == MP_OKAY) { 01825 if (mp_isneg(t2)) 01826 err = mp_add(t2, modulus, t2); 01827 } 01828 /* T2 = T2 * Y */ 01829 if (err == MP_OKAY) 01830 err = mp_mul(t2, y, t2); 01831 if (err == MP_OKAY) 01832 err = mp_montgomery_reduce(t2, modulus, mp); 01833 01834 /* Y = T2 - T1 */ 01835 if (err == MP_OKAY) 01836 err = mp_sub(t2, t1, y); 01837 if (err == MP_OKAY) { 01838 if (mp_isneg(y)) 01839 err = mp_add(y, modulus, y); 01840 } 01841 /* Y = Y/2 */ 01842 if (err == MP_OKAY) { 01843 if (mp_isodd(y) == MP_YES) 01844 err = mp_add(y, modulus, y); 01845 } 01846 if (err == MP_OKAY) 01847 err = mp_div_2(y, y); 01848 01849 #ifdef ALT_ECC_SIZE 01850 if (err == MP_OKAY) 01851 err = mp_copy(x, R->x); 01852 if (err == MP_OKAY) 01853 err = mp_copy(y, R->y); 01854 if (err == MP_OKAY) 01855 err = mp_copy(z, R->z); 01856 #endif 01857 01858 done: 01859 01860 /* clean up */ 01861 mp_clear(t1); 01862 mp_clear(t2); 01863 #ifdef WOLFSSL_SMALL_STACK 01864 #ifdef WOLFSSL_SMALL_STACK_CACHE 01865 if (R->key == NULL) 01866 #endif 01867 { 01868 #ifdef ALT_ECC_SIZE 01869 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01870 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01871 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01872 #endif 01873 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01874 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01875 } 01876 #endif 01877 01878 return err; 01879 #else 01880 if (P == NULL || Q == NULL || R == NULL || modulus == NULL) { 01881 return ECC_BAD_ARG_E; 01882 } 01883 01884 (void)a; 01885 (void)mp; 01886 01887 return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z, 01888 R->x, R->y, R->z); 01889 #endif 01890 } 01891 01892 /* ### Point doubling in Jacobian coordinate system ### 01893 * 01894 * let us have a curve: y^2 = x^3 + a*x + b 01895 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6 01896 * 01897 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where: 01898 * Xr = M^2 - 2*S 01899 * Yr = M * (S - Xr) - 8*T 01900 * Zr = 2 * Yp * Zp 01901 * 01902 * M = 3 * Xp^2 + a*Zp^4 01903 * T = Yp^4 01904 * S = 4 * Xp * Yp^2 01905 * 01906 * SPECIAL CASE: when a == 3 we can compute M as 01907 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2) 01908 */ 01909 01910 /** 01911 Double an ECC point 01912 P The point to double 01913 R [out] The destination of the double 01914 a ECC curve parameter a 01915 modulus The modulus of the field the ECC curve is in 01916 mp The "b" value from montgomery_setup() 01917 return MP_OKAY on success 01918 */ 01919 int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, 01920 mp_int* modulus, mp_digit mp) 01921 { 01922 #ifndef WOLFSSL_SP_MATH 01923 #ifdef WOLFSSL_SMALL_STACK 01924 mp_int* t1 = NULL; 01925 mp_int* t2 = NULL; 01926 #ifdef ALT_ECC_SIZE 01927 mp_int* rx = NULL; 01928 mp_int* ry = NULL; 01929 mp_int* rz = NULL; 01930 #endif 01931 #else 01932 mp_int t1[1], t2[1]; 01933 #ifdef ALT_ECC_SIZE 01934 mp_int rx[1], ry[1], rz[1]; 01935 #endif 01936 #endif 01937 mp_int *x, *y, *z; 01938 int err; 01939 01940 if (P == NULL || R == NULL || modulus == NULL) 01941 return ECC_BAD_ARG_E; 01942 01943 #ifdef WOLFSSL_SMALL_STACK 01944 #ifdef WOLFSSL_SMALL_STACK_CACHE 01945 if (R->key != NULL) { 01946 t1 = R->key->t1; 01947 t2 = R->key->t2; 01948 #ifdef ALT_ECC_SIZE 01949 rx = R->key->x; 01950 ry = R->key->y; 01951 rz = R->key->z; 01952 #endif 01953 } 01954 else 01955 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 01956 { 01957 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01958 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01959 if (t1 == NULL || t2 == NULL) { 01960 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01961 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01962 return MEMORY_E; 01963 } 01964 #ifdef ALT_ECC_SIZE 01965 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01966 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01967 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 01968 if (rx == NULL || ry == NULL || rz == NULL) { 01969 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01970 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01971 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01972 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01973 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01974 return MEMORY_E; 01975 } 01976 #endif 01977 } 01978 #endif 01979 01980 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 01981 #ifdef WOLFSSL_SMALL_STACK 01982 #ifdef WOLFSSL_SMALL_STACK_CACHE 01983 if (R->key == NULL) 01984 #endif 01985 { 01986 #ifdef ALT_ECC_SIZE 01987 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 01988 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 01989 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 01990 #endif 01991 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 01992 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 01993 } 01994 #endif 01995 return err; 01996 } 01997 01998 /* If use ALT_ECC_SIZE we need to use local stack variable since 01999 ecc_point x,y,z is reduced size */ 02000 #ifdef ALT_ECC_SIZE 02001 /* Use local stack variable */ 02002 x = rx; 02003 y = ry; 02004 z = rz; 02005 02006 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 02007 mp_clear(t1); 02008 mp_clear(t2); 02009 #ifdef WOLFSSL_SMALL_STACK 02010 #ifdef WOLFSSL_SMALL_STACK_CACHE 02011 if (R->key == NULL) 02012 #endif 02013 { 02014 #ifdef ALT_ECC_SIZE 02015 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 02016 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 02017 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 02018 #endif 02019 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02020 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02021 } 02022 #endif 02023 return err; 02024 } 02025 #else 02026 /* Use destination directly */ 02027 x = R->x; 02028 y = R->y; 02029 z = R->z; 02030 #endif 02031 02032 if (err == MP_OKAY) 02033 err = mp_copy(P->x, x); 02034 if (err == MP_OKAY) 02035 err = mp_copy(P->y, y); 02036 if (err == MP_OKAY) 02037 err = mp_copy(P->z, z); 02038 02039 /* T1 = Z * Z */ 02040 if (err == MP_OKAY) 02041 err = mp_sqr(z, t1); 02042 if (err == MP_OKAY) 02043 err = mp_montgomery_reduce(t1, modulus, mp); 02044 02045 /* Z = Y * Z */ 02046 if (err == MP_OKAY) 02047 err = mp_mul(z, y, z); 02048 if (err == MP_OKAY) 02049 err = mp_montgomery_reduce(z, modulus, mp); 02050 02051 /* Z = 2Z */ 02052 if (err == MP_OKAY) 02053 err = mp_add(z, z, z); 02054 if (err == MP_OKAY) { 02055 if (mp_cmp(z, modulus) != MP_LT) 02056 err = mp_sub(z, modulus, z); 02057 } 02058 02059 /* Determine if curve "a" should be used in calc */ 02060 #ifdef WOLFSSL_CUSTOM_CURVES 02061 if (err == MP_OKAY) { 02062 /* Use a and prime to determine if a == 3 */ 02063 err = mp_submod(modulus, a, modulus, t2); 02064 } 02065 if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) { 02066 /* use "a" in calc */ 02067 02068 /* T2 = T1 * T1 */ 02069 if (err == MP_OKAY) 02070 err = mp_sqr(t1, t2); 02071 if (err == MP_OKAY) 02072 err = mp_montgomery_reduce(t2, modulus, mp); 02073 /* T1 = T2 * a */ 02074 if (err == MP_OKAY) 02075 err = mp_mulmod(t2, a, modulus, t1); 02076 /* T2 = X * X */ 02077 if (err == MP_OKAY) 02078 err = mp_sqr(x, t2); 02079 if (err == MP_OKAY) 02080 err = mp_montgomery_reduce(t2, modulus, mp); 02081 /* T1 = T2 + T1 */ 02082 if (err == MP_OKAY) 02083 err = mp_add(t1, t2, t1); 02084 if (err == MP_OKAY) { 02085 if (mp_cmp(t1, modulus) != MP_LT) 02086 err = mp_sub(t1, modulus, t1); 02087 } 02088 /* T1 = T2 + T1 */ 02089 if (err == MP_OKAY) 02090 err = mp_add(t1, t2, t1); 02091 if (err == MP_OKAY) { 02092 if (mp_cmp(t1, modulus) != MP_LT) 02093 err = mp_sub(t1, modulus, t1); 02094 } 02095 /* T1 = T2 + T1 */ 02096 if (err == MP_OKAY) 02097 err = mp_add(t1, t2, t1); 02098 if (err == MP_OKAY) { 02099 if (mp_cmp(t1, modulus) != MP_LT) 02100 err = mp_sub(t1, modulus, t1); 02101 } 02102 } 02103 else 02104 #endif /* WOLFSSL_CUSTOM_CURVES */ 02105 { 02106 /* assumes "a" == 3 */ 02107 (void)a; 02108 02109 /* T2 = X - T1 */ 02110 if (err == MP_OKAY) 02111 err = mp_sub(x, t1, t2); 02112 if (err == MP_OKAY) { 02113 if (mp_isneg(t2)) 02114 err = mp_add(t2, modulus, t2); 02115 } 02116 /* T1 = X + T1 */ 02117 if (err == MP_OKAY) 02118 err = mp_add(t1, x, t1); 02119 if (err == MP_OKAY) { 02120 if (mp_cmp(t1, modulus) != MP_LT) 02121 err = mp_sub(t1, modulus, t1); 02122 } 02123 /* T2 = T1 * T2 */ 02124 if (err == MP_OKAY) 02125 err = mp_mul(t1, t2, t2); 02126 if (err == MP_OKAY) 02127 err = mp_montgomery_reduce(t2, modulus, mp); 02128 02129 /* T1 = 2T2 */ 02130 if (err == MP_OKAY) 02131 err = mp_add(t2, t2, t1); 02132 if (err == MP_OKAY) { 02133 if (mp_cmp(t1, modulus) != MP_LT) 02134 err = mp_sub(t1, modulus, t1); 02135 } 02136 /* T1 = T1 + T2 */ 02137 if (err == MP_OKAY) 02138 err = mp_add(t1, t2, t1); 02139 if (err == MP_OKAY) { 02140 if (mp_cmp(t1, modulus) != MP_LT) 02141 err = mp_sub(t1, modulus, t1); 02142 } 02143 } 02144 02145 /* Y = 2Y */ 02146 if (err == MP_OKAY) 02147 err = mp_add(y, y, y); 02148 if (err == MP_OKAY) { 02149 if (mp_cmp(y, modulus) != MP_LT) 02150 err = mp_sub(y, modulus, y); 02151 } 02152 /* Y = Y * Y */ 02153 if (err == MP_OKAY) 02154 err = mp_sqr(y, y); 02155 if (err == MP_OKAY) 02156 err = mp_montgomery_reduce(y, modulus, mp); 02157 02158 /* T2 = Y * Y */ 02159 if (err == MP_OKAY) 02160 err = mp_sqr(y, t2); 02161 if (err == MP_OKAY) 02162 err = mp_montgomery_reduce(t2, modulus, mp); 02163 02164 /* T2 = T2/2 */ 02165 if (err == MP_OKAY) { 02166 if (mp_isodd(t2) == MP_YES) 02167 err = mp_add(t2, modulus, t2); 02168 } 02169 if (err == MP_OKAY) 02170 err = mp_div_2(t2, t2); 02171 02172 /* Y = Y * X */ 02173 if (err == MP_OKAY) 02174 err = mp_mul(y, x, y); 02175 if (err == MP_OKAY) 02176 err = mp_montgomery_reduce(y, modulus, mp); 02177 02178 /* X = T1 * T1 */ 02179 if (err == MP_OKAY) 02180 err = mp_sqr(t1, x); 02181 if (err == MP_OKAY) 02182 err = mp_montgomery_reduce(x, modulus, mp); 02183 02184 /* X = X - Y */ 02185 if (err == MP_OKAY) 02186 err = mp_sub(x, y, x); 02187 if (err == MP_OKAY) { 02188 if (mp_isneg(x)) 02189 err = mp_add(x, modulus, x); 02190 } 02191 /* X = X - Y */ 02192 if (err == MP_OKAY) 02193 err = mp_sub(x, y, x); 02194 if (err == MP_OKAY) { 02195 if (mp_isneg(x)) 02196 err = mp_add(x, modulus, x); 02197 } 02198 02199 /* Y = Y - X */ 02200 if (err == MP_OKAY) 02201 err = mp_sub(y, x, y); 02202 if (err == MP_OKAY) { 02203 if (mp_isneg(y)) 02204 err = mp_add(y, modulus, y); 02205 } 02206 /* Y = Y * T1 */ 02207 if (err == MP_OKAY) 02208 err = mp_mul(y, t1, y); 02209 if (err == MP_OKAY) 02210 err = mp_montgomery_reduce(y, modulus, mp); 02211 02212 /* Y = Y - T2 */ 02213 if (err == MP_OKAY) 02214 err = mp_sub(y, t2, y); 02215 if (err == MP_OKAY) { 02216 if (mp_isneg(y)) 02217 err = mp_add(y, modulus, y); 02218 } 02219 02220 #ifdef ALT_ECC_SIZE 02221 if (err == MP_OKAY) 02222 err = mp_copy(x, R->x); 02223 if (err == MP_OKAY) 02224 err = mp_copy(y, R->y); 02225 if (err == MP_OKAY) 02226 err = mp_copy(z, R->z); 02227 #endif 02228 02229 /* clean up */ 02230 mp_clear(t1); 02231 mp_clear(t2); 02232 02233 #ifdef WOLFSSL_SMALL_STACK 02234 #ifdef WOLFSSL_SMALL_STACK_CACHE 02235 if (R->key == NULL) 02236 #endif 02237 { 02238 #ifdef ALT_ECC_SIZE 02239 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 02240 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 02241 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 02242 #endif 02243 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02244 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02245 } 02246 #endif 02247 02248 return err; 02249 #else 02250 if (P == NULL || R == NULL || modulus == NULL) 02251 return ECC_BAD_ARG_E; 02252 02253 (void)a; 02254 (void)mp; 02255 02256 return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z); 02257 #endif 02258 } 02259 02260 02261 /** 02262 Map a projective jacbobian point back to affine space 02263 P [in/out] The point to map 02264 modulus The modulus of the field the ECC curve is in 02265 mp The "b" value from montgomery_setup() 02266 return MP_OKAY on success 02267 */ 02268 int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) 02269 { 02270 #ifndef WOLFSSL_SP_MATH 02271 #ifdef WOLFSSL_SMALL_STACK 02272 mp_int* t1 = NULL; 02273 mp_int* t2 = NULL; 02274 #ifdef ALT_ECC_SIZE 02275 mp_int* rx = NULL; 02276 mp_int* ry = NULL; 02277 mp_int* rz = NULL; 02278 #endif 02279 #else 02280 mp_int t1[1], t2[1]; 02281 #ifdef ALT_ECC_SIZE 02282 mp_int rx[1], ry[1], rz[1]; 02283 #endif 02284 #endif /* WOLFSSL_SMALL_STACK */ 02285 mp_int *x, *y, *z; 02286 int err; 02287 02288 if (P == NULL || modulus == NULL) 02289 return ECC_BAD_ARG_E; 02290 02291 /* special case for point at infinity */ 02292 if (mp_cmp_d(P->z, 0) == MP_EQ) { 02293 err = mp_set(P->x, 0); 02294 if (err == MP_OKAY) 02295 err = mp_set(P->y, 0); 02296 if (err == MP_OKAY) 02297 err = mp_set(P->z, 1); 02298 return err; 02299 } 02300 02301 #ifdef WOLFSSL_SMALL_STACK 02302 #ifdef WOLFSSL_SMALL_STACK_CACHE 02303 if (P->key != NULL) { 02304 t1 = P->key->t1; 02305 t2 = P->key->t2; 02306 #ifdef ALT_ECC_SIZE 02307 rx = P->key->x; 02308 ry = P->key->y; 02309 rz = P->key->z; 02310 #endif 02311 } 02312 else 02313 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02314 { 02315 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 02316 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 02317 if (t1 == NULL || t2 == NULL) { 02318 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02319 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02320 return MEMORY_E; 02321 } 02322 #ifdef ALT_ECC_SIZE 02323 rx = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 02324 ry = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 02325 rz = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 02326 if (rx == NULL || ry == NULL || rz == NULL) { 02327 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 02328 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 02329 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 02330 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02331 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02332 return MEMORY_E; 02333 } 02334 #endif 02335 } 02336 #endif /* WOLFSSL_SMALL_STACK */ 02337 02338 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 02339 #ifdef WOLFSSL_SMALL_STACK 02340 #ifdef WOLFSSL_SMALL_STACK_CACHE 02341 if (P->key == NULL) 02342 #endif 02343 { 02344 #ifdef ALT_ECC_SIZE 02345 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 02346 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 02347 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 02348 #endif 02349 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02350 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02351 } 02352 #endif 02353 return MEMORY_E; 02354 } 02355 02356 #ifdef ALT_ECC_SIZE 02357 /* Use local stack variable */ 02358 x = rx; 02359 y = ry; 02360 z = rz; 02361 02362 if ((err = mp_init_multi(x, y, z, NULL, NULL, NULL)) != MP_OKAY) { 02363 goto done; 02364 } 02365 02366 if (err == MP_OKAY) 02367 err = mp_copy(P->x, x); 02368 if (err == MP_OKAY) 02369 err = mp_copy(P->y, y); 02370 if (err == MP_OKAY) 02371 err = mp_copy(P->z, z); 02372 02373 if (err != MP_OKAY) { 02374 goto done; 02375 } 02376 #else 02377 /* Use destination directly */ 02378 x = P->x; 02379 y = P->y; 02380 z = P->z; 02381 #endif 02382 02383 /* first map z back to normal */ 02384 err = mp_montgomery_reduce(z, modulus, mp); 02385 02386 /* get 1/z */ 02387 if (err == MP_OKAY) 02388 err = mp_invmod(z, modulus, t1); 02389 02390 /* get 1/z^2 and 1/z^3 */ 02391 if (err == MP_OKAY) 02392 err = mp_sqr(t1, t2); 02393 if (err == MP_OKAY) 02394 err = mp_mod(t2, modulus, t2); 02395 if (err == MP_OKAY) 02396 err = mp_mul(t1, t2, t1); 02397 if (err == MP_OKAY) 02398 err = mp_mod(t1, modulus, t1); 02399 02400 /* multiply against x/y */ 02401 if (err == MP_OKAY) 02402 err = mp_mul(x, t2, x); 02403 if (err == MP_OKAY) 02404 err = mp_montgomery_reduce(x, modulus, mp); 02405 if (err == MP_OKAY) 02406 err = mp_mul(y, t1, y); 02407 if (err == MP_OKAY) 02408 err = mp_montgomery_reduce(y, modulus, mp); 02409 02410 if (err == MP_OKAY) 02411 err = mp_set(z, 1); 02412 02413 #ifdef ALT_ECC_SIZE 02414 /* return result */ 02415 if (err == MP_OKAY) 02416 err = mp_copy(x, P->x); 02417 if (err == MP_OKAY) 02418 err = mp_copy(y, P->y); 02419 if (err == MP_OKAY) 02420 err = mp_copy(z, P->z); 02421 02422 done: 02423 #endif 02424 02425 /* clean up */ 02426 mp_clear(t1); 02427 mp_clear(t2); 02428 02429 #ifdef WOLFSSL_SMALL_STACK 02430 #ifdef WOLFSSL_SMALL_STACK_CACHE 02431 if (P->key == NULL) 02432 #endif 02433 { 02434 #ifdef ALT_ECC_SIZE 02435 XFREE(rz, NULL, DYNAMIC_TYPE_ECC); 02436 XFREE(ry, NULL, DYNAMIC_TYPE_ECC); 02437 XFREE(rx, NULL, DYNAMIC_TYPE_ECC); 02438 #endif 02439 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 02440 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 02441 } 02442 #endif 02443 02444 return err; 02445 #else 02446 if (P == NULL || modulus == NULL) 02447 return ECC_BAD_ARG_E; 02448 02449 (void)mp; 02450 02451 return sp_ecc_map_256(P->x, P->y, P->z); 02452 #endif 02453 } 02454 02455 #endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */ 02456 02457 #if !defined(FREESCALE_LTC_ECC) 02458 02459 #if !defined(FP_ECC) || !defined(WOLFSSL_SP_MATH) 02460 /** 02461 Perform a point multiplication 02462 k The scalar to multiply by 02463 G The base point 02464 R [out] Destination for kG 02465 a ECC curve parameter a 02466 modulus The modulus of the field the ECC curve is in 02467 map Boolean whether to map back to affine or not 02468 (1==map, 0 == leave in projective) 02469 return MP_OKAY on success 02470 */ 02471 #ifdef FP_ECC 02472 static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, 02473 mp_int* a, mp_int* modulus, int map, 02474 void* heap) 02475 #else 02476 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, 02477 mp_int* a, mp_int* modulus, int map, 02478 void* heap) 02479 #endif 02480 { 02481 #ifndef WOLFSSL_SP_MATH 02482 #ifndef ECC_TIMING_RESISTANT 02483 /* size of sliding window, don't change this! */ 02484 #define WINSIZE 4 02485 #define M_POINTS 8 02486 int first = 1, bitbuf = 0, bitcpy = 0, j; 02487 #else 02488 #define M_POINTS 3 02489 #endif 02490 02491 ecc_point *tG, *M[M_POINTS]; 02492 int i, err; 02493 #ifdef WOLFSSL_SMALL_STACK 02494 mp_int* mu = NULL; 02495 #ifdef WOLFSSL_SMALL_STACK_CACHE 02496 ecc_key key; 02497 #endif 02498 #else 02499 mp_int mu[1]; 02500 #endif 02501 mp_digit mp; 02502 mp_digit buf; 02503 int bitcnt = 0, mode = 0, digidx = 0; 02504 02505 if (k == NULL || G == NULL || R == NULL || modulus == NULL) { 02506 return ECC_BAD_ARG_E; 02507 } 02508 02509 /* init variables */ 02510 tG = NULL; 02511 XMEMSET(M, 0, sizeof(M)); 02512 #ifdef WOLFSSL_SMALL_STACK 02513 mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02514 if (mu == NULL) 02515 return MEMORY_E; 02516 #endif 02517 #ifdef WOLFSSL_SMALL_STACK_CACHE 02518 key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02519 key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02520 #ifdef ALT_ECC_SIZE 02521 key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02522 key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02523 key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 02524 #endif 02525 if (key.t1 == NULL || key.t2 == NULL 02526 #ifdef ALT_ECC_SIZE 02527 || key.x == NULL || key.y == NULL || key.z == NULL 02528 #endif 02529 ) { 02530 #ifdef ALT_ECC_SIZE 02531 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 02532 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 02533 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 02534 #endif 02535 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 02536 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 02537 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 02538 return MEMORY_E; 02539 } 02540 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02541 02542 /* init montgomery reduction */ 02543 if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { 02544 #ifdef WOLFSSL_SMALL_STACK_CACHE 02545 #ifdef ALT_ECC_SIZE 02546 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 02547 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 02548 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 02549 #endif 02550 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 02551 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 02552 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02553 #ifdef WOLFSSL_SMALL_STACK 02554 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 02555 #endif 02556 return err; 02557 } 02558 02559 if ((err = mp_init(mu)) != MP_OKAY) { 02560 #ifdef WOLFSSL_SMALL_STACK_CACHE 02561 #ifdef ALT_ECC_SIZE 02562 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 02563 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 02564 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 02565 #endif 02566 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 02567 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 02568 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02569 #ifdef WOLFSSL_SMALL_STACK 02570 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 02571 #endif 02572 return err; 02573 } 02574 if ((err = mp_montgomery_calc_normalization(mu, modulus)) != MP_OKAY) { 02575 mp_clear(mu); 02576 #ifdef WOLFSSL_SMALL_STACK_CACHE 02577 #ifdef ALT_ECC_SIZE 02578 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 02579 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 02580 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 02581 #endif 02582 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 02583 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 02584 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02585 #ifdef WOLFSSL_SMALL_STACK 02586 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 02587 #endif 02588 return err; 02589 } 02590 02591 /* alloc ram for window temps */ 02592 for (i = 0; i < M_POINTS; i++) { 02593 M[i] = wc_ecc_new_point_h(heap); 02594 if (M[i] == NULL) { 02595 mp_clear(mu); 02596 err = MEMORY_E; goto exit; 02597 } 02598 #ifdef WOLFSSL_SMALL_STACK_CACHE 02599 M[i]->key = &key; 02600 #endif 02601 } 02602 02603 /* make a copy of G in case R==G */ 02604 tG = wc_ecc_new_point_h(heap); 02605 if (tG == NULL) 02606 err = MEMORY_E; 02607 02608 /* tG = G and convert to montgomery */ 02609 if (err == MP_OKAY) { 02610 if (mp_cmp_d(mu, 1) == MP_EQ) { 02611 err = mp_copy(G->x, tG->x); 02612 if (err == MP_OKAY) 02613 err = mp_copy(G->y, tG->y); 02614 if (err == MP_OKAY) 02615 err = mp_copy(G->z, tG->z); 02616 } else { 02617 err = mp_mulmod(G->x, mu, modulus, tG->x); 02618 if (err == MP_OKAY) 02619 err = mp_mulmod(G->y, mu, modulus, tG->y); 02620 if (err == MP_OKAY) 02621 err = mp_mulmod(G->z, mu, modulus, tG->z); 02622 } 02623 } 02624 02625 /* done with mu */ 02626 mp_clear(mu); 02627 02628 #ifdef WOLFSSL_SMALL_STACK_CACHE 02629 R->key = &key; 02630 #endif 02631 #ifndef ECC_TIMING_RESISTANT 02632 02633 /* calc the M tab, which holds kG for k==8..15 */ 02634 /* M[0] == 8G */ 02635 if (err == MP_OKAY) 02636 err = ecc_projective_dbl_point(tG, M[0], a, modulus, mp); 02637 if (err == MP_OKAY) 02638 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); 02639 if (err == MP_OKAY) 02640 err = ecc_projective_dbl_point(M[0], M[0], a, modulus, mp); 02641 02642 /* now find (8+k)G for k=1..7 */ 02643 if (err == MP_OKAY) 02644 for (j = 9; j < 16; j++) { 02645 err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, 02646 modulus, mp); 02647 if (err != MP_OKAY) break; 02648 } 02649 02650 /* setup sliding window */ 02651 if (err == MP_OKAY) { 02652 mode = 0; 02653 bitcnt = 1; 02654 buf = 0; 02655 digidx = get_digit_count(k) - 1; 02656 bitcpy = bitbuf = 0; 02657 first = 1; 02658 02659 /* perform ops */ 02660 for (;;) { 02661 /* grab next digit as required */ 02662 if (--bitcnt == 0) { 02663 if (digidx == -1) { 02664 break; 02665 } 02666 buf = get_digit(k, digidx); 02667 bitcnt = (int) DIGIT_BIT; 02668 --digidx; 02669 } 02670 02671 /* grab the next msb from the ltiplicand */ 02672 i = (int)(buf >> (DIGIT_BIT - 1)) & 1; 02673 buf <<= 1; 02674 02675 /* skip leading zero bits */ 02676 if (mode == 0 && i == 0) 02677 continue; 02678 02679 /* if the bit is zero and mode == 1 then we double */ 02680 if (mode == 1 && i == 0) { 02681 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02682 if (err != MP_OKAY) break; 02683 continue; 02684 } 02685 02686 /* else we add it to the window */ 02687 bitbuf |= (i << (WINSIZE - ++bitcpy)); 02688 mode = 2; 02689 02690 if (bitcpy == WINSIZE) { 02691 /* if this is the first window we do a simple copy */ 02692 if (first == 1) { 02693 /* R = kG [k = first window] */ 02694 err = mp_copy(M[bitbuf-M_POINTS]->x, R->x); 02695 if (err != MP_OKAY) break; 02696 02697 err = mp_copy(M[bitbuf-M_POINTS]->y, R->y); 02698 if (err != MP_OKAY) break; 02699 02700 err = mp_copy(M[bitbuf-M_POINTS]->z, R->z); 02701 first = 0; 02702 } else { 02703 /* normal window */ 02704 /* ok window is filled so double as required and add */ 02705 /* double first */ 02706 for (j = 0; j < WINSIZE; j++) { 02707 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02708 if (err != MP_OKAY) break; 02709 } 02710 if (err != MP_OKAY) break; /* out of first for(;;) */ 02711 02712 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ 02713 err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a, 02714 modulus, mp); 02715 } 02716 if (err != MP_OKAY) break; 02717 /* empty window and reset */ 02718 bitcpy = bitbuf = 0; 02719 mode = 1; 02720 } 02721 } 02722 } 02723 02724 /* if bits remain then double/add */ 02725 if (err == MP_OKAY) { 02726 if (mode == 2 && bitcpy > 0) { 02727 /* double then add */ 02728 for (j = 0; j < bitcpy; j++) { 02729 /* only double if we have had at least one add first */ 02730 if (first == 0) { 02731 err = ecc_projective_dbl_point(R, R, a, modulus, mp); 02732 if (err != MP_OKAY) break; 02733 } 02734 02735 bitbuf <<= 1; 02736 if ((bitbuf & (1 << WINSIZE)) != 0) { 02737 if (first == 1) { 02738 /* first add, so copy */ 02739 err = mp_copy(tG->x, R->x); 02740 if (err != MP_OKAY) break; 02741 02742 err = mp_copy(tG->y, R->y); 02743 if (err != MP_OKAY) break; 02744 02745 err = mp_copy(tG->z, R->z); 02746 if (err != MP_OKAY) break; 02747 first = 0; 02748 } else { 02749 /* then add */ 02750 err = ecc_projective_add_point(R, tG, R, a, modulus, 02751 mp); 02752 if (err != MP_OKAY) break; 02753 } 02754 } 02755 } 02756 } 02757 } 02758 02759 #undef WINSIZE 02760 02761 #else /* ECC_TIMING_RESISTANT */ 02762 02763 /* calc the M tab */ 02764 /* M[0] == G */ 02765 if (err == MP_OKAY) 02766 err = mp_copy(tG->x, M[0]->x); 02767 if (err == MP_OKAY) 02768 err = mp_copy(tG->y, M[0]->y); 02769 if (err == MP_OKAY) 02770 err = mp_copy(tG->z, M[0]->z); 02771 02772 /* M[1] == 2G */ 02773 if (err == MP_OKAY) 02774 err = ecc_projective_dbl_point(tG, M[1], a, modulus, mp); 02775 02776 /* setup sliding window */ 02777 mode = 0; 02778 bitcnt = 1; 02779 buf = 0; 02780 digidx = get_digit_count(k) - 1; 02781 02782 /* perform ops */ 02783 if (err == MP_OKAY) { 02784 for (;;) { 02785 /* grab next digit as required */ 02786 if (--bitcnt == 0) { 02787 if (digidx == -1) { 02788 break; 02789 } 02790 buf = get_digit(k, digidx); 02791 bitcnt = (int)DIGIT_BIT; 02792 --digidx; 02793 } 02794 02795 /* grab the next msb from the multiplicand */ 02796 i = (buf >> (DIGIT_BIT - 1)) & 1; 02797 buf <<= 1; 02798 02799 if (mode == 0 && i == 0) { 02800 /* timing resistant - dummy operations */ 02801 if (err == MP_OKAY) 02802 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, 02803 mp); 02804 if (err == MP_OKAY) 02805 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp); 02806 if (err == MP_OKAY) 02807 continue; 02808 } 02809 02810 if (mode == 0 && i == 1) { 02811 mode = 1; 02812 /* timing resistant - dummy operations */ 02813 if (err == MP_OKAY) 02814 err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus, 02815 mp); 02816 if (err == MP_OKAY) 02817 err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp); 02818 if (err == MP_OKAY) 02819 continue; 02820 } 02821 02822 if (err == MP_OKAY) 02823 err = ecc_projective_add_point(M[0], M[1], M[i^1], a, modulus, 02824 mp); 02825 #ifdef WC_NO_CACHE_RESISTANT 02826 if (err == MP_OKAY) 02827 err = ecc_projective_dbl_point(M[i], M[i], a, modulus, mp); 02828 #else 02829 /* instead of using M[i] for double, which leaks key bit to cache 02830 * monitor, use M[2] as temp, make sure address calc is constant, 02831 * keep M[0] and M[1] in cache */ 02832 if (err == MP_OKAY) 02833 err = mp_copy((mp_int*) 02834 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) + 02835 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])), 02836 M[2]->x); 02837 if (err == MP_OKAY) 02838 err = mp_copy((mp_int*) 02839 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) + 02840 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])), 02841 M[2]->y); 02842 if (err == MP_OKAY) 02843 err = mp_copy((mp_int*) 02844 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) + 02845 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])), 02846 M[2]->z); 02847 if (err == MP_OKAY) 02848 err = ecc_projective_dbl_point(M[2], M[2], a, modulus, mp); 02849 /* copy M[2] back to M[i] */ 02850 if (err == MP_OKAY) 02851 err = mp_copy(M[2]->x, 02852 (mp_int*) 02853 ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) + 02854 ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) ); 02855 if (err == MP_OKAY) 02856 err = mp_copy(M[2]->y, 02857 (mp_int*) 02858 ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) + 02859 ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) ); 02860 if (err == MP_OKAY) 02861 err = mp_copy(M[2]->z, 02862 (mp_int*) 02863 ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) + 02864 ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) ); 02865 if (err != MP_OKAY) 02866 break; 02867 #endif /* WC_NO_CACHE_RESISTANT */ 02868 } /* end for */ 02869 } 02870 02871 /* copy result out */ 02872 if (err == MP_OKAY) 02873 err = mp_copy(M[0]->x, R->x); 02874 if (err == MP_OKAY) 02875 err = mp_copy(M[0]->y, R->y); 02876 if (err == MP_OKAY) 02877 err = mp_copy(M[0]->z, R->z); 02878 02879 #endif /* ECC_TIMING_RESISTANT */ 02880 02881 /* map R back from projective space */ 02882 if (err == MP_OKAY && map) 02883 err = ecc_map(R, modulus, mp); 02884 02885 exit: 02886 02887 /* done */ 02888 wc_ecc_del_point_h(tG, heap); 02889 for (i = 0; i < M_POINTS; i++) { 02890 wc_ecc_del_point_h(M[i], heap); 02891 } 02892 #ifdef WOLFSSL_SMALL_STACK_CACHE 02893 R->key = NULL; 02894 #ifdef ALT_ECC_SIZE 02895 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 02896 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 02897 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 02898 #endif 02899 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 02900 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 02901 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 02902 #ifdef WOLFSSL_SMALL_STACK 02903 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 02904 #endif 02905 02906 return err; 02907 #else 02908 if (k == NULL || G == NULL || R == NULL || modulus == NULL) { 02909 return ECC_BAD_ARG_E; 02910 } 02911 02912 (void)a; 02913 02914 return sp_ecc_mulmod_256(k, G, R, map, heap); 02915 #endif 02916 } 02917 02918 #endif /* !FP_ECC || !WOLFSSL_SP_MATH */ 02919 02920 #endif /* !FREESCALE_LTC_ECC */ 02921 02922 /** ECC Fixed Point mulmod global 02923 k The multiplicand 02924 G Base point to multiply 02925 R [out] Destination of product 02926 a ECC curve parameter a 02927 modulus The modulus for the curve 02928 map [boolean] If non-zero maps the point back to affine co-ordinates, 02929 otherwise it's left in jacobian-montgomery form 02930 return MP_OKAY if successful 02931 */ 02932 int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, 02933 mp_int* modulus, int map) 02934 { 02935 return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL); 02936 } 02937 02938 #endif /* !WOLFSSL_ATECC508A */ 02939 02940 /** 02941 * use a heap hint when creating new ecc_point 02942 * return an allocated point on success or NULL on failure 02943 */ 02944 ecc_point* wc_ecc_new_point_h(void* heap) 02945 { 02946 ecc_point* p; 02947 02948 (void)heap; 02949 02950 p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC); 02951 if (p == NULL) { 02952 return NULL; 02953 } 02954 XMEMSET(p, 0, sizeof(ecc_point)); 02955 02956 #ifndef ALT_ECC_SIZE 02957 if (mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL) != MP_OKAY) { 02958 XFREE(p, heap, DYNAMIC_TYPE_ECC); 02959 return NULL; 02960 } 02961 #else 02962 p->x = (mp_int*)&p->xyz[0]; 02963 p->y = (mp_int*)&p->xyz[1]; 02964 p->z = (mp_int*)&p->xyz[2]; 02965 alt_fp_init(p->x); 02966 alt_fp_init(p->y); 02967 alt_fp_init(p->z); 02968 #endif 02969 02970 return p; 02971 } 02972 02973 02974 /** 02975 Allocate a new ECC point 02976 return A newly allocated point or NULL on error 02977 */ 02978 ecc_point* wc_ecc_new_point(void) 02979 { 02980 return wc_ecc_new_point_h(NULL); 02981 } 02982 02983 02984 void wc_ecc_del_point_h(ecc_point* p, void* heap) 02985 { 02986 /* prevents free'ing null arguments */ 02987 if (p != NULL) { 02988 mp_clear(p->x); 02989 mp_clear(p->y); 02990 mp_clear(p->z); 02991 XFREE(p, heap, DYNAMIC_TYPE_ECC); 02992 } 02993 (void)heap; 02994 } 02995 02996 02997 /** Free an ECC point from memory 02998 p The point to free 02999 */ 03000 void wc_ecc_del_point(ecc_point* p) 03001 { 03002 wc_ecc_del_point_h(p, NULL); 03003 } 03004 03005 03006 /** Copy the value of a point to an other one 03007 p The point to copy 03008 r The created point 03009 */ 03010 int wc_ecc_copy_point(ecc_point* p, ecc_point *r) 03011 { 03012 int ret; 03013 03014 /* prevents null arguments */ 03015 if (p == NULL || r == NULL) 03016 return ECC_BAD_ARG_E; 03017 03018 ret = mp_copy(p->x, r->x); 03019 if (ret != MP_OKAY) 03020 return ret; 03021 ret = mp_copy(p->y, r->y); 03022 if (ret != MP_OKAY) 03023 return ret; 03024 ret = mp_copy(p->z, r->z); 03025 if (ret != MP_OKAY) 03026 return ret; 03027 03028 return MP_OKAY; 03029 } 03030 03031 /** Compare the value of a point with an other one 03032 a The point to compare 03033 b The other point to compare 03034 03035 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error 03036 */ 03037 int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) 03038 { 03039 int ret; 03040 03041 /* prevents null arguments */ 03042 if (a == NULL || b == NULL) 03043 return BAD_FUNC_ARG; 03044 03045 ret = mp_cmp(a->x, b->x); 03046 if (ret != MP_EQ) 03047 return ret; 03048 ret = mp_cmp(a->y, b->y); 03049 if (ret != MP_EQ) 03050 return ret; 03051 ret = mp_cmp(a->z, b->z); 03052 if (ret != MP_EQ) 03053 return ret; 03054 03055 return MP_EQ; 03056 } 03057 03058 03059 /** Returns whether an ECC idx is valid or not 03060 n The idx number to check 03061 return 1 if valid, 0 if not 03062 */ 03063 int wc_ecc_is_valid_idx(int n) 03064 { 03065 int x; 03066 03067 for (x = 0; ecc_sets[x].size != 0; x++) 03068 ; 03069 /* -1 is a valid index --- indicating that the domain params 03070 were supplied by the user */ 03071 if ((n >= ECC_CUSTOM_IDX) && (n < x)) { 03072 return 1; 03073 } 03074 03075 return 0; 03076 } 03077 03078 int wc_ecc_get_curve_idx(int curve_id) 03079 { 03080 int curve_idx; 03081 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { 03082 if (curve_id == ecc_sets[curve_idx].id) 03083 break; 03084 } 03085 if (ecc_sets[curve_idx].size == 0) { 03086 return ECC_CURVE_INVALID; 03087 } 03088 return curve_idx; 03089 } 03090 03091 int wc_ecc_get_curve_id(int curve_idx) 03092 { 03093 if (wc_ecc_is_valid_idx(curve_idx)) { 03094 return ecc_sets[curve_idx].id; 03095 } 03096 return ECC_CURVE_INVALID; 03097 } 03098 03099 /* Returns the curve size that corresponds to a given ecc_curve_id identifier 03100 * 03101 * id curve id, from ecc_curve_id enum in ecc.h 03102 * return curve size, from ecc_sets[] on success, negative on error 03103 */ 03104 int wc_ecc_get_curve_size_from_id(int curve_id) 03105 { 03106 int curve_idx = wc_ecc_get_curve_idx(curve_id); 03107 if (curve_idx == ECC_CURVE_INVALID) 03108 return ECC_BAD_ARG_E; 03109 return ecc_sets[curve_idx].size; 03110 } 03111 03112 /* Returns the curve index that corresponds to a given curve name in 03113 * ecc_sets[] of ecc.c 03114 * 03115 * name curve name, from ecc_sets[].name in ecc.c 03116 * return curve index in ecc_sets[] on success, negative on error 03117 */ 03118 int wc_ecc_get_curve_idx_from_name(const char* curveName) 03119 { 03120 int curve_idx; 03121 word32 len; 03122 03123 if (curveName == NULL) 03124 return BAD_FUNC_ARG; 03125 03126 len = (word32)XSTRLEN(curveName); 03127 03128 for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) { 03129 if (ecc_sets[curve_idx].name && 03130 XSTRNCASECMP(ecc_sets[curve_idx].name, curveName, len) == 0) { 03131 break; 03132 } 03133 } 03134 if (ecc_sets[curve_idx].size == 0) { 03135 WOLFSSL_MSG("ecc_set curve name not found"); 03136 return ECC_CURVE_INVALID; 03137 } 03138 return curve_idx; 03139 } 03140 03141 /* Returns the curve size that corresponds to a given curve name, 03142 * as listed in ecc_sets[] of ecc.c. 03143 * 03144 * name curve name, from ecc_sets[].name in ecc.c 03145 * return curve size, from ecc_sets[] on success, negative on error 03146 */ 03147 int wc_ecc_get_curve_size_from_name(const char* curveName) 03148 { 03149 int curve_idx; 03150 03151 if (curveName == NULL) 03152 return BAD_FUNC_ARG; 03153 03154 curve_idx = wc_ecc_get_curve_idx_from_name(curveName); 03155 if (curve_idx < 0) 03156 return curve_idx; 03157 03158 return ecc_sets[curve_idx].size; 03159 } 03160 03161 /* Returns the curve id that corresponds to a given curve name, 03162 * as listed in ecc_sets[] of ecc.c. 03163 * 03164 * name curve name, from ecc_sets[].name in ecc.c 03165 * return curve id, from ecc_sets[] on success, negative on error 03166 */ 03167 int wc_ecc_get_curve_id_from_name(const char* curveName) 03168 { 03169 int curve_idx; 03170 03171 if (curveName == NULL) 03172 return BAD_FUNC_ARG; 03173 03174 curve_idx = wc_ecc_get_curve_idx_from_name(curveName); 03175 if (curve_idx < 0) 03176 return curve_idx; 03177 03178 return ecc_sets[curve_idx].id; 03179 } 03180 03181 /* Compares a curve parameter (hex, from ecc_sets[]) to given input 03182 * parameter (byte array) for equality. 03183 * 03184 * Returns MP_EQ on success, negative on error */ 03185 static int wc_ecc_cmp_param(const char* curveParam, 03186 const byte* param, word32 paramSz) 03187 { 03188 int err = MP_OKAY; 03189 #ifdef WOLFSSL_SMALL_STACK 03190 mp_int* a = NULL; 03191 mp_int* b = NULL; 03192 #else 03193 mp_int a[1], b[1]; 03194 #endif 03195 03196 if (param == NULL || curveParam == NULL) 03197 return BAD_FUNC_ARG; 03198 03199 #ifdef WOLFSSL_SMALL_STACK 03200 a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 03201 if (a == NULL) 03202 return MEMORY_E; 03203 b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 03204 if (b == NULL) { 03205 XFREE(a, NULL, DYNAMIC_TYPE_ECC); 03206 return MEMORY_E; 03207 } 03208 #endif 03209 03210 if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) 03211 return err; 03212 03213 if (err == MP_OKAY) 03214 err = mp_read_unsigned_bin(a, param, paramSz); 03215 03216 if (err == MP_OKAY) 03217 err = mp_read_radix(b, curveParam, MP_RADIX_HEX); 03218 03219 if (err == MP_OKAY) { 03220 if (mp_cmp(a, b) != MP_EQ) { 03221 err = -1; 03222 } else { 03223 err = MP_EQ; 03224 } 03225 } 03226 03227 mp_clear(a); 03228 mp_clear(b); 03229 #ifdef WOLFSSL_SMALL_STACK 03230 XFREE(b, NULL, DYNAMIC_TYPE_ECC); 03231 XFREE(a, NULL, DYNAMIC_TYPE_ECC); 03232 #endif 03233 03234 return err; 03235 } 03236 03237 /* Returns the curve id in ecc_sets[] that corresponds to a given set of 03238 * curve parameters. 03239 * 03240 * fieldSize the field size in bits 03241 * prime prime of the finite field 03242 * primeSz size of prime in octets 03243 * Af first coefficient a of the curve 03244 * AfSz size of Af in octets 03245 * Bf second coefficient b of the curve 03246 * BfSz size of Bf in octets 03247 * order curve order 03248 * orderSz size of curve in octets 03249 * Gx affine x coordinate of base point 03250 * GxSz size of Gx in octets 03251 * Gy affine y coordinate of base point 03252 * GySz size of Gy in octets 03253 * cofactor curve cofactor 03254 * 03255 * return curve id, from ecc_sets[] on success, negative on error 03256 */ 03257 int wc_ecc_get_curve_id_from_params(int fieldSize, 03258 const byte* prime, word32 primeSz, const byte* Af, word32 AfSz, 03259 const byte* Bf, word32 BfSz, const byte* order, word32 orderSz, 03260 const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor) 03261 { 03262 int idx; 03263 int curveSz; 03264 03265 if (prime == NULL || Af == NULL || Bf == NULL || order == NULL || 03266 Gx == NULL || Gy == NULL) 03267 return BAD_FUNC_ARG; 03268 03269 curveSz = (fieldSize + 1) / 8; /* round up */ 03270 03271 for (idx = 0; ecc_sets[idx].size != 0; idx++) { 03272 if (curveSz == ecc_sets[idx].size) { 03273 if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime, 03274 primeSz) == MP_EQ) && 03275 (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz) == MP_EQ) && 03276 (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz) == MP_EQ) && 03277 (wc_ecc_cmp_param(ecc_sets[idx].order, order, 03278 orderSz) == MP_EQ) && 03279 (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz) == MP_EQ) && 03280 (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz) == MP_EQ) && 03281 (cofactor == ecc_sets[idx].cofactor)) { 03282 break; 03283 } 03284 } 03285 } 03286 03287 if (ecc_sets[idx].size == 0) 03288 return ECC_CURVE_INVALID; 03289 03290 return ecc_sets[idx].id; 03291 } 03292 03293 03294 #ifdef WOLFSSL_ASYNC_CRYPT 03295 static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp) 03296 { 03297 if (key == NULL || mp == NULL) 03298 return BAD_FUNC_ARG; 03299 if (*mp == NULL) { 03300 *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT); 03301 if (*mp == NULL) { 03302 return MEMORY_E; 03303 } 03304 XMEMSET(*mp, 0, sizeof(mp_int)); 03305 } 03306 return 0; 03307 } 03308 static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp) 03309 { 03310 if (key && mp && *mp) { 03311 mp_clear(*mp); 03312 XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT); 03313 *mp = NULL; 03314 } 03315 } 03316 03317 static int wc_ecc_alloc_async(ecc_key* key) 03318 { 03319 int err = wc_ecc_alloc_mpint(key, &key->r); 03320 if (err == 0) 03321 err = wc_ecc_alloc_mpint(key, &key->s); 03322 return err; 03323 } 03324 03325 static void wc_ecc_free_async(ecc_key* key) 03326 { 03327 wc_ecc_free_mpint(key, &key->r); 03328 wc_ecc_free_mpint(key, &key->s); 03329 #ifdef HAVE_CAVIUM_V 03330 wc_ecc_free_mpint(key, &key->e); 03331 wc_ecc_free_mpint(key, &key->signK); 03332 #endif /* HAVE_CAVIUM_V */ 03333 } 03334 #endif /* WOLFSSL_ASYNC_CRYPT */ 03335 03336 03337 #ifdef HAVE_ECC_DHE 03338 /** 03339 Create an ECC shared secret between two keys 03340 private_key The private ECC key (heap hint based off of private key) 03341 public_key The public key 03342 out [out] Destination of the shared secret 03343 Conforms to EC-DH from ANSI X9.63 03344 outlen [in/out] The max size and resulting size of the shared secret 03345 return MP_OKAY if successful 03346 */ 03347 int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, 03348 word32* outlen) 03349 { 03350 int err; 03351 03352 if (private_key == NULL || public_key == NULL || out == NULL || 03353 outlen == NULL) { 03354 return BAD_FUNC_ARG; 03355 } 03356 03357 #ifdef WOLF_CRYPTO_DEV 03358 if (private_key->devId != INVALID_DEVID) { 03359 err = wc_CryptoDev_Ecdh(private_key, public_key, out, outlen); 03360 if (err != NOT_COMPILED_IN) 03361 return err; 03362 } 03363 #endif 03364 03365 /* type valid? */ 03366 if (private_key->type != ECC_PRIVATEKEY && 03367 private_key->type != ECC_PRIVATEKEY_ONLY) { 03368 return ECC_BAD_ARG_E; 03369 } 03370 03371 /* Verify domain params supplied */ 03372 if (wc_ecc_is_valid_idx(private_key->idx) == 0 || 03373 wc_ecc_is_valid_idx(public_key->idx) == 0) { 03374 return ECC_BAD_ARG_E; 03375 } 03376 03377 /* Verify curve id matches */ 03378 if (private_key->dp->id != public_key->dp->id) { 03379 return ECC_BAD_ARG_E; 03380 } 03381 03382 #ifdef WOLFSSL_ATECC508A 03383 err = atcatls_ecdh(private_key->slot, public_key->pubkey_raw, out); 03384 if (err != ATCA_SUCCESS) { 03385 err = BAD_COND_E; 03386 } 03387 *outlen = private_key->dp->size; 03388 #else 03389 err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen); 03390 #endif /* WOLFSSL_ATECC508A */ 03391 03392 return err; 03393 } 03394 03395 03396 #ifndef WOLFSSL_ATECC508A 03397 03398 static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, 03399 byte* out, word32* outlen, ecc_curve_spec* curve) 03400 { 03401 int err; 03402 #ifndef WOLFSSL_SP_MATH 03403 ecc_point* result = NULL; 03404 word32 x = 0; 03405 #endif 03406 mp_int* k = &private_key->k; 03407 #ifdef HAVE_ECC_CDH 03408 mp_int k_lcl; 03409 03410 /* if cofactor flag has been set */ 03411 if (private_key->flags & WC_ECC_FLAG_COFACTOR) { 03412 mp_digit cofactor = (mp_digit)private_key->dp->cofactor; 03413 /* only perform cofactor calc if not equal to 1 */ 03414 if (cofactor != 1) { 03415 k = &k_lcl; 03416 if (mp_init(k) != MP_OKAY) 03417 return MEMORY_E; 03418 /* multiply cofactor times private key "k" */ 03419 err = mp_mul_d(&private_key->k, cofactor, k); 03420 if (err != MP_OKAY) { 03421 mp_clear(k); 03422 return err; 03423 } 03424 } 03425 } 03426 #endif 03427 03428 #ifdef WOLFSSL_HAVE_SP_ECC 03429 #ifndef WOLFSSL_SP_NO_256 03430 if (private_key->idx != ECC_CUSTOM_IDX && 03431 ecc_sets[private_key->idx].id == ECC_SECP256R1) { 03432 err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap); 03433 } 03434 else 03435 #endif 03436 #endif 03437 #ifdef WOLFSSL_SP_MATH 03438 { 03439 err = WC_KEY_SIZE_E; 03440 03441 (void)curve; 03442 } 03443 #else 03444 { 03445 /* make new point */ 03446 result = wc_ecc_new_point_h(private_key->heap); 03447 if (result == NULL) { 03448 #ifdef HAVE_ECC_CDH 03449 if (k == &k_lcl) 03450 mp_clear(k); 03451 #endif 03452 return MEMORY_E; 03453 } 03454 03455 err = wc_ecc_mulmod_ex(k, point, result, curve->Af, curve->prime, 1, 03456 private_key->heap); 03457 if (err == MP_OKAY) { 03458 x = mp_unsigned_bin_size(curve->prime); 03459 if (*outlen < x) { 03460 err = BUFFER_E; 03461 } 03462 } 03463 03464 if (err == MP_OKAY) { 03465 XMEMSET(out, 0, x); 03466 err = mp_to_unsigned_bin(result->x,out + 03467 (x - mp_unsigned_bin_size(result->x))); 03468 } 03469 *outlen = x; 03470 03471 wc_ecc_del_point_h(result, private_key->heap); 03472 } 03473 #endif 03474 #ifdef HAVE_ECC_CDH 03475 if (k == &k_lcl) 03476 mp_clear(k); 03477 #endif 03478 03479 return err; 03480 } 03481 03482 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03483 static int wc_ecc_shared_secret_gen_async(ecc_key* private_key, 03484 ecc_point* point, byte* out, word32 *outlen, 03485 ecc_curve_spec* curve) 03486 { 03487 int err; 03488 03489 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) 03490 #ifdef HAVE_CAVIUM_V 03491 /* verify the curve is supported by hardware */ 03492 if (NitroxEccIsCurveSupported(private_key)) 03493 #endif 03494 { 03495 word32 keySz = private_key->dp->size; 03496 03497 /* sync public key x/y */ 03498 err = wc_mp_to_bigint_sz(&private_key->k, &private_key->k.raw, keySz); 03499 if (err == MP_OKAY) 03500 err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz); 03501 if (err == MP_OKAY) 03502 err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz); 03503 #ifdef HAVE_CAVIUM_V 03504 /* allocate buffer for output */ 03505 if (err == MP_OKAY) 03506 err = wc_ecc_alloc_mpint(private_key, &private_key->e); 03507 if (err == MP_OKAY) 03508 err = wc_bigint_alloc(&private_key->e->raw, 03509 NitroxEccGetSize(private_key)*2); 03510 if (err == MP_OKAY) 03511 err = NitroxEcdh(private_key, 03512 &private_key->k.raw, &point->x->raw, &point->y->raw, 03513 private_key->e->raw.buf, &private_key->e->raw.len, 03514 &curve->prime->raw); 03515 #else 03516 if (err == MP_OKAY) 03517 err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF); 03518 if (err == MP_OKAY) 03519 err = IntelQaEcdh(&private_key->asyncDev, 03520 &private_key->k.raw, &point->x->raw, &point->y->raw, 03521 out, outlen, 03522 &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw, 03523 private_key->dp->cofactor); 03524 #endif 03525 return err; 03526 } 03527 #elif defined(WOLFSSL_ASYNC_CRYPT_TEST) 03528 if (wc_AsyncTestInit(&private_key->asyncDev, ASYNC_TEST_ECC_SHARED_SEC)) { 03529 WC_ASYNC_TEST* testDev = &private_key->asyncDev.test; 03530 testDev->eccSharedSec.private_key = private_key; 03531 testDev->eccSharedSec.public_point = point; 03532 testDev->eccSharedSec.out = out; 03533 testDev->eccSharedSec.outLen = outlen; 03534 return WC_PENDING_E; 03535 } 03536 #endif 03537 03538 /* use sync in other cases */ 03539 err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen, curve); 03540 03541 return err; 03542 } 03543 #endif /* WOLFSSL_ASYNC_CRYPT */ 03544 03545 int wc_ecc_shared_secret_gen(ecc_key* private_key, ecc_point* point, 03546 byte* out, word32 *outlen) 03547 { 03548 int err; 03549 DECLARE_CURVE_SPECS(curve, 2); 03550 03551 if (private_key == NULL || point == NULL || out == NULL || 03552 outlen == NULL) { 03553 return BAD_FUNC_ARG; 03554 } 03555 03556 ALLOC_CURVE_SPECS(2); 03557 03558 /* load curve info */ 03559 err = wc_ecc_curve_load(private_key->dp, &curve, 03560 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); 03561 if (err != MP_OKAY) { 03562 FREE_CURVE_SPECS(); 03563 return err; 03564 } 03565 03566 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03567 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03568 err = wc_ecc_shared_secret_gen_async(private_key, point, 03569 out, outlen, curve); 03570 } 03571 else 03572 #endif 03573 { 03574 err = wc_ecc_shared_secret_gen_sync(private_key, point, 03575 out, outlen, curve); 03576 } 03577 03578 wc_ecc_curve_free(curve); 03579 FREE_CURVE_SPECS(); 03580 03581 return err; 03582 } 03583 03584 /** 03585 Create an ECC shared secret between private key and public point 03586 private_key The private ECC key (heap hint based on private key) 03587 point The point to use (public key) 03588 out [out] Destination of the shared secret 03589 Conforms to EC-DH from ANSI X9.63 03590 outlen [in/out] The max size and resulting size of the shared secret 03591 return MP_OKAY if successful 03592 */ 03593 int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, 03594 byte* out, word32 *outlen) 03595 { 03596 int err; 03597 03598 if (private_key == NULL || point == NULL || out == NULL || 03599 outlen == NULL) { 03600 return BAD_FUNC_ARG; 03601 } 03602 03603 /* type valid? */ 03604 if (private_key->type != ECC_PRIVATEKEY && 03605 private_key->type != ECC_PRIVATEKEY_ONLY) { 03606 return ECC_BAD_ARG_E; 03607 } 03608 03609 /* Verify domain params supplied */ 03610 if (wc_ecc_is_valid_idx(private_key->idx) == 0) 03611 return ECC_BAD_ARG_E; 03612 03613 switch(private_key->state) { 03614 case ECC_STATE_NONE: 03615 case ECC_STATE_SHARED_SEC_GEN: 03616 private_key->state = ECC_STATE_SHARED_SEC_GEN; 03617 03618 err = wc_ecc_shared_secret_gen(private_key, point, out, outlen); 03619 if (err < 0) { 03620 break; 03621 } 03622 FALL_THROUGH; 03623 03624 case ECC_STATE_SHARED_SEC_RES: 03625 private_key->state = ECC_STATE_SHARED_SEC_RES; 03626 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03627 if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03628 #ifdef HAVE_CAVIUM_V 03629 /* verify the curve is supported by hardware */ 03630 if (NitroxEccIsCurveSupported(private_key)) { 03631 /* copy output */ 03632 *outlen = private_key->dp->size; 03633 XMEMCPY(out, private_key->e->raw.buf, *outlen); 03634 } 03635 #endif /* HAVE_CAVIUM_V */ 03636 } 03637 #endif /* WOLFSSL_ASYNC_CRYPT */ 03638 err = 0; 03639 break; 03640 03641 default: 03642 err = BAD_STATE_E; 03643 } /* switch */ 03644 03645 /* if async pending then return and skip done cleanup below */ 03646 if (err == WC_PENDING_E) { 03647 private_key->state++; 03648 return err; 03649 } 03650 03651 /* cleanup */ 03652 #ifdef WOLFSSL_ASYNC_CRYPT 03653 wc_ecc_free_async(private_key); 03654 #endif 03655 private_key->state = ECC_STATE_NONE; 03656 03657 return err; 03658 } 03659 #endif /* !WOLFSSL_ATECC508A */ 03660 #endif /* HAVE_ECC_DHE */ 03661 03662 03663 #ifndef WOLFSSL_ATECC508A 03664 /* return 1 if point is at infinity, 0 if not, < 0 on error */ 03665 int wc_ecc_point_is_at_infinity(ecc_point* p) 03666 { 03667 if (p == NULL) 03668 return BAD_FUNC_ARG; 03669 03670 if (get_digit_count(p->x) == 0 && get_digit_count(p->y) == 0) 03671 return 1; 03672 03673 return 0; 03674 } 03675 03676 #ifndef WOLFSSL_SP_MATH 03677 /* generate random and ensure its greater than 0 and less than order */ 03678 static int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order) 03679 { 03680 int err; 03681 DECLARE_VAR(buf, byte, ECC_MAXSIZE_GEN, rng->heap); 03682 03683 /*generate 8 extra bytes to mitigate bias from the modulo operation below*/ 03684 /*see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)'*/ 03685 size += 8; 03686 03687 /* make up random string */ 03688 err = wc_RNG_GenerateBlock(rng, buf, size); 03689 03690 /* load random buffer data into k */ 03691 if (err == 0) 03692 err = mp_read_unsigned_bin(k, (byte*)buf, size); 03693 03694 /* the key should be smaller than the order of base point */ 03695 if (err == MP_OKAY) { 03696 if (mp_cmp(k, order) != MP_LT) { 03697 err = mp_mod(k, order, k); 03698 } 03699 } 03700 03701 /* quick sanity check to make sure we're not dealing with a 0 key */ 03702 if (err == MP_OKAY) { 03703 if (mp_iszero(k) == MP_YES) 03704 err = MP_ZERO_E; 03705 } 03706 03707 ForceZero(buf, ECC_MAXSIZE); 03708 FREE_VAR(buf, rng->heap); 03709 03710 return err; 03711 } 03712 #endif 03713 #endif /* !WOLFSSL_ATECC508A */ 03714 03715 static WC_INLINE void wc_ecc_reset(ecc_key* key) 03716 { 03717 /* make sure required key variables are reset */ 03718 key->state = ECC_STATE_NONE; 03719 } 03720 03721 03722 /* create the public ECC key from a private key 03723 * 03724 * key an initialized private key to generate public part from 03725 * curveIn [in]curve for key, can be NULL 03726 * pubOut [out]ecc_point holding the public key, if NULL then public key part 03727 * is cached in key instead. 03728 * 03729 * Note this function is local to the file because of the argument type 03730 * ecc_curve_spec. Having this argument allows for not having to load the 03731 * curve type multiple times when generating a key with wc_ecc_make_key(). 03732 * 03733 * returns MP_OKAY on success 03734 */ 03735 static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, 03736 ecc_point* pubOut) 03737 { 03738 int err = MP_OKAY; 03739 #ifndef WOLFSSL_ATECC508A 03740 #ifndef WOLFSSL_SP_MATH 03741 ecc_point* base = NULL; 03742 #endif 03743 ecc_point* pub; 03744 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); 03745 #endif 03746 03747 if (key == NULL) { 03748 return BAD_FUNC_ARG; 03749 } 03750 03751 #ifndef WOLFSSL_ATECC508A 03752 03753 /* if ecc_point passed in then use it as output for public key point */ 03754 if (pubOut != NULL) { 03755 pub = pubOut; 03756 } 03757 else { 03758 /* caching public key making it a ECC_PRIVATEKEY instead of 03759 ECC_PRIVATEKEY_ONLY */ 03760 pub = &key->pubkey; 03761 key->type = ECC_PRIVATEKEY_ONLY; 03762 } 03763 03764 /* avoid loading the curve unless it is not passed in */ 03765 if (curveIn != NULL) { 03766 curve = curveIn; 03767 } 03768 else { 03769 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); 03770 03771 /* load curve info */ 03772 if (err == MP_OKAY) 03773 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 03774 } 03775 03776 if (err == MP_OKAY) { 03777 #ifndef ALT_ECC_SIZE 03778 err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL); 03779 #else 03780 pub->x = (mp_int*)&pub->xyz[0]; 03781 pub->y = (mp_int*)&pub->xyz[1]; 03782 pub->z = (mp_int*)&pub->xyz[2]; 03783 alt_fp_init(pub->x); 03784 alt_fp_init(pub->y); 03785 alt_fp_init(pub->z); 03786 #endif 03787 } 03788 03789 03790 #ifdef WOLFSSL_HAVE_SP_ECC 03791 #ifndef WOLFSSL_SP_NO_256 03792 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { 03793 if (err == MP_OKAY) 03794 err = sp_ecc_mulmod_base_256(&key->k, pub, 1, key->heap); 03795 } 03796 else 03797 #endif 03798 #endif 03799 #ifdef WOLFSSL_SP_MATH 03800 err = WC_KEY_SIZE_E; 03801 #else 03802 { 03803 if (err == MP_OKAY) { 03804 base = wc_ecc_new_point_h(key->heap); 03805 if (base == NULL) 03806 err = MEMORY_E; 03807 } 03808 /* read in the x/y for this key */ 03809 if (err == MP_OKAY) 03810 err = mp_copy(curve->Gx, base->x); 03811 if (err == MP_OKAY) 03812 err = mp_copy(curve->Gy, base->y); 03813 if (err == MP_OKAY) 03814 err = mp_set(base->z, 1); 03815 03816 /* make the public key */ 03817 if (err == MP_OKAY) { 03818 err = wc_ecc_mulmod_ex(&key->k, base, pub, curve->Af, curve->prime, 03819 1, key->heap); 03820 } 03821 03822 wc_ecc_del_point_h(base, key->heap); 03823 } 03824 #endif 03825 03826 #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN 03827 /* validate the public key, order * pubkey = point at infinity */ 03828 if (err == MP_OKAY) 03829 err = ecc_check_pubkey_order(key, pub, curve->Af, curve->prime, 03830 curve->order); 03831 #endif /* WOLFSSL_VALIDATE_KEYGEN */ 03832 03833 if (err != MP_OKAY) { 03834 /* clean up if failed */ 03835 #ifndef ALT_ECC_SIZE 03836 mp_clear(pub->x); 03837 mp_clear(pub->y); 03838 mp_clear(pub->z); 03839 #endif 03840 } 03841 03842 /* free up local curve */ 03843 if (curveIn == NULL) { 03844 wc_ecc_curve_free(curve); 03845 #ifndef WOLFSSL_ATECC508A 03846 FREE_CURVE_SPECS(); 03847 #endif 03848 } 03849 03850 #else 03851 (void)curveIn; 03852 #endif /* WOLFSSL_ATECC508A */ 03853 03854 /* change key state if public part is cached */ 03855 if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) { 03856 key->type = ECC_PRIVATEKEY; 03857 } 03858 03859 return err; 03860 } 03861 03862 03863 /* create the public ECC key from a private key 03864 * 03865 * key an initialized private key to generate public part from 03866 * pubOut [out]ecc_point holding the public key, if NULL then public key part 03867 * is cached in key instead. 03868 * 03869 * 03870 * returns MP_OKAY on success 03871 */ 03872 int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut) 03873 { 03874 WOLFSSL_ENTER("wc_ecc_make_pub"); 03875 03876 return wc_ecc_make_pub_ex(key, NULL, pubOut); 03877 } 03878 03879 03880 int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) 03881 { 03882 int err; 03883 #ifndef WOLFSSL_ATECC508A 03884 #ifndef WOLFSSL_SP_MATH 03885 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); 03886 #endif 03887 #endif 03888 03889 if (key == NULL || rng == NULL) { 03890 return BAD_FUNC_ARG; 03891 } 03892 03893 /* make sure required variables are reset */ 03894 wc_ecc_reset(key); 03895 03896 err = wc_ecc_set_curve(key, keysize, curve_id); 03897 if (err != 0) { 03898 return err; 03899 } 03900 03901 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 03902 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 03903 #ifdef HAVE_CAVIUM 03904 /* TODO: Not implemented */ 03905 #elif defined(HAVE_INTEL_QA) 03906 /* TODO: Not implemented */ 03907 #else 03908 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_MAKE)) { 03909 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 03910 testDev->eccMake.rng = rng; 03911 testDev->eccMake.key = key; 03912 testDev->eccMake.size = keysize; 03913 testDev->eccMake.curve_id = curve_id; 03914 return WC_PENDING_E; 03915 } 03916 #endif 03917 } 03918 #endif /* WOLFSSL_ASYNC_CRYPT */ 03919 03920 #ifdef WOLFSSL_ATECC508A 03921 key->type = ECC_PRIVATEKEY; 03922 err = atcatls_create_key(key->slot, key->pubkey_raw); 03923 if (err != ATCA_SUCCESS) { 03924 err = BAD_COND_E; 03925 } 03926 03927 /* populate key->pubkey */ 03928 err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw, 03929 ECC_MAX_CRYPTO_HW_SIZE); 03930 if (err == MP_OKAY) 03931 err = mp_read_unsigned_bin(key->pubkey.y, 03932 key->pubkey_raw + ECC_MAX_CRYPTO_HW_SIZE, 03933 ECC_MAX_CRYPTO_HW_SIZE); 03934 #else 03935 03936 #ifdef WOLFSSL_HAVE_SP_ECC 03937 #ifndef WOLFSSL_SP_NO_256 03938 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { 03939 err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap); 03940 if (err == MP_OKAY) 03941 key->type = ECC_PRIVATEKEY; 03942 } 03943 else 03944 #endif 03945 #endif 03946 #ifdef WOLFSSL_SP_MATH 03947 err = WC_KEY_SIZE_E; 03948 #else 03949 { 03950 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); 03951 03952 /* setup the key variables */ 03953 err = mp_init(&key->k); 03954 03955 /* load curve info */ 03956 if (err == MP_OKAY) 03957 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 03958 03959 /* generate k */ 03960 if (err == MP_OKAY) 03961 err = wc_ecc_gen_k(rng, key->dp->size, &key->k, curve->order); 03962 03963 /* generate public key from k */ 03964 if (err == MP_OKAY) 03965 err = wc_ecc_make_pub_ex(key, curve, NULL); 03966 03967 if (err == MP_OKAY) 03968 key->type = ECC_PRIVATEKEY; 03969 03970 /* cleanup these on failure case only */ 03971 if (err != MP_OKAY) { 03972 /* clean up */ 03973 mp_forcezero(&key->k); 03974 } 03975 03976 /* cleanup allocations */ 03977 wc_ecc_curve_free(curve); 03978 #ifndef WOLFSSL_ATECC508A 03979 FREE_CURVE_SPECS(); 03980 #endif 03981 } 03982 #endif 03983 03984 #endif /* WOLFSSL_ATECC508A */ 03985 03986 return err; 03987 } 03988 03989 #ifdef ECC_DUMP_OID 03990 /* Optional dump of encoded OID for adding new curves */ 03991 static int mOidDumpDone; 03992 static void wc_ecc_dump_oids(void) 03993 { 03994 int x; 03995 03996 if (mOidDumpDone) { 03997 return; 03998 } 03999 04000 /* find matching OID sum (based on encoded value) */ 04001 for (x = 0; ecc_sets[x].size != 0; x++) { 04002 int i; 04003 byte* oid; 04004 word32 oidSz, sum = 0; 04005 04006 printf("ECC %s (%d):\n", ecc_sets[x].name, x); 04007 04008 #ifdef HAVE_OID_ENCODING 04009 byte oidEnc[ECC_MAX_OID_LEN]; 04010 04011 oid = oidEnc; 04012 oidSz = ECC_MAX_OID_LEN; 04013 04014 printf("OID: "); 04015 for (i = 0; i < (int)ecc_sets[x].oidSz; i++) { 04016 printf("%d.", ecc_sets[x].oid[i]); 04017 } 04018 printf("\n"); 04019 04020 EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz); 04021 #else 04022 oid = (byte*)ecc_sets[x].oid; 04023 oidSz = ecc_sets[x].oidSz; 04024 #endif 04025 04026 printf("OID Encoded: "); 04027 for (i = 0; i < (int)oidSz; i++) { 04028 printf("0x%02X,", oid[i]); 04029 } 04030 printf("\n"); 04031 04032 for (i = 0; i < (int)oidSz; i++) { 04033 sum += oid[i]; 04034 } 04035 printf("Sum: %d\n", sum); 04036 04037 /* validate sum */ 04038 if (ecc_sets[x].oidSum != sum) { 04039 printf(" Sum %d Not Valid!\n", ecc_sets[x].oidSum); 04040 } 04041 } 04042 mOidDumpDone = 1; 04043 } 04044 #endif /* ECC_DUMP_OID */ 04045 04046 /** 04047 Make a new ECC key 04048 rng An active RNG state 04049 keysize The keysize for the new key (in octets from 20 to 65 bytes) 04050 key [out] Destination of the newly created key 04051 return MP_OKAY if successful, 04052 upon error all allocated memory will be freed 04053 */ 04054 int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key) 04055 { 04056 return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF); 04057 } 04058 04059 /* Setup dynamic pointers if using normal math for proper freeing */ 04060 int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) 04061 { 04062 int ret = 0; 04063 04064 if (key == NULL) { 04065 return BAD_FUNC_ARG; 04066 } 04067 04068 #ifdef ECC_DUMP_OID 04069 wc_ecc_dump_oids(); 04070 #endif 04071 04072 XMEMSET(key, 0, sizeof(ecc_key)); 04073 key->state = ECC_STATE_NONE; 04074 04075 #if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_DEV) 04076 key->devId = devId; 04077 #else 04078 (void)devId; 04079 #endif 04080 04081 #ifdef WOLFSSL_ATECC508A 04082 key->slot = atmel_ecc_alloc(); 04083 if (key->slot == ATECC_INVALID_SLOT) { 04084 return ECC_BAD_ARG_E; 04085 } 04086 #else 04087 #ifdef ALT_ECC_SIZE 04088 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 04089 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 04090 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 04091 alt_fp_init(key->pubkey.x); 04092 alt_fp_init(key->pubkey.y); 04093 alt_fp_init(key->pubkey.z); 04094 ret = mp_init(&key->k); 04095 #else 04096 ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, 04097 NULL, NULL); 04098 #endif /* ALT_ECC_SIZE */ 04099 if (ret != MP_OKAY) { 04100 return MEMORY_E; 04101 } 04102 #endif /* WOLFSSL_ATECC508A */ 04103 04104 #ifdef WOLFSSL_HEAP_TEST 04105 key->heap = (void*)WOLFSSL_HEAP_TEST; 04106 #else 04107 key->heap = heap; 04108 #endif 04109 04110 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 04111 /* handle as async */ 04112 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC, 04113 key->heap, devId); 04114 #endif 04115 04116 return ret; 04117 } 04118 04119 int wc_ecc_init(ecc_key* key) 04120 { 04121 return wc_ecc_init_ex(key, NULL, INVALID_DEVID); 04122 } 04123 04124 int wc_ecc_set_flags(ecc_key* key, word32 flags) 04125 { 04126 if (key == NULL) { 04127 return BAD_FUNC_ARG; 04128 } 04129 key->flags |= flags; 04130 return 0; 04131 } 04132 04133 #ifdef HAVE_ECC_SIGN 04134 04135 #ifndef NO_ASN 04136 04137 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) 04138 static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, 04139 mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng, 04140 ecc_key* key) 04141 { 04142 int err; 04143 04144 #ifdef PLUTON_CRYPTO_ECC 04145 if (key->devId != INVALID_DEVID) /* use hardware */ 04146 #endif 04147 { 04148 word32 keysize = (word32)key->dp->size; 04149 04150 /* Check args */ 04151 if (keysize > ECC_MAX_CRYPTO_HW_SIZE || inlen != keysize || 04152 *outlen < keysize*2) { 04153 return ECC_BAD_ARG_E; 04154 } 04155 04156 #if defined(WOLFSSL_ATECC508A) 04157 /* Sign: Result is 32-bytes of R then 32-bytes of S */ 04158 err = atcatls_sign(key->slot, in, out); 04159 if (err != ATCA_SUCCESS) { 04160 return BAD_COND_E; 04161 } 04162 #elif defined(PLUTON_CRYPTO_ECC) 04163 { 04164 /* perform ECC sign */ 04165 word32 raw_sig_size = *outlen; 04166 err = Crypto_EccSign(in, inlen, out, &raw_sig_size); 04167 if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){ 04168 return BAD_COND_E; 04169 } 04170 } 04171 #endif 04172 04173 /* Load R and S */ 04174 err = mp_read_unsigned_bin(r, &out[0], keysize); 04175 if (err != MP_OKAY) { 04176 return err; 04177 } 04178 err = mp_read_unsigned_bin(s, &out[keysize], keysize); 04179 if (err != MP_OKAY) { 04180 return err; 04181 } 04182 04183 /* Check for zeros */ 04184 if (mp_iszero(r) || mp_iszero(s)) { 04185 return MP_ZERO_E; 04186 } 04187 } 04188 #ifdef PLUTON_CRYPTO_ECC 04189 else { 04190 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); 04191 } 04192 #endif 04193 (void)rng; 04194 04195 return err; 04196 } 04197 #endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC */ 04198 04199 /** 04200 Sign a message digest 04201 in The message digest to sign 04202 inlen The length of the digest 04203 out [out] The destination for the signature 04204 outlen [in/out] The max size and resulting size of the signature 04205 key A private ECC key 04206 return MP_OKAY if successful 04207 */ 04208 int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, 04209 WC_RNG* rng, ecc_key* key) 04210 { 04211 int err; 04212 mp_int *r = NULL, *s = NULL; 04213 #if !defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_SMALL_STACK) 04214 mp_int r_lcl, s_lcl; 04215 #endif 04216 04217 if (in == NULL || out == NULL || outlen == NULL || key == NULL || 04218 rng == NULL) { 04219 return ECC_BAD_ARG_E; 04220 } 04221 04222 #ifdef WOLF_CRYPTO_DEV 04223 if (key->devId != INVALID_DEVID) { 04224 err = wc_CryptoDev_EccSign(in, inlen, out, outlen, rng, key); 04225 if (err != NOT_COMPILED_IN) 04226 return err; 04227 } 04228 #endif 04229 04230 #ifdef WOLFSSL_ASYNC_CRYPT 04231 err = wc_ecc_alloc_async(key); 04232 if (err != 0) 04233 return err; 04234 r = key->r; 04235 s = key->s; 04236 #elif !defined(WOLFSSL_SMALL_STACK) 04237 r = &r_lcl; 04238 s = &s_lcl; 04239 #else 04240 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 04241 if (r == NULL) 04242 return MEMORY_E; 04243 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 04244 if (s == NULL) { 04245 XFREE(r, key->heap, DYNAMIC_TYPE_ECC); 04246 return MEMORY_E; 04247 } 04248 #endif 04249 04250 switch(key->state) { 04251 case ECC_STATE_NONE: 04252 case ECC_STATE_SIGN_DO: 04253 key->state = ECC_STATE_SIGN_DO; 04254 04255 if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){ 04256 break; 04257 } 04258 04259 /* hardware crypto */ 04260 #if defined(WOLFSSL_ATECC508A) || defined(PLUTON_CRYPTO_ECC) 04261 err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key); 04262 #else 04263 err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s); 04264 #endif 04265 if (err < 0) { 04266 break; 04267 } 04268 04269 FALL_THROUGH; 04270 04271 case ECC_STATE_SIGN_ENCODE: 04272 key->state = ECC_STATE_SIGN_ENCODE; 04273 04274 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 04275 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 04276 #ifdef HAVE_CAVIUM_V 04277 /* Nitrox requires r and s in sep buffer, so split it */ 04278 NitroxEccRsSplit(key, &r->raw, &s->raw); 04279 #endif 04280 #ifndef WOLFSSL_ASYNC_CRYPT_TEST 04281 /* only do this if not simulator, since it overwrites result */ 04282 wc_bigint_to_mp(&r->raw, r); 04283 wc_bigint_to_mp(&s->raw, s); 04284 #endif 04285 } 04286 #endif /* WOLFSSL_ASYNC_CRYPT */ 04287 04288 /* encoded with DSA header */ 04289 err = StoreECC_DSA_Sig(out, outlen, r, s); 04290 04291 /* done with R/S */ 04292 mp_clear(r); 04293 mp_clear(s); 04294 #if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_SMALL_STACK) 04295 XFREE(s, key->heap, DYNAMIC_TYPE_ECC); 04296 XFREE(r, key->heap, DYNAMIC_TYPE_ECC); 04297 #endif 04298 break; 04299 04300 default: 04301 err = BAD_STATE_E; 04302 break; 04303 } 04304 04305 /* if async pending then return and skip done cleanup below */ 04306 if (err == WC_PENDING_E) { 04307 key->state++; 04308 return err; 04309 } 04310 04311 /* cleanup */ 04312 #ifdef WOLFSSL_ASYNC_CRYPT 04313 wc_ecc_free_async(key); 04314 #endif 04315 key->state = ECC_STATE_NONE; 04316 04317 return err; 04318 } 04319 #endif /* !NO_ASN */ 04320 04321 #ifndef WOLFSSL_ATECC508A 04322 /** 04323 Sign a message digest 04324 in The message digest to sign 04325 inlen The length of the digest 04326 key A private ECC key 04327 r [out] The destination for r component of the signature 04328 s [out] The destination for s component of the signature 04329 return MP_OKAY if successful 04330 */ 04331 int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, 04332 ecc_key* key, mp_int *r, mp_int *s) 04333 { 04334 int err; 04335 #ifndef WOLFSSL_SP_MATH 04336 mp_int* e; 04337 #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \ 04338 !defined(WOLFSSL_SMALL_STACK) 04339 mp_int e_lcl; 04340 #endif 04341 DECLARE_CURVE_SPECS(curve, 1); 04342 #endif /* !WOLFSSL_SP_MATH */ 04343 04344 if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) 04345 return ECC_BAD_ARG_E; 04346 04347 /* is this a private key? */ 04348 if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) { 04349 return ECC_BAD_ARG_E; 04350 } 04351 04352 /* is the IDX valid ? */ 04353 if (wc_ecc_is_valid_idx(key->idx) != 1) { 04354 return ECC_BAD_ARG_E; 04355 } 04356 04357 #ifdef WOLFSSL_SP_MATH 04358 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) 04359 return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap); 04360 else 04361 return WC_KEY_SIZE_E; 04362 #else 04363 #ifdef WOLFSSL_HAVE_SP_ECC 04364 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 04365 defined(WOLFSSL_ASYNC_CRYPT_TEST) 04366 if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) 04367 #endif 04368 { 04369 #ifndef WOLFSSL_SP_NO_256 04370 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) 04371 return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap); 04372 #endif 04373 } 04374 #endif /* WOLFSSL_HAVE_SP_ECC */ 04375 04376 04377 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 04378 defined(WOLFSSL_ASYNC_CRYPT_TEST) 04379 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 04380 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_SIGN)) { 04381 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 04382 testDev->eccSign.in = in; 04383 testDev->eccSign.inSz = inlen; 04384 testDev->eccSign.rng = rng; 04385 testDev->eccSign.key = key; 04386 testDev->eccSign.r = r; 04387 testDev->eccSign.s = s; 04388 return WC_PENDING_E; 04389 } 04390 } 04391 #endif 04392 04393 ALLOC_CURVE_SPECS(1); 04394 04395 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) 04396 err = wc_ecc_alloc_mpint(key, &key->e); 04397 if (err != 0) { 04398 FREE_CURVE_SPECS(); 04399 return err; 04400 } 04401 e = key->e; 04402 #elif !defined(WOLFSSL_SMALL_STACK) 04403 e = &e_lcl; 04404 #else 04405 e = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 04406 if (e == NULL) { 04407 FREE_CURVE_SPECS(); 04408 return MEMORY_E; 04409 } 04410 #endif 04411 04412 /* get the hash and load it as a bignum into 'e' */ 04413 /* init the bignums */ 04414 if ((err = mp_init(e)) != MP_OKAY) { 04415 #ifdef WOLFSSL_SMALL_STACK 04416 XFREE(e, key->heap, DYNAMIC_TYPE_ECC); 04417 #endif 04418 FREE_CURVE_SPECS(); 04419 return err; 04420 } 04421 04422 /* load curve info */ 04423 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); 04424 04425 /* load digest into e */ 04426 if (err == MP_OKAY) { 04427 /* we may need to truncate if hash is longer than key size */ 04428 word32 orderBits = mp_count_bits(curve->order); 04429 04430 /* truncate down to byte size, may be all that's needed */ 04431 if ((WOLFSSL_BIT_SIZE * inlen) > orderBits) 04432 inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; 04433 err = mp_read_unsigned_bin(e, (byte*)in, inlen); 04434 04435 /* may still need bit truncation too */ 04436 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits) 04437 mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 04438 } 04439 04440 /* make up a key and export the public copy */ 04441 if (err == MP_OKAY) { 04442 int loop_check = 0; 04443 #ifdef WOLFSSL_SMALL_STACK 04444 ecc_key* pubkey = NULL; 04445 #else 04446 ecc_key pubkey[1]; 04447 #endif 04448 04449 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 04450 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 04451 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) 04452 #ifdef HAVE_CAVIUM_V 04453 if (NitroxEccIsCurveSupported(key)) 04454 #endif 04455 { 04456 word32 keySz = key->dp->size; 04457 mp_int* k; 04458 #ifdef HAVE_CAVIUM_V 04459 err = wc_ecc_alloc_mpint(key, &key->signK); 04460 if (err != 0) 04461 return err; 04462 k = key->signK; 04463 #else 04464 mp_int k_lcl; 04465 k = &k_lcl; 04466 #endif 04467 04468 err = mp_init(k); 04469 04470 /* make sure r and s are allocated */ 04471 #ifdef HAVE_CAVIUM_V 04472 /* Nitrox V needs single buffer for R and S */ 04473 if (err == MP_OKAY) 04474 err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2); 04475 /* Nitrox V only needs Prime and Order */ 04476 if (err == MP_OKAY) 04477 err = wc_ecc_curve_load(key->dp, &curve, 04478 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER)); 04479 #else 04480 if (err == MP_OKAY) 04481 err = wc_bigint_alloc(&key->r->raw, key->dp->size); 04482 if (err == MP_OKAY) 04483 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 04484 #endif 04485 if (err == MP_OKAY) 04486 err = wc_bigint_alloc(&key->s->raw, key->dp->size); 04487 04488 /* load e and k */ 04489 if (err == MP_OKAY) 04490 err = wc_mp_to_bigint_sz(e, &e->raw, keySz); 04491 if (err == MP_OKAY) 04492 err = wc_mp_to_bigint_sz(&key->k, &key->k.raw, keySz); 04493 if (err == MP_OKAY) 04494 err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order); 04495 if (err == MP_OKAY) 04496 err = wc_mp_to_bigint_sz(k, &k->raw, keySz); 04497 04498 #ifdef HAVE_CAVIUM_V 04499 if (err == MP_OKAY) 04500 err = NitroxEcdsaSign(key, &e->raw, &key->k.raw, &k->raw, 04501 &r->raw, &s->raw, &curve->prime->raw, &curve->order->raw); 04502 #else 04503 if (err == MP_OKAY) 04504 err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k.raw, 04505 &k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw, 04506 &curve->prime->raw, &curve->order->raw, &curve->Gx->raw, 04507 &curve->Gy->raw); 04508 #endif 04509 04510 #ifndef HAVE_CAVIUM_V 04511 mp_clear(e); 04512 mp_clear(k); 04513 #endif 04514 wc_ecc_curve_free(curve); 04515 FREE_CURVE_SPECS(); 04516 04517 return err; 04518 } 04519 #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ 04520 } 04521 #endif /* WOLFSSL_ASYNC_CRYPT */ 04522 04523 #ifdef WOLFSSL_SMALL_STACK 04524 pubkey = (ecc_key*)XMALLOC(sizeof(ecc_key), key->heap, DYNAMIC_TYPE_ECC); 04525 if (pubkey == NULL) 04526 err = MEMORY_E; 04527 #endif 04528 04529 /* don't use async for key, since we don't support async return here */ 04530 if (err == MP_OKAY && (err = wc_ecc_init_ex(pubkey, key->heap, 04531 INVALID_DEVID)) == MP_OKAY) { 04532 #ifdef WOLFSSL_SMALL_STACK 04533 mp_int* b = NULL; 04534 #else 04535 mp_int b[1]; 04536 #endif 04537 04538 #ifdef WOLFSSL_SMALL_STACK 04539 if (err == MP_OKAY) { 04540 b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, 04541 DYNAMIC_TYPE_ECC); 04542 if (b == NULL) 04543 err = MEMORY_E; 04544 } 04545 #endif 04546 04547 if (err == MP_OKAY) { 04548 err = mp_init(b); 04549 } 04550 04551 #ifdef WOLFSSL_CUSTOM_CURVES 04552 /* if custom curve, apply params to pubkey */ 04553 if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) { 04554 err = wc_ecc_set_custom_curve(pubkey, key->dp); 04555 } 04556 #endif 04557 04558 if (err == MP_OKAY) { 04559 /* Generate blinding value - non-zero value. */ 04560 do { 04561 if (++loop_check > 64) { 04562 err = RNG_FAILURE_E; 04563 break; 04564 } 04565 04566 err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order); 04567 } 04568 while (err == MP_ZERO_E); 04569 loop_check = 0; 04570 } 04571 04572 for (; err == MP_OKAY;) { 04573 if (++loop_check > 64) { 04574 err = RNG_FAILURE_E; 04575 break; 04576 } 04577 err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey, 04578 key->dp->id); 04579 if (err != MP_OKAY) break; 04580 04581 /* find r = x1 mod n */ 04582 err = mp_mod(pubkey->pubkey.x, curve->order, r); 04583 if (err != MP_OKAY) break; 04584 04585 if (mp_iszero(r) == MP_YES) { 04586 #ifndef ALT_ECC_SIZE 04587 mp_clear(pubkey->pubkey.x); 04588 mp_clear(pubkey->pubkey.y); 04589 mp_clear(pubkey->pubkey.z); 04590 #endif 04591 mp_forcezero(&pubkey->k); 04592 } 04593 else { 04594 /* find s = (e + xr)/k 04595 = b.(e/k.b + x.r/k.b) */ 04596 04597 /* k = k.b */ 04598 err = mp_mulmod(&pubkey->k, b, curve->order, &pubkey->k); 04599 if (err != MP_OKAY) break; 04600 04601 /* k = 1/k.b */ 04602 err = mp_invmod(&pubkey->k, curve->order, &pubkey->k); 04603 if (err != MP_OKAY) break; 04604 04605 /* s = x.r */ 04606 err = mp_mulmod(&key->k, r, curve->order, s); 04607 if (err != MP_OKAY) break; 04608 04609 /* s = x.r/k.b */ 04610 err = mp_mulmod(&pubkey->k, s, curve->order, s); 04611 if (err != MP_OKAY) break; 04612 04613 /* e = e/k.b */ 04614 err = mp_mulmod(&pubkey->k, e, curve->order, e); 04615 if (err != MP_OKAY) break; 04616 04617 /* s = e/k.b + x.r/k.b 04618 = (e + x.r)/k.b */ 04619 err = mp_add(e, s, s); 04620 if (err != MP_OKAY) break; 04621 04622 /* s = b.(e + x.r)/k.b 04623 = (e + x.r)/k */ 04624 err = mp_mulmod(s, b, curve->order, s); 04625 if (err != MP_OKAY) break; 04626 04627 /* s = (e + xr)/k */ 04628 err = mp_mod(s, curve->order, s); 04629 if (err != MP_OKAY) break; 04630 04631 if (mp_iszero(s) == MP_NO) 04632 break; 04633 } 04634 } 04635 mp_clear(b); 04636 mp_free(b); 04637 #ifdef WOLFSSL_SMALL_STACK 04638 XFREE(b, key->heap, DYNAMIC_TYPE_ECC); 04639 #endif 04640 wc_ecc_free(pubkey); 04641 #ifdef WOLFSSL_SMALL_STACK 04642 XFREE(pubkey, key->heap, DYNAMIC_TYPE_ECC); 04643 #endif 04644 } 04645 } 04646 04647 mp_clear(e); 04648 wc_ecc_curve_free(curve); 04649 #ifdef WOLFSSL_SMALL_STACK 04650 XFREE(e, key->heap, DYNAMIC_TYPE_ECC); 04651 #endif 04652 FREE_CURVE_SPECS(); 04653 #endif /* WOLFSSL_SP_MATH */ 04654 04655 return err; 04656 } 04657 #endif /* WOLFSSL_ATECC508A */ 04658 #endif /* HAVE_ECC_SIGN */ 04659 04660 #ifdef WOLFSSL_CUSTOM_CURVES 04661 void wc_ecc_free_curve(const ecc_set_type* curve, void* heap) 04662 { 04663 if (curve->prime != NULL) 04664 XFREE((void*)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER); 04665 if (curve->Af != NULL) 04666 XFREE((void*)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER); 04667 if (curve->Bf != NULL) 04668 XFREE((void*)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER); 04669 if (curve->order != NULL) 04670 XFREE((void*)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER); 04671 if (curve->Gx != NULL) 04672 XFREE((void*)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER); 04673 if (curve->Gy != NULL) 04674 XFREE((void*)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER); 04675 04676 XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER); 04677 04678 (void)heap; 04679 } 04680 #endif /* WOLFSSL_CUSTOM_CURVES */ 04681 04682 /** 04683 Free an ECC key from memory 04684 key The key you wish to free 04685 */ 04686 int wc_ecc_free(ecc_key* key) 04687 { 04688 if (key == NULL) { 04689 return 0; 04690 } 04691 04692 #ifdef WOLFSSL_ASYNC_CRYPT 04693 #ifdef WC_ASYNC_ENABLE_ECC 04694 wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC); 04695 #endif 04696 wc_ecc_free_async(key); 04697 #endif 04698 04699 #ifdef WOLFSSL_ATECC508A 04700 atmel_ecc_free(key->slot); 04701 key->slot = -1; 04702 #else 04703 04704 mp_clear(key->pubkey.x); 04705 mp_clear(key->pubkey.y); 04706 mp_clear(key->pubkey.z); 04707 04708 mp_forcezero(&key->k); 04709 #endif /* WOLFSSL_ATECC508A */ 04710 04711 #ifdef WOLFSSL_CUSTOM_CURVES 04712 if (key->deallocSet && key->dp != NULL) 04713 wc_ecc_free_curve(key->dp, key->heap); 04714 #endif 04715 04716 return 0; 04717 } 04718 04719 #if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) 04720 #ifdef ECC_SHAMIR 04721 04722 /** Computes kA*A + kB*B = C using Shamir's Trick 04723 A First point to multiply 04724 kA What to multiple A by 04725 B Second point to multiply 04726 kB What to multiple B by 04727 C [out] Destination point (can overlap with A or B) 04728 a ECC curve parameter a 04729 modulus Modulus for curve 04730 return MP_OKAY on success 04731 */ 04732 #ifdef FP_ECC 04733 static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, 04734 ecc_point* B, mp_int* kB, 04735 ecc_point* C, mp_int* a, mp_int* modulus, 04736 void* heap) 04737 #else 04738 int ecc_mul2add(ecc_point* A, mp_int* kA, 04739 ecc_point* B, mp_int* kB, 04740 ecc_point* C, mp_int* a, mp_int* modulus, 04741 void* heap) 04742 #endif 04743 { 04744 #ifdef WOLFSSL_SMALL_STACK 04745 ecc_point** precomp = NULL; 04746 #ifdef WOLFSSL_SMALL_STACK_CACHE 04747 ecc_key key; 04748 #endif 04749 #else 04750 ecc_point* precomp[SHAMIR_PRECOMP_SZ]; 04751 #endif 04752 unsigned bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble; 04753 unsigned char* tA; 04754 unsigned char* tB; 04755 int err = MP_OKAY, first, x, y; 04756 mp_digit mp = 0; 04757 04758 /* argchks */ 04759 if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || 04760 modulus == NULL) { 04761 return ECC_BAD_ARG_E; 04762 } 04763 04764 /* allocate memory */ 04765 tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER); 04766 if (tA == NULL) { 04767 return GEN_MEM_ERR; 04768 } 04769 tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER); 04770 if (tB == NULL) { 04771 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); 04772 return GEN_MEM_ERR; 04773 } 04774 #ifdef WOLFSSL_SMALL_STACK 04775 precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap, 04776 DYNAMIC_TYPE_ECC_BUFFER); 04777 if (precomp == NULL) { 04778 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); 04779 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); 04780 return GEN_MEM_ERR; 04781 } 04782 #endif 04783 #ifdef WOLFSSL_SMALL_STACK_CACHE 04784 key.t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04785 key.t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04786 #ifdef ALT_ECC_SIZE 04787 key.x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04788 key.y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04789 key.z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04790 #endif 04791 if (key.t1 == NULL || key.t2 == NULL 04792 #ifdef ALT_ECC_SIZE 04793 || key.x == NULL || key.y == NULL || key.z == NULL 04794 #endif 04795 ) { 04796 #ifdef ALT_ECC_SIZE 04797 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 04798 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 04799 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 04800 #endif 04801 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 04802 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 04803 XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER); 04804 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); 04805 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); 04806 return MEMORY_E; 04807 } 04808 C->key = &key; 04809 #endif /* WOLFSSL_SMALL_STACK_CACHE */ 04810 04811 /* init variables */ 04812 XMEMSET(tA, 0, ECC_BUFSIZE); 04813 XMEMSET(tB, 0, ECC_BUFSIZE); 04814 #ifndef WOLFSSL_SMALL_STACK 04815 XMEMSET(precomp, 0, sizeof(precomp)); 04816 #else 04817 XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ); 04818 #endif 04819 04820 /* get sizes */ 04821 lenA = mp_unsigned_bin_size(kA); 04822 lenB = mp_unsigned_bin_size(kB); 04823 len = MAX(lenA, lenB); 04824 04825 /* sanity check */ 04826 if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { 04827 err = BAD_FUNC_ARG; 04828 } 04829 04830 if (err == MP_OKAY) { 04831 /* extract and justify kA */ 04832 err = mp_to_unsigned_bin(kA, (len - lenA) + tA); 04833 04834 /* extract and justify kB */ 04835 if (err == MP_OKAY) 04836 err = mp_to_unsigned_bin(kB, (len - lenB) + tB); 04837 04838 /* allocate the table */ 04839 if (err == MP_OKAY) { 04840 for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) { 04841 precomp[x] = wc_ecc_new_point_h(heap); 04842 if (precomp[x] == NULL) { 04843 err = GEN_MEM_ERR; 04844 break; 04845 } 04846 #ifdef WOLFSSL_SMALL_STACK_CACHE 04847 precomp[x]->key = &key; 04848 #endif 04849 } 04850 } 04851 } 04852 04853 if (err == MP_OKAY) 04854 /* init montgomery reduction */ 04855 err = mp_montgomery_setup(modulus, &mp); 04856 04857 if (err == MP_OKAY) { 04858 #ifdef WOLFSSL_SMALL_STACK 04859 mp_int* mu = NULL; 04860 #else 04861 mp_int mu[1]; 04862 #endif 04863 #ifdef WOLFSSL_SMALL_STACK 04864 mu = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC); 04865 if (mu == NULL) 04866 err = MEMORY_E; 04867 #endif 04868 if (err == MP_OKAY) { 04869 err = mp_init(mu); 04870 } 04871 if (err == MP_OKAY) { 04872 err = mp_montgomery_calc_normalization(mu, modulus); 04873 04874 if (err == MP_OKAY) 04875 /* copy ones ... */ 04876 err = mp_mulmod(A->x, mu, modulus, precomp[1]->x); 04877 04878 if (err == MP_OKAY) 04879 err = mp_mulmod(A->y, mu, modulus, precomp[1]->y); 04880 if (err == MP_OKAY) 04881 err = mp_mulmod(A->z, mu, modulus, precomp[1]->z); 04882 04883 if (err == MP_OKAY) 04884 err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x); 04885 if (err == MP_OKAY) 04886 err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y); 04887 if (err == MP_OKAY) 04888 err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z); 04889 04890 /* done with mu */ 04891 mp_clear(mu); 04892 #ifdef WOLFSSL_SMALL_STACK 04893 XFREE(mu, heap, DYNAMIC_TYPE_ECC); 04894 #endif 04895 } 04896 } 04897 04898 if (err == MP_OKAY) 04899 /* precomp [i,0](A + B) table */ 04900 err = ecc_projective_dbl_point(precomp[1], precomp[2], a, modulus, mp); 04901 04902 if (err == MP_OKAY) 04903 err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], 04904 a, modulus, mp); 04905 if (err == MP_OKAY) 04906 /* precomp [0,i](A + B) table */ 04907 err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], a, modulus, mp); 04908 04909 if (err == MP_OKAY) 04910 err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], 04911 a, modulus, mp); 04912 04913 if (err == MP_OKAY) { 04914 /* precomp [i,j](A + B) table (i != 0, j != 0) */ 04915 for (x = 1; x < 4; x++) { 04916 for (y = 1; y < 4; y++) { 04917 if (err == MP_OKAY) { 04918 err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], 04919 precomp[x+(y<<2)], a, modulus, mp); 04920 } 04921 } 04922 } 04923 } 04924 04925 if (err == MP_OKAY) { 04926 nibble = 3; 04927 first = 1; 04928 bitbufA = tA[0]; 04929 bitbufB = tB[0]; 04930 04931 /* for every byte of the multiplicands */ 04932 for (x = 0;; ) { 04933 /* grab a nibble */ 04934 if (++nibble == 4) { 04935 if (x == (int)len) break; 04936 bitbufA = tA[x]; 04937 bitbufB = tB[x]; 04938 nibble = 0; 04939 x++; 04940 } 04941 04942 /* extract two bits from both, shift/update */ 04943 nA = (bitbufA >> 6) & 0x03; 04944 nB = (bitbufB >> 6) & 0x03; 04945 bitbufA = (bitbufA << 2) & 0xFF; 04946 bitbufB = (bitbufB << 2) & 0xFF; 04947 04948 /* if both zero, if first, continue */ 04949 if ((nA == 0) && (nB == 0) && (first == 1)) { 04950 continue; 04951 } 04952 04953 /* double twice, only if this isn't the first */ 04954 if (first == 0) { 04955 /* double twice */ 04956 if (err == MP_OKAY) 04957 err = ecc_projective_dbl_point(C, C, a, modulus, mp); 04958 if (err == MP_OKAY) 04959 err = ecc_projective_dbl_point(C, C, a, modulus, mp); 04960 else 04961 break; 04962 } 04963 04964 /* if not both zero */ 04965 if ((nA != 0) || (nB != 0)) { 04966 if (first == 1) { 04967 /* if first, copy from table */ 04968 first = 0; 04969 if (err == MP_OKAY) 04970 err = mp_copy(precomp[nA + (nB<<2)]->x, C->x); 04971 04972 if (err == MP_OKAY) 04973 err = mp_copy(precomp[nA + (nB<<2)]->y, C->y); 04974 04975 if (err == MP_OKAY) 04976 err = mp_copy(precomp[nA + (nB<<2)]->z, C->z); 04977 else 04978 break; 04979 } else { 04980 /* if not first, add from table */ 04981 if (err == MP_OKAY) 04982 err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, 04983 a, modulus, mp); 04984 else 04985 break; 04986 } 04987 } 04988 } 04989 } 04990 04991 /* reduce to affine */ 04992 if (err == MP_OKAY) 04993 err = ecc_map(C, modulus, mp); 04994 04995 /* clean up */ 04996 for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) { 04997 wc_ecc_del_point_h(precomp[x], heap); 04998 } 04999 05000 ForceZero(tA, ECC_BUFSIZE); 05001 ForceZero(tB, ECC_BUFSIZE); 05002 #ifdef WOLFSSL_SMALL_STACK_CACHE 05003 #ifdef ALT_ECC_SIZE 05004 XFREE(key.z, heap, DYNAMIC_TYPE_ECC); 05005 XFREE(key.y, heap, DYNAMIC_TYPE_ECC); 05006 XFREE(key.x, heap, DYNAMIC_TYPE_ECC); 05007 #endif 05008 XFREE(key.t2, heap, DYNAMIC_TYPE_ECC); 05009 XFREE(key.t1, heap, DYNAMIC_TYPE_ECC); 05010 C->key = NULL; 05011 #endif 05012 #ifdef WOLFSSL_SMALL_STACK 05013 XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER); 05014 #endif 05015 XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER); 05016 XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER); 05017 05018 return err; 05019 } 05020 05021 #endif /* ECC_SHAMIR */ 05022 #endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A */ 05023 05024 05025 #ifdef HAVE_ECC_VERIFY 05026 #ifndef NO_ASN 05027 /* verify 05028 * 05029 * w = s^-1 mod n 05030 * u1 = xw 05031 * u2 = rw 05032 * X = u1*G + u2*Q 05033 * v = X_x1 mod n 05034 * accept if v == r 05035 */ 05036 05037 /** 05038 Verify an ECC signature 05039 sig The signature to verify 05040 siglen The length of the signature (octets) 05041 hash The hash (message digest) that was signed 05042 hashlen The length of the hash (octets) 05043 res Result of signature, 1==valid, 0==invalid 05044 key The corresponding public ECC key 05045 return MP_OKAY if successful (even if the signature is not valid) 05046 */ 05047 int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, 05048 word32 hashlen, int* res, ecc_key* key) 05049 { 05050 int err; 05051 mp_int *r = NULL, *s = NULL; 05052 #ifndef WOLFSSL_ASYNC_CRYPT 05053 #ifndef WOLFSSL_SMALL_STACK 05054 mp_int r_lcl[1], s_lcl[1]; 05055 #endif 05056 #endif 05057 05058 if (sig == NULL || hash == NULL || res == NULL || key == NULL) { 05059 return ECC_BAD_ARG_E; 05060 } 05061 05062 #ifdef WOLF_CRYPTO_DEV 05063 if (key->devId != INVALID_DEVID) { 05064 err = wc_CryptoDev_EccVerify(sig, siglen, hash, hashlen, res, key); 05065 if (err != NOT_COMPILED_IN) 05066 return err; 05067 } 05068 #endif 05069 05070 #ifdef WOLFSSL_ASYNC_CRYPT 05071 err = wc_ecc_alloc_async(key); 05072 if (err != 0) 05073 return err; 05074 r = key->r; 05075 s = key->s; 05076 #else 05077 #ifndef WOLFSSL_SMALL_STACK 05078 r = r_lcl; 05079 s = s_lcl; 05080 #else 05081 r = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05082 if (r == NULL) 05083 return MEMORY_E; 05084 s = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05085 if (s == NULL) { 05086 XFREE(r, key->heap, DYNAMIC_TYPE_ECC); 05087 return MEMORY_E; 05088 } 05089 #endif 05090 #endif 05091 05092 switch(key->state) { 05093 case ECC_STATE_NONE: 05094 case ECC_STATE_VERIFY_DECODE: 05095 key->state = ECC_STATE_VERIFY_DECODE; 05096 05097 /* default to invalid signature */ 05098 *res = 0; 05099 05100 /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. 05101 * If either of those don't allocate correctly, none of 05102 * the rest of this function will execute, and everything 05103 * gets cleaned up at the end. */ 05104 /* decode DSA header */ 05105 err = DecodeECC_DSA_Sig(sig, siglen, r, s); 05106 if (err < 0) { 05107 break; 05108 } 05109 FALL_THROUGH; 05110 05111 case ECC_STATE_VERIFY_DO: 05112 key->state = ECC_STATE_VERIFY_DO; 05113 05114 err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key); 05115 05116 #ifndef WOLFSSL_ASYNC_CRYPT 05117 /* done with R/S */ 05118 mp_clear(r); 05119 mp_clear(s); 05120 #ifdef WOLFSSL_SMALL_STACK 05121 XFREE(s, key->heap, DYNAMIC_TYPE_ECC); 05122 XFREE(r, key->heap, DYNAMIC_TYPE_ECC); 05123 #endif 05124 #endif 05125 05126 if (err < 0) { 05127 break; 05128 } 05129 FALL_THROUGH; 05130 05131 case ECC_STATE_VERIFY_RES: 05132 key->state = ECC_STATE_VERIFY_RES; 05133 err = 0; 05134 break; 05135 05136 default: 05137 err = BAD_STATE_E; 05138 } 05139 05140 /* if async pending then return and skip done cleanup below */ 05141 if (err == WC_PENDING_E) { 05142 key->state++; 05143 return err; 05144 } 05145 05146 /* cleanup */ 05147 #ifdef WOLFSSL_ASYNC_CRYPT 05148 wc_ecc_free_async(key); 05149 #endif 05150 key->state = ECC_STATE_NONE; 05151 05152 return err; 05153 } 05154 #endif /* !NO_ASN */ 05155 05156 05157 /** 05158 Verify an ECC signature 05159 r The signature R component to verify 05160 s The signature S component to verify 05161 hash The hash (message digest) that was signed 05162 hashlen The length of the hash (octets) 05163 res Result of signature, 1==valid, 0==invalid 05164 key The corresponding public ECC key 05165 return MP_OKAY if successful (even if the signature is not valid) 05166 */ 05167 int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, 05168 word32 hashlen, int* res, ecc_key* key) 05169 { 05170 int err; 05171 #ifdef WOLFSSL_ATECC508A 05172 byte sigRS[ATECC_KEY_SIZE*2]; 05173 #elif !defined(WOLFSSL_SP_MATH) 05174 int did_init = 0; 05175 ecc_point *mG = NULL, *mQ = NULL; 05176 #ifdef WOLFSSL_SMALL_STACK 05177 mp_int* v = NULL; 05178 mp_int* w = NULL; 05179 mp_int* u1 = NULL; 05180 mp_int* u2 = NULL; 05181 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) 05182 mp_int* e_lcl = NULL; 05183 #endif 05184 #else /* WOLFSSL_SMALL_STACK */ 05185 mp_int v[1]; 05186 mp_int w[1]; 05187 mp_int u1[1]; 05188 mp_int u2[1]; 05189 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) 05190 mp_int e_lcl[1]; 05191 #endif 05192 #endif /* WOLFSSL_SMALL_STACK */ 05193 mp_int* e; 05194 DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); 05195 #endif 05196 05197 if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) 05198 return ECC_BAD_ARG_E; 05199 05200 /* default to invalid signature */ 05201 *res = 0; 05202 05203 /* is the IDX valid ? */ 05204 if (wc_ecc_is_valid_idx(key->idx) != 1) { 05205 return ECC_BAD_ARG_E; 05206 } 05207 05208 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 05209 defined(WOLFSSL_ASYNC_CRYPT_TEST) 05210 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 05211 if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_ECC_VERIFY)) { 05212 WC_ASYNC_TEST* testDev = &key->asyncDev.test; 05213 testDev->eccVerify.r = r; 05214 testDev->eccVerify.s = s; 05215 testDev->eccVerify.hash = hash; 05216 testDev->eccVerify.hashlen = hashlen; 05217 testDev->eccVerify.stat = res; 05218 testDev->eccVerify.key = key; 05219 return WC_PENDING_E; 05220 } 05221 } 05222 #endif 05223 05224 #ifdef WOLFSSL_ATECC508A 05225 /* Extract R and S */ 05226 err = mp_to_unsigned_bin(r, &sigRS[0]); 05227 if (err != MP_OKAY) { 05228 return err; 05229 } 05230 err = mp_to_unsigned_bin(s, &sigRS[ATECC_KEY_SIZE]); 05231 if (err != MP_OKAY) { 05232 return err; 05233 } 05234 05235 err = atcatls_verify(hash, sigRS, key->pubkey_raw, (bool*)res); 05236 if (err != ATCA_SUCCESS) { 05237 return BAD_COND_E; 05238 } 05239 (void)hashlen; 05240 05241 #else 05242 /* checking if private key with no public part */ 05243 if (key->type == ECC_PRIVATEKEY_ONLY) { 05244 WOLFSSL_MSG("Verify called with private key, generating public part"); 05245 err = wc_ecc_make_pub_ex(key, NULL, NULL); 05246 if (err != MP_OKAY) { 05247 WOLFSSL_MSG("Unable to extract public key"); 05248 return err; 05249 } 05250 } 05251 05252 #ifdef WOLFSSL_SP_MATH 05253 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { 05254 return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, 05255 key->pubkey.z, r, s, res, key->heap); 05256 } 05257 else 05258 return WC_KEY_SIZE_E; 05259 #else 05260 #ifdef WOLFSSL_HAVE_SP_ECC 05261 #ifndef WOLFSSL_SP_NO_256 05262 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ 05263 defined(WOLFSSL_ASYNC_CRYPT_TEST) 05264 if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) 05265 #endif 05266 { 05267 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) 05268 return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, 05269 key->pubkey.z,r, s, res, key->heap); 05270 } 05271 #endif /* WOLFSSL_SP_NO_256 */ 05272 #endif /* WOLFSSL_HAVE_SP_ECC */ 05273 05274 ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); 05275 05276 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) 05277 err = wc_ecc_alloc_mpint(key, &key->e); 05278 if (err != 0) { 05279 FREE_CURVE_SPECS(); 05280 return err; 05281 } 05282 e = key->e; 05283 #else 05284 #ifdef WOLFSSL_SMALL_STACK 05285 e_lcl = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05286 if (e_lcl == NULL) { 05287 FREE_CURVE_SPECS(); 05288 return MEMORY_E; 05289 } 05290 #endif 05291 e = e_lcl; 05292 #endif 05293 05294 err = mp_init(e); 05295 if (err != MP_OKAY) 05296 return MEMORY_E; 05297 05298 /* read in the specs for this curve */ 05299 err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); 05300 05301 /* check for zero */ 05302 if (err == MP_OKAY) { 05303 if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || 05304 mp_cmp(r, curve->order) != MP_LT || 05305 mp_cmp(s, curve->order) != MP_LT) { 05306 err = MP_ZERO_E; 05307 } 05308 } 05309 05310 /* read hash */ 05311 if (err == MP_OKAY) { 05312 /* we may need to truncate if hash is longer than key size */ 05313 unsigned int orderBits = mp_count_bits(curve->order); 05314 05315 /* truncate down to byte size, may be all that's needed */ 05316 if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 05317 hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; 05318 err = mp_read_unsigned_bin(e, hash, hashlen); 05319 05320 /* may still need bit truncation too */ 05321 if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits) 05322 mp_rshb(e, WOLFSSL_BIT_SIZE - (orderBits & 0x7)); 05323 } 05324 05325 /* check for async hardware acceleration */ 05326 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) 05327 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { 05328 #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA) 05329 #ifdef HAVE_CAVIUM_V 05330 if (NitroxEccIsCurveSupported(key)) 05331 #endif 05332 { 05333 word32 keySz = key->dp->size; 05334 05335 err = wc_mp_to_bigint_sz(e, &e->raw, keySz); 05336 if (err == MP_OKAY) 05337 err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz); 05338 if (err == MP_OKAY) 05339 err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz); 05340 if (err == MP_OKAY) 05341 #ifdef HAVE_CAVIUM_V 05342 err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw, 05343 &key->pubkey.y->raw, &r->raw, &s->raw, 05344 &curve->prime->raw, &curve->order->raw, res); 05345 #else 05346 err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw, 05347 &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw, 05348 &curve->Bf->raw, &curve->prime->raw, &curve->order->raw, 05349 &curve->Gx->raw, &curve->Gy->raw, res); 05350 #endif 05351 05352 #ifndef HAVE_CAVIUM_V 05353 mp_clear(e); 05354 #endif 05355 wc_ecc_curve_free(curve); 05356 FREE_CURVE_SPECS(); 05357 05358 return err; 05359 } 05360 #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */ 05361 } 05362 #endif /* WOLFSSL_ASYNC_CRYPT */ 05363 05364 #ifdef WOLFSSL_SMALL_STACK 05365 if (err == MP_OKAY) { 05366 v = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05367 if (v == NULL) 05368 err = MEMORY_E; 05369 } 05370 if (err == MP_OKAY) { 05371 w = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05372 if (w == NULL) 05373 err = MEMORY_E; 05374 } 05375 if (err == MP_OKAY) { 05376 u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05377 if (u1 == NULL) 05378 err = MEMORY_E; 05379 } 05380 if (err == MP_OKAY) { 05381 u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 05382 if (u2 == NULL) 05383 err = MEMORY_E; 05384 } 05385 #endif 05386 05387 /* allocate ints */ 05388 if (err == MP_OKAY) { 05389 if ((err = mp_init_multi(v, w, u1, u2, NULL, NULL)) != MP_OKAY) { 05390 err = MEMORY_E; 05391 } 05392 did_init = 1; 05393 } 05394 05395 /* allocate points */ 05396 if (err == MP_OKAY) { 05397 mG = wc_ecc_new_point_h(key->heap); 05398 mQ = wc_ecc_new_point_h(key->heap); 05399 if (mQ == NULL || mG == NULL) 05400 err = MEMORY_E; 05401 } 05402 05403 /* w = s^-1 mod n */ 05404 if (err == MP_OKAY) 05405 err = mp_invmod(s, curve->order, w); 05406 05407 /* u1 = ew */ 05408 if (err == MP_OKAY) 05409 err = mp_mulmod(e, w, curve->order, u1); 05410 05411 /* u2 = rw */ 05412 if (err == MP_OKAY) 05413 err = mp_mulmod(r, w, curve->order, u2); 05414 05415 /* find mG and mQ */ 05416 if (err == MP_OKAY) 05417 err = mp_copy(curve->Gx, mG->x); 05418 if (err == MP_OKAY) 05419 err = mp_copy(curve->Gy, mG->y); 05420 if (err == MP_OKAY) 05421 err = mp_set(mG->z, 1); 05422 05423 if (err == MP_OKAY) 05424 err = mp_copy(key->pubkey.x, mQ->x); 05425 if (err == MP_OKAY) 05426 err = mp_copy(key->pubkey.y, mQ->y); 05427 if (err == MP_OKAY) 05428 err = mp_copy(key->pubkey.z, mQ->z); 05429 05430 #ifdef FREESCALE_LTC_ECC 05431 /* use PKHA to compute u1*mG + u2*mQ */ 05432 if (err == MP_OKAY) 05433 err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap); 05434 if (err == MP_OKAY) 05435 err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap); 05436 if (err == MP_OKAY) 05437 err = wc_ecc_point_add(mG, mQ, mG, curve->prime); 05438 #else 05439 #ifndef ECC_SHAMIR 05440 { 05441 mp_digit mp = 0; 05442 05443 /* compute u1*mG + u2*mQ = mG */ 05444 if (err == MP_OKAY) { 05445 err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, 05446 key->heap); 05447 } 05448 if (err == MP_OKAY) { 05449 err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, 05450 key->heap); 05451 } 05452 05453 /* find the montgomery mp */ 05454 if (err == MP_OKAY) 05455 err = mp_montgomery_setup(curve->prime, &mp); 05456 05457 /* add them */ 05458 if (err == MP_OKAY) 05459 err = ecc_projective_add_point(mQ, mG, mG, curve->Af, 05460 curve->prime, mp); 05461 05462 /* reduce */ 05463 if (err == MP_OKAY) 05464 err = ecc_map(mG, curve->prime, mp); 05465 } 05466 #else 05467 /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ 05468 if (err == MP_OKAY) { 05469 err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime, 05470 key->heap); 05471 } 05472 #endif /* ECC_SHAMIR */ 05473 #endif /* FREESCALE_LTC_ECC */ 05474 /* v = X_x1 mod n */ 05475 if (err == MP_OKAY) 05476 err = mp_mod(mG->x, curve->order, v); 05477 05478 /* does v == r */ 05479 if (err == MP_OKAY) { 05480 if (mp_cmp(v, r) == MP_EQ) 05481 *res = 1; 05482 } 05483 05484 /* cleanup */ 05485 wc_ecc_del_point_h(mG, key->heap); 05486 wc_ecc_del_point_h(mQ, key->heap); 05487 05488 mp_clear(e); 05489 if (did_init) { 05490 mp_clear(v); 05491 mp_clear(w); 05492 mp_clear(u1); 05493 mp_clear(u2); 05494 } 05495 #ifdef WOLFSSL_SMALL_STACK 05496 XFREE(u2, key->heap, DYNAMIC_TYPE_ECC); 05497 XFREE(u1, key->heap, DYNAMIC_TYPE_ECC); 05498 XFREE(w, key->heap, DYNAMIC_TYPE_ECC); 05499 XFREE(v, key->heap, DYNAMIC_TYPE_ECC); 05500 #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V) 05501 XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC); 05502 #endif 05503 #endif 05504 05505 wc_ecc_curve_free(curve); 05506 FREE_CURVE_SPECS(); 05507 05508 #endif /* WOLFSSL_SP_MATH */ 05509 #endif /* WOLFSSL_ATECC508A */ 05510 05511 return err; 05512 } 05513 #endif /* HAVE_ECC_VERIFY */ 05514 05515 #ifdef HAVE_ECC_KEY_IMPORT 05516 /* import point from der */ 05517 int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, 05518 ecc_point* point) 05519 { 05520 int err = 0; 05521 #ifndef WOLFSSL_ATECC508A 05522 int compressed = 0; 05523 int keysize; 05524 byte pointType; 05525 05526 if (in == NULL || point == NULL || (curve_idx < 0) || 05527 (wc_ecc_is_valid_idx(curve_idx) == 0)) 05528 return ECC_BAD_ARG_E; 05529 05530 /* must be odd */ 05531 if ((inLen & 1) == 0) { 05532 return ECC_BAD_ARG_E; 05533 } 05534 05535 /* init point */ 05536 #ifdef ALT_ECC_SIZE 05537 point->x = (mp_int*)&point->xyz[0]; 05538 point->y = (mp_int*)&point->xyz[1]; 05539 point->z = (mp_int*)&point->xyz[2]; 05540 alt_fp_init(point->x); 05541 alt_fp_init(point->y); 05542 alt_fp_init(point->z); 05543 #else 05544 err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL); 05545 #endif 05546 if (err != MP_OKAY) 05547 return MEMORY_E; 05548 05549 /* check for point type (4, 2, or 3) */ 05550 pointType = in[0]; 05551 if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN && 05552 pointType != ECC_POINT_COMP_ODD) { 05553 err = ASN_PARSE_E; 05554 } 05555 05556 if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { 05557 #ifdef HAVE_COMP_KEY 05558 compressed = 1; 05559 #else 05560 err = NOT_COMPILED_IN; 05561 #endif 05562 } 05563 05564 /* adjust to skip first byte */ 05565 inLen -= 1; 05566 in += 1; 05567 05568 /* calculate key size based on inLen / 2 */ 05569 keysize = inLen>>1; 05570 05571 #ifdef WOLFSSL_ATECC508A 05572 /* populate key->pubkey_raw */ 05573 XMEMCPY(key->pubkey_raw, (byte*)in, sizeof(key->pubkey_raw)); 05574 #endif 05575 05576 /* read data */ 05577 if (err == MP_OKAY) 05578 err = mp_read_unsigned_bin(point->x, (byte*)in, keysize); 05579 05580 #ifdef HAVE_COMP_KEY 05581 if (err == MP_OKAY && compressed == 1) { /* build y */ 05582 #ifndef WOLFSSL_SP_MATH 05583 int did_init = 0; 05584 mp_int t1, t2; 05585 DECLARE_CURVE_SPECS(curve, 3); 05586 05587 ALLOC_CURVE_SPECS(3); 05588 05589 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) 05590 err = MEMORY_E; 05591 else 05592 did_init = 1; 05593 05594 /* load curve info */ 05595 if (err == MP_OKAY) 05596 err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, 05597 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | 05598 ECC_CURVE_FIELD_BF)); 05599 05600 /* compute x^3 */ 05601 if (err == MP_OKAY) 05602 err = mp_sqr(point->x, &t1); 05603 if (err == MP_OKAY) 05604 err = mp_mulmod(&t1, point->x, curve->prime, &t1); 05605 05606 /* compute x^3 + a*x */ 05607 if (err == MP_OKAY) 05608 err = mp_mulmod(curve->Af, point->x, curve->prime, &t2); 05609 if (err == MP_OKAY) 05610 err = mp_add(&t1, &t2, &t1); 05611 05612 /* compute x^3 + a*x + b */ 05613 if (err == MP_OKAY) 05614 err = mp_add(&t1, curve->Bf, &t1); 05615 05616 /* compute sqrt(x^3 + a*x + b) */ 05617 if (err == MP_OKAY) 05618 err = mp_sqrtmod_prime(&t1, curve->prime, &t2); 05619 05620 /* adjust y */ 05621 if (err == MP_OKAY) { 05622 if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) || 05623 (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) { 05624 err = mp_mod(&t2, curve->prime, point->y); 05625 } 05626 else { 05627 err = mp_submod(curve->prime, &t2, curve->prime, point->y); 05628 } 05629 } 05630 05631 if (did_init) { 05632 mp_clear(&t2); 05633 mp_clear(&t1); 05634 } 05635 05636 wc_ecc_curve_free(curve); 05637 FREE_CURVE_SPECS(); 05638 #else 05639 sp_ecc_uncompress_256(point->x, pointType, point->y); 05640 #endif 05641 } 05642 #endif 05643 05644 if (err == MP_OKAY && compressed == 0) 05645 err = mp_read_unsigned_bin(point->y, (byte*)in + keysize, keysize); 05646 if (err == MP_OKAY) 05647 err = mp_set(point->z, 1); 05648 05649 if (err != MP_OKAY) { 05650 mp_clear(point->x); 05651 mp_clear(point->y); 05652 mp_clear(point->z); 05653 } 05654 05655 #else 05656 err = NOT_COMPILED_IN; 05657 (void)in; 05658 (void)inLen; 05659 (void)curve_idx; 05660 (void)point; 05661 #endif /* !WOLFSSL_ATECC508A */ 05662 05663 return err; 05664 } 05665 #endif /* HAVE_ECC_KEY_IMPORT */ 05666 05667 #ifdef HAVE_ECC_KEY_EXPORT 05668 /* export point to der */ 05669 int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, 05670 word32* outLen) 05671 { 05672 int ret = MP_OKAY; 05673 word32 numlen; 05674 #ifndef WOLFSSL_ATECC508A 05675 #ifdef WOLFSSL_SMALL_STACK 05676 byte* buf; 05677 #else 05678 byte buf[ECC_BUFSIZE]; 05679 #endif 05680 #endif /* !WOLFSSL_ATECC508A */ 05681 05682 if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) 05683 return ECC_BAD_ARG_E; 05684 05685 /* return length needed only */ 05686 if (point != NULL && out == NULL && outLen != NULL) { 05687 numlen = ecc_sets[curve_idx].size; 05688 *outLen = 1 + 2*numlen; 05689 return LENGTH_ONLY_E; 05690 } 05691 05692 if (point == NULL || out == NULL || outLen == NULL) 05693 return ECC_BAD_ARG_E; 05694 05695 numlen = ecc_sets[curve_idx].size; 05696 05697 if (*outLen < (1 + 2*numlen)) { 05698 *outLen = 1 + 2*numlen; 05699 return BUFFER_E; 05700 } 05701 05702 #ifdef WOLFSSL_ATECC508A 05703 /* TODO: Implement equiv call to ATECC508A */ 05704 ret = BAD_COND_E; 05705 05706 #else 05707 05708 /* store byte point type */ 05709 out[0] = ECC_POINT_UNCOMP; 05710 05711 #ifdef WOLFSSL_SMALL_STACK 05712 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 05713 if (buf == NULL) 05714 return MEMORY_E; 05715 #endif 05716 05717 /* pad and store x */ 05718 XMEMSET(buf, 0, ECC_BUFSIZE); 05719 ret = mp_to_unsigned_bin(point->x, buf + 05720 (numlen - mp_unsigned_bin_size(point->x))); 05721 if (ret != MP_OKAY) 05722 goto done; 05723 XMEMCPY(out+1, buf, numlen); 05724 05725 /* pad and store y */ 05726 XMEMSET(buf, 0, ECC_BUFSIZE); 05727 ret = mp_to_unsigned_bin(point->y, buf + 05728 (numlen - mp_unsigned_bin_size(point->y))); 05729 if (ret != MP_OKAY) 05730 goto done; 05731 XMEMCPY(out+1+numlen, buf, numlen); 05732 05733 *outLen = 1 + 2*numlen; 05734 05735 done: 05736 #ifdef WOLFSSL_SMALL_STACK 05737 XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER); 05738 #endif 05739 #endif /* WOLFSSL_ATECC508A */ 05740 05741 return ret; 05742 } 05743 05744 05745 /* export public ECC key in ANSI X9.63 format */ 05746 int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) 05747 { 05748 int ret = MP_OKAY; 05749 word32 numlen; 05750 #ifdef WOLFSSL_SMALL_STACK 05751 byte* buf; 05752 #else 05753 byte buf[ECC_BUFSIZE]; 05754 #endif 05755 word32 pubxlen, pubylen; 05756 05757 /* return length needed only */ 05758 if (key != NULL && out == NULL && outLen != NULL) { 05759 numlen = key->dp->size; 05760 *outLen = 1 + 2*numlen; 05761 return LENGTH_ONLY_E; 05762 } 05763 05764 if (key == NULL || out == NULL || outLen == NULL) 05765 return ECC_BAD_ARG_E; 05766 05767 if (key->type == ECC_PRIVATEKEY_ONLY) 05768 return ECC_PRIVATEONLY_E; 05769 05770 if (wc_ecc_is_valid_idx(key->idx) == 0) { 05771 return ECC_BAD_ARG_E; 05772 } 05773 numlen = key->dp->size; 05774 05775 /* verify room in out buffer */ 05776 if (*outLen < (1 + 2*numlen)) { 05777 *outLen = 1 + 2*numlen; 05778 return BUFFER_E; 05779 } 05780 05781 /* verify public key length is less than key size */ 05782 pubxlen = mp_unsigned_bin_size(key->pubkey.x); 05783 pubylen = mp_unsigned_bin_size(key->pubkey.y); 05784 if ((pubxlen > numlen) || (pubylen > numlen)) { 05785 WOLFSSL_MSG("Public key x/y invalid!"); 05786 return BUFFER_E; 05787 } 05788 05789 /* store byte point type */ 05790 out[0] = ECC_POINT_UNCOMP; 05791 05792 #ifdef WOLFSSL_SMALL_STACK 05793 buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 05794 if (buf == NULL) 05795 return MEMORY_E; 05796 #endif 05797 05798 /* pad and store x */ 05799 XMEMSET(buf, 0, ECC_BUFSIZE); 05800 ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen)); 05801 if (ret != MP_OKAY) 05802 goto done; 05803 XMEMCPY(out+1, buf, numlen); 05804 05805 /* pad and store y */ 05806 XMEMSET(buf, 0, ECC_BUFSIZE); 05807 ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen)); 05808 if (ret != MP_OKAY) 05809 goto done; 05810 XMEMCPY(out+1+numlen, buf, numlen); 05811 05812 *outLen = 1 + 2*numlen; 05813 05814 done: 05815 #ifdef WOLFSSL_SMALL_STACK 05816 XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER); 05817 #endif 05818 05819 return ret; 05820 } 05821 05822 05823 /* export public ECC key in ANSI X9.63 format, extended with 05824 * compression option */ 05825 int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, 05826 int compressed) 05827 { 05828 if (compressed == 0) 05829 return wc_ecc_export_x963(key, out, outLen); 05830 #ifdef HAVE_COMP_KEY 05831 else 05832 return wc_ecc_export_x963_compressed(key, out, outLen); 05833 #else 05834 return NOT_COMPILED_IN; 05835 #endif 05836 } 05837 #endif /* HAVE_ECC_KEY_EXPORT */ 05838 05839 05840 #ifndef WOLFSSL_ATECC508A 05841 05842 /* is ecc point on curve described by dp ? */ 05843 int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) 05844 { 05845 #ifndef WOLFSSL_SP_MATH 05846 int err; 05847 #ifdef WOLFSSL_SMALL_STACK 05848 mp_int* t1 = NULL; 05849 mp_int* t2 = NULL; 05850 #else 05851 mp_int t1[1], t2[1]; 05852 #endif 05853 05854 #ifdef WOLFSSL_SMALL_STACK 05855 t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 05856 if (t1 == NULL) 05857 return MEMORY_E; 05858 t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 05859 if (t2 == NULL) { 05860 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 05861 return MEMORY_E; 05862 } 05863 #endif 05864 05865 if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { 05866 #ifdef WOLFSSL_SMALL_STACK 05867 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 05868 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 05869 #endif 05870 return err; 05871 } 05872 05873 /* compute y^2 */ 05874 if (err == MP_OKAY) 05875 err = mp_sqr(ecp->y, t1); 05876 05877 /* compute x^3 */ 05878 if (err == MP_OKAY) 05879 err = mp_sqr(ecp->x, t2); 05880 if (err == MP_OKAY) 05881 err = mp_mod(t2, prime, t2); 05882 if (err == MP_OKAY) 05883 err = mp_mul(ecp->x, t2, t2); 05884 05885 /* compute y^2 - x^3 */ 05886 if (err == MP_OKAY) 05887 err = mp_sub(t1, t2, t1); 05888 05889 /* Determine if curve "a" should be used in calc */ 05890 #ifdef WOLFSSL_CUSTOM_CURVES 05891 if (err == MP_OKAY) { 05892 /* Use a and prime to determine if a == 3 */ 05893 err = mp_set(t2, 0); 05894 if (err == MP_OKAY) 05895 err = mp_submod(prime, a, prime, t2); 05896 } 05897 if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) { 05898 /* compute y^2 - x^3 + a*x */ 05899 if (err == MP_OKAY) 05900 err = mp_mulmod(t2, ecp->x, prime, t2); 05901 if (err == MP_OKAY) 05902 err = mp_addmod(t1, t2, prime, t1); 05903 } 05904 else 05905 #endif /* WOLFSSL_CUSTOM_CURVES */ 05906 { 05907 /* assumes "a" == 3 */ 05908 (void)a; 05909 05910 /* compute y^2 - x^3 + 3x */ 05911 if (err == MP_OKAY) 05912 err = mp_add(t1, ecp->x, t1); 05913 if (err == MP_OKAY) 05914 err = mp_add(t1, ecp->x, t1); 05915 if (err == MP_OKAY) 05916 err = mp_add(t1, ecp->x, t1); 05917 if (err == MP_OKAY) 05918 err = mp_mod(t1, prime, t1); 05919 } 05920 05921 /* adjust range (0, prime) */ 05922 while (err == MP_OKAY && mp_isneg(t1)) { 05923 err = mp_add(t1, prime, t1); 05924 } 05925 while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) { 05926 err = mp_sub(t1, prime, t1); 05927 } 05928 05929 /* compare to b */ 05930 if (err == MP_OKAY) { 05931 if (mp_cmp(t1, b) != MP_EQ) { 05932 err = MP_VAL; 05933 } else { 05934 err = MP_OKAY; 05935 } 05936 } 05937 05938 mp_clear(t1); 05939 mp_clear(t2); 05940 #ifdef WOLFSSL_SMALL_STACK 05941 XFREE(t2, NULL, DYNAMIC_TYPE_ECC); 05942 XFREE(t1, NULL, DYNAMIC_TYPE_ECC); 05943 #endif 05944 05945 return err; 05946 #else 05947 (void)a; 05948 (void)b; 05949 (void)prime; 05950 05951 return sp_ecc_is_point_256(ecp->x, ecp->y); 05952 #endif 05953 } 05954 05955 #ifndef WOLFSSL_SP_MATH 05956 /* validate privkey * generator == pubkey, 0 on success */ 05957 static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) 05958 { 05959 int err = MP_OKAY; 05960 ecc_point* base = NULL; 05961 ecc_point* res = NULL; 05962 DECLARE_CURVE_SPECS(curve, 2); 05963 05964 if (key == NULL) 05965 return BAD_FUNC_ARG; 05966 05967 ALLOC_CURVE_SPECS(2); 05968 05969 res = wc_ecc_new_point_h(key->heap); 05970 if (res == NULL) 05971 err = MEMORY_E; 05972 05973 #ifdef WOLFSSL_HAVE_SP_ECC 05974 #ifndef WOLFSSL_SP_NO_256 05975 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { 05976 if (err == MP_OKAY) 05977 err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap); 05978 } 05979 else 05980 #endif 05981 #endif 05982 { 05983 base = wc_ecc_new_point_h(key->heap); 05984 if (base == NULL) 05985 err = MEMORY_E; 05986 05987 if (err == MP_OKAY) { 05988 /* load curve info */ 05989 err = wc_ecc_curve_load(key->dp, &curve, 05990 (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY)); 05991 } 05992 05993 /* set up base generator */ 05994 if (err == MP_OKAY) 05995 err = mp_copy(curve->Gx, base->x); 05996 if (err == MP_OKAY) 05997 err = mp_copy(curve->Gy, base->y); 05998 if (err == MP_OKAY) 05999 err = mp_set(base->z, 1); 06000 06001 if (err == MP_OKAY) 06002 err = wc_ecc_mulmod_ex(&key->k, base, res, a, prime, 1, key->heap); 06003 } 06004 06005 if (err == MP_OKAY) { 06006 /* compare result to public key */ 06007 if (mp_cmp(res->x, key->pubkey.x) != MP_EQ || 06008 mp_cmp(res->y, key->pubkey.y) != MP_EQ || 06009 mp_cmp(res->z, key->pubkey.z) != MP_EQ) { 06010 /* didn't match */ 06011 err = ECC_PRIV_KEY_E; 06012 } 06013 } 06014 06015 wc_ecc_curve_free(curve); 06016 wc_ecc_del_point_h(res, key->heap); 06017 wc_ecc_del_point_h(base, key->heap); 06018 FREE_CURVE_SPECS(); 06019 06020 return err; 06021 } 06022 #endif 06023 06024 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 06025 06026 /* check privkey generator helper, creates prime needed */ 06027 static int ecc_check_privkey_gen_helper(ecc_key* key) 06028 { 06029 int err; 06030 #ifndef WOLFSSL_ATECC508A 06031 DECLARE_CURVE_SPECS(curve, 2); 06032 #endif 06033 06034 if (key == NULL) 06035 return BAD_FUNC_ARG; 06036 06037 #ifdef WOLFSSL_ATECC508A 06038 /* TODO: Implement equiv call to ATECC508A */ 06039 err = BAD_COND_E; 06040 06041 #else 06042 ALLOC_CURVE_SPECS(2); 06043 06044 /* load curve info */ 06045 err = wc_ecc_curve_load(key->dp, &curve, 06046 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF)); 06047 06048 if (err == MP_OKAY) 06049 err = ecc_check_privkey_gen(key, curve->Af, curve->prime); 06050 06051 wc_ecc_curve_free(curve); 06052 FREE_CURVE_SPECS(); 06053 06054 #endif /* WOLFSSL_ATECC508A */ 06055 06056 return err; 06057 } 06058 06059 #endif /* WOLFSSL_VALIDATE_ECC_IMPORT */ 06060 06061 06062 #if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH) 06063 /* validate order * pubkey = point at infinity, 0 on success */ 06064 static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, 06065 mp_int* prime, mp_int* order) 06066 { 06067 ecc_point* inf = NULL; 06068 int err; 06069 06070 if (key == NULL) 06071 return BAD_FUNC_ARG; 06072 06073 inf = wc_ecc_new_point_h(key->heap); 06074 if (inf == NULL) 06075 err = MEMORY_E; 06076 else { 06077 #ifdef WOLFSSL_HAVE_SP_ECC 06078 #ifndef WOLFSSL_SP_NO_256 06079 if (key->idx != ECC_CUSTOM_IDX && 06080 ecc_sets[key->idx].id == ECC_SECP256R1) { 06081 err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap); 06082 } 06083 else 06084 #endif 06085 #endif 06086 #ifndef WOLFSSL_SP_MATH 06087 err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap); 06088 if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) 06089 err = ECC_INF_E; 06090 #else 06091 (void)a; 06092 (void)prime; 06093 06094 err = WC_KEY_SIZE_E; 06095 #endif 06096 } 06097 06098 wc_ecc_del_point_h(inf, key->heap); 06099 06100 return err; 06101 } 06102 #endif 06103 #endif /* !WOLFSSL_ATECC508A */ 06104 06105 06106 /* perform sanity checks on ecc key validity, 0 on success */ 06107 int wc_ecc_check_key(ecc_key* key) 06108 { 06109 int err; 06110 #ifndef WOLFSSL_SP_MATH 06111 #ifndef WOLFSSL_ATECC508A 06112 mp_int* b = NULL; 06113 #ifdef USE_ECC_B_PARAM 06114 DECLARE_CURVE_SPECS(curve, 4); 06115 #else 06116 #ifndef WOLFSSL_SMALL_STACK 06117 mp_int b_lcl; 06118 #endif 06119 DECLARE_CURVE_SPECS(curve, 3); 06120 #endif /* USE_ECC_B_PARAM */ 06121 #endif /* WOLFSSL_ATECC508A */ 06122 06123 if (key == NULL) 06124 return BAD_FUNC_ARG; 06125 06126 #ifdef WOLFSSL_ATECC508A 06127 06128 if (key->slot == ATECC_INVALID_SLOT) 06129 return ECC_BAD_ARG_E; 06130 06131 err = 0; /* consider key check success on ECC508A */ 06132 06133 #else 06134 #ifdef USE_ECC_B_PARAM 06135 ALLOC_CURVE_SPECS(4); 06136 #else 06137 ALLOC_CURVE_SPECS(3); 06138 #ifndef WOLFSSL_SMALL_STACK 06139 b = &b_lcl; 06140 #else 06141 b = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC); 06142 if (b == NULL) { 06143 FREE_CURVE_SPECS(); 06144 return MEMORY_E; 06145 } 06146 #endif 06147 XMEMSET(b, 0, sizeof(mp_int)); 06148 #endif 06149 06150 /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */ 06151 /* pubkey point cannot be at infinity */ 06152 if (wc_ecc_point_is_at_infinity(&key->pubkey)) { 06153 #ifdef WOLFSSL_SMALL_STACK 06154 XFREE(b, key->heap, DYNAMIC_TYPE_ECC); 06155 #endif 06156 FREE_CURVE_SPECS(); 06157 return ECC_INF_E; 06158 } 06159 06160 /* load curve info */ 06161 err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME | 06162 ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER 06163 #ifdef USE_ECC_B_PARAM 06164 | ECC_CURVE_FIELD_BF 06165 #endif 06166 )); 06167 06168 #ifndef USE_ECC_B_PARAM 06169 /* load curve b parameter */ 06170 if (err == MP_OKAY) 06171 err = mp_init(b); 06172 if (err == MP_OKAY) 06173 err = mp_read_radix(b, key->dp->Bf, MP_RADIX_HEX); 06174 #else 06175 b = curve->Bf; 06176 #endif 06177 06178 /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */ 06179 /* Qx must be in the range [0, p-1] */ 06180 if (mp_cmp(key->pubkey.x, curve->prime) != MP_LT) 06181 err = ECC_OUT_OF_RANGE_E; 06182 06183 /* Qy must be in the range [0, p-1] */ 06184 if (mp_cmp(key->pubkey.y, curve->prime) != MP_LT) 06185 err = ECC_OUT_OF_RANGE_E; 06186 06187 /* SP 800-56Ar3, section 5.6.2.3.3, process steps 3 */ 06188 /* make sure point is actually on curve */ 06189 if (err == MP_OKAY) 06190 err = wc_ecc_is_point(&key->pubkey, curve->Af, b, curve->prime); 06191 06192 /* SP 800-56Ar3, section 5.6.2.3.3, process steps 4 */ 06193 /* pubkey * order must be at infinity */ 06194 if (err == MP_OKAY) 06195 err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af, curve->prime, 06196 curve->order); 06197 06198 /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */ 06199 /* private * base generator must equal pubkey */ 06200 if (err == MP_OKAY && key->type == ECC_PRIVATEKEY) 06201 err = ecc_check_privkey_gen(key, curve->Af, curve->prime); 06202 06203 wc_ecc_curve_free(curve); 06204 06205 #ifndef USE_ECC_B_PARAM 06206 mp_clear(b); 06207 #ifdef WOLFSSL_SMALL_STACK 06208 XFREE(b, key->heap, DYNAMIC_TYPE_ECC); 06209 #endif 06210 #endif 06211 06212 FREE_CURVE_SPECS(); 06213 06214 #endif /* WOLFSSL_ATECC508A */ 06215 #else 06216 if (key == NULL) 06217 return BAD_FUNC_ARG; 06218 06219 /* pubkey point cannot be at infinity */ 06220 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { 06221 err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k, 06222 key->heap); 06223 } 06224 else 06225 err = WC_KEY_SIZE_E; 06226 #endif 06227 06228 return err; 06229 } 06230 06231 #ifdef HAVE_ECC_KEY_IMPORT 06232 /* import public ECC key in ANSI X9.63 format */ 06233 int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, 06234 int curve_id) 06235 { 06236 int err = MP_OKAY; 06237 int compressed = 0; 06238 int keysize = 0; 06239 byte pointType; 06240 06241 if (in == NULL || key == NULL) 06242 return BAD_FUNC_ARG; 06243 06244 /* must be odd */ 06245 if ((inLen & 1) == 0) { 06246 return ECC_BAD_ARG_E; 06247 } 06248 06249 /* make sure required variables are reset */ 06250 wc_ecc_reset(key); 06251 06252 /* init key */ 06253 #ifdef ALT_ECC_SIZE 06254 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 06255 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 06256 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 06257 alt_fp_init(key->pubkey.x); 06258 alt_fp_init(key->pubkey.y); 06259 alt_fp_init(key->pubkey.z); 06260 err = mp_init(&key->k); 06261 #else 06262 err = mp_init_multi(&key->k, 06263 key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL); 06264 #endif 06265 if (err != MP_OKAY) 06266 return MEMORY_E; 06267 06268 /* check for point type (4, 2, or 3) */ 06269 pointType = in[0]; 06270 if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN && 06271 pointType != ECC_POINT_COMP_ODD) { 06272 err = ASN_PARSE_E; 06273 } 06274 06275 if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { 06276 #ifdef HAVE_COMP_KEY 06277 compressed = 1; 06278 #else 06279 err = NOT_COMPILED_IN; 06280 #endif 06281 } 06282 06283 /* adjust to skip first byte */ 06284 inLen -= 1; 06285 in += 1; 06286 06287 if (err == MP_OKAY) { 06288 #ifdef HAVE_COMP_KEY 06289 /* adjust inLen if compressed */ 06290 if (compressed) 06291 inLen = inLen*2 + 1; /* used uncompressed len */ 06292 #endif 06293 06294 /* determine key size */ 06295 keysize = (inLen>>1); 06296 err = wc_ecc_set_curve(key, keysize, curve_id); 06297 key->type = ECC_PUBLICKEY; 06298 } 06299 06300 /* read data */ 06301 if (err == MP_OKAY) 06302 err = mp_read_unsigned_bin(key->pubkey.x, (byte*)in, keysize); 06303 06304 #ifdef HAVE_COMP_KEY 06305 if (err == MP_OKAY && compressed == 1) { /* build y */ 06306 #ifndef WOLFSSL_SP_MATH 06307 mp_int t1, t2; 06308 int did_init = 0; 06309 06310 DECLARE_CURVE_SPECS(curve, 3); 06311 ALLOC_CURVE_SPECS(3); 06312 06313 if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) 06314 err = MEMORY_E; 06315 else 06316 did_init = 1; 06317 06318 /* load curve info */ 06319 if (err == MP_OKAY) 06320 err = wc_ecc_curve_load(key->dp, &curve, 06321 (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | 06322 ECC_CURVE_FIELD_BF)); 06323 06324 /* compute x^3 */ 06325 if (err == MP_OKAY) 06326 err = mp_sqr(key->pubkey.x, &t1); 06327 if (err == MP_OKAY) 06328 err = mp_mulmod(&t1, key->pubkey.x, curve->prime, &t1); 06329 06330 /* compute x^3 + a*x */ 06331 if (err == MP_OKAY) 06332 err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, &t2); 06333 if (err == MP_OKAY) 06334 err = mp_add(&t1, &t2, &t1); 06335 06336 /* compute x^3 + a*x + b */ 06337 if (err == MP_OKAY) 06338 err = mp_add(&t1, curve->Bf, &t1); 06339 06340 /* compute sqrt(x^3 + a*x + b) */ 06341 if (err == MP_OKAY) 06342 err = mp_sqrtmod_prime(&t1, curve->prime, &t2); 06343 06344 /* adjust y */ 06345 if (err == MP_OKAY) { 06346 if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) || 06347 (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) { 06348 err = mp_mod(&t2, curve->prime, &t2); 06349 } 06350 else { 06351 err = mp_submod(curve->prime, &t2, curve->prime, &t2); 06352 } 06353 if (err == MP_OKAY) 06354 err = mp_copy(&t2, key->pubkey.y); 06355 } 06356 06357 if (did_init) { 06358 mp_clear(&t2); 06359 mp_clear(&t1); 06360 } 06361 06362 wc_ecc_curve_free(curve); 06363 FREE_CURVE_SPECS(); 06364 #else 06365 sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y); 06366 #endif 06367 } 06368 #endif /* HAVE_COMP_KEY */ 06369 06370 if (err == MP_OKAY && compressed == 0) 06371 err = mp_read_unsigned_bin(key->pubkey.y, (byte*)in + keysize, keysize); 06372 if (err == MP_OKAY) 06373 err = mp_set(key->pubkey.z, 1); 06374 06375 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 06376 if (err == MP_OKAY) 06377 err = wc_ecc_check_key(key); 06378 #endif 06379 06380 if (err != MP_OKAY) { 06381 mp_clear(key->pubkey.x); 06382 mp_clear(key->pubkey.y); 06383 mp_clear(key->pubkey.z); 06384 mp_clear(&key->k); 06385 } 06386 06387 return err; 06388 } 06389 06390 int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) 06391 { 06392 return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); 06393 } 06394 #endif /* HAVE_ECC_KEY_IMPORT */ 06395 06396 #ifdef HAVE_ECC_KEY_EXPORT 06397 /* export ecc private key only raw, outLen is in/out size 06398 return MP_OKAY on success */ 06399 int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) 06400 { 06401 word32 numlen; 06402 06403 if (key == NULL || out == NULL || outLen == NULL) { 06404 return BAD_FUNC_ARG; 06405 } 06406 06407 if (wc_ecc_is_valid_idx(key->idx) == 0) { 06408 return ECC_BAD_ARG_E; 06409 } 06410 numlen = key->dp->size; 06411 06412 if (*outLen < numlen) { 06413 *outLen = numlen; 06414 return BUFFER_E; 06415 } 06416 *outLen = numlen; 06417 XMEMSET(out, 0, *outLen); 06418 06419 #ifdef WOLFSSL_ATECC508A 06420 /* TODO: Implement equiv call to ATECC508A */ 06421 return BAD_COND_E; 06422 06423 #else 06424 06425 return mp_to_unsigned_bin(&key->k, out + (numlen - 06426 mp_unsigned_bin_size(&key->k))); 06427 #endif /* WOLFSSL_ATECC508A */ 06428 } 06429 06430 06431 /* export ecc key to component form, d is optional if only exporting public 06432 * return MP_OKAY on success */ 06433 static int wc_ecc_export_raw(ecc_key* key, byte* qx, word32* qxLen, 06434 byte* qy, word32* qyLen, byte* d, word32* dLen) 06435 { 06436 int err; 06437 byte exportPriv = 0; 06438 word32 numLen; 06439 06440 if (key == NULL || qx == NULL || qxLen == NULL || qy == NULL || 06441 qyLen == NULL) { 06442 return BAD_FUNC_ARG; 06443 } 06444 06445 if (key->type == ECC_PRIVATEKEY_ONLY) { 06446 return ECC_PRIVATEONLY_E; 06447 } 06448 06449 if (wc_ecc_is_valid_idx(key->idx) == 0) { 06450 return ECC_BAD_ARG_E; 06451 } 06452 numLen = key->dp->size; 06453 06454 if (d != NULL) { 06455 if (dLen == NULL || key->type != ECC_PRIVATEKEY) 06456 return BAD_FUNC_ARG; 06457 exportPriv = 1; 06458 } 06459 06460 /* check public buffer sizes */ 06461 if ((*qxLen < numLen) || (*qyLen < numLen)) { 06462 *qxLen = numLen; 06463 *qyLen = numLen; 06464 return BUFFER_E; 06465 } 06466 06467 *qxLen = numLen; 06468 *qyLen = numLen; 06469 06470 XMEMSET(qx, 0, *qxLen); 06471 XMEMSET(qy, 0, *qyLen); 06472 06473 /* private d component */ 06474 if (exportPriv == 1) { 06475 06476 /* check private buffer size */ 06477 if (*dLen < numLen) { 06478 *dLen = numLen; 06479 return BUFFER_E; 06480 } 06481 06482 *dLen = numLen; 06483 XMEMSET(d, 0, *dLen); 06484 06485 #ifdef WOLFSSL_ATECC508A 06486 /* TODO: Implement equiv call to ATECC508A */ 06487 return BAD_COND_E; 06488 06489 #else 06490 06491 /* private key, d */ 06492 err = mp_to_unsigned_bin(&key->k, d + 06493 (numLen - mp_unsigned_bin_size(&key->k))); 06494 if (err != MP_OKAY) 06495 return err; 06496 #endif /* WOLFSSL_ATECC508A */ 06497 } 06498 06499 /* public x component */ 06500 err = mp_to_unsigned_bin(key->pubkey.x, qx + 06501 (numLen - mp_unsigned_bin_size(key->pubkey.x))); 06502 if (err != MP_OKAY) 06503 return err; 06504 06505 /* public y component */ 06506 err = mp_to_unsigned_bin(key->pubkey.y, qy + 06507 (numLen - mp_unsigned_bin_size(key->pubkey.y))); 06508 if (err != MP_OKAY) 06509 return err; 06510 06511 return 0; 06512 } 06513 06514 06515 /* export public key to raw elements including public (Qx,Qy) 06516 * return MP_OKAY on success, negative on error */ 06517 int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen, 06518 byte* qy, word32* qyLen) 06519 { 06520 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, NULL, NULL); 06521 } 06522 06523 06524 /* export ecc key to raw elements including public (Qx,Qy) and private (d) 06525 * return MP_OKAY on success, negative on error */ 06526 int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen, 06527 byte* qy, word32* qyLen, byte* d, word32* dLen) 06528 { 06529 /* sanitize d and dLen, other args are checked later */ 06530 if (d == NULL || dLen == NULL) 06531 return BAD_FUNC_ARG; 06532 06533 return wc_ecc_export_raw(key, qx, qxLen, qy, qyLen, d, dLen); 06534 } 06535 06536 #endif /* HAVE_ECC_KEY_EXPORT */ 06537 06538 #ifdef HAVE_ECC_KEY_IMPORT 06539 /* import private key, public part optional if (pub) passed as NULL */ 06540 int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, 06541 const byte* pub, word32 pubSz, ecc_key* key, 06542 int curve_id) 06543 { 06544 int ret; 06545 word32 idx = 0; 06546 06547 if (key == NULL || priv == NULL) 06548 return BAD_FUNC_ARG; 06549 06550 /* public optional, NULL if only importing private */ 06551 if (pub != NULL) { 06552 ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id); 06553 if (ret < 0) 06554 ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz); 06555 key->type = ECC_PRIVATEKEY; 06556 } 06557 else { 06558 /* make sure required variables are reset */ 06559 wc_ecc_reset(key); 06560 06561 /* set key size */ 06562 ret = wc_ecc_set_curve(key, privSz, curve_id); 06563 key->type = ECC_PRIVATEKEY_ONLY; 06564 } 06565 06566 if (ret != 0) 06567 return ret; 06568 06569 #ifdef WOLFSSL_ATECC508A 06570 /* TODO: Implement equiv call to ATECC508A */ 06571 return BAD_COND_E; 06572 06573 #else 06574 06575 ret = mp_read_unsigned_bin(&key->k, priv, privSz); 06576 06577 #endif /* WOLFSSL_ATECC508A */ 06578 06579 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 06580 if ((pub != NULL) && (ret == MP_OKAY)) 06581 /* public key needed to perform key validation */ 06582 ret = ecc_check_privkey_gen_helper(key); 06583 #endif 06584 06585 return ret; 06586 } 06587 06588 /* ecc private key import, public key in ANSI X9.63 format, private raw */ 06589 int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, 06590 word32 pubSz, ecc_key* key) 06591 { 06592 return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, 06593 ECC_CURVE_DEF); 06594 } 06595 #endif /* HAVE_ECC_KEY_IMPORT */ 06596 06597 #ifndef NO_ASN 06598 /** 06599 Convert ECC R,S to signature 06600 r R component of signature 06601 s S component of signature 06602 out DER-encoded ECDSA signature 06603 outlen [in/out] output buffer size, output signature size 06604 return MP_OKAY on success 06605 */ 06606 int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) 06607 { 06608 int err; 06609 #ifdef WOLFSSL_SMALL_STACK 06610 mp_int* rtmp = NULL; 06611 mp_int* stmp = NULL; 06612 #else 06613 mp_int rtmp[1]; 06614 mp_int stmp[1]; 06615 #endif 06616 06617 if (r == NULL || s == NULL || out == NULL || outlen == NULL) 06618 return ECC_BAD_ARG_E; 06619 06620 #ifdef WOLFSSL_SMALL_STACK 06621 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06622 if (rtmp == NULL) 06623 return MEMORY_E; 06624 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06625 if (stmp == NULL) { 06626 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06627 return MEMORY_E; 06628 } 06629 #endif 06630 06631 err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL); 06632 if (err != MP_OKAY) { 06633 #ifdef WOLFSSL_SMALL_STACK 06634 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); 06635 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06636 #endif 06637 return err; 06638 } 06639 06640 err = mp_read_radix(rtmp, r, MP_RADIX_HEX); 06641 if (err == MP_OKAY) 06642 err = mp_read_radix(stmp, s, MP_RADIX_HEX); 06643 06644 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ 06645 if (err == MP_OKAY) 06646 err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp); 06647 06648 if (err == MP_OKAY) { 06649 if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES) 06650 err = MP_ZERO_E; 06651 } 06652 06653 mp_clear(rtmp); 06654 mp_clear(stmp); 06655 #ifdef WOLFSSL_SMALL_STACK 06656 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); 06657 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06658 #endif 06659 06660 return err; 06661 } 06662 06663 /** 06664 Convert ECC R,S raw unsigned bin to signature 06665 r R component of signature 06666 rSz R size 06667 s S component of signature 06668 sSz S size 06669 out DER-encoded ECDSA signature 06670 outlen [in/out] output buffer size, output signature size 06671 return MP_OKAY on success 06672 */ 06673 int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz, 06674 byte* out, word32* outlen) 06675 { 06676 int err; 06677 #ifdef WOLFSSL_SMALL_STACK 06678 mp_int* rtmp = NULL; 06679 mp_int* stmp = NULL; 06680 #else 06681 mp_int rtmp[1]; 06682 mp_int stmp[1]; 06683 #endif 06684 06685 if (r == NULL || s == NULL || out == NULL || outlen == NULL) 06686 return ECC_BAD_ARG_E; 06687 06688 #ifdef WOLFSSL_SMALL_STACK 06689 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06690 if (rtmp == NULL) 06691 return MEMORY_E; 06692 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06693 if (stmp == NULL) { 06694 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06695 return MEMORY_E; 06696 } 06697 #endif 06698 06699 err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL); 06700 if (err != MP_OKAY) { 06701 #ifdef WOLFSSL_SMALL_STACK 06702 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); 06703 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06704 #endif 06705 return err; 06706 } 06707 06708 err = mp_read_unsigned_bin(rtmp, r, rSz); 06709 if (err == MP_OKAY) 06710 err = mp_read_unsigned_bin(stmp, s, sSz); 06711 06712 /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ 06713 if (err == MP_OKAY) 06714 err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp); 06715 06716 if (err == MP_OKAY) { 06717 if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES) 06718 err = MP_ZERO_E; 06719 } 06720 06721 mp_clear(rtmp); 06722 mp_clear(stmp); 06723 #ifdef WOLFSSL_SMALL_STACK 06724 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); 06725 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06726 #endif 06727 06728 return err; 06729 } 06730 06731 /** 06732 Convert ECC signature to R,S 06733 sig DER-encoded ECDSA signature 06734 sigLen length of signature in octets 06735 r R component of signature 06736 rLen [in/out] output "r" buffer size, output "r" size 06737 s S component of signature 06738 sLen [in/out] output "s" buffer size, output "s" size 06739 return MP_OKAY on success, negative on error 06740 */ 06741 int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, 06742 byte* s, word32* sLen) 06743 { 06744 int err; 06745 word32 x = 0; 06746 #ifdef WOLFSSL_SMALL_STACK 06747 mp_int* rtmp = NULL; 06748 mp_int* stmp = NULL; 06749 #else 06750 mp_int rtmp[1]; 06751 mp_int stmp[1]; 06752 #endif 06753 06754 if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL) 06755 return ECC_BAD_ARG_E; 06756 06757 #ifdef WOLFSSL_SMALL_STACK 06758 rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06759 if (rtmp == NULL) 06760 return MEMORY_E; 06761 stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); 06762 if (stmp == NULL) { 06763 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06764 return MEMORY_E; 06765 } 06766 #endif 06767 06768 err = DecodeECC_DSA_Sig(sig, sigLen, rtmp, stmp); 06769 06770 /* extract r */ 06771 if (err == MP_OKAY) { 06772 x = mp_unsigned_bin_size(rtmp); 06773 if (*rLen < x) 06774 err = BUFFER_E; 06775 06776 if (err == MP_OKAY) { 06777 *rLen = x; 06778 err = mp_to_unsigned_bin(rtmp, r); 06779 } 06780 } 06781 06782 /* extract s */ 06783 if (err == MP_OKAY) { 06784 x = mp_unsigned_bin_size(stmp); 06785 if (*sLen < x) 06786 err = BUFFER_E; 06787 06788 if (err == MP_OKAY) { 06789 *sLen = x; 06790 err = mp_to_unsigned_bin(stmp, s); 06791 } 06792 } 06793 06794 mp_clear(rtmp); 06795 mp_clear(stmp); 06796 #ifdef WOLFSSL_SMALL_STACK 06797 XFREE(stmp, NULL, DYNAMIC_TYPE_ECC); 06798 XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC); 06799 #endif 06800 06801 return err; 06802 } 06803 #endif /* !NO_ASN */ 06804 06805 #ifdef HAVE_ECC_KEY_IMPORT 06806 static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, 06807 const char* qy, const char* d, int curve_id, int encType) 06808 { 06809 int err = MP_OKAY; 06810 06811 /* if d is NULL, only import as public key using Qx,Qy */ 06812 if (key == NULL || qx == NULL || qy == NULL) { 06813 return BAD_FUNC_ARG; 06814 } 06815 06816 /* make sure required variables are reset */ 06817 wc_ecc_reset(key); 06818 06819 /* set curve type and index */ 06820 err = wc_ecc_set_curve(key, 0, curve_id); 06821 if (err != 0) { 06822 return err; 06823 } 06824 06825 #ifdef WOLFSSL_ATECC508A 06826 /* TODO: Implement equiv call to ATECC508A */ 06827 err = BAD_COND_E; 06828 (void)d; 06829 (void)encType; 06830 06831 #else 06832 06833 /* init key */ 06834 #ifdef ALT_ECC_SIZE 06835 key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; 06836 key->pubkey.y = (mp_int*)&key->pubkey.xyz[1]; 06837 key->pubkey.z = (mp_int*)&key->pubkey.xyz[2]; 06838 alt_fp_init(key->pubkey.x); 06839 alt_fp_init(key->pubkey.y); 06840 alt_fp_init(key->pubkey.z); 06841 err = mp_init(&key->k); 06842 #else 06843 err = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z, 06844 NULL, NULL); 06845 #endif 06846 if (err != MP_OKAY) 06847 return MEMORY_E; 06848 06849 /* read Qx */ 06850 if (err == MP_OKAY) { 06851 if (encType == ECC_TYPE_HEX_STR) 06852 err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX); 06853 else 06854 err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx, 06855 key->dp->size); 06856 } 06857 06858 /* read Qy */ 06859 if (err == MP_OKAY) { 06860 if (encType == ECC_TYPE_HEX_STR) 06861 err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX); 06862 else 06863 err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy, 06864 key->dp->size); 06865 06866 } 06867 06868 if (err == MP_OKAY) 06869 err = mp_set(key->pubkey.z, 1); 06870 06871 /* import private key */ 06872 if (err == MP_OKAY) { 06873 if (d != NULL) { 06874 key->type = ECC_PRIVATEKEY; 06875 06876 if (encType == ECC_TYPE_HEX_STR) 06877 err = mp_read_radix(&key->k, d, MP_RADIX_HEX); 06878 else 06879 err = mp_read_unsigned_bin(&key->k, (const byte*)d, 06880 key->dp->size); 06881 06882 } else { 06883 key->type = ECC_PUBLICKEY; 06884 } 06885 } 06886 06887 #ifdef WOLFSSL_VALIDATE_ECC_IMPORT 06888 if (err == MP_OKAY) 06889 err = wc_ecc_check_key(key); 06890 #endif 06891 06892 if (err != MP_OKAY) { 06893 mp_clear(key->pubkey.x); 06894 mp_clear(key->pubkey.y); 06895 mp_clear(key->pubkey.z); 06896 mp_clear(&key->k); 06897 } 06898 #endif /* WOLFSSL_ATECC508A */ 06899 06900 return err; 06901 } 06902 06903 /** 06904 Import raw ECC key 06905 key The destination ecc_key structure 06906 qx x component of the public key, as ASCII hex string 06907 qy y component of the public key, as ASCII hex string 06908 d private key, as ASCII hex string, optional if importing public 06909 key only 06910 dp Custom ecc_set_type 06911 return MP_OKAY on success 06912 */ 06913 int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, 06914 const char* d, int curve_id) 06915 { 06916 return wc_ecc_import_raw_private(key, qx, qy, d, curve_id, 06917 ECC_TYPE_HEX_STR); 06918 06919 } 06920 06921 /* Import x, y and optional private (d) as unsigned binary */ 06922 int wc_ecc_import_unsigned(ecc_key* key, byte* qx, byte* qy, 06923 byte* d, int curve_id) 06924 { 06925 return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy, 06926 (const char*)d, curve_id, ECC_TYPE_UNSIGNED_BIN); 06927 } 06928 06929 /** 06930 Import raw ECC key 06931 key The destination ecc_key structure 06932 qx x component of the public key, as ASCII hex string 06933 qy y component of the public key, as ASCII hex string 06934 d private key, as ASCII hex string, optional if importing public 06935 key only 06936 curveName ECC curve name, from ecc_sets[] 06937 return MP_OKAY on success 06938 */ 06939 int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy, 06940 const char* d, const char* curveName) 06941 { 06942 int err, x; 06943 06944 /* if d is NULL, only import as public key using Qx,Qy */ 06945 if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) { 06946 return BAD_FUNC_ARG; 06947 } 06948 06949 /* set curve type and index */ 06950 for (x = 0; ecc_sets[x].size != 0; x++) { 06951 if (XSTRNCMP(ecc_sets[x].name, curveName, 06952 XSTRLEN(curveName)) == 0) { 06953 break; 06954 } 06955 } 06956 06957 if (ecc_sets[x].size == 0) { 06958 WOLFSSL_MSG("ecc_set curve name not found"); 06959 err = ASN_PARSE_E; 06960 } else { 06961 return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id, 06962 ECC_TYPE_HEX_STR); 06963 } 06964 06965 return err; 06966 } 06967 #endif /* HAVE_ECC_KEY_IMPORT */ 06968 06969 /* key size in octets */ 06970 int wc_ecc_size(ecc_key* key) 06971 { 06972 if (key == NULL) return 0; 06973 06974 return key->dp->size; 06975 } 06976 06977 int wc_ecc_sig_size_calc(int sz) 06978 { 06979 return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ; 06980 } 06981 06982 /* worst case estimate, check actual return from wc_ecc_sign_hash for actual 06983 value of signature size in octets */ 06984 int wc_ecc_sig_size(ecc_key* key) 06985 { 06986 int sz = wc_ecc_size(key); 06987 if (sz <= 0) 06988 return sz; 06989 06990 return wc_ecc_sig_size_calc(sz); 06991 } 06992 06993 06994 #ifdef FP_ECC 06995 06996 /* fixed point ECC cache */ 06997 /* number of entries in the cache */ 06998 #ifndef FP_ENTRIES 06999 #define FP_ENTRIES 15 07000 #endif 07001 07002 /* number of bits in LUT */ 07003 #ifndef FP_LUT 07004 #define FP_LUT 8U 07005 #endif 07006 07007 #ifdef ECC_SHAMIR 07008 /* Sharmir requires a bigger LUT, TAO */ 07009 #if (FP_LUT > 12) || (FP_LUT < 4) 07010 #error FP_LUT must be between 4 and 12 inclusively 07011 #endif 07012 #else 07013 #if (FP_LUT > 12) || (FP_LUT < 2) 07014 #error FP_LUT must be between 2 and 12 inclusively 07015 #endif 07016 #endif 07017 07018 07019 #ifndef WOLFSSL_SP_MATH 07020 07021 /** Our FP cache */ 07022 typedef struct { 07023 ecc_point* g; /* cached COPY of base point */ 07024 ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */ 07025 mp_int mu; /* copy of the montgomery constant */ 07026 int lru_count; /* amount of times this entry has been used */ 07027 int lock; /* flag to indicate cache eviction */ 07028 /* permitted (0) or not (1) */ 07029 } fp_cache_t; 07030 07031 /* if HAVE_THREAD_LS this cache is per thread, no locking needed */ 07032 static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES]; 07033 07034 #ifndef HAVE_THREAD_LS 07035 static volatile int initMutex = 0; /* prevent multiple mutex inits */ 07036 static wolfSSL_Mutex ecc_fp_lock; 07037 #endif /* HAVE_THREAD_LS */ 07038 07039 /* simple table to help direct the generation of the LUT */ 07040 static const struct { 07041 int ham, terma, termb; 07042 } lut_orders[] = { 07043 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 }, 07044 { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 }, 07045 { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 }, 07046 { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 }, 07047 { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 }, 07048 { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 }, 07049 { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 }, 07050 { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 }, 07051 #if FP_LUT > 6 07052 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, 07053 { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, 07054 { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, 07055 { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, 07056 { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, 07057 { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, 07058 { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, 07059 { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, 07060 #if FP_LUT > 7 07061 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, 07062 { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, 07063 { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, 07064 { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, 07065 { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, 07066 { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, 07067 { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, 07068 { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, 07069 { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, 07070 { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, 07071 { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, 07072 { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, 07073 { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, 07074 { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, 07075 { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, 07076 { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, 07077 #if FP_LUT > 8 07078 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, 07079 { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, 07080 { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, 07081 { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, 07082 { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, 07083 { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, 07084 { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, 07085 { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, 07086 { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, 07087 { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, 07088 { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, 07089 { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, 07090 { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, 07091 { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, 07092 { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, 07093 { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, 07094 { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, 07095 { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, 07096 { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, 07097 { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, 07098 { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, 07099 { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, 07100 { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, 07101 { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, 07102 { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, 07103 { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, 07104 { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, 07105 { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, 07106 { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, 07107 { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, 07108 { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, 07109 { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, 07110 #if FP_LUT > 9 07111 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, 07112 { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, 07113 { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, 07114 { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, 07115 { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, 07116 { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, 07117 { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, 07118 { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, 07119 { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, 07120 { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, 07121 { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, 07122 { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, 07123 { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, 07124 { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, 07125 { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, 07126 { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, 07127 { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, 07128 { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, 07129 { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, 07130 { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, 07131 { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, 07132 { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, 07133 { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, 07134 { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, 07135 { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, 07136 { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, 07137 { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, 07138 { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, 07139 { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, 07140 { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, 07141 { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, 07142 { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, 07143 { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, 07144 { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, 07145 { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, 07146 { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, 07147 { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, 07148 { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, 07149 { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, 07150 { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, 07151 { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, 07152 { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, 07153 { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, 07154 { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, 07155 { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, 07156 { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, 07157 { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, 07158 { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, 07159 { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, 07160 { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, 07161 { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, 07162 { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, 07163 { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, 07164 { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, 07165 { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, 07166 { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, 07167 { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, 07168 { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, 07169 { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, 07170 { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, 07171 { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, 07172 { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, 07173 { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, 07174 { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, 07175 #if FP_LUT > 10 07176 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, 07177 { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, 07178 { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, 07179 { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, 07180 { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, 07181 { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, 07182 { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, 07183 { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, 07184 { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, 07185 { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, 07186 { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, 07187 { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, 07188 { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, 07189 { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, 07190 { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, 07191 { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, 07192 { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, 07193 { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, 07194 { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, 07195 { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, 07196 { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, 07197 { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, 07198 { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, 07199 { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, 07200 { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, 07201 { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, 07202 { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, 07203 { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, 07204 { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, 07205 { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, 07206 { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, 07207 { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, 07208 { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, 07209 { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, 07210 { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, 07211 { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, 07212 { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, 07213 { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, 07214 { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, 07215 { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, 07216 { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, 07217 { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, 07218 { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, 07219 { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, 07220 { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, 07221 { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, 07222 { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, 07223 { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, 07224 { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, 07225 { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, 07226 { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, 07227 { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, 07228 { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, 07229 { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, 07230 { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, 07231 { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, 07232 { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, 07233 { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, 07234 { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, 07235 { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, 07236 { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, 07237 { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, 07238 { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, 07239 { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, 07240 { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, 07241 { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, 07242 { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, 07243 { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, 07244 { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, 07245 { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, 07246 { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, 07247 { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, 07248 { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, 07249 { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, 07250 { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, 07251 { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, 07252 { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, 07253 { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, 07254 { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, 07255 { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, 07256 { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, 07257 { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, 07258 { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, 07259 { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, 07260 { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, 07261 { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, 07262 { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, 07263 { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, 07264 { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, 07265 { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, 07266 { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, 07267 { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, 07268 { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, 07269 { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, 07270 { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, 07271 { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, 07272 { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, 07273 { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, 07274 { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, 07275 { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, 07276 { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, 07277 { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, 07278 { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, 07279 { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, 07280 { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, 07281 { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, 07282 { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, 07283 { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, 07284 { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, 07285 { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, 07286 { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, 07287 { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, 07288 { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, 07289 { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, 07290 { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, 07291 { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, 07292 { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, 07293 { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, 07294 { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, 07295 { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, 07296 { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, 07297 { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, 07298 { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, 07299 { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, 07300 { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, 07301 { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, 07302 { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, 07303 { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, 07304 #if FP_LUT > 11 07305 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, 07306 { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, 07307 { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, 07308 { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, 07309 { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, 07310 { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, 07311 { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, 07312 { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, 07313 { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, 07314 { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, 07315 { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, 07316 { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, 07317 { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, 07318 { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, 07319 { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, 07320 { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, 07321 { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, 07322 { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, 07323 { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, 07324 { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, 07325 { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, 07326 { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, 07327 { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, 07328 { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, 07329 { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, 07330 { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, 07331 { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, 07332 { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, 07333 { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, 07334 { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, 07335 { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, 07336 { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, 07337 { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, 07338 { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, 07339 { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, 07340 { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, 07341 { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, 07342 { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, 07343 { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, 07344 { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, 07345 { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, 07346 { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, 07347 { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, 07348 { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, 07349 { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, 07350 { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, 07351 { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, 07352 { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, 07353 { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, 07354 { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, 07355 { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, 07356 { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, 07357 { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, 07358 { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, 07359 { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, 07360 { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, 07361 { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, 07362 { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, 07363 { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, 07364 { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, 07365 { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, 07366 { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, 07367 { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, 07368 { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, 07369 { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, 07370 { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, 07371 { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, 07372 { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, 07373 { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, 07374 { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, 07375 { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, 07376 { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, 07377 { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, 07378 { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, 07379 { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, 07380 { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, 07381 { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, 07382 { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, 07383 { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, 07384 { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, 07385 { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, 07386 { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, 07387 { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, 07388 { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, 07389 { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, 07390 { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, 07391 { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, 07392 { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, 07393 { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, 07394 { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, 07395 { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, 07396 { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, 07397 { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, 07398 { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, 07399 { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, 07400 { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, 07401 { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, 07402 { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, 07403 { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, 07404 { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, 07405 { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, 07406 { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, 07407 { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, 07408 { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, 07409 { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, 07410 { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, 07411 { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, 07412 { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, 07413 { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, 07414 { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, 07415 { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, 07416 { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, 07417 { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, 07418 { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, 07419 { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, 07420 { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, 07421 { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, 07422 { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, 07423 { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, 07424 { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, 07425 { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, 07426 { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, 07427 { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, 07428 { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, 07429 { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, 07430 { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, 07431 { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, 07432 { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, 07433 { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, 07434 { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, 07435 { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, 07436 { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, 07437 { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, 07438 { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, 07439 { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, 07440 { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, 07441 { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, 07442 { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, 07443 { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, 07444 { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, 07445 { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, 07446 { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, 07447 { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, 07448 { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, 07449 { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, 07450 { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, 07451 { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, 07452 { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, 07453 { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, 07454 { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, 07455 { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, 07456 { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, 07457 { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, 07458 { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, 07459 { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, 07460 { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, 07461 { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, 07462 { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, 07463 { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, 07464 { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, 07465 { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, 07466 { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, 07467 { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, 07468 { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, 07469 { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, 07470 { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, 07471 { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, 07472 { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, 07473 { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, 07474 { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, 07475 { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, 07476 { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, 07477 { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, 07478 { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, 07479 { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, 07480 { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, 07481 { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, 07482 { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, 07483 { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, 07484 { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, 07485 { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, 07486 { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, 07487 { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, 07488 { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, 07489 { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, 07490 { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, 07491 { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, 07492 { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, 07493 { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, 07494 { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, 07495 { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, 07496 { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, 07497 { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, 07498 { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, 07499 { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, 07500 { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, 07501 { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, 07502 { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, 07503 { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, 07504 { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, 07505 { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, 07506 { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, 07507 { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, 07508 { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, 07509 { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, 07510 { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, 07511 { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, 07512 { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, 07513 { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, 07514 { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, 07515 { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, 07516 { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, 07517 { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, 07518 { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, 07519 { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, 07520 { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, 07521 { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, 07522 { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, 07523 { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, 07524 { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, 07525 { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, 07526 { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, 07527 { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, 07528 { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, 07529 { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, 07530 { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, 07531 { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, 07532 { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, 07533 { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, 07534 { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, 07535 { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, 07536 { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, 07537 { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, 07538 { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, 07539 { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, 07540 { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, 07541 { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, 07542 { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, 07543 { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, 07544 { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, 07545 { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, 07546 { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, 07547 { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, 07548 { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, 07549 { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, 07550 { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, 07551 { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, 07552 { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, 07553 { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, 07554 { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, 07555 { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, 07556 { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, 07557 { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, 07558 { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, 07559 { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, 07560 { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, 07561 #endif 07562 #endif 07563 #endif 07564 #endif 07565 #endif 07566 #endif 07567 }; 07568 07569 07570 /* find a hole and free as required, return -1 if no hole found */ 07571 static int find_hole(void) 07572 { 07573 unsigned x; 07574 int y, z; 07575 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { 07576 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { 07577 z = x; 07578 y = fp_cache[x].lru_count; 07579 } 07580 } 07581 07582 /* decrease all */ 07583 for (x = 0; x < FP_ENTRIES; x++) { 07584 if (fp_cache[x].lru_count > 3) { 07585 --(fp_cache[x].lru_count); 07586 } 07587 } 07588 07589 /* free entry z */ 07590 if (z >= 0 && fp_cache[z].g) { 07591 mp_clear(&fp_cache[z].mu); 07592 wc_ecc_del_point(fp_cache[z].g); 07593 fp_cache[z].g = NULL; 07594 for (x = 0; x < (1U<<FP_LUT); x++) { 07595 wc_ecc_del_point(fp_cache[z].LUT[x]); 07596 fp_cache[z].LUT[x] = NULL; 07597 } 07598 fp_cache[z].lru_count = 0; 07599 } 07600 return z; 07601 } 07602 07603 /* determine if a base is already in the cache and if so, where */ 07604 static int find_base(ecc_point* g) 07605 { 07606 int x; 07607 for (x = 0; x < FP_ENTRIES; x++) { 07608 if (fp_cache[x].g != NULL && 07609 mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ && 07610 mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ && 07611 mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) { 07612 break; 07613 } 07614 } 07615 if (x == FP_ENTRIES) { 07616 x = -1; 07617 } 07618 return x; 07619 } 07620 07621 /* add a new base to the cache */ 07622 static int add_entry(int idx, ecc_point *g) 07623 { 07624 unsigned x, y; 07625 07626 /* allocate base and LUT */ 07627 fp_cache[idx].g = wc_ecc_new_point(); 07628 if (fp_cache[idx].g == NULL) { 07629 return GEN_MEM_ERR; 07630 } 07631 07632 /* copy x and y */ 07633 if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) || 07634 (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) || 07635 (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) { 07636 wc_ecc_del_point(fp_cache[idx].g); 07637 fp_cache[idx].g = NULL; 07638 return GEN_MEM_ERR; 07639 } 07640 07641 for (x = 0; x < (1U<<FP_LUT); x++) { 07642 fp_cache[idx].LUT[x] = wc_ecc_new_point(); 07643 if (fp_cache[idx].LUT[x] == NULL) { 07644 for (y = 0; y < x; y++) { 07645 wc_ecc_del_point(fp_cache[idx].LUT[y]); 07646 fp_cache[idx].LUT[y] = NULL; 07647 } 07648 wc_ecc_del_point(fp_cache[idx].g); 07649 fp_cache[idx].g = NULL; 07650 fp_cache[idx].lru_count = 0; 07651 return GEN_MEM_ERR; 07652 } 07653 } 07654 07655 fp_cache[idx].lru_count = 0; 07656 07657 return MP_OKAY; 07658 } 07659 #endif 07660 07661 #ifndef WOLFSSL_SP_MATH 07662 /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart 07663 * 07664 * The algorithm builds patterns in increasing bit order by first making all 07665 * single bit input patterns, then all two bit input patterns and so on 07666 */ 07667 static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp, 07668 mp_int* mu) 07669 { 07670 int err; 07671 unsigned x, y, bitlen, lut_gap; 07672 mp_int tmp; 07673 07674 if (mp_init(&tmp) != MP_OKAY) 07675 return GEN_MEM_ERR; 07676 07677 /* sanity check to make sure lut_order table is of correct size, 07678 should compile out to a NOP if true */ 07679 if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) { 07680 err = BAD_FUNC_ARG; 07681 } 07682 else { 07683 /* get bitlen and round up to next multiple of FP_LUT */ 07684 bitlen = mp_unsigned_bin_size(modulus) << 3; 07685 x = bitlen % FP_LUT; 07686 if (x) { 07687 bitlen += FP_LUT - x; 07688 } 07689 lut_gap = bitlen / FP_LUT; 07690 07691 /* init the mu */ 07692 err = mp_init_copy(&fp_cache[idx].mu, mu); 07693 } 07694 07695 /* copy base */ 07696 if (err == MP_OKAY) { 07697 if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus, 07698 fp_cache[idx].LUT[1]->x) != MP_OKAY) || 07699 (mp_mulmod(fp_cache[idx].g->y, mu, modulus, 07700 fp_cache[idx].LUT[1]->y) != MP_OKAY) || 07701 (mp_mulmod(fp_cache[idx].g->z, mu, modulus, 07702 fp_cache[idx].LUT[1]->z) != MP_OKAY)) { 07703 err = MP_MULMOD_E; 07704 } 07705 } 07706 07707 /* make all single bit entries */ 07708 for (x = 1; x < FP_LUT; x++) { 07709 if (err != MP_OKAY) 07710 break; 07711 if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, 07712 fp_cache[idx].LUT[1<<x]->x) != MP_OKAY) || 07713 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, 07714 fp_cache[idx].LUT[1<<x]->y) != MP_OKAY) || 07715 (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, 07716 fp_cache[idx].LUT[1<<x]->z) != MP_OKAY)){ 07717 err = MP_INIT_E; 07718 break; 07719 } else { 07720 07721 /* now double it bitlen/FP_LUT times */ 07722 for (y = 0; y < lut_gap; y++) { 07723 if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<<x], 07724 fp_cache[idx].LUT[1<<x], a, modulus, mp)) != MP_OKAY) { 07725 break; 07726 } 07727 } 07728 } 07729 } 07730 07731 /* now make all entries in increase order of hamming weight */ 07732 for (x = 2; x <= FP_LUT; x++) { 07733 if (err != MP_OKAY) 07734 break; 07735 for (y = 0; y < (1UL<<FP_LUT); y++) { 07736 if (lut_orders[y].ham != (int)x) continue; 07737 07738 /* perform the add */ 07739 if ((err = ecc_projective_add_point( 07740 fp_cache[idx].LUT[lut_orders[y].terma], 07741 fp_cache[idx].LUT[lut_orders[y].termb], 07742 fp_cache[idx].LUT[y], a, modulus, mp)) != MP_OKAY) { 07743 break; 07744 } 07745 } 07746 } 07747 07748 /* now map all entries back to affine space to make point addition faster */ 07749 for (x = 1; x < (1UL<<FP_LUT); x++) { 07750 if (err != MP_OKAY) 07751 break; 07752 07753 /* convert z to normal from montgomery */ 07754 err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp); 07755 07756 /* invert it */ 07757 if (err == MP_OKAY) 07758 err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, 07759 fp_cache[idx].LUT[x]->z); 07760 07761 if (err == MP_OKAY) 07762 /* now square it */ 07763 err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, &tmp); 07764 07765 if (err == MP_OKAY) 07766 /* fix x */ 07767 err = mp_mulmod(fp_cache[idx].LUT[x]->x, &tmp, modulus, 07768 fp_cache[idx].LUT[x]->x); 07769 07770 if (err == MP_OKAY) 07771 /* get 1/z^3 */ 07772 err = mp_mulmod(&tmp, fp_cache[idx].LUT[x]->z, modulus, &tmp); 07773 07774 if (err == MP_OKAY) 07775 /* fix y */ 07776 err = mp_mulmod(fp_cache[idx].LUT[x]->y, &tmp, modulus, 07777 fp_cache[idx].LUT[x]->y); 07778 07779 if (err == MP_OKAY) 07780 /* free z */ 07781 mp_clear(fp_cache[idx].LUT[x]->z); 07782 } 07783 07784 mp_clear(&tmp); 07785 07786 if (err == MP_OKAY) 07787 return MP_OKAY; 07788 07789 /* err cleanup */ 07790 for (y = 0; y < (1U<<FP_LUT); y++) { 07791 wc_ecc_del_point(fp_cache[idx].LUT[y]); 07792 fp_cache[idx].LUT[y] = NULL; 07793 } 07794 wc_ecc_del_point(fp_cache[idx].g); 07795 fp_cache[idx].g = NULL; 07796 fp_cache[idx].lru_count = 0; 07797 mp_clear(&fp_cache[idx].mu); 07798 07799 return err; 07800 } 07801 07802 /* perform a fixed point ECC mulmod */ 07803 static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a, 07804 mp_int* modulus, mp_digit mp, int map) 07805 { 07806 #define KB_SIZE 128 07807 07808 #ifdef WOLFSSL_SMALL_STACK 07809 unsigned char* kb = NULL; 07810 #else 07811 unsigned char kb[KB_SIZE]; 07812 #endif 07813 int x, err; 07814 unsigned y, z = 0, bitlen, bitpos, lut_gap, first; 07815 mp_int tk, order; 07816 07817 if (mp_init_multi(&tk, &order, NULL, NULL, NULL, NULL) != MP_OKAY) 07818 return MP_INIT_E; 07819 07820 /* if it's smaller than modulus we fine */ 07821 if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) { 07822 /* find order */ 07823 y = mp_unsigned_bin_size(modulus); 07824 for (x = 0; ecc_sets[x].size; x++) { 07825 if (y <= (unsigned)ecc_sets[x].size) break; 07826 } 07827 07828 /* back off if we are on the 521 bit curve */ 07829 if (y == 66) --x; 07830 07831 if ((err = mp_read_radix(&order, ecc_sets[x].order, 07832 MP_RADIX_HEX)) != MP_OKAY) { 07833 goto done; 07834 } 07835 07836 /* k must be less than modulus */ 07837 if (mp_cmp(k, &order) != MP_LT) { 07838 if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { 07839 goto done; 07840 } 07841 } else { 07842 if ((err = mp_copy(k, &tk)) != MP_OKAY) { 07843 goto done; 07844 } 07845 } 07846 } else { 07847 if ((err = mp_copy(k, &tk)) != MP_OKAY) { 07848 goto done; 07849 } 07850 } 07851 07852 /* get bitlen and round up to next multiple of FP_LUT */ 07853 bitlen = mp_unsigned_bin_size(modulus) << 3; 07854 x = bitlen % FP_LUT; 07855 if (x) { 07856 bitlen += FP_LUT - x; 07857 } 07858 lut_gap = bitlen / FP_LUT; 07859 07860 /* get the k value */ 07861 if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { 07862 err = BUFFER_E; goto done; 07863 } 07864 07865 /* store k */ 07866 #ifdef WOLFSSL_SMALL_STACK 07867 kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 07868 if (kb == NULL) { 07869 err = MEMORY_E; goto done; 07870 } 07871 #endif 07872 07873 XMEMSET(kb, 0, KB_SIZE); 07874 if ((err = mp_to_unsigned_bin(&tk, kb)) == MP_OKAY) { 07875 /* let's reverse kb so it's little endian */ 07876 x = 0; 07877 y = mp_unsigned_bin_size(&tk); 07878 if (y > 0) { 07879 y -= 1; 07880 } 07881 07882 while ((unsigned)x < y) { 07883 z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z; 07884 ++x; --y; 07885 } 07886 07887 /* at this point we can start, yipee */ 07888 first = 1; 07889 for (x = lut_gap-1; x >= 0; x--) { 07890 /* extract FP_LUT bits from kb spread out by lut_gap bits and offset 07891 by x bits from the start */ 07892 bitpos = x; 07893 for (y = z = 0; y < FP_LUT; y++) { 07894 z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; 07895 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 07896 the mult in each loop */ 07897 } 07898 07899 /* double if not first */ 07900 if (!first) { 07901 if ((err = ecc_projective_dbl_point(R, R, a, modulus, 07902 mp)) != MP_OKAY) { 07903 break; 07904 } 07905 } 07906 07907 /* add if not first, otherwise copy */ 07908 if (!first && z) { 07909 if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, 07910 a, modulus, mp)) != MP_OKAY) { 07911 break; 07912 } 07913 } else if (z) { 07914 if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) || 07915 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) || 07916 (mp_copy(&fp_cache[idx].mu, R->z) != MP_OKAY)) { 07917 err = GEN_MEM_ERR; 07918 break; 07919 } 07920 first = 0; 07921 } 07922 } 07923 } 07924 07925 if (err == MP_OKAY) { 07926 (void) z; /* Acknowledge the unused assignment */ 07927 ForceZero(kb, KB_SIZE); 07928 07929 /* map R back from projective space */ 07930 if (map) { 07931 err = ecc_map(R, modulus, mp); 07932 } else { 07933 err = MP_OKAY; 07934 } 07935 } 07936 07937 done: 07938 /* cleanup */ 07939 mp_clear(&order); 07940 mp_clear(&tk); 07941 07942 #ifdef WOLFSSL_SMALL_STACK 07943 XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER); 07944 #endif 07945 07946 #undef KB_SIZE 07947 07948 return err; 07949 } 07950 #endif 07951 07952 #ifdef ECC_SHAMIR 07953 #ifndef WOLFSSL_SP_MATH 07954 /* perform a fixed point ECC mulmod */ 07955 static int accel_fp_mul2add(int idx1, int idx2, 07956 mp_int* kA, mp_int* kB, 07957 ecc_point *R, mp_int* a, 07958 mp_int* modulus, mp_digit mp) 07959 { 07960 #define KB_SIZE 128 07961 07962 #ifdef WOLFSSL_SMALL_STACK 07963 unsigned char* kb[2] = {NULL, NULL}; 07964 #else 07965 unsigned char kb[2][KB_SIZE]; 07966 #endif 07967 int x, err; 07968 unsigned y, z, bitlen, bitpos, lut_gap, first, zA, zB; 07969 mp_int tka, tkb, order; 07970 07971 if (mp_init_multi(&tka, &tkb, &order, NULL, NULL, NULL) != MP_OKAY) 07972 return MP_INIT_E; 07973 07974 /* if it's smaller than modulus we fine */ 07975 if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { 07976 /* find order */ 07977 y = mp_unsigned_bin_size(modulus); 07978 for (x = 0; ecc_sets[x].size; x++) { 07979 if (y <= (unsigned)ecc_sets[x].size) break; 07980 } 07981 07982 /* back off if we are on the 521 bit curve */ 07983 if (y == 66) --x; 07984 07985 if ((err = mp_read_radix(&order, ecc_sets[x].order, 07986 MP_RADIX_HEX)) != MP_OKAY) { 07987 goto done; 07988 } 07989 07990 /* kA must be less than modulus */ 07991 if (mp_cmp(kA, &order) != MP_LT) { 07992 if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { 07993 goto done; 07994 } 07995 } else { 07996 if ((err = mp_copy(kA, &tka)) != MP_OKAY) { 07997 goto done; 07998 } 07999 } 08000 } else { 08001 if ((err = mp_copy(kA, &tka)) != MP_OKAY) { 08002 goto done; 08003 } 08004 } 08005 08006 /* if it's smaller than modulus we fine */ 08007 if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { 08008 /* find order */ 08009 y = mp_unsigned_bin_size(modulus); 08010 for (x = 0; ecc_sets[x].size; x++) { 08011 if (y <= (unsigned)ecc_sets[x].size) break; 08012 } 08013 08014 /* back off if we are on the 521 bit curve */ 08015 if (y == 66) --x; 08016 08017 if ((err = mp_read_radix(&order, ecc_sets[x].order, 08018 MP_RADIX_HEX)) != MP_OKAY) { 08019 goto done; 08020 } 08021 08022 /* kB must be less than modulus */ 08023 if (mp_cmp(kB, &order) != MP_LT) { 08024 if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { 08025 goto done; 08026 } 08027 } else { 08028 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { 08029 goto done; 08030 } 08031 } 08032 } else { 08033 if ((err = mp_copy(kB, &tkb)) != MP_OKAY) { 08034 goto done; 08035 } 08036 } 08037 08038 /* get bitlen and round up to next multiple of FP_LUT */ 08039 bitlen = mp_unsigned_bin_size(modulus) << 3; 08040 x = bitlen % FP_LUT; 08041 if (x) { 08042 bitlen += FP_LUT - x; 08043 } 08044 lut_gap = bitlen / FP_LUT; 08045 08046 /* get the k value */ 08047 if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || 08048 (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { 08049 err = BUFFER_E; goto done; 08050 } 08051 08052 /* store k */ 08053 #ifdef WOLFSSL_SMALL_STACK 08054 kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08055 if (kb[0] == NULL) { 08056 err = MEMORY_E; goto done; 08057 } 08058 #endif 08059 08060 XMEMSET(kb[0], 0, KB_SIZE); 08061 if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { 08062 goto done; 08063 } 08064 08065 /* let's reverse kb so it's little endian */ 08066 x = 0; 08067 y = mp_unsigned_bin_size(&tka); 08068 if (y > 0) { 08069 y -= 1; 08070 } 08071 mp_clear(&tka); 08072 while ((unsigned)x < y) { 08073 z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z; 08074 ++x; --y; 08075 } 08076 08077 /* store b */ 08078 #ifdef WOLFSSL_SMALL_STACK 08079 kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08080 if (kb[1] == NULL) { 08081 err = MEMORY_E; goto done; 08082 } 08083 #endif 08084 08085 XMEMSET(kb[1], 0, KB_SIZE); 08086 if ((err = mp_to_unsigned_bin(&tkb, kb[1])) == MP_OKAY) { 08087 x = 0; 08088 y = mp_unsigned_bin_size(&tkb); 08089 if (y > 0) { 08090 y -= 1; 08091 } 08092 08093 while ((unsigned)x < y) { 08094 z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z; 08095 ++x; --y; 08096 } 08097 08098 /* at this point we can start, yipee */ 08099 first = 1; 08100 for (x = lut_gap-1; x >= 0; x--) { 08101 /* extract FP_LUT bits from kb spread out by lut_gap bits and 08102 offset by x bits from the start */ 08103 bitpos = x; 08104 for (y = zA = zB = 0; y < FP_LUT; y++) { 08105 zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; 08106 zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; 08107 bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid 08108 the mult in each loop */ 08109 } 08110 08111 /* double if not first */ 08112 if (!first) { 08113 if ((err = ecc_projective_dbl_point(R, R, a, modulus, 08114 mp)) != MP_OKAY) { 08115 break; 08116 } 08117 } 08118 08119 /* add if not first, otherwise copy */ 08120 if (!first) { 08121 if (zA) { 08122 if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], 08123 R, a, modulus, mp)) != MP_OKAY) { 08124 break; 08125 } 08126 } 08127 if (zB) { 08128 if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], 08129 R, a, modulus, mp)) != MP_OKAY) { 08130 break; 08131 } 08132 } 08133 } else { 08134 if (zA) { 08135 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) || 08136 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) || 08137 (mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) { 08138 err = GEN_MEM_ERR; 08139 break; 08140 } 08141 first = 0; 08142 } 08143 if (zB && first == 0) { 08144 if (zB) { 08145 if ((err = ecc_projective_add_point(R, 08146 fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){ 08147 break; 08148 } 08149 } 08150 } else if (zB && first == 1) { 08151 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) || 08152 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) || 08153 (mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) { 08154 err = GEN_MEM_ERR; 08155 break; 08156 } 08157 first = 0; 08158 } 08159 } 08160 } 08161 } 08162 08163 done: 08164 /* cleanup */ 08165 mp_clear(&tkb); 08166 mp_clear(&tka); 08167 mp_clear(&order); 08168 08169 #ifdef WOLFSSL_SMALL_STACK 08170 if (kb[0]) 08171 #endif 08172 ForceZero(kb[0], KB_SIZE); 08173 #ifdef WOLFSSL_SMALL_STACK 08174 if (kb[1]) 08175 #endif 08176 ForceZero(kb[1], KB_SIZE); 08177 08178 #ifdef WOLFSSL_SMALL_STACK 08179 XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER); 08180 XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER); 08181 #endif 08182 08183 #undef KB_SIZE 08184 08185 if (err != MP_OKAY) 08186 return err; 08187 08188 return ecc_map(R, modulus, mp); 08189 } 08190 08191 08192 /** ECC Fixed Point mulmod global with heap hint used 08193 Computes kA*A + kB*B = C using Shamir's Trick 08194 A First point to multiply 08195 kA What to multiple A by 08196 B Second point to multiply 08197 kB What to multiple B by 08198 C [out] Destination point (can overlap with A or B) 08199 a ECC curve parameter a 08200 modulus Modulus for curve 08201 return MP_OKAY on success 08202 */ 08203 int ecc_mul2add(ecc_point* A, mp_int* kA, 08204 ecc_point* B, mp_int* kB, 08205 ecc_point* C, mp_int* a, mp_int* modulus, void* heap) 08206 { 08207 int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; 08208 mp_digit mp; 08209 mp_int mu; 08210 08211 err = mp_init(&mu); 08212 if (err != MP_OKAY) 08213 return err; 08214 08215 #ifndef HAVE_THREAD_LS 08216 if (initMutex == 0) { 08217 wc_InitMutex(&ecc_fp_lock); 08218 initMutex = 1; 08219 } 08220 if (wc_LockMutex(&ecc_fp_lock) != 0) 08221 return BAD_MUTEX_E; 08222 #endif /* HAVE_THREAD_LS */ 08223 08224 /* find point */ 08225 idx1 = find_base(A); 08226 08227 /* no entry? */ 08228 if (idx1 == -1) { 08229 /* find hole and add it */ 08230 if ((idx1 = find_hole()) >= 0) { 08231 err = add_entry(idx1, A); 08232 } 08233 } 08234 if (err == MP_OKAY && idx1 != -1) { 08235 /* increment LRU */ 08236 ++(fp_cache[idx1].lru_count); 08237 } 08238 08239 if (err == MP_OKAY) 08240 /* find point */ 08241 idx2 = find_base(B); 08242 08243 if (err == MP_OKAY) { 08244 /* no entry? */ 08245 if (idx2 == -1) { 08246 /* find hole and add it */ 08247 if ((idx2 = find_hole()) >= 0) 08248 err = add_entry(idx2, B); 08249 } 08250 } 08251 08252 if (err == MP_OKAY && idx2 != -1) { 08253 /* increment LRU */ 08254 ++(fp_cache[idx2].lru_count); 08255 } 08256 08257 if (err == MP_OKAY) { 08258 /* if it's 2 build the LUT, if it's higher just use the LUT */ 08259 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { 08260 /* compute mp */ 08261 err = mp_montgomery_setup(modulus, &mp); 08262 08263 if (err == MP_OKAY) { 08264 mpInit = 1; 08265 err = mp_montgomery_calc_normalization(&mu, modulus); 08266 } 08267 08268 if (err == MP_OKAY) 08269 /* build the LUT */ 08270 err = build_lut(idx1, a, modulus, mp, &mu); 08271 } 08272 } 08273 08274 if (err == MP_OKAY) { 08275 /* if it's 2 build the LUT, if it's higher just use the LUT */ 08276 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { 08277 if (mpInit == 0) { 08278 /* compute mp */ 08279 err = mp_montgomery_setup(modulus, &mp); 08280 if (err == MP_OKAY) { 08281 mpInit = 1; 08282 err = mp_montgomery_calc_normalization(&mu, modulus); 08283 } 08284 } 08285 08286 if (err == MP_OKAY) 08287 /* build the LUT */ 08288 err = build_lut(idx2, a, modulus, mp, &mu); 08289 } 08290 } 08291 08292 08293 if (err == MP_OKAY) { 08294 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && 08295 fp_cache[idx2].lru_count >= 2) { 08296 if (mpInit == 0) { 08297 /* compute mp */ 08298 err = mp_montgomery_setup(modulus, &mp); 08299 } 08300 if (err == MP_OKAY) 08301 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp); 08302 } else { 08303 err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap); 08304 } 08305 } 08306 08307 #ifndef HAVE_THREAD_LS 08308 wc_UnLockMutex(&ecc_fp_lock); 08309 #endif /* HAVE_THREAD_LS */ 08310 mp_clear(&mu); 08311 08312 return err; 08313 } 08314 #endif 08315 #endif /* ECC_SHAMIR */ 08316 08317 /** ECC Fixed Point mulmod global 08318 k The multiplicand 08319 G Base point to multiply 08320 R [out] Destination of product 08321 a ECC curve parameter a 08322 modulus The modulus for the curve 08323 map [boolean] If non-zero maps the point back to affine co-ordinates, 08324 otherwise it's left in jacobian-montgomery form 08325 return MP_OKAY if successful 08326 */ 08327 int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, 08328 mp_int* modulus, int map, void* heap) 08329 { 08330 #ifndef WOLFSSL_SP_MATH 08331 int idx, err = MP_OKAY; 08332 mp_digit mp; 08333 mp_int mu; 08334 int mpSetup = 0; 08335 08336 if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) { 08337 return ECC_BAD_ARG_E; 08338 } 08339 08340 if (mp_init(&mu) != MP_OKAY) 08341 return MP_INIT_E; 08342 08343 #ifndef HAVE_THREAD_LS 08344 if (initMutex == 0) { 08345 wc_InitMutex(&ecc_fp_lock); 08346 initMutex = 1; 08347 } 08348 08349 if (wc_LockMutex(&ecc_fp_lock) != 0) 08350 return BAD_MUTEX_E; 08351 #endif /* HAVE_THREAD_LS */ 08352 08353 /* find point */ 08354 idx = find_base(G); 08355 08356 /* no entry? */ 08357 if (idx == -1) { 08358 /* find hole and add it */ 08359 idx = find_hole(); 08360 08361 if (idx >= 0) 08362 err = add_entry(idx, G); 08363 } 08364 if (err == MP_OKAY && idx >= 0) { 08365 /* increment LRU */ 08366 ++(fp_cache[idx].lru_count); 08367 } 08368 08369 08370 if (err == MP_OKAY) { 08371 /* if it's 2 build the LUT, if it's higher just use the LUT */ 08372 if (idx >= 0 && fp_cache[idx].lru_count == 2) { 08373 /* compute mp */ 08374 err = mp_montgomery_setup(modulus, &mp); 08375 08376 if (err == MP_OKAY) { 08377 /* compute mu */ 08378 mpSetup = 1; 08379 err = mp_montgomery_calc_normalization(&mu, modulus); 08380 } 08381 08382 if (err == MP_OKAY) 08383 /* build the LUT */ 08384 err = build_lut(idx, a, modulus, mp, &mu); 08385 } 08386 } 08387 08388 if (err == MP_OKAY) { 08389 if (idx >= 0 && fp_cache[idx].lru_count >= 2) { 08390 if (mpSetup == 0) { 08391 /* compute mp */ 08392 err = mp_montgomery_setup(modulus, &mp); 08393 } 08394 if (err == MP_OKAY) 08395 err = accel_fp_mul(idx, k, R, a, modulus, mp, map); 08396 } else { 08397 err = normal_ecc_mulmod(k, G, R, a, modulus, map, heap); 08398 } 08399 } 08400 08401 #ifndef HAVE_THREAD_LS 08402 wc_UnLockMutex(&ecc_fp_lock); 08403 #endif /* HAVE_THREAD_LS */ 08404 mp_clear(&mu); 08405 08406 return err; 08407 #else 08408 if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) { 08409 return ECC_BAD_ARG_E; 08410 } 08411 08412 return sp_ecc_mulmod_256(k, G, R, map, heap); 08413 #endif 08414 } 08415 08416 #ifndef WOLFSSL_SP_MATH 08417 /* helper function for freeing the cache ... 08418 must be called with the cache mutex locked */ 08419 static void wc_ecc_fp_free_cache(void) 08420 { 08421 unsigned x, y; 08422 for (x = 0; x < FP_ENTRIES; x++) { 08423 if (fp_cache[x].g != NULL) { 08424 for (y = 0; y < (1U<<FP_LUT); y++) { 08425 wc_ecc_del_point(fp_cache[x].LUT[y]); 08426 fp_cache[x].LUT[y] = NULL; 08427 } 08428 wc_ecc_del_point(fp_cache[x].g); 08429 fp_cache[x].g = NULL; 08430 mp_clear(&fp_cache[x].mu); 08431 fp_cache[x].lru_count = 0; 08432 fp_cache[x].lock = 0; 08433 } 08434 } 08435 } 08436 #endif 08437 08438 /** Free the Fixed Point cache */ 08439 void wc_ecc_fp_free(void) 08440 { 08441 #ifndef WOLFSSL_SP_MATH 08442 #ifndef HAVE_THREAD_LS 08443 if (initMutex == 0) { 08444 wc_InitMutex(&ecc_fp_lock); 08445 initMutex = 1; 08446 } 08447 08448 if (wc_LockMutex(&ecc_fp_lock) == 0) { 08449 #endif /* HAVE_THREAD_LS */ 08450 08451 wc_ecc_fp_free_cache(); 08452 08453 #ifndef HAVE_THREAD_LS 08454 wc_UnLockMutex(&ecc_fp_lock); 08455 wc_FreeMutex(&ecc_fp_lock); 08456 initMutex = 0; 08457 } 08458 #endif /* HAVE_THREAD_LS */ 08459 #endif 08460 } 08461 08462 08463 #endif /* FP_ECC */ 08464 08465 #ifdef HAVE_ECC_ENCRYPT 08466 08467 08468 enum ecCliState { 08469 ecCLI_INIT = 1, 08470 ecCLI_SALT_GET = 2, 08471 ecCLI_SALT_SET = 3, 08472 ecCLI_SENT_REQ = 4, 08473 ecCLI_RECV_RESP = 5, 08474 ecCLI_BAD_STATE = 99 08475 }; 08476 08477 enum ecSrvState { 08478 ecSRV_INIT = 1, 08479 ecSRV_SALT_GET = 2, 08480 ecSRV_SALT_SET = 3, 08481 ecSRV_RECV_REQ = 4, 08482 ecSRV_SENT_RESP = 5, 08483 ecSRV_BAD_STATE = 99 08484 }; 08485 08486 08487 struct ecEncCtx { 08488 const byte* kdfSalt; /* optional salt for kdf */ 08489 const byte* kdfInfo; /* optional info for kdf */ 08490 const byte* macSalt; /* optional salt for mac */ 08491 word32 kdfSaltSz; /* size of kdfSalt */ 08492 word32 kdfInfoSz; /* size of kdfInfo */ 08493 word32 macSaltSz; /* size of macSalt */ 08494 void* heap; /* heap hint for memory used */ 08495 byte clientSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 08496 byte serverSalt[EXCHANGE_SALT_SZ]; /* for msg exchange */ 08497 byte encAlgo; /* which encryption type */ 08498 byte kdfAlgo; /* which key derivation function type */ 08499 byte macAlgo; /* which mac function type */ 08500 byte protocol; /* are we REQ_RESP client or server ? */ 08501 byte cliSt; /* protocol state, for sanity checks */ 08502 byte srvSt; /* protocol state, for sanity checks */ 08503 }; 08504 08505 08506 const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx) 08507 { 08508 if (ctx == NULL || ctx->protocol == 0) 08509 return NULL; 08510 08511 if (ctx->protocol == REQ_RESP_CLIENT) { 08512 if (ctx->cliSt == ecCLI_INIT) { 08513 ctx->cliSt = ecCLI_SALT_GET; 08514 return ctx->clientSalt; 08515 } 08516 else { 08517 ctx->cliSt = ecCLI_BAD_STATE; 08518 return NULL; 08519 } 08520 } 08521 else if (ctx->protocol == REQ_RESP_SERVER) { 08522 if (ctx->srvSt == ecSRV_INIT) { 08523 ctx->srvSt = ecSRV_SALT_GET; 08524 return ctx->serverSalt; 08525 } 08526 else { 08527 ctx->srvSt = ecSRV_BAD_STATE; 08528 return NULL; 08529 } 08530 } 08531 08532 return NULL; 08533 } 08534 08535 08536 /* optional set info, can be called before or after set_peer_salt */ 08537 int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) 08538 { 08539 if (ctx == NULL || info == 0 || sz < 0) 08540 return BAD_FUNC_ARG; 08541 08542 ctx->kdfInfo = info; 08543 ctx->kdfInfoSz = sz; 08544 08545 return 0; 08546 } 08547 08548 08549 static const char* exchange_info = "Secure Message Exchange"; 08550 08551 int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) 08552 { 08553 byte tmp[EXCHANGE_SALT_SZ/2]; 08554 int halfSz = EXCHANGE_SALT_SZ/2; 08555 08556 if (ctx == NULL || ctx->protocol == 0 || salt == NULL) 08557 return BAD_FUNC_ARG; 08558 08559 if (ctx->protocol == REQ_RESP_CLIENT) { 08560 XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); 08561 if (ctx->cliSt == ecCLI_SALT_GET) 08562 ctx->cliSt = ecCLI_SALT_SET; 08563 else { 08564 ctx->cliSt = ecCLI_BAD_STATE; 08565 return BAD_STATE_E; 08566 } 08567 } 08568 else { 08569 XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); 08570 if (ctx->srvSt == ecSRV_SALT_GET) 08571 ctx->srvSt = ecSRV_SALT_SET; 08572 else { 08573 ctx->srvSt = ecSRV_BAD_STATE; 08574 return BAD_STATE_E; 08575 } 08576 } 08577 08578 /* mix half and half */ 08579 /* tmp stores 2nd half of client before overwrite */ 08580 XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); 08581 XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); 08582 XMEMCPY(ctx->serverSalt, tmp, halfSz); 08583 08584 ctx->kdfSalt = ctx->clientSalt; 08585 ctx->kdfSaltSz = EXCHANGE_SALT_SZ; 08586 08587 ctx->macSalt = ctx->serverSalt; 08588 ctx->macSaltSz = EXCHANGE_SALT_SZ; 08589 08590 if (ctx->kdfInfo == NULL) { 08591 /* default info */ 08592 ctx->kdfInfo = (const byte*)exchange_info; 08593 ctx->kdfInfoSz = EXCHANGE_INFO_SZ; 08594 } 08595 08596 return 0; 08597 } 08598 08599 08600 static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, WC_RNG* rng) 08601 { 08602 byte* saltBuffer = NULL; 08603 08604 if (ctx == NULL || rng == NULL || flags == 0) 08605 return BAD_FUNC_ARG; 08606 08607 saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; 08608 08609 return wc_RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); 08610 } 08611 08612 08613 static void ecc_ctx_init(ecEncCtx* ctx, int flags) 08614 { 08615 if (ctx) { 08616 XMEMSET(ctx, 0, sizeof(ecEncCtx)); 08617 08618 ctx->encAlgo = ecAES_128_CBC; 08619 ctx->kdfAlgo = ecHKDF_SHA256; 08620 ctx->macAlgo = ecHMAC_SHA256; 08621 ctx->protocol = (byte)flags; 08622 08623 if (flags == REQ_RESP_CLIENT) 08624 ctx->cliSt = ecCLI_INIT; 08625 if (flags == REQ_RESP_SERVER) 08626 ctx->srvSt = ecSRV_INIT; 08627 } 08628 } 08629 08630 08631 /* allow ecc context reset so user doesn't have to init/free for reuse */ 08632 int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng) 08633 { 08634 if (ctx == NULL || rng == NULL) 08635 return BAD_FUNC_ARG; 08636 08637 ecc_ctx_init(ctx, ctx->protocol); 08638 return ecc_ctx_set_salt(ctx, ctx->protocol, rng); 08639 } 08640 08641 08642 ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap) 08643 { 08644 int ret = 0; 08645 ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap, 08646 DYNAMIC_TYPE_ECC); 08647 08648 if (ctx) { 08649 ctx->protocol = (byte)flags; 08650 ctx->heap = heap; 08651 } 08652 08653 ret = wc_ecc_ctx_reset(ctx, rng); 08654 if (ret != 0) { 08655 wc_ecc_ctx_free(ctx); 08656 ctx = NULL; 08657 } 08658 08659 return ctx; 08660 } 08661 08662 08663 /* alloc/init and set defaults, return new Context */ 08664 ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng) 08665 { 08666 return wc_ecc_ctx_new_ex(flags, rng, NULL); 08667 } 08668 08669 08670 /* free any resources, clear any keys */ 08671 void wc_ecc_ctx_free(ecEncCtx* ctx) 08672 { 08673 if (ctx) { 08674 ForceZero(ctx, sizeof(ecEncCtx)); 08675 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_ECC); 08676 } 08677 } 08678 08679 08680 static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, 08681 int* keysLen, word32* digestSz, word32* blockSz) 08682 { 08683 if (ctx) { 08684 switch (ctx->encAlgo) { 08685 case ecAES_128_CBC: 08686 *encKeySz = KEY_SIZE_128; 08687 *ivSz = IV_SIZE_128; 08688 *blockSz = AES_BLOCK_SIZE; 08689 break; 08690 default: 08691 return BAD_FUNC_ARG; 08692 } 08693 08694 switch (ctx->macAlgo) { 08695 case ecHMAC_SHA256: 08696 *digestSz = WC_SHA256_DIGEST_SIZE; 08697 break; 08698 default: 08699 return BAD_FUNC_ARG; 08700 } 08701 } else 08702 return BAD_FUNC_ARG; 08703 08704 *keysLen = *encKeySz + *ivSz + *digestSz; 08705 08706 return 0; 08707 } 08708 08709 08710 /* ecc encrypt with shared secret run through kdf 08711 ctx holds non default algos and inputs 08712 msgSz should be the right size for encAlgo, i.e., already padded 08713 return 0 on success */ 08714 int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 08715 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 08716 { 08717 int ret = 0; 08718 word32 blockSz; 08719 word32 digestSz; 08720 ecEncCtx localCtx; 08721 #ifdef WOLFSSL_SMALL_STACK 08722 byte* sharedSecret; 08723 byte* keys; 08724 #else 08725 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 08726 byte keys[ECC_BUFSIZE]; /* max size */ 08727 #endif 08728 word32 sharedSz = ECC_MAXSIZE; 08729 int keysLen; 08730 int encKeySz; 08731 int ivSz; 08732 int offset = 0; /* keys offset if doing msg exchange */ 08733 byte* encKey; 08734 byte* encIv; 08735 byte* macKey; 08736 08737 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 08738 outSz == NULL) 08739 return BAD_FUNC_ARG; 08740 08741 if (ctx == NULL) { /* use defaults */ 08742 ecc_ctx_init(&localCtx, 0); 08743 ctx = &localCtx; 08744 } 08745 08746 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 08747 &blockSz); 08748 if (ret != 0) 08749 return ret; 08750 08751 if (ctx->protocol == REQ_RESP_SERVER) { 08752 offset = keysLen; 08753 keysLen *= 2; 08754 08755 if (ctx->srvSt != ecSRV_RECV_REQ) 08756 return BAD_STATE_E; 08757 08758 ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 08759 } 08760 else if (ctx->protocol == REQ_RESP_CLIENT) { 08761 if (ctx->cliSt != ecCLI_SALT_SET) 08762 return BAD_STATE_E; 08763 08764 ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ 08765 } 08766 08767 if (keysLen > ECC_BUFSIZE) /* keys size */ 08768 return BUFFER_E; 08769 08770 if ( (msgSz%blockSz) != 0) 08771 return BAD_PADDING_E; 08772 08773 if (*outSz < (msgSz + digestSz)) 08774 return BUFFER_E; 08775 08776 #ifdef WOLFSSL_SMALL_STACK 08777 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08778 if (sharedSecret == NULL) 08779 return MEMORY_E; 08780 08781 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08782 if (keys == NULL) { 08783 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08784 return MEMORY_E; 08785 } 08786 #endif 08787 08788 do { 08789 #if defined(WOLFSSL_ASYNC_CRYPT) 08790 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); 08791 if (ret != 0) 08792 break; 08793 #endif 08794 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 08795 } while (ret == WC_PENDING_E); 08796 if (ret == 0) { 08797 switch (ctx->kdfAlgo) { 08798 case ecHKDF_SHA256 : 08799 ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 08800 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 08801 keys, keysLen); 08802 break; 08803 08804 default: 08805 ret = BAD_FUNC_ARG; 08806 break; 08807 } 08808 } 08809 08810 if (ret == 0) { 08811 encKey = keys + offset; 08812 encIv = encKey + encKeySz; 08813 macKey = encKey + encKeySz + ivSz; 08814 08815 switch (ctx->encAlgo) { 08816 case ecAES_128_CBC: 08817 { 08818 Aes aes; 08819 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 08820 AES_ENCRYPTION); 08821 if (ret != 0) 08822 break; 08823 ret = wc_AesCbcEncrypt(&aes, out, msg, msgSz); 08824 #if defined(WOLFSSL_ASYNC_CRYPT) 08825 ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE); 08826 #endif 08827 } 08828 break; 08829 08830 default: 08831 ret = BAD_FUNC_ARG; 08832 break; 08833 } 08834 } 08835 08836 if (ret == 0) { 08837 switch (ctx->macAlgo) { 08838 case ecHMAC_SHA256: 08839 { 08840 Hmac hmac; 08841 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); 08842 if (ret == 0) { 08843 ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE); 08844 if (ret == 0) 08845 ret = wc_HmacUpdate(&hmac, out, msgSz); 08846 if (ret == 0) 08847 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 08848 if (ret == 0) 08849 ret = wc_HmacFinal(&hmac, out+msgSz); 08850 wc_HmacFree(&hmac); 08851 } 08852 } 08853 break; 08854 08855 default: 08856 ret = BAD_FUNC_ARG; 08857 break; 08858 } 08859 } 08860 08861 if (ret == 0) 08862 *outSz = msgSz + digestSz; 08863 08864 #ifdef WOLFSSL_SMALL_STACK 08865 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08866 XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08867 #endif 08868 08869 return ret; 08870 } 08871 08872 08873 /* ecc decrypt with shared secret run through kdf 08874 ctx holds non default algos and inputs 08875 return 0 on success */ 08876 int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, 08877 word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) 08878 { 08879 int ret = 0; 08880 word32 blockSz; 08881 word32 digestSz; 08882 ecEncCtx localCtx; 08883 #ifdef WOLFSSL_SMALL_STACK 08884 byte* sharedSecret; 08885 byte* keys; 08886 #else 08887 byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ 08888 byte keys[ECC_BUFSIZE]; /* max size */ 08889 #endif 08890 word32 sharedSz = ECC_MAXSIZE; 08891 int keysLen; 08892 int encKeySz; 08893 int ivSz; 08894 int offset = 0; /* in case using msg exchange */ 08895 byte* encKey; 08896 byte* encIv; 08897 byte* macKey; 08898 08899 if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || 08900 outSz == NULL) 08901 return BAD_FUNC_ARG; 08902 08903 if (ctx == NULL) { /* use defaults */ 08904 ecc_ctx_init(&localCtx, 0); 08905 ctx = &localCtx; 08906 } 08907 08908 ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, 08909 &blockSz); 08910 if (ret != 0) 08911 return ret; 08912 08913 if (ctx->protocol == REQ_RESP_CLIENT) { 08914 offset = keysLen; 08915 keysLen *= 2; 08916 08917 if (ctx->cliSt != ecCLI_SENT_REQ) 08918 return BAD_STATE_E; 08919 08920 ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ 08921 } 08922 else if (ctx->protocol == REQ_RESP_SERVER) { 08923 if (ctx->srvSt != ecSRV_SALT_SET) 08924 return BAD_STATE_E; 08925 08926 ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ 08927 } 08928 08929 if (keysLen > ECC_BUFSIZE) /* keys size */ 08930 return BUFFER_E; 08931 08932 if ( ((msgSz-digestSz) % blockSz) != 0) 08933 return BAD_PADDING_E; 08934 08935 if (*outSz < (msgSz - digestSz)) 08936 return BUFFER_E; 08937 08938 #ifdef WOLFSSL_SMALL_STACK 08939 sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08940 if (sharedSecret == NULL) 08941 return MEMORY_E; 08942 08943 keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08944 if (keys == NULL) { 08945 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); 08946 return MEMORY_E; 08947 } 08948 #endif 08949 08950 do { 08951 #if defined(WOLFSSL_ASYNC_CRYPT) 08952 ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); 08953 if (ret != 0) 08954 break; 08955 #endif 08956 ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); 08957 } while (ret == WC_PENDING_E); 08958 if (ret == 0) { 08959 switch (ctx->kdfAlgo) { 08960 case ecHKDF_SHA256 : 08961 ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt, 08962 ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, 08963 keys, keysLen); 08964 break; 08965 08966 default: 08967 ret = BAD_FUNC_ARG; 08968 break; 08969 } 08970 } 08971 08972 if (ret == 0) { 08973 encKey = keys + offset; 08974 encIv = encKey + encKeySz; 08975 macKey = encKey + encKeySz + ivSz; 08976 08977 switch (ctx->macAlgo) { 08978 case ecHMAC_SHA256: 08979 { 08980 byte verify[WC_SHA256_DIGEST_SIZE]; 08981 Hmac hmac; 08982 08983 ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID); 08984 if (ret == 0) { 08985 ret = wc_HmacSetKey(&hmac, WC_SHA256, macKey, WC_SHA256_DIGEST_SIZE); 08986 if (ret == 0) 08987 ret = wc_HmacUpdate(&hmac, msg, msgSz-digestSz); 08988 if (ret == 0) 08989 ret = wc_HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); 08990 if (ret == 0) 08991 ret = wc_HmacFinal(&hmac, verify); 08992 if (ret == 0) { 08993 if (XMEMCMP(verify, msg + msgSz - digestSz, digestSz) != 0) 08994 ret = -1; 08995 } 08996 08997 wc_HmacFree(&hmac); 08998 } 08999 break; 09000 } 09001 09002 default: 09003 ret = BAD_FUNC_ARG; 09004 break; 09005 } 09006 } 09007 09008 if (ret == 0) { 09009 switch (ctx->encAlgo) { 09010 #ifdef HAVE_AES_CBC 09011 case ecAES_128_CBC: 09012 { 09013 Aes aes; 09014 ret = wc_AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, 09015 AES_DECRYPTION); 09016 if (ret != 0) 09017 break; 09018 ret = wc_AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); 09019 #if defined(WOLFSSL_ASYNC_CRYPT) 09020 ret = wc_AsyncWait(ret, &aes.asyncDev, WC_ASYNC_FLAG_NONE); 09021 #endif 09022 } 09023 break; 09024 #endif 09025 default: 09026 ret = BAD_FUNC_ARG; 09027 break; 09028 } 09029 } 09030 09031 if (ret == 0) 09032 *outSz = msgSz - digestSz; 09033 09034 #ifdef WOLFSSL_SMALL_STACK 09035 XFREE(sharedSecret, NULL, DYNAMIC_TYPE_ECC_BUFFER); 09036 XFREE(keys, NULL, DYNAMIC_TYPE_ECC_BUFFER); 09037 #endif 09038 09039 return ret; 09040 } 09041 09042 09043 #endif /* HAVE_ECC_ENCRYPT */ 09044 09045 09046 #ifdef HAVE_COMP_KEY 09047 #ifndef WOLFSSL_ATECC508A 09048 09049 #ifndef WOLFSSL_SP_MATH 09050 int do_mp_jacobi(mp_int* a, mp_int* n, int* c); 09051 09052 int do_mp_jacobi(mp_int* a, mp_int* n, int* c) 09053 { 09054 int k, s, res; 09055 int r = 0; /* initialize to help static analysis out */ 09056 mp_digit residue; 09057 09058 /* if a < 0 return MP_VAL */ 09059 if (mp_isneg(a) == MP_YES) { 09060 return MP_VAL; 09061 } 09062 09063 /* if n <= 0 return MP_VAL */ 09064 if (mp_cmp_d(n, 0) != MP_GT) { 09065 return MP_VAL; 09066 } 09067 09068 /* step 1. handle case of a == 0 */ 09069 if (mp_iszero (a) == MP_YES) { 09070 /* special case of a == 0 and n == 1 */ 09071 if (mp_cmp_d (n, 1) == MP_EQ) { 09072 *c = 1; 09073 } else { 09074 *c = 0; 09075 } 09076 return MP_OKAY; 09077 } 09078 09079 /* step 2. if a == 1, return 1 */ 09080 if (mp_cmp_d (a, 1) == MP_EQ) { 09081 *c = 1; 09082 return MP_OKAY; 09083 } 09084 09085 /* default */ 09086 s = 0; 09087 09088 /* divide out larger power of two */ 09089 k = mp_cnt_lsb(a); 09090 res = mp_div_2d(a, k, a, NULL); 09091 09092 if (res == MP_OKAY) { 09093 /* step 4. if e is even set s=1 */ 09094 if ((k & 1) == 0) { 09095 s = 1; 09096 } else { 09097 /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ 09098 residue = n->dp[0] & 7; 09099 09100 if (residue == 1 || residue == 7) { 09101 s = 1; 09102 } else if (residue == 3 || residue == 5) { 09103 s = -1; 09104 } 09105 } 09106 09107 /* step 5. if p == 3 (mod 4) *and* a == 3 (mod 4) then s = -s */ 09108 if ( ((n->dp[0] & 3) == 3) && ((a->dp[0] & 3) == 3)) { 09109 s = -s; 09110 } 09111 } 09112 09113 if (res == MP_OKAY) { 09114 /* if a == 1 we're done */ 09115 if (mp_cmp_d(a, 1) == MP_EQ) { 09116 *c = s; 09117 } else { 09118 /* n1 = n mod a */ 09119 res = mp_mod (n, a, n); 09120 if (res == MP_OKAY) 09121 res = do_mp_jacobi(n, a, &r); 09122 09123 if (res == MP_OKAY) 09124 *c = s * r; 09125 } 09126 } 09127 09128 return res; 09129 } 09130 09131 09132 /* computes the jacobi c = (a | n) (or Legendre if n is prime) 09133 * HAC pp. 73 Algorithm 2.149 09134 * HAC is wrong here, as the special case of (0 | 1) is not 09135 * handled correctly. 09136 */ 09137 int mp_jacobi(mp_int* a, mp_int* n, int* c) 09138 { 09139 mp_int a1, n1; 09140 int res; 09141 09142 /* step 3. write a = a1 * 2**k */ 09143 if ((res = mp_init_multi(&a1, &n1, NULL, NULL, NULL, NULL)) != MP_OKAY) { 09144 return res; 09145 } 09146 09147 if ((res = mp_copy(a, &a1)) != MP_OKAY) { 09148 goto done; 09149 } 09150 09151 if ((res = mp_copy(n, &n1)) != MP_OKAY) { 09152 goto done; 09153 } 09154 09155 res = do_mp_jacobi(&a1, &n1, c); 09156 09157 done: 09158 /* cleanup */ 09159 mp_clear(&n1); 09160 mp_clear(&a1); 09161 09162 return res; 09163 } 09164 09165 09166 /* Solves the modular equation x^2 = n (mod p) 09167 * where prime number is greater than 2 (odd prime). 09168 * The result is returned in the third argument x 09169 * the function returns MP_OKAY on success, MP_VAL or another error on failure 09170 */ 09171 int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) 09172 { 09173 #ifdef SQRTMOD_USE_MOD_EXP 09174 int res; 09175 09176 mp_int e; 09177 09178 res = mp_init(&e); 09179 if (res == MP_OKAY) 09180 res = mp_add_d(prime, 1, &e); 09181 if (res == MP_OKAY) 09182 res = mp_div_2d(&e, 2, &e, NULL); 09183 if (res == MP_OKAY) 09184 res = mp_exptmod(n, &e, prime, ret); 09185 09186 mp_clear(&e); 09187 09188 return res; 09189 #else 09190 int res, legendre, done = 0; 09191 mp_int t1, C, Q, S, Z, M, T, R, two; 09192 mp_digit i; 09193 09194 /* first handle the simple cases n = 0 or n = 1 */ 09195 if (mp_cmp_d(n, 0) == MP_EQ) { 09196 mp_zero(ret); 09197 return MP_OKAY; 09198 } 09199 if (mp_cmp_d(n, 1) == MP_EQ) { 09200 return mp_set(ret, 1); 09201 } 09202 09203 /* prime must be odd */ 09204 if (mp_cmp_d(prime, 2) == MP_EQ) { 09205 return MP_VAL; 09206 } 09207 09208 /* is quadratic non-residue mod prime */ 09209 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) { 09210 return res; 09211 } 09212 if (legendre == -1) { 09213 return MP_VAL; 09214 } 09215 09216 if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) 09217 return res; 09218 09219 if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) 09220 != MP_OKAY) { 09221 mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); 09222 mp_clear(&M); 09223 return res; 09224 } 09225 09226 /* SPECIAL CASE: if prime mod 4 == 3 09227 * compute directly: res = n^(prime+1)/4 mod prime 09228 * Handbook of Applied Cryptography algorithm 3.36 09229 */ 09230 res = mp_mod_d(prime, 4, &i); 09231 if (res == MP_OKAY && i == 3) { 09232 res = mp_add_d(prime, 1, &t1); 09233 09234 if (res == MP_OKAY) 09235 res = mp_div_2(&t1, &t1); 09236 if (res == MP_OKAY) 09237 res = mp_div_2(&t1, &t1); 09238 if (res == MP_OKAY) 09239 res = mp_exptmod(n, &t1, prime, ret); 09240 09241 done = 1; 09242 } 09243 09244 /* NOW: TonelliShanks algorithm */ 09245 if (res == MP_OKAY && done == 0) { 09246 09247 /* factor out powers of 2 from prime-1, defining Q and S 09248 * as: prime-1 = Q*2^S */ 09249 /* Q = prime - 1 */ 09250 res = mp_copy(prime, &Q); 09251 if (res == MP_OKAY) 09252 res = mp_sub_d(&Q, 1, &Q); 09253 09254 /* S = 0 */ 09255 if (res == MP_OKAY) 09256 mp_zero(&S); 09257 09258 while (res == MP_OKAY && mp_iseven(&Q) == MP_YES) { 09259 /* Q = Q / 2 */ 09260 res = mp_div_2(&Q, &Q); 09261 09262 /* S = S + 1 */ 09263 if (res == MP_OKAY) 09264 res = mp_add_d(&S, 1, &S); 09265 } 09266 09267 /* find a Z such that the Legendre symbol (Z|prime) == -1 */ 09268 /* Z = 2 */ 09269 if (res == MP_OKAY) 09270 res = mp_set_int(&Z, 2); 09271 09272 while (res == MP_OKAY) { 09273 res = mp_jacobi(&Z, prime, &legendre); 09274 if (res == MP_OKAY && legendre == -1) 09275 break; 09276 09277 /* Z = Z + 1 */ 09278 if (res == MP_OKAY) 09279 res = mp_add_d(&Z, 1, &Z); 09280 } 09281 09282 /* C = Z ^ Q mod prime */ 09283 if (res == MP_OKAY) 09284 res = mp_exptmod(&Z, &Q, prime, &C); 09285 09286 /* t1 = (Q + 1) / 2 */ 09287 if (res == MP_OKAY) 09288 res = mp_add_d(&Q, 1, &t1); 09289 if (res == MP_OKAY) 09290 res = mp_div_2(&t1, &t1); 09291 09292 /* R = n ^ ((Q + 1) / 2) mod prime */ 09293 if (res == MP_OKAY) 09294 res = mp_exptmod(n, &t1, prime, &R); 09295 09296 /* T = n ^ Q mod prime */ 09297 if (res == MP_OKAY) 09298 res = mp_exptmod(n, &Q, prime, &T); 09299 09300 /* M = S */ 09301 if (res == MP_OKAY) 09302 res = mp_copy(&S, &M); 09303 09304 if (res == MP_OKAY) 09305 res = mp_set_int(&two, 2); 09306 09307 while (res == MP_OKAY && done == 0) { 09308 res = mp_copy(&T, &t1); 09309 09310 /* reduce to 1 and count */ 09311 i = 0; 09312 while (res == MP_OKAY) { 09313 if (mp_cmp_d(&t1, 1) == MP_EQ) 09314 break; 09315 res = mp_exptmod(&t1, &two, prime, &t1); 09316 if (res == MP_OKAY) 09317 i++; 09318 } 09319 if (res == MP_OKAY && i == 0) { 09320 res = mp_copy(&R, ret); 09321 done = 1; 09322 } 09323 09324 if (done == 0) { 09325 /* t1 = 2 ^ (M - i - 1) */ 09326 if (res == MP_OKAY) 09327 res = mp_sub_d(&M, i, &t1); 09328 if (res == MP_OKAY) 09329 res = mp_sub_d(&t1, 1, &t1); 09330 if (res == MP_OKAY) 09331 res = mp_exptmod(&two, &t1, prime, &t1); 09332 09333 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ 09334 if (res == MP_OKAY) 09335 res = mp_exptmod(&C, &t1, prime, &t1); 09336 09337 /* C = (t1 * t1) mod prime */ 09338 if (res == MP_OKAY) 09339 res = mp_sqrmod(&t1, prime, &C); 09340 09341 /* R = (R * t1) mod prime */ 09342 if (res == MP_OKAY) 09343 res = mp_mulmod(&R, &t1, prime, &R); 09344 09345 /* T = (T * C) mod prime */ 09346 if (res == MP_OKAY) 09347 res = mp_mulmod(&T, &C, prime, &T); 09348 09349 /* M = i */ 09350 if (res == MP_OKAY) 09351 res = mp_set(&M, i); 09352 } 09353 } 09354 } 09355 09356 /* done */ 09357 mp_clear(&t1); 09358 mp_clear(&C); 09359 mp_clear(&Q); 09360 mp_clear(&S); 09361 mp_clear(&Z); 09362 mp_clear(&M); 09363 mp_clear(&T); 09364 mp_clear(&R); 09365 mp_clear(&two); 09366 09367 return res; 09368 #endif 09369 } 09370 #endif 09371 #endif /* !WOLFSSL_ATECC508A */ 09372 09373 09374 /* export public ECC key in ANSI X9.63 format compressed */ 09375 static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) 09376 { 09377 word32 numlen; 09378 int ret = MP_OKAY; 09379 09380 if (key == NULL || out == NULL || outLen == NULL) 09381 return BAD_FUNC_ARG; 09382 09383 if (wc_ecc_is_valid_idx(key->idx) == 0) { 09384 return ECC_BAD_ARG_E; 09385 } 09386 numlen = key->dp->size; 09387 09388 if (*outLen < (1 + numlen)) { 09389 *outLen = 1 + numlen; 09390 return BUFFER_E; 09391 } 09392 09393 #ifdef WOLFSSL_ATECC508A 09394 /* TODO: Implement equiv call to ATECC508A */ 09395 ret = BAD_COND_E; 09396 09397 #else 09398 09399 /* store first byte */ 09400 out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; 09401 09402 /* pad and store x */ 09403 XMEMSET(out+1, 0, numlen); 09404 ret = mp_to_unsigned_bin(key->pubkey.x, 09405 out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); 09406 *outLen = 1 + numlen; 09407 09408 #endif /* WOLFSSL_ATECC508A */ 09409 09410 return ret; 09411 } 09412 09413 #endif /* HAVE_COMP_KEY */ 09414 09415 09416 int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz) 09417 { 09418 int x; 09419 09420 if (oidSum == 0) { 09421 return BAD_FUNC_ARG; 09422 } 09423 09424 /* find matching OID sum (based on encoded value) */ 09425 for (x = 0; ecc_sets[x].size != 0; x++) { 09426 if (ecc_sets[x].oidSum == oidSum) { 09427 int ret = 0; 09428 #ifdef HAVE_OID_ENCODING 09429 /* check cache */ 09430 oid_cache_t* o = &ecc_oid_cache[x]; 09431 if (o->oidSz == 0) { 09432 o->oidSz = sizeof(o->oid); 09433 ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, 09434 o->oid, &o->oidSz); 09435 } 09436 if (oidSz) { 09437 *oidSz = o->oidSz; 09438 } 09439 if (oid) { 09440 *oid = o->oid; 09441 } 09442 #else 09443 if (oidSz) { 09444 *oidSz = ecc_sets[x].oidSz; 09445 } 09446 if (oid) { 09447 *oid = ecc_sets[x].oid; 09448 } 09449 #endif 09450 /* on success return curve id */ 09451 if (ret == 0) { 09452 ret = ecc_sets[x].id; 09453 } 09454 return ret; 09455 } 09456 } 09457 09458 return NOT_COMPILED_IN; 09459 } 09460 09461 #ifdef WOLFSSL_CUSTOM_CURVES 09462 int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp) 09463 { 09464 if (key == NULL || dp == NULL) { 09465 return BAD_FUNC_ARG; 09466 } 09467 09468 key->idx = ECC_CUSTOM_IDX; 09469 key->dp = dp; 09470 09471 return 0; 09472 } 09473 #endif /* WOLFSSL_CUSTOM_CURVES */ 09474 09475 #ifdef HAVE_X963_KDF 09476 09477 static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr) 09478 { 09479 int i; 09480 09481 /* in network byte order so start at end and work back */ 09482 for (i = 3; i >= 0; i--) { 09483 if (++inOutCtr[i]) /* we're done unless we overflow */ 09484 return; 09485 } 09486 } 09487 09488 /* ASN X9.63 Key Derivation Function (SEC1) */ 09489 int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz, 09490 const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz) 09491 { 09492 int ret, i; 09493 int digestSz, copySz; 09494 int remaining = outSz; 09495 byte* outIdx; 09496 byte counter[4]; 09497 byte tmp[WC_MAX_DIGEST_SIZE]; 09498 09499 #ifdef WOLFSSL_SMALL_STACK 09500 wc_HashAlg* hash; 09501 #else 09502 wc_HashAlg hash[1]; 09503 #endif 09504 09505 if (secret == NULL || secretSz == 0 || out == NULL) 09506 return BAD_FUNC_ARG; 09507 09508 /* X9.63 allowed algos only */ 09509 if (type != WC_HASH_TYPE_SHA && type != WC_HASH_TYPE_SHA224 && 09510 type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 && 09511 type != WC_HASH_TYPE_SHA512) 09512 return BAD_FUNC_ARG; 09513 09514 digestSz = wc_HashGetDigestSize(type); 09515 if (digestSz < 0) 09516 return digestSz; 09517 09518 #ifdef WOLFSSL_SMALL_STACK 09519 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL, 09520 DYNAMIC_TYPE_HASHES); 09521 if (hash == NULL) 09522 return MEMORY_E; 09523 #endif 09524 09525 ret = wc_HashInit(hash, type); 09526 if (ret != 0) { 09527 #ifdef WOLFSSL_SMALL_STACK 09528 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09529 #endif 09530 return ret; 09531 } 09532 09533 outIdx = out; 09534 XMEMSET(counter, 0, sizeof(counter)); 09535 09536 for (i = 1; remaining > 0; i++) { 09537 09538 IncrementX963KdfCounter(counter); 09539 09540 ret = wc_HashUpdate(hash, type, secret, secretSz); 09541 if (ret != 0) { 09542 #ifdef WOLFSSL_SMALL_STACK 09543 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09544 #endif 09545 return ret; 09546 } 09547 09548 ret = wc_HashUpdate(hash, type, counter, sizeof(counter)); 09549 if (ret != 0) { 09550 #ifdef WOLFSSL_SMALL_STACK 09551 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09552 #endif 09553 return ret; 09554 } 09555 09556 if (sinfo) { 09557 ret = wc_HashUpdate(hash, type, sinfo, sinfoSz); 09558 if (ret != 0) { 09559 #ifdef WOLFSSL_SMALL_STACK 09560 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09561 #endif 09562 return ret; 09563 } 09564 } 09565 09566 ret = wc_HashFinal(hash, type, tmp); 09567 if (ret != 0) { 09568 #ifdef WOLFSSL_SMALL_STACK 09569 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09570 #endif 09571 return ret; 09572 } 09573 09574 copySz = min(remaining, digestSz); 09575 XMEMCPY(outIdx, tmp, copySz); 09576 09577 remaining -= copySz; 09578 outIdx += copySz; 09579 } 09580 09581 #ifdef WOLFSSL_SMALL_STACK 09582 XFREE(hash, NULL, DYNAMIC_TYPE_HASHES); 09583 #endif 09584 09585 return 0; 09586 } 09587 #endif /* HAVE_X963_KDF */ 09588 09589 #endif /* HAVE_ECC */ 09590
Generated on Tue Jul 12 2022 16:58:05 by
1.7.2