SP int: improve use of stack

Minimize use of stack.
Make very large stack allocations dynamic memory allocations unless
WOLFSSL_SP_NO_MALLOC.

ProcessBufferTryDecode() split up into a function for each type.
ProcessBufferTryDecodeRsa() decodes the data and gets key size rather
than having or allocating an RsaKey.
Added wc_RsaPrivateKeyValidate() that only validates the encoding is an
RSA key and returns the key size in bytes.

For SP int, only create sp_ints of required size in RSA and ECC
implementation. For WOLFSSL_SMALL_STACK, memory is allocated to have
just enough bytes and size is set to maximum supported. Otherwise,
relies on dynamic stack variables.
For ECC, MAX_ECC_BITS_USE used when dynamic stack variables not
supported. Significantly reduces memory usage when RSA/DH is also built.

Add macros to sp_int.h, tfm.h and integer.h to support declaring,
allocating, initializing and freeing mp_ints.
For integer.h, mp_int is always static as size is no more than 32 bytes.
For tfm.h, WOLFSSL_SMALL_STACK has a full mp_int allocated, otherwise
the full mp_int is put on the stack.
For sp_int.h  with new macros, dynamically allocate sp_int to minimal
size when WOLFSSL_SMALL_STACK, or when dynamic stack variables, declare
them to be of minimal size or otherwise declare with a fixed max.
Added mp_bitsused(), for all implementations, to get the number of bits
available based on used. Included for RSA to get the size of the
modulus.

SP int now always uses dynamic stack variables if possible rather than
for builds with WOLFSSL_SP_SMALL.
Moved code out into separate functions so that stack allocations don't
happen when not going down code path.
This commit is contained in:
Sean Parkinson
2023-03-24 15:02:15 +10:00
parent b8e61a241b
commit 8065139050
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 */
@@ -31167,14 +31259,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

@@ -1939,6 +1939,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