diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index 5b50367..dcb036e 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -100,19 +100,27 @@ 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) || (mp_get_digit_count(key->dP) == 0)) { + /* + * In case CRT optimization parameters are not provided, + * the private key is directly used to 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 */ 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;