Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jul 2018 17:50:25 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r336252 - in head: share/mk stand stand/common stand/efi/loader stand/i386/gptboot stand/i386/gptzfsboot stand/i386/isoboot stand/i386/libi386 stand/i386/loader stand/i386/zfsboot stand...
Message-ID:  <201807131750.w6DHoPD9024230@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Fri Jul 13 17:50:25 2018
New Revision: 336252
URL: https://svnweb.freebsd.org/changeset/base/336252

Log:
  Extend loader(8) geli support to all architectures and all disk-like devices.
  
  This moves the bulk of the geli support from lib386/biosdisk.c into a new
  geli/gelidev.c which implements a devsw-type device whose dv_strategy()
  function handles geli decryption. Support for all arches comes from moving
  the taste-and-attach code to the devopen() function in libsa.
  
  After opening any DEVT_DISK device, devopen() calls the new function
  geli_probe_and_attach(), which will "attach" the geli code to the open_file
  struct by creating a geli_devdesc instance to replace the disk_devdesc
  instance in the open_file. That routes all IO for the device through the
  geli code.
  
  A new public geli_add_key() function is added, to allow arch/vendor-specific
  code to add keys obtained from custom hardware or other sources.
  
  With these changes, geli support will be compiled into all variations of
  loader(8) on all arches because the default is WITH_LOADER_GELI.
  
  Relnotes:	yes
  Sponsored by:	Microchip Technology Inc
  Differential Revision:	https://reviews.freebsd.org/D15743

Added:
  head/stand/libsa/geli/geli_metadata.c   (contents, props changed)
  head/stand/libsa/geli/gelidev.c   (contents, props changed)
Modified:
  head/share/mk/src.opts.mk
  head/stand/common/devopen.c
  head/stand/common/metadata.c
  head/stand/defs.mk
  head/stand/efi/loader/bootinfo.c
  head/stand/i386/gptboot/Makefile
  head/stand/i386/gptboot/gptboot.c
  head/stand/i386/gptzfsboot/Makefile
  head/stand/i386/isoboot/Makefile
  head/stand/i386/libi386/Makefile
  head/stand/i386/libi386/biosdisk.c
  head/stand/i386/libi386/bootinfo32.c
  head/stand/i386/libi386/bootinfo64.c
  head/stand/i386/loader/Makefile
  head/stand/i386/loader/main.c
  head/stand/i386/zfsboot/Makefile
  head/stand/i386/zfsboot/zfsboot.c
  head/stand/libsa/geli/Makefile.inc
  head/stand/libsa/geli/geliboot.c
  head/stand/libsa/geli/geliboot.h
  head/stand/libsa/geli/geliboot_internal.h
  head/stand/userboot/userboot/bootinfo32.c

Modified: head/share/mk/src.opts.mk
==============================================================================
--- head/share/mk/src.opts.mk	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/share/mk/src.opts.mk	Fri Jul 13 17:50:25 2018	(r336252)
@@ -343,10 +343,6 @@ BROKEN_OPTIONS+=SSP
 .if ${__T:Mmips*} || ${__T:Mpowerpc*} || ${__T:Msparc64} || ${__T:Mriscv*}
 BROKEN_OPTIONS+=EFI
 .endif
-# GELI isn't supported on !x86
-.if ${__T} != "i386" && ${__T} != "amd64"
-BROKEN_OPTIONS+=LOADER_GELI
-.endif
 # OFW is only for powerpc and sparc64, exclude others
 .if ${__T:Mpowerpc*} == "" && ${__T:Msparc64} == ""
 BROKEN_OPTIONS+=LOADER_OFW

Modified: head/stand/common/devopen.c
==============================================================================
--- head/stand/common/devopen.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/common/devopen.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -32,6 +32,10 @@ __FBSDID("$FreeBSD$");
 
 #include "bootstrap.h"
 
