[Midnightbsd-cvs] src [9975] trunk/sys/geom/eli: sync

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat May 26 11:28:38 EDT 2018


Revision: 9975
          http://svnweb.midnightbsd.org/src/?rev=9975
Author:   laffer1
Date:     2018-05-26 11:28:37 -0400 (Sat, 26 May 2018)
Log Message:
-----------
sync

Modified Paths:
--------------
    trunk/sys/geom/eli/g_eli.c
    trunk/sys/geom/eli/g_eli.h
    trunk/sys/geom/eli/g_eli_crypto.c
    trunk/sys/geom/eli/g_eli_ctl.c
    trunk/sys/geom/eli/g_eli_integrity.c
    trunk/sys/geom/eli/g_eli_key.c
    trunk/sys/geom/eli/g_eli_key_cache.c

Modified: trunk/sys/geom/eli/g_eli.c
===================================================================
--- trunk/sys/geom/eli/g_eli.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli.c,v 1.5 2011/12/10 15:46:15 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/eli/g_eli.c,v 1.38.2.1 2011/04/12 09:36:38 trociny Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli.c 291195 2015-11-23 12:17:46Z smh $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -89,6 +89,43 @@
 SYSCTL_UINT(_kern_geom_eli, OID_AUTO, batch, CTLFLAG_RW, &g_eli_batch, 0,
     "Use crypto operations batching");
 
