Merge pull request #3841 from SparkiDev/aes_gcm_stream

AES GCM: implement streaming
This commit is contained in:
toddouska
2021-03-18 14:36:55 -07:00
committed by GitHub
10 changed files with 9286 additions and 84 deletions

View File

@@ -1300,6 +1300,11 @@ AC_ARG_ENABLE([aesgcm],
[ ENABLED_AESGCM=$enableval ],
[ ENABLED_AESGCM=yes ]
)
AC_ARG_ENABLE([aesgcm-stream],
[AS_HELP_STRING([--enable-aesgcm-stream],[Enable wolfSSL AES-GCM support with streaming APIs (default: enabled)])],
[ ENABLED_AESGCM_STREAM=$enableval ],
[ ENABLED_AESGCM_STREAM=no ]
)
# leanpsk and leantls don't need gcm
if test "$ENABLED_LEANPSK" = "yes" || ( test "$ENABLED_LEANTLS" = "yes" &&
@@ -5979,6 +5984,16 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"
fi
if test "$ENABLED_AESGCM_STREAM" != "no"
then
if test "$ENABLED_AESGCM" = "no"
then
AC_MSG_ERROR([AES-GCM streaming enabled but AES-GCM is disabled])
else
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESGCM_STREAM"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESGCM_STREAM"
fi
fi
AS_IF([test "x$ENABLED_MAXSTRENGTH" = "xyes"],

View File

@@ -11614,6 +11614,208 @@ static int test_wc_AesCmacGenerate (void)
} /* END test_wc_AesCmacGenerate */
/*
* Testing streaming AES-GCM API.
*/
static int test_wc_AesGcmStream (void)
{
int ret = 0;
#if !defined(NO_AES) && defined(WOLFSSL_AES_128) && defined(HAVE_AESGCM) && \
defined(WOLFSSL_AESGCM_STREAM)
int i;
WC_RNG rng[1];
Aes aesEnc[1];
Aes aesDec[1];
byte tag[AES_BLOCK_SIZE];
byte in[AES_BLOCK_SIZE * 3 + 2] = { 0, };
byte out[AES_BLOCK_SIZE * 3 + 2];
byte plain[AES_BLOCK_SIZE * 3 + 2];
byte aad[AES_BLOCK_SIZE * 3 + 2] = { 0, };
byte key[AES_128_KEY_SIZE] = { 0, };
byte iv[AES_IV_SIZE] = { 1, };
byte ivOut[AES_IV_SIZE];
static const byte expTagAAD1[AES_BLOCK_SIZE] = {
0x6c, 0x35, 0xe6, 0x7f, 0x59, 0x9e, 0xa9, 0x2f,
0x27, 0x2d, 0x5f, 0x8e, 0x7e, 0x42, 0xd3, 0x05
};
static const byte expTagPlain1[AES_BLOCK_SIZE] = {
0x24, 0xba, 0x57, 0x95, 0xd0, 0x27, 0x9e, 0x78,
0x3a, 0x88, 0x4c, 0x0a, 0x5d, 0x50, 0x23, 0xd1
};
static const byte expTag[AES_BLOCK_SIZE] = {
0x22, 0x91, 0x70, 0xad, 0x42, 0xc3, 0xad, 0x96,
0xe0, 0x31, 0x57, 0x60, 0xb7, 0x92, 0xa3, 0x6d
};
/* Create a random for generating IV/nonce. */
AssertIntEQ(wc_InitRng(rng), 0);
/* Initialize data structures. */
AssertIntEQ(wc_AesInit(aesEnc, NULL, INVALID_DEVID), 0);
AssertIntEQ(wc_AesInit(aesDec, NULL, INVALID_DEVID), 0);
/* BadParameters to streaming init. */
AssertIntEQ(wc_AesGcmEncryptInit(NULL, NULL, 0, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptInit(NULL, NULL, 0, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptInit(aesEnc, NULL, AES_128_KEY_SIZE, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptInit(aesEnc, NULL, 0, NULL, GCM_NONCE_MID_SZ),
BAD_FUNC_ARG);
/* Bad parameters to encrypt update. */
AssertIntEQ(wc_AesGcmEncryptUpdate(NULL, NULL, NULL, 0, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, in, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, NULL, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, NULL, 1),
BAD_FUNC_ARG);
/* Bad parameters to decrypt update. */
AssertIntEQ(wc_AesGcmDecryptUpdate(NULL, NULL, NULL, 0, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, in, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, out, NULL, 1, NULL, 0),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, NULL, 1),
BAD_FUNC_ARG);
/* Bad parameters to encrypt final. */
AssertIntEQ(wc_AesGcmEncryptFinal(NULL, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptFinal(NULL, tag, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptFinal(NULL, NULL, AES_BLOCK_SIZE),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, NULL, AES_BLOCK_SIZE),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE + 1),
BAD_FUNC_ARG);
/* Bad parameters to decrypt final. */
AssertIntEQ(wc_AesGcmDecryptFinal(NULL, NULL, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptFinal(NULL, tag, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptFinal(NULL, NULL, AES_BLOCK_SIZE),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, 0), BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, NULL, AES_BLOCK_SIZE),
BAD_FUNC_ARG);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE + 1),
BAD_FUNC_ARG);
/* Check calling final before setting key fails. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, sizeof(tag)), MISSING_KEY);
AssertIntEQ(wc_AesGcmEncryptFinal(aesDec, tag, sizeof(tag)), MISSING_KEY);
/* Check calling update before setting key else fails. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1),
MISSING_KEY);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1),
MISSING_KEY);
/* Set key but not IV. */
AssertIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), NULL, 0), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), NULL, 0), 0);
/* Check calling final before setting IV fails. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, sizeof(tag)), MISSING_IV);
AssertIntEQ(wc_AesGcmEncryptFinal(aesDec, tag, sizeof(tag)), MISSING_IV);
/* Check calling update before setting IV else fails. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1),
MISSING_IV);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1),
MISSING_IV);
/* Set IV using fixed part IV and external IV APIs. */
AssertIntEQ(wc_AesGcmSetIV(aesEnc, GCM_NONCE_MID_SZ, iv, AES_IV_FIXED_SZ,
rng), 0);
AssertIntEQ(wc_AesGcmEncryptInit_ex(aesEnc, NULL, 0, ivOut,
GCM_NONCE_MID_SZ), 0);
AssertIntEQ(wc_AesGcmSetExtIV(aesDec, ivOut, GCM_NONCE_MID_SZ), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, NULL, 0, NULL, 0), 0);
/* Encrypt and decrypt data. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, 1, aad, 1), 0);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, 1, aad, 1), 0);
AssertIntEQ(XMEMCMP(plain, in, 1), 0);
/* Finalize and check tag matches. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);
/* Set key and IV through streaming init API. */
AssertIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
/* Encrypt/decrypt one block and AAD of one block. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, AES_BLOCK_SIZE, aad,
AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, AES_BLOCK_SIZE, aad,
AES_BLOCK_SIZE), 0);
AssertIntEQ(XMEMCMP(plain, in, AES_BLOCK_SIZE), 0);
/* Finalize and check tag matches. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);
/* Set key and IV through streaming init API. */
AssertIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
/* No data to encrypt/decrypt one byte of AAD. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad, 1), 0);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad, 1), 0);
/* Finalize and check tag matches. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
AssertIntEQ(XMEMCMP(tag, expTagAAD1, AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);
/* Set key and IV through streaming init API. */
AssertIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
/* Encrypt/decrypt one byte and no AAD. */
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out, in, 1, NULL, 0), 0);
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain, out, 1, NULL, 0), 0);
AssertIntEQ(XMEMCMP(plain, in, 1), 0);
/* Finalize and check tag matches. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
AssertIntEQ(XMEMCMP(tag, expTagPlain1, AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);
/* Set key and IV through streaming init API. */
AssertIntEQ(wc_AesGcmInit(aesEnc, key, sizeof(key), iv, AES_IV_SIZE), 0);
AssertIntEQ(wc_AesGcmInit(aesDec, key, sizeof(key), iv, AES_IV_SIZE), 0);
/* Encryption AES is one byte at a time */
for (i = 0; i < (int)sizeof(aad); i++) {
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, NULL, NULL, 0, aad + i, 1),
0);
}
for (i = 0; i < (int)sizeof(in); i++) {
AssertIntEQ(wc_AesGcmEncryptUpdate(aesEnc, out + i, in + i, 1, NULL, 0),
0);
}
/* Decryption AES is two bytes at a time */
for (i = 0; i < (int)sizeof(aad); i += 2) {
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, NULL, NULL, 0, aad + i, 2),
0);
}
for (i = 0; i < (int)sizeof(aad); i += 2) {
AssertIntEQ(wc_AesGcmDecryptUpdate(aesDec, plain + i, out + i, 2, NULL,
0), 0);
}
AssertIntEQ(XMEMCMP(plain, in, sizeof(in)), 0);
/* Finalize and check tag matches. */
AssertIntEQ(wc_AesGcmEncryptFinal(aesEnc, tag, AES_BLOCK_SIZE), 0);
AssertIntEQ(XMEMCMP(tag, expTag, AES_BLOCK_SIZE), 0);
AssertIntEQ(wc_AesGcmDecryptFinal(aesDec, tag, AES_BLOCK_SIZE), 0);
/* Check streaming encryption can be decrypted with one shot. */
AssertIntEQ(wc_AesGcmSetKey(aesDec, key, sizeof(key)), 0);
AssertIntEQ(wc_AesGcmDecrypt(aesDec, plain, out, sizeof(in), iv,
AES_IV_SIZE, tag, AES_BLOCK_SIZE, aad, sizeof(aad)), 0);
AssertIntEQ(XMEMCMP(plain, in, sizeof(in)), 0);
#endif
return ret;
} /* END test_wc_AesGcmStream */
/*
@@ -39748,15 +39950,19 @@ static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
const byte iv[12] = { 0 };
const byte key[16] = { 0 };
const byte cleartext[16] = { 0 };
const byte aad[] = {0x01, 0x10, 0x00, 0x2a, 0x08, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xdc, 0x4d,
0xad, 0x6b, 0x06, 0x93, 0x4f};
const byte aad[] = {
0x01, 0x10, 0x00, 0x2a, 0x08, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0xdc, 0x4d, 0xad, 0x6b, 0x06, 0x93,
0x4f
};
byte out1Part[16];
byte outTag1Part[16];
byte out2Part[16];
byte outTag2Part[16];
byte decryptBuf[16];
int len;
int tlen;
EVP_CIPHER_CTX* ctx = NULL;
printf(testingFmt, "wolfssl_EVP_aes_gcm_AAD_2_parts");
@@ -39764,25 +39970,37 @@ static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
/* ENCRYPT */
/* Send AAD and data in 1 part */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
tlen = 0;
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
1);
AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out1Part, &len, cleartext, sizeof(cleartext)), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out1Part, &len, cleartext,
sizeof(cleartext)), 1);
tlen += len;
AssertIntEQ(EVP_EncryptFinal_ex(ctx, out1Part, &len), 1);
AssertIntEQ(len, sizeof(cleartext));
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outTag1Part), 1);
tlen += len;
AssertIntEQ(tlen, sizeof(cleartext));
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16,
outTag1Part), 1);
EVP_CIPHER_CTX_free(ctx);
/* DECRYPT */
/* Send AAD and data in 1 part */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
tlen = 0;
AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
1);
AssertIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part, sizeof(cleartext)), 1);
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, outTag1Part), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part,
sizeof(cleartext)), 1);
tlen += len;
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16,
outTag1Part), 1);
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf, &len), 1);
AssertIntEQ(len, sizeof(cleartext));
tlen += len;
AssertIntEQ(tlen, sizeof(cleartext));
EVP_CIPHER_CTX_free(ctx);
AssertIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0);
@@ -39790,16 +40008,23 @@ static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
/* ENCRYPT */
/* Send AAD and data in 2 parts */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
tlen = 0;
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
1);
AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, 1), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1),
1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out2Part, &len, cleartext, 1), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out2Part, &len, cleartext + 1,
tlen += len;
AssertIntEQ(EVP_EncryptUpdate(ctx, out2Part + tlen, &len, cleartext + 1,
sizeof(cleartext) - 1), 1);
AssertIntEQ(EVP_EncryptFinal_ex(ctx, out2Part, &len), 1);
AssertIntEQ(len, sizeof(cleartext));
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outTag2Part), 1);
tlen += len;
AssertIntEQ(EVP_EncryptFinal_ex(ctx, out2Part + tlen, &len), 1);
tlen += len;
AssertIntEQ(tlen, sizeof(cleartext));
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16,
outTag2Part), 1);
AssertIntEQ(XMEMCMP(out1Part, out2Part, sizeof(out1Part)), 0);
AssertIntEQ(XMEMCMP(outTag1Part, outTag2Part, sizeof(outTag1Part)), 0);
@@ -39808,16 +40033,23 @@ static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
/* DECRYPT */
/* Send AAD and data in 2 parts */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
tlen = 0;
AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL),
1);
AssertIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad, 1), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1),
1);
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part, 1), 1);
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptBuf, &len, out1Part + 1,
tlen += len;
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptBuf + tlen, &len, out1Part + 1,
sizeof(cleartext) - 1), 1);
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, outTag1Part), 1);
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf, &len), 1);
AssertIntEQ(len, sizeof(cleartext));
tlen += len;
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16,
outTag1Part), 1);
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptBuf + tlen, &len), 1);
tlen += len;
AssertIntEQ(tlen, sizeof(cleartext));
AssertIntEQ(XMEMCMP(decryptBuf, cleartext, len), 0);
@@ -39834,14 +40066,15 @@ static void test_wolfssl_EVP_aes_gcm_zeroLen(void)
{
/* Zero length plain text */
byte key[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
byte key[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; /* align */
byte iv[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/* align */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}; /* align */
byte iv[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}; /* align */
byte plaintxt[0];
int ivSz = 12;
int plaintxtSz = 0;
@@ -39861,7 +40094,8 @@ static void test_wolfssl_EVP_aes_gcm_zeroLen(void)
AssertIntEQ(1, EVP_EncryptInit_ex(en, EVP_aes_256_gcm(), NULL, key, iv));
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL));
AssertIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt, plaintxtSz));
AssertIntEQ(1, EVP_EncryptUpdate(en, ciphertxt, &ciphertxtSz , plaintxt,
plaintxtSz));
AssertIntEQ(1, EVP_EncryptFinal_ex(en, ciphertxt, &len));
ciphertxtSz += len;
AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(en, EVP_CTRL_GCM_GET_TAG, 16, tag));
@@ -41833,6 +42067,7 @@ void ApiTest(void)
AssertIntEQ(test_wc_CmacUpdate(), 0);
AssertIntEQ(test_wc_CmacFinal(), 0);
AssertIntEQ(test_wc_AesCmacGenerate(), 0);
AssertIntEQ(test_wc_AesGcmStream(), 0);
AssertIntEQ(test_wc_Des3_SetIV(), 0);
AssertIntEQ(test_wc_Des3_SetKey(), 0);

