Skip to content
Open
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
55 changes: 55 additions & 0 deletions tests/api/test_curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,3 +547,58 @@ int test_wc_curve25519_import_private(void)
return EXPECT_RESULT();
} /* END test_wc_curve25519_import */

/*
* Test curve25519_priv_clamp_check via wc_curve25519_make_pub.
*
* RFC 7748 section 5 requires three clamping invariants on a Curve25519
* private scalar before use:
* Rule 1: bits 0-2 of byte 0 must be clear (scalar &= 0xF8)
* Rule 2: bit 7 of byte 31 must be clear (scalar &= 0x7F)
* Rule 3: bit 6 of byte 31 must be SET (scalar |= 0x40)
*
* Test vectors are derived from RFC 7748 s5; they are the independent oracle.
* Before the fix, rule 3 was not checked, so a scalar with byte[31]==0x00
* (bit 6 clear) was silently accepted -- regression covered below.
*/
int test_wc_curve25519_priv_clamp_check(void)
{
EXPECT_DECLS;
#ifdef HAVE_CURVE25519
/* Valid clamped scalar: all bytes 0x00 except byte[31] = 0x40
* (bit 7 clear, bit 6 set, byte[0] bits 0-2 clear). */
static const byte kValidPriv[CURVE25519_KEYSIZE] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40
};
byte pub[CURVE25519_KEYSIZE];
byte priv[CURVE25519_KEYSIZE];

/* Valid key succeeds. */
ExpectIntEQ(wc_curve25519_make_pub(CURVE25519_KEYSIZE, pub,
CURVE25519_KEYSIZE, kValidPriv), 0);

/* Rule 1 violation: bit 0 of byte[0] set (byte[0] = 0x01). */
XMEMCPY(priv, kValidPriv, sizeof(priv));
priv[0] |= 0x01;
ExpectIntEQ(wc_curve25519_make_pub(CURVE25519_KEYSIZE, pub,
CURVE25519_KEYSIZE, priv), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

/* Rule 2 violation: bit 7 of byte[31] set (byte[31] = 0xC0, keeping
* bit 6 set so only rule 2 is violated). */
XMEMCPY(priv, kValidPriv, sizeof(priv));
priv[CURVE25519_KEYSIZE - 1] = 0xC0;
ExpectIntEQ(wc_curve25519_make_pub(CURVE25519_KEYSIZE, pub,
CURVE25519_KEYSIZE, priv), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));

/* Rule 3 violation: bit 6 of byte[31] clear (byte[31] = 0x00).
* Regression: this was silently accepted before the fix. */
XMEMCPY(priv, kValidPriv, sizeof(priv));
priv[CURVE25519_KEYSIZE - 1] = 0x00;
ExpectIntEQ(wc_curve25519_make_pub(CURVE25519_KEYSIZE, pub,
CURVE25519_KEYSIZE, priv), WC_NO_ERR_TRACE(ECC_BAD_ARG_E));
#endif
return EXPECT_RESULT();
} /* END test_wc_curve25519_priv_clamp_check */

4 changes: 3 additions & 1 deletion tests/api/test_curve25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ int test_wc_curve25519_export_public_ex(void);
int test_wc_curve25519_export_private_raw_ex(void);
int test_wc_curve25519_import_private_raw_ex(void);
int test_wc_curve25519_import_private(void);
int test_wc_curve25519_priv_clamp_check(void);

#define TEST_CURVE25519_DECLS \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_init), \
Expand All @@ -47,6 +48,7 @@ int test_wc_curve25519_import_private(void);
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_public_ex), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_private_raw_ex), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_import_private_raw_ex), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_import_private)
TEST_DECL_GROUP("curve25519", test_wc_curve25519_import_private), \
TEST_DECL_GROUP("curve25519", test_wc_curve25519_priv_clamp_check)

