Skip to content

Commit efe6ad4

Browse files
authored
Merge pull request #10116 from Frauschi/zd21457
Additional fixes
2 parents 9347c89 + 580cbe2 commit efe6ad4

File tree

5 files changed

+316
-4
lines changed

5 files changed

+316
-4
lines changed

src/dtls13.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,14 @@ static Dtls13RecordNumber* Dtls13NewRecordNumber(w64wrapper epoch,
720720
return rn;
721721
}
722722

723+
#ifndef DTLS13_MAX_ACK_RECORDS
724+
#define DTLS13_MAX_ACK_RECORDS 512
725+
#endif
726+
723727
int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq)
724728
{
725729
Dtls13RecordNumber* rn;
730+
int count;
726731

727732
WOLFSSL_ENTER("Dtls13RtxAddAck");
728733

@@ -741,7 +746,9 @@ int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq)
741746
return 0; /* list full, silently drop */
742747
}
743748

749+
count = 0;
744750
for (; cur != NULL; prevNext = &cur->next, cur = cur->next) {
751+
count++;
745752
if (w64Equal(cur->epoch, epoch) && w64Equal(cur->seq, seq)) {
746753
/* already in list. no duplicates. */
747754
#ifdef WOLFSSL_RW_THREADED
@@ -756,6 +763,16 @@ int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq)
756763
}
757764
}
758765

766+
/* Cap the ACK list to prevent word16 overflow in
767+
* Dtls13GetAckListLength and bound memory consumption */
768+
if (count >= DTLS13_MAX_ACK_RECORDS) {
769+
WOLFSSL_MSG("DTLS 1.3 ACK list full, dropping record");
770+
#ifdef WOLFSSL_RW_THREADED
771+
wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
772+
#endif
773+
return 0;
774+
}
775+
759776
rn = Dtls13NewRecordNumber(epoch, seq, ssl->heap);
760777
if (rn == NULL) {
761778
#ifdef WOLFSSL_RW_THREADED

tests/api.c

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34686,6 +34686,256 @@ static int test_sniffer_chain_input_overflow(void)
3468634686
}
3468734687
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_CHAIN_INPUT */
3468834688

