Skip to content

Commit 06bc366

Browse files
MarkAtwoodclaude
andcommitted
Fix AES-EAX to allow empty plaintext
The one-shot wc_AesEaxEncryptAuth/wc_AesEaxDecryptAuth and the incremental wc_AesEaxEncryptUpdate/wc_AesEaxDecryptUpdate functions unconditionally required non-NULL out/in/authIn pointers, returning BAD_FUNC_ARG even when the corresponding length was 0. EAX mode with empty plaintext is a valid authentication-only operation that produces just an authentication tag (OMAC over nonce and AAD). This is permitted by the EAX specification (Bellare, Rogaway, Wagner 2004) and exercised by Wycheproof test vectors. Fix: gate NULL pointer checks on the corresponding length being > 0. In the incremental Update functions, skip the AES-CTR and CMAC ciphertext update when inSz is 0 to avoid passing NULL to wc_AesCtrEncrypt (which also rejects NULL unconditionally). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c4c71ee commit 06bc366

1 file changed

Lines changed: 38 additions & 32 deletions

File tree

wolfcrypt/src/aes.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16779,8 +16779,9 @@ int wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
1677916779
int ret;
1678016780
int eaxInited = 0;
1678116781

16782-
if (key == NULL || out == NULL || in == NULL || nonce == NULL
16783-
|| authTag == NULL || authIn == NULL) {
16782+
if (key == NULL || nonce == NULL || authTag == NULL
16783+
|| (inSz > 0 && (out == NULL || in == NULL))
16784+
|| (authInSz > 0 && authIn == NULL)) {
1678416785
return BAD_FUNC_ARG;
1678516786
}
1678616787

@@ -16842,8 +16843,9 @@ int wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
1684216843
int ret;
1684316844
int eaxInited = 0;
1684416845

16845-
if (key == NULL || out == NULL || in == NULL || nonce == NULL
16846-
|| authTag == NULL || authIn == NULL) {
16846+
if (key == NULL || nonce == NULL || authTag == NULL
16847+
|| (inSz > 0 && (out == NULL || in == NULL))
16848+
|| (authInSz > 0 && authIn == NULL)) {
1684716849
return BAD_FUNC_ARG;
1684816850
}
1684916851

@@ -17031,24 +17033,26 @@ int wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
1703117033
{
1703217034
int ret;
1703317035

17034-
if (eax == NULL || out == NULL || in == NULL) {
17036+
if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))) {
1703517037
return BAD_FUNC_ARG;
1703617038
}
1703717039

17038-
/*
17039-
* Encrypt the plaintext using AES CTR
17040-
* C = CTR(M)
17041-
*/
17042-
if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17043-
return ret;
17044-
}
17040+
if (inSz > 0) {
17041+
/*
17042+
* Encrypt the plaintext using AES CTR
17043+
* C = CTR(M)
17044+
*/
17045+
if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17046+
return ret;
17047+
}
1704517048

17046-
/*
17047-
* update OMAC with new ciphertext
17048-
* C' = OMAC^2_K(C)
17049-
*/
17050-
if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
17051-
return ret;
17049+
/*
17050+
* update OMAC with new ciphertext
17051+
* C' = OMAC^2_K(C)
17052+
*/
17053+
if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
17054+
return ret;
17055+
}
1705217056
}
1705317057

1705417058
/* If there exists new auth data, update the OMAC for that as well */
@@ -17076,24 +17080,26 @@ int wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
1707617080
{
1707717081
int ret;
1707817082

17079-
if (eax == NULL || out == NULL || in == NULL) {
17083+
if (eax == NULL || (inSz > 0 && (out == NULL || in == NULL))) {
1708017084
return BAD_FUNC_ARG;
1708117085
}
1708217086

17083-
/*
17084-
* Decrypt the plaintext using AES CTR
17085-
* C = CTR(M)
17086-
*/
17087-
if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17088-
return ret;
17089-
}
17087+
if (inSz > 0) {
17088+
/*
17089+
* Decrypt the plaintext using AES CTR
17090+
* C = CTR(M)
17091+
*/
17092+
if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17093+
return ret;
17094+
}
1709017095

17091-
/*
17092-
* update OMAC with new ciphertext
17093-
* C' = OMAC^2_K(C)
17094-
*/
17095-
if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
17096-
return ret;
17096+
/*
17097+
* update OMAC with new ciphertext
17098+
* C' = OMAC^2_K(C)
17099+
*/
17100+
if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
17101+
return ret;
17102+
}
1709717103
}
1709817104

1709917105
/* If there exists new auth data, update the OMAC for that as well */

0 commit comments

Comments
 (0)