+/*
+ * Passphrase cached during boot, in order to be more user-friendly if
+ * there are multiple providers using the same passphrase.
+ */
+static char cached_passphrase[256];
+static u_int g_eli_boot_passcache = 1;
+TUNABLE_INT("kern.geom.eli.boot_passcache", &g_eli_boot_passcache);
+SYSCTL_UINT(_kern_geom_eli, OID_AUTO, boot_passcache, CTLFLAG_RD,
+    &g_eli_boot_passcache, 0,
+    "Passphrases are cached during boot process for possible reuse");
+static void
+fetch_loader_passphrase(void * dummy)
+{
+	char * env_passphrase;
+
+	KASSERT(dynamic_kenv, ("need dynamic kenv"));
+
+	if ((env_passphrase = getenv("kern.geom.eli.passphrase")) != NULL) {
+		/* Extract passphrase from the environment. */
+		strlcpy(cached_passphrase, env_passphrase,
+		    sizeof(cached_passphrase));
+		freeenv(env_passphrase);
+
+		/* Wipe the passphrase from the environment. */
+		unsetenv("kern.geom.eli.passphrase");
+	}
+}
+SYSINIT(geli_fetch_loader_passphrase, SI_SUB_KMEM + 1, SI_ORDER_ANY,
+    fetch_loader_passphrase, NULL);
+static void
+zero_boot_passcache(void * dummy)
+{
+
+	memset(cached_passphrase, 0, sizeof(cached_passphrase));
+}
+EVENTHANDLER_DEFINE(mountroot, zero_boot_passcache, NULL, 0);
+
 static eventhandler_tag g_eli_pre_sync = NULL;
 
 static int g_eli_destroy_geom(struct gctl_req *req, struct g_class *mp,
@@ -165,7 +202,7 @@
 
 	G_ELI_LOGREQ(2, bp, "Request done.");
 	pbp = bp->bio_parent;
-	if (pbp->bio_error == 0)
+	if (pbp->bio_error == 0 && bp->bio_error != 0)
 		pbp->bio_error = bp->bio_error;
 	g_destroy_bio(bp);
 	/*
@@ -176,7 +213,8 @@
 		return;
 	sc = pbp->bio_to->geom->softc;
 	if (pbp->bio_error != 0) {
-		G_ELI_LOGREQ(0, pbp, "%s() failed", __func__);
+		G_ELI_LOGREQ(0, pbp, "%s() failed (error=%d)", __func__,
+		    pbp->bio_error);
 		pbp->bio_completed = 0;
 		if (pbp->bio_driver2 != NULL) {
 			free(pbp->bio_driver2, M_ELI);
@@ -205,10 +243,8 @@
 
 	G_ELI_LOGREQ(2, bp, "Request done.");
 	pbp = bp->bio_parent;
-	if (pbp->bio_error == 0) {
-		if (bp->bio_error != 0)
-			pbp->bio_error = bp->bio_error;
-	}
+	if (pbp->bio_error == 0 && bp->bio_error != 0)
+		pbp->bio_error = bp->bio_error;
 	g_destroy_bio(bp);
 	/*
 	 * Do we have all sectors already?
@@ -219,14 +255,15 @@
 	free(pbp->bio_driver2, M_ELI);
 	pbp->bio_driver2 = NULL;
 	if (pbp->bio_error != 0) {
-		G_ELI_LOGREQ(0, pbp, "Crypto WRITE request failed (error=%d).",
+		G_ELI_LOGREQ(0, pbp, "%s() failed (error=%d)", __func__,
 		    pbp->bio_error);
 		pbp->bio_completed = 0;
-	}
+	} else
+		pbp->bio_completed = pbp->bio_length;
+
 	/*
 	 * Write is finished, send it up.
 	 */
-	pbp->bio_completed = pbp->bio_length;
 	sc = pbp->bio_to->geom->softc;
 	g_io_deliver(pbp, pbp->bio_error);
 	atomic_subtract_int(&sc->sc_inflight, 1);
@@ -445,8 +482,7 @@
 	sc = wr->w_softc;
 #ifdef SMP
 	/* Before sched_bind() to a CPU, wait for all CPUs to go on-line. */
-	if (mp_ncpus > 1 && sc->sc_crypto == G_ELI_CRYPTO_SW &&
-	    g_eli_threads == 0) {
+	if (sc->sc_cpubind) {
 		while (!smp_started)
 			tsleep(wr, 0, "geli:smp", hz / 4);
 	}
@@ -453,8 +489,8 @@
 #endif
 	thread_lock(curthread);
 	sched_prio(curthread, PUSER);
-	if (sc->sc_crypto == G_ELI_CRYPTO_SW && g_eli_threads == 0)
-		sched_bind(curthread, wr->w_number);
+	if (sc->sc_cpubind)
+		sched_bind(curthread, wr->w_number % mp_ncpus);
 	thread_unlock(curthread);
 
 	G_ELI_DEBUG(1, "Thread %s started.", curthread->td_proc->p_comm);
@@ -477,7 +513,8 @@
 			}
 			while (sc->sc_flags & G_ELI_FLAG_SUSPEND) {
 				if (sc->sc_inflight > 0) {
-					G_ELI_DEBUG(0, "inflight=%d", sc->sc_inflight);
+					G_ELI_DEBUG(0, "inflight=%d",
+					    sc->sc_inflight);
 					/*
 					 * We still have inflight BIOs, so
 					 * sleep and retry.
@@ -622,21 +659,19 @@
  * to close it when this situation occur.
  */
 static void
-g_eli_last_close(struct g_eli_softc *sc)
+g_eli_last_close(void *arg, int flags __unused)
 {
 	struct g_geom *gp;
-	struct g_provider *pp;
-	char ppname[64];
+	char gpname[64];
 	int error;
 
 	g_topology_assert();
-	gp = sc->sc_geom;
-	pp = LIST_FIRST(&gp->provider);
-	strlcpy(ppname, pp->name, sizeof(ppname));
-	error = g_eli_destroy(sc, TRUE);
+	gp = arg;
+	strlcpy(gpname, gp->name, sizeof(gpname));
+	error = g_eli_destroy(gp->softc, TRUE);
 	KASSERT(error == 0, ("Cannot detach %s on last close (error=%d).",
-	    ppname, error));
-	G_ELI_DEBUG(0, "Detached %s on last close.", ppname);
+	    gpname, error));
+	G_ELI_DEBUG(0, "Detached %s on last close.", gpname);
 }
 
 int
@@ -666,7 +701,7 @@
 	 */
 	if ((sc->sc_flags & G_ELI_FLAG_RW_DETACH) ||
 	    (sc->sc_flags & G_ELI_FLAG_WOPEN)) {
-		g_eli_last_close(sc);
+		g_post_event(g_eli_last_close, gp, M_WAITOK, NULL);
 	}
 	return (0);
 }
