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 fa1bb50..877976c 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 b1a701b..a6d1b5d 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 8e041c5..d51e0d3 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 28ee07c..57433fd 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 0a41b23..1ef78ce 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 a789e85..1ac0e01 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 de1f5a1..aaa44e0 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 1477c78..8d1100b 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 9b88cf8..6de8c70 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 5ff1f49..cbd77f3 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 7d53d9a..1bf3ad6 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