Commit 32a2d8dd authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Provisional AES XTS support.

parent 4bd1e895
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+99 −0
Original line number Diff line number Diff line
@@ -459,4 +459,103 @@ 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
+5 −1
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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)

+6 −0
Original line number Diff line number Diff line
@@ -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);
Loading