Merge pull request #6262 from SparkiDev/mp_int_mem_usage

SP int: improve use of stack
This commit is contained in:
JacobBarthelmeh
2023-04-06 14:06:08 -06:00
committed by GitHub
12 changed files with 2486 additions and 1898 deletions

950
src/ssl.c
View File

@ -6641,8 +6641,535 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
return ret;
}
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
#ifndef NO_RSA
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2))
static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
int devId)
{
int ret;
(void)devId;
*idx = 0;
ret = wc_RsaPrivateKeyValidate(der->buffer, idx, keySz, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if ((ret != 0) && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
word32 nSz;
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_RsaPublicKeyDecode_ex(der->buffer, idx, der->length, NULL,
&nSz, NULL, NULL);
if (ret == 0) {
*keySz = (int)nSz;
}
}
#endif
if (ret != 0) {
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448) && !defined(HAVE_PQC)
WOLFSSL_MSG("RSA decode failed and other algorithms "
"not enabled to try");
ret = WOLFSSL_BAD_FILE;
#else
ret = 0; /* continue trying other algorithms */
#endif
}
else {
/* check that the size of the RSA key is enough */
int minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
if (*keySz < minRsaSz) {
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG("Private Key size too small");
}
if (ssl) {
ssl->buffers.keyType = rsa_sa_algo;
ssl->buffers.keySz = *keySz;
}
else {
ctx->privateKeyType = rsa_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = RSAk;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
ssl->options.haveStaticECC = 0;
*resetSuites = 1;
}
}
return ret;
}
#else
static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap, int devId)
{
int ret;
/* make sure RSA key can be used */
#ifdef WOLFSSL_SMALL_STACK
RsaKey* key;
#else
RsaKey key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_InitRsaKey_ex(key, heap, devId);
if (ret == 0) {
*idx = 0;
ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret != 0) {
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448) && !defined(HAVE_PQC)
WOLFSSL_MSG("RSA decode failed and other algorithms "
"not enabled to try");
ret = WOLFSSL_BAD_FILE;
#else
ret = 0; /* continue trying other algorithms */
#endif
}
else {
/* check that the size of the RSA key is enough */
int minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
*keySz = wc_RsaEncryptSize((RsaKey*)key);
if (*keySz < minRsaSz) {
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG("Private Key size too small");
}
if (ssl) {
ssl->buffers.keyType = rsa_sa_algo;
ssl->buffers.keySz = *keySz;
}
else {
ctx->privateKeyType = rsa_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = RSAk;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
ssl->options.haveStaticECC = 0;
*resetSuites = 1;
}
}
wc_FreeRsaKey(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_RSA);
#endif
return ret;
}
#endif
#endif /* !NO_RSA */
#ifdef HAVE_ECC
static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap, int devId)
{
int ret = 0;
/* make sure ECC key can be used */
#ifdef WOLFSSL_SMALL_STACK
ecc_key* key;
#else
ecc_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
if (key == NULL)
return MEMORY_E;
#endif
if (wc_ecc_init_ex(key, heap, devId) == 0) {
*idx = 0;
ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret == 0) {
/* check for minimum ECC key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
*keySz = wc_ecc_size(key);
if (*keySz < minKeySz) {
WOLFSSL_MSG("ECC private key too small");
ret = ECC_KEY_SIZE_E;
}
*keyFormat = ECDSAk;
if (ssl) {
ssl->options.haveStaticECC = 1;
ssl->buffers.keyType = ecc_dsa_sa_algo;
ssl->buffers.keySz = *keySz;
}
else {
ctx->haveStaticECC = 1;
ctx->privateKeyType = ecc_dsa_sa_algo;
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
else {
ret = 0; /* continue trying other algorithms */
}
wc_ecc_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ECC);
#endif
return ret;
}
#endif /* HAVE_ECC */
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
static int ProcessBufferTryDecodeEd25519(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap, int devId)
{
int ret;
/* make sure Ed25519 key can be used */
#ifdef WOLFSSL_SMALL_STACK
ed25519_key* key;
#else
ed25519_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
DYNAMIC_TYPE_ED25519);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_ed25519_init_ex(key, heap, devId);
if (ret == 0) {
*idx = 0;
ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
*keySz = ED25519_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("ED25519 private key too small");
ret = ECC_KEY_SIZE_E;
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed25519_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed25519_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED25519k;
if (ssl != NULL) {
/* ED25519 requires caching enabled for tracking message
* hash used in EdDSA_Update for signing */
ssl->options.cacheMessages = 1;
if (ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
}
}
else {
ret = 0; /* continue trying other algorithms */
}
wc_ed25519_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ED25519);
#endif
return ret;
}
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
static int ProcessBufferTryDecodeEd448(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap, int devId)
{
int ret;
/* make sure Ed448 key can be used */
#ifdef WOLFSSL_SMALL_STACK
ed448_key* key = NULL;
#else
ed448_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_ed448_init_ex(key, heap, devId);
if (ret == 0) {
*idx = 0;
ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
*keySz = ED448_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("ED448 private key too small");
ret = ECC_KEY_SIZE_E;
}
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed448_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed448_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED448k;
if (ssl != NULL) {
/* ED448 requires caching enabled for tracking message
* hash used in EdDSA_Update for signing */
ssl->options.cacheMessages = 1;
if (ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
}
wc_ed448_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ED448);
#endif
return ret;
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
#if defined(HAVE_PQC)
#if defined(HAVE_FALCON)
static int ProcessBufferTryDecodeFalcon(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap)
{
int ret;
/* make sure Falcon key can be used */
falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
DYNAMIC_TYPE_FALCON);
if (key == NULL) {
return MEMORY_E;
}
ret = wc_falcon_init(key);
if (ret == 0) {
if (*keyFormat == FALCON_LEVEL1k) {
ret = wc_falcon_set_level(key, 1);
}
else if (*keyFormat == FALCON_LEVEL5k) {
ret = wc_falcon_set_level(key, 5);
}
else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
wc_falcon_free(key);
ret = ALGO_ID_E;
}
}
if (ret == 0) {
*idx = 0;
ret = wc_falcon_import_private_only(der->buffer, der->length, key);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minFalconKeySz :
ctx->minFalconKeySz;
*keySz = FALCON_MAX_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("Falcon private key too small");
ret = FALCON_KEY_SIZE_E;
}
if (ssl) {
if (*keyFormat == FALCON_LEVEL1k) {
ssl->buffers.keyType = falcon_level1_sa_algo;
}
else {
ssl->buffers.keyType = falcon_level5_sa_algo;
}
ssl->buffers.keySz = *keySz;
}
else {
if (*keyFormat == FALCON_LEVEL1k) {
ctx->privateKeyType = falcon_level1_sa_algo;
}
else {
ctx->privateKeyType = falcon_level5_sa_algo;
}
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_falcon_free(key);
}
XFREE(key, heap, DYNAMIC_TYPE_FALCON);
return ret;
}
#endif
#if defined(HAVE_DILITHIUM)
static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap)
{
int ret;
/* make sure Dilithium key can be used */
dilithium_key* key = (dilithium_key*)XMALLOC(sizeof(dilithium_key), heap,
DYNAMIC_TYPE_DILITHIUM);
if (key == NULL) {
return MEMORY_E;
}
ret = wc_dilithium_init(key);
if (ret == 0) {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ret = wc_dilithium_set_level(key, 2);
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ret = wc_dilithium_set_level(key, 3);
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ret = wc_dilithium_set_level(key, 5);
}
else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
wc_dilithium_free(key);
ret = ALGO_ID_E;
}
}
if (ret == 0) {
*idx = 0;
ret = wc_dilithium_import_private_only(der->buffer, der->length, key);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minDilithiumKeySz :
ctx->minDilithiumKeySz;
*keySz = DILITHIUM_MAX_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("Dilithium private key too small");
ret = DILITHIUM_KEY_SIZE_E;
}
if (ssl) {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ssl->buffers.keyType = dilithium_level2_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ssl->buffers.keyType = dilithium_level3_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ssl->buffers.keyType = dilithium_level5_sa_algo;
}
ssl->buffers.keySz = *keySz;
}
else {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ctx->privateKeyType = dilithium_level2_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ctx->privateKeyType = dilithium_level3_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ctx->privateKeyType = dilithium_level5_sa_algo;
}
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_dilithium_free(key);
}
XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
return ret;
}
#endif /* HAVE_DILITHIUM */
#endif /* HAVE_PQC */
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat,
void* heap, int devId)
{
int ret = 0;
@ -6656,294 +7183,38 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
#ifndef NO_RSA
if ((*keyFormat == 0 || *keyFormat == RSAk)) {
/* make sure RSA key can be used */
#ifdef WOLFSSL_SMALL_STACK
RsaKey* key;
#else
RsaKey key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_InitRsaKey_ex(key, heap, devId);
if (ret == 0) {
*idx = 0;
ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret != 0) {
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448) && !defined(HAVE_PQC)
WOLFSSL_MSG("RSA decode failed and other algorithms "
"not enabled to try");
ret = WOLFSSL_BAD_FILE;
#else
ret = 0; /* continue trying other algorithms */
#endif
}
else {
/* check that the size of the RSA key is enough */
int minRsaSz = ssl ? ssl->options.minRsaKeySz :
ctx->minRsaKeySz;
*keySz = wc_RsaEncryptSize((RsaKey*)key);
if (*keySz < minRsaSz) {
ret = RSA_KEY_SIZE_E;
WOLFSSL_MSG("Private Key size too small");
}
if (ssl) {
ssl->buffers.keyType = rsa_sa_algo;
ssl->buffers.keySz = *keySz;
}
else {
ctx->privateKeyType = rsa_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = RSAk;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
ssl->options.haveStaticECC = 0;
*resetSuites = 1;
}
}
wc_FreeRsaKey(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_RSA);
#endif
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2))
ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites,
keyFormat, devId);
#else
ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites,
keyFormat, heap, devId);
#endif
if (ret != 0)
return ret;
}
#endif
#ifdef HAVE_ECC
if ((*keyFormat == 0 || *keyFormat == ECDSAk)) {
/* make sure ECC key can be used */
#ifdef WOLFSSL_SMALL_STACK
ecc_key* key;
#else
ecc_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
if (key == NULL)
return MEMORY_E;
#endif
if (wc_ecc_init_ex(key, heap, devId) == 0) {
*idx = 0;
ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret == 0) {
/* check for minimum ECC key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
ctx->minEccKeySz;
*keySz = wc_ecc_size(key);
if (*keySz < minKeySz) {
WOLFSSL_MSG("ECC private key too small");
ret = ECC_KEY_SIZE_E;
}
*keyFormat = ECDSAk;
if (ssl) {
ssl->options.haveStaticECC = 1;
ssl->buffers.keyType = ecc_dsa_sa_algo;
ssl->buffers.keySz = *keySz;
}
else {
ctx->haveStaticECC = 1;
ctx->privateKeyType = ecc_dsa_sa_algo;
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
else {
ret = 0; /* continue trying other algorithms */
}
wc_ecc_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ECC);
#endif
ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keySz, idx, resetSuites,
keyFormat, heap, devId);
if (ret != 0)
return ret;
}
#endif /* HAVE_ECC */
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
if ((*keyFormat == 0 || *keyFormat == ED25519k)) {
/* make sure Ed25519 key can be used */
#ifdef WOLFSSL_SMALL_STACK
ed25519_key* key;
#else
ed25519_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
DYNAMIC_TYPE_ED25519);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_ed25519_init_ex(key, heap, devId);
if (ret == 0) {
*idx = 0;
ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key,
der->length);
}
#endif
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
ctx->minEccKeySz;
*keySz = ED25519_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("ED25519 private key too small");
ret = ECC_KEY_SIZE_E;
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed25519_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed25519_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED25519k;
if (ssl != NULL) {
/* ED25519 requires caching enabled for tracking message
* hash used in EdDSA_Update for signing */
ssl->options.cacheMessages = 1;
if (ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
}
}
else {
ret = 0; /* continue trying other algorithms */
}
wc_ed25519_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ED25519);
#endif
ret = ProcessBufferTryDecodeEd25519(ctx, ssl, der, keySz, idx,
resetSuites, keyFormat, heap, devId);
if (ret != 0)
return ret;
}
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
if ((*keyFormat == 0 || *keyFormat == ED448k)) {
/* make sure Ed448 key can be used */
#ifdef WOLFSSL_SMALL_STACK
ed448_key* key = NULL;
#else
ed448_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_ed448_init(key);
if (ret == 0) {
*idx = 0;
ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key,
der->length);
}
#endif
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
ctx->minEccKeySz;
*keySz = ED448_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("ED448 private key too small");
ret = ECC_KEY_SIZE_E;
}
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed448_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed448_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED448k;
if (ssl != NULL) {
/* ED448 requires caching enabled for tracking message
* hash used in EdDSA_Update for signing */
ssl->options.cacheMessages = 1;
if (ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
}
wc_ed448_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ED448);
#endif
ret = ProcessBufferTryDecodeEd448(ctx, ssl, der, keySz, idx,
resetSuites, keyFormat, heap, devId);
if (ret != 0)
return ret;
}
@ -6952,66 +7223,8 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
#if defined(HAVE_FALCON)
if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
(*keyFormat == FALCON_LEVEL5k))) {
/* make sure Falcon key can be used */
falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
DYNAMIC_TYPE_FALCON);
if (key == NULL) {
return MEMORY_E;
}
ret = wc_falcon_init(key);
if (ret == 0) {
if (*keyFormat == FALCON_LEVEL1k) {
ret = wc_falcon_set_level(key, 1);
}
else if (*keyFormat == FALCON_LEVEL5k) {
ret = wc_falcon_set_level(key, 5);
}
else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
wc_falcon_free(key);
ret = ALGO_ID_E;
}
}
if (ret == 0) {
*idx = 0;
ret = wc_falcon_import_private_only(der->buffer, der->length, key);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minFalconKeySz :
ctx->minFalconKeySz;
*keySz = FALCON_MAX_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("Falcon private key too small");
ret = FALCON_KEY_SIZE_E;
}
if (ssl) {
if (*keyFormat == FALCON_LEVEL1k) {
ssl->buffers.keyType = falcon_level1_sa_algo;
}
else {
ssl->buffers.keyType = falcon_level5_sa_algo;
}
ssl->buffers.keySz = *keySz;
}
else {
if (*keyFormat == FALCON_LEVEL1k) {
ctx->privateKeyType = falcon_level1_sa_algo;
}
else {
ctx->privateKeyType = falcon_level5_sa_algo;
}
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_falcon_free(key);
}
XFREE(key, heap, DYNAMIC_TYPE_FALCON);
ret = ProcessBufferTryDecodeFalcon(ctx, ssl, der, keySz, idx,
resetSuites, keyFormat, heap);
if (ret != 0)
return ret;
}
@ -7021,77 +7234,8 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
(*keyFormat == DILITHIUM_LEVEL2k) ||
(*keyFormat == DILITHIUM_LEVEL3k) ||
(*keyFormat == DILITHIUM_LEVEL5k)) {
/* make sure Dilithium key can be used */
dilithium_key* key = (dilithium_key*)XMALLOC(sizeof(dilithium_key),
heap,
DYNAMIC_TYPE_DILITHIUM);
if (key == NULL) {
return MEMORY_E;
}
ret = wc_dilithium_init(key);
if (ret == 0) {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ret = wc_dilithium_set_level(key, 2);
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ret = wc_dilithium_set_level(key, 3);
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ret = wc_dilithium_set_level(key, 5);
}
else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
wc_dilithium_free(key);
ret = ALGO_ID_E;
}
}
if (ret == 0) {
*idx = 0;
ret = wc_dilithium_import_private_only(der->buffer, der->length,
key);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minDilithiumKeySz :
ctx->minDilithiumKeySz;
*keySz = DILITHIUM_MAX_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("Dilithium private key too small");
ret = DILITHIUM_KEY_SIZE_E;
}
if (ssl) {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ssl->buffers.keyType = dilithium_level2_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ssl->buffers.keyType = dilithium_level3_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ssl->buffers.keyType = dilithium_level5_sa_algo;
}
ssl->buffers.keySz = *keySz;
}
else {
if (*keyFormat == DILITHIUM_LEVEL2k) {
ctx->privateKeyType = dilithium_level2_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL3k) {
ctx->privateKeyType = dilithium_level3_sa_algo;
}
else if (*keyFormat == DILITHIUM_LEVEL5k) {
ctx->privateKeyType = dilithium_level5_sa_algo;
}
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_dilithium_free(key);
}
XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
ret = ProcessBufferTryDecodeDilithium(ctx, ssl, der, keySz, idx,
resetSuites, keyFormat, heap);
if (ret != 0) {
return ret;
}

