Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions tests/api/test_curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,14 +444,17 @@ int test_wc_curve25519_export_private_raw_ex(void)
EXPECT_DECLS;
#if defined(HAVE_CURVE25519)
curve25519_key key;
WC_RNG rng;
byte out[CURVE25519_KEYSIZE];
word32 outLen = sizeof(out);
int endian = EC25519_BIG_ENDIAN;

XMEMSET(&rng, 0, sizeof(WC_RNG));
ExpectIntEQ(wc_curve25519_init(&key), 0);

/* Reject export when private key not set (privSet == 0). */
ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen, endian),
0);
WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
/* test bad cases */
ExpectIntEQ(wc_curve25519_export_private_raw_ex(NULL, NULL, NULL, endian),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
Expand All @@ -461,12 +464,15 @@ int test_wc_curve25519_export_private_raw_ex(void)
endian), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, NULL, endian),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen,
EC25519_LITTLE_ENDIAN), 0);
outLen = outLen - 2;

/* Populate the key, then exercise the buffer-too-small path. */
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &key), 0);
outLen = CURVE25519_KEYSIZE - 1;
ExpectIntEQ(wc_curve25519_export_private_raw_ex(&key, out, &outLen, endian),
WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_curve25519_free(&key);
#endif
return EXPECT_RESULT();
Expand Down
14 changes: 10 additions & 4 deletions tests/api/test_curve448.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ int test_wc_curve448_export_private_raw_ex(void)
EXPECT_DECLS;
#if defined(HAVE_CURVE448)
curve448_key key;
WC_RNG rng;
byte out[CURVE448_KEY_SIZE];
word32 outLen = sizeof(out);
int endian = EC448_BIG_ENDIAN;

XMEMSET(&rng, 0, sizeof(WC_RNG));
ExpectIntEQ(wc_curve448_init(&key), 0);
/* Reject export when private key not set (privSet == 0). */
ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen, endian),
0);
WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
/* test bad cases */
ExpectIntEQ(wc_curve448_export_private_raw_ex(NULL, NULL, NULL, endian),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
Expand All @@ -180,12 +183,15 @@ int test_wc_curve448_export_private_raw_ex(void)
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, NULL, endian),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen,
EC448_LITTLE_ENDIAN), 0);
outLen = outLen - 2;

