Skip to content

Commit c905033

Browse files
committed
API tests: more cipher tests
1. Unaligned Buffer Tests Verify correct output when input/output buffers are byte-offset by 1, 2, and 3 bytes. - AES-CBC, AES-CTS, AES-CTR, AES-GCM, AES-CCM, AES-XTS - ChaCha20, ChaCha20-Poly1305 2. In-Place (Overlapping) Buffer Tests Verify correct output when out == in (same pointer for input and output). - AES-CTS, AES-GCM, AES-CCM, AES-XTS - ChaCha20, ChaCha20-Poly1305 3. Cross-Cipher Verification Tests Verify that a higher-level mode produces identical output when manually reconstructed from a lower-level primitive (typically AES-ECB + XOR). - AES-CBC (= ECB + XOR chaining) - AES-CFB (= ECB(ciphertext feedback) + XOR) - AES-OFB (= ECB(output feedback) + XOR) - AES-CTR (= ECB(counter) + XOR with big-endian increment) - AES-GCM (ciphertext portion = CTR starting at counter J0+1) - ChaCha20-Poly1305 (ciphertext = raw ChaCha20 keystream XOR; tag = independent Poly1305) 4. Counter Overflow Tests Verify correct carry propagation when the internal block counter wraps around. - AES-CTR (32-bit big-endian carry across 4 bytes: 0xFFFFFFFE → wrap) - ChaCha20 (32-bit counter: 0xFFFFFFFF → 0x00000000) 5. AEAD Edge Case Tests Verify correct behavior for empty inputs, empty AAD, and invalid auth tag rejection. - Ascon-AEAD128 - AES-CCM - ChaCha20-Poly1305 6. Non-Standard Parameter Tests Verify behavior outside the common fast path. - AES-GCM: non-96-bit nonce lengths (1-byte, 60-byte, variable-length loop, zero-length rejection) 7. Streaming API State Tests Verify mid-stream state behavior and re-initialization after a final call. - AES-GCM stream, AES-XTS stream - ChaCha20-Poly1305 stream
1 parent 6ac0f82 commit c905033

8 files changed

Lines changed: 3510 additions & 195 deletions

File tree

tests/api/test_aes.c

Lines changed: 2467 additions & 172 deletions
Large diffs are not rendered by default.

