From f46b32ba2ee2e6d15afbfe3f8b92387edd4c4506 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Thu, 8 Jun 2017 23:08:51 +0200 Subject: [PATCH 01/11] better DH primes --- src/headers/tomcrypt_custom.h | 5 +- src/pk/dh/dh.c | 10 +- src/pk/dh/dh_static.c | 256 ++++++++++++++++++++++------------ src/pk/dh/dh_sys.c | 8 +- 4 files changed, 179 insertions(+), 100 deletions(-) diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 83c76d2..155b663 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -364,16 +364,15 @@ /* Supported Key Sizes */ #define LTC_DH768 #define LTC_DH1024 -#define LTC_DH1280 #define LTC_DH1536 -#define LTC_DH1792 #define LTC_DH2048 #ifndef TFM_DESC /* tfm has a problem in fp_isprime for larger key sizes */ -#define LTC_DH2560 #define LTC_DH3072 #define LTC_DH4096 +#define LTC_DH6144 +#define LTC_DH8192 #endif /* Include Katja (a Rabin variant like RSA) */ diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index 7cafc18..14ac335 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -35,8 +35,8 @@ int dh_compat_test(void) #if 0 printf("dh_test():testing size %d-bits\n", sets[x].size * 8); #endif - if ((err = mp_read_radix(g,(char *)sets[x].base, 64)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(p,(char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(g,(char *)sets[x].base, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p,(char *)sets[x].prime, 16)) != CRYPT_OK) { goto error; } /* ensure p is prime */ if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; } @@ -158,8 +158,8 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) goto error; } - if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(g, sets[key->idx].base, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p, sets[key->idx].prime, 16)) != CRYPT_OK) { goto error; } /* load the x value */ if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; } @@ -359,7 +359,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key, return err; } - if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 64)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 16)) != CRYPT_OK) { goto error; } if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; } /* enough space for output? */ diff --git a/src/pk/dh/dh_static.c b/src/pk/dh/dh_static.c index d154017..d5be03c 100644 --- a/src/pk/dh/dh_static.c +++ b/src/pk/dh/dh_static.c @@ -23,121 +23,201 @@ /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ const dh_set sets[] = { #ifdef LTC_DH768 -{ +{ /* 768-bit MODP Group 1 - https://tools.ietf.org/html/rfc7296#appendix-B.1 */ 96, "DH-768", - "4", - "F///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "//////m3wvV" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF" }, #endif #ifdef LTC_DH1024 -{ +{ /* 1024-bit MODP Group 2 - https://tools.ietf.org/html/rfc7296#appendix-B.2 */ 128, "DH-1024", - "4", - "F///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////m3C47" -}, -#endif -#ifdef LTC_DH1280 -{ - 160, - "DH-1280", - "4", - "F///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "//////////////////////////////m4kSN" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + "FFFFFFFFFFFFFFFF" }, #endif #ifdef LTC_DH1536 -{ +{ /* 1536-bit MODP Group 5 - https://tools.ietf.org/html/rfc3526#section-2 */ 192, "DH-1536", - "4", - "F///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////m5uqd" -}, -#endif -#ifdef LTC_DH1792 -{ - 224, - "DH-1792", - "4", - "F///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "//////////////////////////////////////////////////////mT/sd" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" }, #endif #ifdef LTC_DH2048 -{ +{ /* 2048-bit MODP Group 14 - https://tools.ietf.org/html/rfc3526#section-3 */ 256, "DH-2048", - "4", - "3///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "/////////////////////////////////////////m8MPh" -}, -#endif -#ifdef LTC_DH2560 -{ - 320, - "DH-2560", - "4", - "3///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "/////mKFpF" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" }, #endif #ifdef LTC_DH3072 -{ +{ /* 3072-bit MODP Group 15 - https://tools.ietf.org/html/rfc3526#section-4 */ 384, "DH-3072", - "4", - "3///////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "/////////////////////////////m32nN" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" }, #endif #ifdef LTC_DH4096 -{ +{ /* 4096-bit MODP Group 16 - https://tools.ietf.org/html/rfc3526#section-5 */ 512, "DH-4096", - "4", - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "////////////////////////////////////////////////////////////" - "/////////////////////m8pOF" + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF" +}, +#endif +#ifdef LTC_DH6144 +{ /* 6144-bit MODP Group 17 - https://tools.ietf.org/html/rfc3526#section-6 */ + 786, + "DH-6144", + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF" +}, +#endif +#ifdef LTC_DH8192 +{ /* 8192-bit MODP Group 18 - https://tools.ietf.org/html/rfc3526#section-7 */ + 1024, + "DH-8192", + "2", + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" + "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" + "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" + "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" + "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" + "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" + "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" + "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" + "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" + "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" + "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" + "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" + "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" + "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" + "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" + "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" + "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" + "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" + "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" + "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" + "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" + "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF" }, #endif { diff --git a/src/pk/dh/dh_sys.c b/src/pk/dh/dh_sys.c index 63cad60..8a42c96 100644 --- a/src/pk/dh/dh_sys.c +++ b/src/pk/dh/dh_sys.c @@ -354,8 +354,8 @@ int dh_sign_hash(const unsigned char *in, unsigned long inlen, if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto LBL_ERR; } /* load g, p and p1 */ - if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(g, sets[key->idx].base, 16)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(p, sets[key->idx].prime, 16)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto LBL_ERR; } /* p1 = (p-1)/2 */ @@ -458,8 +458,8 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen, INPUT_BIGNUM(b, sig, x, y, siglen); /* load p and g */ - if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; } - if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; } + if ((err = mp_read_radix(p, sets[key->idx].prime, 16)) != CRYPT_OK) { goto error1; } + if ((err = mp_read_radix(g, sets[key->idx].base, 16)) != CRYPT_OK) { goto error1; } /* load m */ if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; } From f31d8ff8641487dc14c84cc3ef8ed72a9b750935 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 9 Jun 2017 18:07:44 +0200 Subject: [PATCH 02/11] implement smaller private key sizes --- src/pk/dh/dh.c | 55 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index 14ac335..e1f824e 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -116,6 +116,39 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) unsigned long x; void *p, *g; int err; + /* Table of the strength estimates from https://tools.ietf.org/html/rfc3526#section-8 + * We use them as a reference to estimate an appropriate private key size. + */ + const int private_key_sizes[][2] = + { +#ifdef LTC_DH768 + { 180, 240, }, +#endif +#ifdef LTC_DH1024 + { 180, 240, }, +#endif +#ifdef LTC_DH1536 + { 180, 240, }, +#endif +#ifdef LTC_DH2048 + /* here we use 224 instead of 220 as NIST requires + * at least 224bits for the 2048bit group */ + { 224, 320, }, +#endif +#ifdef LTC_DH3072 + { 260, 420, }, +#endif +#ifdef LTC_DH4096 + { 300, 480, }, +#endif +#ifdef LTC_DH6144 + { 340, 540, }, +#endif +#ifdef LTC_DH8192 + { 380, 620, }, +#endif + { INT_MAX, INT_MAX, } + }; LTC_ARGCHK(key != NULL); @@ -126,16 +159,28 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) /* find key size */ for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); -#ifdef FAST_PK - keysize = MIN(sets[x].size, 32); -#else - keysize = sets[x].size; -#endif if (sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } + if (x >= sizeof(private_key_sizes) / sizeof(private_key_sizes[0])) { + return CRYPT_INVALID_KEYSIZE; + } key->idx = x; + /* 1. Read a random digit + * 2. Shorten it to the range between both strengths' + * 3. Now we have a random digit between both strengths' + * 4. Make sure the division afterwards rounds up + * 5. Convert bit to byte + */ + if (prng_descriptor[wprng].read((void*)&keysize, sizeof(keysize), prng) != sizeof(keysize)) { + return CRYPT_ERROR_READPRNG; + } + keysize %= private_key_sizes[x][1] - private_key_sizes[x][0]; + keysize += private_key_sizes[x][0]; + keysize += 7; + keysize /= 8; + /* allocate buffer */ buf = XMALLOC(keysize); if (buf == NULL) { From e60d2076c5ec1768ead021a1daa3200f2d431724 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 9 Jun 2017 18:29:18 +0200 Subject: [PATCH 03/11] resurrect DH in timing --- demos/timing.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/demos/timing.c b/demos/timing.c index f03d74f..61f509e 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -888,6 +888,58 @@ static void time_katja(void) static void time_katja(void) { fprintf(stderr, "NO Katja\n"); } #endif +#ifdef LTC_MDH +/* time various DH operations */ +static void time_dh(void) +{ + dh_key key; + ulong64 t1, t2; + unsigned char buf[2][4096]; + unsigned long i, x, y, z; + int err; + static unsigned long sizes[] = {768/8, 1024/8, 1536/8, 2048/8, 3072/8, 4096/8, 6144/8, 8192/8, 100000}; + + for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { + t2 = 0; + for (y = 0; y < 16; y++) { + t_start(); + t1 = t_read(); + if ((err = dh_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + + if (y < 15) { + dh_free(&key); + } + } + t2 >>= 4; + fprintf(stderr, "DH-%4lu make_key took %15llu cycles\n", x*8, t2); + + t2 = 0; + for (y = 0; y < 16; y++) { + t_start(); + t1 = t_read(); + z = sizeof(buf[1]); + if ((err = dh_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), + &key)) != CRYPT_OK) { + fprintf(stderr, "\n\ndh_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t1 = t_read() - t1; + t2 += t1; + } + t2 >>= 4; + fprintf(stderr, "DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2); + dh_free(&key); + } +} +#else +static void time_dh(void) { fprintf(stderr, "NO DH\n"); } +#endif + #ifdef LTC_MECC /* time various ECC operations */ static void time_ecc(void) @@ -1386,6 +1438,7 @@ time_rsa(); time_dsa(); time_ecc(); time_katja(); +time_dh(); return EXIT_SUCCESS; } From e3329bec26ae1150d3ca11af88a32f427086b2f0 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 9 Jun 2017 18:30:18 +0200 Subject: [PATCH 04/11] make it possible to pass a single timing test to run --- demos/timing.c | 87 ++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/demos/timing.c b/demos/timing.c index 61f509e..fa5cdcd 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -133,7 +133,7 @@ static void init_timer(void) fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew); } -static int time_keysched(void) +static void time_keysched(void) { unsigned long x, y1; ulong64 t1, c1; @@ -165,12 +165,10 @@ static int time_keysched(void) #undef DO1 } tally_results(0); - - return 0; } #ifdef LTC_ECB_MODE -static int time_cipher_ecb(void) +static void time_cipher_ecb(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; @@ -237,15 +235,13 @@ static int time_cipher_ecb(void) #undef DO1 } tally_results(1); - - return 0; } #else -static int time_cipher_ecb(void) { fprintf(stderr, "NO ECB\n"); return 0; } +static void time_cipher_ecb(void) { fprintf(stderr, "NO ECB\n"); return 0; } #endif #ifdef LTC_CBC_MODE -static int time_cipher_cbc(void) +static void time_cipher_cbc(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; @@ -312,15 +308,13 @@ static int time_cipher_cbc(void) #undef DO1 } tally_results(1); - - return 0; } #else -static int time_cipher_cbc(void) { fprintf(stderr, "NO CBC\n"); return 0; } +static void time_cipher_cbc(void) { fprintf(stderr, "NO CBC\n"); return 0; } #endif #ifdef LTC_CTR_MODE -static int time_cipher_ctr(void) +static void time_cipher_ctr(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; @@ -387,15 +381,13 @@ static int time_cipher_ctr(void) #undef DO1 } tally_results(1); - - return 0; } #else -static int time_cipher_ctr(void) { fprintf(stderr, "NO CTR\n"); return 0; } +static void time_cipher_ctr(void) { fprintf(stderr, "NO CTR\n"); return 0; } #endif #ifdef LTC_LRW_MODE -static int time_cipher_lrw(void) +static void time_cipher_lrw(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; @@ -464,15 +456,13 @@ static int time_cipher_lrw(void) #undef DO1 } tally_results(1); - - return 0; } #else -static int time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); return 0; } +static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); return 0; } #endif -static int time_hash(void) +static void time_hash(void) { unsigned long x, y1, len; ulong64 t1, t2, c1, c2; @@ -519,8 +509,6 @@ static int time_hash(void) #undef DO1 } tally_results(2); - - return 0; } /*#warning you need an mp_rand!!!*/ @@ -1399,9 +1387,36 @@ static void time_encmacs(void) time_encmacs_(32); } -int main(void) +#define LTC_TEST_FN(f) { f, #f } +int main(int argc, char **argv) { int err; + +const struct +{ + void (*fn)(void); + const char* name; +} test_functions[] = { + LTC_TEST_FN(time_keysched), + LTC_TEST_FN(time_cipher_ecb), + LTC_TEST_FN(time_cipher_cbc), + LTC_TEST_FN(time_cipher_ctr), + LTC_TEST_FN(time_cipher_lrw), + LTC_TEST_FN(time_hash), + LTC_TEST_FN(time_macs), + LTC_TEST_FN(time_encmacs), + LTC_TEST_FN(time_prng), + LTC_TEST_FN(time_mult), + LTC_TEST_FN(time_sqr), + LTC_TEST_FN(time_rsa), + LTC_TEST_FN(time_dsa), + LTC_TEST_FN(time_ecc), + LTC_TEST_FN(time_dh), + LTC_TEST_FN(time_katja) +}; +char *single_test = NULL; +unsigned int i; + init_timer(); register_all_ciphers(); register_all_hashes(); @@ -1423,22 +1438,16 @@ if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT exit(EXIT_FAILURE); } -time_keysched(); -time_cipher_ecb(); -time_cipher_cbc(); -time_cipher_ctr(); -time_cipher_lrw(); -time_hash(); -time_macs(); -time_encmacs(); -time_prng(); -time_mult(); -time_sqr(); -time_rsa(); -time_dsa(); -time_ecc(); -time_katja(); -time_dh(); +/* single test name from commandline */ +if (argc > 1) single_test = argv[1]; + +for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) { + if (single_test && strstr(test_functions[i].name, single_test) == NULL) { + continue; + } + test_functions[i].fn(); +} + return EXIT_SUCCESS; } From c9f462869306182272e8e4c02da53d6370391ab1 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 9 Jun 2017 13:38:21 +0200 Subject: [PATCH 05/11] don't call `rng_make_prng()` from `dh_make_key()` While testing with multiple threads I had spurious errors where some tests can't read from the PRNG. If I tracked it down correctly that's caused by `dh_make_key()` calling `rng_make_prng()` which re-initializes the selected PRNG. I like the idea of "refreshing" the PRNG with entropy from a hopefully secure RNG before generating a new key, but I don't think it's the duty of a key-generation function to ensure that, but merely the application that implements key-generation. --- src/pk/dh/dh.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index e1f824e..73754c1 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -188,11 +188,6 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) } /* make up random string */ - if ( rng_make_prng( keysize, wprng, prng, NULL) != CRYPT_OK) { - err = CRYPT_ERROR_READPRNG; - goto error2; - } - if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { err = CRYPT_ERROR_READPRNG; goto error2; From 532c511f5244e8167dfe35eb9503a0271fbebd5e Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sat, 10 Jun 2017 23:02:30 +0200 Subject: [PATCH 06/11] improved dh_make_key --- src/pk/dh/dh.c | 119 ++++++++++++++++++------------------------------- 1 file changed, 44 insertions(+), 75 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index 73754c1..a0c0913 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -104,53 +104,36 @@ int dh_get_size(dh_key *key) /** Make a DH key [private key pair] - @param prng An active PRNG state - @param wprng The index for the PRNG you desire to use - @param keysize The key size (octets) desired - @param key [out] Where the newly created DH key will be stored + @param prng An active PRNG state + @param wprng The index for the PRNG you desire to use + @param groupsize The size (octets) of used DH group + @param key [out] Where the newly created DH key will be stored @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. */ -int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) +int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) { unsigned char *buf; - unsigned long x; - void *p, *g; + unsigned long x, keysize; + void *p, *g, *p_minus1; int err; - /* Table of the strength estimates from https://tools.ietf.org/html/rfc3526#section-8 - * We use them as a reference to estimate an appropriate private key size. - */ - const int private_key_sizes[][2] = - { -#ifdef LTC_DH768 - { 180, 240, }, -#endif -#ifdef LTC_DH1024 - { 180, 240, }, -#endif -#ifdef LTC_DH1536 - { 180, 240, }, -#endif -#ifdef LTC_DH2048 - /* here we use 224 instead of 220 as NIST requires - * at least 224bits for the 2048bit group */ - { 224, 320, }, -#endif -#ifdef LTC_DH3072 - { 260, 420, }, -#endif -#ifdef LTC_DH4096 - { 300, 480, }, -#endif -#ifdef LTC_DH6144 - { 340, 540, }, -#endif -#ifdef LTC_DH8192 - { 380, 620, }, -#endif - { INT_MAX, INT_MAX, } - }; LTC_ARGCHK(key != NULL); + LTC_ARGCHK(prng != NULL); + + /* Table of the strength estimates from https://tools.ietf.org/html/rfc3526#section-8 + * We use "Estimate 2" to get an appropriate private key (exponent) size. + */ + switch (groupsize) { + case 96: keysize = 30; break; /* 768-bit => key size 240-bit */ + case 128: keysize = 30; break; /* 1024-bit => key size 240-bit */ + case 192: keysize = 30; break; /* 1536-bit => key size 240-bit */ + case 256: keysize = 40; break; /* 2048-bit => key size 320-bit */ + case 384: keysize = 52; break; /* 3072-bit => key size 416-bit */ + case 512: keysize = 60; break; /* 4096-bit => key size 480-bit */ + case 768: keysize = 67; break; /* 6144-bit => key size 536-bit */ + case 1024: keysize = 77; break; /* 8192-bit => key size 616-bit */ + default: return CRYPT_INVALID_KEYSIZE; + } /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { @@ -162,61 +145,47 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) if (sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } - if (x >= sizeof(private_key_sizes) / sizeof(private_key_sizes[0])) { - return CRYPT_INVALID_KEYSIZE; - } key->idx = x; - /* 1. Read a random digit - * 2. Shorten it to the range between both strengths' - * 3. Now we have a random digit between both strengths' - * 4. Make sure the division afterwards rounds up - * 5. Convert bit to byte - */ - if (prng_descriptor[wprng].read((void*)&keysize, sizeof(keysize), prng) != sizeof(keysize)) { - return CRYPT_ERROR_READPRNG; - } - keysize %= private_key_sizes[x][1] - private_key_sizes[x][0]; - keysize += private_key_sizes[x][0]; - keysize += 7; - keysize /= 8; - /* allocate buffer */ buf = XMALLOC(keysize); if (buf == NULL) { return CRYPT_MEM; } - /* make up random string */ - if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { - err = CRYPT_ERROR_READPRNG; - goto error2; - } - - /* init parameters */ - if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != CRYPT_OK) { - goto error; + /* init big numbers */ + if ((err = mp_init_multi(&g, &p, &p_minus1, &key->x, &key->y, NULL)) != CRYPT_OK) { + goto freebuf; } if ((err = mp_read_radix(g, sets[key->idx].base, 16)) != CRYPT_OK) { goto error; } if ((err = mp_read_radix(p, sets[key->idx].prime, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_sub_d(p, 1, p_minus1)) != CRYPT_OK) { goto error; } - /* load the x value */ - if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; } - if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; } + do { + /* make up random buf */ + if (prng_descriptor[wprng].read(buf, keysize, prng) != keysize) { + err = CRYPT_ERROR_READPRNG; + goto error; + } + /* load the x value - private key */ + if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; } + /* compute the y value - public key */ + if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; } + /* avoid: y == 1 OR y == p-1 */ + } while (mp_cmp(key->y, p_minus1) == LTC_MP_EQ || mp_cmp_d(key->y, 1) == LTC_MP_EQ); + + /* success */ key->type = PK_PRIVATE; - - /* free up ram */ err = CRYPT_OK; goto done; + error: mp_clear_multi(key->x, key->y, NULL); done: - mp_clear_multi(p, g, NULL); -error2: -#ifdef LTC_CLEAN_STACK + mp_clear_multi(g, p, p_minus1, NULL); +freebuf: zeromem(buf, keysize); -#endif XFREE(buf); return err; } From 71884788e38bb692255b5c0b9aa8e4b8df161b2c Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sun, 11 Jun 2017 10:12:18 +0200 Subject: [PATCH 07/11] fix warning: comparison between signed and unsigned integer --- src/pk/dh/dh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index a0c0913..b4dc8e5 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -141,7 +141,7 @@ int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) } /* find key size */ - for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); + for (x = 0; ((int)keysize > sets[x].size) && (sets[x].size != 0); x++); if (sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } From 361778d2ac9a8bd00a3e9379b713aeb408e218ed Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sun, 11 Jun 2017 19:43:08 +0200 Subject: [PATCH 08/11] another dh_make_key redesign --- src/pk/dh/dh.c | 58 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index b4dc8e5..6239c7a 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -113,39 +113,50 @@ int dh_get_size(dh_key *key) int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) { unsigned char *buf; - unsigned long x, keysize; + unsigned long idx, keysize; void *p, *g, *p_minus1; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(prng != NULL); - - /* Table of the strength estimates from https://tools.ietf.org/html/rfc3526#section-8 - * We use "Estimate 2" to get an appropriate private key (exponent) size. - */ - switch (groupsize) { - case 96: keysize = 30; break; /* 768-bit => key size 240-bit */ - case 128: keysize = 30; break; /* 1024-bit => key size 240-bit */ - case 192: keysize = 30; break; /* 1536-bit => key size 240-bit */ - case 256: keysize = 40; break; /* 2048-bit => key size 320-bit */ - case 384: keysize = 52; break; /* 3072-bit => key size 416-bit */ - case 512: keysize = 60; break; /* 4096-bit => key size 480-bit */ - case 768: keysize = 67; break; /* 6144-bit => key size 536-bit */ - case 1024: keysize = 77; break; /* 8192-bit => key size 616-bit */ - default: return CRYPT_INVALID_KEYSIZE; - } + LTC_ARGCHK(groupsize >= 32); /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } - /* find key size */ - for (x = 0; ((int)keysize > sets[x].size) && (sets[x].size != 0); x++); - if (sets[x].size == 0) { + /* find group size */ + for (idx = 0; (groupsize > sets[idx].size) && (sets[idx].size != 0); idx++); + if (sets[idx].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + groupsize = sets[idx].size; + + /* The strength estimates from https://tools.ietf.org/html/rfc3526#section-8 + * We use "Estimate 2" to get an appropriate private key (exponent) size. + */ + if (groupsize <= 192) { + keysize = 30; /* 1536-bit => key size 240-bit */ + } + else if (groupsize <= 256) { + keysize = 40; /* 2048-bit => key size 320-bit */ + } + else if (groupsize <= 384) { + keysize = 52; /* 3072-bit => key size 416-bit */ + } + else if (groupsize <= 512) { + keysize = 60; /* 4096-bit => key size 480-bit */ + } + else if (groupsize <= 768) { + keysize = 67; /* 6144-bit => key size 536-bit */ + } + else if (groupsize <= 1024) { + keysize = 77; /* 8192-bit => key size 616-bit */ + } + else { return CRYPT_INVALID_KEYSIZE; } - key->idx = x; /* allocate buffer */ buf = XMALLOC(keysize); @@ -158,8 +169,8 @@ int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) goto freebuf; } - if ((err = mp_read_radix(g, sets[key->idx].base, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(p, sets[key->idx].prime, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(g, sets[idx].base, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p, sets[idx].prime, 16)) != CRYPT_OK) { goto error; } if ((err = mp_sub_d(p, 1, p_minus1)) != CRYPT_OK) { goto error; } do { @@ -173,9 +184,10 @@ int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) /* compute the y value - public key */ if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; } /* avoid: y == 1 OR y == p-1 */ - } while (mp_cmp(key->y, p_minus1) == LTC_MP_EQ || mp_cmp_d(key->y, 1) == LTC_MP_EQ); + } while (mp_cmp(key->y, p_minus1) != LTC_MP_LT || mp_cmp_d(key->y, 1) != LTC_MP_GT); /* success */ + key->idx = idx; key->type = PK_PRIVATE; err = CRYPT_OK; goto done; From bc4236d90ff670fbb132164f48ff55037d94ed50 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sun, 11 Jun 2017 21:12:14 +0200 Subject: [PATCH 09/11] tuning dh_make_key --- src/pk/dh/dh.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index 6239c7a..f832e01 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -119,7 +119,6 @@ int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) LTC_ARGCHK(key != NULL); LTC_ARGCHK(prng != NULL); - LTC_ARGCHK(groupsize >= 32); /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { @@ -183,8 +182,8 @@ int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; } /* compute the y value - public key */ if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; } - /* avoid: y == 1 OR y == p-1 */ - } while (mp_cmp(key->y, p_minus1) != LTC_MP_LT || mp_cmp_d(key->y, 1) != LTC_MP_GT); + /* avoid: y <= 1 OR y >= p-1 */ + } while (mp_cmp(key->y, p_minus1) != LTC_MP_LT || mp_cmp_d(key->y, 1) != LTC_MP_GT); /* success */ key->idx = idx; From 114b694735d4f562b60aa861082fae55c659650f Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Sun, 11 Jun 2017 23:20:46 +0200 Subject: [PATCH 10/11] trying to fix dh_shared_secret - #119 --- src/pk/dh/dh.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index f832e01..16601f2 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -355,7 +355,7 @@ error: int dh_shared_secret(dh_key *private_key, dh_key *public_key, unsigned char *out, unsigned long *outlen) { - void *tmp, *p; + void *tmp, *p, *p_minus1; unsigned long x; int err; @@ -375,26 +375,31 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key, } /* compute y^x mod p */ - if ((err = mp_init_multi(&tmp, &p, NULL)) != CRYPT_OK) { + if ((err = mp_init_multi(&tmp, &p, &p_minus1, NULL)) != CRYPT_OK) { return err; } - if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 16)) != CRYPT_OK) { goto error; } - if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_read_radix(p, sets[private_key->idx].prime, 16)) != CRYPT_OK) { goto error; } + if ((err = mp_sub_d(p, 1, p_minus1)) != CRYPT_OK) { goto error; } + if (mp_cmp(public_key->y, p_minus1) != LTC_MP_LT || mp_cmp_d(public_key->y, 1) != LTC_MP_GT) { + /* reject public key with: y <= 1 OR y >= p-1 */ + err = CRYPT_INVALID_ARG; + goto error; + }; + if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; } /* enough space for output? */ x = (unsigned long)mp_unsigned_bin_size(tmp); if (*outlen < x) { err = CRYPT_BUFFER_OVERFLOW; - goto done; + goto error; } - if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { goto error; } + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { goto error; } *outlen = x; err = CRYPT_OK; - goto done; + error: -done: - mp_clear_multi(p, tmp, NULL); + mp_clear_multi(p_minus1, p, tmp, NULL); return err; } From 4f12e41d29cc7a021599608e6bb85ea97cf73fbc Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Mon, 12 Jun 2017 16:35:27 +0200 Subject: [PATCH 11/11] fix trailing ; --- src/pk/dh/dh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index 16601f2..b907540 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -385,7 +385,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key, /* reject public key with: y <= 1 OR y >= p-1 */ err = CRYPT_INVALID_ARG; goto error; - }; + } if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; } /* enough space for output? */