* Added RSA non-blocking support enabled with WC_RSA_NONBLOCK. Adds new wc_RsaSetNonBlock function for enabling / non-block context. Added wolfCrypt test function rsa_nb_test to validate. Result is: RSA non-block sign: 8200 times and RSA non-block verify: 264 times

* Signature wrapper improvements to eliminate mallocs/frees unless small stack is used. If small stack is used only one allocation is done based on actual max (was previously was allocating too much and in the encoding case was reallocating a second buffer).
This commit is contained in:
David Garske
2018-11-02 12:41:23 -07:00
parent ae07ba93ad
commit 6372c3d6e1
7 changed files with 498 additions and 61 deletions

View File

@ -1379,6 +1379,84 @@ static int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out,
}
#endif /* WOLFSSL_XILINX_CRYPT */
#ifdef WC_RSA_NONBLOCK
static int wc_RsaFunctionNonBlock(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key)
{
int ret = 0;
word32 keyLen, len;
if (key == NULL || key->nb == NULL) {
return BAD_FUNC_ARG;
}
if (key->nb->exptmod.state == TFM_EXPTMOD_NB_INIT) {
if (mp_init(&key->nb->tmp) != MP_OKAY) {
ret = MP_INIT_E;
}
if (ret == 0) {
if (mp_read_unsigned_bin(&key->nb->tmp, (byte*)in, inLen) != MP_OKAY) {
ret = MP_READ_E;
}
}
}
if (ret == 0) {
switch(type) {
case RSA_PRIVATE_DECRYPT:
case RSA_PRIVATE_ENCRYPT:
ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->d,
&key->n, &key->nb->tmp);
if (ret == FP_WOULDBLOCK)
return ret;
if (ret != MP_OKAY)
ret = MP_EXPTMOD_E;
break;
case RSA_PUBLIC_ENCRYPT:
case RSA_PUBLIC_DECRYPT:
ret = fp_exptmod_nb(&key->nb->exptmod, &key->nb->tmp, &key->e,
&key->n, &key->nb->tmp);
if (ret == FP_WOULDBLOCK)
return ret;
if (ret != MP_OKAY)
ret = MP_EXPTMOD_E;
break;
default:
ret = RSA_WRONG_TYPE_E;
break;
}
}
if (ret == 0) {
keyLen = wc_RsaEncryptSize(key);
if (keyLen > *outLen)
ret = RSA_BUFFER_E;
}
if (ret == 0) {
len = mp_unsigned_bin_size(&key->nb->tmp);
/* pad front w/ zeros to match key length */
while (len < keyLen) {
*out++ = 0x00;
len++;
}
*outLen = keyLen;
/* convert */
if (mp_to_unsigned_bin(&key->nb->tmp, out) != MP_OKAY) {
ret = MP_TO_E;
}
}
mp_clear(&key->nb->tmp);
return ret;
}
#endif /* WC_RSA_NONBLOCK */
static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
@ -1800,7 +1878,11 @@ int wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz,
}
/* if async pending then skip cleanup*/
if (ret == WC_PENDING_E) {
if (ret == WC_PENDING_E
#ifdef WC_RSA_NONBLOCK
|| ret == FP_WOULDBLOCK
#endif
) {
return ret;
}
@ -1886,13 +1968,23 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng);
}
else
#endif
#ifdef WC_RSA_NONBLOCK
if (key->nb) {
ret = wc_RsaFunctionNonBlock(in, inLen, out, outLen, type, key);
}
else
#endif
{
ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
}
/* handle error */
if (ret < 0 && ret != WC_PENDING_E) {
if (ret < 0 && ret != WC_PENDING_E
#ifdef WC_RSA_NONBLOCK
&& ret != FP_WOULDBLOCK
#endif
) {
if (ret == MP_EXPTMOD_E) {
/* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
@ -1959,8 +2051,6 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
switch (key->state) {
case RSA_STATE_NONE:
case RSA_STATE_ENCRYPT_PAD:
key->state = RSA_STATE_ENCRYPT_PAD;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
defined(HAVE_CAVIUM)
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
@ -1981,6 +2071,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
#endif
key->state = RSA_STATE_ENCRYPT_PAD;
ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
mgf, label, labelSz, saltLen, mp_count_bits(&key->n),
key->heap);
@ -1989,7 +2080,6 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
key->state = RSA_STATE_ENCRYPT_EXPTMOD;
FALL_THROUGH;
case RSA_STATE_ENCRYPT_EXPTMOD:
@ -2016,7 +2106,11 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
}
/* if async pending then return and skip done cleanup below */
if (ret == WC_PENDING_E) {
if (ret == WC_PENDING_E
#ifdef WC_RSA_NONBLOCK
|| ret == FP_WOULDBLOCK
#endif
) {
return ret;
}
@ -2059,8 +2153,6 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
switch (key->state) {
case RSA_STATE_NONE:
case RSA_STATE_DECRYPT_EXPTMOD:
key->state = RSA_STATE_DECRYPT_EXPTMOD;
key->dataLen = inLen;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
@ -2103,8 +2195,13 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
else {
key->data = out;
}
ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen, rsa_type,
key, rng);
key->state = RSA_STATE_DECRYPT_EXPTMOD;
FALL_THROUGH;
case RSA_STATE_DECRYPT_EXPTMOD:
ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen,
rsa_type, key, rng);
if (ret >= 0 || ret == WC_PENDING_E) {
key->state = RSA_STATE_DECRYPT_UNPAD;
@ -2162,7 +2259,11 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
}
/* if async pending then return and skip done cleanup below */
if (ret == WC_PENDING_E) {
if (ret == WC_PENDING_E
#ifdef WC_RSA_NONBLOCK
|| ret == FP_WOULDBLOCK
#endif
) {
return ret;
}
@ -3139,7 +3240,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
#ifdef WC_RSA_BLINDING
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
{
if (key == NULL)
@ -3149,8 +3249,23 @@ int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
return 0;
}
#endif /* WC_RSA_BLINDING */
#ifdef WC_RSA_NONBLOCK
int wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb)
{
if (key == NULL)
return BAD_FUNC_ARG;
if (nb) {
XMEMSET(nb, 0, sizeof(RsaNb));
}
/* Allow nb == NULL to clear non-block mode */
key->nb = nb;
return 0;
}
#endif /* WC_RSA_NONBLOCK */
#endif /* NO_RSA */

View File

@ -49,35 +49,23 @@
#ifndef NO_SIG_WRAPPER
#if !defined(NO_RSA) && !defined(NO_ASN)
static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte** hash_data,
word32* hash_len)
static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte* hash_data,
word32 hash_len, word32* hash_enc_len)
{
int ret = wc_HashGetOID(hash_type);
if (ret > 0) {
int oid = ret;
int ret, oid;
/* Allocate buffer for hash and max DER encoded */
word32 digest_len = *hash_len + MAX_DER_DIGEST_SZ;
byte *digest_buf = (byte*)XMALLOC(digest_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (digest_buf) {
ret = wc_EncodeSignature(digest_buf, *hash_data, *hash_len, oid);
if (ret > 0) {
digest_len = ret;
ret = 0;
/* Replace hash with digest (DER encoding + hash) */
XFREE(*hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
*hash_data = digest_buf;
*hash_len = digest_len;
}
else {
XFREE(digest_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
}
else {
ret = MEMORY_E;
}
ret = wc_HashGetOID(hash_type);
if (ret < 0) {
return ret;
}
oid = ret;
ret = wc_EncodeSignature(hash_data, hash_data, hash_len, oid);
if (ret > 0) {
*hash_enc_len = ret;
ret = 0;
}
return ret;
}
#endif /* !NO_RSA && !NO_ASN */
@ -244,8 +232,12 @@ int wc_SignatureVerify(
const void* key, word32 key_len)
{
int ret;
word32 hash_len;
byte *hash_data = NULL;
word32 hash_len, hash_enc_len;
#ifdef WOLFSSL_SMALL_STACK
byte *hash_data;
#else
byte hash_data[MAX_DER_DIGEST_SZ];
#endif
/* Check arguments */
if (data == NULL || data_len <= 0 ||
@ -266,13 +258,22 @@ int wc_SignatureVerify(
WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len");
return ret;
}
hash_len = ret;
hash_enc_len = hash_len = ret;
#ifndef NO_RSA
if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
/* For RSA with ASN.1 encoding include room */
hash_enc_len += MAX_DER_DIGEST_ASN_SZ;
}
#endif
#ifdef WOLFSSL_SMALL_STACK
/* Allocate temporary buffer for hash data */
hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (hash_data == NULL) {
return MEMORY_E;
}
#endif
/* Perform hash of data */
ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
@ -282,20 +283,21 @@ int wc_SignatureVerify(
#if defined(NO_RSA) || defined(NO_ASN)
ret = SIG_TYPE_E;
#else
ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len);
ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
&hash_enc_len);
#endif
}
if (ret == 0) {
/* Verify signature using hash */
ret = wc_SignatureVerifyHash(hash_type, sig_type,
hash_data, hash_len, sig, sig_len, key, key_len);
hash_data, hash_enc_len, sig, sig_len, key, key_len);
}
}
if (hash_data) {
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
@ -390,8 +392,12 @@ int wc_SignatureGenerate(
const void* key, word32 key_len, WC_RNG* rng)
{
int ret;
word32 hash_len;
byte *hash_data = NULL;
word32 hash_len, hash_enc_len;
#ifdef WOLFSSL_SMALL_STACK
byte *hash_data;
#else
byte hash_data[MAX_DER_DIGEST_SZ];
#endif
/* Check arguments */
if (data == NULL || data_len <= 0 ||
@ -412,13 +418,22 @@ int wc_SignatureGenerate(
WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len");
return ret;
}
hash_len = ret;
hash_enc_len = hash_len = ret;
#ifndef NO_RSA
if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
/* For RSA with ASN.1 encoding include room */
hash_enc_len += MAX_DER_DIGEST_ASN_SZ;
}
#endif
#ifdef WOLFSSL_SMALL_STACK
/* Allocate temporary buffer for hash data */
hash_data = (byte*)XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (hash_data == NULL) {
return MEMORY_E;
}
#endif
/* Perform hash of data */
ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
@ -428,20 +443,21 @@ int wc_SignatureGenerate(
#if defined(NO_RSA) || defined(NO_ASN)
ret = SIG_TYPE_E;
#else
ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len);
ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
&hash_enc_len);
#endif
}
if (ret == 0) {
/* Generate signature using hash */
ret = wc_SignatureGenerateHash(hash_type, sig_type,
hash_data, hash_len, sig, sig_len, key, key_len, rng);
hash_data, hash_enc_len, sig, sig_len, key, key_len, rng);
}
}
if (hash_data) {
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}

View File

@ -1194,6 +1194,159 @@ int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
#ifdef TFM_TIMING_RESISTANT
#ifdef WC_RSA_NONBLOCK
/* non-blocking version of timing resistant fp_exptmod function */
/* supports cache resistance */
int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y)
{
int err;
if (nb == NULL)
return FP_VAL;
switch (nb->state) {
case TFM_EXPTMOD_NB_INIT:
/* now setup montgomery */
if ((err = fp_montgomery_setup(P, &nb->mp)) != FP_OKAY) {
nb->state = TFM_EXPTMOD_NB_INIT;
return err;
}
/* init ints */
fp_init(&nb->R[0]);
fp_init(&nb->R[1]);
#ifndef WC_NO_CACHE_RESISTANT
fp_init(&nb->R[2]);
#endif
nb->state = TFM_EXPTMOD_NB_MONT;
break;
case TFM_EXPTMOD_NB_MONT:
/* mod m -> R[0] */
fp_montgomery_calc_normalization (&nb->R[0], P);
nb->state = TFM_EXPTMOD_NB_MONT_RED;
break;
case TFM_EXPTMOD_NB_MONT_RED:
/* reduce G -> R[1] */
if (fp_cmp_mag(P, G) != FP_GT) {
/* G > P so we reduce it first */
fp_mod(G, P, &nb->R[1]);
} else {
fp_copy(G, &nb->R[1]);
}
nb->state = TFM_EXPTMOD_NB_MONT_MUL;
break;
case TFM_EXPTMOD_NB_MONT_MUL:
/* G (R[1]) * m (R[0]) */
err = fp_mul(&nb->R[1], &nb->R[0], &nb->R[1]);
if (err != FP_OKAY) {
nb->state = TFM_EXPTMOD_NB_INIT;
return err;
}
nb->state = TFM_EXPTMOD_NB_MONT_MOD;
break;
case TFM_EXPTMOD_NB_MONT_MOD:
/* mod m */
err = fp_div(&nb->R[1], P, NULL, &nb->R[1]);
if (err != FP_OKAY) {
nb->state = TFM_EXPTMOD_NB_INIT;
return err;
}
nb->state = TFM_EXPTMOD_NB_MONT_MODCHK;
break;
case TFM_EXPTMOD_NB_MONT_MODCHK:
/* m matches sign of (G * R mod m) */
if (nb->R[1].sign != P->sign) {
fp_add(&nb->R[1], P, &nb->R[1]);
}
/* set initial mode and bit cnt */
nb->bitcnt = 1;
nb->buf = 0;
nb->digidx = X->used - 1;
nb->state = TFM_EXPTMOD_NB_NEXT;
break;
case TFM_EXPTMOD_NB_NEXT:
/* grab next digit as required */
if (--nb->bitcnt == 0) {
/* if nb->digidx == -1 we are out of digits so break */
if (nb->digidx == -1) {
nb->state = TFM_EXPTMOD_NB_RED;
break;
}
/* read next digit and reset nb->bitcnt */
nb->buf = X->dp[nb->digidx--];
nb->bitcnt = (int)DIGIT_BIT;
}
/* grab the next msb from the exponent */
nb->y = (int)(nb->buf >> (DIGIT_BIT - 1)) & 1;
nb->buf <<= (fp_digit)1;
nb->state = TFM_EXPTMOD_NB_MUL;
FALL_THROUGH;
case TFM_EXPTMOD_NB_MUL:
fp_mul(&nb->R[0], &nb->R[1], &nb->R[nb->y^1]);
nb->state = TFM_EXPTMOD_NB_MUL_RED;
break;
case TFM_EXPTMOD_NB_MUL_RED:
fp_montgomery_reduce(&nb->R[nb->y^1], P, nb->mp);
nb->state = TFM_EXPTMOD_NB_SQR;
break;
case TFM_EXPTMOD_NB_SQR:
#ifdef WC_NO_CACHE_RESISTANT
fp_sqr(&nb->R[nb->y], &nb->R[nb->y]);
#else
fp_copy((fp_int*) ( ((wolfssl_word)&nb->R[0] & wc_off_on_addr[nb->y^1]) +
((wolfssl_word)&nb->R[1] & wc_off_on_addr[nb->y]) ),
&nb->R[2]);
fp_sqr(&nb->R[2], &nb->R[2]);
#endif /* WC_NO_CACHE_RESISTANT */
nb->state = TFM_EXPTMOD_NB_SQR_RED;
break;
case TFM_EXPTMOD_NB_SQR_RED:
#ifdef WC_NO_CACHE_RESISTANT
fp_montgomery_reduce(&nb->R[nb->y], P, nb->mp);
#else
fp_montgomery_reduce(&nb->R[2], P, nb->mp);
fp_copy(&nb->R[2],
(fp_int*) ( ((wolfssl_word)&nb->R[0] & wc_off_on_addr[nb->y^1]) +
((wolfssl_word)&nb->R[1] & wc_off_on_addr[nb->y]) ) );
#endif /* WC_NO_CACHE_RESISTANT */
nb->state = TFM_EXPTMOD_NB_NEXT;
break;
case TFM_EXPTMOD_NB_RED:
/* final reduce */
fp_montgomery_reduce(&nb->R[0], P, nb->mp);
fp_copy(&nb->R[0], Y);
nb->state = TFM_EXPTMOD_NB_INIT;
return FP_OKAY;
} /* switch */
return FP_WOULDBLOCK;
}
#endif /* WC_RSA_NONBLOCK */
/* timing resistant montgomery ladder based exptmod
Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
Cryptographic Hardware and Embedded Systems, CHES 2002

View File

@ -9260,6 +9260,86 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng)
}
#endif /* !NO_SIG_WRAPPER */
#ifdef WC_RSA_NONBLOCK
static int rsa_nb_test(RsaKey* key, const byte* in, word32 inLen, byte* out,
word32 outSz, byte* plain, word32 plainSz, WC_RNG* rng)
{
int ret = 0, count;
int signSz = 0;
RsaNb nb;
byte* inlinePlain = NULL;
/* Enable non-blocking RSA mode - provide context */
ret = wc_RsaSetNonBlock(key, &nb);
if (ret != 0)
return ret;
count = 0;
do {
ret = wc_RsaSSL_Sign(in, inLen, out, outSz, key, rng);
count++; /* track number of would blocks */
if (ret == FP_WOULDBLOCK) {
/* do "other" work here */
}
} while (ret == FP_WOULDBLOCK);
if (ret < 0) {
return ret;
}
#ifdef DEBUG_WOLFSSL
printf("RSA non-block sign: %d times\n", count);
#endif
signSz = ret;
/* Test non-blocking verify */
XMEMSET(plain, 0, plainSz);
count = 0;
do {
ret = wc_RsaSSL_Verify(out, (word32)signSz, plain, plainSz, key);
count++; /* track number of would blocks */
if (ret == FP_WOULDBLOCK) {
/* do "other" work here */
}
} while (ret == FP_WOULDBLOCK);
if (ret < 0) {
return ret;
}
#ifdef DEBUG_WOLFSSL
printf("RSA non-block verify: %d times\n", count);
#endif
if (signSz == ret && XMEMCMP(plain, in, (size_t)ret)) {
return SIG_VERIFY_E;
}
/* Test inline non-blocking verify */
count = 0;
do {
ret = wc_RsaSSL_VerifyInline(out, (word32)signSz, &inlinePlain, key);
count++; /* track number of would blocks */
if (ret == FP_WOULDBLOCK) {
/* do "other" work here */
}
} while (ret == FP_WOULDBLOCK);
if (ret < 0) {
return ret;
}
#ifdef DEBUG_WOLFSSL
printf("RSA non-block inline verify: %d times\n", count);
#endif
if (signSz == ret && XMEMCMP(inlinePlain, in, (size_t)ret)) {
return SIG_VERIFY_E;
}
/* Disabling non-block RSA mode */
ret = wc_RsaSetNonBlock(key, NULL);
(void)count;
return 0;
}
#endif
#ifndef HAVE_USER_RSA
static int rsa_decode_test(RsaKey* keyPub)
{
@ -10671,6 +10751,12 @@ int rsa_test(void)
goto exit_rsa;
#endif
#ifdef WC_RSA_NONBLOCK
ret = rsa_nb_test(&key, in, inLen, out, outSz, plain, plainSz, &rng);
if (ret != 0)
goto exit_rsa;
#endif
do {
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
@ -11444,7 +11530,7 @@ exit_rsa:
}
}
#endif
#endif /* !NO_RSA */
#ifndef NO_DH

