From 38cfec89e8ae6afb14e97eb214b782ee4fb1ea2a Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 30 Sep 2021 10:33:08 +1000 Subject: [PATCH] ARMv8: fix configurations Poly1305: poly1305_block() is void for ARMv8 ASM SHA512: explicitly include cryptocb.h. AES: set keylen for EVP API AES: Implement streaming AES-GCM. --- wolfcrypt/src/poly1305.c | 6 +- wolfcrypt/src/port/arm/armv8-aes.c | 642 ++++++++++++++++++++++++++ wolfcrypt/src/port/arm/armv8-sha512.c | 3 + 3 files changed, 650 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/poly1305.c b/wolfcrypt/src/poly1305.c index 29e5c7dc5..2db1cafc2 100644 --- a/wolfcrypt/src/poly1305.c +++ b/wolfcrypt/src/poly1305.c @@ -786,11 +786,15 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) /* process full blocks */ if (bytes >= POLY1305_BLOCK_SIZE) { - int ret; size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1)); +#if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) + int ret; ret = poly1305_blocks(ctx, m, want); if (ret != 0) return ret; +#else + poly1305_blocks(ctx, m, want); +#endif m += want; bytes -= (word32)want; } diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index bdb075eb0..5ec2dca65 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -176,6 +176,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, aes->left = 0; #endif /* WOLFSSL_AES_COUNTER */ + aes->keylen = keylen; aes->rounds = keylen/4 + 6; XMEMCPY(rk, userKey, keylen); @@ -4381,6 +4382,643 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, #endif /* aarch64 */ +#ifdef HAVE_AESGCM +#ifdef WOLFSSL_AESGCM_STREAM + /* Access initialization counter data. */ + #define AES_INITCTR(aes) ((aes)->streamData + 0 * AES_BLOCK_SIZE) + /* Access counter data. */ + #define AES_COUNTER(aes) ((aes)->streamData + 1 * AES_BLOCK_SIZE) + /* Access tag data. */ + #define AES_TAG(aes) ((aes)->streamData + 2 * AES_BLOCK_SIZE) + /* Access last GHASH block. */ + #define AES_LASTGBLOCK(aes) ((aes)->streamData + 3 * AES_BLOCK_SIZE) + /* Access last encrypted block. */ + #define AES_LASTBLOCK(aes) ((aes)->streamData + 4 * AES_BLOCK_SIZE) + +/* GHASH one block of data. + * + * XOR block into tag and GMULT with H. + * + * @param [in, out] aes AES GCM object. + * @param [in] block Block of AAD or cipher text. + */ +#define GHASH_ONE_BLOCK(aes, block) \ + do { \ + xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE); \ + GMULT(AES_TAG(aes), aes->H); \ + } \ + while (0) + +/* Hash in the lengths of the AAD and cipher text in bits. + * + * Default implementation. + * + * @param [in, out] aes AES GCM object. + */ +#define GHASH_LEN_BLOCK(aes) \ + do { \ + byte scratch[AES_BLOCK_SIZE]; \ + FlattenSzInBits(&scratch[0], aes->aSz); \ + FlattenSzInBits(&scratch[8], aes->cSz); \ + GHASH_ONE_BLOCK(aes, scratch); \ + } \ + while (0) + +static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) +{ + int i; + for (i = ctrSz-1; i >= 0; i--) { + if (++ctr[i]) + break; + } +} + +/* Initialize a GHASH for streaming operations. + * + * @param [in, out] aes AES GCM object. + */ +static void GHASH_INIT(Aes* aes) { + /* Set tag to all zeros as initial value. */ + XMEMSET(AES_TAG(aes), 0, AES_BLOCK_SIZE); + /* Reset counts of AAD and cipher text. */ + aes->aOver = 0; + aes->cOver = 0; +} + +/* Update the GHASH with AAD and/or cipher text. + * + * @param [in,out] aes AES GCM object. + * @param [in] a Additional authentication data buffer. + * @param [in] aSz Size of data in AAD buffer. + * @param [in] c Cipher text buffer. + * @param [in] cSz Size of data in cipher text buffer. + */ +static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c, + word32 cSz) +{ + word32 blocks; + word32 partial; + + /* Hash in A, the Additional Authentication Data */ + if (aSz != 0 && a != NULL) { + /* Update count of AAD we have hashed. */ + aes->aSz += aSz; + /* Check if we have unprocessed data. */ + if (aes->aOver > 0) { + /* Calculate amount we can use - fill up the block. */ + byte sz = AES_BLOCK_SIZE - aes->aOver; + if (sz > aSz) { + sz = aSz; + } + /* Copy extra into last GHASH block array and update count. */ + XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz); + aes->aOver += sz; + if (aes->aOver == AES_BLOCK_SIZE) { + /* We have filled up the block and can process. */ + GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes)); + /* Reset count. */ + aes->aOver = 0; + } + /* Used up some data. */ + aSz -= sz; + a += sz; + } + + /* Calculate number of blocks of AAD and the leftover. */ + blocks = aSz / AES_BLOCK_SIZE; + partial = aSz % AES_BLOCK_SIZE; + /* GHASH full blocks now. */ + while (blocks--) { + GHASH_ONE_BLOCK(aes, a); + a += AES_BLOCK_SIZE; + } + if (partial != 0) { + /* Cache the partial block. */ + XMEMCPY(AES_LASTGBLOCK(aes), a, partial); + aes->aOver = (byte)partial; + } + } + if (aes->aOver > 0 && cSz > 0 && c != NULL) { + /* No more AAD coming and we have a partial block. */ + /* Fill the rest of the block with zeros. */ + byte sz = AES_BLOCK_SIZE - aes->aOver; + XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz); + /* GHASH last AAD block. */ + GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes)); + /* Clear partial count for next time through. */ + aes->aOver = 0; + } + + /* Hash in C, the Ciphertext */ + if (cSz != 0 && c != NULL) { + /* Update count of cipher text we have hashed. */ + aes->cSz += cSz; + if (aes->cOver > 0) { + /* Calculate amount we can use - fill up the block. */ + byte sz = AES_BLOCK_SIZE - aes->cOver; + if (sz > cSz) { + sz = cSz; + } + XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz); + /* Update count of unsed encrypted counter. */ + aes->cOver += sz; + if (aes->cOver == AES_BLOCK_SIZE) { + /* We have filled up the block and can process. */ + GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes)); + /* Reset count. */ + aes->cOver = 0; + } + /* Used up some data. */ + cSz -= sz; + c += sz; + } + + /* Calculate number of blocks of cipher text and the leftover. */ + blocks = cSz / AES_BLOCK_SIZE; + partial = cSz % AES_BLOCK_SIZE; + /* GHASH full blocks now. */ + while (blocks--) { + GHASH_ONE_BLOCK(aes, c); + c += AES_BLOCK_SIZE; + } + if (partial != 0) { + /* Cache the partial block. */ + XMEMCPY(AES_LASTGBLOCK(aes), c, partial); + aes->cOver = (byte)partial; + } + } +} + +/* Finalize the GHASH calculation. + * + * Complete hashing cipher text and hash the AAD and cipher text lengths. + * + * @param [in, out] aes AES GCM object. + * @param [out] s Authentication tag. + * @param [in] sSz Size of authentication tag required. + */ +static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz) +{ + /* AAD block incomplete when > 0 */ + byte over = aes->aOver; + + if (aes->cOver > 0) { + /* Cipher text block incomplete. */ + over = aes->cOver; + } + if (over > 0) { + /* Zeroize the unused part of the block. */ + XMEMSET(AES_LASTGBLOCK(aes) + over, 0, AES_BLOCK_SIZE - over); + /* Hash the last block of cipher text. */ + GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes)); + } + /* Hash in the lengths of AAD and cipher text in bits */ + GHASH_LEN_BLOCK(aes); + /* Copy the result into s. */ + XMEMCPY(s, AES_TAG(aes), sSz); +} + +/* Initialize the AES GCM cipher with an IV. C implementation. + * + * @param [in, out] aes AES object. + * @param [in] iv IV/nonce buffer. + * @param [in] ivSz Length of IV/nonce data. + */ +static void AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz) +{ + ALIGN32 byte counter[AES_BLOCK_SIZE]; + + if (ivSz == GCM_NONCE_MID_SZ) { + /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */ + XMEMCPY(counter, iv, ivSz); + XMEMSET(counter + GCM_NONCE_MID_SZ, 0, + AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1); + counter[AES_BLOCK_SIZE - 1] = 1; + } + else { + /* Counter is GHASH of IV. */ + #ifdef OPENSSL_EXTRA + word32 aadTemp = aes->aadLen; + aes->aadLen = 0; + #endif + GHASH(aes, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE); + GMULT(counter, aes->H); + #ifdef OPENSSL_EXTRA + aes->aadLen = aadTemp; + #endif + } + + /* Copy in the counter for use with cipher. */ + XMEMCPY(AES_COUNTER(aes), counter, AES_BLOCK_SIZE); + /* Encrypt initial counter into a buffer for GCM. */ + wc_AesEncrypt(aes, counter, AES_INITCTR(aes)); + /* Reset state fields. */ + aes->over = 0; + aes->aSz = 0; + aes->cSz = 0; + /* Initialization for GHASH. */ + GHASH_INIT(aes); +} + +/* Update the AES GCM cipher with data. C implementation. + * + * Only enciphers data. + * + * @param [in, out] aes AES object. + * @param [in] out Cipher text or plaintext buffer. + * @param [in] in Plaintext or cipher text buffer. + * @param [in] sz Length of data. + */ +static void AesGcmCryptUpdate_C(Aes* aes, byte* out, const byte* in, word32 sz) +{ + word32 blocks; + word32 partial; + + /* Check if previous encrypted block was not used up. */ + if (aes->over > 0) { + byte pSz = AES_BLOCK_SIZE - aes->over; + if (pSz > sz) pSz = sz; + + /* Use some/all of last encrypted block. */ + xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz); + aes->over = (aes->over + pSz) & (AES_BLOCK_SIZE - 1); + + /* Some data used. */ + sz -= pSz; + in += pSz; + out += pSz; + } + + /* Calculate the number of blocks needing to be encrypted and any leftover. + */ + blocks = sz / AES_BLOCK_SIZE; + partial = sz & (AES_BLOCK_SIZE - 1); + + /* Encrypt block by block. */ + while (blocks--) { + ALIGN32 byte scratch[AES_BLOCK_SIZE]; + IncrementGcmCounter(AES_COUNTER(aes)); + /* Encrypt counter into a buffer. */ + wc_AesEncrypt(aes, AES_COUNTER(aes), scratch); + /* XOR plain text into encrypted counter into cipher text buffer. */ + xorbufout(out, scratch, in, AES_BLOCK_SIZE); + /* Data complete. */ + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + if (partial != 0) { + /* Generate an extra block and use up as much as needed. */ + IncrementGcmCounter(AES_COUNTER(aes)); + /* Encrypt counter into cache. */ + wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes)); + /* XOR plain text into encrypted counter into cipher text buffer. */ + xorbufout(out, AES_LASTBLOCK(aes), in, partial); + /* Keep amount of encrypted block used. */ + aes->over = partial; + } +} + +/* Calculates authentication tag for AES GCM. C implementation. + * + * @param [in, out] aes AES object. + * @param [out] authTag Buffer to store authentication tag in. + * @param [in] authTagSz Length of tag to create. + */ +static void AesGcmFinal_C(Aes* aes, byte* authTag, word32 authTagSz) +{ + /* Calculate authentication tag. */ + GHASH_FINAL(aes, authTag, authTagSz); + /* XOR in as much of encrypted counter as is required. */ + xorbuf(authTag, AES_INITCTR(aes), authTagSz); +#ifdef OPENSSL_EXTRA + /* store AAD size for next call */ + aes->aadLen = aes->aSz; +#endif + /* Zeroize last block to protect sensitive data. */ + ForceZero(AES_LASTBLOCK(aes), AES_BLOCK_SIZE); +} + +/* Initialize an AES GCM cipher for encryption or decryption. + * + * Must call wc_AesInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [in] key Buffer holding key. + * @param [in] len Length of key in bytes. + * @param [in] iv Buffer holding IV/nonce. + * @param [in] ivSz Length of IV/nonce in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL, or the IV is NULL and no previous IV has been set. + * @return MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK) + */ +int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv, + word32 ivSz) +{ + int ret = 0; + + /* Check validity of parameters. */ + if ((aes == NULL) || ((len > 0) && (key == NULL)) || + ((ivSz == 0) && (iv != NULL)) || (ivSz > AES_BLOCK_SIZE) || + ((ivSz > 0) && (iv == NULL))) { + ret = BAD_FUNC_ARG; + } + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI) + if ((ret == 0) && (aes->streamData == NULL)) { + /* Allocate buffers for streaming. */ + aes->streamData = (byte*)XMALLOC(5 * AES_BLOCK_SIZE, aes->heap, + DYNAMIC_TYPE_AES); + if (aes->streamData == NULL) { + ret = MEMORY_E; + } + } +#endif + + /* Set the key if passed in. */ + if ((ret == 0) && (key != NULL)) { + ret = wc_AesGcmSetKey(aes, key, len); + } + + if (ret == 0) { + /* Setup with IV if needed. */ + if (iv != NULL) { + /* Cache the IV in AES GCM object. */ + XMEMCPY((byte*)aes->reg, iv, ivSz); + aes->nonceSz = ivSz; + } + else if (aes->nonceSz != 0) { + /* Copy out the cached copy. */ + iv = (byte*)aes->reg; + ivSz = aes->nonceSz; + } + + if (iv != NULL) { + /* Initialize with the IV. */ + AesGcmInit_C(aes, iv, ivSz); + + aes->nonceSet = 1; + } + } + + return ret; +} + +/* Initialize an AES GCM cipher for encryption. + * + * Must call wc_AesInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [in] key Buffer holding key. + * @param [in] len Length of key in bytes. + * @param [in] iv Buffer holding IV/nonce. + * @param [in] ivSz Length of IV/nonce in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL, or the IV is NULL and no previous IV has been set. + */ +int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv, + word32 ivSz) +{ + return wc_AesGcmInit(aes, key, len, iv, ivSz); +} + +/* Initialize an AES GCM cipher for encryption or decryption. Get IV. + * + * Must call wc_AesInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [in] key Buffer holding key. + * @param [in] len Length of key in bytes. + * @param [in] iv Buffer holding IV/nonce. + * @param [in] ivSz Length of IV/nonce in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL, or the IV is NULL and no previous IV has been set. + */ +int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut, + word32 ivOutSz) +{ + XMEMCPY(ivOut, aes->reg, ivOutSz); + return wc_AesGcmInit(aes, key, len, NULL, 0); +} + +/* Update the AES GCM for encryption with data and/or authentication data. + * + * All the AAD must be passed to update before the plaintext. + * Last part of AAD can be passed with first part of plaintext. + * + * Must set key and IV before calling this function. + * Must call wc_AesGcmInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [out] out Buffer to hold cipher text. + * @param [in] in Buffer holding plaintext. + * @param [in] sz Length of plaintext in bytes. + * @param [in] authIn Buffer holding authentication data. + * @param [in] authInSz Length of authentication data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL. + */ +int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* authIn, word32 authInSz) +{ + int ret = 0; + + /* Check validity of parameters. */ + if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) && + ((out == NULL) || (in == NULL)))) { + ret = BAD_FUNC_ARG; + } + + /* Check key has been set. */ + if ((ret == 0) && (!aes->gcmKeySet)) { + ret = MISSING_KEY; + } + /* Check IV has been set. */ + if ((ret == 0) && (!aes->nonceSet)) { + ret = MISSING_IV; + } + + if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) { + aes->invokeCtr[0]++; + if (aes->invokeCtr[0] == 0) { + aes->invokeCtr[1]++; + if (aes->invokeCtr[1] == 0) + ret = AES_GCM_OVERFLOW_E; + } + } + + if (ret == 0) { + /* Encrypt the plaintext. */ + AesGcmCryptUpdate_C(aes, out, in, sz); + /* Update the authenication tag with any authentication data and the + * new cipher text. */ + GHASH_UPDATE(aes, authIn, authInSz, out, sz); + } + + return ret; +} + +/* Finalize the AES GCM for encryption and return the authentication tag. + * + * Must set key and IV before calling this function. + * Must call wc_AesGcmInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [out] authTag Buffer to hold authentication tag. + * @param [in] authTagSz Length of authentication tag in bytes. + * @return 0 on success. + */ +int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz) +{ + int ret = 0; + + /* Check validity of parameters. */ + if ((aes == NULL) || (authTag == NULL) || (authTagSz > AES_BLOCK_SIZE) || + (authTagSz == 0)) { + ret = BAD_FUNC_ARG; + } + + /* Check key has been set. */ + if ((ret == 0) && (!aes->gcmKeySet)) { + ret = MISSING_KEY; + } + /* Check IV has been set. */ + if ((ret == 0) && (!aes->nonceSet)) { + ret = MISSING_IV; + } + + if (ret == 0) { + /* Calculate authentication tag. */ + AesGcmFinal_C(aes, authTag, authTagSz); + } + + if ((ret == 0) && aes->ctrSet) { + IncCtr((byte*)aes->reg, aes->nonceSz); + } + + return ret; +} + +#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT) +/* Initialize an AES GCM cipher for decryption. + * + * Must call wc_AesInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [in] key Buffer holding key. + * @param [in] len Length of key in bytes. + * @param [in] iv Buffer holding IV/nonce. + * @param [in] ivSz Length of IV/nonce in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL, or the IV is NULL and no previous IV has been set. + */ +int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv, + word32 ivSz) +{ + return wc_AesGcmInit(aes, key, len, iv, ivSz); +} + +/* Update the AES GCM for decryption with data and/or authentication data. + * + * All the AAD must be passed to update before the cipher text. + * Last part of AAD can be passed with first part of cipher text. + * + * Must set key and IV before calling this function. + * Must call wc_AesGcmInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [out] out Buffer to hold plaintext. + * @param [in] in Buffer holding cipher text. + * @param [in] sz Length of cipher text in bytes. + * @param [in] authIn Buffer holding authentication data. + * @param [in] authInSz Length of authentication data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer + * is NULL. + */ +int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz, + const byte* authIn, word32 authInSz) +{ + int ret = 0; + + /* Check validity of parameters. */ + if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) && + ((out == NULL) || (in == NULL)))) { + ret = BAD_FUNC_ARG; + } + + /* Check key has been set. */ + if ((ret == 0) && (!aes->gcmKeySet)) { + ret = MISSING_KEY; + } + /* Check IV has been set. */ + if ((ret == 0) && (!aes->nonceSet)) { + ret = MISSING_IV; + } + + if (ret == 0) { + /* Decrypt with AAD and/or cipher text. */ + /* Update the authenication tag with any authentication data and + * cipher text. */ + GHASH_UPDATE(aes, authIn, authInSz, in, sz); + /* Decrypt the cipher text. */ + AesGcmCryptUpdate_C(aes, out, in, sz); + } + + return ret; +} + +/* Finalize the AES GCM for decryption and check the authentication tag. + * + * Must set key and IV before calling this function. + * Must call wc_AesGcmInit() before calling this function. + * + * @param [in, out] aes AES object. + * @param [in] authTag Buffer holding authentication tag. + * @param [in] authTagSz Length of authentication tag in bytes. + * @return 0 on success. + */ +int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz) +{ + int ret = 0; + + /* Check validity of parameters. */ + if ((aes == NULL) || (authTag == NULL) || (authTagSz > AES_BLOCK_SIZE) || + (authTagSz == 0)) { + ret = BAD_FUNC_ARG; + } + + /* Check key has been set. */ + if ((ret == 0) && (!aes->gcmKeySet)) { + ret = MISSING_KEY; + } + /* Check IV has been set. */ + if ((ret == 0) && (!aes->nonceSet)) { + ret = MISSING_IV; + } + + if (ret == 0) { + /* Calculate authentication tag and compare with one passed in.. */ + ALIGN32 byte calcTag[AES_BLOCK_SIZE]; + /* Calculate authentication tag. */ + AesGcmFinal_C(aes, calcTag, authTagSz); + /* Check calculated tag matches the one passed in. */ + if (ConstantCompare(authTag, calcTag, authTagSz) != 0) { + ret = AES_GCM_AUTH_E; + } + } + + return ret; +} +#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */ +#endif /* WOLFSSL_AESGCM_STREAM */ +#endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM /* Software version of AES-CCM from wolfcrypt/src/aes.c @@ -4641,6 +5279,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); if (ret == 0) { +#ifdef WOLFSSL_AESGCM_STREAM + aes->gcmKeySet = 1; +#endif + wc_AesEncrypt(aes, iv, aes->H); #if defined(__aarch64__) { diff --git a/wolfcrypt/src/port/arm/armv8-sha512.c b/wolfcrypt/src/port/arm/armv8-sha512.c index c077263c4..d9db65aa6 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512.c +++ b/wolfcrypt/src/port/arm/armv8-sha512.c @@ -44,6 +44,9 @@ #define WOLFSSL_MISC_INCLUDED #include #endif +#ifdef WOLF_CRYPTO_CB +#include +#endif #ifdef WOLFSSL_SHA512