From 32a2d8ddfebdde06bfdf4fdac54d487c5d03cbea Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 12 Apr 2011 23:21:33 +0000 Subject: [PATCH] Provisional AES XTS support. --- CHANGES | 5 ++ crypto/evp/e_aes.c | 99 ++++++++++++++++++++++++++++++++++++++ crypto/evp/evp.h | 6 ++- crypto/modes/Makefile | 4 +- crypto/modes/modes.h | 6 +++ crypto/modes/modes_lcl.h | 6 +++ crypto/modes/xts128.c | 17 +------ crypto/objects/obj_dat.h | 12 +++-- crypto/objects/obj_mac.h | 8 +++ crypto/objects/obj_mac.num | 2 + crypto/objects/objects.txt | 2 + 11 files changed, 146 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index fa1bb509aa..877976c23a 100644 --- 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 diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index b1a701b65d..a6d1b5da9f 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -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 diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 8e041c56d1..d51e0d3403 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -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); diff --git a/crypto/modes/Makefile b/crypto/modes/Makefile index 28ee07c3fa..57433fdbd0 100644 --- a/crypto/modes/Makefile +++ b/crypto/modes/Makefile @@ -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) diff --git a/crypto/modes/modes.h b/crypto/modes/modes.h index 0a41b23eaa..1ef78cef22 100644 --- a/crypto/modes/modes.h +++ b/crypto/modes/modes.h @@ -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); diff --git a/crypto/modes/modes_lcl.h b/crypto/modes/modes_lcl.h index a789e8584c..1ac0e01a88 100644 --- a/crypto/modes/modes_lcl.h +++ b/crypto/modes/modes_lcl.h @@ -116,3 +116,9 @@ struct gcm128_context { block128_f block; void *key; }; + +struct xts128_context { + void *key1, *key2; + block128_f block1,block2; +}; + diff --git a/crypto/modes/xts128.c b/crypto/modes/xts128.c index de1f5a11fa..aaa44e05f0 100644 --- a/crypto/modes/xts128.c +++ b/crypto/modes/xts128.c @@ -58,12 +58,7 @@ #endif #include -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); diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 1477c787f8..8d1100b321 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -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" */ diff --git a/crypto/objects/obj_mac.h b/crypto/objects/obj_mac.h index 9b88cf88d6..6de8c70479 100644 --- a/crypto/objects/obj_mac.h +++ b/crypto/objects/obj_mac.h @@ -2735,6 +2735,14 @@ #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 diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 5ff1f49e82..cbd77f3a41 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -910,3 +910,5 @@ id_camellia256_wrap 909 anyExtendedKeyUsage 910 mgf1 911 rsassaPss 912 +aes_128_xts 913 +aes_256_xts 914 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 7d53d9a12c..1bf3ad6eed 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -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 -- GitLab