View File

@ -3273,8 +3273,6 @@ static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
#ifndef WOLFSSL_ASN_TEMPLATE
#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
|| defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DSA))
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || !defined(NO_DSA)
static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
{
@ -3291,7 +3289,6 @@ static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
return 0;
}
#endif
#endif
#endif /* !WOLFSSL_ASN_TEMPLATE */
#ifdef WOLFSSL_ASN_TEMPLATE
@ -6350,9 +6347,12 @@ enum {
* @param [in] input Buffer holding BER encoded data.
* @param [in, out] inOutIdx On in, start of RSA private key.
* On out, start of ASN.1 item after RSA private key.
* @param [in, out] key RSA key object.
* @param [in, out] key RSA key object. May be NULL.
* @param [out] keySz Size of key in bytes. May be NULL.
* @param [in] inSz Number of bytes in buffer.
* @return 0 on success.
* @return BAD_FUNC_ARG when input or inOutIdx is NULL.
* @return BAD_FUNC_ARG when key and keySz are NULL.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
@ -6361,14 +6361,14 @@ enum {
* @return MP_INIT_E when the unable to initialize an mp_int.
* @return ASN_GETINT_E when the unable to convert data to an mp_int.
*/
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
RsaKey* key, int* keySz, word32 inSz)
{
#ifndef WOLFSSL_ASN_TEMPLATE
int version, length;
word32 algId = 0;
if (inOutIdx == NULL || input == NULL || key == NULL) {
if (inOutIdx == NULL || input == NULL || (key == NULL && keySz == NULL)) {
return BAD_FUNC_ARG;
}
@ -6383,50 +6383,66 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
return ASN_PARSE_E;
key->type = RSA_PRIVATE;
if (key == NULL) {
int i;
#ifdef WOLFSSL_CHECK_MEM_ZERO
mp_memzero_add("Decode RSA key d", &key->d);
mp_memzero_add("Decode RSA key p", &key->p);
mp_memzero_add("Decode RSA key q", &key->q);
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
!defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
mp_memzero_add("Decode RSA key dP", &key->dP);
mp_memzero_add("Decode RSA key dQ", &key->dQ);
mp_memzero_add("Decode RSA key u", &key->u);
#endif
#endif
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
GetInt(&key->q, input, inOutIdx, inSz) < 0
#else
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0
#endif
) {
return ASN_RSA_KEY_E;
}
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
&& !defined(WOLFSSL_RSA_PUBLIC_ONLY)
if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
#else
if (SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
#endif
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
if (wc_InitRsaHw(key) != 0) {
return BAD_STATE_E;
/* Modulus */
if (GetASNInt(input, inOutIdx, keySz, inSz) < 0) {
return ASN_PARSE_E;
}
*inOutIdx += *keySz;
for (i = 1; i < RSA_INTS; i++) {
if (SkipInt(input, inOutIdx, inSz) < 0) {
return ASN_RSA_KEY_E;
}
}
}
else {
key->type = RSA_PRIVATE;
#ifdef WOLFSSL_CHECK_MEM_ZERO
mp_memzero_add("Decode RSA key d", &key->d);
mp_memzero_add("Decode RSA key p", &key->p);
mp_memzero_add("Decode RSA key q", &key->q);
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
!defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
mp_memzero_add("Decode RSA key dP", &key->dP);
mp_memzero_add("Decode RSA key dQ", &key->dQ);
mp_memzero_add("Decode RSA key u", &key->u);
#endif
#endif
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
GetInt(&key->q, input, inOutIdx, inSz) < 0
#else
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0
#endif
) {
return ASN_RSA_KEY_E;
}
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
&& !defined(WOLFSSL_RSA_PUBLIC_ONLY)
if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
#else
if (SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ||
SkipInt(input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
#endif
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
if (wc_InitRsaHw(key) != 0) {
return BAD_STATE_E;
}
#endif
}
#endif
return 0;
#else
@ -6436,12 +6452,20 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
word32 algId = 0;
#endif
void* heap = NULL;
(void)heap;
/* Check validity of parameters. */
if (inOutIdx == NULL || input == NULL || key == NULL) {
if ((inOutIdx == NULL) || (input == NULL) || ((key == NULL) &&
(keySz == NULL))) {
ret = BAD_FUNC_ARG;
}
if ((ret == 0) && (key != NULL)) {
heap = key->heap;
}
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
if (ret == 0) {
/* if has pkcs8 header skip it */
@ -6451,7 +6475,7 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
}
#endif
CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, heap);
if (ret == 0) {
int i;
@ -6459,20 +6483,21 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
/* Setup data to store INTEGER data in mp_int's in RSA object. */
#if defined(WOLFSSL_RSA_PUBLIC_ONLY)
/* Extract all public fields. */
for (i = 0; i < RSA_PUB_INTS; i++) {
GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
}
#define RSA_ASN_INTS RSA_PUB_INTS
/* Not extracting all data from BER encoding. */
#define RSA_ASN_COMPLETE 0
#else
/* Extract all private fields. */
for (i = 0; i < RSA_INTS; i++) {
GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
}
#define RSA_ASN_INTS RSA_INTS
/* Extracting all data from BER encoding. */
#define RSA_ASN_COMPLETE 1
#endif
if (key != NULL) {
/* Extract all public fields. */
for (i = 0; i < RSA_ASN_INTS; i++) {
GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i],
GetRsaInt(key, i));
}
}
/* Parse BER encoding for RSA private key. */
ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
RSA_ASN_COMPLETE, input, inOutIdx, inSz);
@ -6484,7 +6509,7 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
if ((ret == 0) && (version > PKCS1v1)) {
ret = ASN_PARSE_E;
}
if (ret == 0) {
if ((ret == 0) && (key != NULL)) {
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
/* RSA key object has all private key values. */
key->type = RSA_PRIVATE;
@ -6498,11 +6523,78 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
ret = BAD_STATE_E;
#endif
}
else if (ret == 0) {
/* Not filling in key but do want key size. */
*keySz = dataASN[(byte)RSAKEYASN_IDX_N].length;
/* Check whether first byte of data is 0x00 and drop it. */
if (input[dataASN[(byte)RSAKEYASN_IDX_E].offset - *keySz] == 0) {
(*keySz)--;
}
}
FREE_ASNGETDATA(dataASN, key->heap);
FREE_ASNGETDATA(dataASN, heap);
return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */
}
/* Decode RSA private key.
*
* PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
*
* Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
* being extracted.
*
* @param [in] input Buffer holding BER encoded data.
* @param [in, out] inOutIdx On in, start of RSA private key.
* On out, start of ASN.1 item after RSA private key.
* @param [in, out] key RSA key object.
* @param [in] inSz Number of bytes in buffer.
* @return 0 on success.
* @return BAD_FUNC_ARG when input, inOutIdx or key is NULL.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
* @return MP_INIT_E when the unable to initialize an mp_int.
* @return ASN_GETINT_E when the unable to convert data to an mp_int.
*/
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
}
/* Valdidate RSA private key ASN.1 encoding.
*
* PKCS #1: RFC 8017, A.1.2 - RSAPrivateKey
*
* Compiling with WOLFSSL_RSA_PUBLIC_ONLY will result in only the public fields
* being extracted.
*
* @param [in] input Buffer holding BER encoded data.
* @param [in, out] inOutIdx On in, start of RSA private key.
* On out, start of ASN.1 item after RSA private key.
* @param [in] inSz Number of bytes in buffer.
* @return 0 on success.
* @return BAD_FUNC_ARG when input, inOutIdx or keySz is NULL.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
* @return MP_INIT_E when the unable to initialize an mp_int.
* @return ASN_GETINT_E when the unable to convert data to an mp_int.
*/
int wc_RsaPrivateKeyValidate(const byte* input, word32* inOutIdx, int* keySz,
word32 inSz)
{
return _RsaPrivateKeyDecode(input, inOutIdx, NULL, keySz, inSz);
}
#endif /* HAVE_USER_RSA */
#endif /* NO_RSA */
@ -31177,14 +31269,17 @@ static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
/* Allocate a new parameter set. */
curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
DYNAMIC_TYPE_ECC_BUFFER);
if (curve == NULL)
if (curve == NULL) {
ret = MEMORY_E;
}
else {
/* Clear out parameters and set fields to indicate it is custom. */
XMEMSET(curve, 0, sizeof(*curve));
}
CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, key->heap);
if (ret == 0) {
/* Clear out parameters and set fields to indicate it is custom. */
XMEMSET(curve, 0, sizeof(*curve));
/* Set name to be: "Custom" */
#ifndef WOLFSSL_ECC_CURVE_STATIC
curve->name = ecSetCustomName;

File diff suppressed because it is too large Load Diff

View File

@ -764,11 +764,10 @@ static int _ifc_pairwise_consistency_test(RsaKey* key, WC_RNG* rng)
int wc_CheckRsaKey(RsaKey* key)
{
DECL_MP_INT_SIZE_DYN(tmp, mp_bitsused(&key->n), RSA_MAX_SIZE);
#ifdef WOLFSSL_SMALL_STACK
mp_int *tmp = NULL;
WC_RNG *rng = NULL;
#else
mp_int tmp[1];
WC_RNG rng[1];
#endif
int ret = 0;
@ -782,11 +781,14 @@ int wc_CheckRsaKey(RsaKey* key)
#ifdef WOLFSSL_SMALL_STACK
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (rng != NULL)
tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_RSA);
if (rng == NULL || tmp == NULL) {
if (rng == NULL) {
return MEMORY_E;
}
#endif
NEW_MP_INT_SIZE(tmp, mp_bitsused(&key->n), NULL, DYNAMIC_TYPE_RSA);
#ifdef MP_INT_SIZE_CHECK_NULL
if (tmp == NULL) {
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
return MEMORY_E;
}
#endif
@ -797,7 +799,7 @@ int wc_CheckRsaKey(RsaKey* key)
SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
if (ret == 0) {
if (mp_init(tmp) != MP_OKAY)
if (INIT_MP_INT_SIZE(tmp, mp_bitsused(&key->n)) != MP_OKAY)
ret = MP_INIT_E;
}
@ -916,8 +918,8 @@ int wc_CheckRsaKey(RsaKey* key)
RESTORE_VECTOR_REGISTERS();
wc_FreeRng(rng);
FREE_MP_INT_SIZE(tmp, NULL, DYNAMIC_TYPE_RSA);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
mp_memzero_check(tmp);
@ -2471,35 +2473,12 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
}
#else
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
#if !defined(WOLFSSL_SP_MATH)
#ifdef WOLFSSL_SMALL_STACK
mp_int* tmp;
#ifdef WC_RSA_BLINDING
mp_int* rnd;
mp_int* rndi;
#endif
#else
mp_int tmp[1];
#ifdef WC_RSA_BLINDING
mp_int rnd[1], rndi[1];
#endif
#endif
int ret = 0;
#endif
word32 keyLen = wc_RsaEncryptSize(key);
if (inLen > keyLen) {
WOLFSSL_MSG("Expected that inLen be no longer RSA key length");
return BAD_FUNC_ARG;
}
if (mp_iseven(&key->n)) {
return MP_VAL;
}
#ifdef WOLFSSL_HAVE_SP_RSA
static int RsaFunction_SP(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
(void)rng;
#ifndef WOLFSSL_SP_NO_2048
if (mp_count_bits(&key->n) == 2048) {
switch(type) {
@ -2593,61 +2572,184 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
}
}
#endif
#endif /* WOLFSSL_HAVE_SP_RSA */
#if defined(WOLFSSL_SP_MATH)
(void)rng;
#ifndef WOLFSSL_HAVE_SP_RSA
(void)in;
(void)inLen;
(void)out;
(void)outLen;
(void)type;
(void)key;
#error RSA SP option invalid (enable WOLFSSL_HAVE_SP_RSA or disable WOLFSSL_SP_MATH)
return NOT_COMPILED_IN;
#else
WOLFSSL_MSG("SP Key Size Error");
/* SP not able to do operation. */
return WC_KEY_SIZE_E;
#endif
#else
}
#endif
#if !defined(WOLFSSL_SP_MATH)
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
static int RsaFunctionPrivate(mp_int* tmp, RsaKey* key, WC_RNG* rng)
{
int ret = 0;
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
DECL_MP_INT_SIZE_DYN(rnd, mp_bitsused(&key->n), RSA_MAX_SIZE);
DECL_MP_INT_SIZE_DYN(rndi, mp_bitsused(&key->n), RSA_MAX_SIZE);
#endif /* WC_RSA_BLINDING && !WC_NO_RNG */
(void)rng;
#ifdef WOLFSSL_SMALL_STACK
tmp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);
if (tmp == NULL)
return MEMORY_E;
#ifdef WC_RSA_BLINDING
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
rnd = (mp_int*)XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA);
if (rnd == NULL) {
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
NEW_MP_INT_SIZE(rnd, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
NEW_MP_INT_SIZE(rndi, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
#ifdef MP_INT_SIZE_CHECK_NULL
if ((rnd == NULL) || (rndi == NULL)) {
FREE_MP_INT_SIZE(rnd, key->heap, DYNAMIC_TYPE_RSA);
FREE_MP_INT_SIZE(rndi, key->heap, DYNAMIC_TYPE_RSA);
return MEMORY_E;
}
rndi = rnd + 1;
#else
rnd = NULL;
rndi = NULL;
#endif
#endif /* WC_RSA_BLINDING */
#endif /* WOLFSSL_SMALL_STACK */
if (mp_init(tmp) != MP_OKAY)
if ((INIT_MP_INT_SIZE(rnd, mp_bitsused(&key->n)) != MP_OKAY) ||
(INIT_MP_INT_SIZE(rndi, mp_bitsused(&key->n)) != MP_OKAY)) {
ret = MP_INIT_E;
}
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
#ifdef WC_RSA_BLINDING
if (ret == 0) {
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
if (mp_init_multi(rnd, rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
mp_clear(tmp);
ret = MP_INIT_E;
}
/* blind */
ret = mp_rand(rnd, get_digit_count(&key->n), rng);
}
if (ret == 0) {
/* rndi = 1/rnd mod n */
if (mp_invmod(rnd, &key->n, rndi) != MP_OKAY) {
ret = MP_INVMOD_E;
}
}
if (ret == 0) {
#ifdef WOLFSSL_CHECK_MEM_ZERO
mp_memzero_add("RSA Private rnd", rnd);
mp_memzero_add("RSA Private rndi", rndi);
#endif
/* rnd = rnd^e */
#ifndef WOLFSSL_SP_MATH_ALL
if (mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY) {
ret = MP_EXPTMOD_E;
}
#else
if (mp_exptmod_nct(rnd, &key->e, &key->n, rnd) != MP_OKAY) {
ret = MP_EXPTMOD_E;
}
#endif
}
if (ret == 0) {
/* tmp = tmp*rnd mod n */
if (mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY) {
ret = MP_MULMOD_E;
}
}
#endif /* WC_RSA_BLINDING && !WC_NO_RNG */
#ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
if (ret == 0) {
if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) {
ret = MP_EXPTMOD_E;
}
}
#else
if (ret == 0) {
mp_int* tmpa = tmp;
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
mp_int* tmpb = rnd;
#else
DECL_MP_INT_SIZE_DYN(tmpb, mp_bitsused(&key->n), RSA_MAX_SIZE);
#endif
#if !defined(WC_RSA_BLINDING) || defined(WC_NO_RNG)
NEW_MP_INT_SIZE(tmpb, mp_bitsused(&key->n), key->heap,
DYNAMIC_TYPE_RSA);
#ifdef MP_INT_SIZE_CHECK_NULL
if (tmpb == NULL) {
ret = MEMORY_E;
}
#endif
if ((ret == 0) && INIT_MP_INT_SIZE(tmpb, mp_bitsused(&key->n)) !=
MP_OKAY) {
ret = MP_INIT_E;
}
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
if (ret == 0) {
mp_memzero_add("RSA Sync tmpb", tmpb);
}
#endif
/* tmpb = tmp^dQ mod q */
if (ret == 0 && mp_exptmod(tmp, &key->dQ, &key->q, tmpb) != MP_OKAY)
ret = MP_EXPTMOD_E;
/* tmpa = tmp^dP mod p */
if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p, tmpa) != MP_OKAY)
ret = MP_EXPTMOD_E;
/* tmp = (tmp - tmpb) * qInv (mod p) */
#if (defined(WOLFSSL_SP_MATH) || (defined(WOLFSSL_SP_MATH_ALL)) && \
!defined(WOLFSSL_SP_INT_NEGATIVE))
if (ret == 0 && mp_submod(tmpa, tmpb, &key->p, tmp) != MP_OKAY)
ret = MP_SUB_E;
#else
if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY)
ret = MP_SUB_E;
#endif
if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p, tmp) != MP_OKAY)
ret = MP_MULMOD_E;
/* tmp = tmpb + q * tmp */
if (ret == 0 && mp_mul(tmp, &key->q, tmp) != MP_OKAY)
ret = MP_MUL_E;
if (ret == 0 && mp_add(tmp, tmpb, tmp) != MP_OKAY)
ret = MP_ADD_E;
#if !defined(WC_RSA_BLINDING) || defined(WC_NO_RNG)
mp_forcezero(tmpb);
FREE_MP_INT_SIZE(tmpb, key->heap, DYNAMIC_TYPE_RSA);
#if !defined(MP_INT_SIZE_CHECK_NULL) && defined(WOLFSSL_CHECK_MEM_ZERO)
mp_memzero_check(tmpb);
#endif
#endif
}
#endif /* RSA_LOW_MEM */
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
/* unblind */
if (ret == 0 && mp_mulmod(tmp, rndi, &key->n, tmp) != MP_OKAY)
ret = MP_MULMOD_E;
mp_forcezero(rndi);
mp_forcezero(rnd);
FREE_MP_INT_SIZE(rndi, key->heap, DYNAMIC_TYPE_RSA);
FREE_MP_INT_SIZE(rnd, key->heap, DYNAMIC_TYPE_RSA);
#if !defined(MP_INT_SIZE_CHECK_NULL) && defined(WOLFSSL_CHECK_MEM_ZERO)
mp_memzero_check(rnd);
mp_memzero_check(rndi);
#endif
#endif /* WC_RSA_BLINDING && !WC_NO_RNG */
return ret;
}
#endif
static int RsaFunctionSync(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
DECL_MP_INT_SIZE_DYN(tmp, mp_bitsused(&key->n), RSA_MAX_SIZE);
int ret = 0;
(void)rng;
NEW_MP_INT_SIZE(tmp, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
#ifdef MP_INT_SIZE_CHECK_NULL
if (tmp == NULL)
return MEMORY_E;
#endif
if (INIT_MP_INT_SIZE(tmp, mp_bitsused(&key->n)) != MP_OKAY)
ret = MP_INIT_E;
#ifndef TEST_UNPAD_CONSTANT_TIME
if (ret == 0 && mp_read_unsigned_bin(tmp, in, inLen) != MP_OKAY)
ret = MP_READ_E;
@ -2664,144 +2766,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
case RSA_PRIVATE_DECRYPT:
case RSA_PRIVATE_ENCRYPT:
{
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
/* blind */
ret = mp_rand(rnd, get_digit_count(&key->n), rng);
if (ret != 0)
break;
/* rndi = 1/rnd mod n */
if (mp_invmod(rnd, &key->n, rndi) != MP_OKAY) {
ret = MP_INVMOD_E;
break;
}
#ifdef WOLFSSL_CHECK_MEM_ZERO
mp_memzero_add("RSA sync rnd", rnd);
mp_memzero_add("RSA sync rndi", rndi);
#endif
/* rnd = rnd^e */
#ifndef WOLFSSL_SP_MATH_ALL
if (mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY) {
ret = MP_EXPTMOD_E;
break;
}
#else
if (mp_exptmod_nct(rnd, &key->e, &key->n, rnd) != MP_OKAY) {
ret = MP_EXPTMOD_E;
break;
}
#endif
/* tmp = tmp*rnd mod n */
if (mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY) {
ret = MP_MULMOD_E;
break;
}
#endif /* WC_RSA_BLINDING && !WC_NO_RNG */
#ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) {
ret = MP_EXPTMOD_E;
break;
}
#else
{
#ifdef WOLFSSL_SMALL_STACK
mp_int* tmpa;
mp_int* tmpb = NULL;
#else
mp_int tmpa[1], tmpb[1];
#endif
int cleara = 0, clearb = 0;
#ifdef WOLFSSL_SMALL_STACK
tmpa = (mp_int*)XMALLOC(sizeof(mp_int) * 2,
key->heap, DYNAMIC_TYPE_RSA);
if (tmpa != NULL)
tmpb = tmpa + 1;
else
ret = MEMORY_E;
if (ret == 0)
#endif
{
if (mp_init(tmpa) != MP_OKAY)
ret = MP_INIT_E;
else
cleara = 1;
}
if (ret == 0) {
if (mp_init(tmpb) != MP_OKAY)
ret = MP_INIT_E;
else
clearb = 1;
}
#ifdef WOLFSSL_CHECK_MEM_ZERO
if (ret == 0) {
mp_memzero_add("RSA Sync tmpa", tmpa);
mp_memzero_add("RSA Sync tmpb", tmpb);
}
#endif
/* tmpa = tmp^dP mod p */
if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p,
tmpa) != MP_OKAY)
ret = MP_EXPTMOD_E;
/* tmpb = tmp^dQ mod q */
if (ret == 0 && mp_exptmod(tmp, &key->dQ, &key->q,
tmpb) != MP_OKAY)
ret = MP_EXPTMOD_E;
/* tmp = (tmpa - tmpb) * qInv (mod p) */
#if defined(WOLFSSL_SP_MATH) || (defined(WOLFSSL_SP_MATH_ALL) && \
!defined(WOLFSSL_SP_INT_NEGATIVE))
if (ret == 0 && mp_submod(tmpa, tmpb, &key->p, tmp) != MP_OKAY)
ret = MP_SUB_E;
#else
if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY)
ret = MP_SUB_E;
#endif
if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p,
tmp) != MP_OKAY)
ret = MP_MULMOD_E;
/* tmp = tmpb + q * tmp */
if (ret == 0 && mp_mul(tmp, &key->q, tmp) != MP_OKAY)
ret = MP_MUL_E;
if (ret == 0 && mp_add(tmp, tmpb, tmp) != MP_OKAY)
ret = MP_ADD_E;
#ifdef WOLFSSL_SMALL_STACK
if (tmpa != NULL)
#endif
{
if (cleara) {
mp_forcezero(tmpa);
}
if (clearb) {
mp_forcezero(tmpb);
}
#ifdef WOLFSSL_SMALL_STACK
/* tmpb is allocated after tmpa. */
XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
mp_memzero_check(tmpb);
mp_memzero_check(tmpa);
#endif
}
} /* tmpa/b scope */
#endif /* RSA_LOW_MEM */
#ifdef WC_RSA_BLINDING
/* unblind */
if (ret == 0 && mp_mulmod(tmp, rndi, &key->n, tmp) != MP_OKAY)
ret = MP_MULMOD_E;
#endif /* WC_RSA_BLINDING */
ret = RsaFunctionPrivate(tmp, key, rng);
break;
}
#endif
@ -2817,43 +2782,70 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
}
if (ret == 0) {
if (keyLen > *outLen)
ret = RSA_BUFFER_E;
}
if (ret == 0) {
*outLen = keyLen;
if (mp_to_unsigned_bin_len(tmp, out, keyLen) != MP_OKAY)
if (mp_to_unsigned_bin_len(tmp, out, *outLen) != MP_OKAY)
ret = MP_TO_E;
}
#else
(void)type;
(void)key;
XMEMCPY(out, in, inLen);
*outLen = inLen;
#endif
mp_forcezero(tmp);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
FREE_MP_INT_SIZE(tmp, key->heap, DYNAMIC_TYPE_RSA);
#if !defined(MP_INT_SIZE_CHECK_NULL) && defined(WOLFSSL_CHECK_MEM_ZERO)
mp_memzero_check(tmp);
#endif
#ifdef WC_RSA_BLINDING
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
mp_forcezero(rndi);
mp_forcezero(rnd);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA);
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
mp_memzero_check(rnd);
mp_memzero_check(rndi);
}
#endif
#endif /* WC_RSA_BLINDING */
return ret;
}
#endif /* !WOLFSSL_SP_MATH */
static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
{
#ifdef WOLFSSL_HAVE_SP_RSA
int ret;
#endif
word32 keyLen = wc_RsaEncryptSize(key);
if (inLen > keyLen) {
WOLFSSL_MSG("Expected that inLen be no longer RSA key length");
return BAD_FUNC_ARG;
}
if (keyLen > *outLen) {
WOLFSSL_MSG("Expected that outLen be no shorter RSA key length");
return RSA_BUFFER_E;
}
if (mp_iseven(&key->n)) {
return MP_VAL;
}
#ifdef WOLFSSL_HAVE_SP_RSA
ret = RsaFunction_SP(in, inLen, out, outLen, type, key, rng);
if (ret != WC_KEY_SIZE_E)
return ret;
#endif /* WOLFSSL_HAVE_SP_RSA */
#if defined(WOLFSSL_SP_MATH)
(void)rng;
#ifndef WOLFSSL_HAVE_SP_RSA
(void)in;
(void)inLen;
(void)out;
(void)outLen;
(void)type;
(void)key;
#error RSA SP option invalid (enable WOLFSSL_HAVE_SP_RSA or disable WOLFSSL_SP_MATH)
return NOT_COMPILED_IN;
#else
WOLFSSL_MSG("SP Key Size Error");
return WC_KEY_SIZE_E;
#endif
#else
*outLen = keyLen;
return RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
#endif /* WOLFSSL_SP_MATH */
}
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
@ -3129,6 +3121,53 @@ int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,
}
#endif /* WOLFSSL_CRYPTOCELL */
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(TEST_UNPAD_CONSTANT_TIME) && !defined(NO_RSA_BOUNDS_CHECK)
/* Check that 1 < in < n-1. (Requirement of 800-56B.) */
static int RsaFunctionCheckIn(const byte* in, word32 inLen, RsaKey* key,
int checkSmallCt)
{
int ret = 0;
DECL_MP_INT_SIZE_DYN(c, mp_bitsused(&key->n), RSA_MAX_SIZE);
NEW_MP_INT_SIZE(c, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
#ifdef MP_INT_SIZE_CHECK_NULL
if (c == NULL)
ret = MEMORY_E;
#endif
if (ret == 0 && INIT_MP_INT_SIZE(c, mp_bitsused(&key->n)) != MP_OKAY) {
ret = MP_INIT_E;
}
if (ret == 0) {
if (mp_read_unsigned_bin(c, in, inLen) != 0)
ret = MP_READ_E;
}
if (ret == 0) {
/* check c > 1 */
if (checkSmallCt && (mp_cmp_d(c, 1) != MP_GT))
ret = RSA_OUT_OF_RANGE_E;
}
if (ret == 0) {
/* add c+1 */
if (mp_add_d(c, 1, c) != MP_OKAY)
ret = MP_ADD_E;
}
if (ret == 0) {
/* check c+1 < n */
if (mp_cmp(c, &key->n) != MP_LT)
ret = RSA_OUT_OF_RANGE_E;
}
mp_clear(c);
FREE_MP_INT_SIZE(c, key->heap, DYNAMIC_TYPE_RSA);
return ret;
}
#endif /* !WOLFSSL_RSA_VERIFY_ONLY && !TEST_UNPAD_CONSTANT_TIME &&
* !NO_RSA_BOUNDS_CHECK */
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
int checkSmallCt)
@ -3169,47 +3208,7 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
if (type == RSA_PRIVATE_DECRYPT &&
key->state == RSA_STATE_DECRYPT_EXPTMOD) {
/* Check that 1 < in < n-1. (Requirement of 800-56B.) */
#ifdef WOLFSSL_SMALL_STACK
mp_int* c;
#else
mp_int c[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
c = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);
if (c == NULL)
ret = MEMORY_E;
#endif
if (ret == 0 && mp_init(c) != MP_OKAY)
ret = MP_INIT_E;
if (ret == 0) {
if (mp_read_unsigned_bin(c, in, inLen) != 0)
ret = MP_READ_E;
}
if (ret == 0) {
/* check c > 1 */
if (checkSmallCt && (mp_cmp_d(c, 1) != MP_GT))
ret = RSA_OUT_OF_RANGE_E;
}
if (ret == 0) {
/* add c+1 */
if (mp_add_d(c, 1, c) != MP_OKAY)
ret = MP_ADD_E;
}
if (ret == 0) {
/* check c+1 < n */
if (mp_cmp(c, &key->n) != MP_LT)
ret = RSA_OUT_OF_RANGE_E;
}
mp_clear(c);
#ifdef WOLFSSL_SMALL_STACK
if (c != NULL)
XFREE(c, key->heap, DYNAMIC_TYPE_RSA);
#endif
ret = RsaFunctionCheckIn(in, inLen, key, checkSmallCt);
if (ret != 0) {
RESTORE_VECTOR_REGISTERS();
return ret;

View File

@ -34,6 +34,19 @@ This library provides single precision (SP) integer math functions.
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \
defined(WOLFSSL_SP_NO_MALLOC)
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(WOLFSSL_SP_NO_DYN_STACK)
#pragma GCC diagnostic push
/* We are statically declaring a variable smaller than sp_int.
* We track available memory in the 'size' field.
* Disable warnings of sp_int being partly outside array bounds of variable.
*/
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
#endif
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
@ -89,8 +102,9 @@ This library provides single precision (SP) integer math functions.
* WOLFSSL_SP_INT_DIGIT_ALIGN Enable when unaligned access of sp_int_digit
* pointer is not allowed.
* WOLFSSL_SP_NO_DYN_STACK Disable use of dynamic stack items.
* Used with small code size and not small stack.
* Dynamic arrays used when not small stack.
* WOLFSSL_SP_FAST_MODEXP Allow fast mod_exp with small C code
* WOLFSSL_SP_LOW_MEM Use algorithms that use less memory.
*/
/* TODO: WOLFSSL_SP_SMALL is incompatible with clang-12+ -Os. */
@ -109,7 +123,7 @@ This library provides single precision (SP) integer math functions.
sp_int* n = NULL
#else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a variable on the stack with the required data size. */
#define DECL_SP_INT(n, s) \
byte n##d[MP_INT_SIZEOF(s)]; \
@ -187,16 +201,20 @@ This library provides single precision (SP) integer math functions.
#endif
/* Declare a variable that will be assigned a value on XMALLOC. */
#define DECL_DYN_SP_INT_ARRAY(n, s, c) \
sp_int* n##d = NULL; \
sp_int* (n)[c] = { NULL, }
/* DECL_SP_INT_ARRAY: Declare array of 'sp_int'. */
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
!defined(WOLFSSL_SP_NO_MALLOC)
/* Declare a variable that will be assigned a value on XMALLOC. */
#define DECL_SP_INT_ARRAY(n, s, c) \
sp_int* n##d = NULL; \
sp_int* (n)[c] = { NULL, }
DECL_DYN_SP_INT_ARRAY(n, s, c)
#else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a variable on the stack with the required data size. */
#define DECL_SP_INT_ARRAY(n, s, c) \
byte n##d[MP_INT_SIZEOF(s) * (c)]; \
@ -209,38 +227,41 @@ This library provides single precision (SP) integer math functions.
#endif
#endif
/* ALLOC_SP_INT_ARRAY: Allocate an array of 'sp_int's of required size. */
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
!defined(WOLFSSL_SP_NO_MALLOC)
/* Dynamically allocate just enough data to support multiple sp_ints of the
* required size. Use pointers into data to make up array and set sizes.
*/
#define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \
do { \
if (((err) == MP_OKAY) && ((s) > SP_INT_DIGITS)) { \
(err) = MP_VAL; \
} \
if ((err) == MP_OKAY) { \
n##d = (sp_int*)XMALLOC(MP_INT_SIZEOF(s) * (c), (h), \
/* Dynamically allocate just enough data to support multiple sp_ints of the
* required size. Use pointers into data to make up array and set sizes.
*/
#define ALLOC_DYN_SP_INT_ARRAY(n, s, c, err, h) \
do { \
if (((err) == MP_OKAY) && ((s) > SP_INT_DIGITS)) { \
(err) = MP_VAL; \
} \
if ((err) == MP_OKAY) { \
n##d = (sp_int*)XMALLOC(MP_INT_SIZEOF(s) * (c), (h), \
DYNAMIC_TYPE_BIGINT); \
if (n##d == NULL) { \
(err) = MP_MEM; \
} \
else { \
int n##ii; \
(n)[0] = n##d; \
(n)[0]->size = (s); \
for (n##ii = 1; n##ii < (c); n##ii++) { \
(n)[n##ii] = MP_INT_NEXT((n)[n##ii-1], s); \
(n)[n##ii]->size = (s); \
} \
if (n##d == NULL) { \
(err) = MP_MEM; \
} \
else { \
int n##ii; \
(n)[0] = n##d; \
(n)[0]->size = (s); \
for (n##ii = 1; n##ii < (c); n##ii++) { \
(n)[n##ii] = MP_INT_NEXT((n)[n##ii-1], s); \
(n)[n##ii]->size = (s); \
} \
} \
} \
while (0)
} \
while (0)
/* ALLOC_SP_INT_ARRAY: Allocate an array of 'sp_int's of required size. */
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
!defined(WOLFSSL_SP_NO_MALLOC)
#define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \
ALLOC_DYN_SP_INT_ARRAY(n, s, c, err, h)
#else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Data declared on stack that supports multiple sp_ints of the
* required size. Use pointers into data to make up array and set sizes.
*/
@ -281,17 +302,20 @@ This library provides single precision (SP) integer math functions.
#endif
#endif
/* Free data variable that was dynamically allocated. */
#define FREE_DYN_SP_INT_ARRAY(n, h) \
do { \
if (n##d != NULL) { \
XFREE(n##d, h, DYNAMIC_TYPE_BIGINT); \
} \
} \
while (0)
/* FREE_SP_INT_ARRAY: Free an array of 'sp_int'. */
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
!defined(WOLFSSL_SP_NO_MALLOC)
/* Free data variable that was dynamically allocated. */
#define FREE_SP_INT_ARRAY(n, h) \
do { \
if (n##d != NULL) { \
XFREE(n##d, h, DYNAMIC_TYPE_BIGINT); \
} \
} \
while (0)
FREE_DYN_SP_INT_ARRAY(n, h)
#else
/* Nothing to do as data declared on stack. */
#define FREE_SP_INT_ARRAY(n, h)
@ -8256,13 +8280,18 @@ int sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem)
/* Set to temporary when not reusing. */
if (sa == NULL) {
sa = td[i++];
_sp_init_size(sa, a->used + 1);
}
if (tr == NULL) {
tr = td[i];
_sp_init_size(tr, a->used - d->used + 2);
}
#else
sa = td[2];
tr = td[3];
_sp_init_size(sa, a->used + 1);
_sp_init_size(tr, a->used - d->used + 2);
#endif
sd = td[0];
trial = td[1];
@ -8270,18 +8299,6 @@ int sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem)
/* Initialize sizes to minimal values. */
_sp_init_size(sd, d->used + 1);
_sp_init_size(trial, a->used + 1);
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
!defined(WOLFSSL_SP_NO_MALLOC)
if (sa != rem) {
_sp_init_size(sa, a->used + 1);
}
if (tr != r) {
_sp_init_size(tr, a->used - d->used + 2);
}
#else
_sp_init_size(sa, a->used + 1);
_sp_init_size(tr, a->used - d->used + 2);
#endif
/* Move divisor to top of word. Adjust dividend as well. */
s = sp_count_bits(d);
@ -8348,6 +8365,7 @@ int sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem)
(!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \
!defined(WOLFSSL_RSA_PUBLIC_ONLY))
#ifndef FREESCALE_LTC_TFM
#ifdef WOLFSSL_SP_INT_NEGATIVE
/* Calculate the remainder of dividing a by m: r = a mod m.
*
* @param [in] a SP integer to reduce.
@ -8355,31 +8373,14 @@ int sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem)
* @param [out] r SP integer to store result in.
*
* @return MP_OKAY on success.
* @return MP_VAL when a, m or r is NULL or m is 0.
* @return MP_MEM when dynamic memory allocation fails.
*/
int sp_mod(const sp_int* a, const sp_int* m, sp_int* r)
static int _sp_mod(const sp_int* a, const sp_int* m, sp_int* r)
{
int err = MP_OKAY;
#ifdef WOLFSSL_SP_INT_NEGATIVE
/* Remainder will start as a. */
DECL_SP_INT(t, (a == NULL) ? 1 : a->used + 1);
#endif /* WOLFSSL_SP_INT_NEGATIVE */
/* Validate parameters. */
if ((a == NULL) || (m == NULL) || (r == NULL)) {
err = MP_VAL;
}
/* Ensure a isn't too big a number to operate on. */
else if (a->used >= SP_INT_DIGITS) {
err = MP_VAL;
}
#ifndef WOLFSSL_SP_INT_NEGATIVE
if (err == MP_OKAY) {
/* Use divide to calculate remainder and don't get quotient. */
err = sp_div(a, m, NULL, r);
}
#else
/* In case remainder is modulus - allocate temporary. */
ALLOC_SP_INT(t, a->used + 1, err, NULL);
if (err == MP_OKAY) {
@ -8396,8 +8397,50 @@ int sp_mod(const sp_int* a, const sp_int* m, sp_int* r)
err = sp_copy(t, r);
}
}
FREE_SP_INT(t, NULL);
return err;
}
#endif
/* Calculate the remainder of dividing a by m: r = a mod m.
*
* @param [in] a SP integer to reduce.
* @param [in] m SP integer that is the modulus.
* @param [out] r SP integer to store result in.
*
* @return MP_OKAY on success.
* @return MP_VAL when a, m or r is NULL or m is 0.
* @return MP_MEM when dynamic memory allocation fails.
*/
int sp_mod(const sp_int* a, const sp_int* m, sp_int* r)
{
int err = MP_OKAY;
/* Validate parameters. */
if ((a == NULL) || (m == NULL) || (r == NULL)) {
err = MP_VAL;
}
/* Ensure a isn't too big a number to operate on. */
else if (a->used >= SP_INT_DIGITS) {
err = MP_VAL;
}
#ifndef WOLFSSL_SP_INT_NEGATIVE
if (err == MP_OKAY) {
/* Use divide to calculate remainder and don't get quotient. */
err = sp_div(a, m, NULL, r);
}
#else
if ((err == MP_OKAY) && (r != m)) {
err = sp_div(a, m, NULL, r);
if ((!sp_iszero(r)) && (r->sign != m->sign)) {
err = sp_add(r, m, r);
}
}
else if (err == MP_OKAY) {
err = _sp_mod(a, m, r);
}
#endif /* WOLFSSL_SP_INT_NEGATIVE */
return err;
@ -8438,14 +8481,14 @@ static int _sp_mul_nxn(const sp_int* a, const sp_int* b, sp_int* r)
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used * 2];
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used];
#else
sp_int_digit t[SP_INT_DIGITS];
sp_int_digit t[SP_INT_DIGITS / 2];
#endif
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used * 2), NULL,
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * a->used, NULL,
DYNAMIC_TYPE_BIGINT);
if (t == NULL) {
err = MP_MEM;
@ -8480,14 +8523,14 @@ static int _sp_mul_nxn(const sp_int* a, const sp_int* b, sp_int* r)
for (; i < a->used; i++, dp--) {
SP_ASM_MUL_ADD(l, h, o, a->dp[i], dp[0]);
}
t[k] = l;
r->dp[k] = l;
l = h;
h = o;
o = 0;
}
t[k] = l;
r->dp[k] = l;
XMEMCPY(r->dp, t, a->used * sizeof(sp_int_digit));
r->used = k + 1;
XMEMCPY(r->dp, t, r->used * sizeof(sp_int_digit));
sp_clamp(r);
}
@ -8517,7 +8560,7 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used + b->used];
#else
sp_int_digit t[SP_INT_DIGITS];
@ -8595,7 +8638,7 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used + b->used];
#else
sp_int_digit t[SP_INT_DIGITS];
@ -8664,7 +8707,7 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
#ifndef WOLFSSL_SP_SMALL
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 256)
#ifndef SQR_MUL_ASM
/* Multiply a by b and store in r: r = a * b
*
@ -8852,7 +8895,7 @@ static int _sp_mul_4(const sp_int* a, const sp_int* b, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
/* Multiply a by b and store in r: r = a * b
*
@ -8955,7 +8998,7 @@ static int _sp_mul_6(const sp_int* a, const sp_int* b, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
#ifdef SQR_MUL_ASM
/* Multiply a by b and store in r: r = a * b
*
@ -9102,7 +9145,7 @@ static int _sp_mul_8(const sp_int* a, const sp_int* b, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 32 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
/* Multiply a by b and store in r: r = a * b
*
@ -11307,13 +11350,13 @@ int sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
else
#ifndef WOLFSSL_SP_SMALL
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 256)
if ((a->used == 4) && (b->used == 4)) {
err = _sp_mul_4(a, b, r);
}
else
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
if ((a->used == 6) && (b->used == 6)) {
err = _sp_mul_6(a, b, r);
@ -11321,7 +11364,7 @@ int sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
else
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
#ifdef SQR_MUL_ASM
if ((a->used == 8) && (b->used == 8)) {
err = _sp_mul_8(a, b, r);
@ -11329,7 +11372,7 @@ int sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
else
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 32 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
if ((a->used == 12) && (b->used == 12)) {
err = _sp_mul_12(a, b, r);
@ -11415,6 +11458,32 @@ int sp_mul(const sp_int* a, const sp_int* b, sp_int* r)
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \
defined(WOLFCRYPT_HAVE_ECCSI) || \
(!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || defined(OPENSSL_ALL)
static int _sp_mulmod(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r)
{
int err = MP_OKAY;
/* Create temporary for multiplication result. */
DECL_SP_INT(t, a->used + b->used);
ALLOC_SP_INT(t, a->used + b->used, err, NULL);
if (err == MP_OKAY) {
err = sp_init_size(t, a->used + b->used);
}
/* Multiply and reduce. */
if (err == MP_OKAY) {
err = sp_mul(a, b, t);
}
if (err == MP_OKAY) {
err = sp_mod(t, m, r);
}
/* Dispose of an allocated SP int. */
FREE_SP_INT(t, NULL);
return err;
}
/* Multiply a by b mod m and store in r: r = (a * b) mod m
*
* @param [in] a SP integer to multiply.
@ -11459,23 +11528,7 @@ int sp_mulmod(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r)
}
}
else if (err == MP_OKAY) {
/* Create temporary for multiplication result. */
DECL_SP_INT(t, a->used + b->used);
ALLOC_SP_INT(t, a->used + b->used, err, NULL);
if (err == MP_OKAY) {
err = sp_init_size(t, a->used + b->used);
}
/* Multiply and reduce. */
if (err == MP_OKAY) {
err = sp_mul(a, b, t);
}
if (err == MP_OKAY) {
err = sp_mod(t, m, r);
}
/* Dispose of an allocated SP int. */
FREE_SP_INT(t, NULL);
_sp_mulmod(a, b, m, r);
}
#if 0
@ -11581,7 +11634,8 @@ static int _sp_invmod_bin(const sp_int* a, const sp_int* m, sp_int* u,
return err;
}
#if !defined(WOLFSSL_SP_SMALL) && (!defined(NO_RSA) || !defined(NO_DH))
#if !defined(WOLFSSL_SP_LOW_MEM) && !defined(WOLFSSL_SP_SMALL) && \
(!defined(NO_RSA) || !defined(NO_DH))
/* Calculates the multiplicative inverse in the field. r*a = x*m + 1
* Extended Euclidean Algorithm. NOT constant time.
*
@ -11614,20 +11668,17 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
sp_int* y, sp_int* b, sp_int* c, sp_int* inv)
{
int err = MP_OKAY;
sp_int* d = NULL;
sp_int* r = NULL;
sp_int* s;
#ifndef WOLFSSL_SP_INT_NEGATIVE
int bneg = 0;
int cneg = 0;
int neg;
#endif
DECL_SP_INT_ARRAY(t, m->used + 1, 2);
DECL_SP_INT(d, m->used + 1);
ALLOC_SP_INT_ARRAY(t, m->used + 1, 2, err, NULL);
ALLOC_SP_INT(d, m->used + 1, err, NULL);
if (err == MP_OKAY) {
d = t[0];
r = t[1];
mp_init(d);
/* 1. x = m, y = a, b = 1, c = 0 */
_sp_copy(a, y);
@ -11639,7 +11690,7 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
/* 2. while x > 1 */
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
/* 2.1. d = x / y, r = x mod y */
err = sp_div(x, y, d, r);
err = sp_div(x, y, d, x);
if (err == MP_OKAY) {
/* 2.2. c -= d * b */
if (sp_isone(d)) {
@ -11655,7 +11706,7 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
}
}
/* 2.3. x = y, y = r */
s = x; x = y; y = r; r = s;
s = y; y = x; x = s;
/* 2.4. s = b, b = c, c = s */
s = b; b = c; c = s;
}
@ -11676,7 +11727,7 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
/* 2. while x > 1 */
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
/* 2.1. d = x / y, r = x mod y */
err = sp_div(x, y, d, r);
err = sp_div(x, y, d, x);
if (err == MP_OKAY) {
if (sp_isone(d)) {
/* c -= 1 * b */
@ -11715,7 +11766,7 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
}
}
/* 2.3. x = y, y = r */
s = x; x = y; y = r; r = s;
s = y; y = x; x = s;
/* 2.4. s = b, b = c, c = s */
s = b; b = c; c = s;
neg = bneg; bneg = cneg; cneg = neg;
@ -11736,7 +11787,7 @@ static int _sp_invmod_div(const sp_int* a, const sp_int* m, sp_int* x,
}
#endif
FREE_SP_INT_ARRAY(t, NULL);
FREE_SP_INT(d, NULL);
return err;
}
#endif
@ -11810,7 +11861,8 @@ static int _sp_invmod(const sp_int* a, const sp_int* m, sp_int* r)
if (err == MP_OKAY) {
/* Calculate inverse. */
#if !defined(WOLFSSL_SP_SMALL) && (!defined(NO_RSA) || !defined(NO_DH))
#if !defined(WOLFSSL_SP_LOW_MEM) && !defined(WOLFSSL_SP_SMALL) && \
(!defined(NO_RSA) || !defined(NO_DH))
if (sp_count_bits(mm) >= 1024) {
err = _sp_invmod_div(ma, mm, u, v, b, c, c);
}
@ -11975,8 +12027,13 @@ int sp_invmod_mont_ct(const sp_int* a, const sp_int* m, sp_int* r,
int s = 0;
sp_int* t = NULL;
sp_int* e = NULL;
#ifndef WOLFSSL_SP_NO_MALLOC
DECL_DYN_SP_INT_ARRAY(pre, (m == NULL) ? 1 : m->used * 2 + 1,
CT_INV_MOD_PRE_CNT + 2);
#else
DECL_SP_INT_ARRAY(pre, (m == NULL) ? 1 : m->used * 2 + 1,
CT_INV_MOD_PRE_CNT + 2);
#endif
/* Validate parameters. */
if ((a == NULL) || (m == NULL) || (r == NULL)) {
@ -11989,7 +12046,12 @@ int sp_invmod_mont_ct(const sp_int* a, const sp_int* m, sp_int* r,
err = MP_VAL;
}
#ifndef WOLFSSL_SP_NO_MALLOC
ALLOC_DYN_SP_INT_ARRAY(pre, m->used * 2 + 1, CT_INV_MOD_PRE_CNT + 2, err,
NULL);
#else
ALLOC_SP_INT_ARRAY(pre, m->used * 2 + 1, CT_INV_MOD_PRE_CNT + 2, err, NULL);
#endif
if (err == MP_OKAY) {
t = pre[CT_INV_MOD_PRE_CNT + 0];
e = pre[CT_INV_MOD_PRE_CNT + 1];
@ -12118,7 +12180,11 @@ int sp_invmod_mont_ct(const sp_int* a, const sp_int* m, sp_int* r,
}
}
#ifndef WOLFSSL_SP_NO_MALLOC
FREE_DYN_SP_INT_ARRAY(pre, NULL);
#else
FREE_SP_INT_ARRAY(pre, NULL);
#endif
return err;
}
@ -13084,13 +13150,6 @@ int sp_exptmod(const sp_int* b, const sp_int* e, const sp_int* m, sp_int* r)
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH)
#if defined(WOLFSSL_SP_FAST_NCT_EXPTMOD) || !defined(WOLFSSL_SP_SMALL)
/* Always allocate large array of sp_ints unless defined WOLFSSL_SP_NO_MALLOC */
#ifdef SP_ALLOC
#define SP_ALLOC_PREDEFINED
#else
#define SP_ALLOC
#endif
/* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m
* Creates a window of precalculated exponents with base in Montgomery form.
* Sliding window and is NOT constant time.
@ -13141,7 +13200,11 @@ static int _sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
sp_int* bm = NULL;
sp_int_digit mask;
/* Maximum winBits is 6 and preCnt is (1 << (winBits - 1)). */
#ifndef WOLFSSL_SP_NO_MALLOC
DECL_DYN_SP_INT_ARRAY(t, m->used * 2 + 1, (1 << 5) + 2);
#else
DECL_SP_INT_ARRAY(t, m->used * 2 + 1, (1 << 5) + 2);
#endif
bits = sp_count_bits(e);
@ -13175,7 +13238,11 @@ static int _sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
* - temporary result
* - Montgomery form of base
*/
#ifndef WOLFSSL_SP_NO_MALLOC
ALLOC_DYN_SP_INT_ARRAY(t, m->used * 2 + 1, preCnt + 2, err, NULL);
#else
ALLOC_SP_INT_ARRAY(t, m->used * 2 + 1, preCnt + 2, err, NULL);
#endif
if (err == MP_OKAY) {
/* Set variables to use allocate memory. */
tr = t[preCnt + 0];
@ -13393,15 +13460,14 @@ static int _sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
err = sp_copy(tr, r);
}
#ifndef WOLFSSL_SP_NO_MALLOC
FREE_DYN_SP_INT_ARRAY(t, NULL);
#else
FREE_SP_INT_ARRAY(t, NULL);
#endif
return err;
}
#ifndef SP_ALLOC_PREDEFINED
#undef SP_ALLOC
#undef SP_ALLOC_PREDEFINED
#endif
#else
/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m
* Non-constant time implementation.
@ -13796,14 +13862,15 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used * 2];
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[((a->used + 1) / 2) * 2 + 1];
#else
sp_int_digit t[SP_INT_DIGITS];
sp_int_digit t[(SP_INT_DIGITS + 1) / 2];
#endif
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used * 2), NULL,
t = (sp_int_digit*)XMALLOC(
sizeof(sp_int_digit) * (((a->used + 1) / 2) * 2 + 1), NULL,
DYNAMIC_TYPE_BIGINT);
if (t == NULL) {
err = MP_MEM;
@ -13816,13 +13883,14 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
h = 0;
l = 0;
SP_ASM_SQR(h, l, a->dp[0]);
t[0] = h;
t[1] = l;
r->dp[0] = h;
r->dp[1] = l;
}
else if (err == MP_OKAY) {
sp_int_digit l;
sp_int_digit h;
sp_int_digit o;
sp_int_digit* p = t;
h = 0;
l = 0;
@ -13858,7 +13926,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
for (; (i < a->used); i++, j--) {
SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]);
}
t[k * 2 - 1] = l;
p[k * 2 - 1] = l;
l = h;
h = o;
o = 0;
@ -13869,17 +13937,19 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
for (; (i < a->used); i++, j--) {
SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]);
}
t[k * 2] = l;
p[k * 2] = l;
l = h;
h = o;
o = 0;
p = r->dp;
}
t[k * 2 - 1] = l;
r->dp[k * 2 - 1] = l;
XMEMCPY(r->dp, t, (((a->used + 1) / 2) * 2 + 1) * sizeof(sp_int_digit));
}
if (err == MP_OKAY) {
r->used = a->used * 2;
XMEMCPY(r->dp, t, r->used * sizeof(sp_int_digit));
sp_clamp(r);
}
@ -13908,7 +13978,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SP_NO_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used * 2];
#else
sp_int_digit t[SP_INT_DIGITS];
@ -13996,7 +14066,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
#ifndef WOLFSSL_SP_SMALL
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 256)
#ifndef SQR_MUL_ASM
/* Square a and store in r. r = a * a
*
@ -14164,7 +14234,7 @@ static int _sp_sqr_4(const sp_int* a, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
/* Square a and store in r. r = a * a
*
@ -14259,7 +14329,7 @@ static int _sp_sqr_6(const sp_int* a, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
#ifdef SQR_MUL_ASM
/* Square a and store in r. r = a * a
*
@ -14389,7 +14459,7 @@ static int _sp_sqr_8(const sp_int* a, sp_int* r)
}
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 32 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
/* Square a and store in r. r = a * a
*
@ -16106,13 +16176,13 @@ int sp_sqr(const sp_int* a, sp_int* r)
else
#ifndef WOLFSSL_SP_SMALL
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 256)
if (a->used == 4) {
err = _sp_sqr_4(a, r);
}
else
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 64
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
if (a->used == 6) {
err = _sp_sqr_6(a, r);
@ -16120,7 +16190,7 @@ int sp_sqr(const sp_int* a, sp_int* r)
else
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 64 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
#ifdef SQR_MUL_ASM
if (a->used == 8) {
err = _sp_sqr_8(a, r);
@ -16128,7 +16198,7 @@ int sp_sqr(const sp_int* a, sp_int* r)
else
#endif /* SQR_MUL_ASM */
#endif /* SP_WORD_SIZE == 32 */
#if SP_WORD_SIZE == 32
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
#ifdef SQR_MUL_ASM
if (a->used == 12) {
err = _sp_sqr_12(a, r);
@ -18577,5 +18647,12 @@ void sp_memzero_check(sp_int* sp)
}
#endif /* WOLFSSL_CHECK_MEM_ZERO */
#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \
defined(WOLFSSL_SP_NO_MALLOC)
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(WOLFSSL_SP_NO_DYN_STACK)
#pragma GCC diagnostic pop
#endif
#endif
#endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */

