mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 11:44:38 +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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
|
#ifndef NO_RSA
|
||||||
int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
|
#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;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -6656,294 +7183,38 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
|
|||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
if ((*keyFormat == 0 || *keyFormat == RSAk)) {
|
if ((*keyFormat == 0 || *keyFormat == RSAk)) {
|
||||||
/* make sure RSA key can be used */
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
(HAVE_FIPS_VERSION > 2))
|
||||||
RsaKey* key;
|
ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites,
|
||||||
#else
|
keyFormat, devId);
|
||||||
RsaKey key[1];
|
#else
|
||||||
#endif
|
ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites,
|
||||||
|
keyFormat, heap, devId);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#endif
|
||||||
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 (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
if ((*keyFormat == 0 || *keyFormat == ECDSAk)) {
|
if ((*keyFormat == 0 || *keyFormat == ECDSAk)) {
|
||||||
/* make sure ECC key can be used */
|
ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keySz, idx, resetSuites,
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
keyFormat, heap, devId);
|
||||||
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
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
|
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
|
||||||
if ((*keyFormat == 0 || *keyFormat == ED25519k)) {
|
if ((*keyFormat == 0 || *keyFormat == ED25519k)) {
|
||||||
/* make sure Ed25519 key can be used */
|
ret = ProcessBufferTryDecodeEd25519(ctx, ssl, der, keySz, idx,
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
resetSuites, keyFormat, heap, devId);
|
||||||
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
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
|
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
|
||||||
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
|
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
|
||||||
if ((*keyFormat == 0 || *keyFormat == ED448k)) {
|
if ((*keyFormat == 0 || *keyFormat == ED448k)) {
|
||||||
/* make sure Ed448 key can be used */
|
ret = ProcessBufferTryDecodeEd448(ctx, ssl, der, keySz, idx,
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
resetSuites, keyFormat, heap, devId);
|
||||||
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
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -6952,66 +7223,8 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
|
|||||||
#if defined(HAVE_FALCON)
|
#if defined(HAVE_FALCON)
|
||||||
if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
|
if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
|
||||||
(*keyFormat == FALCON_LEVEL5k))) {
|
(*keyFormat == FALCON_LEVEL5k))) {
|
||||||
/* make sure Falcon key can be used */
|
ret = ProcessBufferTryDecodeFalcon(ctx, ssl, der, keySz, idx,
|
||||||
falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
|
resetSuites, keyFormat, 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);
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -7021,77 +7234,8 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
|
|||||||
(*keyFormat == DILITHIUM_LEVEL2k) ||
|
(*keyFormat == DILITHIUM_LEVEL2k) ||
|
||||||
(*keyFormat == DILITHIUM_LEVEL3k) ||
|
(*keyFormat == DILITHIUM_LEVEL3k) ||
|
||||||
(*keyFormat == DILITHIUM_LEVEL5k)) {
|
(*keyFormat == DILITHIUM_LEVEL5k)) {
|
||||||
/* make sure Dilithium key can be used */
|
ret = ProcessBufferTryDecodeDilithium(ctx, ssl, der, keySz, idx,
|
||||||
dilithium_key* key = (dilithium_key*)XMALLOC(sizeof(dilithium_key),
|
resetSuites, keyFormat, heap);
|
||||||
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);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -3273,8 +3273,6 @@ static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
|
|||||||
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
|
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
|
||||||
|
|
||||||
#ifndef 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)
|
#if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || !defined(NO_DSA)
|
||||||
static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#endif /* !WOLFSSL_ASN_TEMPLATE */
|
#endif /* !WOLFSSL_ASN_TEMPLATE */
|
||||||
|
|
||||||
#ifdef WOLFSSL_ASN_TEMPLATE
|
#ifdef WOLFSSL_ASN_TEMPLATE
|
||||||
@@ -6350,9 +6347,12 @@ enum {
|
|||||||
* @param [in] input Buffer holding BER encoded data.
|
* @param [in] input Buffer holding BER encoded data.
|
||||||
* @param [in, out] inOutIdx On in, start of RSA private key.
|
* @param [in, out] inOutIdx On in, start of RSA private key.
|
||||||
* On out, start of ASN.1 item after 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.
|
* @param [in] inSz Number of bytes in buffer.
|
||||||
* @return 0 on success.
|
* @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
|
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
|
||||||
* is invalid.
|
* is invalid.
|
||||||
* @return BUFFER_E when data in buffer is too small.
|
* @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 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.
|
* @return ASN_GETINT_E when the unable to convert data to an mp_int.
|
||||||
*/
|
*/
|
||||||
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||||
word32 inSz)
|
RsaKey* key, int* keySz, word32 inSz)
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||||
int version, length;
|
int version, length;
|
||||||
word32 algId = 0;
|
word32 algId = 0;
|
||||||
|
|
||||||
if (inOutIdx == NULL || input == NULL || key == NULL) {
|
if (inOutIdx == NULL || input == NULL || (key == NULL && keySz == NULL)) {
|
||||||
return BAD_FUNC_ARG;
|
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)
|
if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
key->type = RSA_PRIVATE;
|
if (key == NULL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
/* Modulus */
|
||||||
mp_memzero_add("Decode RSA key d", &key->d);
|
if (GetASNInt(input, inOutIdx, keySz, inSz) < 0) {
|
||||||
mp_memzero_add("Decode RSA key p", &key->p);
|
return ASN_PARSE_E;
|
||||||
mp_memzero_add("Decode RSA key q", &key->q);
|
}
|
||||||
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
|
*inOutIdx += *keySz;
|
||||||
!defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
for (i = 1; i < RSA_INTS; i++) {
|
||||||
mp_memzero_add("Decode RSA key dP", &key->dP);
|
if (SkipInt(input, inOutIdx, inSz) < 0) {
|
||||||
mp_memzero_add("Decode RSA key dQ", &key->dQ);
|
return ASN_RSA_KEY_E;
|
||||||
mp_memzero_add("Decode RSA key u", &key->u);
|
}
|
||||||
#endif
|
}
|
||||||
#endif
|
}
|
||||||
|
else {
|
||||||
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
|
key->type = RSA_PRIVATE;
|
||||||
GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
|
|
||||||
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
|
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||||
GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
|
mp_memzero_add("Decode RSA key d", &key->d);
|
||||||
GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
|
mp_memzero_add("Decode RSA key p", &key->p);
|
||||||
GetInt(&key->q, input, inOutIdx, inSz) < 0
|
mp_memzero_add("Decode RSA key q", &key->q);
|
||||||
#else
|
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
|
||||||
SkipInt(input, inOutIdx, inSz) < 0 ||
|
!defined(RSA_LOW_MEM)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
||||||
SkipInt(input, inOutIdx, inSz) < 0 ||
|
mp_memzero_add("Decode RSA key dP", &key->dP);
|
||||||
SkipInt(input, inOutIdx, inSz) < 0
|
mp_memzero_add("Decode RSA key dQ", &key->dQ);
|
||||||
#endif
|
mp_memzero_add("Decode RSA key u", &key->u);
|
||||||
) {
|
#endif
|
||||||
return ASN_RSA_KEY_E;
|
#endif
|
||||||
}
|
|
||||||
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)) \
|
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
|
||||||
&& !defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
|
||||||
if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
|
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
|
||||||
GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
|
GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
|
||||||
GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
|
GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
|
||||||
#else
|
GetInt(&key->q, input, inOutIdx, inSz) < 0
|
||||||
if (SkipInt(input, inOutIdx, inSz) < 0 ||
|
#else
|
||||||
SkipInt(input, inOutIdx, inSz) < 0 ||
|
SkipInt(input, inOutIdx, inSz) < 0 ||
|
||||||
SkipInt(input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
|
SkipInt(input, inOutIdx, inSz) < 0 ||
|
||||||
#endif
|
SkipInt(input, inOutIdx, inSz) < 0
|
||||||
|
#endif
|
||||||
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL)
|
) {
|
||||||
if (wc_InitRsaHw(key) != 0) {
|
return ASN_RSA_KEY_E;
|
||||||
return BAD_STATE_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;
|
return 0;
|
||||||
#else
|
#else
|
||||||
@@ -6436,12 +6452,20 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||||||
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
|
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
|
||||||
word32 algId = 0;
|
word32 algId = 0;
|
||||||
#endif
|
#endif
|
||||||
|
void* heap = NULL;
|
||||||
|
|
||||||
|
(void)heap;
|
||||||
|
|
||||||
/* Check validity of parameters. */
|
/* Check validity of parameters. */
|
||||||
if (inOutIdx == NULL || input == NULL || key == NULL) {
|
if ((inOutIdx == NULL) || (input == NULL) || ((key == NULL) &&
|
||||||
|
(keySz == NULL))) {
|
||||||
ret = BAD_FUNC_ARG;
|
ret = BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret == 0) && (key != NULL)) {
|
||||||
|
heap = key->heap;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
|
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* if has pkcs8 header skip it */
|
/* if has pkcs8 header skip it */
|
||||||
@@ -6451,7 +6475,7 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, key->heap);
|
CALLOC_ASNGETDATA(dataASN, rsaKeyASN_Length, ret, heap);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int i;
|
int i;
|
||||||
@@ -6459,20 +6483,21 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||||||
GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
|
GetASN_Int8Bit(&dataASN[RSAKEYASN_IDX_VER], &version);
|
||||||
/* Setup data to store INTEGER data in mp_int's in RSA object. */
|
/* Setup data to store INTEGER data in mp_int's in RSA object. */
|
||||||
#if defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
#if defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
||||||
/* Extract all public fields. */
|
#define RSA_ASN_INTS RSA_PUB_INTS
|
||||||
for (i = 0; i < RSA_PUB_INTS; i++) {
|
|
||||||
GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
|
|
||||||
}
|
|
||||||
/* Not extracting all data from BER encoding. */
|
/* Not extracting all data from BER encoding. */
|
||||||
#define RSA_ASN_COMPLETE 0
|
#define RSA_ASN_COMPLETE 0
|
||||||
#else
|
#else
|
||||||
/* Extract all private fields. */
|
#define RSA_ASN_INTS RSA_INTS
|
||||||
for (i = 0; i < RSA_INTS; i++) {
|
|
||||||
GetASN_MP(&dataASN[(byte)RSAKEYASN_IDX_N + i], GetRsaInt(key, i));
|
|
||||||
}
|
|
||||||
/* Extracting all data from BER encoding. */
|
/* Extracting all data from BER encoding. */
|
||||||
#define RSA_ASN_COMPLETE 1
|
#define RSA_ASN_COMPLETE 1
|
||||||
#endif
|
#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. */
|
/* Parse BER encoding for RSA private key. */
|
||||||
ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
|
ret = GetASN_Items(rsaKeyASN, dataASN, rsaKeyASN_Length,
|
||||||
RSA_ASN_COMPLETE, input, inOutIdx, inSz);
|
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)) {
|
if ((ret == 0) && (version > PKCS1v1)) {
|
||||||
ret = ASN_PARSE_E;
|
ret = ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if ((ret == 0) && (key != NULL)) {
|
||||||
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY)
|
||||||
/* RSA key object has all private key values. */
|
/* RSA key object has all private key values. */
|
||||||
key->type = RSA_PRIVATE;
|
key->type = RSA_PRIVATE;
|
||||||
@@ -6498,11 +6523,78 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||||||
ret = BAD_STATE_E;
|
ret = BAD_STATE_E;
|
||||||
#endif
|
#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;
|
return ret;
|
||||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
#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 /* HAVE_USER_RSA */
|
||||||
#endif /* NO_RSA */
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
@@ -31177,14 +31269,17 @@ static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz,
|
|||||||
/* Allocate a new parameter set. */
|
/* Allocate a new parameter set. */
|
||||||
curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
|
curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
|
||||||
DYNAMIC_TYPE_ECC_BUFFER);
|
DYNAMIC_TYPE_ECC_BUFFER);
|
||||||
if (curve == NULL)
|
if (curve == NULL) {
|
||||||
ret = MEMORY_E;
|
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);
|
CALLOC_ASNGETDATA(dataASN, eccSpecifiedASN_Length, ret, key->heap);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Clear out parameters and set fields to indicate it is custom. */
|
|
||||||
XMEMSET(curve, 0, sizeof(*curve));
|
|
||||||
/* Set name to be: "Custom" */
|
/* Set name to be: "Custom" */
|
||||||
#ifndef WOLFSSL_ECC_CURVE_STATIC
|
#ifndef WOLFSSL_ECC_CURVE_STATIC
|
||||||
curve->name = ecSetCustomName;
|
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)
|
int wc_CheckRsaKey(RsaKey* key)
|
||||||
{
|
{
|
||||||
|
DECL_MP_INT_SIZE_DYN(tmp, mp_bitsused(&key->n), RSA_MAX_SIZE);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
mp_int *tmp = NULL;
|
|
||||||
WC_RNG *rng = NULL;
|
WC_RNG *rng = NULL;
|
||||||
#else
|
#else
|
||||||
mp_int tmp[1];
|
|
||||||
WC_RNG rng[1];
|
WC_RNG rng[1];
|
||||||
#endif
|
#endif
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -782,11 +781,14 @@ int wc_CheckRsaKey(RsaKey* key)
|
|||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
|
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
|
||||||
if (rng != NULL)
|
if (rng == NULL) {
|
||||||
tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_RSA);
|
return MEMORY_E;
|
||||||
if (rng == NULL || tmp == NULL) {
|
}
|
||||||
|
#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(rng, NULL, DYNAMIC_TYPE_RNG);
|
||||||
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -797,7 +799,7 @@ int wc_CheckRsaKey(RsaKey* key)
|
|||||||
SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
|
SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
|
||||||
|
|
||||||
if (ret == 0) {
|
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;
|
ret = MP_INIT_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -916,8 +918,8 @@ int wc_CheckRsaKey(RsaKey* key)
|
|||||||
RESTORE_VECTOR_REGISTERS();
|
RESTORE_VECTOR_REGISTERS();
|
||||||
|
|
||||||
wc_FreeRng(rng);
|
wc_FreeRng(rng);
|
||||||
|
FREE_MP_INT_SIZE(tmp, NULL, DYNAMIC_TYPE_RSA);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(tmp, NULL, DYNAMIC_TYPE_RSA);
|
|
||||||
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
|
XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
|
||||||
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
|
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
|
||||||
mp_memzero_check(tmp);
|
mp_memzero_check(tmp);
|
||||||
@@ -2471,35 +2473,12 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
|
#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
|
#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
|
#ifndef WOLFSSL_SP_NO_2048
|
||||||
if (mp_count_bits(&key->n) == 2048) {
|
if (mp_count_bits(&key->n) == 2048) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@@ -2593,61 +2572,184 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* WOLFSSL_HAVE_SP_RSA */
|
|
||||||
|
|
||||||
#if defined(WOLFSSL_SP_MATH)
|
/* SP not able to do operation. */
|
||||||
(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;
|
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;
|
(void)rng;
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
|
||||||
tmp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA);
|
NEW_MP_INT_SIZE(rnd, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
|
||||||
if (tmp == NULL)
|
NEW_MP_INT_SIZE(rndi, mp_bitsused(&key->n), key->heap, DYNAMIC_TYPE_RSA);
|
||||||
return MEMORY_E;
|
#ifdef MP_INT_SIZE_CHECK_NULL
|
||||||
#ifdef WC_RSA_BLINDING
|
if ((rnd == NULL) || (rndi == NULL)) {
|
||||||
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
|
FREE_MP_INT_SIZE(rnd, key->heap, DYNAMIC_TYPE_RSA);
|
||||||
rnd = (mp_int*)XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA);
|
FREE_MP_INT_SIZE(rndi, key->heap, DYNAMIC_TYPE_RSA);
|
||||||
if (rnd == NULL) {
|
|
||||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
rndi = rnd + 1;
|
|
||||||
#else
|
|
||||||
rnd = NULL;
|
|
||||||
rndi = NULL;
|
|
||||||
#endif
|
#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;
|
ret = MP_INIT_E;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
|
|
||||||
#ifdef WC_RSA_BLINDING
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
|
/* blind */
|
||||||
if (mp_init_multi(rnd, rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
|
ret = mp_rand(rnd, get_digit_count(&key->n), rng);
|
||||||
mp_clear(tmp);
|
}
|
||||||
ret = MP_INIT_E;
|
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
|
#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
|
#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
|
#ifndef TEST_UNPAD_CONSTANT_TIME
|
||||||
if (ret == 0 && mp_read_unsigned_bin(tmp, in, inLen) != MP_OKAY)
|
if (ret == 0 && mp_read_unsigned_bin(tmp, in, inLen) != MP_OKAY)
|
||||||
ret = MP_READ_E;
|
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_DECRYPT:
|
||||||
case RSA_PRIVATE_ENCRYPT:
|
case RSA_PRIVATE_ENCRYPT:
|
||||||
{
|
{
|
||||||
#if defined(WC_RSA_BLINDING) && !defined(WC_NO_RNG)
|
ret = RsaFunctionPrivate(tmp, key, 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 */
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2817,43 +2782,70 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (keyLen > *outLen)
|
if (mp_to_unsigned_bin_len(tmp, out, *outLen) != MP_OKAY)
|
||||||
ret = RSA_BUFFER_E;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
*outLen = keyLen;
|
|
||||||
if (mp_to_unsigned_bin_len(tmp, out, keyLen) != MP_OKAY)
|
|
||||||
ret = MP_TO_E;
|
ret = MP_TO_E;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)type;
|
(void)type;
|
||||||
(void)key;
|
(void)key;
|
||||||
XMEMCPY(out, in, inLen);
|
XMEMCPY(out, in, inLen);
|
||||||
*outLen = inLen;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mp_forcezero(tmp);
|
mp_forcezero(tmp);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
FREE_MP_INT_SIZE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
||||||
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
|
#if !defined(MP_INT_SIZE_CHECK_NULL) && defined(WOLFSSL_CHECK_MEM_ZERO)
|
||||||
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
|
|
||||||
mp_memzero_check(tmp);
|
mp_memzero_check(tmp);
|
||||||
#endif
|
#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;
|
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 /* WOLFSSL_SP_MATH */
|
||||||
}
|
}
|
||||||
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
|
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
|
||||||
@@ -3129,6 +3121,53 @@ int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSSL_CRYPTOCELL */
|
#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,
|
static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
|
||||||
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
|
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
|
||||||
int checkSmallCt)
|
int checkSmallCt)
|
||||||
@@ -3169,47 +3208,7 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
|
|||||||
if (type == RSA_PRIVATE_DECRYPT &&
|
if (type == RSA_PRIVATE_DECRYPT &&
|
||||||
key->state == RSA_STATE_DECRYPT_EXPTMOD) {
|
key->state == RSA_STATE_DECRYPT_EXPTMOD) {
|
||||||
|
|
||||||
/* Check that 1 < in < n-1. (Requirement of 800-56B.) */
|
ret = RsaFunctionCheckIn(in, inLen, key, checkSmallCt);
|
||||||
#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
|
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
RESTORE_VECTOR_REGISTERS();
|
RESTORE_VECTOR_REGISTERS();
|
||||||
return ret;
|
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_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
|
#ifdef NO_INLINE
|
||||||
#include <wolfssl/wolfcrypt/misc.h>
|
#include <wolfssl/wolfcrypt/misc.h>
|
||||||
#else
|
#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
|
* WOLFSSL_SP_INT_DIGIT_ALIGN Enable when unaligned access of sp_int_digit
|
||||||
* pointer is not allowed.
|
* pointer is not allowed.
|
||||||
* WOLFSSL_SP_NO_DYN_STACK Disable use of dynamic stack items.
|
* 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_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. */
|
/* 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
|
sp_int* n = NULL
|
||||||
#else
|
#else
|
||||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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. */
|
/* Declare a variable on the stack with the required data size. */
|
||||||
#define DECL_SP_INT(n, s) \
|
#define DECL_SP_INT(n, s) \
|
||||||
byte n##d[MP_INT_SIZEOF(s)]; \
|
byte n##d[MP_INT_SIZEOF(s)]; \
|
||||||
@@ -187,16 +201,20 @@ This library provides single precision (SP) integer math functions.
|
|||||||
#endif
|
#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'. */
|
/* DECL_SP_INT_ARRAY: Declare array of 'sp_int'. */
|
||||||
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
|
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
|
||||||
!defined(WOLFSSL_SP_NO_MALLOC)
|
!defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
/* Declare a variable that will be assigned a value on XMALLOC. */
|
/* Declare a variable that will be assigned a value on XMALLOC. */
|
||||||
#define DECL_SP_INT_ARRAY(n, s, c) \
|
#define DECL_SP_INT_ARRAY(n, s, c) \
|
||||||
sp_int* n##d = NULL; \
|
DECL_DYN_SP_INT_ARRAY(n, s, c)
|
||||||
sp_int* (n)[c] = { NULL, }
|
|
||||||
#else
|
#else
|
||||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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. */
|
/* Declare a variable on the stack with the required data size. */
|
||||||
#define DECL_SP_INT_ARRAY(n, s, c) \
|
#define DECL_SP_INT_ARRAY(n, s, c) \
|
||||||
byte n##d[MP_INT_SIZEOF(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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ALLOC_SP_INT_ARRAY: Allocate an array of 'sp_int's of required size. */
|
/* Dynamically allocate just enough data to support multiple sp_ints of the
|
||||||
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
|
* required size. Use pointers into data to make up array and set sizes.
|
||||||
!defined(WOLFSSL_SP_NO_MALLOC)
|
*/
|
||||||
/* Dynamically allocate just enough data to support multiple sp_ints of the
|
#define ALLOC_DYN_SP_INT_ARRAY(n, s, c, err, h) \
|
||||||
* required size. Use pointers into data to make up array and set sizes.
|
do { \
|
||||||
*/
|
if (((err) == MP_OKAY) && ((s) > SP_INT_DIGITS)) { \
|
||||||
#define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \
|
(err) = MP_VAL; \
|
||||||
do { \
|
} \
|
||||||
if (((err) == MP_OKAY) && ((s) > SP_INT_DIGITS)) { \
|
if ((err) == MP_OKAY) { \
|
||||||
(err) = MP_VAL; \
|
n##d = (sp_int*)XMALLOC(MP_INT_SIZEOF(s) * (c), (h), \
|
||||||
} \
|
|
||||||
if ((err) == MP_OKAY) { \
|
|
||||||
n##d = (sp_int*)XMALLOC(MP_INT_SIZEOF(s) * (c), (h), \
|
|
||||||
DYNAMIC_TYPE_BIGINT); \
|
DYNAMIC_TYPE_BIGINT); \
|
||||||
if (n##d == NULL) { \
|
if (n##d == NULL) { \
|
||||||
(err) = MP_MEM; \
|
(err) = MP_MEM; \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
int n##ii; \
|
int n##ii; \
|
||||||
(n)[0] = n##d; \
|
(n)[0] = n##d; \
|
||||||
(n)[0]->size = (s); \
|
(n)[0]->size = (s); \
|
||||||
for (n##ii = 1; n##ii < (c); n##ii++) { \
|
for (n##ii = 1; n##ii < (c); n##ii++) { \
|
||||||
(n)[n##ii] = MP_INT_NEXT((n)[n##ii-1], s); \
|
(n)[n##ii] = MP_INT_NEXT((n)[n##ii-1], s); \
|
||||||
(n)[n##ii]->size = (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
|
#else
|
||||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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
|
/* Data declared on stack that supports multiple sp_ints of the
|
||||||
* required size. Use pointers into data to make up array and set sizes.
|
* 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
|
||||||
#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'. */
|
/* FREE_SP_INT_ARRAY: Free an array of 'sp_int'. */
|
||||||
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
|
#if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \
|
||||||
!defined(WOLFSSL_SP_NO_MALLOC)
|
!defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
/* Free data variable that was dynamically allocated. */
|
|
||||||
#define FREE_SP_INT_ARRAY(n, h) \
|
#define FREE_SP_INT_ARRAY(n, h) \
|
||||||
do { \
|
FREE_DYN_SP_INT_ARRAY(n, h)
|
||||||
if (n##d != NULL) { \
|
|
||||||
XFREE(n##d, h, DYNAMIC_TYPE_BIGINT); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
#else
|
#else
|
||||||
/* Nothing to do as data declared on stack. */
|
/* Nothing to do as data declared on stack. */
|
||||||
#define FREE_SP_INT_ARRAY(n, h)
|
#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. */
|
/* Set to temporary when not reusing. */
|
||||||
if (sa == NULL) {
|
if (sa == NULL) {
|
||||||
sa = td[i++];
|
sa = td[i++];
|
||||||
|
_sp_init_size(sa, a->used + 1);
|
||||||
}
|
}
|
||||||
if (tr == NULL) {
|
if (tr == NULL) {
|
||||||
tr = td[i];
|
tr = td[i];
|
||||||
|
_sp_init_size(tr, a->used - d->used + 2);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
sa = td[2];
|
sa = td[2];
|
||||||
tr = td[3];
|
tr = td[3];
|
||||||
|
|
||||||
|
_sp_init_size(sa, a->used + 1);
|
||||||
|
_sp_init_size(tr, a->used - d->used + 2);
|
||||||
#endif
|
#endif
|
||||||
sd = td[0];
|
sd = td[0];
|
||||||
trial = td[1];
|
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. */
|
/* Initialize sizes to minimal values. */
|
||||||
_sp_init_size(sd, d->used + 1);
|
_sp_init_size(sd, d->used + 1);
|
||||||
_sp_init_size(trial, a->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. */
|
/* Move divisor to top of word. Adjust dividend as well. */
|
||||||
s = sp_count_bits(d);
|
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(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \
|
||||||
!defined(WOLFSSL_RSA_PUBLIC_ONLY))
|
!defined(WOLFSSL_RSA_PUBLIC_ONLY))
|
||||||
#ifndef FREESCALE_LTC_TFM
|
#ifndef FREESCALE_LTC_TFM
|
||||||
|
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||||
/* Calculate the remainder of dividing a by m: r = a mod m.
|
/* Calculate the remainder of dividing a by m: r = a mod m.
|
||||||
*
|
*
|
||||||
* @param [in] a SP integer to reduce.
|
* @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.
|
* @param [out] r SP integer to store result in.
|
||||||
*
|
*
|
||||||
* @return MP_OKAY on success.
|
* @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;
|
int err = MP_OKAY;
|
||||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
|
||||||
/* Remainder will start as a. */
|
/* Remainder will start as a. */
|
||||||
DECL_SP_INT(t, (a == NULL) ? 1 : a->used + 1);
|
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. */
|
/* In case remainder is modulus - allocate temporary. */
|
||||||
ALLOC_SP_INT(t, a->used + 1, err, NULL);
|
ALLOC_SP_INT(t, a->used + 1, err, NULL);
|
||||||
if (err == MP_OKAY) {
|
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);
|
err = sp_copy(t, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE_SP_INT(t, NULL);
|
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 */
|
#endif /* WOLFSSL_SP_INT_NEGATIVE */
|
||||||
|
|
||||||
return err;
|
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)
|
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
sp_int_digit* t = NULL;
|
sp_int_digit* t = NULL;
|
||||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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];
|
sp_int_digit t[a->used];
|
||||||
#else
|
#else
|
||||||
sp_int_digit t[SP_INT_DIGITS];
|
sp_int_digit t[SP_INT_DIGITS / 2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
#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);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
err = MP_MEM;
|
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--) {
|
for (; i < a->used; i++, dp--) {
|
||||||
SP_ASM_MUL_ADD(l, h, o, a->dp[i], dp[0]);
|
SP_ASM_MUL_ADD(l, h, o, a->dp[i], dp[0]);
|
||||||
}
|
}
|
||||||
t[k] = l;
|
r->dp[k] = l;
|
||||||
l = h;
|
l = h;
|
||||||
h = o;
|
h = o;
|
||||||
o = 0;
|
o = 0;
|
||||||
}
|
}
|
||||||
t[k] = l;
|
r->dp[k] = l;
|
||||||
|
XMEMCPY(r->dp, t, a->used * sizeof(sp_int_digit));
|
||||||
r->used = k + 1;
|
r->used = k + 1;
|
||||||
XMEMCPY(r->dp, t, r->used * sizeof(sp_int_digit));
|
|
||||||
sp_clamp(r);
|
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)
|
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
sp_int_digit* t = NULL;
|
sp_int_digit* t = NULL;
|
||||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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];
|
sp_int_digit t[a->used + b->used];
|
||||||
#else
|
#else
|
||||||
sp_int_digit t[SP_INT_DIGITS];
|
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)
|
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
sp_int_digit* t = NULL;
|
sp_int_digit* t = NULL;
|
||||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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];
|
sp_int_digit t[a->used + b->used];
|
||||||
#else
|
#else
|
||||||
sp_int_digit t[SP_INT_DIGITS];
|
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
|
#ifndef WOLFSSL_SP_SMALL
|
||||||
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
|
#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
|
#ifndef SQR_MUL_ASM
|
||||||
/* Multiply a by b and store in r: r = a * b
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 64
|
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Multiply a by b and store in r: r = a * b
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Multiply a by b and store in r: r = a * b
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 32 */
|
#endif /* SP_WORD_SIZE == 32 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Multiply a by b and store in r: r = a * b
|
/* 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
|
else
|
||||||
#ifndef WOLFSSL_SP_SMALL
|
#ifndef WOLFSSL_SP_SMALL
|
||||||
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
|
#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)) {
|
if ((a->used == 4) && (b->used == 4)) {
|
||||||
err = _sp_mul_4(a, b, r);
|
err = _sp_mul_4(a, b, r);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 64
|
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if ((a->used == 6) && (b->used == 6)) {
|
if ((a->used == 6) && (b->used == 6)) {
|
||||||
err = _sp_mul_6(a, b, r);
|
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
|
else
|
||||||
#endif /* SQR_MUL_ASM */
|
#endif /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if ((a->used == 8) && (b->used == 8)) {
|
if ((a->used == 8) && (b->used == 8)) {
|
||||||
err = _sp_mul_8(a, b, r);
|
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
|
else
|
||||||
#endif /* SQR_MUL_ASM */
|
#endif /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 32 */
|
#endif /* SP_WORD_SIZE == 32 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if ((a->used == 12) && (b->used == 12)) {
|
if ((a->used == 12) && (b->used == 12)) {
|
||||||
err = _sp_mul_12(a, b, r);
|
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) || \
|
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \
|
||||||
defined(WOLFCRYPT_HAVE_ECCSI) || \
|
defined(WOLFCRYPT_HAVE_ECCSI) || \
|
||||||
(!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || defined(OPENSSL_ALL)
|
(!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
|
/* Multiply a by b mod m and store in r: r = (a * b) mod m
|
||||||
*
|
*
|
||||||
* @param [in] a SP integer to multiply.
|
* @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) {
|
else if (err == MP_OKAY) {
|
||||||
/* Create temporary for multiplication result. */
|
_sp_mulmod(a, b, m, r);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -11581,7 +11634,8 @@ static int _sp_invmod_bin(const sp_int* a, const sp_int* m, sp_int* u,
|
|||||||
return err;
|
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
|
/* Calculates the multiplicative inverse in the field. r*a = x*m + 1
|
||||||
* Extended Euclidean Algorithm. NOT constant time.
|
* 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)
|
sp_int* y, sp_int* b, sp_int* c, sp_int* inv)
|
||||||
{
|
{
|
||||||
int err = MP_OKAY;
|
int err = MP_OKAY;
|
||||||
sp_int* d = NULL;
|
|
||||||
sp_int* r = NULL;
|
|
||||||
sp_int* s;
|
sp_int* s;
|
||||||
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
||||||
int bneg = 0;
|
int bneg = 0;
|
||||||
int cneg = 0;
|
int cneg = 0;
|
||||||
int neg;
|
int neg;
|
||||||
#endif
|
#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) {
|
if (err == MP_OKAY) {
|
||||||
d = t[0];
|
mp_init(d);
|
||||||
r = t[1];
|
|
||||||
|
|
||||||
/* 1. x = m, y = a, b = 1, c = 0 */
|
/* 1. x = m, y = a, b = 1, c = 0 */
|
||||||
_sp_copy(a, y);
|
_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 */
|
/* 2. while x > 1 */
|
||||||
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
|
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
|
||||||
/* 2.1. d = x / y, r = x mod y */
|
/* 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 (err == MP_OKAY) {
|
||||||
/* 2.2. c -= d * b */
|
/* 2.2. c -= d * b */
|
||||||
if (sp_isone(d)) {
|
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 */
|
/* 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 */
|
/* 2.4. s = b, b = c, c = s */
|
||||||
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 */
|
/* 2. while x > 1 */
|
||||||
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
|
while ((err == MP_OKAY) && (!sp_isone(x)) && (!sp_iszero(x))) {
|
||||||
/* 2.1. d = x / y, r = x mod y */
|
/* 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 (err == MP_OKAY) {
|
||||||
if (sp_isone(d)) {
|
if (sp_isone(d)) {
|
||||||
/* c -= 1 * b */
|
/* 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 */
|
/* 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 */
|
/* 2.4. s = b, b = c, c = s */
|
||||||
s = b; b = c; c = s;
|
s = b; b = c; c = s;
|
||||||
neg = bneg; bneg = cneg; cneg = neg;
|
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
|
#endif
|
||||||
|
|
||||||
FREE_SP_INT_ARRAY(t, NULL);
|
FREE_SP_INT(d, NULL);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -11810,7 +11861,8 @@ static int _sp_invmod(const sp_int* a, const sp_int* m, sp_int* r)
|
|||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
/* Calculate inverse. */
|
/* 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) {
|
if (sp_count_bits(mm) >= 1024) {
|
||||||
err = _sp_invmod_div(ma, mm, u, v, b, c, c);
|
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;
|
int s = 0;
|
||||||
sp_int* t = NULL;
|
sp_int* t = NULL;
|
||||||
sp_int* e = 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,
|
DECL_SP_INT_ARRAY(pre, (m == NULL) ? 1 : m->used * 2 + 1,
|
||||||
CT_INV_MOD_PRE_CNT + 2);
|
CT_INV_MOD_PRE_CNT + 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Validate parameters. */
|
/* Validate parameters. */
|
||||||
if ((a == NULL) || (m == NULL) || (r == NULL)) {
|
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;
|
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);
|
ALLOC_SP_INT_ARRAY(pre, m->used * 2 + 1, CT_INV_MOD_PRE_CNT + 2, err, NULL);
|
||||||
|
#endif
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
t = pre[CT_INV_MOD_PRE_CNT + 0];
|
t = pre[CT_INV_MOD_PRE_CNT + 0];
|
||||||
e = pre[CT_INV_MOD_PRE_CNT + 1];
|
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);
|
FREE_SP_INT_ARRAY(pre, NULL);
|
||||||
|
#endif
|
||||||
return err;
|
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_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH)
|
||||||
#if defined(WOLFSSL_SP_FAST_NCT_EXPTMOD) || !defined(WOLFSSL_SP_SMALL)
|
#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
|
/* 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.
|
* Creates a window of precalculated exponents with base in Montgomery form.
|
||||||
* Sliding window and is NOT constant time.
|
* 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* bm = NULL;
|
||||||
sp_int_digit mask;
|
sp_int_digit mask;
|
||||||
/* Maximum winBits is 6 and preCnt is (1 << (winBits - 1)). */
|
/* 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);
|
DECL_SP_INT_ARRAY(t, m->used * 2 + 1, (1 << 5) + 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
bits = sp_count_bits(e);
|
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
|
* - temporary result
|
||||||
* - Montgomery form of base
|
* - 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);
|
ALLOC_SP_INT_ARRAY(t, m->used * 2 + 1, preCnt + 2, err, NULL);
|
||||||
|
#endif
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
/* Set variables to use allocate memory. */
|
/* Set variables to use allocate memory. */
|
||||||
tr = t[preCnt + 0];
|
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);
|
err = sp_copy(tr, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_SP_NO_MALLOC
|
||||||
|
FREE_DYN_SP_INT_ARRAY(t, NULL);
|
||||||
|
#else
|
||||||
FREE_SP_INT_ARRAY(t, NULL);
|
FREE_SP_INT_ARRAY(t, NULL);
|
||||||
|
#endif
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SP_ALLOC_PREDEFINED
|
|
||||||
#undef SP_ALLOC
|
|
||||||
#undef SP_ALLOC_PREDEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m
|
/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m
|
||||||
* Non-constant time implementation.
|
* 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)
|
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
sp_int_digit* t = NULL;
|
sp_int_digit* t = NULL;
|
||||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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];
|
sp_int_digit t[((a->used + 1) / 2) * 2 + 1];
|
||||||
#else
|
#else
|
||||||
sp_int_digit t[SP_INT_DIGITS];
|
sp_int_digit t[(SP_INT_DIGITS + 1) / 2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
#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);
|
DYNAMIC_TYPE_BIGINT);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
err = MP_MEM;
|
err = MP_MEM;
|
||||||
@@ -13816,13 +13883,14 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
h = 0;
|
h = 0;
|
||||||
l = 0;
|
l = 0;
|
||||||
SP_ASM_SQR(h, l, a->dp[0]);
|
SP_ASM_SQR(h, l, a->dp[0]);
|
||||||
t[0] = h;
|
r->dp[0] = h;
|
||||||
t[1] = l;
|
r->dp[1] = l;
|
||||||
}
|
}
|
||||||
else if (err == MP_OKAY) {
|
else if (err == MP_OKAY) {
|
||||||
sp_int_digit l;
|
sp_int_digit l;
|
||||||
sp_int_digit h;
|
sp_int_digit h;
|
||||||
sp_int_digit o;
|
sp_int_digit o;
|
||||||
|
sp_int_digit* p = t;
|
||||||
|
|
||||||
h = 0;
|
h = 0;
|
||||||
l = 0;
|
l = 0;
|
||||||
@@ -13858,7 +13926,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
for (; (i < a->used); i++, j--) {
|
for (; (i < a->used); i++, j--) {
|
||||||
SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[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;
|
l = h;
|
||||||
h = o;
|
h = o;
|
||||||
o = 0;
|
o = 0;
|
||||||
@@ -13869,17 +13937,19 @@ static int _sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
for (; (i < a->used); i++, j--) {
|
for (; (i < a->used); i++, j--) {
|
||||||
SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]);
|
SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]);
|
||||||
}
|
}
|
||||||
t[k * 2] = l;
|
p[k * 2] = l;
|
||||||
l = h;
|
l = h;
|
||||||
h = o;
|
h = o;
|
||||||
o = 0;
|
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) {
|
if (err == MP_OKAY) {
|
||||||
r->used = a->used * 2;
|
r->used = a->used * 2;
|
||||||
XMEMCPY(r->dp, t, r->used * sizeof(sp_int_digit));
|
|
||||||
sp_clamp(r);
|
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)
|
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
|
||||||
sp_int_digit* t = NULL;
|
sp_int_digit* t = NULL;
|
||||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
#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];
|
sp_int_digit t[a->used * 2];
|
||||||
#else
|
#else
|
||||||
sp_int_digit t[SP_INT_DIGITS];
|
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
|
#ifndef WOLFSSL_SP_SMALL
|
||||||
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
|
#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
|
#ifndef SQR_MUL_ASM
|
||||||
/* Square a and store in r. r = a * a
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 64
|
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Square a and store in r. r = a * a
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Square a and store in r. r = a * a
|
/* 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 /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 32 */
|
#endif /* SP_WORD_SIZE == 32 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
/* Square a and store in r. r = a * a
|
/* Square a and store in r. r = a * a
|
||||||
*
|
*
|
||||||
@@ -16106,13 +16176,13 @@ int sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
else
|
else
|
||||||
#ifndef WOLFSSL_SP_SMALL
|
#ifndef WOLFSSL_SP_SMALL
|
||||||
#if !defined(WOLFSSL_HAVE_SP_ECC) && defined(HAVE_ECC)
|
#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) {
|
if (a->used == 4) {
|
||||||
err = _sp_sqr_4(a, r);
|
err = _sp_sqr_4(a, r);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 64
|
#if (SP_WORD_SIZE == 64 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if (a->used == 6) {
|
if (a->used == 6) {
|
||||||
err = _sp_sqr_6(a, r);
|
err = _sp_sqr_6(a, r);
|
||||||
@@ -16120,7 +16190,7 @@ int sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
else
|
else
|
||||||
#endif /* SQR_MUL_ASM */
|
#endif /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 64 */
|
#endif /* SP_WORD_SIZE == 64 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 256)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if (a->used == 8) {
|
if (a->used == 8) {
|
||||||
err = _sp_sqr_8(a, r);
|
err = _sp_sqr_8(a, r);
|
||||||
@@ -16128,7 +16198,7 @@ int sp_sqr(const sp_int* a, sp_int* r)
|
|||||||
else
|
else
|
||||||
#endif /* SQR_MUL_ASM */
|
#endif /* SQR_MUL_ASM */
|
||||||
#endif /* SP_WORD_SIZE == 32 */
|
#endif /* SP_WORD_SIZE == 32 */
|
||||||
#if SP_WORD_SIZE == 32
|
#if (SP_WORD_SIZE == 32 && SP_INT_BITS >= 384)
|
||||||
#ifdef SQR_MUL_ASM
|
#ifdef SQR_MUL_ASM
|
||||||
if (a->used == 12) {
|
if (a->used == 12) {
|
||||||
err = _sp_sqr_12(a, r);
|
err = _sp_sqr_12(a, r);
|
||||||
@@ -18577,5 +18647,12 @@ void sp_memzero_check(sp_int* sp)
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSSL_CHECK_MEM_ZERO */
|
#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 */
|
#endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */
|
||||||
|
@@ -1235,9 +1235,11 @@ enum {
|
|||||||
#endif
|
#endif
|
||||||
#define MAX_DHKEY_SZ (WOLFSSL_MAX_DHKEY_BITS / 8)
|
#define MAX_DHKEY_SZ (WOLFSSL_MAX_DHKEY_BITS / 8)
|
||||||
|
|
||||||
|
#ifndef NO_DH
|
||||||
#if WOLFSSL_MAX_DHKEY_BITS < WOLFSSL_MIN_DHKEY_BITS
|
#if WOLFSSL_MAX_DHKEY_BITS < WOLFSSL_MIN_DHKEY_BITS
|
||||||
#error "WOLFSSL_MAX_DHKEY_BITS has to be greater than WOLFSSL_MIN_DHKEY_BITS"
|
#error "WOLFSSL_MAX_DHKEY_BITS has to be greater than WOLFSSL_MIN_DHKEY_BITS"
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* NO_DH */
|
||||||
|
|
||||||
#ifndef MAX_PSK_ID_LEN
|
#ifndef MAX_PSK_ID_LEN
|
||||||
/* max psk identity/hint supported */
|
/* 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)))))
|
(! ((HAVE_FIPS_VERSION == 5) && (HAVE_FIPS_VERSION_MINOR == 0)))))
|
||||||
WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen);
|
WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif /* !HAVE_USER_RSA */
|
||||||
WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);
|
WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);
|
||||||
WOLFSSL_API int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
|
WOLFSSL_API int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
|
||||||
int with_header);
|
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
|
#endif
|
||||||
|
|
||||||
#ifndef NO_DSA
|
#ifndef NO_DSA
|
||||||
|
@@ -189,6 +189,26 @@ typedef int mp_err;
|
|||||||
BITS_PER_DIGIT*2) */
|
BITS_PER_DIGIT*2) */
|
||||||
#define MP_WARRAY ((mp_word)1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
|
#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
|
#ifdef HAVE_WOLF_BIGINT
|
||||||
/* raw big integer */
|
/* raw big integer */
|
||||||
typedef struct WC_BIGINT {
|
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) \
|
#define mp_isword(a, w) \
|
||||||
((((a)->used == 1) && ((a)->dp[0] == (w))) || (((w) == 0) && ((a)->used == 0)) \
|
((((a)->used == 1) && ((a)->dp[0] == (w))) || (((w) == 0) && ((a)->used == 0)) \
|
||||||
? MP_YES : MP_NO)
|
? MP_YES : MP_NO)
|
||||||
|
/* Number of bits used based on used field only. */
|
||||||
|
#define mp_bitsused(a) ((a)->used * DIGIT_BIT)
|
||||||
|
|
||||||
/* number of primes */
|
/* number of primes */
|
||||||
#ifdef MP_8BIT
|
#ifdef MP_8BIT
|
||||||
|
@@ -352,6 +352,11 @@ WOLFSSL_API int wc_RsaEncryptSize(const RsaKey* key);
|
|||||||
/* to avoid asn duplicate symbols @wc_fips */
|
/* to avoid asn duplicate symbols @wc_fips */
|
||||||
WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
|
WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||||
RsaKey* key, word32 inSz);
|
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,
|
WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||||
RsaKey* key, word32 inSz);
|
RsaKey* key, word32 inSz);
|
||||||
WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
|
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
|
#undef WOLFSSL_SP_INT_DIGIT_ALIGN
|
||||||
#define WOLFSSL_SP_INT_DIGIT_ALIGN
|
#define WOLFSSL_SP_INT_DIGIT_ALIGN
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define WOLFSSL_SP_NO_DYN_STACK
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
#pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */
|
#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)
|
#define sp_setneg(a) ((a)->sign = MP_NEG)
|
||||||
#endif
|
#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.
|
/* Updates the used count to exclude leading zeros.
|
||||||
*
|
*
|
||||||
* Assumes a is not NULL.
|
* Assumes a is not NULL.
|
||||||
*
|
*
|
||||||
* @param [in] a SP integer to update.
|
* @param [in] a SP integer to update.
|
||||||
*/
|
*/
|
||||||
#define sp_clamp(a) \
|
#define sp_clamp(a) \
|
||||||
do { \
|
do { \
|
||||||
int ii; \
|
int ii; \
|
||||||
for (ii = (a)->used - 1; ii >= 0 && (a)->dp[ii] == 0; ii--) { \
|
for (ii = (a)->used - 1; ii >= 0 && (a)->dp[ii] == 0; ii--) { \
|
||||||
} \
|
} \
|
||||||
(a)->used = ii + 1; \
|
(a)->used = ii + 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Check the compiled and linked math implementation are the same.
|
/* 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())
|
#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.
|
* A result of NO.
|
||||||
* e.g. Is prime? NO.
|
* e.g. Is prime? NO.
|
||||||
@@ -747,6 +740,86 @@ typedef struct sp_ecc_ctx {
|
|||||||
/* Mask of all used bits in word/digit. */
|
/* Mask of all used bits in word/digit. */
|
||||||
#define MP_MASK SP_MASK
|
#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
|
#ifdef HAVE_WOLF_BIGINT
|
||||||
/* Raw big integer as a big-endian byte array.
|
/* 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_abs sp_abs
|
||||||
#define mp_isneg sp_isneg
|
#define mp_isneg sp_isneg
|
||||||
#define mp_setneg sp_setneg
|
#define mp_setneg sp_setneg
|
||||||
|
#define mp_bitsused sp_bitsused
|
||||||
#define mp_clamp sp_clamp
|
#define mp_clamp sp_clamp
|
||||||
|
|
||||||
/* One to one mappings. */
|
/* One to one mappings. */
|
||||||
|
@@ -317,6 +317,55 @@
|
|||||||
#define FP_YES 1 /* yes response */
|
#define FP_YES 1 /* yes response */
|
||||||
#define FP_NO 0 /* no 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
|
#ifdef HAVE_WOLF_BIGINT
|
||||||
/* raw big integer */
|
/* raw big integer */
|
||||||
typedef struct WC_BIGINT {
|
typedef struct WC_BIGINT {
|
||||||
@@ -448,6 +497,8 @@ MP_API void fp_free(fp_int* a);
|
|||||||
#define fp_isword(a, w) \
|
#define fp_isword(a, w) \
|
||||||
(((((a)->used == 1) && ((a)->dp[0] == (w))) || \
|
(((((a)->used == 1) && ((a)->dp[0] == (w))) || \
|
||||||
(((w) == 0) && ((a)->used == 0))) ? FP_YES : FP_NO)
|
(((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 */
|
/* set to a small digit */
|
||||||
void fp_set(fp_int *a, fp_digit b);
|
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_isneg(a) fp_isneg(a)
|
||||||
#define mp_setneg(a) fp_setneg(a)
|
#define mp_setneg(a) fp_setneg(a)
|
||||||
#define mp_isword(a, w) fp_isword(a, w)
|
#define mp_isword(a, w) fp_isword(a, w)
|
||||||
|
#define mp_bitsused(a) fp_bitsused(a)
|
||||||
|
|
||||||
#define MP_RADIX_BIN 2
|
#define MP_RADIX_BIN 2
|
||||||
#define MP_RADIX_OCT 8
|
#define MP_RADIX_OCT 8
|
||||||
|
Reference in New Issue
Block a user