mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 04:34:41 +02:00
Wycheproof fixes/changes
Allow Chachac20-Poly1305 to take an empty msg. Allow AES-SIV to have an empty nonce. Don't allow the length to be malleable. Must use the smallest number of bytes to represent value. ECDSA and DSA signature values are positive. Add Sha512-224 and Sha512-256 OIDs. ASN template - ensure the ECDSA/DSA signature uses all data. Curve25519/Curve448 - WOLFSSL_ECDHX_SHARED_NOT_ZERO means shared secret can't be 0. Curve25519/Curve448 - check public value is less than order. ECC - x or y may be zero but not both. Ed25519/Ed448 - check S is less than order. Ed448 - ge_p3_dbl can be simplified for ASM. Prime check (integer.c/tfm.c/sp_int.c): Don't allow negative values and make sure random candidate doesn't have bits higher than those in a set when bits not a multiple of 8. RSA: support Sha512-224 and Sha512-256. RSA: Fix check for invalid in decryption. Affects plaintexts 256 bytes and longer. RSA: Don't allow base be larger than modulus. RSA: Check small ciphertext (1 or 0) on decrypt when not using OAEP. RSA: WOLFSSL_RSA_DECRYPT_TO_0_LEN allows decrypted value to be 0. SP math all: fix div to handle large a and d when checking size of remainder. SP math all: set sign of result in sp_mod_2d()
This commit is contained in:
@@ -16259,7 +16259,7 @@ static int test_wc_ChaCha20Poly1305_aead (void)
|
||||
sizeof(plaintext), generatedCiphertext, generatedAuthTag);
|
||||
AssertIntEQ(ret, BAD_FUNC_ARG);
|
||||
ret = wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
|
||||
plaintext, 0, generatedCiphertext, generatedAuthTag);
|
||||
NULL, sizeof(plaintext), generatedCiphertext, generatedAuthTag);
|
||||
AssertIntEQ(ret, BAD_FUNC_ARG);
|
||||
ret = wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad),
|
||||
plaintext, sizeof(plaintext), NULL, generatedAuthTag);
|
||||
@@ -16298,8 +16298,8 @@ static int test_wc_ChaCha20Poly1305_aead (void)
|
||||
ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), cipher,
|
||||
sizeof(cipher), authTag, NULL);
|
||||
AssertIntEQ(ret, BAD_FUNC_ARG);
|
||||
ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), cipher,
|
||||
0, authTag, generatedPlaintext);
|
||||
ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad), NULL,
|
||||
sizeof(cipher), authTag, generatedPlaintext);
|
||||
AssertIntEQ(ret, BAD_FUNC_ARG);
|
||||
if (ret == BAD_FUNC_ARG) {
|
||||
ret = 0;
|
||||
|
@@ -11993,13 +11993,16 @@ static WARN_UNUSED_RESULT int S2V(
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if ((ret == 0) && (nonceSz > 0)) {
|
||||
ShiftAndXorRb(tmp[0], tmp[1]);
|
||||
ret = wc_AesCmacGenerate(tmp[1], &macSz, nonce, nonceSz, key, keySz);
|
||||
if (ret == 0) {
|
||||
xorbuf(tmp[0], tmp[1], AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
XMEMCPY(tmp[0], tmp[1], AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (dataSz >= AES_BLOCK_SIZE) {
|
||||
|
@@ -2089,6 +2089,19 @@ int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
|
||||
* Note: 0 indicates indefinte length encoding *not* 0 bytes of length.
|
||||
*/
|
||||
word32 bytes = b & 0x7F;
|
||||
int minLen;
|
||||
|
||||
/* Calculate minimum length to be encoded with bytes. */
|
||||
if (b == 0x80) {
|
||||
/* Indefinite length encoding - no length bytes. */
|
||||
minLen = 0;
|
||||
}
|
||||
else if (bytes == 1) {
|
||||
minLen = 0x80;
|
||||
}
|
||||
else {
|
||||
minLen = 1 << ((bytes - 1) * 8);
|
||||
}
|
||||
|
||||
/* Check the number of bytes required are available. */
|
||||
if ((idx + bytes) > maxIdx) {
|
||||
@@ -2109,6 +2122,10 @@ int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx,
|
||||
if (length < 0) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
/* Don't allow lengths that are longer than strictly required. */
|
||||
if (length < minLen) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Length in first byte. */
|
||||
@@ -3122,6 +3139,42 @@ int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(HAVE_ECC) || !defined(NO_DSA)) && !defined(WOLFSSL_ASN_TEMPLATE)
|
||||
static int GetIntPositive(mp_int* mpi, const byte* input, word32* inOutIdx,
|
||||
word32 maxIdx)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
int ret;
|
||||
int length;
|
||||
|
||||
ret = GetASNInt(input, &idx, &length, maxIdx);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (((input[idx] & 0x80) == 0x80) && (input[idx - 1] != 0x00))
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_init(mpi) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_read_unsigned_bin(mpi, input + idx, length) != 0) {
|
||||
mp_clear(mpi);
|
||||
return ASN_GETINT_E;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WOLF_BIGINT
|
||||
if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
|
||||
mp_clear(mpi);
|
||||
return ASN_GETINT_E;
|
||||
}
|
||||
#endif /* HAVE_WOLF_BIGINT */
|
||||
|
||||
*inOutIdx = idx + length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* (ECC || !NO_DSA) && !WOLFSSL_ASN_TEMPLATE */
|
||||
|
||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||
#if (!defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)) \
|
||||
|| defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DSA))
|
||||
@@ -3737,6 +3790,12 @@ static word32 SetBitString16Bit(word16 val, byte* output)
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
static const byte hashSha512_224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 5};
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
static const byte hashSha512_256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 6};
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
#ifndef WOLFSSL_NOSHA3_224
|
||||
@@ -4130,6 +4189,18 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
case SHA512_224h:
|
||||
oid = hashSha512_224hOid;
|
||||
*oidSz = sizeof(hashSha512_224hOid);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
case SHA512_256h:
|
||||
oid = hashSha512_256hOid;
|
||||
*oidSz = sizeof(hashSha512_256hOid);
|
||||
break;
|
||||
#endif
|
||||
case SHA512h:
|
||||
oid = hashSha512hOid;
|
||||
*oidSz = sizeof(hashSha512hOid);
|
||||
@@ -27119,11 +27190,11 @@ int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GetInt(r, sig, &idx, sigLen) < 0) {
|
||||
if (GetIntPositive(r, sig, &idx, sigLen) < 0) {
|
||||
return ASN_ECC_KEY_E;
|
||||
}
|
||||
|
||||
if (GetInt(s, sig, &idx, sigLen) < 0) {
|
||||
if (GetIntPositive(s, sig, &idx, sigLen) < 0) {
|
||||
mp_clear(r);
|
||||
return ASN_ECC_KEY_E;
|
||||
}
|
||||
@@ -27142,6 +27213,7 @@ int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
|
||||
#else
|
||||
ASNGetData dataASN[dsaSigASN_Length];
|
||||
word32 idx = 0;
|
||||
int ret;
|
||||
|
||||
/* Clear dynamic data and set mp_ints to put r and s into. */
|
||||
XMEMSET(dataASN, 0, sizeof(dataASN));
|
||||
@@ -27149,8 +27221,19 @@ int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
|
||||
GetASN_MP(&dataASN[DSASIGASN_IDX_S], s);
|
||||
|
||||
/* Decode the DSA signature. */
|
||||
return GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
|
||||
sigLen);
|
||||
ret = GetASN_Items(dsaSigASN, dataASN, dsaSigASN_Length, 1, sig, &idx,
|
||||
sigLen);
|
||||
#ifndef NO_STRICT_ECDSA_LEN
|
||||
/* sanity check that the index has been advanced all the way to the end of
|
||||
* the buffer */
|
||||
if ((ret == 0) && (idx != sigLen)) {
|
||||
mp_clear(r);
|
||||
mp_clear(s);
|
||||
ret = ASN_ECC_KEY_E;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||
}
|
||||
#endif
|
||||
|
@@ -60,7 +60,7 @@ int wc_ChaCha20Poly1305_Encrypt(
|
||||
|
||||
/* Validate function arguments */
|
||||
if (!inKey || !inIV ||
|
||||
!inPlaintext || !inPlaintextLen ||
|
||||
(inPlaintextLen > 0 && inPlaintext == NULL) ||
|
||||
!outCiphertext ||
|
||||
!outAuthTag)
|
||||
{
|
||||
@@ -93,7 +93,7 @@ int wc_ChaCha20Poly1305_Decrypt(
|
||||
|
||||
/* Validate function arguments */
|
||||
if (!inKey || !inIV ||
|
||||
!inCiphertext || !inCiphertextLen ||
|
||||
(inCiphertextLen > 0 && inCiphertext == NULL) ||
|
||||
!inAuthTag ||
|
||||
!outPlaintext)
|
||||
{
|
||||
|
@@ -312,6 +312,18 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
|
||||
|
||||
RESTORE_VECTOR_REGISTERS();
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
if (ret == 0) {
|
||||
int i;
|
||||
byte t = 0;
|
||||
for (i = 0; i < CURVE25519_KEYSIZE; i++) {
|
||||
t |= o.point[i];
|
||||
}
|
||||
if (t == 0) {
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
ForceZero(&o, sizeof(o));
|
||||
@@ -444,7 +456,7 @@ int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian)
|
||||
|
||||
if (endian == EC25519_LITTLE_ENDIAN) {
|
||||
/* Check for value of zero or one */
|
||||
for (i = pubSz - 1; i > 0; i--) {
|
||||
for (i = CURVE25519_KEYSIZE - 1; i > 0; i--) {
|
||||
if (pub[i] != 0)
|
||||
break;
|
||||
}
|
||||
@@ -452,21 +464,41 @@ int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian)
|
||||
return ECC_BAD_ARG_E;
|
||||
|
||||
/* Check high bit set */
|
||||
if (pub[CURVE25519_KEYSIZE-1] & 0x80)
|
||||
if (pub[CURVE25519_KEYSIZE - 1] & 0x80)
|
||||
return ECC_OUT_OF_RANGE_E;
|
||||
|
||||
/* Check for order-1 or higher. */
|
||||
if (pub[CURVE25519_KEYSIZE - 1] == 0x7f) {
|
||||
for (i = CURVE25519_KEYSIZE - 2; i > 0; i--) {
|
||||
if (pub[i] != 0xff)
|
||||
break;
|
||||
}
|
||||
if (i == 0 && (pub[0] >= 0xec))
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check for value of zero or one */
|
||||
for (i = 0; i < pubSz-1; i++) {
|
||||
for (i = 0; i < CURVE25519_KEYSIZE - 1; i++) {
|
||||
if (pub[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == pubSz - 1 && (pub[i] == 0 || pub[i] == 1))
|
||||
if (i == CURVE25519_KEYSIZE - 1 && (pub[i] == 0 || pub[i] == 1))
|
||||
return ECC_BAD_ARG_E;
|
||||
|
||||
/* Check high bit set */
|
||||
if (pub[0] & 0x80)
|
||||
return ECC_OUT_OF_RANGE_E;
|
||||
|
||||
/* Check for order-1 or higher. */
|
||||
if (pub[0] == 0x7f) {
|
||||
for (i = 1; i < CURVE25519_KEYSIZE - 1; i++) {
|
||||
if (pub[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == CURVE25519_KEYSIZE - 1 && (pub[i] >= 0xec))
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -170,6 +170,17 @@ int wc_curve448_shared_secret_ex(curve448_key* private_key,
|
||||
if (ret == 0) {
|
||||
ret = curve448(o, private_key->k, public_key->p);
|
||||
}
|
||||
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
if (ret == 0) {
|
||||
byte t = 0;
|
||||
for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) {
|
||||
t |= o[i];
|
||||
}
|
||||
if (t == 0) {
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
if (endian == EC448_BIG_ENDIAN) {
|
||||
/* put shared secret key in Big Endian format */
|
||||
@@ -353,7 +364,7 @@ int wc_curve448_check_public(const byte* pub, word32 pubSz, int endian)
|
||||
if (ret == 0) {
|
||||
if (endian == EC448_LITTLE_ENDIAN) {
|
||||
/* Check for value of zero or one */
|
||||
for (i = pubSz - 1; i > 0; i--) {
|
||||
for (i = CURVE448_PUB_KEY_SIZE - 1; i > 0; i--) {
|
||||
if (pub[i] != 0) {
|
||||
break;
|
||||
}
|
||||
@@ -361,17 +372,56 @@ int wc_curve448_check_public(const byte* pub, word32 pubSz, int endian)
|
||||
if ((i == 0) && (pub[0] == 0 || pub[0] == 1)) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
/* Check for order-1 or higher */
|
||||
for (i = CURVE448_PUB_KEY_SIZE - 1; i > 28; i--) {
|
||||
if (pub[i] != 0xff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == 28) && (pub[i] == 0xff)) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
if ((i == 28) && (pub[i] == 0xfe)) {
|
||||
for (--i; i > 0; i--) {
|
||||
if (pub[i] != 0xff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == 0) && (pub[i] >= 0xfe)) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check for value of zero or one */
|
||||
for (i = 0; i < pubSz-1; i++) {
|
||||
for (i = 0; i < CURVE448_PUB_KEY_SIZE-1; i++) {
|
||||
if (pub[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == pubSz - 1) && (pub[i] == 0 || pub[i] == 1)) {
|
||||
if ((i == CURVE448_PUB_KEY_SIZE - 1) &&
|
||||
(pub[i] == 0 || pub[i] == 1)) {
|
||||
ret = ECC_BAD_ARG_E;
|
||||
}
|
||||
/* Check for order-1 or higher */
|
||||
for (i = 0; i < 27; i++) {
|
||||
if (pub[i] != 0xff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == 27) && (pub[i] == 0xff)) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
if ((i == 27) && (pub[i] == 0xfe)) {
|
||||
for (++i; i < CURVE448_PUB_KEY_SIZE - 1; i--) {
|
||||
if (pub[i] != 0xff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == CURVE448_PUB_KEY_SIZE) && (pub[i] >= 0xfe)) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10011,7 +10011,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
|
||||
key->dp->size);
|
||||
|
||||
if (mp_iszero(key->pubkey.x) || mp_isneg(key->pubkey.x)) {
|
||||
if (mp_isneg(key->pubkey.x)) {
|
||||
WOLFSSL_MSG("Invalid Qx");
|
||||
err = BAD_FUNC_ARG;
|
||||
}
|
||||
@@ -10025,12 +10025,19 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
|
||||
key->dp->size);
|
||||
|
||||
if (mp_iszero(key->pubkey.y) || mp_isneg(key->pubkey.y)) {
|
||||
if (mp_isneg(key->pubkey.y)) {
|
||||
WOLFSSL_MSG("Invalid Qy");
|
||||
err = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == MP_OKAY) {
|
||||
if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
|
||||
WOLFSSL_MSG("Invalid Qx and Qy");
|
||||
err = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_set(key->pubkey.z, 1);
|
||||
|
||||
|
@@ -572,6 +572,15 @@ static int ed25519_verify_msg_update_with_sha(const byte* msgSegment,
|
||||
return ed25519_hash_update(key, sha, msgSegment, msgSegmentLen);
|
||||
}
|
||||
|
||||
/* Low part of order in big endian. */
|
||||
static const byte ed25519_low_order[] = {
|
||||
0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
|
||||
0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed
|
||||
};
|
||||
|
||||
#define ED25519_SIG_LOW_ORDER_IDX \
|
||||
((int)(ED25519_SIG_SIZE/2 + sizeof(ed25519_low_order) - 1))
|
||||
|
||||
/*
|
||||
sig is array of bytes containing the signature
|
||||
sigLen is the length of sig byte array
|
||||
@@ -599,8 +608,39 @@ static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
|
||||
*res = 0;
|
||||
|
||||
/* check on basics needed to verify signature */
|
||||
if (sigLen != ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
|
||||
if (sigLen != ED25519_SIG_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
/* S is not larger or equal to the order:
|
||||
* 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed
|
||||
* = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
|
||||
*/
|
||||
if (sig[ED25519_SIG_SIZE-1] > 0x10)
|
||||
return BAD_FUNC_ARG;
|
||||
if (sig[ED25519_SIG_SIZE-1] == 0x10) {
|
||||
int i = ED25519_SIG_SIZE-1;
|
||||
int j;
|
||||
|
||||
/* Check high zeros. */
|
||||
for (--i; i > ED25519_SIG_LOW_ORDER_IDX; i--) {
|
||||
if (sig[i] > 0x00)
|
||||
break;
|
||||
}
|
||||
/* Did we see all zeros up to lower order index? */
|
||||
if (i == ED25519_SIG_LOW_ORDER_IDX) {
|
||||
/* Check lower part. */
|
||||
for (j = 0; j < (int)sizeof(ed25519_low_order); j++, i--) {
|
||||
/* Check smaller. */
|
||||
if (sig[i] < ed25519_low_order[j])
|
||||
break;
|
||||
/* Check bigger. */
|
||||
if (sig[i] > ed25519_low_order[j])
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
/* Check equal - all bytes match. */
|
||||
if (i == ED25519_SIG_SIZE/2 - 1)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* uncompress A (public key), test if valid, and negate it */
|
||||
#ifndef FREESCALE_LTC_ECC
|
||||
|
@@ -547,6 +547,18 @@ static int ed448_verify_msg_update_with_sha(const byte* msgSegment,
|
||||
return ed448_hash_update(key, sha, msgSegment, msgSegmentLen);
|
||||
}
|
||||
|
||||
/* Order of the ed448 curve - little endian. */
|
||||
static const byte ed448_order[] = {
|
||||
0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23,
|
||||
0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21,
|
||||
0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4,
|
||||
0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0x00
|
||||
};
|
||||
|
||||
/* Verify the message using the ed448 public key.
|
||||
*
|
||||
* sig [in] Signature to verify.
|
||||
@@ -566,6 +578,7 @@ static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
|
||||
ge448_p2 A;
|
||||
ge448_p2 R;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* sanity check on arguments */
|
||||
if ((sig == NULL) || (res == NULL) || (key == NULL))
|
||||
@@ -577,6 +590,18 @@ static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
|
||||
/* check on basics needed to verify signature */
|
||||
if (sigLen != ED448_SIG_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
/* Check S is not larger than or equal to order. */
|
||||
for (i = (int)sizeof(ed448_order) - 1; i >= 0; i--) {
|
||||
/* Bigger than order. */
|
||||
if (sig[ED448_SIG_SIZE/2 + i] > ed448_order[i])
|
||||
return BAD_FUNC_ARG;
|
||||
/* Less than order. */
|
||||
if (sig[ED448_SIG_SIZE/2 + i] < ed448_order[i])
|
||||
break;
|
||||
}
|
||||
/* Same value as order. */
|
||||
if (i == -1)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* uncompress A (public key), test if valid, and negate it */
|
||||
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
|
||||
|
@@ -59,8 +59,8 @@
|
||||
static void ge_p2_0(ge_p2 *h);
|
||||
#ifndef CURVED25519_ASM
|
||||
static void ge_precomp_0(ge_precomp *h);
|
||||
#endif
|
||||
static void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p);
|
||||
#endif
|
||||
static WC_INLINE void ge_p3_to_cached(ge_cached *r,const ge_p3 *p);
|
||||
static void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p);
|
||||
static WC_INLINE void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p);
|
||||
@@ -9725,9 +9725,13 @@ r = 2 * p
|
||||
|
||||
static void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p)
|
||||
{
|
||||
ge_p2 q;
|
||||
ge_p3_to_p2(&q,p);
|
||||
ge_p2_dbl(r,&q);
|
||||
#ifndef CURVED25519_ASM
|
||||
ge_p2 q;
|
||||
ge_p3_to_p2(&q,p);
|
||||
ge_p2_dbl(r,&q);
|
||||
#else
|
||||
fe_ge_dbl(r->X, r->Y, r->Z, r->T, p->X, p->Y, p->Z);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -9772,12 +9776,14 @@ static WC_INLINE void ge_p3_to_cached(ge_cached *r,const ge_p3 *p)
|
||||
r = p
|
||||
*/
|
||||
|
||||
#ifndef CURVED25519_ASM
|
||||
static void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p)
|
||||
{
|
||||
fe_copy(r->X,p->X);
|
||||
fe_copy(r->Y,p->Y);
|
||||
fe_copy(r->Z,p->Z);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ge p3 tobytes */
|
||||
|
@@ -4905,6 +4905,7 @@ int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
|
||||
mp_int b, c;
|
||||
int ix, err, res;
|
||||
byte* base = NULL;
|
||||
word32 bitSz = 0;
|
||||
word32 baseSz = 0;
|
||||
|
||||
/* default to no */
|
||||
@@ -4915,6 +4916,10 @@ int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
if (a->sign == MP_NEG) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
if (mp_isone(a)) {
|
||||
*result = MP_NO;
|
||||
return MP_OKAY;
|
||||
@@ -4947,8 +4952,9 @@ int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
|
||||
return err;
|
||||
}
|
||||
|
||||
baseSz = mp_count_bits(a);
|
||||
baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);
|
||||
bitSz = mp_count_bits(a);
|
||||
baseSz = (bitSz / 8) + ((bitSz % 8) ? 1 : 0);
|
||||
bitSz %= 8;
|
||||
|
||||
base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (base == NULL) {
|
||||
@@ -4968,6 +4974,11 @@ int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
|
||||
goto LBL_B;
|
||||
}
|
||||
|
||||
/* Clear bits higher than those in a. */
|
||||
if (bitSz > 0) {
|
||||
base[0] &= (1 << bitSz) - 1;
|
||||
}
|
||||
|
||||
if ((err = mp_read_unsigned_bin(&b, base, baseSz)) != MP_OKAY) {
|
||||
goto LBL_B;
|
||||
}
|
||||
|
@@ -986,6 +986,18 @@ static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out,
|
||||
case WC_MGF1SHA512:
|
||||
ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap);
|
||||
break;
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
case WC_MGF1SHA512_224:
|
||||
ret = RsaMGF1(WC_HASH_TYPE_SHA512_224, seed, seedSz, out, outSz,
|
||||
heap);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
case WC_MGF1SHA512_256:
|
||||
ret = RsaMGF1(WC_HASH_TYPE_SHA512_256, seed, seedSz, out, outSz,
|
||||
heap);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("Unknown MGF type: check build options");
|
||||
@@ -1770,7 +1782,7 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
|
||||
invalid |= ctMaskNotEq(pkcsBlock[1], padValue);
|
||||
|
||||
*output = (byte *)(pkcsBlock + i);
|
||||
ret = ((int)(byte)~invalid) & (pkcsBlockLen - i);
|
||||
ret = ((int)-1 + (int)(invalid >> 7)) & (pkcsBlockLen - i);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2277,8 +2289,13 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
||||
#endif
|
||||
#endif
|
||||
int ret = 0;
|
||||
word32 keyLen = 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;
|
||||
@@ -2578,7 +2595,6 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
keyLen = wc_RsaEncryptSize(key);
|
||||
if (keyLen > *outLen)
|
||||
ret = RSA_BUFFER_E;
|
||||
}
|
||||
@@ -2591,7 +2607,6 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
|
||||
#else
|
||||
(void)type;
|
||||
(void)key;
|
||||
(void)keyLen;
|
||||
XMEMCPY(out, in, inLen);
|
||||
*outLen = inLen;
|
||||
#endif
|
||||
@@ -2885,8 +2900,9 @@ int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,
|
||||
}
|
||||
#endif /* WOLFSSL_CRYPTOCELL */
|
||||
|
||||
int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
|
||||
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
|
||||
static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
|
||||
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
|
||||
int checkSmallCt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -2944,7 +2960,7 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* check c > 1 */
|
||||
if (mp_cmp_d(c, 1) != MP_GT)
|
||||
if (checkSmallCt && (mp_cmp_d(c, 1) != MP_GT))
|
||||
ret = RSA_OUT_OF_RANGE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
@@ -2971,6 +2987,8 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
|
||||
}
|
||||
#endif /* NO_RSA_BOUNDS_CHECK */
|
||||
#endif
|
||||
#else
|
||||
(void)checkSmallCt;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
|
||||
@@ -3012,6 +3030,12 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_RSA */
|
||||
}
|
||||
|
||||
int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
|
||||
word32* outLen, int type, RsaKey* key, WC_RNG* rng)
|
||||
{
|
||||
/* Always check for ciphertext of 0 or 1. (Should't for OAEP decrypt.) */
|
||||
return wc_RsaFunction_ex(in, inLen, out, outLen, type, key, rng, 1);
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_RSA_VERIFY_ONLY
|
||||
/* Internal Wrappers */
|
||||
@@ -3260,10 +3284,12 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
|
||||
|
||||
case RSA_STATE_DECRYPT_EXPTMOD:
|
||||
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE)
|
||||
ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen,
|
||||
rsa_type, key, rng);
|
||||
ret = wc_RsaFunction_ex(key->data, inLen, key->data, &key->dataLen,
|
||||
rsa_type, key, rng,
|
||||
pad_type != WC_RSA_OAEP_PAD);
|
||||
#else
|
||||
ret = wc_RsaFunction(in, inLen, out, &key->dataLen, rsa_type, key, rng);
|
||||
ret = wc_RsaFunction_ex(in, inLen, out, &key->dataLen, rsa_type, key,
|
||||
rng, pad_type != WC_RSA_OAEP_PAD);
|
||||
#endif
|
||||
|
||||
if (ret >= 0 || ret == WC_PENDING_E) {
|
||||
@@ -3319,7 +3345,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
|
||||
|
||||
#if !defined(WOLFSSL_RSA_VERIFY_ONLY)
|
||||
ret = ctMaskSelInt(ctMaskLTE(ret, outLen), ret, RSA_BUFFER_E);
|
||||
#ifndef WOLFSSL_RSA_DECRYPT_TO_0_LEN
|
||||
ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret, RSA_BUFFER_E);
|
||||
#endif
|
||||
#else
|
||||
if (outLen < (word32)ret)
|
||||
ret = RSA_BUFFER_E;
|
||||
|
@@ -6712,8 +6712,13 @@ int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem)
|
||||
if ((err == MP_OKAY) && (r != NULL) && (r->size < a->used - d->used + 2)) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
if ((err == MP_OKAY) && (rem != NULL) && (rem->size < a->used + 1)) {
|
||||
err = MP_VAL;
|
||||
if ((err == MP_OKAY) && (rem != NULL)) {
|
||||
if ((a->used <= d->used) && (rem->size < a->used + 1)) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
else if ((a->used > d->used) && (rem->size < d->used + 1)) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
}
|
||||
/* May need to shift number being divided left into a new word. */
|
||||
if ((err == MP_OKAY) && (a->used == SP_INT_DIGITS)) {
|
||||
@@ -11528,6 +11533,9 @@ int sp_mod_2d(sp_int* a, int e, sp_int* r)
|
||||
if (a != r) {
|
||||
XMEMCPY(r->dp, a->dp, digits * sizeof(sp_int_digit));
|
||||
r->used = a->used;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
r->sign = a->sign;
|
||||
#endif
|
||||
}
|
||||
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (digits <= a->used)
|
||||
@@ -15632,6 +15640,12 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng)
|
||||
err = MP_VAL;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if ((err == MP_OKAY) && (a->sign == MP_NEG)) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((err == MP_OKAY) && sp_isone(a)) {
|
||||
ret = MP_NO;
|
||||
haveRes = 1;
|
||||
@@ -15700,6 +15714,7 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng)
|
||||
/* Ensure the top word has no more bits than necessary. */
|
||||
if (bits > 0) {
|
||||
b->dp[b->used - 1] &= ((sp_digit)1 << bits) - 1;
|
||||
sp_clamp(b);
|
||||
}
|
||||
|
||||
if ((sp_cmp_d(b, 2) != MP_GT) || (_sp_cmp(b, c) != MP_LT)) {
|
||||
|
@@ -5069,6 +5069,8 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
|
||||
if (a == NULL || result == NULL || rng == NULL)
|
||||
return FP_VAL;
|
||||
if (a->sign == FP_NEG)
|
||||
return FP_VAL;
|
||||
|
||||
if (fp_isone(a)) {
|
||||
*result = FP_NO;
|
||||
@@ -5107,12 +5109,14 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
byte* base;
|
||||
#endif
|
||||
word32 baseSz;
|
||||
word32 bitSz;
|
||||
int err;
|
||||
|
||||
baseSz = fp_count_bits(a);
|
||||
bitSz = fp_count_bits(a);
|
||||
/* The base size is the number of bits / 8. One is added if the number
|
||||
* of bits isn't an even 8. */
|
||||
baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);
|
||||
baseSz = (bitSz / 8) + ((bitSz % 8) ? 1 : 0);
|
||||
bitSz %= 8;
|
||||
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
if (baseSz > sizeof(base))
|
||||
@@ -5153,6 +5157,9 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (bitSz != 0)
|
||||
base[0] &= (1 << bitSz) - 1;
|
||||
|
||||
err = fp_read_unsigned_bin(b, base, baseSz);
|
||||
if (err != FP_OKAY) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
|
@@ -5860,8 +5860,8 @@ WOLFSSL_TEST_SUBROUTINE int chacha20_poly1305_aead_test(void)
|
||||
sizeof(plaintext1), generatedCiphertext, NULL);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4904;
|
||||
err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1,
|
||||
0, generatedCiphertext, generatedAuthTag);
|
||||
err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), NULL,
|
||||
sizeof(plaintext1), generatedCiphertext, generatedAuthTag);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4905;
|
||||
/* Decrypt */
|
||||
@@ -5885,8 +5885,8 @@ WOLFSSL_TEST_SUBROUTINE int chacha20_poly1305_aead_test(void)
|
||||
sizeof(cipher2), authTag2, NULL);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4910;
|
||||
err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2,
|
||||
0, authTag2, generatedPlaintext);
|
||||
err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), NULL,
|
||||
sizeof(cipher2), authTag2, generatedPlaintext);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4911;
|
||||
|
||||
|
@@ -329,12 +329,14 @@ WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
|
||||
*/
|
||||
|
||||
/* Mask Generation Function Identifiers */
|
||||
#define WC_MGF1NONE 0
|
||||
#define WC_MGF1SHA1 26
|
||||
#define WC_MGF1SHA224 4
|
||||
#define WC_MGF1SHA256 1
|
||||
#define WC_MGF1SHA384 2
|
||||
#define WC_MGF1SHA512 3
|
||||
#define WC_MGF1NONE 0
|
||||
#define WC_MGF1SHA1 26
|
||||
#define WC_MGF1SHA224 4
|
||||
#define WC_MGF1SHA256 1
|
||||
#define WC_MGF1SHA384 2
|
||||
#define WC_MGF1SHA512 3
|
||||
#define WC_MGF1SHA512_224 5
|
||||
#define WC_MGF1SHA512_256 6
|
||||
|
||||
/* Padding types */
|
||||
#define WC_RSA_PKCSV15_PAD 0
|
||||
|
Reference in New Issue
Block a user