Merge pull request #1901 from dgarske/rsa_nonblock

Added RSA non-blocking support
This commit is contained in:
toddouska
2018-11-06 16:39:43 -08:00
committed by GitHub
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;
}
@ -3158,7 +3259,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)
@ -3168,8 +3268,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)
{
@ -10672,6 +10752,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);
@ -11445,7 +11531,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" */