View File

@@ -2394,10 +2394,23 @@ static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz,
/* while free pending slots in queue, submit ops */
for (i = 0; i < BENCH_MAX_PENDING; i++) {
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
#ifndef BENCHMARK_AESGCM_STREAM
ret = wc_AesGcmEncrypt(&enc[i], bench_cipher,
bench_plain, BENCH_SIZE,
iv, ivSz, bench_tag, AES_AUTH_TAG_SZ,
bench_additional, aesAuthAddSz);
#else
ret = wc_AesGcmEncryptInit(&enc[i], NULL, 0, iv, ivSz);
if (ret == 0) {
ret = wc_AesGcmEncryptUpdate(&enc[i], bench_cipher,
bench_plain, BENCH_SIZE, bench_additional,
aesAuthAddSz);
}
if (ret == 0) {
ret = wc_AesGcmEncryptFinal(&enc[i], bench_tag,
AES_AUTH_TAG_SZ);
}
#endif
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
goto exit_aes_gcm;
}
@@ -2433,10 +2446,23 @@ exit_aes_gcm:
/* while free pending slots in queue, submit ops */
for (i = 0; i < BENCH_MAX_PENDING; i++) {
if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, &times, numBlocks, &pending)) {
#ifndef BENCHMARK_AESGCM_STREAM
ret = wc_AesGcmDecrypt(&dec[i], bench_plain,
bench_cipher, BENCH_SIZE,
iv, ivSz, bench_tag, AES_AUTH_TAG_SZ,
bench_additional, aesAuthAddSz);
#else
ret = wc_AesGcmDecryptInit(&enc[i], NULL, 0, iv, ivSz);
if (ret == 0) {
ret = wc_AesGcmDecryptUpdate(&enc[i], bench_plain,
bench_cipher, BENCH_SIZE, bench_additional,
aesAuthAddSz);
}
if (ret == 0) {
ret = wc_AesGcmDecryptFinal(&enc[i], bench_tag,
AES_AUTH_TAG_SZ);
}
#endif
if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, &times, &pending)) {
goto exit_aes_gcm_dec;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -521,6 +521,12 @@ const char* wc_GetErrorString(int error)
case SAKKE_VERIFY_FAIL_E:
return "SAKKE derivation verification error";
case MISSING_IV:
return "Required IV not set";
case MISSING_KEY:
return "Required key not set";
default:
return "unknown error number";

View File

@@ -553,6 +553,7 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
}
#if defined(HAVE_AESGCM)
#ifndef WOLFSSL_AESGCM_STREAM
static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
const unsigned char *in, int inl) {
if (in && inl > 0) {
@@ -570,11 +571,13 @@ static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
}
return 0;
}
#endif /* WOLFSSL_AESGCM_STREAM */
static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
#ifndef WOLFSSL_AESGCM_STREAM
int ret = 0;
*outl = inl;
@@ -606,8 +609,42 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
}
return WOLFSSL_SUCCESS;
#else
int ret;
/* When out is NULL then this is AAD. */
if (out == NULL) {
if (ctx->enc) {
ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in,
inl);
}
else {
ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL, NULL, 0, in,
inl);
}
}
/* When out is not NULL then this is plaintext/cipher text. */
else {
if (ctx->enc) {
ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, out, in, inl, NULL,
0);
}
else {
ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, out, in, inl, NULL,
0);
}
}
*outl = inl;
if (ret == 0) {
ret = WOLFSSL_SUCCESS;
}
else {
ret = WOLFSSL_FAILURE;
}
return ret;
#endif /* WOLFSSL_AESGCM_STREAM */
}
#endif
#endif /* HAVE_AESGCM */
/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
@@ -626,16 +663,16 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
*outl = 0;
#if !defined(NO_AES) && defined(HAVE_AESGCM)
switch (ctx->cipherType) {
case AES_128_GCM_TYPE:
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
/* if out == NULL, in/inl contains the additional authenticated data for GCM */
return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);
default:
/* fall-through */
break;
}
switch (ctx->cipherType) {
case AES_128_GCM_TYPE:
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
/* if out == NULL, in/inl contains the additional authenticated data * for GCM */
return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl);
default:
/* fall-through */
break;
}
#endif /* !defined(NO_AES) && defined(HAVE_AESGCM) */
if (out == NULL) {
@@ -770,6 +807,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
case AES_128_GCM_TYPE:
case AES_192_GCM_TYPE:
case AES_256_GCM_TYPE:
#ifndef WOLFSSL_AESGCM_STREAM
if ((ctx->gcmBuffer && ctx->gcmBufferLen > 0)
|| (ctx->gcmBufferLen == 0)) {
if (ctx->enc)
@@ -799,6 +837,24 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
else {
*outl = 0;
}
#else
/* No data to return - all handled in Update. */
*outl = 0;
if (ctx->enc) {
ret = wc_AesGcmEncryptFinal(&ctx->cipher.aes, ctx->authTag,
ctx->authTagSz);
}
else {
ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes, ctx->authTag,
ctx->authTagSz);
}
if (ret == 0) {
ret = WOLFSSL_SUCCESS;
}
else {
ret = WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_AESGCM_STREAM */
/* Clear IV, since IV reuse is not recommended for AES GCM. */
XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE);
break;
@@ -4073,10 +4129,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
WOLFSSL_MSG("Key or IV not set");
break;
}
if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, ctx->ivSz)) != 0) {
if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv,
ctx->ivSz)) != 0) {
WOLFSSL_MSG("wc_AesGcmSetIV failed");
ret = WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_AESGCM_STREAM
/* Initialize using IV cached in Aes object. */
if (wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, NULL, 0) != 0) {
WOLFSSL_MSG("wc_AesGcmInit failed");
ret = WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_AESGCM_STREAM */
/* OpenSSL increments the IV. Not sure why */
IncCtr(ctx->iv, ctx->ivSz);
break;
@@ -4373,14 +4437,25 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
ctx->authTagSz = AES_BLOCK_SIZE;
ctx->ivSz = GCM_NONCE_MID_SZ;
#ifndef WOLFSSL_AESGCM_STREAM
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
return WOLFSSL_FAILURE;
}
#endif /* !WOLFSSL_AESGCM_STREAM */
if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_AESGCM_STREAM
/* Initialize with key and IV if available. */
if (wc_AesGcmInit(&ctx->cipher.aes, key,
(key == NULL) ? 0 : ctx->keyLen, iv,
(iv == NULL) ? 0 : GCM_NONCE_MID_SZ) != 0) {
WOLFSSL_MSG("wc_AesGcmInit() failed");
return WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
}
@@ -4398,14 +4473,25 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
ctx->authTagSz = AES_BLOCK_SIZE;
ctx->ivSz = GCM_NONCE_MID_SZ;
#ifndef WOLFSSL_AESGCM_STREAM
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
return WOLFSSL_FAILURE;
}
#endif /* !WOLFSSL_AESGCM_STREAM */
if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_AESGCM_STREAM
/* Initialize with key and IV if available. */
if (wc_AesGcmInit(&ctx->cipher.aes, key,
(key == NULL) ? 0 : ctx->keyLen, iv,
(iv == NULL) ? 0 : GCM_NONCE_MID_SZ) != 0) {
WOLFSSL_MSG("wc_AesGcmInit() failed");
return WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
}
@@ -4423,14 +4509,25 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
ctx->authTagSz = AES_BLOCK_SIZE;
ctx->ivSz = GCM_NONCE_MID_SZ;
#ifndef WOLFSSL_AESGCM_STREAM
if (key && wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen)) {
WOLFSSL_MSG("wc_AesGcmSetKey() failed");
return WOLFSSL_FAILURE;
}
#endif /* !WOLFSSL_AESGCM_STREAM */
if (iv && wc_AesGcmSetExtIV(&ctx->cipher.aes, iv, GCM_NONCE_MID_SZ)) {
WOLFSSL_MSG("wc_AesGcmSetExtIV() failed");
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_AESGCM_STREAM
/* Initialize with key and IV if available. */
if (wc_AesGcmInit(&ctx->cipher.aes,
key, (key == NULL) ? 0 : ctx->keyLen,
iv, (iv == NULL) ? 0 : GCM_NONCE_MID_SZ) != 0) {
WOLFSSL_MSG("wc_AesGcmInit() failed");
return WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
}
@@ -4482,7 +4579,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
if (key) {
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
AES_ENCRYPTION, 1);
if (ret != 0)
return WOLFSSL_FAILURE;
@@ -4510,7 +4607,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
if (key) {
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
AES_ENCRYPTION, 1);
if (ret != 0)
return WOLFSSL_FAILURE;
@@ -4536,7 +4633,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
if (enc == 0 || enc == 1)
ctx->enc = enc ? 1 : 0;
if (key) {
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL,
ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1);
}
if (ret != 0)
@@ -5262,6 +5359,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
case AES_192_GCM_TYPE :
case AES_256_GCM_TYPE :
WOLFSSL_MSG("AES GCM");
#ifndef WOLFSSL_AESGCM_STREAM
if (!dst) {
ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, src, len);
}
@@ -5275,6 +5373,50 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
len, ctx->iv, ctx->ivSz, ctx->authTag,
ctx->authTagSz, ctx->gcmAuthIn, ctx->gcmAuthInSz);
}
#else
/* Do one shot operation with streaming API as other
* initialization set up for streaming. */
ret = wc_AesGcmInit(&ctx->cipher.aes, NULL, 0, ctx->iv,
ctx->ivSz);
/* No destination means only AAD. */
if ((ret == 0) && (dst == NULL)) {
if (ctx->enc) {
ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, NULL,
NULL, 0, src, len);
}
else {
ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, NULL,
NULL, 0, src, len);
}
}
/* Only plaintext/cipher text. */
else if (ret == 0) {
if (ctx->enc) {
ret = wc_AesGcmEncryptUpdate(&ctx->cipher.aes, dst, src,
len, NULL, 0);
}
else {
ret = wc_AesGcmDecryptUpdate(&ctx->cipher.aes, dst, src,
len, NULL, 0);
if (ret == 0) {
ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes,
ctx->authTag, ctx->authTagSz);
}
}
}
if (ret == 0) {
if (ctx->enc) {
/* Calculate authentication tag. */
ret = wc_AesGcmEncryptFinal(&ctx->cipher.aes,
ctx->authTag, ctx->authTagSz);
}
else {
/* Calculate authentication tag and compare. */
ret = wc_AesGcmDecryptFinal(&ctx->cipher.aes,
ctx->authTag, ctx->authTagSz);
}
}
#endif /* WOLFSSL_AESGCM_STREAM */
if (ret == 0)
ret = len;
break;