View File

@ -1235,9 +1235,11 @@ enum {
#endif
#define MAX_DHKEY_SZ (WOLFSSL_MAX_DHKEY_BITS / 8)
#ifndef NO_DH
#if WOLFSSL_MAX_DHKEY_BITS < WOLFSSL_MIN_DHKEY_BITS
#error "WOLFSSL_MAX_DHKEY_BITS has to be greater than WOLFSSL_MIN_DHKEY_BITS"
#endif
#endif /* NO_DH */
#ifndef MAX_PSK_ID_LEN
/* max psk identity/hint supported */

View File

@ -689,10 +689,17 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
(! ((HAVE_FIPS_VERSION == 5) && (HAVE_FIPS_VERSION_MINOR == 0)))))
WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen);
#endif
#endif
#endif /* !HAVE_USER_RSA */
WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);
WOLFSSL_API int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
int with_header);
/* For FIPS v1/v2 and selftest rsa.h is replaced. */
#if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && \
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION <= 5)))
WOLFSSL_API int wc_RsaPrivateKeyValidate(const byte* input,
word32* inOutIdx, int* keySz, word32 inSz);
#endif
#endif
#ifndef NO_DSA

View File

@ -189,6 +189,26 @@ typedef int mp_err;
BITS_PER_DIGIT*2) */
#define MP_WARRAY ((mp_word)1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
/* No point in dynamically allocating mp_int when it is very small.
* The dp field will grow and shrink dynamically.
*/
/* Declare a statically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \
mp_int name[1]
/* Declare statically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
mp_int name[1]
/* Zero out mp_int of minimal size. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
XMEMSET(name, 0, sizeof(mp_int))
/* Dispose of static mp_int. */
#define FREE_MP_INT_SIZE(name, heap, type)
/* Initialize an mp_int. */
#define INIT_MP_INT_SIZE(name, bits) \
mp_init(name)
/* Type to cast to when using size marcos. */
#define MP_INT_SIZE mp_int
#ifdef HAVE_WOLF_BIGINT
/* raw big integer */
typedef struct WC_BIGINT {
@ -237,6 +257,8 @@ typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
#define mp_isword(a, w) \
((((a)->used == 1) && ((a)->dp[0] == (w))) || (((w) == 0) && ((a)->used == 0)) \
? MP_YES : MP_NO)
/* Number of bits used based on used field only. */
#define mp_bitsused(a) ((a)->used * DIGIT_BIT)
/* number of primes */
#ifdef MP_8BIT

View File

@ -352,6 +352,11 @@ WOLFSSL_API int wc_RsaEncryptSize(const RsaKey* key);
/* to avoid asn duplicate symbols @wc_fips */
WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
RsaKey* key, word32 inSz);
#if !defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))
WOLFSSL_API int wc_RsaPrivateKeyValidate(const byte* input, word32* inOutIdx,
int* keySz, word32 inSz);
#endif
WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
RsaKey* key, word32 inSz);
WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,