34689+
/* Test: wc_DhAgree must reject p-1 as peer public key.
34690+
* ffdhe2048 p ends with ...FFFFFFFFFFFFFFFF so p-1 ends ...FFFFFFFFFFFFFFFE */
34691+
static int test_DhAgree_rejects_p_minus_1(void)
34692+
{
34693+
EXPECT_DECLS;
34694+
#if !defined(HAVE_SELFTEST) && !defined(NO_DH) && \
34695+
defined(HAVE_FFDHE_2048) && !defined(WOLFSSL_NO_MALLOC) && \
34696+
(!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
34697+
DhKey key;
34698+
WC_RNG rng;
34699+
byte priv[256], pub[256], agree[256];
34700+
word32 privSz = sizeof(priv), pubSz = sizeof(pub), agreeSz;
34701+
34702+
/* ffdhe2048 p - copied from wolfcrypt/src/dh.c dh_ffdhe2048_p.
34703+
* p ends with 0xFF*8 so p-1 ends with ...0xFE */
34704+
static const byte ffdhe2048_p[256] = {
34705+
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
34706+
0xAD,0xF8,0x54,0x58,0xA2,0xBB,0x4A,0x9A,
34707+
0xAF,0xDC,0x56,0x20,0x27,0x3D,0x3C,0xF1,
34708+
0xD8,0xB9,0xC5,0x83,0xCE,0x2D,0x36,0x95,
34709+
0xA9,0xE1,0x36,0x41,0x14,0x64,0x33,0xFB,
34710+
0xCC,0x93,0x9D,0xCE,0x24,0x9B,0x3E,0xF9,
34711+
0x7D,0x2F,0xE3,0x63,0x63,0x0C,0x75,0xD8,
34712+
0xF6,0x81,0xB2,0x02,0xAE,0xC4,0x61,0x7A,
34713+
0xD3,0xDF,0x1E,0xD5,0xD5,0xFD,0x65,0x61,
34714+
0x24,0x33,0xF5,0x1F,0x5F,0x06,0x6E,0xD0,
34715+
0x85,0x63,0x65,0x55,0x3D,0xED,0x1A,0xF3,
34716+
0xB5,0x57,0x13,0x5E,0x7F,0x57,0xC9,0x35,
34717+
0x98,0x4F,0x0C,0x70,0xE0,0xE6,0x8B,0x77,
34718+
0xE2,0xA6,0x89,0xDA,0xF3,0xEF,0xE8,0x72,
34719+
0x1D,0xF1,0x58,0xA1,0x36,0xAD,0xE7,0x35,
34720+
0x30,0xAC,0xCA,0x4F,0x48,0x3A,0x79,0x7A,
34721+
0xBC,0x0A,0xB1,0x82,0xB3,0x24,0xFB,0x61,
34722+
0xD1,0x08,0xA9,0x4B,0xB2,0xC8,0xE3,0xFB,
34723+
0xB9,0x6A,0xDA,0xB7,0x60,0xD7,0xF4,0x68,
34724+
0x1D,0x4F,0x42,0xA3,0xDE,0x39,0x4D,0xF4,
34725+
0xAE,0x56,0xED,0xE7,0x63,0x72,0xBB,0x19,
34726+
0x0B,0x07,0xA7,0xC8,0xEE,0x0A,0x6D,0x70,
34727+
0x9E,0x02,0xFC,0xE1,0xCD,0xF7,0xE2,0xEC,
34728+
0xC0,0x34,0x04,0xCD,0x28,0x34,0x2F,0x61,
34729+
0x91,0x72,0xFE,0x9C,0xE9,0x85,0x83,0xFF,
34730+
0x8E,0x4F,0x12,0x32,0xEE,0xF2,0x81,0x83,
34731+
0xC3,0xFE,0x3B,0x1B,0x4C,0x6F,0xAD,0x73,
34732+
0x3B,0xB5,0xFC,0xBC,0x2E,0xC2,0x20,0x05,
34733+
0xC5,0x8E,0xF1,0x83,0x7D,0x16,0x83,0xB2,
34734+
0xC6,0xF3,0x4A,0x26,0xC1,0xB2,0xEF,0xFA,
34735+
0x88,0x6B,0x42,0x38,0x61,0x28,0x5C,0x97,
34736+
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
34737+
};
34738+
byte pMinus1[256];
34739+
34740+
ExpectIntEQ(wc_InitRng(&rng), 0);
34741+
ExpectIntEQ(wc_InitDhKey(&key), 0);
34742+
ExpectIntEQ(wc_DhSetNamedKey(&key, WC_FFDHE_2048), 0);
34743+
ExpectIntEQ(wc_DhGenerateKeyPair(&key, &rng, priv, &privSz,
34744+
pub, &pubSz), 0);
34745+
34746+
/* Construct p-1: last byte FF -> FE */
34747+
XMEMCPY(pMinus1, ffdhe2048_p, sizeof(ffdhe2048_p));
34748+
pMinus1[255] -= 1;
34749+
34750+
/* wc_DhAgree must reject p-1 */
34751+
agreeSz = sizeof(agree);
34752+
ExpectIntNE(wc_DhAgree(&key, agree, &agreeSz, priv, privSz,
34753+
pMinus1, sizeof(pMinus1)), 0);
34754+
34755+
wc_FreeDhKey(&key);
34756+
wc_FreeRng(&rng);
34757+
#endif
34758+
return EXPECT_RESULT();
34759+
}
34760+
34761+
/* Test: Ed448 must reject identity public key (0,1) */
34762+
static int test_ed448_rejects_identity_key(void)
34763+
{
34764+
EXPECT_DECLS;
34765+
#if defined(HAVE_ED448) && !defined(HAVE_SELFTEST) && \
34766+
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
34767+
ed448_key key;
34768+
byte identity[ED448_PUB_KEY_SIZE];
34769+
byte forged_sig[ED448_SIG_SIZE];
34770+
const byte msg[] = "test message";
34771+
int res = 0;
34772+
34773+
XMEMSET(identity, 0, sizeof(identity));
34774+
identity[0] = 0x01; /* identity (0,1) encoding */
34775+
34776+
XMEMSET(forged_sig, 0, sizeof(forged_sig));
34777+
forged_sig[0] = 0x01; /* R = identity, S = 0 */
34778+
34779+
ExpectIntEQ(wc_ed448_init(&key), 0);
34780+
34781+
/* The identity public key must be rejected at import time. */
34782+
ExpectIntNE(wc_ed448_import_public(identity, sizeof(identity), &key), 0);
34783+
34784+
/* If import somehow succeeded, verify must also reject the forgery. */
34785+
if (EXPECT_SUCCESS() && key.pubKeySet) {
34786+
int verifyRet = wc_ed448_verify_msg(forged_sig, sizeof(forged_sig),
34787+
msg, sizeof(msg) - 1,
34788+
&res, &key, NULL, 0);
34789+
ExpectTrue(verifyRet != 0 || res == 0);
34790+
}
34791+
34792+
wc_ed448_free(&key);
34793+
#endif
34794+
return EXPECT_RESULT();
34795+
}
34796+
34797+
/* Test: wc_PKCS7_DecodeEncryptedData must respect outputSz.
34798+
* 588-byte EncryptedData blob: 496 bytes of 'A' encrypted with
34799+
* AES-256-CBC under all-zero key/IV. Decrypted content is 496 bytes,
34800+
* but we pass a 128-byte output buffer. Must return BUFFER_E. */
34801+
static int test_pkcs7_decode_encrypted_outputsz(void)
34802+
{
34803+
EXPECT_DECLS;
34804+
#if defined(HAVE_PKCS7) && !defined(NO_AES) && defined(HAVE_AES_CBC) && \
34805+
!defined(WOLFSSL_NO_MALLOC) && defined(WOLFSSL_AES_256)
34806+
wc_PKCS7* p7 = NULL;
34807+
byte key[32];
34808+
byte out[128]; /* smaller than 496-byte decrypted content */
34809+
34810+
static const byte encBlob[] = {
34811+
0x30,0x82,0x02,0x48,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
34812+
0x01,0x07,0x06,0xa0,0x82,0x02,0x39,0x30,0x82,0x02,0x35,0x02,
34813+
0x01,0x00,0x30,0x82,0x02,0x2e,0x06,0x09,0x2a,0x86,0x48,0x86,
34814+
0xf7,0x0d,0x01,0x07,0x01,0x30,0x1d,0x06,0x09,0x60,0x86,0x48,
34815+
0x01,0x65,0x03,0x04,0x01,0x2a,0x04,0x10,0x00,0x00,0x00,0x00,
34816+
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34817+
0x80,0x82,0x02,0x00,0x7e,0x0e,0x75,0x77,0xef,0x9c,0x30,0xa6,
34818+
0xbf,0x0b,0x25,0xe0,0x62,0x1e,0x82,0x7e,0x76,0xf7,0x57,0xef,
34819+
0x12,0x71,0xc5,0x74,0x0e,0x60,0xc3,0x3c,0x8e,0xc3,0xce,0x70,
34820+
0xbd,0x3c,0xb4,0x60,0x76,0xb1,0xea,0xb5,0x4b,0xc1,0xfe,0x5b,
34821+
0x88,0xfa,0x43,0x46,0x03,0x28,0x9d,0xab,0x3d,0xb5,0x88,0x50,
34822+
0x07,0xfc,0x3c,0xc9,0x49,0x4d,0x68,0x97,0xb1,0x59,0xb6,0x35,
34823+
0xa1,0x68,0x80,0xb0,0x8f,0xb2,0x21,0x9b,0xfc,0xd8,0xf0,0x67,
34824+
0xbc,0x4b,0x9b,0x28,0x1c,0x3b,0xa0,0x40,0x76,0x8f,0x1f,0x9f,
34825+
0x87,0xe6,0xe4,0xa5,0xdc,0x9a,0x9a,0x84,0x86,0xff,0x43,0x8a,
34826+
0x57,0x8d,0x97,0xd2,0x8f,0x67,0x90,0xd8,0x4f,0x0f,0x0d,0xac,
34827+
0x56,0x6d,0x51,0x33,0xa3,0x37,0x9e,0xe9,0xbf,0x07,0xab,0x93,
34828+
0xbc,0xbe,0xc1,0x64,0x07,0x30,0xf0,0xff,0x89,0x0a,0x36,0x1c,
34829+
0xc8,0xe9,0xae,0x24,0x1f,0x95,0x5c,0xa1,0x8a,0x3e,0x15,0x86,
34830+
0x49,0x70,0x55,0xc2,0xa5,0x90,0xb9,0xda,0x2b,0x97,0x6f,0x5f,
34831+
0x60,0x61,0xc9,0xcf,0x4d,0x3a,0xb1,0xe4,0x9f,0x37,0x0f,0xf3,
34832+
0xba,0x85,0x04,0x52,0x68,0x00,0x47,0x3d,0x83,0xc1,0x3f,0xc6,
34833+
0x70,0x97,0xc1,0x0c,0xc0,0x0b,0xa2,0xcb,0x8c,0x88,0xb5,0x01,
34834+
0x29,0x7f,0x7e,0xd2,0x46,0x24,0x82,0x92,0x28,0xdd,0x49,0x53,
34835+
0x0f,0x76,0xad,0x4b,0x81,0x85,0x3a,0x9f,0xda,0x0d,0x69,0xe2,
34836+
0x57,0xb9,0xe9,0xfa,0x53,0xed,0x20,0x6f,0x62,0x43,0x1d,0x21,
34837+
0xa9,0x53,0x3d,0xd5,0xb9,0x1a,0x4b,0x3e,0xb7,0x05,0x87,0xb6,
34838+
0xe3,0xfe,0x03,0x09,0xe1,0x74,0x34,0x42,0x84,0xb1,0x06,0xf9,
34839+
0xfe,0x64,0xc1,0xd2,0xce,0x3d,0x29,0xf4,0x94,0xb8,0xfc,0xbe,
34840+
0xb1,0x90,0xd6,0x38,0x61,0x4e,0x43,0x36,0x4e,0x27,0x87,0xd3,
34841+
0x24,0xdc,0x34,0xf0,0x28,0x2d,0xc8,0xff,0x89,0x9f,0xeb,0xee,
34842+
0x0d,0x45,0xfb,0xc5,0x53,0xd3,0xdf,0xcb,0xf8,0xeb,0x7e,0xcb,
34843+
0x2a,0xd7,0xa2,0xd6,0x6a,0xf1,0xb8,0x24,0xa1,0x05,0x16,0x56,
34844+
0x2e,0x03,0xfe,0x21,0x19,0x36,0x8a,0xeb,0x50,0x8d,0x42,0x31,
34845+
0x1d,0xb3,0x0a,0x13,0x1d,0x16,0x09,0x0b,0x40,0x4e,0x90,0x78,
34846+
0xbf,0x41,0x5f,0x4d,0xd9,0xce,0x91,0xaa,0xd0,0x38,0x5c,0xfb,
34847+
0xc4,0x9f,0x55,0x4e,0x04,0x9d,0xd0,0xca,0x74,0x3c,0x6c,0x01,
34848+
0x1b,0x84,0x76,0xfa,0xba,0x5d,0x2d,0x35,0x7e,0xe3,0x37,0x8b,
34849+
0x72,0x0a,0xbb,0xa4,0x4d,0x56,0x2b,0x3b,0x9f,0x5a,0xa0,0xe3,
34850+
0x60,0x26,0x65,0x09,0xed,0xfc,0x10,0x0c,0xa1,0x4f,0x12,0x76,
34851+
0xe2,0x4c,0xbd,0x1b,0x67,0xb4,0xb4,0x54,0x5c,0x38,0x47,0x8b,
34852+
0x7e,0x35,0x8e,0x4d,0x4e,0xef,0x91,0x3f,0xff,0x16,0x0a,0x42,
34853+
0x0b,0xe5,0x28,0x26,0x24,0x9f,0x6f,0xb4,0x63,0x8a,0xa1,0x52,
34854+
0x22,0x3a,0xdb,0xd9,0x8e,0x76,0x6e,0x6a,0xa9,0xa1,0xec,0xf2,
34855+
0x9c,0x58,0xf8,0x6b,0xdd,0xf2,0xf8,0x2d,0xcb,0x8c,0x96,0xda,
34856+
0xb4,0x9c,0x44,0xdc,0xab,0x43,0x2c,0x22,0xf3,0xfe,0x1a,0xb9,
34857+
0x3b,0x82,0x30,0xa2,0xc7,0xef,0x52,0x08,0x7b,0x4f,0x3f,0x7a,
34858+
0x7e,0x28,0xd7,0x67,0xb9,0xb1,0x69,0x9b,0x96,0x3e,0xc5,0xe4,
34859+
0x45,0xb0,0x23,0x75,0x00,0xda,0xee,0xdb,0x6d,0xa9,0xe7,0x98
34860+
};
34861+
34862+
XMEMSET(key, 0, sizeof(key));
34863+
34864+
p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
34865+
ExpectNotNull(p7);
34866+
if (p7 != NULL) {
34867+
p7->encryptionKey = key;
34868+
p7->encryptionKeySz = sizeof(key);
34869+
34870+
/* 496-byte content into 128-byte buffer must return BUFFER_E */
34871+
ExpectIntLT(wc_PKCS7_DecodeEncryptedData(p7, (byte*)encBlob,
34872+
(word32)sizeof(encBlob), out, sizeof(out)), 0);
34873+
34874+
wc_PKCS7_Free(p7);
34875+
}
34876+
#endif
34877+
return EXPECT_RESULT();
34878+
}
34879+
34880+
/* Dummy ORI callback for PKCS#7 ORI overflow test */
34881+
#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC)
34882+
static int test_dummy_ori_cb(wc_PKCS7* pkcs7, byte* oriType, word32 oriTypeSz,
34883+
byte* oriValue, word32 oriValueSz,
34884+
byte* decryptedKey, word32* decryptedKeySz,
34885+
void* ctx)
34886+
{
34887+
(void)pkcs7; (void)oriType; (void)oriTypeSz;
34888+
(void)oriValue; (void)oriValueSz;
34889+
(void)decryptedKey; (void)decryptedKeySz; (void)ctx;
34890+
return -1;
34891+
}
34892+
#endif
34893+
34894+
/* Test: PKCS#7 ORI must reject OID larger than MAX_OID_SZ (32) */
34895+
static int test_pkcs7_ori_oversized_oid(void)
34896+
{
34897+
EXPECT_DECLS;
34898+
#if defined(HAVE_PKCS7) && !defined(WOLFSSL_NO_MALLOC)
34899+
wc_PKCS7* p7 = NULL;
34900+
byte out[256];
34901+
34902+
/* EnvelopedData with [4] IMPLICIT ORI containing an 80-byte OID */
34903+
static const byte poc[] = {
34904+
0x30, 0x6b,
34905+
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03,
34906+
0xa0, 0x5e,
34907+
0x30, 0x5c,
34908+
0x02, 0x01, 0x00,
34909+
0x31, 0x57,
34910+
0xa4, 0x55,
34911+
0x06, 0x50,
34912+
0x2a,
34913+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34914+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34915+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34916+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34917+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34918+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34919+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34920+
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
34921+
0x04, 0x01, 0x00
34922+
};
34923+
34924+
p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
34925+
ExpectNotNull(p7);
34926+
if (p7 != NULL) {
34927+
wc_PKCS7_SetOriDecryptCb(p7, test_dummy_ori_cb);
34928+
34929+
/* Must return error (ASN_PARSE_E), not overflow the stack */
34930+
ExpectIntLT(wc_PKCS7_DecodeEnvelopedData(p7, (byte*)poc, sizeof(poc),
34931+
out, sizeof(out)), 0);
34932+
34933+
wc_PKCS7_Free(p7);
34934+
}
34935+
#endif
34936+
return EXPECT_RESULT();
34937+
}
34938+
3468934939
TEST_CASE testCases[] = {
3469034940
TEST_DECL(test_fileAccess),
3469134941

@@ -35500,6 +35750,10 @@ TEST_CASE testCases[] = {
3550035750
TEST_DECL(test_ocsp_responder),
3550135751
TEST_TLS_DECLS,
3550235752
TEST_DECL(test_wc_DhSetNamedKey),
35753+
TEST_DECL(test_DhAgree_rejects_p_minus_1),
35754+
TEST_DECL(test_ed448_rejects_identity_key),
35755+
TEST_DECL(test_pkcs7_decode_encrypted_outputsz),
35756+
TEST_DECL(test_pkcs7_ori_oversized_oid),
3550335757

3550435758
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
3550535759
TEST_DECL(test_sniffer_chain_input_overflow),

wolfcrypt/src/dh.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2030,12 +2030,13 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
20302030
WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
20312031
return DH_CHECK_PRIV_E;
20322032
}
2033+
#endif
20332034

2035+
/* Always validate peer public key (2 <= y <= p-2) per SP 800-56A */
20342036
if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
20352037
WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
20362038
return DH_CHECK_PUB_E;
20372039
}
2038-
#endif
20392040

20402041
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
20412042
y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);

