@@ -184,3 +184,163 @@ int test_ascon_aead128(void)
184184#endif
185185 return EXPECT_RESULT ();
186186}
187+
188+ /*
189+ * Ascon-AEAD128 AEAD edge cases:
190+ * - invalid auth tag rejection (DecryptFinal with wrong tag -> ASCON_AUTH_E)
191+ * - empty plaintext with empty AAD (KAT[0])
192+ * - empty plaintext with non-empty AAD (KAT[1])
193+ *
194+ * KAT vectors are from the Ascon reference implementation:
195+ * https://github.com/ascon/ascon-c
196+ */
197+ int test_ascon_aead128_edge_cases (void )
198+ {
199+ EXPECT_DECLS ;
200+ #ifdef HAVE_ASCON
201+ /* Shared key and nonce for all sub-tests (same as KAT[0..N]) */
202+ static const byte key [ASCON_AEAD128_KEY_SZ ] = {
203+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
204+ 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F
205+ };
206+ static const byte nonce [ASCON_AEAD128_NONCE_SZ ] = {
207+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
208+ 0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F
209+ };
210+ /* KAT[0]: PT="", AD="" -> CT = tag only */
211+ static const byte expTag0 [ASCON_AEAD128_TAG_SZ ] = {
212+ 0x44 , 0x27 , 0xD6 , 0x4B , 0x8E , 0x1E , 0x14 , 0x51 ,
213+ 0xFC , 0x44 , 0x59 , 0x60 , 0xF0 , 0x83 , 0x9B , 0xB0
214+ };
215+ /* KAT[1]: PT="", AD="00" -> CT = tag only */
216+ static const byte ad1 [1 ] = { 0x00 };
217+ static const byte expTag1 [ASCON_AEAD128_TAG_SZ ] = {
218+ 0x10 , 0x3A , 0xB7 , 0x9D , 0x91 , 0x3A , 0x03 , 0x21 ,
219+ 0x28 , 0x77 , 0x15 , 0xA9 , 0x79 , 0xBB , 0x85 , 0x85
220+ };
221+ wc_AsconAEAD128 * asconAEAD = NULL ;
222+ byte tagBuf [ASCON_AEAD128_TAG_SZ ];
223+ byte badTag [ASCON_AEAD128_TAG_SZ ];
224+ byte dummy [1 ]; /* non-NULL placeholder for 0-length pt/ct args */
225+
226+ ExpectNotNull (asconAEAD = wc_AsconAEAD128_New ());
227+
228+ /* ------------------------------------------------------------------ */
229+ /* 1. Empty plaintext + empty AAD (KAT[0]) */
230+ /* ------------------------------------------------------------------ */
231+
232+ /* Encrypt and verify tag against KAT */
233+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
234+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
235+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
236+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
237+ ExpectIntEQ (wc_AsconAEAD128_EncryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
238+ XMEMSET (tagBuf , 0 , sizeof (tagBuf ));
239+ ExpectIntEQ (wc_AsconAEAD128_EncryptFinal (asconAEAD , tagBuf ), 0 );
240+ ExpectBufEQ (tagBuf , expTag0 , ASCON_AEAD128_TAG_SZ );
241+ wc_AsconAEAD128_Clear (asconAEAD );
242+
243+ /* Decrypt with correct tag -> success */
244+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
245+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
246+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
247+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
248+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
249+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , expTag0 ), 0 );
250+ wc_AsconAEAD128_Clear (asconAEAD );
251+
252+ /* Decrypt with wrong tag -> ASCON_AUTH_E */
253+ XMEMCPY (badTag , expTag0 , ASCON_AEAD128_TAG_SZ );
254+ badTag [0 ] ^= 0xff ;
255+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
256+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
257+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
258+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
259+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
260+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , badTag ),
261+ WC_NO_ERR_TRACE (ASCON_AUTH_E ));
262+ wc_AsconAEAD128_Clear (asconAEAD );
263+
264+ /* ------------------------------------------------------------------ */
265+ /* 2. Empty plaintext + non-empty AAD (KAT[1], AD = {0x00}) */
266+ /* ------------------------------------------------------------------ */
267+
268+ /* Encrypt and verify tag against KAT */
269+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
270+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
271+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
272+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , ad1 , sizeof (ad1 )), 0 );
273+ ExpectIntEQ (wc_AsconAEAD128_EncryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
274+ XMEMSET (tagBuf , 0 , sizeof (tagBuf ));
275+ ExpectIntEQ (wc_AsconAEAD128_EncryptFinal (asconAEAD , tagBuf ), 0 );
276+ ExpectBufEQ (tagBuf , expTag1 , ASCON_AEAD128_TAG_SZ );
277+ wc_AsconAEAD128_Clear (asconAEAD );
278+
279+ /* Decrypt with correct tag -> success */
280+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
281+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
282+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
283+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , ad1 , sizeof (ad1 )), 0 );
284+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
285+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , expTag1 ), 0 );
286+ wc_AsconAEAD128_Clear (asconAEAD );
287+
288+ /* Decrypt with wrong tag -> ASCON_AUTH_E */
289+ XMEMCPY (badTag , expTag1 , ASCON_AEAD128_TAG_SZ );
290+ badTag [0 ] ^= 0xff ;
291+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
292+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
293+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
294+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , ad1 , sizeof (ad1 )), 0 );
295+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , dummy , 0 ), 0 );
296+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , badTag ),
297+ WC_NO_ERR_TRACE (ASCON_AUTH_E ));
298+ wc_AsconAEAD128_Clear (asconAEAD );
299+
300+ /* ------------------------------------------------------------------ */
301+ /* 3. Non-empty plaintext: invalid tag rejection */
302+ /* ------------------------------------------------------------------ */
303+ {
304+ static const byte pt [] = { 0x00 };
305+ byte ct [sizeof (pt )];
306+ byte encTag [ASCON_AEAD128_TAG_SZ ];
307+
308+ /* Encrypt one byte */
309+ XMEMSET (ct , 0 , sizeof (ct ));
310+ XMEMSET (encTag , 0 , sizeof (encTag ));
311+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
312+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
313+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
314+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
315+ ExpectIntEQ (wc_AsconAEAD128_EncryptUpdate (asconAEAD , ct , pt ,
316+ sizeof (pt )), 0 );
317+ ExpectIntEQ (wc_AsconAEAD128_EncryptFinal (asconAEAD , encTag ), 0 );
318+ wc_AsconAEAD128_Clear (asconAEAD );
319+
320+ /* Decrypt with correct tag -> success */
321+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
322+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
323+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
324+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
325+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , ct ,
326+ sizeof (ct )), 0 );
327+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , encTag ), 0 );
328+ wc_AsconAEAD128_Clear (asconAEAD );
329+
330+ /* Decrypt with tampered tag -> ASCON_AUTH_E */
331+ encTag [ASCON_AEAD128_TAG_SZ - 1 ] ^= 0xff ;
332+ ExpectIntEQ (wc_AsconAEAD128_Init (asconAEAD ), 0 );
333+ ExpectIntEQ (wc_AsconAEAD128_SetKey (asconAEAD , key ), 0 );
334+ ExpectIntEQ (wc_AsconAEAD128_SetNonce (asconAEAD , nonce ), 0 );
335+ ExpectIntEQ (wc_AsconAEAD128_SetAD (asconAEAD , dummy , 0 ), 0 );
336+ ExpectIntEQ (wc_AsconAEAD128_DecryptUpdate (asconAEAD , dummy , ct ,
337+ sizeof (ct )), 0 );
338+ ExpectIntEQ (wc_AsconAEAD128_DecryptFinal (asconAEAD , encTag ),
339+ WC_NO_ERR_TRACE (ASCON_AUTH_E ));
340+ wc_AsconAEAD128_Clear (asconAEAD );
341+ }
342+
343+ wc_AsconAEAD128_Free (asconAEAD );
344+ #endif /* HAVE_ASCON */
345+ return EXPECT_RESULT ();
346+ } /* END test_ascon_aead128_edge_cases */
0 commit comments