diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-04-12 23:21:33 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-04-12 23:21:33 +0000 |
commit | 32a2d8ddfebdde06bfdf4fdac54d487c5d03cbea (patch) | |
tree | 65c2b96de034be57560a3cc7943890ce62d6b2ce /crypto/evp | |
parent | 4bd1e895faa35a8d4810402fe3ba9d07c1166908 (diff) |
Provisional AES XTS support.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/e_aes.c | 99 | ||||
-rw-r--r-- | crypto/evp/evp.h | 6 |
2 files changed, 104 insertions, 1 deletions
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); |