Is there no interest in this patch? ---------- Forwarded Message ----------
Subject: [Patch] EVP AES XTS for OpenSSL Date: Sunday 14 November 2010 From: Joel Sing <[email protected]> To: [email protected] Hi, The following patch provides an EVP AES XTS implementation for possible inclusion in OpenSSL. This work is largely based on a standalone AES XTS implementation created by Damien Miller ([email protected]). The AES XTS block/unit number is provided via the EVP IV interface. A test application can also be provided if anyone is interested. Cheers, Joel Index: crypto/evp/Makefile =================================================================== RCS file: /v/openssl/cvs/openssl/crypto/evp/Makefile,v retrieving revision 1.25 diff -u -p -u -p -r1.25 Makefile --- crypto/evp/Makefile 15 Jan 2010 15:24:16 -0000 1.25 +++ crypto/evp/Makefile 12 Nov 2010 12:29:07 -0000 @@ -20,7 +20,7 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \ e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\ - e_rc4.c e_aes.c names.c e_seed.c \ + e_rc4.c e_aes.c e_aes_xts.c names.c e_seed.c \ e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \ m_null.c m_md2.c m_md4.c m_md5.c m_sha.c m_sha1.c m_wp.c \ m_dss.c m_dss1.c m_mdc2.c m_ripemd.c m_ecdsa.c\ @@ -32,7 +32,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \ e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\ - e_rc4.o e_aes.o names.o e_seed.o \ + e_rc4.o e_aes.o e_aes_xts.o names.o e_seed.o \ e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \ m_null.o m_md2.o m_md4.o m_md5.o m_sha.o m_sha1.o m_wp.o \ m_dss.o m_dss1.o m_mdc2.o m_ripemd.o m_ecdsa.o\ @@ -189,11 +189,19 @@ e_aes.o: ../../include/openssl/aes.h ../ e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h -e_aes.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h -e_aes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h -e_aes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h -e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h e_aes.c -e_aes.o: evp_locl.h +e_aes.o: ../../include/openssl/modes.h ../../include/openssl/obj_mac.h +e_aes.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +e_aes.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +e_aes.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +e_aes.o: ../../include/openssl/symhacks.h e_aes.c evp_locl.h +e_aes_xts.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +e_aes_xts.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +e_aes_xts.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +e_aes_xts.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +e_aes_xts.o: ../../include/openssl/opensslconf.h +e_aes_xts.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +e_aes_xts.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +e_aes_xts.o: ../../include/openssl/symhacks.h e_aes_xts.c e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h Index: crypto/evp/e_aes_xts.c =================================================================== RCS file: crypto/evp/e_aes_xts.c diff -N crypto/evp/e_aes_xts.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ crypto/evp/e_aes_xts.c 12 Nov 2010 12:29:07 -0000 @@ -0,0 +1,160 @@ +/* crypto/evp/e_aes_xts.c */ +/* + * Copyright (c) 2003 Markus Friedl <[email protected]> + * Copyright (c) 2008 Damien Miller <[email protected]> + * Copyright (c) 2010 Joel Sing <[email protected]> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <openssl/opensslconf.h> +#ifndef OPENSSL_NO_AES + +#include <string.h> + +#include <openssl/aes.h> +#include <openssl/evp.h> + +#define GF2_128_ALPHA 0x87 + +struct aes_xts_ctx +{ + AES_KEY aes_key1; + AES_KEY aes_key2; + u_char unit_no[AES_BLOCK_SIZE]; /* Unit no in network order. */ + u_char tweak[AES_BLOCK_SIZE]; + int init_tweak; + int enc; +}; + +static int +aes_xts_init(EVP_CIPHER_CTX *cc, const u_char *key, const u_char *iv, int enc) +{ + struct aes_xts_ctx *ctx; + int i; + + ctx = (struct aes_xts_ctx *)cc->cipher_data; + + if (enc != -1) + ctx->enc = enc; + + if (iv != NULL) { + for (i = 0; i < AES_BLOCK_SIZE; i++) + ctx->unit_no[i] = iv[i]; + ctx->init_tweak = 1; + } + + if (key != NULL) { + + if (EVP_CIPHER_CTX_key_length(cc) != 32 && + EVP_CIPHER_CTX_key_length(cc) != 64) + return (0); + + if (enc) + AES_set_encrypt_key(key, + (EVP_CIPHER_CTX_key_length(cc) / 2) * 8, + &ctx->aes_key1); + else + AES_set_decrypt_key(key, + (EVP_CIPHER_CTX_key_length(cc) / 2) * 8, + &ctx->aes_key1); + + AES_set_encrypt_key(key + (EVP_CIPHER_CTX_key_length(cc) / 2), + (EVP_CIPHER_CTX_key_length(cc) / 2) * 8, &ctx->aes_key2); + + } + + return (1); +} + +static int +aes_xts_cleanup(EVP_CIPHER_CTX *cc) +{ + return (1); +} + +static int +aes_xts_crypt(EVP_CIPHER_CTX *cc, u_char *dst, const u_char *src, size_t len) +{ + struct aes_xts_ctx *ctx; + u_int8_t block[AES_BLOCK_SIZE]; + u_int carry_in, carry_out; + int i, j; + + if (len % AES_BLOCK_SIZE != 0) + return (0); + + ctx = (struct aes_xts_ctx *)cc->cipher_data; + + if (ctx->init_tweak) { + + /* Tweak starts as E(key2, unit_no as 128-bit LE). */ + for (i = 0; i < AES_BLOCK_SIZE; i++) + ctx->tweak[i] = ctx->unit_no[AES_BLOCK_SIZE - 1 - i]; + AES_encrypt(ctx->tweak, ctx->tweak, &ctx->aes_key2); + ctx->init_tweak = 0; + + } + + for (i = 0; i < len; i += AES_BLOCK_SIZE) { + + for (j = 0; j < AES_BLOCK_SIZE; j++) + block[j] = src[i + j] ^ ctx->tweak[j]; + + if (ctx->enc) + AES_encrypt(block, dst + i, &ctx->aes_key1); + else + AES_decrypt(block, dst + i, &ctx->aes_key1); + + for (j = 0; j < AES_BLOCK_SIZE; j++) + dst[i + j] ^= ctx->tweak[j]; + + /* Exponentiate tweak. */ + carry_in = 0; + for (j = 0; j < AES_BLOCK_SIZE; j++) { + carry_out = ctx->tweak[j] & 0x80; + ctx->tweak[j] = + (ctx->tweak[j] << 1) | (carry_in ? 1 : 0); + carry_in = carry_out; + } + if (carry_in) + ctx->tweak[0] ^= GF2_128_ALPHA; + + } + + bzero(block, sizeof(block)); + + return (1); +} + +const EVP_CIPHER +*EVP_aes_xts(void) +{ + static EVP_CIPHER aes_xts; + + bzero(&aes_xts, sizeof(EVP_CIPHER)); + + aes_xts.nid = NID_undef; + aes_xts.block_size = AES_BLOCK_SIZE; + aes_xts.ctx_size = sizeof(struct aes_xts_ctx); + aes_xts.iv_len = 0; + aes_xts.key_len = 0; + aes_xts.init = aes_xts_init; + aes_xts.cleanup = aes_xts_cleanup; + aes_xts.do_cipher = aes_xts_crypt; + aes_xts.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CUSTOM_IV; + + return (&aes_xts); +} +#endif -- "Stop assuming that systems are secure unless demonstrated insecure; start assuming that systems are insecure unless designed securely." - Bruce Schneier ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [email protected]