@@ -714,16 +749,21 @@
 	else
 		gp->access = g_std_access;
 
+	sc->sc_version = md->md_version;
 	sc->sc_inflight = 0;
 	sc->sc_crypto = G_ELI_CRYPTO_UNKNOWN;
 	sc->sc_flags = md->md_flags;
 	/* Backward compatibility. */
-	if (md->md_version < 4)
+	if (md->md_version < G_ELI_VERSION_04)
 		sc->sc_flags |= G_ELI_FLAG_NATIVE_BYTE_ORDER;
-	if (md->md_version < 5)
+	if (md->md_version < G_ELI_VERSION_05)
 		sc->sc_flags |= G_ELI_FLAG_SINGLE_KEY;
-	if (md->md_version < 6 && (sc->sc_flags & G_ELI_FLAG_AUTH) != 0)
+	if (md->md_version < G_ELI_VERSION_06 &&
+	    (sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
 		sc->sc_flags |= G_ELI_FLAG_FIRST_KEY;
+	}
+	if (md->md_version < G_ELI_VERSION_07)
+		sc->sc_flags |= G_ELI_FLAG_ENC_IVKEY;
 	sc->sc_ealgo = md->md_ealgo;
 	sc->sc_nkey = nkey;
 
@@ -811,11 +851,7 @@
 	threads = g_eli_threads;
 	if (threads == 0)
 		threads = mp_ncpus;
-	else if (threads > mp_ncpus) {
-		/* There is really no need for too many worker threads. */
-		threads = mp_ncpus;
-		G_ELI_DEBUG(0, "Reducing number of threads to %u.", threads);
-	}
+	sc->sc_cpubind = (mp_ncpus > 1 && threads == mp_ncpus);
 	for (i = 0; i < threads; i++) {
 		if (g_eli_cpu_is_disabled(i)) {
 			G_ELI_DEBUG(1, "%s: CPU %u disabled, skipping.",
@@ -855,9 +891,6 @@
 			goto failed;
 		}
 		LIST_INSERT_HEAD(&sc->sc_workers, wr, w_next);
-		/* If we have hardware support, one thread is enough. */
-		if (sc->sc_crypto == G_ELI_CRYPTO_HW)
-			break;
 	}
 
 	/*
@@ -919,6 +952,10 @@
 		if (force) {
 			G_ELI_DEBUG(1, "Device %s is still open, so it "
 			    "cannot be definitely removed.", pp->name);
+			sc->sc_flags |= G_ELI_FLAG_RW_DETACH;
+			gp->access = g_eli_access;
+			g_wither_provider(pp, ENXIO);
+			return (EBUSY);
 		} else {
 			G_ELI_DEBUG(1,
 			    "Device %s is still open (r%dw%de%d).", pp->name,
@@ -1066,7 +1103,7 @@
 		tries = g_eli_tries;
 	}
 
-	for (i = 0; i < tries; i++) {
+	for (i = 0; i <= tries; i++) {
 		g_eli_crypto_hmac_init(&ctx, NULL, 0);
 
 		/*
@@ -1090,9 +1127,19 @@
 
 		/* Ask for the passphrase if defined. */
 		if (md.md_iterations >= 0) {
-			printf("Enter passphrase for %s: ", pp->name);
-			cngets(passphrase, sizeof(passphrase),
-			    g_eli_visible_passphrase);
+			/* Try first with cached passphrase. */
+			if (i == 0) {
+				if (!g_eli_boot_passcache)
+					continue;
+				memcpy(passphrase, cached_passphrase,
+				    sizeof(passphrase));
+			} else {
+				printf("Enter passphrase for %s: ", pp->name);
+				cngets(passphrase, sizeof(passphrase),
+				    g_eli_visible_passphrase);
+				memcpy(cached_passphrase, passphrase,
+				    sizeof(passphrase));
+			}
 		}
 
 		/*
@@ -1122,7 +1169,7 @@
 		error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
 		bzero(key, sizeof(key));
 		if (error == -1) {
-			if (i == tries - 1) {
+			if (i == tries) {
 				G_ELI_DEBUG(0,
 				    "Wrong key for %s. No tries left.",
 				    pp->name);
@@ -1129,16 +1176,21 @@
 				g_eli_keyfiles_clear(pp->name);
 				return (NULL);
 			}
-			G_ELI_DEBUG(0, "Wrong key for %s. Tries left: %u.",
-			    pp->name, tries - i - 1);
+			if (i > 0) {
+				G_ELI_DEBUG(0,
+				    "Wrong key for %s. Tries left: %u.",
+				    pp->name, tries - i);
+			}
 			/* Try again. */
 			continue;
 		} else if (error > 0) {
-			G_ELI_DEBUG(0, "Cannot decrypt Master Key for %s (error=%d).",
+			G_ELI_DEBUG(0,
+			    "Cannot decrypt Master Key for %s (error=%d).",
 			    pp->name, error);
 			g_eli_keyfiles_clear(pp->name);
 			return (NULL);
 		}
+		g_eli_keyfiles_clear(pp->name);
 		G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
 		break;
 	}
@@ -1170,9 +1222,9 @@
 	if (pp != NULL || cp != NULL)
 		return;	/* Nothing here. */
 
-	sbuf_printf(sb, "%s<KeysTotal>%ju</KeysTotal>", indent,
+	sbuf_printf(sb, "%s<KeysTotal>%ju</KeysTotal>\n", indent,
 	    (uintmax_t)sc->sc_ekeys_total);
-	sbuf_printf(sb, "%s<KeysAllocated>%ju</KeysAllocated>", indent,
+	sbuf_printf(sb, "%s<KeysAllocated>%ju</KeysAllocated>\n", indent,
 	    (uintmax_t)sc->sc_ekeys_allocated);
 	sbuf_printf(sb, "%s<Flags>", indent);
 	if (sc->sc_flags == 0)
@@ -1208,6 +1260,7 @@
 		sbuf_printf(sb, "%s<UsedKey>%u</UsedKey>\n", indent,
 		    sc->sc_nkey);
 	}
+	sbuf_printf(sb, "%s<Version>%u</Version>\n", indent, sc->sc_version);
 	sbuf_printf(sb, "%s<Crypto>", indent);
 	switch (sc->sc_crypto) {
 	case G_ELI_CRYPTO_HW:
@@ -1228,8 +1281,8 @@
 	}
 	sbuf_printf(sb, "%s<KeyLength>%u</KeyLength>\n", indent,
 	    sc->sc_ekeylen);
-	sbuf_printf(sb, "%s<EncryptionAlgorithm>%s</EncryptionAlgorithm>\n", indent,
-	    g_eli_algo2str(sc->sc_ealgo));
+	sbuf_printf(sb, "%s<EncryptionAlgorithm>%s</EncryptionAlgorithm>\n",
+	    indent, g_eli_algo2str(sc->sc_ealgo));
 	sbuf_printf(sb, "%s<State>%s</State>\n", indent,
 	    (sc->sc_flags & G_ELI_FLAG_SUSPEND) ? "SUSPENDED" : "ACTIVE");
 }

Modified: trunk/sys/geom/eli/g_eli.h
===================================================================
--- trunk/sys/geom/eli/g_eli.h	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli.h	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli.h,v 1.4 2008/12/03 00:25:48 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/eli/g_eli.h,v 1.13 2007/09/01 06:33:01 pjd Exp $
+ * $FreeBSD: stable/10/sys/geom/eli/g_eli.h 314327 2017-02-27 08:27:38Z avg $
  */
 
 #ifndef	_G_ELI_H_
@@ -33,7 +33,8 @@
 #include <sys/endian.h>
 #include <sys/errno.h>
 #include <sys/malloc.h>
-#include <crypto/sha2/sha2.h>
+#include <crypto/sha2/sha256.h>
+#include <crypto/sha2/sha512.h>
 #include <opencrypto/cryptodev.h>
 #ifdef _KERNEL
 #include <sys/bio.h>
@@ -44,6 +45,7 @@
 #include <sys/tree.h>
 #include <geom/geom.h>
 #else
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include <strings.h>
@@ -68,6 +70,8 @@
  * 5 - Added multiple encrypton keys and AES-XTS support.
  * 6 - Fixed usage of multiple keys for authenticated providers (the
  *     G_ELI_FLAG_FIRST_KEY flag will be set for older versions).
+ * 7 - Encryption keys are now generated from the Data Key and not from the
+ *     IV Key (the G_ELI_FLAG_ENC_IVKEY flag will be set for older versions).
  */
 #define	G_ELI_VERSION_00	0
 #define	G_ELI_VERSION_01	1
@@ -76,7 +80,8 @@
 #define	G_ELI_VERSION_04	4
 #define	G_ELI_VERSION_05	5
 #define	G_ELI_VERSION_06	6
-#define	G_ELI_VERSION		G_ELI_VERSION_06
+#define	G_ELI_VERSION_07	7
+#define	G_ELI_VERSION		G_ELI_VERSION_07
 
 /* ON DISK FLAGS. */
 /* Use random, onetime keys. */
@@ -104,6 +109,8 @@
 #define	G_ELI_FLAG_SUSPEND		0x00100000
 /* Provider uses first encryption key. */
 #define	G_ELI_FLAG_FIRST_KEY		0x00200000
+/* Provider uses IV-Key for encryption key generation. */
+#define	G_ELI_FLAG_ENC_IVKEY		0x00400000
 
 #define	G_ELI_NEW_BIO	255
 
@@ -167,6 +174,7 @@
 
 struct g_eli_softc {
 	struct g_geom	*sc_geom;
+	u_int		 sc_version;
 	u_int		 sc_crypto;
 	uint8_t		 sc_mkey[G_ELI_DATAIVKEYLEN];
 	uint8_t		 sc_ekey[G_ELI_DATAKEYLEN];
@@ -191,6 +199,7 @@
 	size_t		 sc_sectorsize;
 	u_int		 sc_bytes_per_sector;
 	u_int		 sc_data_per_sector;
+	boolean_t	 sc_cpubind;
 
 	/* Only for software cryptography. */
 	struct bio_queue_head sc_queue;
@@ -218,17 +227,31 @@
 } __packed;
 #ifndef _OpenSSL_
 static __inline void
-eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
+eli_metadata_encode_v0(struct g_eli_metadata *md, u_char **datap)
 {
-	MD5_CTX ctx;
 	u_char *p;
 
-	p = data;
-	bcopy(md->md_magic, p, sizeof(md->md_magic)); p += sizeof(md->md_magic);
-	le32enc(p, md->md_version);	p += sizeof(md->md_version);
+	p = *datap;
 	le32enc(p, md->md_flags);	p += sizeof(md->md_flags);
 	le16enc(p, md->md_ealgo);	p += sizeof(md->md_ealgo);
 	le16enc(p, md->md_keylen);	p += sizeof(md->md_keylen);
+	le64enc(p, md->md_provsize);	p += sizeof(md->md_provsize);
+	le32enc(p, md->md_sectorsize);	p += sizeof(md->md_sectorsize);
+	*p = md->md_keys;		p += sizeof(md->md_keys);
+	le32enc(p, md->md_iterations);	p += sizeof(md->md_iterations);
+	bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt);
+	bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
+	*datap = p;
+}
+static __inline void
+eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap)
+{
+	u_char *p;
+
+	p = *datap;
+	le32enc(p, md->md_flags);	p += sizeof(md->md_flags);
+	le16enc(p, md->md_ealgo);	p += sizeof(md->md_ealgo);
+	le16enc(p, md->md_keylen);	p += sizeof(md->md_keylen);
 	le16enc(p, md->md_aalgo);	p += sizeof(md->md_aalgo);
 	le64enc(p, md->md_provsize);	p += sizeof(md->md_provsize);
 	le32enc(p, md->md_sectorsize);	p += sizeof(md->md_sectorsize);
@@ -236,6 +259,40 @@
 	le32enc(p, md->md_iterations);	p += sizeof(md->md_iterations);
 	bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt);
 	bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
