svn commit: r214254 - stable/8/sys/opencrypto

Pawel Jakub Dawidek pjd at FreeBSD.org
Sat Oct 23 22:11:30 UTC 2010


Author: pjd
Date: Sat Oct 23 22:11:30 2010
New Revision: 214254
URL: http://svn.freebsd.org/changeset/base/214254

Log:
  MFC r213065,r213068:
  
  r213065:
  
  Remove redundant space.
  
  r213068:
  
  Add support for AES-XTS.
  
  Obtained from:	OpenBSD

Modified:
  stable/8/sys/opencrypto/cryptodev.c
  stable/8/sys/opencrypto/cryptodev.h
  stable/8/sys/opencrypto/cryptosoft.c
  stable/8/sys/opencrypto/xform.c
  stable/8/sys/opencrypto/xform.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/opencrypto/cryptodev.c
==============================================================================
--- stable/8/sys/opencrypto/cryptodev.c	Sat Oct 23 22:04:37 2010	(r214253)
+++ stable/8/sys/opencrypto/cryptodev.c	Sat Oct 23 22:11:30 2010	(r214254)
@@ -419,6 +419,9 @@ cryptof_ioctl(
 		case CRYPTO_AES_CBC:
 			txform = &enc_xform_rijndael128;
 			break;
+		case CRYPTO_AES_XTS:
+			txform = &enc_xform_aes_xts;
+			break;
 		case CRYPTO_NULL_CBC:
 			txform = &enc_xform_null;
 			break;

Modified: stable/8/sys/opencrypto/cryptodev.h
==============================================================================
--- stable/8/sys/opencrypto/cryptodev.h	Sat Oct 23 22:04:37 2010	(r214253)
+++ stable/8/sys/opencrypto/cryptodev.h	Sat Oct 23 22:11:30 2010	(r214254)
@@ -123,7 +123,8 @@
 #define	CRYPTO_SHA2_384_HMAC	19
 #define	CRYPTO_SHA2_512_HMAC	20
 #define CRYPTO_CAMELLIA_CBC	21
-#define	CRYPTO_ALGORITHM_MAX	21 /* Keep updated - see below */
+#define	CRYPTO_AES_XTS		22
+#define	CRYPTO_ALGORITHM_MAX	22 /* Keep updated - see below */
 
 /* Algorithm flags */
 #define	CRYPTO_ALG_FLAG_SUPPORTED	0x01 /* Algorithm is supported */

Modified: stable/8/sys/opencrypto/cryptosoft.c
==============================================================================
--- stable/8/sys/opencrypto/cryptosoft.c	Sat Oct 23 22:04:37 2010	(r214253)
+++ stable/8/sys/opencrypto/cryptosoft.c	Sat Oct 23 22:11:30 2010	(r214254)
@@ -114,8 +114,16 @@ swcr_encdec(struct cryptodesc *crd, stru
 		if (error)
 			return (error);
 	}
+
 	ivp = iv;
 
+	/*
+	 * xforms that provide a reinit method perform all IV
+	 * handling themselves.
+	 */
+	if (exf->reinit)
+		exf->reinit(sw->sw_kschedule, iv);
+
 	if (flags & CRYPTO_F_IMBUF) {
 		struct mbuf *m = (struct mbuf *) buf;
 
@@ -135,7 +143,15 @@ swcr_encdec(struct cryptodesc *crd, stru
 				m_copydata(m, k, blks, blk);
 
 				/* Actual encryption/decryption */
-				if (crd->crd_flags & CRD_F_ENCRYPT) {
+				if (exf->reinit) {
+					if (crd->crd_flags & CRD_F_ENCRYPT) {
+						exf->encrypt(sw->sw_kschedule,
+						    blk);
+					} else {
+						exf->decrypt(sw->sw_kschedule,
+						    blk);
+					}
+				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
 					/* XOR with previous block */
 					for (j = 0; j < blks; j++)
 						blk[j] ^= ivp[j];
@@ -205,7 +221,15 @@ swcr_encdec(struct cryptodesc *crd, stru
 			idat = mtod(m, unsigned char *) + k;
 
 	   		while (m->m_len >= k + blks && i > 0) {
-				if (crd->crd_flags & CRD_F_ENCRYPT) {
+				if (exf->reinit) {
+					if (crd->crd_flags & CRD_F_ENCRYPT) {
+						exf->encrypt(sw->sw_kschedule,
+						    idat);
+					} else {
+						exf->decrypt(sw->sw_kschedule,
+						    idat);
+					}
+				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
 					/* XOR with previous block/IV */
 					for (j = 0; j < blks; j++)
 						idat[j] ^= ivp[j];
@@ -261,7 +285,15 @@ swcr_encdec(struct cryptodesc *crd, stru
 				cuio_copydata(uio, k, blks, blk);
 
 				/* Actual encryption/decryption */
-				if (crd->crd_flags & CRD_F_ENCRYPT) {
+				if (exf->reinit) {
+					if (crd->crd_flags & CRD_F_ENCRYPT) {
+						exf->encrypt(sw->sw_kschedule,
+						    blk);
+					} else {
+						exf->decrypt(sw->sw_kschedule,
+						    blk);
+					}
+				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
 					/* XOR with previous block */
 					for (j = 0; j < blks; j++)
 						blk[j] ^= ivp[j];
@@ -319,7 +351,15 @@ swcr_encdec(struct cryptodesc *crd, stru
 			idat = (char *)iov->iov_base + k;
 
 	   		while (iov->iov_len >= k + blks && i > 0) {
-				if (crd->crd_flags & CRD_F_ENCRYPT) {
+				if (exf->reinit) {
+					if (crd->crd_flags & CRD_F_ENCRYPT) {
+						exf->encrypt(sw->sw_kschedule,
+						    idat);
+					} else {
+						exf->decrypt(sw->sw_kschedule,
+						    idat);
+					}
+				} else if (crd->crd_flags & CRD_F_ENCRYPT) {
 					/* XOR with previous block/IV */
 					for (j = 0; j < blks; j++)
 						idat[j] ^= ivp[j];
@@ -360,7 +400,15 @@ swcr_encdec(struct cryptodesc *crd, stru
 
 		return 0; /* Done with iovec encryption/decryption */
 	} else {	/* contiguous buffer */
-		if (crd->crd_flags & CRD_F_ENCRYPT) {
+		if (exf->reinit) {
+			for (i = crd->crd_skip;
+			    i < crd->crd_skip + crd->crd_len; i += blks) {
+				if (crd->crd_flags & CRD_F_ENCRYPT)
+					exf->encrypt(sw->sw_kschedule, buf + i);
+				else
+					exf->decrypt(sw->sw_kschedule, buf + i);
+			}
+		} else if (crd->crd_flags & CRD_F_ENCRYPT) {
 			for (i = crd->crd_skip;
 			    i < crd->crd_skip + crd->crd_len; i += blks) {
 				/* XOR with the IV/previous block, as appropriate. */
@@ -687,6 +735,9 @@ swcr_newsession(device_t dev, u_int32_t 
 		case CRYPTO_RIJNDAEL128_CBC:
 			txf = &enc_xform_rijndael128;
 			goto enccommon;
+		case CRYPTO_AES_XTS:
+			txf = &enc_xform_aes_xts;
+			goto enccommon;
 		case CRYPTO_CAMELLIA_CBC:
 			txf = &enc_xform_camellia;
 			goto enccommon;
@@ -845,6 +896,7 @@ swcr_freesession(device_t dev, u_int64_t
 		case CRYPTO_CAST_CBC:
 		case CRYPTO_SKIPJACK_CBC:
 		case CRYPTO_RIJNDAEL128_CBC:
+		case CRYPTO_AES_XTS:
 		case CRYPTO_CAMELLIA_CBC:
 		case CRYPTO_NULL_CBC:
 			txf = swd->sw_exf;
@@ -958,6 +1010,7 @@ swcr_process(device_t dev, struct crypto
 		case CRYPTO_CAST_CBC:
 		case CRYPTO_SKIPJACK_CBC:
 		case CRYPTO_RIJNDAEL128_CBC:
+		case CRYPTO_AES_XTS:
 		case CRYPTO_CAMELLIA_CBC:
 			if ((crp->crp_etype = swcr_encdec(crd, sw,
 			    crp->crp_buf, crp->crp_flags)) != 0)
@@ -1050,6 +1103,7 @@ swcr_attach(device_t dev)
 	REGISTER(CRYPTO_MD5);
 	REGISTER(CRYPTO_SHA1);
 	REGISTER(CRYPTO_RIJNDAEL128_CBC);
+	REGISTER(CRYPTO_AES_XTS);
  	REGISTER(CRYPTO_CAMELLIA_CBC);
 	REGISTER(CRYPTO_DEFLATE_COMP);
 #undef REGISTER

Modified: stable/8/sys/opencrypto/xform.c
==============================================================================
--- stable/8/sys/opencrypto/xform.c	Sat Oct 23 22:04:37 2010	(r214253)
+++ stable/8/sys/opencrypto/xform.c	Sat Oct 23 22:11:30 2010	(r214254)
@@ -64,40 +64,48 @@ __FBSDID("$FreeBSD$");
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>
 
-static void null_encrypt(caddr_t, u_int8_t *);
-static void null_decrypt(caddr_t, u_int8_t *);
-static int null_setkey(u_int8_t **, u_int8_t *, int);
-static void null_zerokey(u_int8_t **);
-
+static	int null_setkey(u_int8_t **, u_int8_t *, int);
 static	int des1_setkey(u_int8_t **, u_int8_t *, int);
 static	int des3_setkey(u_int8_t **, u_int8_t *, int);
 static	int blf_setkey(u_int8_t **, u_int8_t *, int);
 static	int cast5_setkey(u_int8_t **, u_int8_t *, int);
 static	int skipjack_setkey(u_int8_t **, u_int8_t *, int);
 static	int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
+static	int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
 static	int cml_setkey(u_int8_t **, u_int8_t *, int);
+
+static	void null_encrypt(caddr_t, u_int8_t *);
 static	void des1_encrypt(caddr_t, u_int8_t *);
 static	void des3_encrypt(caddr_t, u_int8_t *);
 static	void blf_encrypt(caddr_t, u_int8_t *);
 static	void cast5_encrypt(caddr_t, u_int8_t *);
 static	void skipjack_encrypt(caddr_t, u_int8_t *);
 static	void rijndael128_encrypt(caddr_t, u_int8_t *);
+static	void aes_xts_encrypt(caddr_t, u_int8_t *);
 static	void cml_encrypt(caddr_t, u_int8_t *);
+
+static	void null_decrypt(caddr_t, u_int8_t *);
 static	void des1_decrypt(caddr_t, u_int8_t *);
 static	void des3_decrypt(caddr_t, u_int8_t *);
 static	void blf_decrypt(caddr_t, u_int8_t *);
 static	void cast5_decrypt(caddr_t, u_int8_t *);
 static	void skipjack_decrypt(caddr_t, u_int8_t *);
 static	void rijndael128_decrypt(caddr_t, u_int8_t *);
+static	void aes_xts_decrypt(caddr_t, u_int8_t *);
 static	void cml_decrypt(caddr_t, u_int8_t *);
+
+static	void null_zerokey(u_int8_t **);
 static	void des1_zerokey(u_int8_t **);
 static	void des3_zerokey(u_int8_t **);
 static	void blf_zerokey(u_int8_t **);
 static	void cast5_zerokey(u_int8_t **);
 static	void skipjack_zerokey(u_int8_t **);
 static	void rijndael128_zerokey(u_int8_t **);
+static	void aes_xts_zerokey(u_int8_t **);
 static	void cml_zerokey(u_int8_t **);
 
+static	void aes_xts_reinit(caddr_t, u_int8_t *);
+
 static	void null_init(void *);
 static	int null_update(void *, u_int8_t *, u_int16_t);
 static	void null_final(u_int8_t *, void *);
@@ -124,6 +132,7 @@ struct enc_xform enc_xform_null = {
 	null_decrypt,
 	null_setkey,
 	null_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_des = {
@@ -133,6 +142,7 @@ struct enc_xform enc_xform_des = {
 	des1_decrypt,
 	des1_setkey,
 	des1_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_3des = {
@@ -141,7 +151,8 @@ struct enc_xform enc_xform_3des = {
 	des3_encrypt,
 	des3_decrypt,
 	des3_setkey,
-	des3_zerokey
+	des3_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_blf = {
@@ -150,7 +161,8 @@ struct enc_xform enc_xform_blf = {
 	blf_encrypt,
 	blf_decrypt,
 	blf_setkey,
-	blf_zerokey
+	blf_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_cast5 = {
@@ -159,7 +171,8 @@ struct enc_xform enc_xform_cast5 = {
 	cast5_encrypt,
 	cast5_decrypt,
 	cast5_setkey,
-	cast5_zerokey
+	cast5_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_skipjack = {
@@ -168,7 +181,8 @@ struct enc_xform enc_xform_skipjack = {
 	skipjack_encrypt,
 	skipjack_decrypt,
 	skipjack_setkey,
-	skipjack_zerokey
+	skipjack_zerokey,
+	NULL
 };
 
 struct enc_xform enc_xform_rijndael128 = {
@@ -178,6 +192,17 @@ struct enc_xform enc_xform_rijndael128 =
 	rijndael128_decrypt,
 	rijndael128_setkey,
 	rijndael128_zerokey,
+	NULL
+};
+
+struct enc_xform enc_xform_aes_xts = {
+	CRYPTO_AES_XTS, "AES-XTS",
+	RIJNDAEL128_BLOCK_LEN, 32, 64,
+	aes_xts_encrypt,
+	aes_xts_decrypt,
+	aes_xts_setkey,
+	aes_xts_zerokey,
+	aes_xts_reinit
 };
 
 struct enc_xform enc_xform_arc4 = {
@@ -187,6 +212,7 @@ struct enc_xform enc_xform_arc4 = {
 	NULL,
 	NULL,
 	NULL,
+	NULL
 };
 
 struct enc_xform enc_xform_camellia = {
@@ -196,6 +222,7 @@ struct enc_xform enc_xform_camellia = {
 	cml_decrypt,
 	cml_setkey,
 	cml_zerokey,
+	NULL
 };
 
 /* Authentication instances */
@@ -226,7 +253,7 @@ struct auth_hash auth_hash_hmac_ripemd_1
 };
 
 struct auth_hash auth_hash_key_md5 = {
-	CRYPTO_MD5_KPDK, "Keyed MD5", 
+	CRYPTO_MD5_KPDK, "Keyed MD5",
 	0, MD5_KPDK_HASH_LEN, 0, sizeof(MD5_CTX),
 	(void (*)(void *)) MD5Init, MD5Update_int,
 	(void (*)(u_int8_t *, void *)) MD5Final
@@ -547,6 +574,107 @@ rijndael128_zerokey(u_int8_t **sched)
 	*sched = NULL;
 }
 
+#define	AES_XTS_BLOCKSIZE	16
+#define	AES_XTS_IVSIZE		8
+#define	AES_XTS_ALPHA		0x87	/* GF(2^128) generator polynomial */
+
+struct aes_xts_ctx {
+	rijndael_ctx key1;
+	rijndael_ctx key2;
+	u_int8_t tweak[AES_XTS_BLOCKSIZE];
+};
+
+void
+aes_xts_reinit(caddr_t key, u_int8_t *iv)
+{
+	struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
+	u_int64_t blocknum;
+	u_int i;
+
+	/*
+	 * Prepare tweak as E_k2(IV). IV is specified as LE representation
+	 * of a 64-bit block number which we allow to be passed in directly.
+	 */
+	bcopy(iv, &blocknum, AES_XTS_IVSIZE);
+	for (i = 0; i < AES_XTS_IVSIZE; i++) {
+		ctx->tweak[i] = blocknum & 0xff;
+		blocknum >>= 8;
+	}
+	/* Last 64 bits of IV are always zero */
+	bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
+
+	rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
+}
+
+static void
+aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
+{
+	u_int8_t block[AES_XTS_BLOCKSIZE];
+	u_int i, carry_in, carry_out;
+
+	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
+		block[i] = data[i] ^ ctx->tweak[i];
+
+	if (do_encrypt)
+		rijndael_encrypt(&ctx->key1, block, data);
+	else
+		rijndael_decrypt(&ctx->key1, block, data);
+
+	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
+		data[i] ^= ctx->tweak[i];
+
+	/* Exponentiate tweak */
+	carry_in = 0;
+	for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
+		carry_out = ctx->tweak[i] & 0x80;
+		ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
+		carry_in = carry_out;
+	}
+	if (carry_in)
+		ctx->tweak[0] ^= AES_XTS_ALPHA;
+	bzero(block, sizeof(block));
+}
+
+void
+aes_xts_encrypt(caddr_t key, u_int8_t *data)
+{
+	aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
+}
+
+void
+aes_xts_decrypt(caddr_t key, u_int8_t *data)
+{
+	aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
+}
+
+int
+aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
+{
+	struct aes_xts_ctx *ctx;
+
+	if (len != 32 && len != 64)
+		return EINVAL;
+
+	*sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
+	    M_NOWAIT | M_ZERO);
+	if (*sched == NULL)
+		return ENOMEM;
+	ctx = (struct aes_xts_ctx *)*sched;
+
+	rijndael_set_key(&ctx->key1, key, len * 4);
+	rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
+
+	return 0;
+}
+
+void
+aes_xts_zerokey(u_int8_t **sched)
+{
+	bzero(*sched, sizeof(struct aes_xts_ctx));
+	free(*sched, M_CRYPTO_DATA);
+	*sched = NULL;
+}
+
 static void
 cml_encrypt(caddr_t key, u_int8_t *blk)
 {

Modified: stable/8/sys/opencrypto/xform.h
==============================================================================
--- stable/8/sys/opencrypto/xform.h	Sat Oct 23 22:04:37 2010	(r214253)
+++ stable/8/sys/opencrypto/xform.h	Sat Oct 23 22:11:30 2010	(r214254)
@@ -54,6 +54,7 @@ struct enc_xform {
 	void (*decrypt) (caddr_t, u_int8_t *);
 	int (*setkey) (u_int8_t **, u_int8_t *, int len);
 	void (*zerokey) (u_int8_t **);
+	void (*reinit) (caddr_t, u_int8_t *);
 };
 
 struct comp_algo {
@@ -80,6 +81,7 @@ extern struct enc_xform enc_xform_blf;
 extern struct enc_xform enc_xform_cast5;
 extern struct enc_xform enc_xform_skipjack;
 extern struct enc_xform enc_xform_rijndael128;
+extern struct enc_xform enc_xform_aes_xts;
 extern struct enc_xform enc_xform_arc4;
 extern struct enc_xform enc_xform_camellia;
 


More information about the svn-src-all mailing list