add WC_RSA_BLINDING, wc_RsaSetRNG() for RSA Private Decrypt which doesn't have an RNG

This commit is contained in:
toddouska
2016-07-18 11:57:47 -07:00
parent 9a9a98ac82
commit d235a5f0cc
10 changed files with 195 additions and 10 deletions

View File

@@ -2827,6 +2827,11 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz,
else
#endif /* HAVE_PK_CALLBACKS */
{
#ifdef WC_RSA_BLINDING
ret = wc_RsaSetRNG(key, ssl->rng);
if (ret != 0)
return ret;
#endif
ret = wc_RsaPrivateDecryptInline(in, inSz, out, key);
}

View File

@@ -1366,6 +1366,13 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
wc_FreeRsaKey(&key);
return -1;
}
#ifdef WC_RSA_BLINDING
ret = wc_RsaSetRNG(&key, session->sslServer->rng);
if (ret != 0) {
SetError(RSA_DECRYPT_STR, error, session, FATAL_ERROR_STATE);
return -1;
}
#endif
ret = wc_RsaPrivateDecrypt(input, length,
session->sslServer->arrays->preMasterSecret,SECRET_LEN, &key);

View File

@@ -1443,6 +1443,9 @@ void bench_rsa(void)
return;
}
#ifdef WC_RSA_BLINDING
wc_RsaSetRNG(&rsaKey, &rng);
#endif
start = current_time(1);
for (i = 0; i < ntimes; i++) {

View File

@@ -1769,8 +1769,15 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
}
/* decrypt encryptedKey */
keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
#ifdef WC_RSA_BLINDING
ret = wc_RsaSetRNG(key, ssl->rng);
#endif
if (ret == 0) {
keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
&decryptedKey, privKey);
} else {
keySz = ret;
}
wc_FreeRsaKey(privKey);
#ifdef WOLFSSL_SMALL_STACK

View File

@@ -781,22 +781,117 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
#endif /* WC_NO_RSA_OAEP */
#ifdef WC_RSA_BLINDING
/* helper for either lib */
static int get_digit_count(mp_int* a)
{
if (a == NULL)
return 0;
return a->used;
}
static int get_rand_digit(WC_RNG* rng, mp_digit* d)
{
return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit));
}
static int mp_rand(mp_int* a, int digits, WC_RNG* rng)
{
int ret;
mp_digit d;
if (a == NULL || rng == NULL)
return BAD_FUNC_ARG;
mp_zero(a);
if (digits <= 0) {
return MP_OKAY;
}
/* first place a random non-zero digit */
do {
ret = get_rand_digit(rng, &d);
if (ret != 0) {
return ret;
}
} while (d == 0);
if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
return ret;
}
while (--digits > 0) {
if ((ret = mp_lshd(a, 1)) != MP_OKAY) {
return ret;
}
if ((ret = get_rand_digit(rng, &d)) != 0) {
return ret;
}
if ((ret = mp_add_d(a, d, a)) != MP_OKAY) {
return ret;
}
}
return ret;
}
#endif /* WC_RSA_BLINGING */
static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key)
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
#define ERROR_OUT(x) { ret = (x); goto done;}
mp_int tmp;
#ifdef WC_RSA_BLINDING
mp_int rnd, rndi;
#endif
int ret = 0;
word32 keyLen, len;
(void)rng;
if (mp_init(&tmp) != MP_OKAY)
return MP_INIT_E;
#ifdef WC_RSA_BLINDING
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
if (mp_init_multi(&rnd, &rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
mp_clear(&tmp);
return MP_INIT_E;
}
}
#endif
if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
ERROR_OUT(MP_READ_E);
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
#ifdef WC_RSA_BLINDING
/* blind */
ret = mp_rand(&rnd, get_digit_count(&key->n), rng);
if (ret != MP_OKAY)
ERROR_OUT(ret);
/* rndi = 1/rnd mod n */
if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY)
ERROR_OUT(MP_INVMOD_E);
/* rnd = rnd^e */
if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY)
ERROR_OUT(MP_EXPTMOD_E);
/* tmp = tmp*rnd mod n */
if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY)
ERROR_OUT(MP_MULMOD_E);
#endif /* WC_RSA_BLINGING */
#ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
ERROR_OUT(MP_EXPTMOD_E);
@@ -844,6 +939,12 @@ static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
}
#endif /* RSA_LOW_MEM */
#ifdef WC_RSA_BLINDING
/* unblind */
if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY)
ERROR_OUT(MP_MULMOD_E);
#endif /* WC_RSA_BLINDING */
}
else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
@@ -872,6 +973,12 @@ static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
done:
mp_clear(&tmp);
#ifdef WC_RSA_BLINDING
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
mp_clear(&rndi);
mp_clear(&rnd);
}
#endif
if (ret == MP_EXPTMOD_E) {
WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
}
@@ -905,7 +1012,7 @@ int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
return ret;
if ((ret = wc_RsaFunction(out, sz, out, &outLen,
RSA_PUBLIC_ENCRYPT, key)) < 0)
RSA_PUBLIC_ENCRYPT, key, NULL)) < 0)
sz = ret;
return sz;
@@ -953,7 +1060,7 @@ int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
return ret;
if ((ret = wc_RsaFunction(out, sz, out, &outLen,
RSA_PUBLIC_ENCRYPT, key)) < 0)
RSA_PUBLIC_ENCRYPT, key, NULL)) < 0)
sz = ret;
return sz;
@@ -964,6 +1071,7 @@ int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
{
int ret;
WC_RNG* rng = NULL;
#ifdef HAVE_CAVIUM
if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
@@ -974,8 +1082,12 @@ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
}
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
< 0) {
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key,
rng)) < 0) {
return ret;
}
@@ -999,6 +1111,7 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
byte* label, word32 labelSz)
{
int ret;
WC_RNG* rng = NULL;
/* sanity check on arguments */
if (in == NULL || key == NULL) {
@@ -1019,7 +1132,12 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
}
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
#ifdef WC_RSA_BLINDING
rng = key->rng;
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key,
rng))
< 0) {
return ret;
}
@@ -1139,8 +1257,8 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
}
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
< 0) {
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key,
NULL)) < 0) {
return ret;
}
@@ -1211,7 +1329,7 @@ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
return ret;
if ((ret = wc_RsaFunction(out, sz, out, &outLen,
RSA_PRIVATE_ENCRYPT,key)) < 0)
RSA_PRIVATE_ENCRYPT, key, rng)) < 0)
sz = ret;
return sz;
@@ -1366,6 +1484,20 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
#endif /* WOLFSSL_KEY_GEN */
#ifdef WC_RSA_BLINDING
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
{
if (key == NULL)
return BAD_FUNC_ARG;
key->rng = rng;
return 0;
}
#endif /* WC_RSA_BLINDING */
#ifdef HAVE_CAVIUM
#include <wolfssl/wolfcrypt/logging.h>