+#ifdef LOADER_GELI_SUPPORT
+#include "geliboot.h"
+#endif
+
 int
 devopen(struct open_file *f, const char *fname, const char **file) 
 {
@@ -43,6 +47,7 @@ devopen(struct open_file *f, const char *fname, const 
 		return (result);
 
 	/* point to device-specific data so that device open can use it */
+	f->f_dev = dev->d_dev;
 	f->f_devdata = dev;
 	result = dev->d_dev->dv_open(f, dev);
 	if (result != 0) {
@@ -51,8 +56,17 @@ devopen(struct open_file *f, const char *fname, const 
 		return (result);
 	}
 
-	/* reference the devsw entry from the open_file structure */
-	f->f_dev = dev->d_dev;
+#ifdef LOADER_GELI_SUPPORT
+	/*
+	 * If f->f_dev is geli-encrypted and we can decrypt it (will prompt for
+	 * pw if needed), this will attach the geli code to the open_file by
+	 * replacing f->f_dev and f_devdata with pointers to a geli_devdesc.
+	 */
+	if (f->f_dev->dv_type == DEVT_DISK) {
+		geli_probe_and_attach(f);
+	}
+#endif
+
 	return (0);
 }
 

Modified: head/stand/common/metadata.c
==============================================================================
--- head/stand/common/metadata.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/common/metadata.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -45,6 +45,10 @@ __FBSDID("$FreeBSD$");
 
 #include "bootstrap.h"
 
+#ifdef LOADER_GELI_SUPPORT
+#include "geliboot.h"
+#endif
+
 #if defined(__sparc64__)
 #include <openfirm.h>
 
@@ -355,7 +359,9 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offs
 #endif
 	file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
     }
-
+#ifdef LOADER_GELI_SUPPORT
+    geli_export_key_metadata(kfp);
+#endif
 #if defined(__sparc64__)
     file_addmetadata(kfp, MODINFOMD_DTLB_SLOTS,
 	sizeof dtlb_slot, &dtlb_slot);

Modified: head/stand/defs.mk
==============================================================================
--- head/stand/defs.mk	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/defs.mk	Fri Jul 13 17:50:25 2018	(r336252)
@@ -56,7 +56,6 @@ CFLAGS+=	-Ddouble=jagged-little-pill -Dfloat=floaty-mc
 
 
 # GELI Support, with backward compat hooks (mostly)
-.if defined(HAVE_GELI)
 .if defined(LOADER_NO_GELI_SUPPORT)
 MK_LOADER_GELI=no
 .warning "Please move from LOADER_NO_GELI_SUPPORT to WITHOUT_LOADER_GELI"
@@ -69,7 +68,6 @@ MK_LOADER_GELI=yes
 CFLAGS+=	-DLOADER_GELI_SUPPORT
 CFLAGS+=	-I${SASRC}/geli
 .endif # MK_LOADER_GELI
-.endif # HAVE_GELI
 
 # These should be confined to loader.mk, but can't because uboot/lib
 # also uses it. It's part of loader, but isn't a loader so we can't

Modified: head/stand/efi/loader/bootinfo.c
==============================================================================
--- head/stand/efi/loader/bootinfo.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/efi/loader/bootinfo.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -56,6 +56,10 @@ __FBSDID("$FreeBSD$");
 #include <fdt_platform.h>
 #endif
 
+#ifdef LOADER_GELI_SUPPORT
+#include "geliboot.h"
+#endif
+
 int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
 
 extern EFI_SYSTEM_TABLE	*ST;
@@ -452,7 +456,9 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t 
 #endif
 	file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
 	file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof ST, &ST);
-
+#ifdef LOADER_GELI_SUPPORT
+	geli_export_key_metadata(kfp);
+#endif
 	bi_load_efi_data(kfp);
 
 	/* Figure out the size and location of the metadata. */

Modified: head/stand/i386/gptboot/Makefile
==============================================================================
--- head/stand/i386/gptboot/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/gptboot/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=		yes
-
 .include <bsd.init.mk>
 
 .PATH:		${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC}

Modified: head/stand/i386/gptboot/gptboot.c
==============================================================================
--- head/stand/i386/gptboot/gptboot.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/gptboot/gptboot.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -113,11 +113,20 @@ static int vdev_read(void *vdev __unused, void *priv, 
 #include "ufsread.c"
 #include "gpt.c"
 #ifdef LOADER_GELI_SUPPORT
-#include "geliboot.c"
+#include "geliboot.h"
 static char gelipw[GELI_PW_MAXLEN];
 static struct keybuf *gelibuf;
 #endif
 
+struct gptdsk {
+	struct dsk       dsk;
+#ifdef LOADER_GELI_SUPPORT
+	struct geli_dev *gdev;
+#endif
+};
+
+static struct gptdsk gdsk;
+
 static inline int
 xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
 {
@@ -225,19 +234,21 @@ static int
 gptinit(void)
 {
 
-	if (gptread(&freebsd_ufs_uuid, &dsk, dmadat->secbuf) == -1) {
+	if (gptread(&freebsd_ufs_uuid, &gdsk.dsk, dmadat->secbuf) == -1) {
 		printf("%s: unable to load GPT\n", BOOTPROG);
 		return (-1);
 	}
-	if (gptfind(&freebsd_ufs_uuid, &dsk, dsk.part) == -1) {
+	if (gptfind(&freebsd_ufs_uuid, &gdsk.dsk, gdsk.dsk.part) == -1) {
 		printf("%s: no UFS partition was found\n", BOOTPROG);
 		return (-1);
 	}
 #ifdef LOADER_GELI_SUPPORT
-	if (geli_taste(vdev_read, &dsk, (gpttable[curent].ent_lba_end -
-	    gpttable[curent].ent_lba_start)) == 0) {
-		if (geli_havekey(&dsk) != 0 && geli_passphrase(gelipw,
-		    dsk.unit, 'p', curent + 1, &dsk) != 0) {
+	gdsk.gdev = geli_taste(vdev_read, &gdsk.dsk, 
+	    (gpttable[curent].ent_lba_end - gpttable[curent].ent_lba_start),
+	    "disk%up%u:", gdsk.dsk.unit, curent + 1);
+	if (gdsk.gdev != NULL) {
+		if (geli_havekey(gdsk.gdev) != 0 &&
+		    geli_passphrase(gdsk.gdev, gelipw) != 0) {
 			printf("%s: unable to decrypt GELI key\n", BOOTPROG);
 			return (-1);
 		}
@@ -273,21 +284,18 @@ main(void)
 
 	v86.ctl = V86_FLAGS;
 	v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
-	dsk.drive = *(uint8_t *)PTOV(ARGS);
-	dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
-	dsk.unit = dsk.drive & DRV_MASK;
-	dsk.part = -1;
-	dsk.start = 0;
+	gdsk.dsk.drive = *(uint8_t *)PTOV(ARGS);
+	gdsk.dsk.type = gdsk.dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
+	gdsk.dsk.unit = gdsk.dsk.drive & DRV_MASK;
+	gdsk.dsk.part = -1;
+	gdsk.dsk.start = 0;
 	bootinfo.bi_version = BOOTINFO_VERSION;
 	bootinfo.bi_size = sizeof(bootinfo);
 	bootinfo.bi_basemem = bios_basemem / 1024;
 	bootinfo.bi_extmem = bios_extmem / 1024;
 	bootinfo.bi_memsizes_valid++;
-	bootinfo.bi_bios_dev = dsk.drive;
+	bootinfo.bi_bios_dev = gdsk.dsk.drive;
 
-#ifdef LOADER_GELI_SUPPORT
-	geli_init();
-#endif
 	/* Process configuration file */
 
 	if (gptinit() != 0)
@@ -332,8 +340,8 @@ main(void)
 		load();
 		memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL));
 		load();
-		gptbootfailed(&dsk);
-		if (gptfind(&freebsd_ufs_uuid, &dsk, -1) == -1)
+		gptbootfailed(&gdsk.dsk);
+		if (gptfind(&freebsd_ufs_uuid, &gdsk.dsk, -1) == -1)
 			break;
 		dsk_meta = 0;
 	}
@@ -345,8 +353,8 @@ main(void)
 			printf("\nFreeBSD/x86 boot\n"
 			    "Default: %u:%s(%up%u)%s\n"
 			    "boot: ",
-			    dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
-			    dsk.part, kname);
+			    gdsk.dsk.drive & DRV_MASK, dev_nm[gdsk.dsk.type],
+			    gdsk.dsk.unit, gdsk.dsk.part, kname);
 		}
 		if (ioctrl & IO_SERIAL)
 			sio_flush();
@@ -392,10 +400,9 @@ load(void)
 	if (!(ino = lookup(kname))) {
 		if (!ls) {
 			printf("%s: No %s on %u:%s(%up%u)\n", BOOTPROG,
-			    kname, dsk.drive & DRV_MASK, dev_nm[dsk.type],
-			    dsk.unit,
-			    dsk.part);
-		}
+		kname, gdsk.dsk.drive & DRV_MASK, dev_nm[gdsk.dsk.type], 
+		gdsk.dsk.unit, gdsk.dsk.part);
+	}
 		return;
 	}
 	if (xfsread(ino, &hdr, sizeof(hdr)))
@@ -469,19 +476,19 @@ load(void)
 	}
 	bootinfo.bi_esymtab = VTOP(p);
 	bootinfo.bi_kernelname = VTOP(kname);