+	*datap = p;
+}
+static __inline void
+eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
+{
+	MD5_CTX ctx;
+	u_char *p;
+
+	p = data;
+	bcopy(md->md_magic, p, sizeof(md->md_magic));
+	p += sizeof(md->md_magic);
+	le32enc(p, md->md_version);
+	p += sizeof(md->md_version);
+	switch (md->md_version) {
+	case G_ELI_VERSION_00:
+		eli_metadata_encode_v0(md, &p);
+		break;
+	case G_ELI_VERSION_01:
+	case G_ELI_VERSION_02:
+	case G_ELI_VERSION_03:
+	case G_ELI_VERSION_04:
+	case G_ELI_VERSION_05:
+	case G_ELI_VERSION_06:
+	case G_ELI_VERSION_07:
+		eli_metadata_encode_v1v2v3v4v5v6v7(md, &p);
+		break;
+	default:
+#ifdef _KERNEL
+		panic("%s: Unsupported version %u.", __func__,
+		    (u_int)md->md_version);
+#else
+		assert(!"Unsupported metadata version.");
+#endif
+	}
 	MD5Init(&ctx);
 	MD5Update(&ctx, data, p - data);
 	MD5Final(md->md_hash, &ctx);
@@ -266,7 +323,7 @@
 }
 
 static __inline int
