Provisional AES XTS support.
authorDr. Stephen Henson <steve@openssl.org>
Tue, 12 Apr 2011 23:21:33 +0000 (23:21 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 12 Apr 2011 23:21:33 +0000 (23:21 +0000)
CHANGES
crypto/evp/e_aes.c
crypto/evp/evp.h
crypto/modes/Makefile
crypto/modes/modes.h
crypto/modes/modes_lcl.h
crypto/modes/xts128.c
crypto/objects/obj_dat.h
crypto/objects/obj_mac.h
crypto/objects/obj_mac.num
crypto/objects/objects.txt

diff --git a/CHANGES b/CHANGES
index fa1bb509aa7e6cb81fd58438d5ccd2663ae483e5..877976c23acd91526504e20bd52d584668eac0bd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 
+  *) Provisional XTS support. Note: this does increase the maximum key
+     length from 32 to 64 bytes but there should be no binary compatibility
+     issues as existing applications will never use XTS mode.
+     [Steve Henson]
+
   *) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies
      to OpenSSL RAND code and replace with a tiny FIPS RAND API which also
      performs algorithm blocking for unapproved PRNG types. Also do not
index b1a701b65d6221e0933fb8766a8d1fe40f594725..a6d1b5da9f0cc468ec384dd015708adf6439e88c 100644 (file)
@@ -458,5 +458,104 @@ static const EVP_CIPHER aes_256_gcm_cipher=
 
 const EVP_CIPHER *EVP_aes_256_gcm (void)
 {      return &aes_256_gcm_cipher;     }