#endif /* WOLFCRYPT_TEST_CURVE25519_H */
44 changes: 44 additions & 0 deletions tests/api/test_evp_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,28 @@ int test_wolfSSL_EVP_CIPHER_iv_length(void)
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
NID_chacha20_poly1305,
#endif
#ifdef WOLFSSL_AES_CFB
#ifdef WOLFSSL_AES_128
NID_aes_128_cfb128,
#endif
#ifdef WOLFSSL_AES_192
NID_aes_192_cfb128,
#endif
#ifdef WOLFSSL_AES_256
NID_aes_256_cfb128,
#endif
#endif /* WOLFSSL_AES_CFB */
#ifdef WOLFSSL_AES_OFB
#ifdef WOLFSSL_AES_128
NID_aes_128_ofb,
#endif
#ifdef WOLFSSL_AES_192
NID_aes_192_ofb,
#endif
#ifdef WOLFSSL_AES_256
NID_aes_256_ofb,
#endif
#endif /* WOLFSSL_AES_OFB */
};
int iv_lengths[] = {
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
Expand Down Expand Up @@ -546,6 +568,28 @@ int test_wolfSSL_EVP_CIPHER_iv_length(void)
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
CHACHA20_POLY1305_AEAD_IV_SIZE,
#endif
#ifdef WOLFSSL_AES_CFB
#ifdef WOLFSSL_AES_128
AES_BLOCK_SIZE,
#endif
#ifdef WOLFSSL_AES_192
AES_BLOCK_SIZE,
#endif
#ifdef WOLFSSL_AES_256
AES_BLOCK_SIZE,
#endif
#endif /* WOLFSSL_AES_CFB */
#ifdef WOLFSSL_AES_OFB
#ifdef WOLFSSL_AES_128
AES_BLOCK_SIZE,
#endif
#ifdef WOLFSSL_AES_192
AES_BLOCK_SIZE,
#endif
#ifdef WOLFSSL_AES_256
AES_BLOCK_SIZE,
#endif
#endif /* WOLFSSL_AES_OFB */
};
int i;
int nidsLen = (sizeof(nids)/sizeof(int));
Expand Down
8 changes: 6 additions & 2 deletions wolfcrypt/src/curve25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ static WC_INLINE int curve25519_priv_clamp(byte* priv)
}
static WC_INLINE int curve25519_priv_clamp_check(const byte* priv)
{
/* check that private part of key has been clamped */
/* check that private part of key has been clamped per RFC 7748 section 5:
* bits 0-2 of byte 0 must be clear (priv[0] &= 248)
* bit 7 of byte 31 must be clear (priv[31] &= 127)
* bit 6 of byte 31 must be set (priv[31] |= 64) */
int ret = 0;
if ((priv[0] & ~248) ||
(priv[CURVE25519_KEYSIZE-1] & 128)) {
(priv[CURVE25519_KEYSIZE-1] & 128) ||
!(priv[CURVE25519_KEYSIZE-1] & 64)) {
Comment thread
dgarske marked this conversation as resolved.
Comment thread
dgarske marked this conversation as resolved.
ret = ECC_BAD_ARG_E;
}
return ret;
Expand Down
83 changes: 83 additions & 0 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5674,6 +5674,34 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
return wolfSSL_EVP_aes_256_ccm();
#endif
#endif
#ifdef WOLFSSL_AES_OFB
#ifdef WOLFSSL_AES_128
case WC_NID_aes_128_ofb:
return wolfSSL_EVP_aes_128_ofb();
#endif
#ifdef WOLFSSL_AES_192
case WC_NID_aes_192_ofb:
return wolfSSL_EVP_aes_192_ofb();
#endif
#ifdef WOLFSSL_AES_256
case WC_NID_aes_256_ofb:
return wolfSSL_EVP_aes_256_ofb();
#endif
#endif /* WOLFSSL_AES_OFB */
#ifdef WOLFSSL_AES_CFB
#ifdef WOLFSSL_AES_128
case WC_NID_aes_128_cfb128:
return wolfSSL_EVP_aes_128_cfb128();
#endif
#ifdef WOLFSSL_AES_192
case WC_NID_aes_192_cfb128:
return wolfSSL_EVP_aes_192_cfb128();
#endif
#ifdef WOLFSSL_AES_256
case WC_NID_aes_256_cfb128:
return wolfSSL_EVP_aes_256_cfb128();
#endif
#endif /* WOLFSSL_AES_CFB */
#endif

#ifdef HAVE_ARIA
Expand Down Expand Up @@ -9960,6 +9988,61 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
#endif /* WOLFSSL_AES_256 */
#endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */

#ifdef WOLFSSL_AES_OFB
#ifdef WOLFSSL_AES_128
if (XSTRCMP(name, EVP_AES_128_OFB) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_192
if (XSTRCMP(name, EVP_AES_192_OFB) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_256
if (XSTRCMP(name, EVP_AES_256_OFB) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#endif /* WOLFSSL_AES_OFB */
#ifdef WOLFSSL_AES_CFB
#ifndef WOLFSSL_NO_AES_CFB_1_8
#ifdef WOLFSSL_AES_128
if (XSTRCMP(name, EVP_AES_128_CFB1) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_192
if (XSTRCMP(name, EVP_AES_192_CFB1) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_256
if (XSTRCMP(name, EVP_AES_256_CFB1) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_128
if (XSTRCMP(name, EVP_AES_128_CFB8) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_192
if (XSTRCMP(name, EVP_AES_192_CFB8) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_256
if (XSTRCMP(name, EVP_AES_256_CFB8) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
#ifdef WOLFSSL_AES_128
if (XSTRCMP(name, EVP_AES_128_CFB128) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_192
if (XSTRCMP(name, EVP_AES_192_CFB128) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#ifdef WOLFSSL_AES_256
if (XSTRCMP(name, EVP_AES_256_CFB128) == 0)
return WC_AES_BLOCK_SIZE;
#endif
#endif /* WOLFSSL_AES_CFB */

#endif
#ifdef HAVE_ARIA
if (XSTRCMP(name, EVP_ARIA_128_GCM) == 0)
Expand Down
Loading