wolfcrypt/src/ed448.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,18 @@ static int ed448_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
716716
if (i == -1)
717717
return BAD_FUNC_ARG;
718718

719+
/* Reject identity public key (0,1): 0x01 followed by 56 zero bytes. */
720+
{
721+
int isIdentity = (key->p[0] == 0x01);
722+
int j;
723+
for (j = 1; j < ED448_PUB_KEY_SIZE && isIdentity; j++) {
724+
if (key->p[j] != 0x00)
725+
isIdentity = 0;
726+
}
727+
if (isIdentity)
728+
return BAD_FUNC_ARG;
729+
}
730+
719731
/* uncompress A (public key), test if valid, and negate it */
720732
if (ge448_from_bytes_negate_vartime(&A, key->p) != 0)
721733
return BAD_FUNC_ARG;
@@ -1346,14 +1358,28 @@ int wc_ed448_check_key(ed448_key* key)
13461358
}
13471359
/* No private key, check Y is valid. */
13481360
else if ((ret == 0) && (!key->privKeySet)) {
1349-
/* Verify that Q is not identity element 0.
1350-
* 0 has no representation for Ed448. */
1361+
/* Reject the identity element (0, 1).
1362+
* Encoding: 0x01 followed by 56 zero bytes. */
1363+
{
1364+
int isIdentity = 1;
1365+
int i;
1366+
if (key->p[0] != 0x01)
1367+
isIdentity = 0;
1368+
for (i = 1; i < ED448_PUB_KEY_SIZE && isIdentity; i++) {
1369+
if (key->p[i] != 0x00)
1370+
isIdentity = 0;
1371+
}
1372+
if (isIdentity) {
1373+
WOLFSSL_MSG("Ed448 public key is the identity element");
1374+
ret = PUBLIC_KEY_E;
1375+
}
1376+
}
13511377

13521378
/* Verify that xQ and yQ are integers in the interval [0, p - 1].
13531379
* Only have yQ so check that ordinate.
13541380
* p = 2^448-2^224-1 = 0xff..fe..ff
13551381
*/
1356-
{
1382+
if (ret == 0) {
13571383
int i;
13581384
ret = PUBLIC_KEY_E;
13591385

0 commit comments

Comments
 (0)