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]