mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 13:10:52 +02:00
Enable all-zero shared secret check for curve448/25519 by default. Change macro to opt-out macro WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK. Add unit test.
Thanks to Xiangdong Li for the report.
This commit is contained in:
@@ -755,7 +755,6 @@ WOLFSSL_ECC_BLIND_K
|
||||
WOLFSSL_ECC_GEN_REJECT_SAMPLING
|
||||
WOLFSSL_ECC_NO_SMALL_STACK
|
||||
WOLFSSL_ECC_SIGALG_PARAMS_NULL_ALLOWED
|
||||
WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
WOLFSSL_ECDSA_MATCH_HASH
|
||||
WOLFSSL_ECDSA_SET_K_ONE_LOOP
|
||||
WOLFSSL_EC_POINT_CMP_JACOBIAN
|
||||
@@ -832,6 +831,7 @@ WOLFSSL_NO_DEL_HANDLE
|
||||
WOLFSSL_NO_DER_TO_PEM
|
||||
WOLFSSL_NO_DH186
|
||||
WOLFSSL_NO_DTLS_SIZE_CHECK
|
||||
WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
WOLFSSL_NO_ETM_ALERT
|
||||
WOLFSSL_NO_FENCE
|
||||
WOLFSSL_NO_ISSUERHASH_TDPEER
|
||||
|
||||
@@ -353,6 +353,51 @@ int test_wc_curve25519_shared_secret_ex(void)
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_curve25519_shared_secret_ex */
|
||||
|
||||
/*
|
||||
* Testing that wc_curve25519_shared_secret_ex rejects an all-zero shared
|
||||
* secret (RFC 7748 section 6.1). This is the default behavior; users that
|
||||
* need the legacy behavior can opt out with WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK.
|
||||
*/
|
||||
int test_wc_curve25519_shared_secret_zero_check(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT) && \
|
||||
!defined(WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK)
|
||||
curve25519_key private_key;
|
||||
curve25519_key public_key;
|
||||
WC_RNG rng;
|
||||
byte out[CURVE25519_KEYSIZE];
|
||||
word32 outLen = sizeof(out);
|
||||
/* All-zero public key is a low-order point that yields an all-zero
|
||||
* shared secret for any private key. */
|
||||
byte zero_pub[CURVE25519_KEYSIZE];
|
||||
|
||||
XMEMSET(&rng, 0, sizeof(WC_RNG));
|
||||
XMEMSET(zero_pub, 0, sizeof(zero_pub));
|
||||
|
||||
ExpectIntEQ(wc_curve25519_init(&private_key), 0);
|
||||
ExpectIntEQ(wc_curve25519_init(&public_key), 0);
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
#ifdef WOLFSSL_CURVE25519_BLINDING
|
||||
ExpectIntEQ(wc_curve25519_set_rng(&private_key, &rng), 0);
|
||||
#endif
|
||||
|
||||
ExpectIntEQ(wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &private_key),
|
||||
0);
|
||||
ExpectIntEQ(wc_curve25519_import_public_ex(zero_pub, sizeof(zero_pub),
|
||||
&public_key, EC25519_LITTLE_ENDIAN), 0);
|
||||
|
||||
ExpectIntEQ(wc_curve25519_shared_secret_ex(&private_key, &public_key, out,
|
||||
&outLen, EC25519_BIG_ENDIAN),
|
||||
WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E));
|
||||
|
||||
DoExpectIntEQ(wc_FreeRng(&rng), 0);
|
||||
wc_curve25519_free(&private_key);
|
||||
wc_curve25519_free(&public_key);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_curve25519_shared_secret_zero_check */
|
||||
|
||||
/*
|
||||
* Testing wc_curve25519_make_pub
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ int test_wc_curve25519_export_key_raw(void);
|
||||
int test_wc_curve25519_export_key_raw_ex(void);
|
||||
int test_wc_curve25519_make_key(void);
|
||||
int test_wc_curve25519_shared_secret_ex(void);
|
||||
int test_wc_curve25519_shared_secret_zero_check(void);
|
||||
int test_wc_curve25519_make_pub(void);
|
||||
int test_wc_curve25519_export_public_ex(void);
|
||||
int test_wc_curve25519_export_private_raw_ex(void);
|
||||
@@ -45,6 +46,7 @@ int test_wc_Curve25519KeyToDer_oneasymkey_version(void);
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_key_raw_ex), \
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_key), \
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_ex), \
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_shared_secret_zero_check),\
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_make_pub), \
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_public_ex), \
|
||||
TEST_DECL_GROUP("curve25519", test_wc_curve25519_export_private_raw_ex), \
|
||||
|
||||
@@ -116,6 +116,48 @@ int test_wc_curve448_shared_secret_ex(void)
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_curve448_shared_secret_ex */
|
||||
|
||||
/*
|
||||
* Testing that wc_curve448_shared_secret_ex rejects an all-zero shared
|
||||
* secret (RFC 7748 section 6.2). This is the default behavior; users that
|
||||
* need the legacy behavior can opt out with WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK.
|
||||
*/
|
||||
int test_wc_curve448_shared_secret_zero_check(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT) && \
|
||||
defined(HAVE_CURVE448_SHARED_SECRET) && \
|
||||
!defined(WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK)
|
||||
curve448_key private_key;
|
||||
curve448_key public_key;
|
||||
WC_RNG rng;
|
||||
byte out[CURVE448_KEY_SIZE];
|
||||
word32 outLen = sizeof(out);
|
||||
/* All-zero public key is a low-order point that yields an all-zero
|
||||
* shared secret for any private key. */
|
||||
byte zero_pub[CURVE448_PUB_KEY_SIZE];
|
||||
|
||||
XMEMSET(&rng, 0, sizeof(WC_RNG));
|
||||
XMEMSET(zero_pub, 0, sizeof(zero_pub));
|
||||
|
||||
ExpectIntEQ(wc_curve448_init(&private_key), 0);
|
||||
ExpectIntEQ(wc_curve448_init(&public_key), 0);
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
|
||||
ExpectIntEQ(wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &private_key), 0);
|
||||
ExpectIntEQ(wc_curve448_import_public_ex(zero_pub, sizeof(zero_pub),
|
||||
&public_key, EC448_LITTLE_ENDIAN), 0);
|
||||
|
||||
ExpectIntEQ(wc_curve448_shared_secret_ex(&private_key, &public_key, out,
|
||||
&outLen, EC448_BIG_ENDIAN),
|
||||
WC_NO_ERR_TRACE(ECC_OUT_OF_RANGE_E));
|
||||
|
||||
DoExpectIntEQ(wc_FreeRng(&rng), 0);
|
||||
wc_curve448_free(&private_key);
|
||||
wc_curve448_free(&public_key);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
} /* END test_wc_curve448_shared_secret_zero_check */
|
||||
|
||||
/*
|
||||
* Testing test_wc_curve448_export_public_ex
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
int test_wc_curve448_make_key(void);
|
||||
int test_wc_curve448_shared_secret_ex(void);
|
||||
int test_wc_curve448_shared_secret_zero_check(void);
|
||||
int test_wc_curve448_export_public_ex(void);
|
||||
int test_wc_curve448_export_private_raw_ex(void);
|
||||
int test_wc_curve448_export_key_raw(void);
|
||||
@@ -39,6 +40,7 @@ int test_wc_Curve448PrivateKeyToDer_oneasymkey_version(void);
|
||||
#define TEST_CURVE448_DECLS \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_make_key), \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_shared_secret_ex), \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_shared_secret_zero_check), \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_export_public_ex), \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_export_private_raw_ex), \
|
||||
TEST_DECL_GROUP("curve448", test_wc_curve448_export_key_raw), \
|
||||
|
||||
@@ -637,7 +637,7 @@ static int wc_curve25519_shared_secret_nb(curve25519_key* privKey,
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
{
|
||||
int i;
|
||||
byte t = 0;
|
||||
@@ -649,13 +649,13 @@ static int wc_curve25519_shared_secret_nb(curve25519_key* privKey,
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
else
|
||||
#endif /* WOLFSSL_ECDHX_SHARED_NOT_ZERO */
|
||||
#endif /* !WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK */
|
||||
{
|
||||
curve25519_copy_point(out, privKey->nb_ctx->o.point, endian);
|
||||
*outlen = CURVE25519_KEYSIZE;
|
||||
ret = 0;
|
||||
}
|
||||
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@@ -761,7 +761,7 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
|
||||
#endif
|
||||
}
|
||||
#endif /* FREESCALE_LTC_ECC */
|
||||
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
if (ret == 0) {
|
||||
int i;
|
||||
byte t = 0;
|
||||
@@ -772,7 +772,7 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
|
||||
ret = ECC_OUT_OF_RANGE_E;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_ECDHX_SHARED_NOT_ZERO */
|
||||
#endif /* !WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK */
|
||||
if (ret == 0) {
|
||||
curve25519_copy_point(out, o.point, endian);
|
||||
*outlen = CURVE25519_KEYSIZE;
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
* (when HAVE_CURVE448 is enabled)
|
||||
* HAVE_CURVE448_KEY_EXPORT: Enable Curve448 key export default: on
|
||||
* HAVE_CURVE448_KEY_IMPORT: Enable Curve448 key import default: on
|
||||
* WOLFSSL_ECDHX_SHARED_NOT_ZERO: Check ECDH shared secret != 0 default: off
|
||||
* WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK: Skip ECDH shared secret != 0 check
|
||||
* default: off
|
||||
*/
|
||||
|
||||
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
|
||||
@@ -176,7 +177,7 @@ 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
|
||||
#ifndef WOLFSSL_NO_ECDHX_SHARED_ZERO_CHECK
|
||||
if (ret == 0) {
|
||||
byte t = 0;
|
||||
for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) {
|
||||
|
||||
Reference in New Issue
Block a user