svn commit: r213070 - head/sys/geom/eli

Pawel Jakub Dawidek pjd at FreeBSD.org
Thu Sep 23 11:58:37 UTC 2010


Author: pjd
Date: Thu Sep 23 11:58:36 2010
New Revision: 213070
URL: http://svn.freebsd.org/changeset/base/213070

Log:
  Add support for AES-XTS. This will be the default now.
  
  MFC after:	1 week

Modified:
  head/sys/geom/eli/g_eli.c
  head/sys/geom/eli/g_eli.h
  head/sys/geom/eli/g_eli_crypto.c
  head/sys/geom/eli/g_eli_integrity.c
  head/sys/geom/eli/g_eli_privacy.c

Modified: head/sys/geom/eli/g_eli.c
==============================================================================
--- head/sys/geom/eli/g_eli.c	Thu Sep 23 11:57:25 2010	(r213069)
+++ head/sys/geom/eli/g_eli.c	Thu Sep 23 11:58:36 2010	(r213070)
@@ -409,18 +409,31 @@ void
 g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv,
     size_t size)
 {
-	u_char off[8], hash[SHA256_DIGEST_LENGTH];
-	SHA256_CTX ctx;
+	uint8_t off[8];
 
 	if ((sc->sc_flags & G_ELI_FLAG_NATIVE_BYTE_ORDER) != 0)
 		bcopy(&offset, off, sizeof(off));
 	else
 		le64enc(off, (uint64_t)offset);
-	/* Copy precalculated SHA256 context for IV-Key. */
-	bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx));
-	SHA256_Update(&ctx, off, sizeof(off));
-	SHA256_Final(hash, &ctx);
-	bcopy(hash, iv, size);
+
+	switch (sc->sc_ealgo) {
+	case CRYPTO_AES_XTS:
+		bcopy(off, iv, sizeof(off));
+		bzero(iv + sizeof(off), size - sizeof(off));
+		break;
+	default:
+	    {
+		u_char hash[SHA256_DIGEST_LENGTH];
+		SHA256_CTX ctx;
+
+		/* Copy precalculated SHA256 context for IV-Key. */
+		bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx));
+		SHA256_Update(&ctx, off, sizeof(off));
+		SHA256_Final(hash, &ctx);
+		bcopy(hash, iv, MIN(sizeof(hash), size));
+		break;
+	    }
+	}
 }
 
 int
@@ -672,14 +685,23 @@ g_eli_create(struct gctl_req *req, struc
 	 * This is expensive operation and we can do it only once now or for
 	 * every access to sector, so now will be much better.
 	 */
-	SHA256_Init(&sc->sc_ivctx);
-	SHA256_Update(&sc->sc_ivctx, sc->sc_ivkey, sizeof(sc->sc_ivkey));
+	switch (sc->sc_ealgo) {
+	case CRYPTO_AES_XTS:
+		break;
+	default:
+		SHA256_Init(&sc->sc_ivctx);
+		SHA256_Update(&sc->sc_ivctx, sc->sc_ivkey,
+		    sizeof(sc->sc_ivkey));
+		break;
+	}
 
 	LIST_INIT(&sc->sc_workers);
 
 	bzero(&crie, sizeof(crie));
 	crie.cri_alg = sc->sc_ealgo;
 	crie.cri_klen = sc->sc_ekeylen;
+	if (sc->sc_ealgo == CRYPTO_AES_XTS)
+		crie.cri_klen <<= 1;
 	crie.cri_key = sc->sc_ekeys[0];
 	if (sc->sc_flags & G_ELI_FLAG_AUTH) {
 		bzero(&cria, sizeof(cria));

Modified: head/sys/geom/eli/g_eli.h
==============================================================================
--- head/sys/geom/eli/g_eli.h	Thu Sep 23 11:57:25 2010	(r213069)
+++ head/sys/geom/eli/g_eli.h	Thu Sep 23 11:58:36 2010	(r213070)
@@ -60,7 +60,7 @@
  * 3 - Added 'configure' subcommand.
  * 4 - IV is generated from offset converted to little-endian
  *     (flag G_ELI_FLAG_NATIVE_BYTE_ORDER will be set for older versions).
- * 5 - Added multiple encrypton keys.
+ * 5 - Added multiple encrypton keys and AES-XTS support.
  */
 #define	G_ELI_VERSION		5
 
@@ -294,14 +294,26 @@ g_eli_str2ealgo(const char *name)
 
 	if (strcasecmp("null", name) == 0)
 		return (CRYPTO_NULL_CBC);
+	else if (strcasecmp("null-cbc", name) == 0)
+		return (CRYPTO_NULL_CBC);
 	else if (strcasecmp("aes", name) == 0)
+		return (CRYPTO_AES_XTS);
+	else if (strcasecmp("aes-cbc", name) == 0)
 		return (CRYPTO_AES_CBC);
+	else if (strcasecmp("aes-xts", name) == 0)
+		return (CRYPTO_AES_XTS);
 	else if (strcasecmp("blowfish", name) == 0)
 		return (CRYPTO_BLF_CBC);
+	else if (strcasecmp("blowfish-cbc", name) == 0)
+		return (CRYPTO_BLF_CBC);
 	else if (strcasecmp("camellia", name) == 0)
 		return (CRYPTO_CAMELLIA_CBC);
+	else if (strcasecmp("camellia-cbc", name) == 0)
+		return (CRYPTO_CAMELLIA_CBC);
 	else if (strcasecmp("3des", name) == 0)
 		return (CRYPTO_3DES_CBC);
+	else if (strcasecmp("3des-cbc", name) == 0)
+		return (CRYPTO_3DES_CBC);
 	return (CRYPTO_ALGORITHM_MIN - 1);
 }
 
@@ -333,6 +345,8 @@ g_eli_algo2str(u_int algo)
 		return ("NULL");
 	case CRYPTO_AES_CBC:
 		return ("AES-CBC");
+	case CRYPTO_AES_XTS:
+		return ("AES-XTS");
 	case CRYPTO_BLF_CBC:
 		return ("Blowfish-CBC");
 	case CRYPTO_CAMELLIA_CBC:
@@ -418,6 +432,16 @@ g_eli_keylen(u_int algo, u_int keylen)
 		default:
 			return (0);
 		}
