diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2214f8a71..730817823 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -6383,7 +6383,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #endif return BAD_FUNC_ARG; } - #ifdef OPENSSL_EXTRA XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH)); aes->gcm.aadLen = 0; @@ -12250,7 +12249,7 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, #ifdef WOLFSSL_AES_XTS -/* Galios Field to use */ +/* Galois Field to use */ #define GF_XTS 0x87 int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) @@ -12264,21 +12263,28 @@ int wc_AesXtsInit(XtsAes* aes, void* heap, int devId) if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { return ret; } - if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) { + if ((ret = wc_AesInit(&aes->aes_encrypt, heap, devId)) != 0) { + (void)wc_AesFree(&aes->tweak); + return ret; + } + if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) { + (void)wc_AesFree(&aes->tweak); + (void)wc_AesFree(&aes->aes_encrypt); return ret; } return 0; } -/* This is to help with setting keys to correct encrypt or decrypt type. +/* Set up keys for encryption and/or decryption. * * tweak AES key for tweak in XTS * aes AES key for encrypt/decrypt process * key buffer holding aes key | tweak key * len length of key buffer in bytes. Should be twice that of key size. i.e. * 32 for a 16 byte key. - * dir direction, either AES_ENCRYPTION or AES_DECRYPTION + * dir direction: AES_ENCRYPTION, AES_DECRYPTION, or + * AES_ENCRYPTION_AND_DECRYPTION * heap heap hint to use for memory. Can be NULL * devId id to use with async crypto. Can be 0 * @@ -12294,26 +12300,49 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) } keySz = len/2; - if (keySz != 16 && keySz != 32) { + if (keySz != AES_128_KEY_SIZE && keySz != AES_256_KEY_SIZE) { WOLFSSL_MSG("Unsupported key size"); return WC_KEY_SIZE_E; } - if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) { +#ifdef HAVE_FIPS_VERSION + if (XMEMCMP(key, key + keySz, keySz) == 0) { + WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ"); + return BAD_FUNC_ARG; + } +#endif + + if ((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) + ret = wc_AesSetKey(&aes->aes_encrypt, key, keySz, NULL, AES_ENCRYPTION); + + if ((ret == 0) && ((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION))) + ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION); + + if (ret == 0) ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL, AES_ENCRYPTION); - if (ret != 0) { - wc_AesFree(&aes->aes); - } + #ifdef WOLFSSL_AESNI - if (aes->aes.use_aesni != aes->tweak.use_aesni) { - if (aes->aes.use_aesni) - aes->aes.use_aesni = 0; - else - aes->tweak.use_aesni = 0; - } + if (ret == 0) { + /* With WC_AES_C_DYNAMIC_FALLBACK, the main and tweak keys could have + * conflicting _aesni status, but the AES-XTS asm implementations need + * them to all be AESNI. If any aren't, disable AESNI on all. + */ + if ((((dir == AES_ENCRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + (aes->aes_encrypt.use_aesni != aes->tweak.use_aesni)) || + (((dir == AES_DECRYPTION) || (dir == AES_ENCRYPTION_AND_DECRYPTION)) && + (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni))) + { +#ifdef WC_AES_C_DYNAMIC_FALLBACK + aes->aes_encrypt.use_aesni = 0; + aes->aes_decrypt.use_aesni = 0; + aes->tweak.use_aesni = 0; +#else + ret = SYSLIB_FAILED_E; #endif + } } +#endif return ret; } @@ -12355,7 +12384,8 @@ int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, int wc_AesXtsFree(XtsAes* aes) { if (aes != NULL) { - wc_AesFree(&aes->aes); + wc_AesFree(&aes->aes_encrypt); + wc_AesFree(&aes->aes_decrypt); wc_AesFree(&aes->tweak); } @@ -12512,7 +12542,7 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); - Aes *aes = &xaes->aes; + Aes *aes = &xaes->aes_encrypt; Aes *tweak = &xaes->tweak; byte tmp[AES_BLOCK_SIZE]; @@ -12619,6 +12649,11 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } + if (xaes->aes_encrypt.keylen == 0) { + WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key."); + return BAD_FUNC_ARG; + } + if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -12631,28 +12666,29 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes.use_aesni; + int orig_use_aesni = xaes->aes_encrypt.use_aesni; #endif - if (xaes->aes.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { + + if (xaes->aes_encrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { #ifdef WC_AES_C_DYNAMIC_FALLBACK - xaes->aes.use_aesni = 0; + xaes->aes_encrypt.use_aesni = 0; xaes->tweak.use_aesni = 0; #else return ret; #endif } - if (xaes->aes.use_aesni) { + if (xaes->aes_encrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); ret = 0; } else #endif { - AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_encrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_encrypt.rounds); ret = 0; } } @@ -12663,11 +12699,11 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes.use_aesni) + if (xaes->aes_encrypt.use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes.use_aesni = orig_use_aesni; + xaes->aes_encrypt.use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif @@ -12677,7 +12713,7 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return ret; } -/* Same process as encryption but Aes key is AES_DECRYPTION type. +/* Same process as encryption but use aes_decrypt key. * * xaes AES keys to use for block encrypt/decrypt * out output buffer to hold plain text @@ -12693,7 +12729,7 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz, { int ret = 0; word32 blocks = (sz / AES_BLOCK_SIZE); - Aes *aes = &xaes->aes; + Aes *aes = &xaes->aes_decrypt; Aes *tweak = &xaes->tweak; word32 j; byte carry = 0; @@ -12826,6 +12862,11 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } + if (xaes->aes_decrypt.keylen == 0) { + WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key."); + return BAD_FUNC_ARG; + } + if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -12838,25 +12879,29 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, { #ifdef WOLFSSL_AESNI #ifdef WC_AES_C_DYNAMIC_FALLBACK - int orig_use_aesni = xaes->aes.use_aesni; + int orig_use_aesni = xaes->aes_decrypt.use_aesni; #endif - if (xaes->aes.use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) { - xaes->aes.use_aesni = 0; + if (xaes->aes_decrypt.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2() != 0))) { +#ifdef WC_AES_C_DYNAMIC_FALLBACK + xaes->aes_decrypt.use_aesni = 0; xaes->tweak.use_aesni = 0; +#else + return ret; +#endif } - if (xaes->aes.use_aesni) { + if (xaes->aes_decrypt.use_aesni) { #if defined(HAVE_INTEL_AVX1) if (IS_INTEL_AVX1(intel_flags)) { - AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); ret = 0; } else #endif { - AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key, - (const byte*)xaes->tweak.key, (int)xaes->aes.rounds); + AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes_decrypt.key, + (const byte*)xaes->tweak.key, (int)xaes->aes_decrypt.rounds); ret = 0; } } @@ -12867,11 +12912,11 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, } #ifdef WOLFSSL_AESNI - if (xaes->aes.use_aesni) + if (xaes->aes_decrypt.use_aesni) RESTORE_VECTOR_REGISTERS(); #ifdef WC_AES_C_DYNAMIC_FALLBACK else if (orig_use_aesni) { - xaes->aes.use_aesni = orig_use_aesni; + xaes->aes_decrypt.use_aesni = orig_use_aesni; xaes->tweak.use_aesni = orig_use_aesni; } #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index dcd3320de..cb24bd36d 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -179,6 +179,7 @@ enum { AES_ENC_TYPE = WC_CIPHER_AES, /* cipher unique type */ AES_ENCRYPTION = 0, AES_DECRYPTION = 1, + AES_ENCRYPTION_AND_DECRYPTION = 2, AES_BLOCK_SIZE = 16, @@ -398,7 +399,8 @@ struct Aes { #ifdef WOLFSSL_AES_XTS typedef struct XtsAes { - Aes aes; + Aes aes_encrypt; + Aes aes_decrypt; Aes tweak; } XtsAes; #endif