View File

@ -250,7 +250,8 @@ enum Misc_ASN {
MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */
MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */
MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/
MAX_ENCODED_DIG_SZ = 73, /* sha512 + enum(bit or octet) + length(4) */
MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */
MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */
MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */
MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */
MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */
@ -258,7 +259,10 @@ enum Misc_ASN {
MAX_RSA_E_SZ = 16, /* Max RSA public e size */
MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */
MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */
MAX_DER_DIGEST_SZ = MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ, /* Maximum DER digest size */
MAX_DER_DIGEST_SZ = MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
/* Maximum DER digest size */
MAX_DER_DIGEST_ASN_SZ = MAX_ENCODED_DIG_ASN_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ,
/* Maximum DER digest ASN header size */
#ifdef WOLFSSL_CERT_GEN
#ifdef WOLFSSL_CERT_REQ
/* Max encoded cert req attributes length */

View File

@ -37,6 +37,17 @@
#define WC_RSA_EXPONENT 65537L
#endif
#if defined(WC_RSA_NONBLOCK)
/* enable support for fast math based non-blocking exptmod */
/* this splits the RSA function into many smaller operations */
#ifndef USE_FAST_MATH
#error RSA non-blocking mode only supported using fast math
#endif
/* RSA bounds check is not supported with RSA non-blocking mode */
#undef NO_RSA_BOUNDS_CHECK
#define NO_RSA_BOUNDS_CHECK
#endif
/* allow for user to plug in own crypto */
#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA))
@ -117,6 +128,13 @@ enum {
#endif
};
#ifdef WC_RSA_NONBLOCK
typedef struct RsaNb {
exptModNb_t exptmod; /* non-block expt_mod */
mp_int tmp;
} RsaNb;
#endif
/* RSA */
struct RsaKey {
mp_int n, e, d, p, q;
@ -150,6 +168,9 @@ struct RsaKey {
int idLen;
#endif
byte dataIsAlloc;
#ifdef WC_RSA_NONBLOCK
RsaNb* nb;
#endif
};
#ifndef WC_RSAKEY_TYPE_DEFINED
@ -237,7 +258,12 @@ 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);
#ifdef WC_RSA_BLINDING
WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
#endif
#ifdef WC_RSA_NONBLOCK
WOLFSSL_API int wc_RsaSetNonBlock(RsaKey* key, RsaNb* nb);
#endif
/*
choice of padding added after fips, so not available when using fips RSA

View File

@ -294,6 +294,7 @@
#define FP_VAL -1
#define FP_MEM -2
#define FP_NOT_INF -3
#define FP_WOULDBLOCK -4
/* equalities */
#define FP_LT -1 /* less than */
@ -538,6 +539,42 @@ int fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp);
/* d = a**b (mod c) */
int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);
#ifdef WC_RSA_NONBLOCK
enum tfmExptModNbState {
TFM_EXPTMOD_NB_INIT = 0,
TFM_EXPTMOD_NB_MONT,
TFM_EXPTMOD_NB_MONT_RED,
TFM_EXPTMOD_NB_MONT_MUL,
TFM_EXPTMOD_NB_MONT_MOD,
TFM_EXPTMOD_NB_MONT_MODCHK,
TFM_EXPTMOD_NB_NEXT,
TFM_EXPTMOD_NB_MUL,
TFM_EXPTMOD_NB_MUL_RED,
TFM_EXPTMOD_NB_SQR,
TFM_EXPTMOD_NB_SQR_RED,
TFM_EXPTMOD_NB_RED,
};
typedef struct {
#ifndef WC_NO_CACHE_RESISTANT
fp_int R[3];
#else
fp_int R[2];
#endif
fp_digit buf, mp;
int bitcnt;
int digidx;
int y;
int state; /* tfmExptModNbState */
} exptModNb_t;
/* non-blocking version of timing resistant fp_exptmod function */
/* supports cache resistance */
int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y);
#endif /* WC_RSA_NONBLOCK */
/* primality stuff */
/* perform a Miller-Rabin test of a to the base b and store result in "result" */