+
+typedef struct
+       {
+       /* AES key schedules to use */
+       AES_KEY ks1, ks2;
+       XTS128_CONTEXT xts;
+       } EVP_AES_XTS_CTX;
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+       {
+       EVP_AES_XTS_CTX *xctx = c->cipher_data;
+       if (type != EVP_CTRL_INIT)
+               return -1;
+       /* key1 and key2 are used as an indicator both key and IV are set */
+       xctx->xts.key1 = NULL;
+       xctx->xts.key2 = NULL;
+       xctx->xts.block1 = (block128_f)AES_encrypt;
+       xctx->xts.block2 = (block128_f)AES_encrypt;
+       return 1;
+       }
+
+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 = ctx->cipher_data;
+       if (!iv && !key)
+               return 1;
+
+       if (key)
+               {
+               AES_set_encrypt_key(key, ctx->key_len * 8, &xctx->ks1);
+               AES_set_encrypt_key(key + ctx->key_len, ctx->key_len * 8,
+                                                               &xctx->ks2);
+
+               xctx->xts.key1 = &xctx->ks1;
+               xctx->xts.block1 = (block128_f)AES_encrypt;
+               xctx->xts.block2 = (block128_f)AES_encrypt;
+               }
+
+       if (iv)
+               {
+               xctx->xts.key2 = &xctx->ks2;
+               memcpy(ctx->iv, iv, 16);
+               }
+
+       return 1;
+       }
+
+static int aes_xts(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               const unsigned char *in, size_t len)
+       {
+       EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+       if (!xctx->xts.key1 || !xctx->xts.key2)
+               return -1;
+       if (!out || !in)
+               return -1;
+       if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
+                                                               ctx->encrypt))
+               return -1;
+       return len;
+       }
+
+static const EVP_CIPHER aes_128_xts_cipher=
+       {
+       NID_aes_128_xts,16,32,16,
+       EVP_CIPH_XTS_MODE|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1
+               | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
+               | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
+       aes_xts_init_key,
+       aes_xts,
+       0,
+       sizeof(EVP_AES_XTS_CTX),
+       NULL,
+       NULL,
+       aes_xts_ctrl,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_aes_128_xts (void)
+{      return &aes_128_xts_cipher;     }
+       
+static const EVP_CIPHER aes_256_xts_cipher=
+       {
+       NID_aes_256_xts,16,64,16,
+       EVP_CIPH_XTS_MODE|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1
+               | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
+               | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT,
+       aes_xts_init_key,
+       aes_xts,
+       0,
+       sizeof(EVP_AES_XTS_CTX),
+       NULL,
+       NULL,
+       aes_xts_ctrl,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_aes_256_xts (void)
+{      return &aes_256_xts_cipher;     }
                
 #endif
index 8e041c56d1a0b09fbb832d32584a07615a9e6950..d51e0d3403da5c492ac4f3b65c143226790421da 100644 (file)
@@ -83,7 +83,7 @@
 #define EVP_RC5_32_12_16_KEY_SIZE      16
 */
 #define EVP_MAX_MD_SIZE                        64      /* longest known is SHA512 */
-#define EVP_MAX_KEY_LENGTH             32
+#define EVP_MAX_KEY_LENGTH             64
 #define EVP_MAX_IV_LENGTH              16
 #define EVP_MAX_BLOCK_LENGTH           32
 
@@ -330,6 +330,8 @@ struct evp_cipher_st
 #define                EVP_CIPH_OFB_MODE               0x4
 #define                EVP_CIPH_CTR_MODE               0x5
 #define                EVP_CIPH_GCM_MODE               0x6
+#define                EVP_CIPH_CCM_MODE               0x7
+#define                EVP_CIPH_XTS_MODE               0x10001
 #define        EVP_CIPH_MODE                   0xF0007
 /* Set if variable length cipher */
 #define        EVP_CIPH_VARIABLE_LENGTH        0x8
@@ -788,6 +790,7 @@ const EVP_CIPHER *EVP_aes_128_cfb128(void);
 const EVP_CIPHER *EVP_aes_128_ofb(void);
 const EVP_CIPHER *EVP_aes_128_ctr(void);
 const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
 const EVP_CIPHER *EVP_aes_192_ecb(void);
 const EVP_CIPHER *EVP_aes_192_cbc(void);
 const EVP_CIPHER *EVP_aes_192_cfb1(void);
@@ -806,6 +809,7 @@ const EVP_CIPHER *EVP_aes_256_cfb128(void);
 const EVP_CIPHER *EVP_aes_256_ofb(void);
 const EVP_CIPHER *EVP_aes_256_ctr(void);
 const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
 const EVP_CIPHER *EVP_camellia_128_ecb(void);
index 28ee07c3fa097a1b2c2de966f4f80fc07a911901..57433fdbd013385d66c31204400f05e589da6873 100644 (file)
@@ -21,9 +21,9 @@ TEST=
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c
+LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c xts128.c
 LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o gcm128.o \
-       $(MODES_ASM_OBJ)
+       xts128.o $(MODES_ASM_OBJ)
 
 SRC= $(LIBSRC)
 
index 0a41b23eaa93a0f42de35648e1136e5bf1261857..1ef78cef222a94b4abf1bf33bf0f540bb0945413 100644 (file)
@@ -104,3 +104,9 @@ int  CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
                        size_t len);
 void  CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
 void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+typedef struct xts128_context XTS128_CONTEXT;
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char *iv,
+       const unsigned char *inp, unsigned char *out,
+       size_t len, int enc);
index a789e8584c2b54356091f6ee5359a3fb1f0e448e..1ac0e01a88277b1dff430c98909b834742d7428a 100644 (file)
@@ -116,3 +116,9 @@ struct gcm128_context {
        block128_f block;
        void *key;
 };
+
+struct xts128_context {
+       void      *key1, *key2;
+       block128_f block1,block2;
+};
+
index de1f5a11fa244eafaed4597d8fa34a7547499ad1..aaa44e05f04a40123d52a49c32063a553f72ecef 100644 (file)
 #endif
 #include <assert.h>
 