-eli_metadata_decode_v1v2v3v4v5v6(const u_char *data, struct g_eli_metadata *md)
+eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md)
 {
 	MD5_CTX ctx;
 	const u_char *p;
@@ -295,6 +352,8 @@
 	int error;
 
 	bcopy(data, md->md_magic, sizeof(md->md_magic));
+	if (strcmp(md->md_magic, G_ELI_MAGIC) != 0)
+		return (EINVAL);
 	md->md_version = le32dec(data + sizeof(md->md_magic));
 	switch (md->md_version) {
 	case G_ELI_VERSION_00:
@@ -306,10 +365,11 @@
 	case G_ELI_VERSION_04:
 	case G_ELI_VERSION_05:
 	case G_ELI_VERSION_06:
-		error = eli_metadata_decode_v1v2v3v4v5v6(data, md);
+	case G_ELI_VERSION_07:
+		error = eli_metadata_decode_v1v2v3v4v5v6v7(data, md);
 		break;
 	default:
-		error = EINVAL;
+		error = EOPNOTSUPP;
 		break;
 	}
 	return (error);

Modified: trunk/sys/geom/eli/g_eli_crypto.c
===================================================================
--- trunk/sys/geom/eli/g_eli_crypto.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli_crypto.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli_crypto.c,v 1.4 2008/12/03 00:25:48 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2010 Pawel Jakub Dawidek <pjd at FreeBSD.org>
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/eli/g_eli_crypto.c,v 1.5 2007/09/01 06:33:01 pjd Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli_crypto.c 266749 2014-05-27 14:55:09Z marius $");
 
 #include <sys/param.h>
 #ifdef _KERNEL
@@ -266,6 +266,7 @@
 	/* Perform inner SHA512. */
 	SHA512_Init(&ctx->shactx);
 	SHA512_Update(&ctx->shactx, k_ipad, sizeof(k_ipad));
+	bzero(k_ipad, sizeof(k_ipad));
 }
 
 void