/* Populate the key, then exercise the buffer-too-small path. */
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &key), 0);
outLen = CURVE448_KEY_SIZE - 1;
ExpectIntEQ(wc_curve448_export_private_raw_ex(&key, out, &outLen, endian),
WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_curve448_free(&key);
#endif
return EXPECT_RESULT();
Expand Down
21 changes: 21 additions & 0 deletions tests/api/test_ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ int test_wc_ed25519_export(void)
XMEMSET(&rng, 0, sizeof(WC_RNG));

ExpectIntEQ(wc_ed25519_init(&key), 0);
/* Reject export when private key not set. */
PRIVATE_KEY_UNLOCK();
ExpectIntEQ(wc_ed25519_export_private_only(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_export_private(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();
ExpectIntEQ(wc_InitRng(&rng), 0);
#ifdef HAVE_ED25519_MAKE_KEY
ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key), 0);
Expand Down Expand Up @@ -379,6 +386,20 @@ int test_wc_ed25519_export(void)
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();

#ifdef HAVE_ED25519_KEY_IMPORT
/* Public-only key: re-init and import just the public part; private
* exports must still fail with privKeySet == 0. */
wc_ed25519_free(&key);
ExpectIntEQ(wc_ed25519_init(&key), 0);
ExpectIntEQ(wc_ed25519_import_public(pub, pubSz, &key), 0);
PRIVATE_KEY_UNLOCK();
ExpectIntEQ(wc_ed25519_export_private_only(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed25519_export_private(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();
#endif

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_ed25519_free(&key);
#endif
Expand Down
21 changes: 21 additions & 0 deletions tests/api/test_ed448.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ int test_wc_ed448_export(void)
XMEMSET(&rng, 0, sizeof(WC_RNG));

ExpectIntEQ(wc_ed448_init(&key), 0);
/* Reject export when private key not set. */
PRIVATE_KEY_UNLOCK();
ExpectIntEQ(wc_ed448_export_private_only(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed448_export_private(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key), 0);

Expand Down Expand Up @@ -351,6 +358,20 @@ int test_wc_ed448_export(void)
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();

#ifdef HAVE_ED448_KEY_IMPORT
/* Public-only key: re-init and import just the public part; private
* exports must still fail with privKeySet == 0. */
wc_ed448_free(&key);
ExpectIntEQ(wc_ed448_init(&key), 0);
ExpectIntEQ(wc_ed448_import_public(pub, pubSz, &key), 0);
PRIVATE_KEY_UNLOCK();
ExpectIntEQ(wc_ed448_export_private_only(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_ed448_export_private(&key, priv, &privSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
PRIVATE_KEY_LOCK();
#endif

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_ed448_free(&key);
#endif
Expand Down
2 changes: 2 additions & 0 deletions wolfcrypt/src/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
*/
int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz)
{
if ((cmac == NULL) || (in == NULL && inSz != 0))
return BAD_FUNC_ARG;
return _wc_Hash_Grow(&cmac->msg, &cmac->used, &cmac->len, in, inSz, cmac->aes.heap);
}
#endif /* WOLFSSL_HASH_KEEP */
Expand Down
3 changes: 3 additions & 0 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,9 @@ int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
if (key == NULL || out == NULL || outLen == NULL)
return BAD_FUNC_ARG;

if (!key->privSet)
return ECC_BAD_ARG_E;

/* check size of outgoing buffer */
if (*outLen < CURVE25519_KEYSIZE) {
*outLen = CURVE25519_KEYSIZE;
Expand Down
4 changes: 4 additions & 0 deletions wolfcrypt/src/curve448.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,10 @@ int wc_curve448_export_private_raw_ex(curve448_key* key, byte* out,
ret = BAD_FUNC_ARG;
}

if ((ret == 0) && (!key->privSet)) {
ret = ECC_BAD_ARG_E;
}

/* check size of outgoing buffer */
if ((ret == 0) && (*outLen < CURVE448_KEY_SIZE)) {
*outLen = CURVE448_KEY_SIZE;
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,7 @@ int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
int wc_ed25519_export_private_only(const ed25519_key* key, byte* out, word32* outLen)
{
/* sanity checks on arguments */
if (key == NULL || out == NULL || outLen == NULL)
if (key == NULL || !key->privKeySet || out == NULL || outLen == NULL)
return BAD_FUNC_ARG;

if (*outLen < ED25519_KEY_SIZE) {
Expand Down
8 changes: 8 additions & 0 deletions wolfcrypt/src/ed448.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,10 @@ int wc_ed448_export_private_only(const ed448_key* key, byte* out, word32* outLen
ret = BAD_FUNC_ARG;
}

if ((ret == 0) && (!key->privKeySet)) {
ret = BAD_FUNC_ARG;
}

if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) {
*outLen = ED448_KEY_SIZE;
ret = BUFFER_E;
Expand Down Expand Up @@ -1333,6 +1337,10 @@ int wc_ed448_export_private(const ed448_key* key, byte* out, word32* outLen)
ret = BAD_FUNC_ARG;
}

if ((ret == 0) && (!key->privKeySet)) {
ret = BAD_FUNC_ARG;
}

if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) {
*outLen = ED448_PRV_KEY_SIZE;
ret = BUFFER_E;
Expand Down
41 changes: 34 additions & 7 deletions wolfcrypt/src/integer.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,21 +549,48 @@ int mp_exch (mp_int * a, mp_int * b)
return MP_OKAY;
}

/* Constant-time conditional swap: must not branch on m (leaks scalar bit).
* m must be 0 or 1. The t parameter is unused; XOR is performed in place
* with a single-digit stack scratch so callers don't need to clear t->dp. */
int mp_cond_swap_ct_ex (mp_int * a, mp_int * b, int c, int m, mp_int * t)
{
(void)c;
int i;
int err;
int imask;
int idiff;
mp_digit mask;
mp_digit d;

(void)t;
if (m == 1)
mp_exch(a, b);

m &= 1;
imask = -m;
mask = (mp_digit)0 - (mp_digit)m;

if ((err = mp_grow(a, c)) != MP_OKAY)
return err;
if ((err = mp_grow(b, c)) != MP_OKAY)
return err;

idiff = (a->used ^ b->used) & imask;
a->used ^= idiff;
b->used ^= idiff;
idiff = (a->sign ^ b->sign) & imask;
a->sign ^= idiff;
b->sign ^= idiff;

for (i = 0; i < c; i++) {
d = (a->dp[i] ^ b->dp[i]) & mask;
a->dp[i] ^= d;
b->dp[i] ^= d;
}

return MP_OKAY;
}

int mp_cond_swap_ct (mp_int * a, mp_int * b, int c, int m)
{
(void)c;
if (m == 1)
mp_exch(a, b);
return MP_OKAY;
return mp_cond_swap_ct_ex(a, b, c, m, NULL);
}


Expand Down
49 changes: 49 additions & 0 deletions wolfcrypt/src/pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -12009,6 +12009,9 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,

int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
int hashOID = WC_SHA; /* default to SHA1 */
int keyLen = 0;
int keyLenPresent = 0;
word32 pbkdf2End = 0;
word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
Expand Down Expand Up @@ -12055,6 +12058,7 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
/* get KDF params SEQ */
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
pbkdf2End = *idx + (word32)length;

/* get KDF salt OCTET STRING */
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
Expand All @@ -12080,6 +12084,44 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
return ASN_PARSE_E;
}

/* optional keyLength - validated below once kekKeySz is known */
if (*idx < pbkdf2End && pkiMsg[*idx] == ASN_INTEGER) {
if (GetShortInt(pkiMsg, idx, &keyLen, pbkdf2End) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
keyLenPresent = 1;
}

/* optional prf; default hmacWithSHA1 keeps hashOID at WC_SHA */
if (*idx < pbkdf2End &&
pkiMsg[*idx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
word32 prfOid = 0;
if (GetAlgoId(pkiMsg, idx, &prfOid, oidHmacType,
pbkdf2End) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
switch ((int)prfOid) {
#ifdef WOLFSSL_SHA224
case HMAC_SHA224_OID: hashOID = WC_SHA224; break;
#endif
#ifndef NO_SHA256
case HMAC_SHA256_OID: hashOID = WC_SHA256; break;
#endif
#ifdef WOLFSSL_SHA384
case HMAC_SHA384_OID: hashOID = WC_SHA384; break;
#endif
#ifdef WOLFSSL_SHA512
case HMAC_SHA512_OID: hashOID = WC_SHA512; break;
#endif
default:
/* unknown id (incl. explicit hmacWithSHA1) - keep
* default WC_SHA; MAC unwrap fails if mismatched */
break;
}
}

/* get KeyEncAlgoId SEQ */
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
Expand Down Expand Up @@ -12112,6 +12154,13 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz,
return kekKeySz;
}

/* RFC 8018: when present, PBKDF2 keyLength must equal the
* derived key length expected by the encryption algorithm */
if (keyLenPresent && keyLen != kekKeySz) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}

/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
Expand Down
2 changes: 2 additions & 0 deletions wolfcrypt/src/rng_bank.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,8 @@ WOLFSSL_API int wc_BankRef_Release(WC_RNG *rng)
{
int isZero = 0;
int ret = 0;
if (rng == NULL)
return BAD_FUNC_ARG;
if (rng->bankref == NULL)
return BAD_FUNC_ARG;
wolfSSL_RefDec(&rng->bankref->refcount, &isZero, &ret);
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/wc_pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -2633,7 +2633,7 @@ int wc_hash2sz(int hType)
case WC_HASH_TYPE_SHA:
return 20;
case WC_HASH_TYPE_SHA224:
return 24;
return 28;
case WC_HASH_TYPE_SHA256:
return 32;
case WC_HASH_TYPE_SHA384:
Expand Down
Loading
Loading