mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
New API's for ChaCha20/Poly1305 AEAD init/update/final:
* Provides a context for AEAD to allow "chunked" updates of data then a final calculation for the authentication tag. * New API's are on by default and can be disabled using NO_CHACHAPOLY_AEAD_IUF.
This commit is contained in:
@ -32,8 +32,6 @@
|
||||
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/chacha.h>
|
||||
#include <wolfssl/wolfcrypt/poly1305.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
@ -121,7 +119,6 @@ int wc_ChaCha20Poly1305_Decrypt(
|
||||
byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
|
||||
|
||||
/* Validate function arguments */
|
||||
|
||||
if (!inKey || !inIV ||
|
||||
!inCiphertext || !inCiphertextLen ||
|
||||
!inAuthTag ||
|
||||
@ -152,11 +149,8 @@ int wc_ChaCha20Poly1305_Decrypt(
|
||||
calculatedAuthTag);
|
||||
|
||||
/* Compare the calculated auth tag with the received one */
|
||||
if (err == 0 && ConstantCompare(inAuthTag, calculatedAuthTag,
|
||||
CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) != 0)
|
||||
{
|
||||
err = MAC_CMP_FAILED_E;
|
||||
}
|
||||
if (err == 0)
|
||||
err = wc_ChaCha20Poly1305_CheckTag(inAuthTag, calculatedAuthTag);
|
||||
|
||||
/* Decrypt the received ciphertext */
|
||||
if (err == 0)
|
||||
@ -167,6 +161,17 @@ int wc_ChaCha20Poly1305_Decrypt(
|
||||
return err;
|
||||
}
|
||||
|
||||
int wc_ChaCha20Poly1305_CheckTag(
|
||||
const byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
|
||||
const byte authTagChk[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])
|
||||
{
|
||||
int ret = 0;
|
||||
if (ConstantCompare(authTag, authTagChk,
|
||||
CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE) != 0) {
|
||||
ret = MAC_CMP_FAILED_E;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int calculateAuthTag(
|
||||
const byte inAuthKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
|
||||
@ -248,4 +253,167 @@ static void word32ToLittle64(const word32 inLittle32, byte outLittle64[8])
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_CHACHAPOLY_AEAD_IUF
|
||||
int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
|
||||
const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
|
||||
const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
|
||||
int isEncrypt)
|
||||
{
|
||||
int ret;
|
||||
byte authKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
|
||||
|
||||
/* check arguments */
|
||||
if (aead == NULL || inKey == NULL || inIV == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* setup aead context */
|
||||
XMEMSET(aead, 0, sizeof(ChaChaPoly_Aead));
|
||||
XMEMSET(authKey, 0, sizeof(authKey));
|
||||
aead->isEncrypt = isEncrypt;
|
||||
|
||||
/* Initialize the ChaCha20 context (key and iv) */
|
||||
ret = wc_Chacha_SetKey(&aead->chacha, inKey,
|
||||
CHACHA20_POLY1305_AEAD_KEYSIZE);
|
||||
if (ret == 0) {
|
||||
ret = wc_Chacha_SetIV(&aead->chacha, inIV,
|
||||
CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);
|
||||
}
|
||||
|
||||
/* Create the Poly1305 key */
|
||||
if (ret == 0) {
|
||||
ret = wc_Chacha_Process(&aead->chacha, authKey, authKey,
|
||||
CHACHA20_POLY1305_AEAD_KEYSIZE);
|
||||
}
|
||||
|
||||
/* Initialize Poly1305 context */
|
||||
if (ret == 0) {
|
||||
ret = wc_Poly1305SetKey(&aead->poly, authKey,
|
||||
CHACHA20_POLY1305_AEAD_KEYSIZE);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
aead->state = CHACHA20_POLY1305_STATE_READY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* optional additional authentication data */
|
||||
int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
|
||||
const byte* inAAD, word32 inAADLen)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aead == NULL || inAAD == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (aead->state != CHACHA20_POLY1305_STATE_READY &&
|
||||
aead->state != CHACHA20_POLY1305_STATE_AAD) {
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (inAADLen > 0) {
|
||||
ret = wc_Poly1305Update(&aead->poly, inAAD, inAADLen);
|
||||
if (ret == 0) {
|
||||
aead->aadLen += inAADLen;
|
||||
aead->state = CHACHA20_POLY1305_STATE_AAD;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
|
||||
byte* data, word32 dataLen)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aead == NULL || data == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (aead->state != CHACHA20_POLY1305_STATE_READY &&
|
||||
aead->state != CHACHA20_POLY1305_STATE_AAD &&
|
||||
aead->state != CHACHA20_POLY1305_STATE_DATA) {
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (aead->state == CHACHA20_POLY1305_STATE_AAD) {
|
||||
/* Pad the AAD to 16 bytes */
|
||||
byte padding[CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1];
|
||||
word32 paddingLen = -(int)aead->aadLen &
|
||||
(CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);
|
||||
if (paddingLen > 0) {
|
||||
XMEMSET(padding, 0, paddingLen);
|
||||
ret = wc_Poly1305Update(&aead->poly, padding, paddingLen);
|
||||
}
|
||||
}
|
||||
aead->state = CHACHA20_POLY1305_STATE_DATA;
|
||||
|
||||
if (ret == 0) {
|
||||
/* Perform ChaCha20 encrypt or decrypt inline and Poly1305 auth calc */
|
||||
if (aead->isEncrypt) {
|
||||
ret = wc_Chacha_Process(&aead->chacha, data, data, dataLen);
|
||||
if (ret == 0)
|
||||
ret = wc_Poly1305Update(&aead->poly, data, dataLen);
|
||||
}
|
||||
else {
|
||||
ret = wc_Poly1305Update(&aead->poly, data, dataLen);
|
||||
if (ret == 0)
|
||||
ret = wc_Chacha_Process(&aead->chacha, data, data, dataLen);
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
aead->dataLen += dataLen;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
|
||||
byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE])
|
||||
{
|
||||
int ret = 0;
|
||||
byte padding[CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1];
|
||||
word32 paddingLen;
|
||||
byte little64[16]; /* word64 * 2 */
|
||||
|
||||
if (aead == NULL || outAuthTag == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (aead->state != CHACHA20_POLY1305_STATE_DATA) {
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
aead->state = CHACHA20_POLY1305_STATE_FINAL;
|
||||
|
||||
/* Pad the ciphertext to 16 bytes */
|
||||
paddingLen = -(int)aead->dataLen &
|
||||
(CHACHA20_POLY1305_MAC_PADDING_ALIGNMENT - 1);
|
||||
if (paddingLen > 0) {
|
||||
XMEMSET(padding, 0, paddingLen);
|
||||
ret = wc_Poly1305Update(&aead->poly, padding, paddingLen);
|
||||
}
|
||||
|
||||
/* Add the aad and ciphertext length */
|
||||
if (ret == 0) {
|
||||
/* AAD length as a 64-bit little endian integer */
|
||||
word32ToLittle64(aead->aadLen, little64);
|
||||
/* Ciphertext length as a 64-bit little endian integer */
|
||||
word32ToLittle64(aead->dataLen, little64 + 8);
|
||||
|
||||
ret = wc_Poly1305Update(&aead->poly, little64, sizeof(little64));
|
||||
}
|
||||
|
||||
/* Finalize the auth tag */
|
||||
if (ret == 0) {
|
||||
ret = wc_Poly1305Final(&aead->poly, outAuthTag);
|
||||
}
|
||||
|
||||
/* reset and cleanup sensitive context */
|
||||
ForceZero(aead, sizeof(ChaChaPoly_Aead));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !NO_CHACHAPOLY_AEAD_IUF */
|
||||
|
||||
#endif /* HAVE_CHACHA && HAVE_POLY1305 */
|
||||
|
@ -5034,6 +5034,13 @@ int chacha20_poly1305_aead_test(void)
|
||||
byte generatedPlaintext[272];
|
||||
byte generatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
|
||||
int err;
|
||||
#ifndef NO_CHACHAPOLY_AEAD_IUF
|
||||
ChaChaPoly_Aead aead;
|
||||
#define TEST_SMALL_CHACHA_CHUNKS 64
|
||||
#ifdef TEST_SMALL_CHACHA_CHUNKS
|
||||
word32 testLen;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext));
|
||||
XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag));
|
||||
@ -5092,8 +5099,8 @@ int chacha20_poly1305_aead_test(void)
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4511;
|
||||
|
||||
/* Test #1 */
|
||||
|
||||
/* Test #1 */
|
||||
err = wc_ChaCha20Poly1305_Encrypt(key1, iv1,
|
||||
aad1, sizeof(aad1),
|
||||
plaintext1, sizeof(plaintext1),
|
||||
@ -5103,17 +5110,14 @@ int chacha20_poly1305_aead_test(void)
|
||||
}
|
||||
|
||||
/* -- Check the ciphertext and authtag */
|
||||
|
||||
if (XMEMCMP(generatedCiphertext, cipher1, sizeof(cipher1))) {
|
||||
return -4512;
|
||||
}
|
||||
|
||||
if (XMEMCMP(generatedAuthTag, authTag1, sizeof(authTag1))) {
|
||||
return -4513;
|
||||
}
|
||||
|
||||
/* -- Verify decryption works */
|
||||
|
||||
err = wc_ChaCha20Poly1305_Decrypt(key1, iv1,
|
||||
aad1, sizeof(aad1),
|
||||
cipher1, sizeof(cipher1),
|
||||
@ -5121,17 +5125,16 @@ int chacha20_poly1305_aead_test(void)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (XMEMCMP(generatedPlaintext, plaintext1, sizeof( plaintext1))) {
|
||||
if (XMEMCMP(generatedPlaintext, plaintext1, sizeof(plaintext1))) {
|
||||
return -4514;
|
||||
}
|
||||
|
||||
|
||||
XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext));
|
||||
XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag));
|
||||
XMEMSET(generatedPlaintext, 0, sizeof(generatedPlaintext));
|
||||
|
||||
/* Test #2 */
|
||||
|
||||
err = wc_ChaCha20Poly1305_Encrypt(key2, iv2,
|
||||
aad2, sizeof(aad2),
|
||||
plaintext2, sizeof(plaintext2),
|
||||
@ -5141,17 +5144,14 @@ int chacha20_poly1305_aead_test(void)
|
||||
}
|
||||
|
||||
/* -- Check the ciphertext and authtag */
|
||||
|
||||
if (XMEMCMP(generatedCiphertext, cipher2, sizeof(cipher2))) {
|
||||
return -4515;
|
||||
}
|
||||
|
||||
if (XMEMCMP(generatedAuthTag, authTag2, sizeof(authTag2))) {
|
||||
return -4516;
|
||||
}
|
||||
|
||||
/* -- Verify decryption works */
|
||||
|
||||
err = wc_ChaCha20Poly1305_Decrypt(key2, iv2,
|
||||
aad2, sizeof(aad2),
|
||||
cipher2, sizeof(cipher2),
|
||||
@ -5164,6 +5164,222 @@ int chacha20_poly1305_aead_test(void)
|
||||
return -4517;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_CHACHAPOLY_AEAD_IUF
|
||||
/* AEAD init/update/final */
|
||||
err = wc_ChaCha20Poly1305_Init(NULL, key1, iv1, 0);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4520;
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, NULL, iv1, 0);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4521;
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, key1, NULL, 0);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4522;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(NULL, aad1, sizeof(aad1));
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4523;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, NULL, sizeof(aad1));
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4524;
|
||||
err = wc_ChaCha20Poly1305_UpdateData(NULL, generatedPlaintext, sizeof(plaintext1));
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4525;
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, NULL, sizeof(plaintext1));
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4526;
|
||||
err = wc_ChaCha20Poly1305_Final(NULL, generatedAuthTag);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4527;
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, NULL);
|
||||
if (err != BAD_FUNC_ARG)
|
||||
return -4528;
|
||||
|
||||
/* AEAD init/update/final - state tests */
|
||||
aead.state = CHACHA20_POLY1305_STATE_INIT;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1));
|
||||
if (err != BAD_STATE_E)
|
||||
return -4529;
|
||||
aead.state = CHACHA20_POLY1305_STATE_DATA;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1));
|
||||
if (err != BAD_STATE_E)
|
||||
return -4530;
|
||||
aead.state = CHACHA20_POLY1305_STATE_FINAL;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1));
|
||||
if (err != BAD_STATE_E)
|
||||
return -4531;
|
||||
aead.state = CHACHA20_POLY1305_STATE_INIT;
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, sizeof(plaintext1));
|
||||
if (err != BAD_STATE_E)
|
||||
return -4532;
|
||||
aead.state = CHACHA20_POLY1305_STATE_FINAL;
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, sizeof(plaintext1));
|
||||
if (err != BAD_STATE_E)
|
||||
return -4533;
|
||||
aead.state = CHACHA20_POLY1305_STATE_INIT;
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != BAD_STATE_E)
|
||||
return -4534;
|
||||
aead.state = CHACHA20_POLY1305_STATE_READY;
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != BAD_STATE_E)
|
||||
return -4535;
|
||||
aead.state = CHACHA20_POLY1305_STATE_AAD;
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != BAD_STATE_E)
|
||||
return -4536;
|
||||
|
||||
XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext));
|
||||
XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag));
|
||||
XMEMSET(generatedPlaintext, 0, sizeof(generatedPlaintext));
|
||||
|
||||
/* Test 1 - Encrypt */
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, key1, iv1, 1);
|
||||
if (err != 0)
|
||||
return -4537;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1));
|
||||
if (err != 0)
|
||||
return -4538;
|
||||
#ifdef TEST_SMALL_CHACHA_CHUNKS
|
||||
/* test doing data in smaller chunks */
|
||||
for (testLen=0; testLen<sizeof(plaintext1); ) {
|
||||
word32 dataLen = sizeof(plaintext1) - testLen;
|
||||
if (dataLen > TEST_SMALL_CHACHA_CHUNKS)
|
||||
dataLen = TEST_SMALL_CHACHA_CHUNKS;
|
||||
XMEMCPY(&generatedCiphertext[testLen], &plaintext1[testLen], dataLen);
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead,
|
||||
&generatedCiphertext[testLen], dataLen);
|
||||
if (err != 0)
|
||||
return -4539;
|
||||
testLen += dataLen;
|
||||
}
|
||||
#else
|
||||
XMEMCPY(generatedCiphertext, plaintext1, sizeof(plaintext1));
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedCiphertext,
|
||||
sizeof(plaintext1));
|
||||
#endif
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != 0)
|
||||
return -4540;
|
||||
err = wc_ChaCha20Poly1305_CheckTag(generatedAuthTag, authTag1);
|
||||
if (err != 0)
|
||||
return -4541;
|
||||
if (XMEMCMP(generatedCiphertext, cipher1, sizeof(cipher1))) {
|
||||
return -4542;
|
||||
}
|
||||
|
||||
/* Test 1 - Decrypt */
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, key1, iv1, 0);
|
||||
if (err != 0)
|
||||
return -4543;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1));
|
||||
if (err != 0)
|
||||
return -4544;
|
||||
#ifdef TEST_SMALL_CHACHA_CHUNKS
|
||||
/* test doing data in smaller chunks */
|
||||
for (testLen=0; testLen<sizeof(plaintext1); ) {
|
||||
word32 dataLen = sizeof(plaintext1) - testLen;
|
||||
if (dataLen > TEST_SMALL_CHACHA_CHUNKS)
|
||||
dataLen = TEST_SMALL_CHACHA_CHUNKS;
|
||||
XMEMCPY(&generatedPlaintext[testLen], &generatedCiphertext[testLen],
|
||||
dataLen);
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead,
|
||||
&generatedPlaintext[testLen], dataLen);
|
||||
if (err != 0)
|
||||
return -4545;
|
||||
testLen += dataLen;
|
||||
}
|
||||
#else
|
||||
XMEMCPY(generatedPlaintext, generatedCiphertext, sizeof(cipher1));
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext,
|
||||
sizeof(cipher1));
|
||||
#endif
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != 0)
|
||||
return -4546;
|
||||
err = wc_ChaCha20Poly1305_CheckTag(generatedAuthTag, authTag1);
|
||||
if (err != 0)
|
||||
return -4547;
|
||||
if (XMEMCMP(generatedPlaintext, plaintext1, sizeof(plaintext1))) {
|
||||
return -4548;
|
||||
}
|
||||
|
||||
XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext));
|
||||
XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag));
|
||||
XMEMSET(generatedPlaintext, 0, sizeof(generatedPlaintext));
|
||||
|
||||
/* Test 2 - Encrypt */
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, key2, iv2, 1);
|
||||
if (err != 0)
|
||||
return -4550;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad2, sizeof(aad2));
|
||||
if (err != 0)
|
||||
return -4551;
|
||||
#ifdef TEST_SMALL_CHACHA_CHUNKS
|
||||
/* test doing data in smaller chunks */
|
||||
for (testLen=0; testLen<sizeof(plaintext2); ) {
|
||||
word32 dataLen = sizeof(plaintext2) - testLen;
|
||||
if (dataLen > TEST_SMALL_CHACHA_CHUNKS)
|
||||
dataLen = TEST_SMALL_CHACHA_CHUNKS;
|
||||
XMEMCPY(&generatedCiphertext[testLen], &plaintext2[testLen], dataLen);
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead,
|
||||
&generatedCiphertext[testLen], dataLen);
|
||||
if (err != 0)
|
||||
return -4552;
|
||||
testLen += dataLen;
|
||||
}
|
||||
#else
|
||||
XMEMCPY(generatedCiphertext, plaintext2, sizeof(plaintext2));
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedCiphertext,
|
||||
sizeof(plaintext2));
|
||||
#endif
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != 0)
|
||||
return -4553;
|
||||
err = wc_ChaCha20Poly1305_CheckTag(generatedAuthTag, authTag2);
|
||||
if (err != 0)
|
||||
return -4554;
|
||||
if (XMEMCMP(generatedCiphertext, cipher2, sizeof(cipher2))) {
|
||||
return -4555;
|
||||
}
|
||||
|
||||
/* Test 2 - Decrypt */
|
||||
err = wc_ChaCha20Poly1305_Init(&aead, key2, iv2, 0);
|
||||
if (err != 0)
|
||||
return -4556;
|
||||
err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad2, sizeof(aad2));
|
||||
if (err != 0)
|
||||
return -4557;
|
||||
#ifdef TEST_SMALL_CHACHA_CHUNKS
|
||||
/* test doing data in smaller chunks */
|
||||
for (testLen=0; testLen<sizeof(plaintext2); ) {
|
||||
word32 dataLen = sizeof(plaintext2) - testLen;
|
||||
if (dataLen > TEST_SMALL_CHACHA_CHUNKS)
|
||||
dataLen = TEST_SMALL_CHACHA_CHUNKS;
|
||||
XMEMCPY(&generatedPlaintext[testLen], &generatedCiphertext[testLen],
|
||||
dataLen);
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead,
|
||||
&generatedPlaintext[testLen], dataLen);
|
||||
if (err != 0)
|
||||
return -4558;
|
||||
testLen += dataLen;
|
||||
}
|
||||
#else
|
||||
XMEMCPY(generatedPlaintext, generatedCiphertext, sizeof(cipher2));
|
||||
err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext,
|
||||
sizeof(cipher2));
|
||||
#endif
|
||||
err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag);
|
||||
if (err != 0)
|
||||
return -4559;
|
||||
err = wc_ChaCha20Poly1305_CheckTag(generatedAuthTag, authTag2);
|
||||
if (err != 0)
|
||||
return -4560;
|
||||
if (XMEMCMP(generatedPlaintext, plaintext2, sizeof(plaintext2))) {
|
||||
return -4561;
|
||||
}
|
||||
#endif /* !NO_CHACHAPOLY_AEAD_IUF */
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* HAVE_CHACHA && HAVE_POLY1305 */
|
||||
|
@ -33,6 +33,8 @@
|
||||
#define WOLF_CRYPT_CHACHA20_POLY1305_H
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
#include <wolfssl/wolfcrypt/chacha.h>
|
||||
#include <wolfssl/wolfcrypt/poly1305.h>
|
||||
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
|
||||
@ -45,10 +47,33 @@
|
||||
#define CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE 16
|
||||
|
||||
enum {
|
||||
CHACHA20_POLY_1305_ENC_TYPE = 8 /* cipher unique type */
|
||||
CHACHA20_POLY_1305_ENC_TYPE = 8, /* cipher unique type */
|
||||
|
||||
/* AEAD Cipher Direction */
|
||||
CHACHA20_POLY1305_AEAD_DECRYPT = 0,
|
||||
CHACHA20_POLY1305_AEAD_ENCRYPT = 1,
|
||||
|
||||
/* AEAD State */
|
||||
CHACHA20_POLY1305_STATE_INIT = 0,
|
||||
CHACHA20_POLY1305_STATE_READY = 1,
|
||||
CHACHA20_POLY1305_STATE_AAD = 2,
|
||||
CHACHA20_POLY1305_STATE_DATA = 3,
|
||||
CHACHA20_POLY1305_STATE_FINAL = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
typedef struct ChaChaPoly_Aead {
|
||||
ChaCha chacha;
|
||||
Poly1305 poly;
|
||||
|
||||
word32 aadLen;
|
||||
word32 dataLen;
|
||||
|
||||
byte state;
|
||||
word32 isEncrypt:1;
|
||||
} ChaChaPoly_Aead;
|
||||
|
||||
|
||||
/*
|
||||
* The IV for this implementation is 96 bits to give the most flexibility.
|
||||
*
|
||||
* Some protocols may have unique per-invocation inputs that are not
|
||||
@ -76,6 +101,27 @@ int wc_ChaCha20Poly1305_Decrypt(
|
||||
const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
|
||||
byte* outPlaintext);
|
||||
|
||||
WOLFSSL_API
|
||||
int wc_ChaCha20Poly1305_CheckTag(
|
||||
const byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE],
|
||||
const byte authTagChk[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
|
||||
|
||||
|
||||
#ifndef NO_CHACHAPOLY_AEAD_IUF
|
||||
/* Implementation of AEAD, which includes support for adding
|
||||
data, then final calculation of authentication tag */
|
||||
WOLFSSL_API int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
|
||||
const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
|
||||
const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
|
||||
int isEncrypt);
|
||||
WOLFSSL_API int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
|
||||
const byte* inAAD, word32 inAADLen);
|
||||
WOLFSSL_API int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead,
|
||||
byte* data, word32 dataLen);
|
||||
WOLFSSL_API int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead,
|
||||
byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]);
|
||||
#endif /* !NO_CHACHAPOLY_AEAD_IUF */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user