mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 17:50:48 +02:00
Properly reject Ed448 identity public key
Reported by: Nicholas Carlini <npc@anthropic.com>
This commit is contained in:
+37
@@ -34758,6 +34758,42 @@ static int test_DhAgree_rejects_p_minus_1(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Test: Ed448 must reject identity public key (0,1) */
|
||||
static int test_ed448_rejects_identity_key(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_ED448) && !defined(HAVE_SELFTEST) && \
|
||||
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
|
||||
ed448_key key;
|
||||
byte identity[ED448_PUB_KEY_SIZE];
|
||||
byte forged_sig[ED448_SIG_SIZE];
|
||||
const byte msg[] = "test message";
|
||||
int res = 0;
|
||||
|
||||
XMEMSET(identity, 0, sizeof(identity));
|
||||
identity[0] = 0x01; /* identity (0,1) encoding */
|
||||
|
||||
XMEMSET(forged_sig, 0, sizeof(forged_sig));
|
||||
forged_sig[0] = 0x01; /* R = identity, S = 0 */
|
||||
|
||||
ExpectIntEQ(wc_ed448_init(&key), 0);
|
||||
|
||||
/* The identity public key must be rejected at import time. */
|
||||
ExpectIntNE(wc_ed448_import_public(identity, sizeof(identity), &key), 0);
|
||||
|
||||
/* If import somehow succeeded, verify must also reject the forgery. */
|
||||
if (EXPECT_SUCCESS() && key.pubKeySet) {
|
||||
int verifyRet = wc_ed448_verify_msg(forged_sig, sizeof(forged_sig),
|
||||
msg, sizeof(msg) - 1,
|
||||
&res, &key, NULL, 0);
|
||||
ExpectTrue(verifyRet != 0 || res == 0);
|
||||
}
|
||||
|
||||
wc_ed448_free(&key);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_fileAccess),
|
||||
|
||||
@@ -35573,6 +35609,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_TLS_DECLS,
|
||||
TEST_DECL(test_wc_DhSetNamedKey),
|
||||
TEST_DECL(test_DhAgree_rejects_p_minus_1),
|
||||
TEST_DECL(test_ed448_rejects_identity_key),
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
|
||||
TEST_DECL(test_sniffer_chain_input_overflow),
|
||||
|
||||
+29
-3
@@ -711,6 +711,18 @@ static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
|
||||
if (i == -1)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Reject identity public key (0,1): 0x01 followed by 56 zero bytes. */
|
||||
{
|
||||
int isIdentity = (key->p[0] == 0x01);
|
||||
int j;
|
||||
for (j = 1; j < ED448_PUB_KEY_SIZE && isIdentity; j++) {
|
||||
if (key->p[j] != 0x00)
|
||||
isIdentity = 0;
|
||||
}
|
||||
if (isIdentity)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* uncompress A (public key), test if valid, and negate it */
|
||||
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -1335,14 +1347,28 @@ int wc_ed448_check_key(ed448_key* key)
|
||||
}
|
||||
/* No private key, check Y is valid. */
|
||||
else if ((ret == 0) && (!key->privKeySet)) {
|
||||
/* Verify that Q is not identity element 0.
|
||||
* 0 has no representation for Ed448. */
|
||||
/* Reject the identity element (0, 1).
|
||||
* Encoding: 0x01 followed by 56 zero bytes. */
|
||||
{
|
||||
int isIdentity = 1;
|
||||
int i;
|
||||
if (key->p[0] != 0x01)
|
||||
isIdentity = 0;
|
||||
for (i = 1; i < ED448_PUB_KEY_SIZE && isIdentity; i++) {
|
||||
if (key->p[i] != 0x00)
|
||||
isIdentity = 0;
|
||||
}
|
||||
if (isIdentity) {
|
||||
WOLFSSL_MSG("Ed448 public key is the identity element");
|
||||
ret = PUBLIC_KEY_E;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that xQ and yQ are integers in the interval [0, p - 1].
|
||||
* Only have yQ so check that ordinate.
|
||||
* p = 2^448-2^224-1 = 0xff..fe..ff
|
||||
*/
|
||||
{
|
||||
if (ret == 0) {
|
||||
int i;
|
||||
ret = PUBLIC_KEY_E;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user