API testing additions: cipher tests

Fixed wc_AesEaxAuthDataUpdate to check eax for NULL before
dereferencing.

Fix AesSivCipher to delete/free AES if new/initialization succeeded.
Memsetting to 0 doesn't work when WC_DEBUG_CIPHER_LIFECYCLE is defined.

Added tests for:
 - AES-EAX streaming
 - AES-SIV
 - Poly1305
 - DES-CBC
This commit is contained in:
Sean Parkinson
2026-04-09 18:10:28 +10:00
parent 1d363f3adc
commit b764aac074
8 changed files with 665 additions and 32 deletions
+3
View File
@@ -35194,6 +35194,9 @@ TEST_CASE testCases[] = {
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
TEST_AES_EAX_DECLS,
#endif /* WOLFSSL_AES_EAX */
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
TEST_AES_SIV_DECLS,
#endif /* WOLFSSL_AES_SIV && WOLFSSL_AES_128 */
TEST_GMAC_DECLS,
/* Ascon */
TEST_ASCON_DECLS,
+336
View File
@@ -5218,10 +5218,346 @@ int test_wc_AesEaxDecryptAuth(void)
return EXPECT_RESULT();
} /* END test_wc_AesEaxDecryptAuth() */
/*
* Testing AES-EAX streaming (incremental) API:
* wc_AesEaxInit, wc_AesEaxEncryptUpdate, wc_AesEaxAuthDataUpdate,
* wc_AesEaxEncryptFinal, wc_AesEaxDecryptUpdate, wc_AesEaxDecryptFinal,
* wc_AesEaxFree
*/
int test_wc_AesEaxStream(void)
{
EXPECT_DECLS;
#ifdef WOLFSSL_AES_128
/* Wycheproof AES-EAX 128-bit key vectors */
/* Vector 1: empty plaintext - AAD passed via Init */
const byte key1[] = {0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78};
const byte nonce1[] = {0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3};
const byte aad1[] = {0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b};
const byte tag1[] = {0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01};
/* Vector 2: 2-byte plaintext - AAD passed via EncryptUpdate */
const byte key2[] = {0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4};
const byte nonce2[] = {0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd};
const byte aad2[] = {0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa};
const byte pt2[] = {0xf7, 0xfb};
const byte ct2[] = {0x19, 0xdd};
const byte tag2[] = {0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5};
/* Vector 3: 5-byte plaintext - multi-chunk, AAD via AuthDataUpdate */
const byte key3[] = {0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23};
const byte nonce3[] = {0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e};
const byte aad3[] = {0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6};
const byte pt3[] = {0x1a, 0x47, 0xcb, 0x49, 0x33};
const byte ct3[] = {0xd8, 0x51, 0xd5, 0xba, 0xe0};
const byte tag3[] = {0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80};
AesEax eax;
byte out[16];
byte tagBuf[WC_AES_BLOCK_SIZE];
XMEMSET(&eax, 0, sizeof(eax));
XMEMSET(out, 0, sizeof(out));
XMEMSET(tagBuf, 0, sizeof(tagBuf));
/* --- Test 1: empty plaintext, AAD passed to Init --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key1, sizeof(key1),
nonce1, sizeof(nonce1),
aad1, sizeof(aad1)), 0);
ExpectIntEQ(wc_AesEaxEncryptFinal(&eax, tagBuf, sizeof(tag1)), 0);
ExpectBufEQ(tagBuf, tag1, sizeof(tag1));
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Test 1d: empty plaintext decrypt --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key1, sizeof(key1),
nonce1, sizeof(nonce1),
aad1, sizeof(aad1)), 0);
ExpectIntEQ(wc_AesEaxDecryptFinal(&eax, tag1, sizeof(tag1)), 0);
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Test 2: 2-byte plaintext, single EncryptUpdate with inline AAD --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key2, sizeof(key2),
nonce2, sizeof(nonce2),
NULL, 0), 0);
ExpectIntEQ(wc_AesEaxEncryptUpdate(&eax, out, pt2, sizeof(pt2),
aad2, sizeof(aad2)), 0);
ExpectBufEQ(out, ct2, sizeof(ct2));
ExpectIntEQ(wc_AesEaxEncryptFinal(&eax, tagBuf, sizeof(tag2)), 0);
ExpectBufEQ(tagBuf, tag2, sizeof(tag2));
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Test 2d: 2-byte ciphertext, single DecryptUpdate with inline AAD --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key2, sizeof(key2),
nonce2, sizeof(nonce2),
NULL, 0), 0);
ExpectIntEQ(wc_AesEaxDecryptUpdate(&eax, out, ct2, sizeof(ct2),
aad2, sizeof(aad2)), 0);
ExpectBufEQ(out, pt2, sizeof(pt2));
ExpectIntEQ(wc_AesEaxDecryptFinal(&eax, tag2, sizeof(tag2)), 0);
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Test 3: 5-byte plaintext, multi-chunk encrypt with AuthDataUpdate --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key3, sizeof(key3),
nonce3, sizeof(nonce3),
NULL, 0), 0);
/* Feed AAD via AuthDataUpdate split into two calls */
ExpectIntEQ(wc_AesEaxAuthDataUpdate(&eax, aad3, 4), 0);
ExpectIntEQ(wc_AesEaxAuthDataUpdate(&eax, aad3 + 4, sizeof(aad3) - 4), 0);
/* Encrypt plaintext in two chunks */
ExpectIntEQ(wc_AesEaxEncryptUpdate(&eax, out, pt3, 2, NULL, 0), 0);
ExpectBufEQ(out, ct3, 2);
ExpectIntEQ(wc_AesEaxEncryptUpdate(&eax, out + 2, pt3 + 2,
(word32)(sizeof(pt3) - 2), NULL, 0), 0);
ExpectBufEQ(out + 2, ct3 + 2, sizeof(ct3) - 2);
ExpectIntEQ(wc_AesEaxEncryptFinal(&eax, tagBuf, sizeof(tag3)), 0);
ExpectBufEQ(tagBuf, tag3, sizeof(tag3));
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Test 3d: 5-byte ciphertext, multi-chunk decrypt with AuthDataUpdate --- */
ExpectIntEQ(wc_AesEaxInit(&eax, key3, sizeof(key3),
nonce3, sizeof(nonce3),
NULL, 0), 0);
ExpectIntEQ(wc_AesEaxAuthDataUpdate(&eax, aad3, 4), 0);
ExpectIntEQ(wc_AesEaxAuthDataUpdate(&eax, aad3 + 4, sizeof(aad3) - 4), 0);
/* Decrypt ciphertext in two chunks */
ExpectIntEQ(wc_AesEaxDecryptUpdate(&eax, out, ct3, 2, NULL, 0), 0);
ExpectBufEQ(out, pt3, 2);
ExpectIntEQ(wc_AesEaxDecryptUpdate(&eax, out + 2, ct3 + 2,
(word32)(sizeof(ct3) - 2), NULL, 0), 0);
ExpectBufEQ(out + 2, pt3 + 2, sizeof(pt3) - 2);
ExpectIntEQ(wc_AesEaxDecryptFinal(&eax, tag3, sizeof(tag3)), 0);
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* --- Bad args --- */
/* wc_AesEaxInit */
ExpectIntEQ(wc_AesEaxInit(NULL, key1, sizeof(key1),
nonce1, sizeof(nonce1), NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesEaxInit(&eax, NULL, sizeof(key1),
nonce1, sizeof(nonce1), NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesEaxInit(&eax, key1, sizeof(key1),
NULL, sizeof(nonce1), NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* wc_AesEaxAuthDataUpdate */
ExpectIntEQ(wc_AesEaxAuthDataUpdate(NULL, aad1, sizeof(aad1)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* wc_AesEaxEncryptFinal */
ExpectIntEQ(wc_AesEaxEncryptFinal(NULL, tagBuf, WC_AES_BLOCK_SIZE),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* wc_AesEaxDecryptFinal NULL eax */
ExpectIntEQ(wc_AesEaxDecryptFinal(NULL, tag1, sizeof(tag1)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* wc_AesEaxDecryptFinal authInSz > WC_AES_BLOCK_SIZE */
ExpectIntEQ(wc_AesEaxInit(&eax, key1, sizeof(key1),
nonce1, sizeof(nonce1), NULL, 0), 0);
ExpectIntEQ(wc_AesEaxDecryptFinal(&eax, tag1, WC_AES_BLOCK_SIZE + 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesEaxFree(&eax), 0);
/* wc_AesEaxFree NULL */
ExpectIntEQ(wc_AesEaxFree(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif /* WOLFSSL_AES_128 */
return EXPECT_RESULT();
} /* END test_wc_AesEaxStream() */
#endif /* WOLFSSL_AES_EAX && WOLFSSL_AES_256
* (!HAVE_FIPS || FIPS_VERSION_GE(5, 3)) && !HAVE_SELFTEST
*/
/*----------------------------------------------------------------------------*
| AES-SIV Test
*----------------------------------------------------------------------------*/
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
/*
* Testing wc_AesSivEncrypt, wc_AesSivDecrypt,
* wc_AesSivEncrypt_ex, wc_AesSivDecrypt_ex.
* Uses RFC 5297 Example A.1 (single assoc) and A.2 (two assocs).
*/
int test_wc_AesSivEncryptDecrypt(void)
{
EXPECT_DECLS;
/* RFC 5297 Example A.1: single associated data buffer */
const byte key_a1[] = {
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,
0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,
0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
};
const byte assoc_a1[] = {
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
};
const byte pt_a1[] = {
0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
0x99,0xaa,0xbb,0xcc,0xdd,0xee
};
const byte siv_a1[] = {
0x85,0x63,0x2d,0x07,0xc6,0xe8,0xf3,0x7f,
0x95,0x0a,0xcd,0x32,0x0a,0x2e,0xcc,0x93
};
const byte ct_a1[] = {
0x40,0xc0,0x2b,0x96,0x90,0xc4,0xdc,0x04,
0xda,0xef,0x7f,0x6a,0xfe,0x5c
};
/* RFC 5297 Example A.2: two associated data buffers, no nonce */
const byte key_a2[] = {
0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,
0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
};
const byte assoc2_1_a2[] = {
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,
0xde,0xad,0xda,0xda,0xde,0xad,0xda,0xda,
0xff,0xee,0xdd,0xcc,0xbb,0xaa,0x99,0x88,
0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00
};
const byte assoc2_2_a2[] = {
0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,
0x90,0xa0
};
const byte nonce_a2[] = {
0x09,0xf9,0x11,0x02,0x9d,0x74,0xe3,0x5b,
0xd8,0x41,0x56,0xc5,0x63,0x56,0x88,0xc0
};
const byte pt_a2[] = {
0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,
0x73,0x6f,0x6d,0x65,0x20,0x70,0x6c,0x61,
0x69,0x6e,0x74,0x65,0x78,0x74,0x20,0x74,
0x6f,0x20,0x65,0x6e,0x63,0x72,0x79,0x70,
0x74,0x20,0x75,0x73,0x69,0x6e,0x67,0x20,
0x53,0x49,0x56,0x2d,0x41,0x45,0x53
};
const byte siv_a2[] = {
0x7b,0xdb,0x6e,0x3b,0x43,0x26,0x67,0xeb,
0x06,0xf4,0xd1,0x4b,0xff,0x2f,0xbd,0x0f
};
const byte ct_a2[] = {
0xcb,0x90,0x0f,0x2f,0xdd,0xbe,0x40,0x43,
0x26,0x60,0x19,0x65,0xc8,0x89,0xbf,0x17,
0xdb,0xa7,0x7c,0xeb,0x09,0x4f,0xa6,0x63,
0xb7,0xa3,0xf7,0x48,0xba,0x8a,0xf8,0x29,
0xea,0x64,0xad,0x54,0x4a,0x27,0x2e,0x9c,
0x48,0x5b,0x62,0xa3,0xfd,0x5c,0x0d
};
byte siv[WC_AES_BLOCK_SIZE];
byte ct[sizeof(pt_a2)]; /* large enough for both tests */
byte pt[sizeof(pt_a2)];
/* --- A.1: wc_AesSivEncrypt (single assoc, no nonce) --- */
XMEMSET(siv, 0, sizeof(siv));
XMEMSET(ct, 0, sizeof(ct));
ExpectIntEQ(wc_AesSivEncrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0,
pt_a1, sizeof(pt_a1),
siv, ct), 0);
ExpectBufEQ(siv, siv_a1, sizeof(siv_a1));
ExpectBufEQ(ct, ct_a1, sizeof(ct_a1));
/* --- A.1: wc_AesSivDecrypt --- */
XMEMSET(pt, 0, sizeof(pt));
XMEMCPY(siv, siv_a1, sizeof(siv_a1));
ExpectIntEQ(wc_AesSivDecrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0,
ct_a1, sizeof(ct_a1),
siv, pt), 0);
ExpectBufEQ(pt, pt_a1, sizeof(pt_a1));
/* Corrupt SIV: decrypt must fail */
siv[0] ^= 0xff;
ExpectIntNE(wc_AesSivDecrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0,
ct_a1, sizeof(ct_a1),
siv, pt), 0);
/* --- A.2: wc_AesSivEncrypt_ex (two assocs + nonce) --- */
{
const AesSivAssoc assocs[2] = {
{ assoc2_1_a2, sizeof(assoc2_1_a2) },
{ assoc2_2_a2, sizeof(assoc2_2_a2) }
};
XMEMSET(siv, 0, sizeof(siv));
XMEMSET(ct, 0, sizeof(ct));
ExpectIntEQ(wc_AesSivEncrypt_ex(key_a2, sizeof(key_a2),
assocs, 2,
nonce_a2, sizeof(nonce_a2),
pt_a2, sizeof(pt_a2),
siv, ct), 0);
ExpectBufEQ(siv, siv_a2, sizeof(siv_a2));
ExpectBufEQ(ct, ct_a2, sizeof(ct_a2));
/* wc_AesSivDecrypt_ex */
XMEMSET(pt, 0, sizeof(pt));
XMEMCPY(siv, siv_a2, sizeof(siv_a2));
ExpectIntEQ(wc_AesSivDecrypt_ex(key_a2, sizeof(key_a2),
assocs, 2,
nonce_a2, sizeof(nonce_a2),
ct_a2, sizeof(ct_a2),
siv, pt), 0);
ExpectBufEQ(pt, pt_a2, sizeof(pt_a2));
}
/* --- Bad args: wc_AesSivEncrypt --- */
ExpectIntNE(wc_AesSivEncrypt(NULL, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, pt_a1, sizeof(pt_a1), siv, ct), 0);
ExpectIntNE(wc_AesSivEncrypt(key_a1, 0,
assoc_a1, sizeof(assoc_a1),
NULL, 0, pt_a1, sizeof(pt_a1), siv, ct), 0);
ExpectIntNE(wc_AesSivEncrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, pt_a1, sizeof(pt_a1), NULL, ct), 0);
ExpectIntNE(wc_AesSivEncrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, pt_a1, sizeof(pt_a1), siv, NULL), 0);
/* --- Bad args: wc_AesSivDecrypt --- */
XMEMCPY(siv, siv_a1, sizeof(siv_a1));
ExpectIntNE(wc_AesSivDecrypt(NULL, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, ct_a1, sizeof(ct_a1), siv, pt), 0);
ExpectIntNE(wc_AesSivDecrypt(key_a1, 0,
assoc_a1, sizeof(assoc_a1),
NULL, 0, ct_a1, sizeof(ct_a1), siv, pt), 0);
ExpectIntNE(wc_AesSivDecrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, ct_a1, sizeof(ct_a1), NULL, pt), 0);
ExpectIntNE(wc_AesSivDecrypt(key_a1, sizeof(key_a1),
assoc_a1, sizeof(assoc_a1),
NULL, 0, ct_a1, sizeof(ct_a1), siv, NULL), 0);
return EXPECT_RESULT();
} /* END test_wc_AesSivEncryptDecrypt */
#endif /* WOLFSSL_AES_SIV && WOLFSSL_AES_128 */
/*----------------------------------------------------------------------------*
| CryptoCB AES SetKey Test
*----------------------------------------------------------------------------*/
+11 -1
View File
@@ -49,7 +49,11 @@ int test_wc_AesXtsEncryptDecrypt(void);
int test_wc_AesEaxVectors(void);
int test_wc_AesEaxEncryptAuth(void);
int test_wc_AesEaxDecryptAuth(void);
int test_wc_AesEaxStream(void);
#endif /* WOLFSSL_AES_EAX && WOLFSSL_AES_256*/
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
int test_wc_AesSivEncryptDecrypt(void);
#endif
int test_wc_GmacSetKey(void);
int test_wc_GmacUpdate(void);
@@ -95,9 +99,15 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void);
#define TEST_AES_EAX_DECLS \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxVectors), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxEncryptAuth), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxDecryptAuth)
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxDecryptAuth), \
TEST_DECL_GROUP("aes-eax", test_wc_AesEaxStream)
#endif /* WOLFSSL_AES_EAX */
#if defined(WOLFSSL_AES_SIV) && defined(WOLFSSL_AES_128)
#define TEST_AES_SIV_DECLS \
TEST_DECL_GROUP("aes-siv", test_wc_AesSivEncryptDecrypt)
#endif /* WOLFSSL_AES_SIV && WOLFSSL_AES_128 */
#define TEST_GMAC_DECLS \
TEST_DECL_GROUP("gmac", test_wc_GmacSetKey), \
TEST_DECL_GROUP("gmac", test_wc_GmacUpdate)
+205
View File
@@ -63,3 +63,208 @@ int test_wc_Poly1305SetKey(void)
return EXPECT_RESULT();
} /* END test_wc_Poly1305_SetKey() */
/*
* Unit test for wc_Poly1305Update and wc_Poly1305Final.
* Uses RFC 8439 2.5.2 test vector.
*/
int test_wc_Poly1305UpdateFinal(void)
{
EXPECT_DECLS;
#ifdef HAVE_POLY1305
/* RFC 8439 2.5.2 test vector */
const byte key[] = {
0x85,0xd6,0xbe,0x78,0x57,0x55,0x6d,0x33,
0x7f,0x44,0x52,0xfe,0x42,0xd5,0x06,0xa8,
0x01,0x03,0x80,0x8a,0xfb,0x0d,0xb2,0xfd,
0x4a,0xbf,0xf6,0xaf,0x41,0x49,0xf5,0x1b
};
/* "Cryptographic Forum Research Group" */
const byte msg[] = {
0x43,0x72,0x79,0x70,0x74,0x6f,0x67,0x72,
0x61,0x70,0x68,0x69,0x63,0x20,0x46,0x6f,
0x72,0x75,0x6d,0x20,0x52,0x65,0x73,0x65,
0x61,0x72,0x63,0x68,0x20,0x47,0x72,0x6f,
0x75,0x70
};
const byte expected[] = {
0xa8,0x06,0x1d,0xc1,0x30,0x51,0x36,0xc6,
0xc2,0x2b,0x8b,0xaf,0x0c,0x01,0x27,0xa9
};
Poly1305 ctx;
byte tag[WC_POLY1305_MAC_SZ];
/* Single update */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, msg, sizeof(msg)), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag), 0);
ExpectBufEQ(tag, expected, sizeof(expected));
/* Multi-chunk update produces the same result */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, msg, 16), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, msg + 16, sizeof(msg) - 16), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag), 0);
ExpectBufEQ(tag, expected, sizeof(expected));
/* Bad args */
ExpectIntEQ(wc_Poly1305Update(NULL, msg, sizeof(msg)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Poly1305Final(NULL, tag),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Poly1305Final(&ctx, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
return EXPECT_RESULT();
} /* END test_wc_Poly1305UpdateFinal */
/*
* Unit test for wc_Poly1305_MAC.
* Uses RFC 7539 2.8.2 test vector.
*/
int test_wc_Poly1305_MAC(void)
{
EXPECT_DECLS;
#ifdef HAVE_POLY1305
const byte key[] = {
0x7b,0xac,0x2b,0x25,0x2d,0xb4,0x47,0xaf,
0x09,0xb6,0x7a,0x55,0xa4,0xe9,0x55,0x84,
0x0a,0xe1,0xd6,0x73,0x10,0x75,0xd9,0xeb,
0x2a,0x93,0x75,0x78,0x3e,0xd5,0x53,0xff
};
const byte aad[] = {
0x50,0x51,0x52,0x53,0xc0,0xc1,0xc2,0xc3,
0xc4,0xc5,0xc6,0xc7
};
const byte input[] = {
0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb,
0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2,
0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe,
0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6,
0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12,
0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b,
0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29,
0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36,
0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c,
0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58,
0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94,
0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc,
0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d,
0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b,
0x61,0x16
};
const byte expected[] = {
0x1a,0xe1,0x0b,0x59,0x4f,0x09,0xe2,0x6a,
0x7e,0x90,0x2e,0xcb,0xd0,0x60,0x06,0x91
};
Poly1305 ctx;
byte tag[WC_POLY1305_MAC_SZ];
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305_MAC(&ctx, aad, sizeof(aad),
input, sizeof(input),
tag, sizeof(tag)), 0);
ExpectBufEQ(tag, expected, sizeof(expected));
/* Bad args */
ExpectIntEQ(wc_Poly1305_MAC(NULL, aad, sizeof(aad),
input, sizeof(input), tag, sizeof(tag)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Poly1305_MAC(&ctx, aad, sizeof(aad),
NULL, sizeof(input), tag, sizeof(tag)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Poly1305_MAC(&ctx, aad, sizeof(aad),
input, sizeof(input), NULL, sizeof(tag)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* tagSz too small */
ExpectIntEQ(wc_Poly1305_MAC(&ctx, aad, sizeof(aad),
input, sizeof(input),
tag, WC_POLY1305_MAC_SZ - 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* non-NULL additional with addSz > 0 but additional == NULL */
ExpectIntEQ(wc_Poly1305_MAC(&ctx, NULL, 1,
input, sizeof(input), tag, sizeof(tag)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
return EXPECT_RESULT();
} /* END test_wc_Poly1305_MAC */
/*
* Unit test for wc_Poly1305_Pad and wc_Poly1305_EncodeSizes /
* wc_Poly1305_EncodeSizes64.
* These are exercised via wc_Poly1305_MAC in normal use; test them directly
* by verifying the tag changes when data is artificially padded/encoded.
*/
int test_wc_Poly1305_PadEncodeSizes(void)
{
EXPECT_DECLS;
#ifdef HAVE_POLY1305
const byte key[] = {
0x85,0xd6,0xbe,0x78,0x57,0x55,0x6d,0x33,
0x7f,0x44,0x52,0xfe,0x42,0xd5,0x06,0xa8,
0x01,0x03,0x80,0x8a,0xfb,0x0d,0xb2,0xfd,
0x4a,0xbf,0xf6,0xaf,0x41,0x49,0xf5,0x1b
};
const byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; /* 5 bytes */
Poly1305 ctx;
byte tag1[WC_POLY1305_MAC_SZ];
byte tag2[WC_POLY1305_MAC_SZ];
/* Build tag1: data + manual Pad + EncodeSizes(5, 5) */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, data, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_Pad(&ctx, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_EncodeSizes(&ctx,
(word32)sizeof(data),
(word32)sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag1), 0);
/* Build tag2 same way - must match */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, data, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_Pad(&ctx, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_EncodeSizes(&ctx,
(word32)sizeof(data),
(word32)sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag2), 0);
ExpectBufEQ(tag1, tag2, sizeof(tag1));
/* Omitting the pad must produce a different tag */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, data, sizeof(data)), 0);
/* intentionally skip Pad */
ExpectIntEQ(wc_Poly1305_EncodeSizes(&ctx,
(word32)sizeof(data),
(word32)sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag2), 0);
/* tags must differ */
ExpectIntNE(XMEMCMP(tag1, tag2, sizeof(tag1)), 0);
#ifdef WORD64_AVAILABLE
/* wc_Poly1305_EncodeSizes64: same data as 64-bit sizes, same result */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305Update(&ctx, data, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_Pad(&ctx, sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305_EncodeSizes64(&ctx,
(word64)sizeof(data),
(word64)sizeof(data)), 0);
ExpectIntEQ(wc_Poly1305Final(&ctx, tag2), 0);
ExpectBufEQ(tag1, tag2, sizeof(tag1));
#endif
/* Pad lenToPad == 0 is a no-op */
ExpectIntEQ(wc_Poly1305SetKey(&ctx, key, sizeof(key)), 0);
ExpectIntEQ(wc_Poly1305_Pad(&ctx, 0), 0);
/* Bad args */
ExpectIntEQ(wc_Poly1305_Pad(NULL, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Poly1305_EncodeSizes(NULL, 1, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WORD64_AVAILABLE
ExpectIntEQ(wc_Poly1305_EncodeSizes64(NULL, 1, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#endif
return EXPECT_RESULT();
} /* END test_wc_Poly1305_PadEncodeSizes */
+8 -2
View File
@@ -25,8 +25,14 @@
#include <tests/api/api_decl.h>
int test_wc_Poly1305SetKey(void);
int test_wc_Poly1305UpdateFinal(void);
int test_wc_Poly1305_MAC(void);
int test_wc_Poly1305_PadEncodeSizes(void);
#define TEST_POLY1305_DECLS \
TEST_DECL_GROUP("poly1305", test_wc_Poly1305SetKey)
#define TEST_POLY1305_DECLS \
TEST_DECL_GROUP("poly1305", test_wc_Poly1305SetKey), \
TEST_DECL_GROUP("poly1305", test_wc_Poly1305UpdateFinal), \
TEST_DECL_GROUP("poly1305", test_wc_Poly1305_MAC), \
TEST_DECL_GROUP("poly1305", test_wc_Poly1305_PadEncodeSizes)
#endif /* WOLFCRYPT_TEST_POLY1305_H */
+66
View File
@@ -89,3 +89,69 @@ int test_wc_Des3_CbcEncryptDecryptWithKey(void)
return EXPECT_RESULT();
} /* END test_wc_Des3_CbcEncryptDecryptWithKey */
/*
* Unit test for wc_Des_CbcEncryptWithKey and wc_Des_CbcDecryptWithKey
* (single DES, not triple-DES)
*/
int test_wc_Des_CbcEncryptDecryptWithKey(void)
{
EXPECT_DECLS;
#ifndef NO_DES3
/* "now is the time for all " */
const byte vector[] = {
0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
};
const byte key[] = {
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
};
const byte iv[] = {
0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef
};
/* expected ciphertext matches wolfcrypt des_test */
const byte verify[] = {
0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8,
0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73,
0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b
};
byte cipher[sizeof(vector)];
byte plain[sizeof(vector)];
/* Encrypt */
ExpectIntEQ(wc_Des_CbcEncryptWithKey(cipher, vector, sizeof(vector),
key, iv), 0);
ExpectBufEQ(cipher, verify, sizeof(verify));
/* Decrypt */
ExpectIntEQ(wc_Des_CbcDecryptWithKey(plain, cipher, sizeof(cipher),
key, iv), 0);
ExpectBufEQ(plain, vector, sizeof(vector));
/* Bad args - encrypt */
ExpectIntEQ(wc_Des_CbcEncryptWithKey(NULL, vector, sizeof(vector), key, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Des_CbcEncryptWithKey(cipher, NULL, sizeof(vector), key, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Des_CbcEncryptWithKey(cipher, vector, sizeof(vector),
NULL, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* NULL iv is allowed (uses zero IV) */
ExpectIntEQ(wc_Des_CbcEncryptWithKey(cipher, vector, sizeof(vector),
key, NULL), 0);
/* Bad args - decrypt */
ExpectIntEQ(wc_Des_CbcDecryptWithKey(NULL, cipher, sizeof(cipher), key, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Des_CbcDecryptWithKey(plain, NULL, sizeof(cipher), key, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_Des_CbcDecryptWithKey(plain, cipher, sizeof(cipher),
NULL, iv),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* NULL iv is allowed (uses zero IV) */
ExpectIntEQ(wc_Des_CbcDecryptWithKey(plain, cipher, sizeof(cipher),
key, NULL), 0);
#endif
return EXPECT_RESULT();
} /* END test_wc_Des_CbcEncryptDecryptWithKey */
+4 -2
View File
@@ -25,8 +25,10 @@
#include <tests/api/api_decl.h>
int test_wc_Des3_CbcEncryptDecryptWithKey(void);
int test_wc_Des_CbcEncryptDecryptWithKey(void);
#define TEST_WC_ENCRYPT_DECLS \
TEST_DECL_GROUP("wc_encrypt", test_wc_Des3_CbcEncryptDecryptWithKey)
#define TEST_WC_ENCRYPT_DECLS \
TEST_DECL_GROUP("wc_encrypt", test_wc_Des3_CbcEncryptDecryptWithKey), \
TEST_DECL_GROUP("wc_encrypt", test_wc_Des_CbcEncryptDecryptWithKey)
#endif /* WOLFCRYPT_TEST_WC_ENCRYPT_H */
+32 -27
View File
@@ -16579,41 +16579,43 @@ static WARN_UNUSED_RESULT int AesSivCipher(
}
}
if (ret == 0 && dataSz > 0) {
sivTmp[12] &= 0x7f;
sivTmp[8] &= 0x7f;
ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
AES_ENCRYPTION);
if (ret != 0) {
WOLFSSL_MSG("Failed to set key for AES-CTR.");
}
else {
ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
if (ret == 0) {
if (dataSz > 0) {
sivTmp[12] &= 0x7f;
sivTmp[8] &= 0x7f;
ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
AES_ENCRYPTION);
if (ret != 0) {
WOLFSSL_MSG("AES-CTR encryption failed.");
WOLFSSL_MSG("Failed to set key for AES-CTR.");
}
else {
ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
if (ret != 0) {
WOLFSSL_MSG("AES-CTR encryption failed.");
}
}
}
}
if (ret == 0 && enc == 0) {
ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out, dataSz,
sivTmp);
if (ret != 0) {
WOLFSSL_MSG("S2V failed.");
if (ret == 0 && enc == 0) {
ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
dataSz, sivTmp);
if (ret != 0) {
WOLFSSL_MSG("S2V failed.");
}
if (ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
ret = AES_SIV_AUTH_E;
}
}
if (ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
ret = AES_SIV_AUTH_E;
}
#ifdef WOLFSSL_SMALL_STACK
wc_AesDelete(aes, NULL);
#else
wc_AesFree(aes);
#endif
}
#ifdef WOLFSSL_SMALL_STACK
wc_AesDelete(aes, NULL);
#else
wc_AesFree(aes);
#endif
ForceZero(sivTmp, sizeof(sivTmp));
return ret;
@@ -17036,6 +17038,9 @@ int wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
*/
int wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
{
if (eax == NULL) {
return BAD_FUNC_ARG;
}
return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
}