View File

@ -1995,6 +1995,9 @@ extern void uITRON4_free(void *p) ;
#undef WOLFSSL_SP_INT_DIGIT_ALIGN
#define WOLFSSL_SP_INT_DIGIT_ALIGN
#endif
#ifdef __APPLE__
#define WOLFSSL_SP_NO_DYN_STACK
#endif
#ifdef __INTEL_COMPILER
#pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */

View File

@ -658,18 +658,21 @@ typedef struct sp_ecc_ctx {
#define sp_setneg(a) ((a)->sign = MP_NEG)
#endif
/* Number of bits used based on used field only. */
#define sp_bitsused(a) ((a)->used * SP_WORD_SIZE)
/* Updates the used count to exclude leading zeros.
*
* Assumes a is not NULL.
*
* @param [in] a SP integer to update.
*/
#define sp_clamp(a) \
do { \
int ii; \
for (ii = (a)->used - 1; ii >= 0 && (a)->dp[ii] == 0; ii--) { \
} \
(a)->used = ii + 1; \
#define sp_clamp(a) \
do { \
int ii; \
for (ii = (a)->used - 1; ii >= 0 && (a)->dp[ii] == 0; ii--) { \
} \
(a)->used = ii + 1; \
} while (0)
/* Check the compiled and linked math implementation are the same.
@ -681,16 +684,6 @@ typedef struct sp_ecc_ctx {
#define CheckFastMathSettings() (SP_WORD_SIZE == CheckRunTimeFastMath())
/* The number of bytes to a sp_int with 'cnt' digits.
* Must have at least one digit.
*/
#define MP_INT_SIZEOF(cnt) \
(sizeof(sp_int) - (SP_INT_DIGITS - (((cnt) == 0) ? 1 : (cnt))) * \
sizeof(sp_int_digit))
/* The address of the next sp_int after one with 'cnt' digits. */
#define MP_INT_NEXT(t, cnt) \
(sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(cnt))
/**
* A result of NO.
* e.g. Is prime? NO.
@ -747,6 +740,86 @@ typedef struct sp_ecc_ctx {
/* Mask of all used bits in word/digit. */
#define MP_MASK SP_MASK
#ifdef MP_LOW_MEM
/* Use algorithms that use less memory. */
#define WOLFSSL_SP_LOW_MEM
#endif
/* The number of bytes to a sp_int with 'cnt' digits.
* Must have at least one digit.
*/
#define MP_INT_SIZEOF(cnt) \
(sizeof(sp_int) - (SP_INT_DIGITS - (((cnt) == 0) ? 1 : (cnt))) * \
sizeof(sp_int_digit))
/* The address of the next sp_int after one with 'cnt' digits. */
#define MP_INT_NEXT(t, cnt) \
(sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(cnt))
/* Calculate the number of words required to support a number of bits. */
#define MP_BITS_CNT(bits) \
(((bits + SP_WORD_SIZE - 1) / SP_WORD_SIZE) * 2 + 1)
#ifdef WOLFSSL_SMALL_STACK
/*
* Dynamic memory allocation of mp_int.
*/
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
sp_int* name = NULL
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \
sp_int* name = NULL
/* Allocate an mp_int of minimal size and zero out. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
do { \
name = (mp_int*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(bits)), heap, type); \
if (name != NULL) { \
XMEMSET(name, 0, MP_INT_SIZEOF(MP_BITS_CNT(bits))); \
} \
} \
while (0)
/* Dispose of dynamically allocated mp_int. */
#define FREE_MP_INT_SIZE(name, heap, type) \
XFREE(name, heap, type)
/* Type to cast to when using size marcos. */
#define MP_INT_SIZE sp_int
/* Must check mp_int pointer for NULL. */
#define MP_INT_SIZE_CHECK_NULL
#else
/*
* Static allocation of mp_int.
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \
sp_int* name = (sp_int*)name##d
#else
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(max))]; \
sp_int* name = (sp_int*)name##d
#endif
/* Declare a statically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \
sp_int* name = (sp_int*)name##d
/* Zero out mp_int of minimal size. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
XMEMSET(name, 0, MP_INT_SIZEOF(MP_BITS_CNT(bits)))
/* Dispose of static mp_int. */
#define FREE_MP_INT_SIZE(name, heap, type)
/* Type to force compiler to not complain about size. */
#define MP_INT_SIZE sp_int_minimal
#endif
/* Initialize an mp_int to a specific size. */
#define INIT_MP_INT_SIZE(name, bits) \
mp_init_size(name, MP_BITS_CNT(bits))
#ifdef HAVE_WOLF_BIGINT
/* Raw big integer as a big-endian byte array.
@ -992,6 +1065,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
#define mp_abs sp_abs
#define mp_isneg sp_isneg
#define mp_setneg sp_setneg
#define mp_bitsused sp_bitsused
#define mp_clamp sp_clamp
/* One to one mappings. */

View File

@ -317,6 +317,55 @@
#define FP_YES 1 /* yes response */
#define FP_NO 0 /* no response */
#ifdef WOLFSSL_SMALL_STACK
/*
* Dynamic memory allocation of mp_int.
*/
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \
mp_int* name = NULL
/* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
mp_int* name = NULL
/* Allocate an mp_int of minimal size and zero out. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
do { \
name = (mp_int*)XMALLOC(sizeof(mp_int), heap, type); \
if (name != NULL) { \
XMEMSET(name, 0, sizeof(mp_int)); \
} \
} \
while (0)
/* Dispose of dynamically allocated mp_int. */
#define FREE_MP_INT_SIZE(name, heap, type) \
XFREE(name, heap, type)
/* Must check for mp_int pointer for NULL. */
#define MP_INT_SIZE_CHECK_NULL
#else
/*
* Static allocation of mp_int.
*/
/* Declare a statically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \
mp_int name[1]
/* Declare a statically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
mp_int name[1]
/* Zero out mp_int of minimal size. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
XMEMSET(name, 0, sizeof(mp_int))
/* Dispose of static mp_int. */
#define FREE_MP_INT_SIZE(name, heap, type)
#endif
/* Initialize an mp_int. */
#define INIT_MP_INT_SIZE(name, bits) \
mp_init(name)
/* Type to cast to when using size marcos. */
#define MP_INT_SIZE mp_int
#ifdef HAVE_WOLF_BIGINT
/* raw big integer */
typedef struct WC_BIGINT {
@ -448,6 +497,8 @@ MP_API void fp_free(fp_int* a);
#define fp_isword(a, w) \
(((((a)->used == 1) && ((a)->dp[0] == (w))) || \
(((w) == 0) && ((a)->used == 0))) ? FP_YES : FP_NO)
/* Number of bits used based on used field only. */
#define fp_bitsused(a) ((a)->used * DIGIT_BIT)
/* set to a small digit */
void fp_set(fp_int *a, fp_digit b);
@ -740,6 +791,7 @@ int fp_sqr_comba64(fp_int *a, fp_int *b);
#define mp_isneg(a) fp_isneg(a)
#define mp_setneg(a) fp_setneg(a)
#define mp_isword(a, w) fp_isword(a, w)
#define mp_bitsused(a) fp_bitsused(a)
#define MP_RADIX_BIN 2
#define MP_RADIX_OCT 8