From d35e191434c4149a2a30163fc57644355b57b992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Sun, 1 Dec 2013 16:15:32 +0100 Subject: [PATCH 1/7] Drop useless include in ecp.c --- library/ecp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/library/ecp.c b/library/ecp.c index ef38d19d7..45fbd9356 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -55,7 +55,6 @@ #define polarssl_free free #endif -#include #include #if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ From a0d758b9175fba7fd45dd7d6030e2b5f0c4a12f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Sun, 1 Dec 2013 16:27:00 +0100 Subject: [PATCH 2/7] Fix typo in test dependency --- tests/suites/test_suite_rsa.data | 4 ---- tests/suites/test_suite_rsa.function | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data index f1a9d8246..bd4b6e9bb 100644 --- a/tests/suites/test_suite_rsa.data +++ b/tests/suites/test_suite_rsa.data @@ -325,19 +325,15 @@ RSA Public (Data larger than N) rsa_public:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":2048:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"3":"605baf947c0de49e4f6a0dfb94a43ae318d5df8ed20ba4ba5a37a73fb009c5c9e5cce8b70a25b1c7580f389f0d7092485cdfa02208b70d33482edf07a7eafebdc54862ca0e0396a5a7d09991b9753eb1ffb6091971bb5789c6b121abbcd0a3cbaa39969fa7c28146fce96c6d03272e3793e5be8f5abfa9afcbebb986d7b3050604a2af4d3a40fa6c003781a539a60259d1e84f13322da9e538a49c369b83e7286bf7d30b64bbb773506705da5d5d5483a563a1ffacc902fb75c9a751b1e83cdc7a6db0470056883f48b5a5446b43b1d180ea12ba11a6a8d93b3b32a30156b6084b7fb142998a2a0d28014b84098ece7d9d5e4d55cc342ca26f5a0167a679dec8":POLARSSL_ERR_RSA_BAD_INPUT_DATA RSA Generate Key -depends_on:POLARSSL_ENTROPY_C:POLARSSL_CTR_DRBG_C rsa_gen_key:128:3:0 RSA Generate Key (Number of bits too small) -depends_on:POLARSSL_ENTROPY_C:POLARSSL_CTR_DRBG_C rsa_gen_key:127:3:POLARSSL_ERR_RSA_BAD_INPUT_DATA RSA Generate Key (Exponent too small) -depends_on:POLARSSL_ENTROPY_C:POLARSSL_CTR_DRBG_C rsa_gen_key:128:2:POLARSSL_ERR_RSA_BAD_INPUT_DATA RSA Generate Key -depends_on:POLARSSL_ENTROPY_C:POLARSSL_CTR_DRBG_C rsa_gen_key:1024:3:0 RSA PKCS1 Encrypt Bad RNG diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function index 1d4a162c9..2b40b49b4 100644 --- a/tests/suites/test_suite_rsa.function +++ b/tests/suites/test_suite_rsa.function @@ -507,7 +507,7 @@ void rsa_check_privkey( int mod, int radix_P, char *input_P, int radix_Q, } /* END_CASE */ -/* BEGIN_CASE depends_on:POLARSSL_CTR_CRBG_C:POLARSSL_ENTROPY_C */ +/* BEGIN_CASE depends_on:POLARSSL_CTR_DRBG_C:POLARSSL_ENTROPY_C */ void rsa_gen_key( int nrbits, int exponent, int result) { rsa_context ctx; From 43863eeffc6b7f54da710f186e06ea3b73f33a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Sun, 1 Dec 2013 16:51:27 +0100 Subject: [PATCH 3/7] Declare internal variables static in ecp.c --- library/ecp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 45fbd9356..969e11dc3 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -75,7 +75,7 @@ * Counts of point addition and doubling, and field multiplications. * Used to test resistance of point multiplication to simple timing attacks. */ -unsigned long add_count, dbl_count, mul_count; +static unsigned long add_count, dbl_count, mul_count; #endif /* @@ -85,7 +85,7 @@ unsigned long add_count, dbl_count, mul_count; * - size in bits * - readable name */ -const ecp_curve_info ecp_supported_curves[] = +static const ecp_curve_info ecp_supported_curves[] = { #if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, From 32b04c1237e2f59931741c631ca4466eb5f59851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 2 Dec 2013 15:49:09 +0100 Subject: [PATCH 4/7] Split ecp.c --- library/CMakeLists.txt | 1 + library/Makefile | 2 +- library/ecp.c | 645 +---------------------------- library/ecp_curves.c | 700 ++++++++++++++++++++++++++++++++ visualc/VS2010/PolarSSL.vcxproj | 1 + visualc/VS6/polarssl.dsp | 4 + 6 files changed, 708 insertions(+), 645 deletions(-) create mode 100644 library/ecp_curves.c diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 1a3e0772f..411c07d80 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -17,6 +17,7 @@ set(src des.c dhm.c ecp.c + ecp_curves.c ecdh.c ecdsa.c entropy.c diff --git a/library/Makefile b/library/Makefile index 331c0a0f1..a9c86f84c 100644 --- a/library/Makefile +++ b/library/Makefile @@ -40,7 +40,7 @@ OBJS= aes.o arc4.o asn1parse.o \ certs.o cipher.o cipher_wrap.o \ ctr_drbg.o debug.o des.o \ dhm.o ecdh.o ecdsa.o \ - ecp.o \ + ecp.o ecp_curves.o \ entropy.o entropy_poll.o \ error.o gcm.o havege.o \ md.o md_wrap.o md2.o \ diff --git a/library/ecp.c b/library/ecp.c index 969e11dc3..21e28c845 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -1,5 +1,5 @@ /* - * Elliptic curves over GF(p) + * Elliptic curves over GF(p): generic functions * * Copyright (C) 2006-2013, Brainspark B.V. * @@ -513,246 +513,6 @@ cleanup: return( ret ); } -/* - * Domain parameters for secp192r1 - */ -#define SECP192R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF" -#define SECP192R1_B \ - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1" -#define SECP192R1_GX \ - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" -#define SECP192R1_GY \ - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811" -#define SECP192R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831" - -/* - * Domain parameters for secp224r1 - */ -#define SECP224R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001" -#define SECP224R1_B \ - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4" -#define SECP224R1_GX \ - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" -#define SECP224R1_GY \ - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34" -#define SECP224R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D" - -/* - * Domain parameters for secp256r1 - */ -#define SECP256R1_P \ - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP256R1_B \ - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B" -#define SECP256R1_GX \ - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" -#define SECP256R1_GY \ - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5" -#define SECP256R1_N \ - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" - -/* - * Domain parameters for secp384r1 - */ -#define SECP384R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" -#define SECP384R1_B \ - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \ - "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF" -#define SECP384R1_GX \ - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \ - "59F741E082542A385502F25DBF55296C3A545E3872760AB7" -#define SECP384R1_GY \ - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \ - "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" -#define SECP384R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" - -/* - * Domain parameters for secp521r1 - */ -#define SECP521R1_P \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP521R1_B \ - "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \ - "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \ - "3BB1BF073573DF883D2C34F1EF451FD46B503F00" -#define SECP521R1_GX \ - "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \ - "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \ - "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" -#define SECP521R1_GY \ - "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \ - "579B446817AFBD17273E662C97EE72995EF42640C550B901" \ - "3FAD0761353C7086A272C24088BE94769FD16650" -#define SECP521R1_N \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \ - "F709A5D03BB5C9B8899C47AEBB6FB71E91386409" - -/* - * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) - */ -#define BP256R1_P \ - "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377" -#define BP256R1_A \ - "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9" -#define BP256R1_B \ - "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6" -#define BP256R1_GX \ - "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262" -#define BP256R1_GY \ - "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997" -#define BP256R1_N \ - "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7" - -/* - * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) - */ -#define BP384R1_P \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711" \ - "23ACD3A729901D1A71874700133107EC53" -#define BP384R1_A \ - "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9" \ - "0F8AA5814A503AD4EB04A8C7DD22CE2826" -#define BP384R1_B \ - "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62" \ - "D57CB4390295DBC9943AB78696FA504C11" -#define BP384R1_GX \ - "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10" \ - "E8E826E03436D646AAEF87B2E247D4AF1E" -#define BP384R1_GY \ - "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129" \ - "280E4646217791811142820341263C5315" -#define BP384R1_N \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425" \ - "A7CF3AB6AF6B7FC3103B883202E9046565" - -/* - * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) - */ -#define BP512R1_P \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3" -#define BP512R1_A \ - "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863" \ - "BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA" -#define BP512R1_B \ - "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117" \ - "A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723" -#define BP512R1_GX \ - "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009" \ - "8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822" -#define BP512R1_GY \ - "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81" \ - "11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892" -#define BP512R1_N \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069" - -#if defined(POLARSSL_ECP_NIST_OPTIM) -/* Forward declarations */ -static int ecp_mod_p192( mpi * ); -static int ecp_mod_p224( mpi * ); -static int ecp_mod_p256( mpi * ); -static int ecp_mod_p384( mpi * ); -static int ecp_mod_p521( mpi * ); -#endif - -/* - * Set a group using well-known domain parameters - */ -int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) -{ - grp->id = id; - - switch( id ) - { -#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) - case POLARSSL_ECP_DP_SECP192R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p192; -#endif - return( ecp_group_read_string( grp, 16, - SECP192R1_P, SECP192R1_B, - SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) - case POLARSSL_ECP_DP_SECP224R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p224; -#endif - return( ecp_group_read_string( grp, 16, - SECP224R1_P, SECP224R1_B, - SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) - case POLARSSL_ECP_DP_SECP256R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p256; -#endif - return( ecp_group_read_string( grp, 16, - SECP256R1_P, SECP256R1_B, - SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) - case POLARSSL_ECP_DP_SECP384R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p384; -#endif - return( ecp_group_read_string( grp, 16, - SECP384R1_P, SECP384R1_B, - SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) - case POLARSSL_ECP_DP_SECP521R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p521; -#endif - return( ecp_group_read_string( grp, 16, - SECP521R1_P, SECP521R1_B, - SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) ); -#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) - case POLARSSL_ECP_DP_BP256R1: - return( ecp_group_read_string_gen( grp, 16, - BP256R1_P, BP256R1_A, BP256R1_B, - BP256R1_GX, BP256R1_GY, BP256R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) - case POLARSSL_ECP_DP_BP384R1: - return( ecp_group_read_string_gen( grp, 16, - BP384R1_P, BP384R1_A, BP384R1_B, - BP384R1_GX, BP384R1_GY, BP384R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) - case POLARSSL_ECP_DP_BP512R1: - return( ecp_group_read_string_gen( grp, 16, - BP512R1_P, BP512R1_A, BP512R1_B, - BP512R1_GX, BP512R1_GY, BP512R1_N ) ); -#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ - - default: - ecp_group_free( grp ); - return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); - } -} - /* * Set a group from an ECParameters record (RFC 4492) */ @@ -1705,409 +1465,6 @@ int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, return( ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); } -#if defined(POLARSSL_ECP_NIST_OPTIM) -/* - * Fast reduction modulo the primes used by the NIST curves. - * - * These functions are: critical for speed, but not need for correct - * operations. So, we make the choice to heavily rely on the internals of our - * bignum library, which creates a tight coupling between these functions and - * our MPI implementation. However, the coupling between the ECP module and - * MPI remains loose, since these functions can be deactivated at will. - */ - -#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) -/* - * Compared to the way things are presented in FIPS 186-3 D.2, - * we proceed in columns, from right (least significant chunk) to left, - * adding chunks to N in place, and keeping a carry for the next chunk. - * This avoids moving things around in memory, and uselessly adding zeros, - * compared to the more straightforward, line-oriented approach. - * - * For this prime we need to handle data in chunks of 64 bits. - * Since this is always a multiple of our basic t_uint, we can - * use a t_uint * to designate such a chunk, and small loops to handle it. - */ - -/* Add 64-bit chunks (dst += src) and update carry */ -static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) -{ - unsigned char i; - t_uint c = 0; - for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) - { - *dst += c; c = ( *dst < c ); - *dst += *src; c += ( *dst < *src ); - } - *carry += c; -} - -/* Add carry to a 64-bit chunk and update carry */ -static inline void carry64( t_uint *dst, t_uint *carry ) -{ - unsigned char i; - for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) - { - *dst += *carry; - *carry = ( *dst < *carry ); - } -} - -#define WIDTH 8 / sizeof( t_uint ) -#define A( i ) N->p + i * WIDTH -#define ADD( i ) add64( p, A( i ), &c ) -#define NEXT p += WIDTH; carry64( p, &c ) -#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 - -/* - * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) - */ -static int ecp_mod_p192( mpi *N ) -{ - int ret; - t_uint c = 0; - t_uint *p, *end; - - /* Make sure we have enough blocks so that A(5) is legal */ - MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); - - p = N->p; - end = p + N->n; - - ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 - ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 - ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 - -cleanup: - return( ret ); -} - -#undef WIDTH -#undef A -#undef ADD -#undef NEXT -#undef LAST -#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ - defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ - defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A( i ); - -#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ - -#define MAX32 N->n / 4 -#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ - ( N->p[4*j+1] << 8 ) | \ - ( N->p[4*j+2] << 16 ) | \ - ( N->p[4*j+3] << 24 ) -#define STORE32 N->p[4*i+0] = (t_uint)( cur ); \ - N->p[4*i+1] = (t_uint)( cur >> 8 ); \ - N->p[4*i+2] = (t_uint)( cur >> 16 ); \ - N->p[4*i+3] = (t_uint)( cur >> 24 ); - -#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ - -#define MAX32 N->n / 2 -#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) -#define STORE32 N->p[2*i+0] = (t_uint)( cur ); \ - N->p[2*i+1] = (t_uint)( cur >> 16 ); - -#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A( j ) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) -#define STORE32 \ - if( i % 2 ) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((t_uint) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (t_uint) cur; \ - } - -#endif /* sizeof( t_uint ) */ - -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *dst += src; - *carry += ( *dst < src ); -} - -static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) -{ - *carry -= ( *dst < src ); - *dst -= src; -} - -#define ADD( j ) add32( &cur, A( j ), &c ); -#define SUB( j ) sub32( &cur, A( j ), &c ); - -/* - * Helpers for the main 'loop' - * (see fix_negative for the motivation of C) - */ -#define INIT( b ) \ - int ret; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = b; \ - mpi C; \ - t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ - \ - C.s = 1; \ - C.n = b / 8 / sizeof( t_uint) + 1; \ - C.p = Cp; \ - memset( Cp, 0, C.n * sizeof( t_uint ) ); \ - \ - MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if( cc < 0 ) \ - sub32( &cur, -cc, &c ); \ - else \ - add32( &cur, cc, &c ); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while( ++i < MAX32 ) { STORE32; } \ - if( c < 0 ) fix_negative( N, c, &C, bits ); - -/* - * If the result is negative, we get it in the form - * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' - */ -static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) -{ - int ret; - - /* C = - c * 2^(bits + 32) */ -#if !defined(POLARSSL_HAVE_INT64) - ((void) bits); -#else - if( bits == 224 ) - C->p[ C->n - 1 ] = ((t_uint) -c) << 32; - else -#endif - C->p[ C->n - 1 ] = (t_uint) -c; - - /* N = - ( C - N ) */ - MPI_CHK( mpi_sub_abs( N, C, N ) ); - N->s = -1; - -cleanup: - - return( ret ); -} - -#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224( mpi *N ) -{ - INIT( 224 ); - - SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 - SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 - SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 - SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 - SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 - SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 - SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 - -cleanup: - return( ret ); -} -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) -/* - * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) - */ -static int ecp_mod_p256( mpi *N ) -{ - INIT( 256 ); - - ADD( 8 ); ADD( 9 ); - SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 - - ADD( 9 ); ADD( 10 ); - SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 - - ADD( 10 ); ADD( 11 ); - SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 - - ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); - SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 - - ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); - SUB( 9 ); SUB( 10 ); NEXT; // A4 - - ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); - SUB( 10 ); SUB( 11 ); NEXT; // A5 - - ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); - SUB( 8 ); SUB( 9 ); NEXT; // A6 - - ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); - SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 - -cleanup: - return( ret ); -} -#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) -/* - * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) - */ -static int ecp_mod_p384( mpi *N ) -{ - INIT( 384 ); - - ADD( 12 ); ADD( 21 ); ADD( 20 ); - SUB( 23 ); NEXT; // A0 - - ADD( 13 ); ADD( 22 ); ADD( 23 ); - SUB( 12 ); SUB( 20 ); NEXT; // A2 - - ADD( 14 ); ADD( 23 ); - SUB( 13 ); SUB( 21 ); NEXT; // A2 - - ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); - SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 - - ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); - SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 - - ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); - SUB( 16 ); NEXT; // A5 - - ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); - SUB( 17 ); NEXT; // A6 - - ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); - SUB( 18 ); NEXT; // A7 - - ADD( 20 ); ADD( 17 ); ADD( 16 ); - SUB( 19 ); NEXT; // A8 - - ADD( 21 ); ADD( 18 ); ADD( 17 ); - SUB( 20 ); NEXT; // A9 - - ADD( 22 ); ADD( 19 ); ADD( 18 ); - SUB( 21 ); NEXT; // A10 - - ADD( 23 ); ADD( 20 ); ADD( 19 ); - SUB( 22 ); LAST; // A11 - -cleanup: - return( ret ); -} -#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ - -#undef A -#undef LOAD32 -#undef STORE32 -#undef MAX32 -#undef INIT -#undef NEXT -#undef LAST - -#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || - POLARSSL_ECP_DP_SECP256R1_ENABLED || - POLARSSL_ECP_DP_SECP384R1_ENABLED */ - -#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - -/* Size of p521 in terms of t_uint */ -#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) - -/* Bits to keep in the most significant t_uint */ -#if defined(POLARSSL_HAVE_INT8) -#define P521_MASK 0x01 -#else -#define P521_MASK 0x01FF -#endif - -/* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 - */ -static int ecp_mod_p521( mpi *N ) -{ - int ret; - size_t i; - mpi M; - t_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when t_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ - - if( N->n < P521_WIDTH ) - return( 0 ); - - /* M = A1 */ - M.s = 1; - M.n = N->n - ( P521_WIDTH - 1 ); - if( M.n > P521_WIDTH + 1 ) - M.n = P521_WIDTH + 1; - M.p = Mp; - memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); - MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); - - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for( i = P521_WIDTH; i < N->n; i++ ) - N->p[i] = 0; - - /* N = A0 + A1 */ - MPI_CHK( mpi_add_abs( N, N, &M ) ); - -cleanup: - return( ret ); -} - -#undef P521_WIDTH -#undef P521_MASK -#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ - -#endif /* POLARSSL_ECP_NIST_OPTIM */ - #if defined(POLARSSL_SELF_TEST) /* diff --git a/library/ecp_curves.c b/library/ecp_curves.c new file mode 100644 index 000000000..a7b7bc73a --- /dev/null +++ b/library/ecp_curves.c @@ -0,0 +1,700 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +/* + * Domain parameters for secp192r1 + */ +#define SECP192R1_P \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF" +#define SECP192R1_B \ + "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1" +#define SECP192R1_GX \ + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" +#define SECP192R1_GY \ + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811" +#define SECP192R1_N \ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831" + +/* + * Domain parameters for secp224r1 + */ +#define SECP224R1_P \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001" +#define SECP224R1_B \ + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4" +#define SECP224R1_GX \ + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" +#define SECP224R1_GY \ + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34" +#define SECP224R1_N \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D" + +/* + * Domain parameters for secp256r1 + */ +#define SECP256R1_P \ + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF" +#define SECP256R1_B \ + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B" +#define SECP256R1_GX \ + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" +#define SECP256R1_GY \ + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5" +#define SECP256R1_N \ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" + +/* + * Domain parameters for secp384r1 + */ +#define SECP384R1_P \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ + "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" +#define SECP384R1_B \ + "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \ + "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF" +#define SECP384R1_GX \ + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \ + "59F741E082542A385502F25DBF55296C3A545E3872760AB7" +#define SECP384R1_GY \ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \ + "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" +#define SECP384R1_N \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ + "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" + +/* + * Domain parameters for secp521r1 + */ +#define SECP521R1_P \ + "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +#define SECP521R1_B \ + "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \ + "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \ + "3BB1BF073573DF883D2C34F1EF451FD46B503F00" +#define SECP521R1_GX \ + "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \ + "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \ + "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" +#define SECP521R1_GY \ + "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \ + "579B446817AFBD17273E662C97EE72995EF42640C550B901" \ + "3FAD0761353C7086A272C24088BE94769FD16650" +#define SECP521R1_N \ + "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ + "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \ + "F709A5D03BB5C9B8899C47AEBB6FB71E91386409" + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#define BP256R1_P \ + "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377" +#define BP256R1_A \ + "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9" +#define BP256R1_B \ + "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6" +#define BP256R1_GX \ + "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262" +#define BP256R1_GY \ + "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997" +#define BP256R1_N \ + "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7" + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#define BP384R1_P \ + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711" \ + "23ACD3A729901D1A71874700133107EC53" +#define BP384R1_A \ + "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9" \ + "0F8AA5814A503AD4EB04A8C7DD22CE2826" +#define BP384R1_B \ + "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62" \ + "D57CB4390295DBC9943AB78696FA504C11" +#define BP384R1_GX \ + "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10" \ + "E8E826E03436D646AAEF87B2E247D4AF1E" +#define BP384R1_GY \ + "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129" \ + "280E4646217791811142820341263C5315" +#define BP384R1_N \ + "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425" \ + "A7CF3AB6AF6B7FC3103B883202E9046565" + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#define BP512R1_P \ + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ + "717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3" +#define BP512R1_A \ + "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863" \ + "BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA" +#define BP512R1_B \ + "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117" \ + "A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723" +#define BP512R1_GX \ + "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009" \ + "8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822" +#define BP512R1_GY \ + "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81" \ + "11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892" +#define BP512R1_N \ + "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ + "70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069" + +/* + * Import an ECP group from ASCII strings, general case (A used) + */ +static int ecp_group_read_string_gen( ecp_group *grp, int radix, + const char *p, const char *a, const char *b, + const char *gx, const char *gy, const char *n) +{ + int ret; + + MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); + MPI_CHK( mpi_read_string( &grp->A, radix, a ) ); + MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); + MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); + MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* Forward declarations */ +int ecp_mod_p192( mpi * ); +int ecp_mod_p224( mpi * ); +int ecp_mod_p256( mpi * ); +int ecp_mod_p384( mpi * ); +int ecp_mod_p521( mpi * ); +#endif + +/* + * Set a group using well-known domain parameters + */ +int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) +{ + grp->id = id; + + switch( id ) + { +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + case POLARSSL_ECP_DP_SECP192R1: +#if defined(POLARSSL_ECP_NIST_OPTIM) + grp->modp = ecp_mod_p192; +#endif + return( ecp_group_read_string( grp, 16, + SECP192R1_P, SECP192R1_B, + SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) ); +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + case POLARSSL_ECP_DP_SECP224R1: +#if defined(POLARSSL_ECP_NIST_OPTIM) + grp->modp = ecp_mod_p224; +#endif + return( ecp_group_read_string( grp, 16, + SECP224R1_P, SECP224R1_B, + SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) ); +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + case POLARSSL_ECP_DP_SECP256R1: +#if defined(POLARSSL_ECP_NIST_OPTIM) + grp->modp = ecp_mod_p256; +#endif + return( ecp_group_read_string( grp, 16, + SECP256R1_P, SECP256R1_B, + SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) ); +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + case POLARSSL_ECP_DP_SECP384R1: +#if defined(POLARSSL_ECP_NIST_OPTIM) + grp->modp = ecp_mod_p384; +#endif + return( ecp_group_read_string( grp, 16, + SECP384R1_P, SECP384R1_B, + SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) ); +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + case POLARSSL_ECP_DP_SECP521R1: +#if defined(POLARSSL_ECP_NIST_OPTIM) + grp->modp = ecp_mod_p521; +#endif + return( ecp_group_read_string( grp, 16, + SECP521R1_P, SECP521R1_B, + SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) ); +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + case POLARSSL_ECP_DP_BP256R1: + return( ecp_group_read_string_gen( grp, 16, + BP256R1_P, BP256R1_A, BP256R1_B, + BP256R1_GX, BP256R1_GY, BP256R1_N ) ); +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + case POLARSSL_ECP_DP_BP384R1: + return( ecp_group_read_string_gen( grp, 16, + BP384R1_P, BP384R1_A, BP384R1_B, + BP384R1_GX, BP384R1_GY, BP384R1_N ) ); +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + case POLARSSL_ECP_DP_BP512R1: + return( ecp_group_read_string_gen( grp, 16, + BP512R1_P, BP512R1_A, BP512R1_B, + BP512R1_GX, BP512R1_GY, BP512R1_N ) ); +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + + default: + ecp_group_free( grp ); + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic t_uint, we can + * use a t_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) +{ + unsigned char i; + t_uint c = 0; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64( t_uint *dst, t_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( t_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +int ecp_mod_p192( mpi *N ) +{ + int ret; + t_uint c = 0; + t_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ + +#define MAX32 N->n / 4 +#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ + ( N->p[4*j+1] << 8 ) | \ + ( N->p[4*j+2] << 16 ) | \ + ( N->p[4*j+3] << 24 ) +#define STORE32 N->p[4*i+0] = (t_uint)( cur ); \ + N->p[4*i+1] = (t_uint)( cur >> 8 ); \ + N->p[4*i+2] = (t_uint)( cur >> 16 ); \ + N->p[4*i+3] = (t_uint)( cur >> 24 ); + +#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ + +#define MAX32 N->n / 2 +#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) +#define STORE32 N->p[2*i+0] = (t_uint)( cur ); \ + N->p[2*i+1] = (t_uint)( cur >> 16 ); + +#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((t_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (t_uint) cur; \ + } + +#endif /* sizeof( t_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mpi C; \ + t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( t_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( t_uint ) ); \ + \ + MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(POLARSSL_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((t_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (t_uint) -c; + + /* N = - ( C - N ) */ + MPI_CHK( mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +int ecp_mod_p224( mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +int ecp_mod_p256( mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +int ecp_mod_p384( mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || + POLARSSL_ECP_DP_SECP256R1_ENABLED || + POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of t_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) + +/* Bits to keep in the most significant t_uint */ +#if defined(POLARSSL_HAVE_INT8) +#define P521_MASK 0x01 +#else +#define P521_MASK 0x01FF +#endif + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +int ecp_mod_p521( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when t_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +#endif diff --git a/visualc/VS2010/PolarSSL.vcxproj b/visualc/VS2010/PolarSSL.vcxproj index d371f841e..33f00312b 100644 --- a/visualc/VS2010/PolarSSL.vcxproj +++ b/visualc/VS2010/PolarSSL.vcxproj @@ -218,6 +218,7 @@ + diff --git a/visualc/VS6/polarssl.dsp b/visualc/VS6/polarssl.dsp index 47fdce0ba..c40b75b18 100644 --- a/visualc/VS6/polarssl.dsp +++ b/visualc/VS6/polarssl.dsp @@ -157,6 +157,10 @@ SOURCE=..\..\library\ecp.c # End Source File # Begin Source File +SOURCE=..\..\library\ecp_curves.c +# End Source File +# Begin Source File + SOURCE=..\..\library\entropy.c # End Source File # Begin Source File From 9854fe986b748f4a7e33d72d0140a401fc3b3cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 2 Dec 2013 16:30:43 +0100 Subject: [PATCH 5/7] Convert curve constants to binary Makes source longer but resulting binary smaller --- library/ecp_curves.c | 397 +++++++++++++++++++++++++++---------------- 1 file changed, 251 insertions(+), 146 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index a7b7bc73a..87edbb708 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -32,162 +32,275 @@ /* * Domain parameters for secp192r1 */ -#define SECP192R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF" -#define SECP192R1_B \ - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1" -#define SECP192R1_GX \ - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" -#define SECP192R1_GY \ - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811" -#define SECP192R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831" +static unsigned char secp192r1_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static unsigned char *secp192r1_a = NULL; +static unsigned char secp192r1_b[] = { + 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, + 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1 }; +static unsigned char secp192r1_gx[] = { + 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, + 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12 }; +static unsigned char secp192r1_gy[] = { + 0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, 0x63, 0x10, 0x11, 0xED, + 0x6B, 0x24, 0xCD, 0xD5, 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11 }; +static unsigned char secp192r1_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 }; /* * Domain parameters for secp224r1 */ -#define SECP224R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001" -#define SECP224R1_B \ - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4" -#define SECP224R1_GX \ - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" -#define SECP224R1_GY \ - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34" -#define SECP224R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D" +static unsigned char secp224r1_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 }; +static unsigned char *secp224r1_a = NULL; +static unsigned char secp224r1_b[] = { + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4 }; +static unsigned char secp224r1_gx[] = { + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21 }; +static unsigned char secp224r1_gy[] = { + 0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6, + 0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, + 0x85, 0x00, 0x7E, 0x34 }; +static unsigned char secp224r1_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D }; /* * Domain parameters for secp256r1 */ -#define SECP256R1_P \ - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP256R1_B \ - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B" -#define SECP256R1_GX \ - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" -#define SECP256R1_GY \ - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5" -#define SECP256R1_N \ - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551" +static unsigned char secp256r1_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static unsigned char *secp256r1_a = NULL; +static unsigned char secp256r1_b[] = { + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B }; +static unsigned char secp256r1_gx[] = { + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 }; +static unsigned char secp256r1_gy[] = { + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 }; +static unsigned char secp256r1_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 }; /* * Domain parameters for secp384r1 */ -#define SECP384R1_P \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF" -#define SECP384R1_B \ - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE814112" \ - "0314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF" -#define SECP384R1_GX \ - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B98" \ - "59F741E082542A385502F25DBF55296C3A545E3872760AB7" -#define SECP384R1_GY \ - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147C" \ - "E9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F" -#define SECP384R1_N \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "C7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973" +static unsigned char secp384r1_p[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; +static unsigned char *secp384r1_a = NULL; +static unsigned char secp384r1_b[] = { + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF }; +static unsigned char secp384r1_gx[] = { + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 }; +static unsigned char secp384r1_gy[] = { + 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F }; +static unsigned char secp384r1_n[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 }; /* * Domain parameters for secp521r1 */ -#define SECP521R1_P \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" -#define SECP521R1_B \ - "00000051953EB9618E1C9A1F929A21A0B68540EEA2DA725B" \ - "99B315F3B8B489918EF109E156193951EC7E937B1652C0BD" \ - "3BB1BF073573DF883D2C34F1EF451FD46B503F00" -#define SECP521R1_GX \ - "000000C6858E06B70404E9CD9E3ECB662395B4429C648139" \ - "053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127" \ - "A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66" -#define SECP521R1_GY \ - "0000011839296A789A3BC0045C8A5FB42C7D1BD998F54449" \ - "579B446817AFBD17273E662C97EE72995EF42640C550B901" \ - "3FAD0761353C7086A272C24088BE94769FD16650" -#define SECP521R1_N \ - "000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" \ - "FFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148" \ - "F709A5D03BB5C9B8899C47AEBB6FB71E91386409" +static unsigned char secp521r1_p[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static unsigned char *secp521r1_a = NULL; +static unsigned char secp521r1_b[] = { + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 }; +static unsigned char secp521r1_gx[] = { + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 }; +static unsigned char secp521r1_gy[] = { + 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 }; +static unsigned char secp521r1_n[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 }; /* * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) */ -#define BP256R1_P \ - "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377" -#define BP256R1_A \ - "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9" -#define BP256R1_B \ - "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6" -#define BP256R1_GX \ - "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262" -#define BP256R1_GY \ - "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997" -#define BP256R1_N \ - "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7" +static unsigned char brainpoolP256r1_p[] = { + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, + 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77 }; +static unsigned char brainpoolP256r1_a[] = { + 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, + 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, + 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9 }; +static unsigned char brainpoolP256r1_b[] = { + 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, + 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, + 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6 }; +static unsigned char brainpoolP256r1_gx[] = { + 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, + 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, + 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62 }; +static unsigned char brainpoolP256r1_gy[] = { + 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, + 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, + 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97 }; +static unsigned char brainpoolP256r1_n[] = { + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, + 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 }; /* * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) */ -#define BP384R1_P \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711" \ - "23ACD3A729901D1A71874700133107EC53" -#define BP384R1_A \ - "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9" \ - "0F8AA5814A503AD4EB04A8C7DD22CE2826" -#define BP384R1_B \ - "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62" \ - "D57CB4390295DBC9943AB78696FA504C11" -#define BP384R1_GX \ - "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10" \ - "E8E826E03436D646AAEF87B2E247D4AF1E" -#define BP384R1_GY \ - "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129" \ - "280E4646217791811142820341263C5315" -#define BP384R1_N \ - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425" \ - "A7CF3AB6AF6B7FC3103B883202E9046565" +static unsigned char brainpoolP384r1_p[] = { + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, + 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, + 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53 }; +static unsigned char brainpoolP384r1_a[] = { + 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, + 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, + 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, + 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26 }; +static unsigned char brainpoolP384r1_b[] = { + 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, + 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, + 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, + 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11 }; +static unsigned char brainpoolP384r1_gx[] = { + 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, + 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, + 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, + 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E }; +static unsigned char brainpoolP384r1_gy[] = { + 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, + 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, + 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, + 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15 }; +static unsigned char brainpoolP384r1_n[] = { + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, + 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, + 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 }; /* * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) */ -#define BP512R1_P \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3" -#define BP512R1_A \ - "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863" \ - "BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA" -#define BP512R1_B \ - "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117" \ - "A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723" -#define BP512R1_GX \ - "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009" \ - "8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822" -#define BP512R1_GY \ - "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81" \ - "11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892" -#define BP512R1_N \ - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308" \ - "70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069" +static unsigned char brainpoolP512r1_p[] = { + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, + 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, + 0x58, 0x3A, 0x48, 0xF3 }; +static unsigned char brainpoolP512r1_a[] = { + 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, + 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, + 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, + 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, + 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, + 0x77, 0xFC, 0x94, 0xCA }; +static unsigned char brainpoolP512r1_b[] = { + 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, + 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, + 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, + 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, + 0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, + 0x80, 0x16, 0xF7, 0x23 }; +static unsigned char brainpoolP512r1_gx[] = { + 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, + 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, + 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, + 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, + 0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, + 0xBC, 0xB9, 0xF8, 0x22 }; +static unsigned char brainpoolP512r1_gy[] = { + 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, + 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, + 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, + 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, + 0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, + 0x3A, 0xD8, 0x08, 0x92 }; +static unsigned char brainpoolP512r1_n[] = { + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, + 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, + 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, + 0x9C, 0xA9, 0x00, 0x69 }; /* - * Import an ECP group from ASCII strings, general case (A used) + * Import an ECP group from binary */ -static int ecp_group_read_string_gen( ecp_group *grp, int radix, - const char *p, const char *a, const char *b, - const char *gx, const char *gy, const char *n) +static int ecp_group_read_binary( ecp_group *grp, + const unsigned char *p, size_t plen, + const unsigned char *a, size_t alen, + const unsigned char *b, size_t blen, + const unsigned char *gx, size_t gxlen, + const unsigned char *gy, size_t gylen, + const unsigned char *n, size_t nlen) { int ret; - MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); - MPI_CHK( mpi_read_string( &grp->A, radix, a ) ); - MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); - MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); - MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); + MPI_CHK( mpi_read_binary( &grp->P, p, plen ) ); + if( a != NULL ) + MPI_CHK( mpi_read_binary( &grp->A, a, alen ) ); + else + MPI_CHK( mpi_sub_int( &grp->A, &grp->P, 3 ) ); + MPI_CHK( mpi_read_binary( &grp->B, b, blen ) ); + MPI_CHK( mpi_read_binary( &grp->N, n, nlen ) ); + + MPI_CHK( mpi_read_binary( &grp->G.X, gx, gxlen ) ); + MPI_CHK( mpi_read_binary( &grp->G.Y, gy, gylen ) ); + MPI_CHK( mpi_lset( &grp->G.Z, 1 ) ); grp->pbits = mpi_msb( &grp->P ); grp->nbits = mpi_msb( &grp->N ); @@ -208,6 +321,14 @@ int ecp_mod_p384( mpi * ); int ecp_mod_p521( mpi * ); #endif +#define LOAD_GROUP( G ) ecp_group_read_binary( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + /* * Set a group using well-known domain parameters */ @@ -222,9 +343,7 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) #if defined(POLARSSL_ECP_NIST_OPTIM) grp->modp = ecp_mod_p192; #endif - return( ecp_group_read_string( grp, 16, - SECP192R1_P, SECP192R1_B, - SECP192R1_GX, SECP192R1_GY, SECP192R1_N ) ); + return( LOAD_GROUP( secp192r1 ) ); #endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) @@ -232,9 +351,7 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) #if defined(POLARSSL_ECP_NIST_OPTIM) grp->modp = ecp_mod_p224; #endif - return( ecp_group_read_string( grp, 16, - SECP224R1_P, SECP224R1_B, - SECP224R1_GX, SECP224R1_GY, SECP224R1_N ) ); + return( LOAD_GROUP( secp224r1 ) ); #endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) @@ -242,9 +359,7 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) #if defined(POLARSSL_ECP_NIST_OPTIM) grp->modp = ecp_mod_p256; #endif - return( ecp_group_read_string( grp, 16, - SECP256R1_P, SECP256R1_B, - SECP256R1_GX, SECP256R1_GY, SECP256R1_N ) ); + return( LOAD_GROUP( secp256r1 ) ); #endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) @@ -252,9 +367,7 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) #if defined(POLARSSL_ECP_NIST_OPTIM) grp->modp = ecp_mod_p384; #endif - return( ecp_group_read_string( grp, 16, - SECP384R1_P, SECP384R1_B, - SECP384R1_GX, SECP384R1_GY, SECP384R1_N ) ); + return( LOAD_GROUP( secp384r1 ) ); #endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) @@ -262,30 +375,22 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) #if defined(POLARSSL_ECP_NIST_OPTIM) grp->modp = ecp_mod_p521; #endif - return( ecp_group_read_string( grp, 16, - SECP521R1_P, SECP521R1_B, - SECP521R1_GX, SECP521R1_GY, SECP521R1_N ) ); + return( LOAD_GROUP( secp521r1 ) ); #endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ #if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) case POLARSSL_ECP_DP_BP256R1: - return( ecp_group_read_string_gen( grp, 16, - BP256R1_P, BP256R1_A, BP256R1_B, - BP256R1_GX, BP256R1_GY, BP256R1_N ) ); + return( LOAD_GROUP( brainpoolP256r1 ) ); #endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ #if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) case POLARSSL_ECP_DP_BP384R1: - return( ecp_group_read_string_gen( grp, 16, - BP384R1_P, BP384R1_A, BP384R1_B, - BP384R1_GX, BP384R1_GY, BP384R1_N ) ); + return( LOAD_GROUP( brainpoolP384r1 ) ); #endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ #if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) case POLARSSL_ECP_DP_BP512R1: - return( ecp_group_read_string_gen( grp, 16, - BP512R1_P, BP512R1_A, BP512R1_B, - BP512R1_GX, BP512R1_GY, BP512R1_N ) ); + return( LOAD_GROUP( brainpoolP512r1 ) ); #endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ default: From 3ee90003c97828dd5cc01dbd75626c4b04134191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 2 Dec 2013 17:14:48 +0100 Subject: [PATCH 6/7] Make internal functions static again + cosmetics --- library/ecp_curves.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 87edbb708..ec11789d0 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -314,11 +314,15 @@ cleanup: #if defined(POLARSSL_ECP_NIST_OPTIM) /* Forward declarations */ -int ecp_mod_p192( mpi * ); -int ecp_mod_p224( mpi * ); -int ecp_mod_p256( mpi * ); -int ecp_mod_p384( mpi * ); -int ecp_mod_p521( mpi * ); +static int ecp_mod_p192( mpi * ); +static int ecp_mod_p224( mpi * ); +static int ecp_mod_p256( mpi * ); +static int ecp_mod_p384( mpi * ); +static int ecp_mod_p521( mpi * ); + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) #endif #define LOAD_GROUP( G ) ecp_group_read_binary( grp, \ @@ -340,41 +344,31 @@ int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) { #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) case POLARSSL_ECP_DP_SECP192R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p192; -#endif + NIST_MODP( p192 ); return( LOAD_GROUP( secp192r1 ) ); #endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) case POLARSSL_ECP_DP_SECP224R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p224; -#endif + NIST_MODP( p224 ); return( LOAD_GROUP( secp224r1 ) ); #endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) case POLARSSL_ECP_DP_SECP256R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p256; -#endif + NIST_MODP( p256 ); return( LOAD_GROUP( secp256r1 ) ); #endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) case POLARSSL_ECP_DP_SECP384R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p384; -#endif + NIST_MODP( p384 ); return( LOAD_GROUP( secp384r1 ) ); #endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) case POLARSSL_ECP_DP_SECP521R1: -#if defined(POLARSSL_ECP_NIST_OPTIM) - grp->modp = ecp_mod_p521; -#endif + NIST_MODP( p521 ); return( LOAD_GROUP( secp521r1 ) ); #endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ @@ -456,7 +450,7 @@ static inline void carry64( t_uint *dst, t_uint *carry ) /* * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) */ -int ecp_mod_p192( mpi *N ) +static int ecp_mod_p192( mpi *N ) { int ret; t_uint c = 0; @@ -627,7 +621,7 @@ cleanup: /* * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) */ -int ecp_mod_p224( mpi *N ) +static int ecp_mod_p224( mpi *N ) { INIT( 224 ); @@ -648,7 +642,7 @@ cleanup: /* * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) */ -int ecp_mod_p256( mpi *N ) +static int ecp_mod_p256( mpi *N ) { INIT( 256 ); @@ -685,7 +679,7 @@ cleanup: /* * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) */ -int ecp_mod_p384( mpi *N ) +static int ecp_mod_p384( mpi *N ) { INIT( 384 ); @@ -762,7 +756,7 @@ cleanup: * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) * Write N as A1 + 2^521 A0, return A0 + A1 */ -int ecp_mod_p521( mpi *N ) +static int ecp_mod_p521( mpi *N ) { int ret; size_t i; From d5e0fbe1a3d11dd66aa6b37ed585e10e248a0368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 2 Dec 2013 17:20:39 +0100 Subject: [PATCH 7/7] Remove now useless function --- library/ecp.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 21e28c845..8338b2c6a 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -469,31 +469,6 @@ int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt, return 0; } -/* - * Import an ECP group from ASCII strings, general case (A used) - */ -static int ecp_group_read_string_gen( ecp_group *grp, int radix, - const char *p, const char *a, const char *b, - const char *gx, const char *gy, const char *n) -{ - int ret; - - MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); - MPI_CHK( mpi_read_string( &grp->A, radix, a ) ); - MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); - MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); - MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); - - grp->pbits = mpi_msb( &grp->P ); - grp->nbits = mpi_msb( &grp->N ); - -cleanup: - if( ret != 0 ) - ecp_group_free( grp ); - - return( ret ); -} - /* * Import an ECP group from ASCII strings, case A == -3 */ @@ -503,8 +478,14 @@ int ecp_group_read_string( ecp_group *grp, int radix, { int ret; - MPI_CHK( ecp_group_read_string_gen( grp, radix, p, "00", b, gx, gy, n ) ); + MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); MPI_CHK( mpi_add_int( &grp->A, &grp->P, -3 ) ); + MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); + MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); + MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); cleanup: if( ret != 0 )