Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -12321,3 +12321,179 @@ int test_wc_AesOfb_MonteCarlo(void)
#endif
return EXPECT_RESULT();
}

#if defined(WOLF_CRYPTO_CB) && !defined(NO_AES) && defined(HAVE_AES_ECB) && \
defined(WOLFSSL_AES_128) && !defined(WOLF_CRYPTO_CB_ONLY_AES) && \
(defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESGCM))

#define TEST_CRYPTOCB_AESECB_FAIL_DEVID 13

static int cryptoCbAesEcbFailCalled = 0;

static int test_CryptoCb_AesEcbFail_Cb(int devId, wc_CryptoInfo* info,
void* ctx)
{
(void)devId;
(void)ctx;

if (info->algo_type == WC_ALGO_TYPE_CIPHER &&
info->cipher.type == WC_CIPHER_AES_ECB) {
cryptoCbAesEcbFailCalled++;
return WC_HW_E;
}

return CRYPTOCB_UNAVAILABLE;
}

#define TEST_AESECB_FAIL_SZ (2 * WC_AES_BLOCK_SIZE)

int test_wc_AesEcb_RetCodeChecked(void)
{
EXPECT_DECLS;
const byte key[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
byte plain[TEST_AESECB_FAIL_SZ];
byte out[TEST_AESECB_FAIL_SZ];
byte zeros[TEST_AESECB_FAIL_SZ];
int devRegistered = 0;
int exercised = 0;

XMEMSET(plain, 0x5a, sizeof(plain));
XMEMSET(zeros, 0, sizeof(zeros));

ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_CRYPTOCB_AESECB_FAIL_DEVID,
test_CryptoCb_AesEcbFail_Cb, NULL), 0);
if (EXPECT_SUCCESS())
devRegistered = 1;

#ifdef WOLFSSL_AES_COUNTER
{
Aes aes;
int ret = 0;
byte iv[WC_AES_BLOCK_SIZE] = {
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00
};

XMEMSET(&aes, 0, sizeof(aes));
XMEMSET(out, 0, sizeof(out));
cryptoCbAesEcbFailCalled = 0;

ExpectIntEQ(wc_AesInit(&aes, NULL, TEST_CRYPTOCB_AESECB_FAIL_DEVID), 0);
ExpectIntEQ(wc_AesSetKey(&aes, key, sizeof(key), iv, AES_ENCRYPTION), 0);
#ifdef WOLFSSL_AESNI
aes.use_aesni = 0;
#endif
if (EXPECT_SUCCESS())
ret = wc_AesCtrEncrypt(&aes, out, plain, sizeof(plain));

if (cryptoCbAesEcbFailCalled != 0) {
exercised = 1;
ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_HW_E));
ExpectBufEQ(out, zeros, sizeof(out));
}

wc_AesFree(&aes);
}
#endif /* WOLFSSL_AES_COUNTER */

#ifdef HAVE_AESGCM
{
Aes aes;
int ret = 0;
byte iv[GCM_NONCE_MID_SZ] = {
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5,
0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb
};
byte tag[WC_AES_BLOCK_SIZE];

XMEMSET(tag, 0, sizeof(tag));

XMEMSET(&aes, 0, sizeof(aes));
XMEMSET(out, 0, sizeof(out));
cryptoCbAesEcbFailCalled = 0;

ExpectIntEQ(wc_AesInit(&aes, NULL, TEST_CRYPTOCB_AESECB_FAIL_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetKey(&aes, key, sizeof(key)), 0);
#ifdef WOLFSSL_AESNI
aes.use_aesni = 0;
#endif
if (EXPECT_SUCCESS()) {
ret = wc_AesGcmEncrypt(&aes, out, plain, sizeof(plain),
iv, sizeof(iv), tag, sizeof(tag), NULL, 0);
}
if (cryptoCbAesEcbFailCalled != 0) {
exercised = 1;
ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_HW_E));
ExpectBufEQ(out, zeros, sizeof(out));
}
wc_AesFree(&aes);

XMEMSET(&aes, 0, sizeof(aes));
XMEMSET(out, 0, sizeof(out));
cryptoCbAesEcbFailCalled = 0;

ExpectIntEQ(wc_AesInit(&aes, NULL, TEST_CRYPTOCB_AESECB_FAIL_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetKey(&aes, key, sizeof(key)), 0);
#ifdef WOLFSSL_AESNI
aes.use_aesni = 0;
#endif
/* the tag is bogus, but the ECB failure is hit before it is checked
* unless the build authenticates early */
if (EXPECT_SUCCESS()) {
ret = wc_AesGcmDecrypt(&aes, out, plain, sizeof(plain),
iv, sizeof(iv), tag, sizeof(tag), NULL, 0);
}
if (cryptoCbAesEcbFailCalled != 0) {
exercised = 1;
ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_HW_E));
ExpectBufEQ(out, zeros, sizeof(out));
}
wc_AesFree(&aes);