@@ -289,10 +290,12 @@
 	bzero(ctx, sizeof(*ctx));
 	SHA512_Update(&lctx, digest, sizeof(digest));
 	SHA512_Final(digest, &lctx);
+	bzero(&lctx, sizeof(lctx));
 	/* mdsize == 0 means "Give me the whole hash!" */
 	if (mdsize == 0)
 		mdsize = SHA512_MDLEN;
 	bcopy(digest, md, mdsize);
+	bzero(digest, sizeof(digest));
 }
 
 void

Modified: trunk/sys/geom/eli/g_eli_ctl.c
===================================================================
--- trunk/sys/geom/eli/g_eli_ctl.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli_ctl.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli_ctl.c,v 1.4 2008/12/03 00:25:48 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/eli/g_eli_ctl.c,v 1.13 2007/05/06 14:56:03 pjd Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli_ctl.c 257718 2013-11-05 19:58:40Z delphij $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -472,7 +472,7 @@
 			    prov, error);
 		}
 		bzero(&md, sizeof(md));
-		bzero(sector, sizeof(sector));
+		bzero(sector, pp->sectorsize);
 		free(sector, M_ELI);
 	}
 }
@@ -563,7 +563,7 @@
 
 	/* Encrypt Master Key with the new key. */
 	error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst);