-	bootinfo.bi_bios_dev = dsk.drive;
+	bootinfo.bi_bios_dev = gdsk.dsk.drive;
 #ifdef LOADER_GELI_SUPPORT
 	geliargs.size = sizeof(geliargs);
 	explicit_bzero(gelipw, sizeof(gelipw));
 	gelibuf = malloc(sizeof(struct keybuf) +
 	    (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
-	geli_fill_keybuf(gelibuf);
+	geli_export_key_buffer(gelibuf);
 	geliargs.notapw = '\0';
 	geliargs.keybuf_sentinel = KEYBUF_SENTINEL;
 	geliargs.keybuf = gelibuf;
 #endif
 	__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
-	    MAKEBOOTDEV(dev_maj[dsk.type], dsk.part + 1, dsk.unit, 0xff),
+	    MAKEBOOTDEV(dev_maj[gdsk.dsk.type], gdsk.dsk.part + 1, gdsk.dsk.unit, 0xff),
 	    KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo)
 #ifdef LOADER_GELI_SUPPORT
 	    , geliargs
@@ -595,12 +602,13 @@ dskread(void *buf, daddr_t lba, unsigned nblk)
 {
 	int err;
 
-	err = drvread(&dsk, buf, lba + dsk.start, nblk);
+	err = drvread(&gdsk.dsk, buf, lba + gdsk.dsk.start, nblk);
 
 #ifdef LOADER_GELI_SUPPORT
-	if (err == 0 && is_geli(&dsk) == 0) {
+	if (err == 0 && gdsk.gdev != NULL) {
 		/* Decrypt */
-		if (geli_read(&dsk, lba * DEV_BSIZE, buf, nblk * DEV_BSIZE))
+		if (geli_read(gdsk.gdev, lba * DEV_BSIZE, buf,
+		    nblk * DEV_BSIZE))
 			return (err);
 	}
 #endif
@@ -610,8 +618,8 @@ dskread(void *buf, daddr_t lba, unsigned nblk)
 
 #ifdef LOADER_GELI_SUPPORT
 /*
- * Read function compartible with the ZFS callback, required to keep the GELI
- * Implementation the same for both UFS and ZFS
+ * Read function compatible with the ZFS callback, required to keep the GELI
+ * implementation the same for both UFS and ZFS.
  */
 static int
 vdev_read(void *vdev __unused, void *priv, off_t off, void *buf, size_t bytes)
@@ -619,22 +627,22 @@ vdev_read(void *vdev __unused, void *priv, off_t off, 
 	char *p;
 	daddr_t lba;
 	unsigned int nb;
-	struct dsk *dskp;
+	struct gptdsk *dskp;
 
-	dskp = (struct dsk *)priv;
+	dskp = (struct gptdsk *)priv;
 
 	if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
 		return (-1);
 
 	p = buf;
 	lba = off / DEV_BSIZE;
-	lba += dskp->start;
+	lba += dskp->dsk.start;
 
 	while (bytes > 0) {
 		nb = bytes / DEV_BSIZE;
 		if (nb > VBLKSIZE / DEV_BSIZE)
 			nb = VBLKSIZE / DEV_BSIZE;
-		if (drvread(dskp, dmadat->blkbuf, lba, nb))
+		if (drvread(&dskp->dsk, dmadat->blkbuf, lba, nb))
 			return (-1);
 		memcpy(p, dmadat->blkbuf, nb * DEV_BSIZE);
 		p += nb * DEV_BSIZE;

Modified: head/stand/i386/gptzfsboot/Makefile
==============================================================================
--- head/stand/i386/gptzfsboot/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/gptzfsboot/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=	yes
-
 .include <bsd.init.mk>
 
 .PATH:		${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \

Modified: head/stand/i386/isoboot/Makefile
==============================================================================
--- head/stand/i386/isoboot/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/isoboot/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=		yes
-
 .include <bsd.init.mk>
 
 .PATH:		${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/gptboot \

Modified: head/stand/i386/libi386/Makefile
==============================================================================
--- head/stand/i386/libi386/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/libi386/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=		yes
-
 .include <bsd.init.mk>
 
 LIB=			i386

Modified: head/stand/i386/libi386/biosdisk.c
==============================================================================
--- head/stand/i386/libi386/biosdisk.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/libi386/biosdisk.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -51,31 +51,7 @@ __FBSDID("$FreeBSD$");
 #include "libi386.h"
 
 #ifdef LOADER_GELI_SUPPORT
-#include "cons.h"
-#include "drv.h"
-#include "gpt.h"
-#include "part.h"
-#include <uuid.h>
-struct pentry {
-	struct ptable_entry	part;
-	uint64_t		flags;
-	union {
-		uint8_t bsd;
-		uint8_t	mbr;
-		uuid_t	gpt;
-		uint16_t vtoc8;
-	} type;
-	STAILQ_ENTRY(pentry)	entry;
-};
-struct ptable {
-	enum ptable_type	type;
-	uint16_t		sectorsize;
-	uint64_t		sectors;
-
-	STAILQ_HEAD(, pentry)	entries;
-};
-
-#include "geliboot.c"
+#include "geliboot.h"
 #endif /* LOADER_GELI_SUPPORT */
 
 #define BIOS_NUMDRIVES		0x475
@@ -138,17 +114,6 @@ static int bd_close(struct open_file *f);
 static int bd_ioctl(struct open_file *f, u_long cmd, void *data);
 static int bd_print(int verbose);
 
-#ifdef LOADER_GELI_SUPPORT
-enum isgeli {
-	ISGELI_UNKNOWN,
-	ISGELI_NO,
-	ISGELI_YES
-};
-static enum isgeli geli_status[MAXBDDEV][MAXTBLENTS];
-
-int bios_read(void *, void *, off_t off, void *buf, size_t bytes);
-#endif /* LOADER_GELI_SUPPORT */
-
 struct devsw biosdisk = {
 	"disk",
 	DEVT_DISK,
@@ -195,9 +160,6 @@ bd_init(void)
 {
 	int base, unit, nfd = 0;
 
-#ifdef LOADER_GELI_SUPPORT
-	geli_init();
-#endif
 	/* sequence 0, 0x80 */
 	for (base = 0; base <= 0x80; base += 0x80) {
 		for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
@@ -379,7 +341,7 @@ bd_print(int verbose)
 static int
 bd_open(struct open_file *f, ...)
 {
-	struct disk_devdesc *dev;
+	struct disk_devdesc *dev, rdev;
 	struct disk_devdesc disk;
 	int err, g_err;
 	va_list ap;
@@ -421,81 +383,6 @@ bd_open(struct open_file *f, ...)
 	err = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
 	    BD(dev).bd_sectorsize);
 
-#ifdef LOADER_GELI_SUPPORT
-	static char gelipw[GELI_PW_MAXLEN];
-	char *passphrase;
-
-	if (err)
-		return (err);
-
-	/* if we already know there is no GELI, skip the rest */
-	if (geli_status[dev->dd.d_unit][dev->d_slice] != ISGELI_UNKNOWN)
-		return (err);
-
-	struct dsk dskp;
-	struct ptable *table = NULL;
-	struct ptable_entry part;
-	struct pentry *entry;
-	int geli_part = 0;
-
-	dskp.drive = bd_unit2bios(dev->dd.d_unit);
-	dskp.type = dev->dd.d_dev->dv_type;
-	dskp.unit = dev->dd.d_unit;
-	dskp.slice = dev->d_slice;
-	dskp.part = dev->d_partition;
-	dskp.start = dev->d_offset;
-
-	/* We need the LBA of the end of the partition */
-	table = ptable_open(&disk, BD(dev).bd_sectors,
-	    BD(dev).bd_sectorsize, ptblread);
-	if (table == NULL) {
-		DEBUG("Can't read partition table");
-		/* soft failure, return the exit status of disk_open */
-		return (err);
-	}
-
-	if (table->type == PTABLE_GPT)
-		dskp.part = 255;
-
-	STAILQ_FOREACH(entry, &table->entries, entry) {
-		dskp.slice = entry->part.index;
-		dskp.start = entry->part.start;
-		if (is_geli(&dskp) == 0) {
-			geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES;
-			return (0);
-		}
-		if (geli_taste(bios_read, &dskp,
-		    entry->part.end - entry->part.start) == 0) {
-			if (geli_havekey(&dskp) == 0) {
-				geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES;
-				geli_part++;
-				continue;
-			}
-			if ((passphrase = getenv("kern.geom.eli.passphrase"))
-			    != NULL) {
-				/* Use the cached passphrase */
-				bcopy(passphrase, &gelipw, GELI_PW_MAXLEN);
-			}
-			if (geli_passphrase(gelipw, dskp.unit, 'p',
-				    (dskp.slice > 0 ? dskp.slice : dskp.part),
-				    &dskp) == 0) {
-				setenv("kern.geom.eli.passphrase", gelipw, 1);
-				bzero(gelipw, sizeof(gelipw));
-				geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_YES;
-				geli_part++;
-				continue;
-			}
-		} else
-			geli_status[dev->dd.d_unit][dskp.slice] = ISGELI_NO;
-	}
-
-	/* none of the partitions on this disk have GELI */
-	if (geli_part == 0) {
-		/* found no GELI */
-		geli_status[dev->dd.d_unit][dev->d_slice] = ISGELI_NO;
-	}
-#endif /* LOADER_GELI_SUPPORT */
-
 	return (err);
 }
 
@@ -841,80 +728,7 @@ bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks
 static int
 bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
 {
-#ifdef LOADER_GELI_SUPPORT
-	struct dsk dskp;
-	off_t p_off, diff;
-	daddr_t alignlba;
-	int err, n, alignblks;
-	char *tmpbuf;
 
-	/* if we already know there is no GELI, skip the rest */
-	if (geli_status[dev->dd.d_unit][dev->d_slice] != ISGELI_YES)
-		return (bd_io(dev, dblk, blks, dest, 0));
-
-	if (geli_status[dev->dd.d_unit][dev->d_slice] == ISGELI_YES) {
-		/*
-		 * Align reads to DEV_GELIBOOT_BSIZE bytes because partial
-		 * sectors cannot be decrypted. Round the requested LBA down to
-		 * nearest multiple of DEV_GELIBOOT_BSIZE bytes.
-		 */
-		alignlba = rounddown2(dblk * BD(dev).bd_sectorsize,
-		    DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize;
-		/*
-		 * Round number of blocks to read up to nearest multiple of
-		 * DEV_GELIBOOT_BSIZE
-		 */
-		diff = (dblk - alignlba) * BD(dev).bd_sectorsize;
-		alignblks = roundup2(blks * BD(dev).bd_sectorsize + diff,
-		    DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize;
-
-		/*
-		 * If the read is rounded up to a larger size, use a temporary
-		 * buffer here because the buffer provided by the caller may be
-		 * too small.
-		 */
-		if (diff == 0) {
-			tmpbuf = dest;
-		} else {
-			tmpbuf = malloc(alignblks * BD(dev).bd_sectorsize);
-			if (tmpbuf == NULL) {
-				return (-1);
-			}
-		}
-
-		if (alignlba + alignblks > BD(dev).bd_sectors) {
-			DEBUG("Shorted read at %llu from %d to %llu blocks",
-			    alignlba, alignblks, BD(dev).bd_sectors - alignlba);
-			alignblks = BD(dev).bd_sectors - alignlba;
-		}
-
-		err = bd_io(dev, alignlba, alignblks, tmpbuf, 0);
-		if (err)
-			return (err);
-
-		dskp.drive = bd_unit2bios(dev->dd.d_unit);
-		dskp.type = dev->dd.d_dev->dv_type;
-		dskp.unit = dev->dd.d_unit;
-		dskp.slice = dev->d_slice;
-		dskp.part = dev->d_partition;
-		dskp.start = dev->d_offset;
-
-		/* GELI needs the offset relative to the partition start */
-		p_off = alignlba - dskp.start;
-
-		err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, (u_char *)tmpbuf,
-		    alignblks * BD(dev).bd_sectorsize);
-		if (err)
-			return (err);
-
-		if (tmpbuf != dest) {
-			bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize);
-			free(tmpbuf);
-		}
-		return (0);
-	}
-#endif /* LOADER_GELI_SUPPORT */
-
 	return (bd_io(dev, dblk, blks, dest, 0));
 }
 
@@ -1009,25 +823,3 @@ bd_getdev(struct i386_devdesc *d)
     DEBUG("dev is 0x%x\n", rootdev);
     return(rootdev);
 }
-
-#ifdef LOADER_GELI_SUPPORT
-int
-bios_read(void *vdev __unused, void *xpriv, off_t off, void *buf, size_t bytes)
-{
-	struct disk_devdesc dev;
-	struct dsk *priv = xpriv;
-
-	dev.dd.d_dev = &biosdisk;
-	dev.dd.d_unit = priv->unit;
-	dev.d_slice = priv->slice;
-	dev.d_partition = priv->part;
-	dev.d_offset = priv->start;
-
-	off = off / BD(&dev).bd_sectorsize;
-	/* GELI gives us the offset relative to the partition start */
-	off += dev.d_offset;
-	bytes = bytes / BD(&dev).bd_sectorsize;
-
-	return (bd_io(&dev, off, bytes, buf, 0));
-}
-#endif /* LOADER_GELI_SUPPORT */

Modified: head/stand/i386/libi386/bootinfo32.c
==============================================================================
--- head/stand/i386/libi386/bootinfo32.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/libi386/bootinfo32.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -39,9 +39,6 @@ __FBSDID("$FreeBSD$");
 
 #ifdef LOADER_GELI_SUPPORT
 #include "geliboot.h"
-
-static const size_t keybuf_size = sizeof(struct keybuf) +
-    (GELI_MAX_KEYS * sizeof(struct keybuf_ent));
 #endif
 
 static struct bootinfo  bi;
@@ -154,10 +151,6 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_o
     int				bootdevnr, i, howto;
     char			*kernelname;
     const char			*kernelpath;
-#ifdef LOADER_GELI_SUPPORT
-    char                        buf[keybuf_size];
-    struct keybuf               *keybuf = (struct keybuf *)buf;
-#endif
 
     howto = bi_getboothowto(args);
 
@@ -235,9 +228,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_o
     file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
     bios_addsmapdata(kfp);
 #ifdef LOADER_GELI_SUPPORT
-    geli_fill_keybuf(keybuf);
-    file_addmetadata(kfp, MODINFOMD_KEYBUF, keybuf_size, buf);
-    bzero(buf, sizeof(buf));
+    geli_export_key_metadata(kfp);
 #endif
 
     /* Figure out the size and location of the metadata */

Modified: head/stand/i386/libi386/bootinfo64.c
==============================================================================
--- head/stand/i386/libi386/bootinfo64.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/libi386/bootinfo64.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -42,9 +42,6 @@ __FBSDID("$FreeBSD$");
 
 #ifdef LOADER_GELI_SUPPORT
 #include "geliboot.h"
-
-static const size_t keybuf_size = sizeof(struct keybuf) +
-    (GELI_MAX_KEYS * sizeof(struct keybuf_ent));
 #endif
 
 /*
@@ -196,10 +193,6 @@ bi_load64(char *args, vm_offset_t addr, vm_offset_t *m
     vm_offset_t			size;
     char			*rootdevname;
     int				howto;
-#ifdef LOADER_GELI_SUPPORT
-    char                        buf[keybuf_size];
-    struct keybuf               *keybuf = (struct keybuf *)buf;
-#endif
 
     if (!bi_checkcpu()) {
 	printf("CPU doesn't support long mode\n");
@@ -248,11 +241,8 @@ bi_load64(char *args, vm_offset_t addr, vm_offset_t *m
     file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof module, &module);
     if (add_smap != 0)
         bios_addsmapdata(kfp);
-
 #ifdef LOADER_GELI_SUPPORT
-    geli_fill_keybuf(keybuf);
-    file_addmetadata(kfp, MODINFOMD_KEYBUF, keybuf_size, buf);
-    bzero(buf, sizeof(buf));
+    geli_export_key_metadata(kfp);
 #endif
 
     size = bi_copymodules64(0);

Modified: head/stand/i386/loader/Makefile
==============================================================================
--- head/stand/i386/loader/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/loader/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=		yes
-
 LOADER_NET_SUPPORT?=	yes
 LOADER_NFS_SUPPORT?=	yes
 LOADER_TFTP_SUPPORT?=	yes

Modified: head/stand/i386/loader/main.c
==============================================================================
--- head/stand/i386/loader/main.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/loader/main.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -175,7 +175,7 @@ main(void)
 	if (zargs != NULL && zargs->size >= offsetof(struct zfs_boot_args, gelipw)) {
 	    if (zargs->size >= offsetof(struct zfs_boot_args, keybuf_sentinel) &&
 	      zargs->keybuf_sentinel == KEYBUF_SENTINEL) {
-		geli_save_keybuf(zargs->keybuf);
+		geli_import_key_buffer(zargs->keybuf);
 	    }
 	    if (zargs->gelipw[0] != '\0') {
 		setenv("kern.geom.eli.passphrase", zargs->gelipw, 1);
@@ -190,7 +190,7 @@ main(void)
 	gargs = (struct geli_boot_args *)(kargs + 1);
 	if (gargs != NULL && gargs->size >= offsetof(struct geli_boot_args, gelipw)) {
 	    if (gargs->keybuf_sentinel == KEYBUF_SENTINEL) {
-		geli_save_keybuf(gargs->keybuf);
+		geli_import_key_buffer(gargs->keybuf);
 	    }
 	    if (gargs->gelipw[0] != '\0') {
 		setenv("kern.geom.eli.passphrase", gargs->gelipw, 1);

Modified: head/stand/i386/zfsboot/Makefile
==============================================================================
--- head/stand/i386/zfsboot/Makefile	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/zfsboot/Makefile	Fri Jul 13 17:50:25 2018	(r336252)
@@ -1,7 +1,5 @@
 # $FreeBSD$
 
-HAVE_GELI=yes
-
 .include <bsd.init.mk>
 
 .PATH:		${BOOTSRC}/i386/boot2 ${BOOTSRC}/i386/common ${SASRC}

Modified: head/stand/i386/zfsboot/zfsboot.c
==============================================================================
--- head/stand/i386/zfsboot/zfsboot.c	Fri Jul 13 17:42:48 2018	(r336251)
+++ head/stand/i386/zfsboot/zfsboot.c	Fri Jul 13 17:50:25 2018	(r336252)
@@ -127,11 +127,18 @@ static void bios_getmem(void);
 int main(void);
 
 #ifdef LOADER_GELI_SUPPORT
-#include "geliboot.c"
+#include "geliboot.h"
 static char gelipw[GELI_PW_MAXLEN];
 static struct keybuf *gelibuf;
 #endif
 
+struct zfsdsk {
+	struct dsk       dsk;
+#ifdef LOADER_GELI_SUPPORT
+	struct geli_dev *gdev;
+#endif
+};
+
 #include "zfsimpl.c"
 
 /*
@@ -174,14 +181,14 @@ vdev_read(void *xvdev, void *priv, off_t off, void *bu
 	daddr_t lba, alignlba;
 	off_t diff;
 	unsigned int nb, alignnb;
-	struct dsk *dsk = (struct dsk *) priv;
+	struct zfsdsk *zdsk = (struct zfsdsk *) priv;
 
 	if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
 		return -1;
 
 	p = buf;
 	lba = off / DEV_BSIZE;
-	lba += dsk->start;
+	lba += zdsk->dsk.start;
 	/*
 	 * Align reads to 4k else 4k sector GELIs will not decrypt.
 	 * Round LBA down to nearest multiple of DEV_GELIBOOT_BSIZE bytes.
@@ -191,7 +198,7 @@ vdev_read(void *xvdev, void *priv, off_t off, void *bu
 	 * The read must be aligned to DEV_GELIBOOT_BSIZE bytes relative to the
 	 * start of the GELI partition, not the start of the actual disk.
 	 */
-	alignlba += dsk->start;
+	alignlba += zdsk->dsk.start;
 	diff = (lba - alignlba) * DEV_BSIZE;
 
 	while (bytes > 0) {
@@ -209,18 +216,20 @@ vdev_read(void *xvdev, void *priv, off_t off, void *bu
 		alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE)
 		    / DEV_BSIZE;
 
-		if (dsk->size > 0 && alignlba + alignnb > dsk->size + dsk->start) {
-			printf("Shortening read at %lld from %d to %lld\n", alignlba,
-			    alignnb, (dsk->size + dsk->start) - alignlba);
-			alignnb = (dsk->size + dsk->start) - alignlba;
+		if (zdsk->dsk.size > 0 && alignlba + alignnb >
+		    zdsk->dsk.size + zdsk->dsk.start) {
+			printf("Shortening read at %lld from %d to %lld\n",
+			    alignlba, alignnb,
+			    (zdsk->dsk.size + zdsk->dsk.start) - alignlba);
+			alignnb = (zdsk->dsk.size + zdsk->dsk.start) - alignlba;
 		}
 
-		if (drvread(dsk, dmadat->rdbuf, alignlba, alignnb))
+		if (drvread(&zdsk->dsk, dmadat->rdbuf, alignlba, alignnb))
 			return -1;
 #ifdef LOADER_GELI_SUPPORT
 		/* decrypt */
-		if (is_geli(dsk) == 0) {
-			if (geli_read(dsk, ((alignlba - dsk->start) *
+		if (zdsk->gdev != NULL) {
+			if (geli_read(zdsk->gdev, ((alignlba - zdsk->dsk.start) *
 			    DEV_BSIZE), dmadat->rdbuf, alignnb * DEV_BSIZE))
 				return (-1);
 		}
@@ -250,20 +259,20 @@ vdev_write(vdev_t *vdev, void *priv, off_t off, void *
 	char *p;
 	daddr_t lba;
 	unsigned int nb;
-	struct dsk *dsk = (struct dsk *) priv;
+	struct zfsdsk *zdsk = (struct zfsdsk *) priv;
 
 	if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
 		return -1;
 
 	p = buf;
 	lba = off / DEV_BSIZE;
-	lba += dsk->start;
+	lba += zdsk->dsk.start;
 	while (bytes > 0) {
 		nb = bytes / DEV_BSIZE;
 		if (nb > READ_BUF_SIZE / DEV_BSIZE)
 			nb = READ_BUF_SIZE / DEV_BSIZE;
 		memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE);
-		if (drvwrite(dsk, dmadat->rdbuf, lba, nb))
+		if (drvwrite(&zdsk->dsk, dmadat->rdbuf, lba, nb))
 			return -1;
 		p += nb * DEV_BSIZE;
 		lba += nb;
@@ -441,13 +450,13 @@ int13probe(int drive)
  * We call this when we find a ZFS vdev - ZFS consumes the dsk
  * structure so we must make a new one.
  */
-static struct dsk *
-copy_dsk(struct dsk *dsk)
+static struct zfsdsk *
+copy_dsk(struct zfsdsk *zdsk)
 {
-    struct dsk *newdsk;
+    struct zfsdsk *newdsk;
 
-    newdsk = malloc(sizeof(struct dsk));
-    *newdsk = *dsk;
+    newdsk = malloc(sizeof(struct zfsdsk));
+    *newdsk = *zdsk;
     return (newdsk);
 }
 
@@ -459,11 +468,14 @@ copy_dsk(struct dsk *dsk)
  * with boot2 and we can not afford to grow that code.
  */
 static uint64_t
-drvsize_ext(struct dsk *dskp)
+drvsize_ext(struct zfsdsk *zdsk)
 {
+	struct dsk *dskp;
 	uint64_t size, tmp;
 	int cyl, hds, sec;
 
+	dskp = &zdsk->dsk;
+
 	v86.ctl = V86_FLAGS;
 	v86.addr = 0x13;
 	v86.eax = 0x800;
@@ -508,17 +520,17 @@ drvsize_ext(struct dsk *dskp)
 uint64_t
 ldi_get_size(void *priv)
 {
-	struct dsk *dskp = priv;
-	uint64_t size = dskp->size;
+	struct zfsdsk *zdsk = priv;
+	uint64_t size = zdsk->dsk.size;
 
-	if (dskp->start == 0)
-		size = drvsize_ext(dskp);
+	if (zdsk->dsk.start == 0)
+		size = drvsize_ext(zdsk);
 
 	return (size * DEV_BSIZE);
 }
 
 static void
-probe_drive(struct dsk *dsk)
+probe_drive(struct zfsdsk *zdsk)
 {
 #ifdef GPT
     struct gpt_hdr hdr;
@@ -537,7 +549,7 @@ probe_drive(struct dsk *dsk)
     /*
      * If we find a vdev on the whole disk, stop here.
      */
-    if (vdev_probe(vdev_read2, dsk, NULL) == 0)
+    if (vdev_probe(vdev_read2, zdsk, NULL) == 0)
 	return;
 
 #ifdef LOADER_GELI_SUPPORT
@@ -547,14 +559,15 @@ probe_drive(struct dsk *dsk)
      * out the partition table and probe each slice/partition
      * in turn for a vdev or GELI encrypted vdev.
      */
-    elba = drvsize_ext(dsk);
+    elba = drvsize_ext(zdsk);
     if (elba > 0) {
 	elba--;
     }
-    if (geli_taste(vdev_read, dsk, elba) == 0) {
-	if (geli_havekey(dsk) == 0 || geli_passphrase(gelipw, dsk->unit,
-	  ':', 0, dsk) == 0) {
-	    if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
+    zdsk->gdev = geli_taste(vdev_read, zdsk, elba, "disk%u:0:");
+    if (zdsk->gdev != NULL) {
+	if (geli_havekey(zdsk->gdev) == 0 || 
+	    geli_passphrase(zdsk->gdev, gelipw) == 0) {
+	    if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
 		return;
 	    }
 	}
@@ -562,13 +575,13 @@ probe_drive(struct dsk *dsk)
 #endif /* LOADER_GELI_SUPPORT */
 
     sec = dmadat->secbuf;
-    dsk->start = 0;
+    zdsk->dsk.start = 0;
 
 #ifdef GPT
     /*
      * First check for GPT.
      */
-    if (drvread(dsk, sec, 1, 1)) {
+    if (drvread(&zdsk->dsk, sec, 1, 1)) {
 	return;
     }
     memcpy(&hdr, sec, sizeof(hdr));
@@ -590,38 +603,39 @@ probe_drive(struct dsk *dsk)
     slba = hdr.hdr_lba_table;
     elba = slba + hdr.hdr_entries / entries_per_sec;
     while (slba < elba) {
-	dsk->start = 0;
-	if (drvread(dsk, sec, slba, 1))
+	zdsk->dsk.start = 0;
+	if (drvread(&zdsk->dsk, sec, slba, 1))
 	    return;
 	for (part = 0; part < entries_per_sec; part++) {
 	    ent = (struct gpt_ent *)(sec + part * hdr.hdr_entsz);
 	    if (memcmp(&ent->ent_type, &freebsd_zfs_uuid,
 		     sizeof(uuid_t)) == 0) {
-		dsk->start = ent->ent_lba_start;
-		dsk->size = ent->ent_lba_end - ent->ent_lba_start + 1;
-		dsk->slice = part + 1;
-		dsk->part = 255;
-		if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
+		zdsk->dsk.start = ent->ent_lba_start;
+		zdsk->dsk.size = ent->ent_lba_end - ent->ent_lba_start + 1;
+		zdsk->dsk.slice = part + 1;
+		zdsk->dsk.part = 255;
+		if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
 		    /*
 		     * This slice had a vdev. We need a new dsk
 		     * structure now since the vdev now owns this one.
 		     */
-		    dsk = copy_dsk(dsk);
+		    zdsk = copy_dsk(zdsk);
 		}
 #ifdef LOADER_GELI_SUPPORT
-		else if (geli_taste(vdev_read, dsk, ent->ent_lba_end -
-			 ent->ent_lba_start) == 0) {
-		    if (geli_havekey(dsk) == 0 || geli_passphrase(gelipw,
-		      dsk->unit, 'p', dsk->slice, dsk) == 0) {
+		else if ((zdsk->gdev = geli_taste(vdev_read, zdsk,
+		    ent->ent_lba_end - ent->ent_lba_start, "disk%up%u:",
+		    zdsk->dsk.unit, zdsk->dsk.slice)) != NULL) {
+		    if (geli_havekey(zdsk->gdev) == 0 ||
+			geli_passphrase(zdsk->gdev, gelipw) == 0) {
 			/*
 			 * This slice has GELI, check it for ZFS.
 			 */
-			if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
+			if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
 			    /*
 			     * This slice had a vdev. We need a new dsk
 			     * structure now since the vdev now owns this one.
 			     */
-			    dsk = copy_dsk(dsk);
+			    zdsk = copy_dsk(zdsk);
 			}
 			break;
 		    }
@@ -635,33 +649,33 @@ probe_drive(struct dsk *dsk)
 trymbr:
 #endif /* GPT */
 
-    if (drvread(dsk, sec, DOSBBSECTOR, 1))
+    if (drvread(&zdsk->dsk, sec, DOSBBSECTOR, 1))
 	return;
     dp = (void *)(sec + DOSPARTOFF);
 
     for (i = 0; i < NDOSPART; i++) {
 	if (!dp[i].dp_typ)
 	    continue;
-	dsk->start = dp[i].dp_start;
-	dsk->size = dp[i].dp_size;
-	dsk->slice = i + 1;
-	if (vdev_probe(vdev_read2, dsk, NULL) == 0) {
-	    dsk = copy_dsk(dsk);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807131750.w6DHoPD9024230>