mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 02:37:28 +02:00
Merge pull request #6262 from SparkiDev/mp_int_mem_usage
SP int: improve use of stack
This commit is contained in:
950
src/ssl.c
950
src/ssl.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
2082
wolfcrypt/src/ecc.c
2082
wolfcrypt/src/ecc.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user