-	bzero(key, sizeof(key));
+	bzero(key, keysize);
 	if (error != 0) {
 		bzero(&md, sizeof(md));
 		gctl_error(req, "Cannot encrypt Master Key (error=%d).", error);
@@ -576,7 +576,7 @@
 	bzero(&md, sizeof(md));
 	error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
 	    pp->sectorsize);
-	bzero(sector, sizeof(sector));
+	bzero(sector, pp->sectorsize);
 	free(sector, M_ELI);
 	if (error != 0) {
 		gctl_error(req, "Cannot store metadata on %s (error=%d).",
@@ -692,7 +692,7 @@
 		(void)g_io_flush(cp);
 	}
 	bzero(&md, sizeof(md));
-	bzero(sector, sizeof(sector));
+	bzero(sector, pp->sectorsize);
 	free(sector, M_ELI);
 	if (*all)
 		G_ELI_DEBUG(1, "All keys removed from %s.", pp->name);
@@ -1021,6 +1021,12 @@
 			/* Compatible. */
 			break;
 		}
+		if (G_ELI_VERSION == G_ELI_VERSION_07 &&
+		    (*version == G_ELI_VERSION_05 ||
+		     *version == G_ELI_VERSION_06)) {
+			/* Compatible. */
+			break;
+		}
 		gctl_error(req, "Userland and kernel parts are out of sync.");
 		return;
 	}

Modified: trunk/sys/geom/eli/g_eli_integrity.c
===================================================================
--- trunk/sys/geom/eli/g_eli_integrity.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli_integrity.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli_integrity.c,v 1.2 2008/12/03 00:25:48 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/eli/g_eli_integrity.c,v 1.4 2006/07/22 10:05:55 pjd Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli_integrity.c 330737 2018-03-10 04:17:01Z asomers $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -469,8 +469,16 @@
 		iov = (struct iovec *)p;	p += sizeof(*iov);
 
 		data_secsize = sc->sc_data_per_sector;
