From 2c840201e57e27fa9f1b26a970270a91813e32fe Mon Sep 17 00:00:00 2001 From: Pauli Date: Mon, 24 Jun 2019 17:54:47 +1000 Subject: [PATCH] Allow AES XTS decryption using duplicate keys. This feature is enabled by default outside of FIPS builds which ban such actions completely. Encryption is always disallowed and will generate an error. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/9112) --- crypto/evp/e_aes.c | 22 ++++++++++++++++++---- test/recipes/30-test_evp_data/evpciph.txt | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index c9dbca98d7..697b5a542d 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -63,6 +63,12 @@ typedef struct { const unsigned char iv[16]); } EVP_AES_XTS_CTX; +#ifdef FIPS_MODE +static const int allow_insecure_decrypt = 0; +#else +static const int allow_insecure_decrypt = 1; +#endif + typedef struct { union { OSSL_UNION_ALIGN; @@ -387,6 +393,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx); + if (!iv && !key) return 1; @@ -401,7 +408,8 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * This addresses Rogaway's vulnerability. * See comment in aes_xts_init_key() below. */ - if (memcmp(key, key + bytes, bytes) == 0) { + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { EVPerr(EVP_F_AESNI_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); return 0; } @@ -804,6 +812,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx); + if (!iv && !key) return 1; @@ -818,7 +827,8 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * This addresses Rogaway's vulnerability. * See comment in aes_xts_init_key() below. */ - if (memcmp(key, key + bytes, bytes) == 0) { + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { EVPerr(EVP_F_AES_T4_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); return 0; } @@ -3408,10 +3418,12 @@ BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { - EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,c); + EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX, c); + if (type == EVP_CTRL_COPY) { EVP_CIPHER_CTX *out = ptr; EVP_AES_XTS_CTX *xctx_out = EVP_C_DATA(EVP_AES_XTS_CTX,out); + if (xctx->xts.key1) { if (xctx->xts.key1 != &xctx->ks1) return 0; @@ -3435,6 +3447,7 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx); + if (!iv && !key) return 1; @@ -3460,7 +3473,8 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, * BEFORE using the keys in the XTS-AES algorithm to process * data with them." */ - if (memcmp(key, key + bytes, bytes) == 0) { + if ((!allow_insecure_decrypt || enc) + && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { EVPerr(EVP_F_AES_XTS_INIT_KEY, EVP_R_XTS_DUPLICATED_KEYS); return 0; } diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt index 916ba15922..3dd5a87ba7 100644 --- a/test/recipes/30-test_evp_data/evpciph.txt +++ b/test/recipes/30-test_evp_data/evpciph.txt @@ -1190,13 +1190,34 @@ Result = CIPHERFINAL_ERROR Title = AES XTS test vectors from IEEE Std 1619-2007 +# Using the same key twice for encryption is always banned. Cipher = aes-128-xts +Operation = ENCRYPT Key = 0000000000000000000000000000000000000000000000000000000000000000 IV = 00000000000000000000000000000000 Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e Result = KEY_SET_ERROR +# Using the same key twice for decryption is banned in FIPS mode. +#Cipher = aes-128-xts +#FIPS = YES +#Operation = DECRYPT +#Key = 0000000000000000000000000000000000000000000000000000000000000000 +#IV = 00000000000000000000000000000000 +#Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 +#Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e +#Result = KEY_SET_ERROR + +# Using the same key twice for decryption is allowed outside of FIPS mode. +Cipher = aes-128-xts +#FIPS = NO +Operation = DECRYPT +Key = 0000000000000000000000000000000000000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 +Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e + Cipher = aes-128-xts Key = 1111111111111111111111111111111122222222222222222222222222222222 IV = 33333333330000000000000000000000 -- 2.25.1