-typedef struct {
-       void      *key1, *key2;
-       block128_f block1,block2;
-} XTS128_CONTEXT;
-
-int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, u64 secno,
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char *iv,
        const unsigned char *inp, unsigned char *out,
        size_t len, int enc)
 {
@@ -73,15 +68,7 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, u64 secno,
 
        if (len<16) return -1;
 
-       if (is_endian.little) {
-               tweak.u[0] = secno;
-               tweak.u[1] = 0;
-       }
-       else {
-               PUTU32(tweak.c,secno);
-               PUTU32(tweak.c+4,secno>>32);
-               tweak.u[1] = 0;
-       }
+       memcpy(tweak.c, iv, 16);
 
        (*ctx->block2)(tweak.c,tweak.c,ctx->key2);
 
index 1477c787f8df580f1d23ff7b80bf834b1cd64aff..8d1100b321eb806b76ca5e2967d65f0d7beedca8 100644 (file)
@@ -62,9 +62,9 @@
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 913
-#define NUM_SN 906
-#define NUM_LN 906
+#define NUM_NID 915
+#define NUM_SN 908
+#define NUM_LN 908
 #define NUM_OBJ 856
 
 static const unsigned char lvalues[5971]={
@@ -2395,6 +2395,8 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
        NID_anyExtendedKeyUsage,4,&(lvalues[5948]),0},
 {"MGF1","mgf1",NID_mgf1,9,&(lvalues[5952]),0},
 {"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5961]),0},
+{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0},
+{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0},
 };
 
 static const unsigned int sn_objs[NUM_SN]={
@@ -2406,6 +2408,7 @@ static const unsigned int sn_objs[NUM_SN]={
 904,   /* "AES-128-CTR" */
 418,   /* "AES-128-ECB" */
 420,   /* "AES-128-OFB" */
+913,   /* "AES-128-XTS" */
 423,   /* "AES-192-CBC" */
 425,   /* "AES-192-CFB" */
 651,   /* "AES-192-CFB1" */
@@ -2420,6 +2423,7 @@ static const unsigned int sn_objs[NUM_SN]={
 906,   /* "AES-256-CTR" */
 426,   /* "AES-256-ECB" */
 428,   /* "AES-256-OFB" */
+914,   /* "AES-256-XTS" */
 91,    /* "BF-CBC" */
 93,    /* "BF-CFB" */
 92,    /* "BF-ECB" */
@@ -3459,6 +3463,7 @@ static const unsigned int ln_objs[NUM_LN]={
 418,   /* "aes-128-ecb" */
 895,   /* "aes-128-gcm" */
 420,   /* "aes-128-ofb" */
+913,   /* "aes-128-xts" */
 423,   /* "aes-192-cbc" */
 899,   /* "aes-192-ccm" */
 425,   /* "aes-192-cfb" */
@@ -3477,6 +3482,7 @@ static const unsigned int ln_objs[NUM_LN]={
 426,   /* "aes-256-ecb" */
 901,   /* "aes-256-gcm" */
 428,   /* "aes-256-ofb" */
+914,   /* "aes-256-xts" */
 376,   /* "algorithm" */
 484,   /* "associatedDomain" */
 485,   /* "associatedName" */
index 9b88cf88d656d6d6423278b725961dd4ce5bbd2d..6de8c704791ebe308bb46f19525327fafb31b966 100644 (file)
 #define LN_aes_256_ctr         "aes-256-ctr"
 #define NID_aes_256_ctr                906
 
+#define SN_aes_128_xts         "AES-128-XTS"
+#define LN_aes_128_xts         "aes-128-xts"
+#define NID_aes_128_xts                913
+
+#define SN_aes_256_xts         "AES-256-XTS"
+#define LN_aes_256_xts         "aes-256-xts"
+#define NID_aes_256_xts                914
+
 #define SN_des_cfb1            "DES-CFB1"
 #define LN_des_cfb1            "des-cfb1"
 #define NID_des_cfb1           656
index 5ff1f49e82bae0ab279ab1992982348a00643560..cbd77f3a41d0d73d98fe9ef9995b3b87a507031d 100644 (file)
@@ -910,3 +910,5 @@ id_camellia256_wrap         909
 anyExtendedKeyUsage            910
 mgf1           911
 rsassaPss              912
+aes_128_xts            913
+aes_256_xts            914
index 7d53d9a12cc22f6eea212bf3be08cc14f1245a06..1bf3ad6eedcb62b53ae45100119605bad4cb46c8 100644 (file)
@@ -892,6 +892,8 @@ aes 48                      : id-aes256-wrap-pad
                        : AES-128-CTR           : aes-128-ctr
                        : AES-192-CTR           : aes-192-ctr
                        : AES-256-CTR           : aes-256-ctr
+                       : AES-128-XTS           : aes-128-xts
+                       : AES-256-XTS           : aes-256-xts
                        : DES-CFB1              : des-cfb1
                        : DES-CFB8              : des-cfb8
                        : DES-EDE3-CFB1         : des-ede3-cfb1