View File

@@ -10045,6 +10045,103 @@ WOLFSSL_TEST_SUBROUTINE int aesgcm_test(void)
#endif /* WOLFSSL_AES_256 && !(WC_NO_RNG || HAVE_SELFTEST) */
#endif /* HAVE_FIPS_VERSION >= 2 */
#if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT)
#ifdef WOLFSSL_AES_256
#ifdef WOLFSSL_AESGCM_STREAM
result = wc_AesGcmEncryptInit(enc, k1, sizeof(k1), iv1, sizeof(iv1));
if (result != 0)
ERROR_OUT(-6360, out);
result = wc_AesGcmEncryptUpdate(enc, resultC, p, sizeof(p), a, sizeof(a));
if (result != 0)
ERROR_OUT(-6361, out);
result = wc_AesGcmEncryptFinal(enc, resultT, sizeof(resultT));
if (result != 0)
ERROR_OUT(-6362, out);
if (XMEMCMP(resultC, c1, sizeof(c1)) != 0)
ERROR_OUT(-6363, out);
if (XMEMCMP(resultT, t1, sizeof(t1)) != 0)
ERROR_OUT(-6364, out);
#ifdef HAVE_AES_DECRYPT
result = wc_AesGcmDecryptInit(enc, k1, sizeof(k1), iv1, sizeof(iv1));
if (result != 0)
ERROR_OUT(-6370, out);
result = wc_AesGcmDecryptUpdate(enc, resultP, c1, sizeof(c1), a, sizeof(a));
if (result != 0)
ERROR_OUT(-6371, out);
result = wc_AesGcmDecryptFinal(enc, t1, sizeof(t1));
if (result != 0)
ERROR_OUT(-6372, out);
if (XMEMCMP(resultP, p, sizeof(p)) != 0)
ERROR_OUT(-6373, out);
#endif
/* alen is the size to pass in with each update. */
for (alen = 1; alen < AES_BLOCK_SIZE + 1; alen++) {
result = wc_AesGcmEncryptInit(enc, k1, sizeof(k1), iv1, sizeof(iv1));
if (result != 0)
ERROR_OUT(-6380, out);
/* plen is the offset into AAD to update with. */
for (plen = 0; plen < (int)sizeof(a); plen += alen) {
int len = sizeof(a) - plen;
if (len > alen) len = alen;
result = wc_AesGcmEncryptUpdate(enc, NULL, NULL, 0, a + plen, len);
if (result != 0)
ERROR_OUT(-6381, out);
}
/* plen is the offset into plaintext to update with. */
for (plen = 0; plen < (int)sizeof(p); plen += alen) {
int len = sizeof(p) - plen;
if (len > alen) len = alen;
result = wc_AesGcmEncryptUpdate(enc, resultC + plen, p + plen, len,
NULL, 0);
if (result != 0)
ERROR_OUT(-6382, out);
}
result = wc_AesGcmEncryptFinal(enc, resultT, sizeof(resultT));
if (result != 0)
ERROR_OUT(-6383, out);
if (XMEMCMP(resultC, c1, sizeof(c1)) != 0)
ERROR_OUT(-6384, out);
if (XMEMCMP(resultT, t1, sizeof(t1)) != 0)
ERROR_OUT(-6385, out);
}
#ifdef HAVE_AES_DECRYPT
for (alen = 1; alen < AES_BLOCK_SIZE + 1; alen++) {
result = wc_AesGcmDecryptInit(enc, k1, sizeof(k1), iv1, sizeof(iv1));
if (result != 0)
ERROR_OUT(-6390, out);
/* plen is the offset into AAD to update with. */
for (plen = 0; plen < (int)sizeof(a); plen += alen) {
int len = sizeof(a) - plen;
if (len > alen) len = alen;
result = wc_AesGcmDecryptUpdate(enc, NULL, NULL, 0, a + plen, len);
if (result != 0)
ERROR_OUT(-6391, out);
}
/* plen is the offset into cipher text to update with. */
for (plen = 0; plen < (int)sizeof(c1); plen += alen) {
int len = sizeof(c1) - plen;
if (len > alen) len = alen;
result = wc_AesGcmDecryptUpdate(enc, resultP + plen, c1 + plen, len,
NULL, 0);
if (result != 0)
ERROR_OUT(-6392, out);
}
result = wc_AesGcmDecryptFinal(enc, t1, sizeof(t1));
if (result != 0)
ERROR_OUT(-6393, out);
if (XMEMCMP(resultP, p, sizeof(p)) != 0)
ERROR_OUT(-6394, out);
}
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AESGCM_STREAM */
#endif /* WOLFSSL_AES_256 */
#endif /* !WOLFSSL_AFALG_XILINX_AES && !WOLFSSL_XILINX_CRYPT */
wc_AesFree(enc);
wc_AesFree(dec);

