mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
add WC_RSA_BLINDING, wc_RsaSetRNG() for RSA Private Decrypt which doesn't have an RNG
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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++) {
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user