#ifdef WOLFSSL_AESGCM_STREAM
XMEMSET(&aes, 0, sizeof(aes));
XMEMSET(out, 0, sizeof(out));
cryptoCbAesEcbFailCalled = 0;

ExpectIntEQ(wc_AesInit(&aes, NULL, TEST_CRYPTOCB_AESECB_FAIL_DEVID), 0);
ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key, sizeof(key), iv,
sizeof(iv)), 0);
#ifdef WOLFSSL_AESNI
aes.use_aesni = 0;
#endif
if (EXPECT_SUCCESS()) {
ret = wc_AesGcmEncryptUpdate(&aes, out, plain, sizeof(plain),
NULL, 0);
}
if (cryptoCbAesEcbFailCalled != 0) {
exercised = 1;
ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_HW_E));
ExpectBufEQ(out, zeros, sizeof(out));
}
wc_AesFree(&aes);
#endif /* WOLFSSL_AESGCM_STREAM */
}
#endif /* HAVE_AESGCM */

if (devRegistered)
wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_AESECB_FAIL_DEVID);

/* no mode in this build stages its keystream with wc_AesEcbEncrypt() */
if (EXPECT_SUCCESS() && !exercised)
return TEST_SKIPPED;

return EXPECT_RESULT();
}

#else

int test_wc_AesEcb_RetCodeChecked(void)
{
return TEST_SKIPPED;
}

#endif /* WOLF_CRYPTO_CB && !NO_AES && HAVE_AES_ECB && WOLFSSL_AES_128 &&
* !WOLF_CRYPTO_CB_ONLY_AES && (WOLFSSL_AES_COUNTER || HAVE_AESGCM) */
4 changes: 3 additions & 1 deletion tests/api/test_aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ int test_wc_CryptoCb_AesCfb_EncryptDecrypt(void);
!defined(WOLF_CRYPTO_CB_ONLY_AES)
int test_wc_CryptoCb_AesOfb_EncryptDecrypt(void);
#endif
int test_wc_AesEcb_RetCodeChecked(void);

/* These test functions always have a (possibly empty) definition in
* test_aes.c so that callers can reference them unconditionally. Declare
Expand Down Expand Up @@ -226,7 +227,8 @@ int test_wc_CryptoCb_Tls13_Key_No_Zero_Without_Offload(void);
TEST_DECL_GROUP("aes", test_wc_AesGcm_MonteCarlo), \
TEST_DECL_GROUP("aes", test_wc_AesCcm_MonteCarlo), \
TEST_DECL_GROUP("aes", test_wc_AesCfb_MonteCarlo), \
TEST_DECL_GROUP("aes", test_wc_AesOfb_MonteCarlo) \
TEST_DECL_GROUP("aes", test_wc_AesOfb_MonteCarlo), \
TEST_DECL_GROUP("aes", test_wc_AesEcb_RetCodeChecked) \
TEST_CRYPTOCB_AES_SETKEY_DECL \
TEST_CRYPTOCB_TLS13_KEY_ZERO_DECL \
TEST_CRYPTOCB_AESCFB_DECL \
Expand Down
34 changes: 26 additions & 8 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -7921,11 +7921,17 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)

/* reset number of blocks and then do encryption */
blocks = sz / WC_AES_BLOCK_SIZE;
wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
in += WC_AES_BLOCK_SIZE * blocks;
out += WC_AES_BLOCK_SIZE * blocks;
sz -= blocks * WC_AES_BLOCK_SIZE;
ret = wc_AesEcbEncrypt(aes, out, out,
WC_AES_BLOCK_SIZE * blocks);
Comment on lines 7921 to +7925

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think the object should not be re-used in case of error

if (ret == 0) {
xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
in += WC_AES_BLOCK_SIZE * blocks;
out += WC_AES_BLOCK_SIZE * blocks;
sz -= blocks * WC_AES_BLOCK_SIZE;
}
else {
ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
}
}
else
#endif
Expand Down Expand Up @@ -10752,7 +10758,11 @@ WARN_UNUSED_RESULT int AES_GCM_encrypt_C(

/* reset number of blocks and then do encryption */
blocks = sz / WC_AES_BLOCK_SIZE;
wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
if (ret != 0) {
ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
return ret;
}
xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
p += WC_AES_BLOCK_SIZE * blocks;
}
Expand Down Expand Up @@ -11572,7 +11582,11 @@ int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
/* reset number of blocks and then do encryption */
blocks = sz / WC_AES_BLOCK_SIZE;

wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
if (ret != 0) {
ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
return ret;
}
xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
c += WC_AES_BLOCK_SIZE * blocks;
}
Expand Down Expand Up @@ -12081,7 +12095,11 @@ static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
}

/* Encrypt counter blocks. */
wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
ret = wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
if (ret != 0) {
ForceZero(out, WC_AES_BLOCK_SIZE * blocks);
return ret;
}
/* XOR in plaintext. */
xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
/* Skip over processed data. */
Expand Down
Loading