forked from wolfSSL/wolfssl
Merge pull request #1901 from dgarske/rsa_nonblock
Added RSA non-blocking support
This commit is contained in:
@ -1379,6 +1379,84 @@ static int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSSL_XILINX_CRYPT */
|
#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,
|
static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
||||||
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
|
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 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;
|
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);
|
ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef WC_RSA_NONBLOCK
|
||||||
|
if (key->nb) {
|
||||||
|
ret = wc_RsaFunctionNonBlock(in, inLen, out, outLen, type, key);
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
|
ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle error */
|
/* 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) {
|
if (ret == MP_EXPTMOD_E) {
|
||||||
/* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
|
/* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
|
||||||
WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
|
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) {
|
switch (key->state) {
|
||||||
case RSA_STATE_NONE:
|
case RSA_STATE_NONE:
|
||||||
case RSA_STATE_ENCRYPT_PAD:
|
case RSA_STATE_ENCRYPT_PAD:
|
||||||
key->state = RSA_STATE_ENCRYPT_PAD;
|
|
||||||
|
|
||||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
|
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
|
||||||
defined(HAVE_CAVIUM)
|
defined(HAVE_CAVIUM)
|
||||||
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
|
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
|
||||||
@ -1981,6 +2071,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
key->state = RSA_STATE_ENCRYPT_PAD;
|
||||||
ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
|
ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
|
||||||
mgf, label, labelSz, saltLen, mp_count_bits(&key->n),
|
mgf, label, labelSz, saltLen, mp_count_bits(&key->n),
|
||||||
key->heap);
|
key->heap);
|
||||||
@ -1989,7 +2080,6 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
key->state = RSA_STATE_ENCRYPT_EXPTMOD;
|
key->state = RSA_STATE_ENCRYPT_EXPTMOD;
|
||||||
|
|
||||||
FALL_THROUGH;
|
FALL_THROUGH;
|
||||||
|
|
||||||
case RSA_STATE_ENCRYPT_EXPTMOD:
|
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 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2059,8 +2153,6 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
|
|||||||
|
|
||||||
switch (key->state) {
|
switch (key->state) {
|
||||||
case RSA_STATE_NONE:
|
case RSA_STATE_NONE:
|
||||||
case RSA_STATE_DECRYPT_EXPTMOD:
|
|
||||||
key->state = RSA_STATE_DECRYPT_EXPTMOD;
|
|
||||||
key->dataLen = inLen;
|
key->dataLen = inLen;
|
||||||
|
|
||||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
|
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
|
||||||
@ -2103,8 +2195,13 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
|
|||||||
else {
|
else {
|
||||||
key->data = out;
|
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) {
|
if (ret >= 0 || ret == WC_PENDING_E) {
|
||||||
key->state = RSA_STATE_DECRYPT_UNPAD;
|
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 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3158,7 +3259,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WC_RSA_BLINDING
|
#ifdef WC_RSA_BLINDING
|
||||||
|
|
||||||
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
|
int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
|
||||||
{
|
{
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
@ -3168,8 +3268,23 @@ int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WC_RSA_BLINDING */
|
#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 */
|
#endif /* NO_RSA */
|
||||||
|
@ -49,35 +49,23 @@
|
|||||||
#ifndef NO_SIG_WRAPPER
|
#ifndef NO_SIG_WRAPPER
|
||||||
|
|
||||||
#if !defined(NO_RSA) && !defined(NO_ASN)
|
#if !defined(NO_RSA) && !defined(NO_ASN)
|
||||||
static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte** hash_data,
|
static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte* hash_data,
|
||||||
word32* hash_len)
|
word32 hash_len, word32* hash_enc_len)
|
||||||
{
|
{
|
||||||
int ret = wc_HashGetOID(hash_type);
|
int ret, oid;
|
||||||
if (ret > 0) {
|
|
||||||
int oid = ret;
|
|
||||||
|
|
||||||
/* Allocate buffer for hash and max DER encoded */
|
ret = wc_HashGetOID(hash_type);
|
||||||
word32 digest_len = *hash_len + MAX_DER_DIGEST_SZ;
|
if (ret < 0) {
|
||||||
byte *digest_buf = (byte*)XMALLOC(digest_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
return ret;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
oid = ret;
|
||||||
|
|
||||||
|
ret = wc_EncodeSignature(hash_data, hash_data, hash_len, oid);
|
||||||
|
if (ret > 0) {
|
||||||
|
*hash_enc_len = ret;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* !NO_RSA && !NO_ASN */
|
#endif /* !NO_RSA && !NO_ASN */
|
||||||
@ -244,8 +232,12 @@ int wc_SignatureVerify(
|
|||||||
const void* key, word32 key_len)
|
const void* key, word32 key_len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
word32 hash_len;
|
word32 hash_len, hash_enc_len;
|
||||||
byte *hash_data = NULL;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
byte *hash_data;
|
||||||
|
#else
|
||||||
|
byte hash_data[MAX_DER_DIGEST_SZ];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
if (data == NULL || data_len <= 0 ||
|
if (data == NULL || data_len <= 0 ||
|
||||||
@ -266,13 +258,22 @@ int wc_SignatureVerify(
|
|||||||
WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len");
|
WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len");
|
||||||
return ret;
|
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 */
|
/* 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) {
|
if (hash_data == NULL) {
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Perform hash of data */
|
/* Perform hash of data */
|
||||||
ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
|
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)
|
#if defined(NO_RSA) || defined(NO_ASN)
|
||||||
ret = SIG_TYPE_E;
|
ret = SIG_TYPE_E;
|
||||||
#else
|
#else
|
||||||
ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len);
|
ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
|
||||||
|
&hash_enc_len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Verify signature using hash */
|
/* Verify signature using hash */
|
||||||
ret = wc_SignatureVerifyHash(hash_type, sig_type,
|
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) {
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -390,8 +392,12 @@ int wc_SignatureGenerate(
|
|||||||
const void* key, word32 key_len, WC_RNG* rng)
|
const void* key, word32 key_len, WC_RNG* rng)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
word32 hash_len;
|
word32 hash_len, hash_enc_len;
|
||||||
byte *hash_data = NULL;
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
byte *hash_data;
|
||||||
|
#else
|
||||||
|
byte hash_data[MAX_DER_DIGEST_SZ];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check arguments */
|
/* Check arguments */
|
||||||
if (data == NULL || data_len <= 0 ||
|
if (data == NULL || data_len <= 0 ||
|
||||||
@ -412,13 +418,22 @@ int wc_SignatureGenerate(
|
|||||||
WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len");
|
WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len");
|
||||||
return ret;
|
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 */
|
/* 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) {
|
if (hash_data == NULL) {
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Perform hash of data */
|
/* Perform hash of data */
|
||||||
ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
|
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)
|
#if defined(NO_RSA) || defined(NO_ASN)
|
||||||
ret = SIG_TYPE_E;
|
ret = SIG_TYPE_E;
|
||||||
#else
|
#else
|
||||||
ret = wc_SignatureDerEncode(hash_type, &hash_data, &hash_len);
|
ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
|
||||||
|
&hash_enc_len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Generate signature using hash */
|
/* Generate signature using hash */
|
||||||
ret = wc_SignatureGenerateHash(hash_type, sig_type,
|
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) {
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1194,6 +1194,159 @@ int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
|
|||||||
|
|
||||||
#ifdef TFM_TIMING_RESISTANT
|
#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
|
/* timing resistant montgomery ladder based exptmod
|
||||||
Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
|
Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
|
||||||
Cryptographic Hardware and Embedded Systems, CHES 2002
|
Cryptographic Hardware and Embedded Systems, CHES 2002
|
||||||
|
@ -9260,6 +9260,86 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng)
|
|||||||
}
|
}
|
||||||
#endif /* !NO_SIG_WRAPPER */
|
#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
|
#ifndef HAVE_USER_RSA
|
||||||
static int rsa_decode_test(RsaKey* keyPub)
|
static int rsa_decode_test(RsaKey* keyPub)
|
||||||
{
|
{
|
||||||
@ -10672,6 +10752,12 @@ int rsa_test(void)
|
|||||||
goto exit_rsa;
|
goto exit_rsa;
|
||||||
#endif
|
#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 {
|
do {
|
||||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||||
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||||
@ -11445,7 +11531,7 @@ exit_rsa:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* !NO_RSA */
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_DH
|
#ifndef NO_DH
|
||||||
|
@ -250,7 +250,8 @@ enum Misc_ASN {
|
|||||||
MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */
|
MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */
|
||||||
MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */
|
MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */
|
||||||
MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/
|
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_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_KEY_SZ = 610, /* NTRU 112 bit public key */
|
||||||
MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */
|
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_RSA_E_SZ = 16, /* Max RSA public e size */
|
||||||
MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */
|
MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */
|
||||||
MAX_SN_SZ = 35, /* Max encoded serial number (INT) 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_GEN
|
||||||
#ifdef WOLFSSL_CERT_REQ
|
#ifdef WOLFSSL_CERT_REQ
|
||||||
/* Max encoded cert req attributes length */
|
/* Max encoded cert req attributes length */
|
||||||
|
@ -37,6 +37,17 @@
|
|||||||
#define WC_RSA_EXPONENT 65537L
|
#define WC_RSA_EXPONENT 65537L
|
||||||
#endif
|
#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 */
|
/* allow for user to plug in own crypto */
|
||||||
#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA))
|
#if !defined(HAVE_FIPS) && (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA))
|
||||||
@ -117,6 +128,13 @@ enum {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef WC_RSA_NONBLOCK
|
||||||
|
typedef struct RsaNb {
|
||||||
|
exptModNb_t exptmod; /* non-block expt_mod */
|
||||||
|
mp_int tmp;
|
||||||
|
} RsaNb;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* RSA */
|
/* RSA */
|
||||||
struct RsaKey {
|
struct RsaKey {
|
||||||
mp_int n, e, d, p, q;
|
mp_int n, e, d, p, q;
|
||||||
@ -150,6 +168,9 @@ struct RsaKey {
|
|||||||
int idLen;
|
int idLen;
|
||||||
#endif
|
#endif
|
||||||
byte dataIsAlloc;
|
byte dataIsAlloc;
|
||||||
|
#ifdef WC_RSA_NONBLOCK
|
||||||
|
RsaNb* nb;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef WC_RSAKEY_TYPE_DEFINED
|
#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);
|
WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
|
||||||
#endif
|
#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
|
choice of padding added after fips, so not available when using fips RSA
|
||||||
|
@ -294,6 +294,7 @@
|
|||||||
#define FP_VAL -1
|
#define FP_VAL -1
|
||||||
#define FP_MEM -2
|
#define FP_MEM -2
|
||||||
#define FP_NOT_INF -3
|
#define FP_NOT_INF -3
|
||||||
|
#define FP_WOULDBLOCK -4
|
||||||
|
|
||||||
/* equalities */
|
/* equalities */
|
||||||
#define FP_LT -1 /* less than */
|
#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) */
|
/* d = a**b (mod c) */
|
||||||
int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);
|
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 */
|
/* primality stuff */
|
||||||
|
|
||||||
/* perform a Miller-Rabin test of a to the base b and store result in "result" */
|
/* perform a Miller-Rabin test of a to the base b and store result in "result" */
|
||||||
|
Reference in New Issue
Block a user