Allow AES XTS decryption using duplicate keys.
authorPauli <paul.dale@oracle.com>
Mon, 24 Jun 2019 07:54:47 +0000 (17:54 +1000)
committerPauli <paul.dale@oracle.com>
Mon, 24 Jun 2019 07:54:47 +0000 (17:54 +1000)
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 <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/9112)

crypto/evp/e_aes.c
test/recipes/30-test_evp_data/evpciph.txt

index c9dbca98d7180ba0ad72f411073da6917931d004..697b5a542d9851c7d0b9b3a63fa76f46ca178eef 100644 (file)
@@ -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;
             }
index 916ba15922e2da87db60f447211e1278bd293dd4..3dd5a87ba7a3e8d6b9a00c66facf7c4346d0f4f1 100644 (file)
@@ -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