From 2bb3f0246f65e77dcce56527a1101c824745a745 Mon Sep 17 00:00:00 2001 From: Pascal Brand Date: Thu, 18 Sep 2014 02:12:59 +0200 Subject: [PATCH 1/3] RSA in case CRT optimization parameters are not populated rsa_exptmod(), ran on the private key, makes use of CRT optimization parameters. In some use-cases, the given key does not include the optimization parameters. This patch allows rsa_exptmod() to run without the CRT parameters, using directly mp_exptmod(). Signed-off-by: Pascal Brand --- src/pk/rsa/rsa_exptmod.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index 5b50367..b9f8870 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -100,19 +100,32 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } #endif /* LTC_RSA_BLINDING */ - /* tmpa = tmp^dP mod p */ - if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } + if (key->dP == NULL) { + /* + * In case CRT optimization parameters are provided, + * the private key is directly used + */ + LTC_ARGCHK(key->dQ == NULL); + LTC_ARGCHK(key->qP == NULL); + LTC_ARGCHK(key->p == NULL); + LTC_ARGCHK(key->q == NULL); + /* exptmod it */ + if ((err = mp_exptmod(tmp, key->d, key->N, tmp)) != CRYPT_OK) { goto error; } + } else { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } - /* tmpb = tmp^dQ mod q */ - if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } - /* tmp = (tmpa - tmpb) * qInv (mod p) */ - if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } - /* tmp = tmpb + q * tmp */ - if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + } #ifdef LTC_RSA_BLINDING /* unblind */ From a6e89d58d4fbb89a770be0e94f482bd7f4416b14 Mon Sep 17 00:00:00 2001 From: Pascal Brand Date: Thu, 18 Sep 2014 20:45:42 +0200 Subject: [PATCH 2/3] RSA in CRT optimization parameters are empty --- src/pk/rsa/rsa_exptmod.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index b9f8870..dcb036e 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -100,16 +100,11 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, } #endif /* LTC_RSA_BLINDING */ - if (key->dP == NULL) { + if ((key->dP == NULL) || (mp_get_digit_count(key->dP) == 0)) { /* - * In case CRT optimization parameters are provided, - * the private key is directly used + * In case CRT optimization parameters are not provided, + * the private key is directly used to exptmod it */ - LTC_ARGCHK(key->dQ == NULL); - LTC_ARGCHK(key->qP == NULL); - LTC_ARGCHK(key->p == NULL); - LTC_ARGCHK(key->q == NULL); - /* exptmod it */ if ((err = mp_exptmod(tmp, key->d, key->N, tmp)) != CRYPT_OK) { goto error; } } else { /* tmpa = tmp^dP mod p */ From 94363b601c66a006b29e800696205f3675c207a0 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Sun, 28 Sep 2014 22:52:32 +0200 Subject: [PATCH 3/3] add testcase to verify that this patch is working --- testprof/rsa_test.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/testprof/rsa_test.c b/testprof/rsa_test.c index ae27ec1..7e7e45c 100644 --- a/testprof/rsa_test.c +++ b/testprof/rsa_test.c @@ -291,6 +291,26 @@ for (cnt = 0; cnt < len; ) { return 1; } + /* verify with privKey but remove pointer to dP to test without CRT */ + + void* dP = privKey.dP; + privKey.dP = NULL; + /* change byte back to original */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + /* change a byte */ + in[0] ^= 1; + DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); + rsa_free(&key); + rsa_free(&pubKey); + rsa_free(&privKey); + return 1; + } + privKey.dP = dP; + /* verify with pubKey */ /* change byte back to original */ in[0] ^= 1;