tests/api/test_aes.h

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,45 @@ int test_wc_AesSetIV(void);
2929
int test_wc_AesEncryptDecryptDirect(void);
3030
int test_wc_AesEcbEncryptDecrypt(void);
3131
int test_wc_AesCbcEncryptDecrypt(void);
32+
int test_wc_AesCbcEncryptDecrypt_UnalignedBuffers(void);
33+
int test_wc_AesCbc_CrossCipher(void);
3234
int test_wc_AesCfbEncryptDecrypt(void);
35+
int test_wc_AesCfb_CrossCipher(void);
3336
int test_wc_AesOfbEncryptDecrypt(void);
37+
int test_wc_AesOfb_CrossCipher(void);
3438
int test_wc_AesCtsEncryptDecrypt(void);
39+
int test_wc_AesCtsEncryptDecrypt_InPlace(void);
40+
int test_wc_AesCtsEncryptDecrypt_UnalignedBuffers(void);
3541
int test_wc_AesCtrSetKey(void);
3642
int test_wc_AesCtrEncryptDecrypt(void);
43+
int test_wc_AesCtrEncryptDecrypt_UnalignedBuffers(void);
44+
int test_wc_AesCtr_CrossCipher(void);
45+
int test_wc_AesCtrCounterOverflow(void);
3746
int test_wc_AesGcmSetKey(void);
3847
int test_wc_AesGcmEncryptDecrypt_Sizes(void);
3948
int test_wc_AesGcmEncryptDecrypt(void);
49+
int test_wc_AesGcmEncryptDecrypt_InPlace(void);
50+
int test_wc_AesGcmEncryptDecrypt_UnalignedBuffers(void);
51+
int test_wc_AesGcm_CrossCipher(void);
4052
int test_wc_AesGcmMixedEncDecLongIV(void);
53+
int test_wc_AesGcmNonStdNonce(void);
4154
int test_wc_AesGcmStream(void);
55+
int test_wc_AesGcmStream_MidStreamState(void);
56+
int test_wc_AesGcmStream_ReinitAfterFinal(void);
4257
int test_wc_AesCcmSetKey(void);
4358
int test_wc_AesCcmEncryptDecrypt(void);
59+
int test_wc_AesCcmEncryptDecrypt_InPlace(void);
60+
int test_wc_AesCcmEncryptDecrypt_UnalignedBuffers(void);
61+
int test_wc_AesCcmAeadEdgeCases(void);
4462
int test_wc_AesXtsSetKey(void);
4563
int test_wc_AesXtsEncryptDecrypt_Sizes(void);
4664
int test_wc_AesXtsEncryptDecrypt(void);
65+
int test_wc_AesXtsEncryptDecrypt_InPlace(void);
66+
int test_wc_AesXtsEncryptDecrypt_UnalignedBuffers(void);
67+
int test_wc_AesXtsEncryptDecryptSector(void);
68+
int test_wc_AesXtsStream(void);
69+
int test_wc_AesXtsStream_MidStreamState(void);
70+
int test_wc_AesXtsStream_ReinitAfterFinal(void);
4771
#if defined(WOLFSSL_AES_EAX) && defined(WOLFSSL_AES_256) && \
4872
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
4973
int test_wc_AesEaxVectors(void);
@@ -83,22 +107,46 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void);
83107
TEST_DECL_GROUP("aes", test_wc_AesSetIV), \
84108
TEST_DECL_GROUP("aes", test_wc_AesEncryptDecryptDirect), \
85109
TEST_DECL_GROUP("aes", test_wc_AesEcbEncryptDecrypt), \
86-
TEST_DECL_GROUP("aes", test_wc_AesCbcEncryptDecrypt), \
87-
TEST_DECL_GROUP("aes", test_wc_AesCfbEncryptDecrypt), \
110+
TEST_DECL_GROUP("aes", test_wc_AesCbcEncryptDecrypt), \
111+
TEST_DECL_GROUP("aes", test_wc_AesCbcEncryptDecrypt_UnalignedBuffers), \
112+
TEST_DECL_GROUP("aes", test_wc_AesCbc_CrossCipher), \
113+
TEST_DECL_GROUP("aes", test_wc_AesCfbEncryptDecrypt), \
114+
TEST_DECL_GROUP("aes", test_wc_AesCfb_CrossCipher), \
88115
TEST_DECL_GROUP("aes", test_wc_AesOfbEncryptDecrypt), \
89-
TEST_DECL_GROUP("aes", test_wc_AesCtsEncryptDecrypt), \
90-
TEST_DECL_GROUP("aes", test_wc_AesCtrSetKey), \
91-
TEST_DECL_GROUP("aes", test_wc_AesCtrEncryptDecrypt), \
116+
TEST_DECL_GROUP("aes", test_wc_AesOfb_CrossCipher), \
117+
TEST_DECL_GROUP("aes", test_wc_AesCtsEncryptDecrypt), \
118+
TEST_DECL_GROUP("aes", test_wc_AesCtsEncryptDecrypt_InPlace), \
119+
TEST_DECL_GROUP("aes", test_wc_AesCtsEncryptDecrypt_UnalignedBuffers), \
120+
TEST_DECL_GROUP("aes", test_wc_AesCtrSetKey), \
121+
TEST_DECL_GROUP("aes", test_wc_AesCtrEncryptDecrypt), \
122+
TEST_DECL_GROUP("aes", test_wc_AesCtrEncryptDecrypt_UnalignedBuffers), \
123+
TEST_DECL_GROUP("aes", test_wc_AesCtr_CrossCipher), \
124+
TEST_DECL_GROUP("aes", test_wc_AesCtrCounterOverflow), \
92125
TEST_DECL_GROUP("aes", test_wc_AesGcmSetKey), \
93126
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt_Sizes), \
94-
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt), \
95-
TEST_DECL_GROUP("aes", test_wc_AesGcmMixedEncDecLongIV), \
127+
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt), \
128+
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt_InPlace), \
129+
TEST_DECL_GROUP("aes", test_wc_AesGcmEncryptDecrypt_UnalignedBuffers), \
130+
TEST_DECL_GROUP("aes", test_wc_AesGcm_CrossCipher), \
131+
TEST_DECL_GROUP("aes", test_wc_AesGcmMixedEncDecLongIV), \
132+
TEST_DECL_GROUP("aes", test_wc_AesGcmNonStdNonce), \
96133
TEST_DECL_GROUP("aes", test_wc_AesGcmStream), \
134+
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_MidStreamState), \
135+
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_ReinitAfterFinal), \
97136
TEST_DECL_GROUP("aes", test_wc_AesCcmSetKey), \
98-
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt), \
99-
TEST_DECL_GROUP("aes", test_wc_AesXtsSetKey), \
100-
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt_Sizes), \
101-
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt), \
137+
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt), \
138+
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt_InPlace), \
139+
TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt_UnalignedBuffers), \
140+
TEST_DECL_GROUP("aes", test_wc_AesCcmAeadEdgeCases), \
141+
TEST_DECL_GROUP("aes", test_wc_AesXtsSetKey), \
142+
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt_Sizes), \
143+
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt), \
144+
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt_InPlace), \
145+
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt_UnalignedBuffers), \
146+
TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecryptSector), \
147+
TEST_DECL_GROUP("aes", test_wc_AesXtsStream), \
148+
TEST_DECL_GROUP("aes", test_wc_AesXtsStream_MidStreamState), \
149+
TEST_DECL_GROUP("aes", test_wc_AesXtsStream_ReinitAfterFinal), \
102150
TEST_DECL_GROUP("aes", test_wc_AesCbc_MonteCarlo), \
103151
TEST_DECL_GROUP("aes", test_wc_AesCtr_MonteCarlo), \
104152
TEST_DECL_GROUP("aes", test_wc_AesGcm_MonteCarlo), \

tests/api/test_ascon.c

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */

tests/api/test_ascon.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626

2727
int test_ascon_hash256(void);
2828
int test_ascon_aead128(void);
29+
int test_ascon_aead128_edge_cases(void);
2930

30-
#define TEST_ASCON_DECLS \
31-
TEST_DECL_GROUP("ascon", test_ascon_hash256), \
32-
TEST_DECL_GROUP("ascon", test_ascon_aead128)
31+
#define TEST_ASCON_DECLS \
32+
TEST_DECL_GROUP("ascon", test_ascon_hash256), \
33+
TEST_DECL_GROUP("ascon", test_ascon_aead128), \
34+
TEST_DECL_GROUP("ascon", test_ascon_aead128_edge_cases)
3335

3436
#endif /* TESTS_API_TEST_ASCON_H */

0 commit comments

Comments
 (0)