+	case CRYPTO_AES_XTS:
+		switch (keylen) {
+		case 0:
+			return (128);
+		case 128:
+		case 256:
+			return (keylen);
+		default:
+			return (0);
+		}
 	case CRYPTO_BLF_CBC:
 		if (keylen == 0)
 			return (128);

Modified: head/sys/geom/eli/g_eli_crypto.c
==============================================================================
--- head/sys/geom/eli/g_eli_crypto.c	Thu Sep 23 11:57:25 2010	(r213069)
+++ head/sys/geom/eli/g_eli_crypto.c	Thu Sep 23 11:58:36 2010	(r213070)
@@ -69,6 +69,9 @@ g_eli_crypto_cipher(u_int algo, int enc,
 	u_char *p;
 	int error;
 
+	KASSERT(algo != CRYPTO_AES_XTS,
+	    ("%s: CRYPTO_AES_XTS unexpected here", __func__));
+
 	bzero(&cri, sizeof(cri));
 	cri.cri_alg = algo;
 	cri.cri_key = __DECONST(void *, key);
@@ -136,6 +139,8 @@ g_eli_crypto_cipher(u_int algo, int enc,
 	u_char iv[keysize];
 	int outsize;
 
+	assert(algo != CRYPTO_AES_XTS);
+
 	switch (algo) {
 	case CRYPTO_NULL_CBC:
 		type = EVP_enc_null();
@@ -212,6 +217,10 @@ g_eli_crypto_encrypt(u_int algo, u_char 
     const u_char *key, size_t keysize)
 {
 
+	/* We prefer AES-CBC for metadata protection. */
+	if (algo == CRYPTO_AES_XTS)
+		algo = CRYPTO_AES_CBC;
+
 	return (g_eli_crypto_cipher(algo, 1, data, datasize, key, keysize));
 }
 
@@ -220,6 +229,10 @@ g_eli_crypto_decrypt(u_int algo, u_char 
     const u_char *key, size_t keysize)
 {
 
+	/* We prefer AES-CBC for metadata protection. */
+	if (algo == CRYPTO_AES_XTS)
+		algo = CRYPTO_AES_CBC;
+
 	return (g_eli_crypto_cipher(algo, 0, data, datasize, key, keysize));
 }
 

Modified: head/sys/geom/eli/g_eli_integrity.c
==============================================================================
--- head/sys/geom/eli/g_eli_integrity.c	Thu Sep 23 11:57:25 2010	(r213069)
+++ head/sys/geom/eli/g_eli_integrity.c	Thu Sep 23 11:58:36 2010	(r213070)
@@ -509,6 +509,8 @@ g_eli_auth_run(struct g_eli_worker *wr, 
 		crde->crd_alg = sc->sc_ealgo;
 		crde->crd_key = g_eli_crypto_key(sc, dstoff, encr_secsize);
 		crde->crd_klen = sc->sc_ekeylen;
+		if (sc->sc_ealgo == CRYPTO_AES_XTS)
+			crde->crd_klen <<= 1;
 		g_eli_crypto_ivgen(sc, dstoff, crde->crd_iv,
 		    sizeof(crde->crd_iv));
 

Modified: head/sys/geom/eli/g_eli_privacy.c
==============================================================================
--- head/sys/geom/eli/g_eli_privacy.c	Thu Sep 23 11:57:25 2010	(r213069)
+++ head/sys/geom/eli/g_eli_privacy.c	Thu Sep 23 11:58:36 2010	(r213070)
@@ -259,6 +259,8 @@ g_eli_crypto_run(struct g_eli_worker *wr
 		crd->crd_alg = sc->sc_ealgo;
 		crd->crd_key = g_eli_crypto_key(sc, dstoff, secsize);
 		crd->crd_klen = sc->sc_ekeylen;
+		if (sc->sc_ealgo == CRYPTO_AES_XTS)
+			crd->crd_klen <<= 1;
 		g_eli_crypto_ivgen(sc, dstoff, crd->crd_iv,
 		    sizeof(crd->crd_iv));
 		crd->crd_next = NULL;


More information about the svn-src-head mailing list