View File

@@ -3133,4 +3133,11 @@ void mp_dump(const char* desc, mp_int* a, byte verbose)
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */
int mp_lshd (mp_int * a, int b)
{
fp_lshd(a, b);
return FP_OKAY;
}
#endif /* USE_FAST_MATH */

View File

@@ -4222,6 +4222,17 @@ int rsa_test(void)
TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER);
return -43;
}
#ifdef WC_RSA_BLINDING
{
int tmpret = ret;
ret = wc_RsaSetRNG(&key, &rng);
if (ret < 0) {
TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER);
return -843;
}
ret = tmpret;
}
#endif
ret = wc_RsaPrivateDecrypt(out, ret, plain, sizeof(plain), &key);
if (ret < 0) {
TEST_XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER);

View File

@@ -1773,6 +1773,13 @@ static INLINE int myRsaDec(WOLFSSL* ssl, byte* in, word32 inSz,
ret = wc_RsaPrivateKeyDecode(key, &idx, &myKey, keySz);
if (ret == 0) {
#ifdef WC_RSA_BLINDING
ret = wc_RsaSetRNG(&myKey, ssl->rng);
if (ret != 0) {
wc_FreeRsaKey(&myKey);
return ret;
}
#endif
ret = wc_RsaPrivateDecryptInline(in, inSz, out, &myKey);
}
wc_FreeRsaKey(&myKey);

View File

@@ -65,6 +65,9 @@ typedef struct RsaKey {
mp_int n, e, d, p, q, dP, dQ, u;
int type; /* public or private */
void* heap; /* for user memory overrides */
#ifdef WC_RSA_BLINDING
WC_RNG* rng; /* for PrivateDecrypt blinding */
#endif
#ifdef HAVE_CAVIUM
int devId; /* nitrox device id */
word32 magic; /* using cavium magic */
@@ -110,6 +113,8 @@ WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
#endif
WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
/*
choice of padding added after fips, so not available when using fips RSA
*/

View File

@@ -689,6 +689,7 @@ int mp_exch(mp_int *a, mp_int *b);
int mp_cnt_lsb(fp_int *a);
int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);
int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c);
int mp_lshd (mp_int * a, int b);
WOLFSSL_API word32 CheckRunTimeFastMath(void);