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:
Sean Parkinson
2022-04-05 18:16:20 +10:00
parent df9335ee0a
commit e9187f5f00
16 changed files with 359 additions and 50 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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,
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

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;
}
}
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
{
#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 */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -6712,9 +6712,14 @@ 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)) {
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)) {
err = MP_VAL;
@@ -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)) {

View File

@@ -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

View File

@@ -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;

View File

@@ -335,6 +335,8 @@ WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
#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