View File

@@ -250,6 +250,21 @@ struct Aes {
silabs_aes_t ctx;
#endif
void* heap; /* memory hint to use */
#ifdef WOLFSSL_AESGCM_STREAM
#if !defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_AESNI)
ALIGN16 byte streamData[5 * AES_BLOCK_SIZE];
#else
byte* streamData;
#endif
word32 aSz;
word32 cSz;
byte over;
byte aOver;
byte cOver;
byte gcmKeySet:1;
byte nonceSet:1;
byte ctrSet:1;
#endif
};
#ifndef WC_AES_TYPE_DEFINED
@@ -361,6 +376,26 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
const byte* iv, word32 ivSz,
const byte* authTag, word32 authTagSz,
const byte* authIn, word32 authInSz);
#ifdef WOLFSSL_AESGCM_STREAM
WOLFSSL_API int wc_AesGcmInit(Aes* aes, const byte* key, word32 len,
const byte* iv, word32 ivSz);
WOLFSSL_API int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len,
const byte* iv, word32 ivSz);
WOLFSSL_API int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len,
byte* ivOut, word32 ivOutSz);
WOLFSSL_API int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in,
word32 sz, const byte* authIn, word32 authInSz);
WOLFSSL_API int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag,
word32 authTagSz);
WOLFSSL_API int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len,
const byte* iv, word32 ivSz);
WOLFSSL_API int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in,
word32 sz, const byte* authIn, word32 authInSz);
WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag,
word32 authTagSz);
#endif
#ifndef WC_NO_RNG
WOLFSSL_API int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz);

View File

@@ -235,8 +235,10 @@ enum {
CHACHA_POLY_OVERFLOW =-274, /* ChaCha20Poly1305 limit overflow */
ASN_SELF_SIGNED_E = -275, /* ASN self-signed certificate error */
SAKKE_VERIFY_FAIL_E = -276, /* SAKKE derivation verification error */
MISSING_IV = -277, /* IV was not set */
MISSING_KEY = -278, /* Key was not set */
WC_LAST_E = -276, /* Update this to indicate last error */
WC_LAST_E = -278, /* Update this to indicate last error */
MIN_CODE_E = -300 /* errors -101 - -299 */
/* add new companion error id strings for any new error codes