-		if ((i % lsec) == 0)
+		if ((i % lsec) == 0) {
 			data_secsize = decr_secsize % data_secsize;
+			/*
+			 * Last encrypted sector of each decrypted sector is
+			 * only partially filled.
+			 */
+			if (bp->bio_cmd == BIO_WRITE)
+				memset(data + sc->sc_alen + data_secsize, 0,
+				    encr_secsize - sc->sc_alen - data_secsize);
+		}
 
 		if (bp->bio_cmd == BIO_READ) {
 			/* Remember read HMAC. */

Modified: trunk/sys/geom/eli/g_eli_key.c
===================================================================
--- trunk/sys/geom/eli/g_eli_key.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli_key.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/eli/g_eli_key.c,v 1.4 2008/12/03 00:25:48 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/eli/g_eli_key.c,v 1.3 2006/06/05 21:38:54 pjd Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli_key.c 238114 2012-07-04 17:43:25Z pjd $");
 
 #include <sys/param.h>
 #ifdef _KERNEL
@@ -198,7 +198,7 @@
 	mkey += sizeof(sc->sc_ivkey);
 
 	/*
-	 * The authentication key is: akey = HMAC_SHA512(Master-Key, 0x11)
+	 * The authentication key is: akey = HMAC_SHA512(Data-Key, 0x11)
 	 */
 	if ((sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
 		g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x11", 1,
@@ -210,7 +210,7 @@
 	/* Initialize encryption keys. */
 	g_eli_key_init(sc);
 
-	if (sc->sc_flags & G_ELI_FLAG_AUTH) {
+	if ((sc->sc_flags & G_ELI_FLAG_AUTH) != 0) {
 		/*
 		 * Precalculate SHA256 for HMAC key generation.
 		 * This is expensive operation and we can do it only once now or

Modified: trunk/sys/geom/eli/g_eli_key_cache.c
===================================================================
--- trunk/sys/geom/eli/g_eli_key_cache.c	2018-05-26 15:27:27 UTC (rev 9974)
+++ trunk/sys/geom/eli/g_eli_key_cache.c	2018-05-26 15:28:37 UTC (rev 9975)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2011 Pawel Jakub Dawidek <pawel at dawidek.net>
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/eli/g_eli_key_cache.c 239184 2012-08-10 18:43:29Z pjd $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -91,14 +92,20 @@
 static void
 g_eli_key_fill(struct g_eli_softc *sc, struct g_eli_key *key, uint64_t keyno)
 {
+	const uint8_t *ekey;
 	struct {
 		char magic[4];
 		uint8_t keyno[8];
 	} __packed hmacdata;
 
+	if ((sc->sc_flags & G_ELI_FLAG_ENC_IVKEY) != 0)
+		ekey = sc->sc_mkey;
+	else
+		ekey = sc->sc_ekey;
+
 	bcopy("ekey", hmacdata.magic, 4);
 	le64enc(hmacdata.keyno, keyno);
-	g_eli_crypto_hmac(sc->sc_mkey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
+	g_eli_crypto_hmac(ekey, G_ELI_MAXKEYLEN, (uint8_t *)&hmacdata,
 	    sizeof(hmacdata), key->gek_key, 0);
 	key->gek_keyno = keyno;
 	key->gek_count = 0;
@@ -187,24 +194,24 @@
 void
 g_eli_key_init(struct g_eli_softc *sc)
 {
+	uint8_t *mkey;
 
 	mtx_lock(&sc->sc_ekeys_lock);
-	if ((sc->sc_flags & G_ELI_FLAG_SINGLE_KEY) != 0) {
-		uint8_t *mkey;
 
-		mkey = sc->sc_mkey + sizeof(sc->sc_ivkey);
+	mkey = sc->sc_mkey + sizeof(sc->sc_ivkey);
+	if ((sc->sc_flags & G_ELI_FLAG_AUTH) == 0)
+		bcopy(mkey, sc->sc_ekey, G_ELI_DATAKEYLEN);
+	else {
+		/*
+		 * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
+		 */
+		g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x10", 1,
+		    sc->sc_ekey, 0);
+	}
 
+	if ((sc->sc_flags & G_ELI_FLAG_SINGLE_KEY) != 0) {
 		sc->sc_ekeys_total = 1;
 		sc->sc_ekeys_allocated = 0;
-		if ((sc->sc_flags & G_ELI_FLAG_AUTH) == 0)
-			bcopy(mkey, sc->sc_ekey, G_ELI_DATAKEYLEN);
-		else {
-			/*
-			 * The encryption key is: ekey = HMAC_SHA512(Master-Key, 0x10)
-			 */
-			g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x10", 1,
-			    sc->sc_ekey, 0);
-		}
 	} else {
 		off_t mediasize;
 		size_t blocksize;
@@ -235,6 +242,7 @@
 			    (uintmax_t)sc->sc_ekeys_allocated));
 		}
 	}
+
 	mtx_unlock(&sc->sc_ekeys_lock);
 }
 



More information about the Midnightbsd-cvs mailing list