From f31d8ff8641487dc14c84cc3ef8ed72a9b750935 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Fri, 9 Jun 2017 18:07:44 +0200 Subject: [PATCH] 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) {