Page MenuHomeFreeBSD

D9575.id25355.diff
No OneTemporary

D9575.id25355.diff

Index: sys/boot/geli/Makefile
===================================================================
--- sys/boot/geli/Makefile
+++ sys/boot/geli/Makefile
@@ -39,6 +39,7 @@
# AES implementation from sys/crypto
.PATH: ${.CURDIR}/../../crypto/rijndael
CFLAGS+= -I${.CURDIR}/../../
+CFLAGS+= -I${.CURDIR}/../common/
# Remove asserts
CFLAGS+= -DNDEBUG
SRCS+= rijndael-alg-fst.c rijndael-api-fst.c rijndael-api.c
Index: sys/boot/geli/geliboot.h
===================================================================
--- sys/boot/geli/geliboot.h
+++ sys/boot/geli/geliboot.h
@@ -30,6 +30,10 @@
#include <sys/endian.h>
#include <sys/queue.h>
+#include <crypto/intake.h>
+
+#include <bootstrap.h>
+
#ifndef _GELIBOOT_H_
#define _GELIBOOT_H_
@@ -63,6 +67,7 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#define GELI_MAX_KEYS 64
#define GELI_PW_MAXLEN 256
extern void pwgets(char *buf, int n);
@@ -89,4 +94,6 @@
int geliboot_crypt(u_int algo, int enc, u_char *data, size_t datasize,
const u_char *key, size_t keysize, u_char *iv);
+void geli_fill_keybuf(struct keybuf *keybuf);
+
#endif /* _GELIBOOT_H_ */
Index: sys/boot/geli/geliboot.c
===================================================================
--- sys/boot/geli/geliboot.c
+++ sys/boot/geli/geliboot.c
@@ -27,11 +27,47 @@
* $FreeBSD$
*/
+#include <crypto/intake.h>
+
#include "geliboot.h"
SLIST_HEAD(geli_list, geli_entry) geli_head = SLIST_HEAD_INITIALIZER(geli_head);
struct geli_list *geli_headp;
+typedef u_char geli_mkey[G_ELI_DATAIVKEYLEN];
+
+static geli_mkey saved_keys[GELI_MAX_KEYS];
+static unsigned int nsaved_keys = 0;
+
+void
+geli_fill_keybuf(struct keybuf *keybuf)
+{
+ unsigned int i;
+
+ for (i = 0; i < nsaved_keys; i++) {
+ keybuf->kb_ents[i].ke_type = KEYBUF_TYPE_GELI;
+ memcpy(keybuf->kb_ents[i].ke_data, saved_keys[i],
+ G_ELI_DATAIVKEYLEN);
+ }
+
+ keybuf->kb_nents = nsaved_keys;
+ bzero(saved_keys, sizeof(saved_keys));
+}
+
+static void
+save_key(geli_mkey key)
+{
+
+ /*
+ * If we run out of key space, the worst that will happen is
+ * it will ask the user for the password again.
+ */
+ if (nsaved_keys < GELI_MAX_KEYS) {
+ memcpy(saved_keys[nsaved_keys], key, G_ELI_DATAIVKEYLEN);
+ nsaved_keys++;
+ }
+}
+
static int
geli_same_device(struct geli_entry *ge, struct dsk *dskp)
{
@@ -191,6 +227,7 @@
}
/* Store the keys */
+ save_key(mkey);
bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
@@ -231,7 +268,7 @@
return (0);
}
}
-
+
return (1);
}
Index: sys/boot/i386/gptboot/gptboot.c
===================================================================
--- sys/boot/i386/gptboot/gptboot.c
+++ sys/boot/i386/gptboot/gptboot.c
@@ -101,7 +101,7 @@
void exit(int);
static void load(void);
-static int parse(char *, int *);
+static int parse_cmds(char *, int *);
static int dskread(void *, daddr_t, unsigned);
void *malloc(size_t n);
void free(void *ptr);
@@ -316,7 +316,7 @@
}
if (*cmd != '\0') {
memcpy(cmdtmp, cmd, sizeof(cmdtmp));
- if (parse(cmdtmp, &dskupdated))
+ if (parse_cmds(cmdtmp, &dskupdated))
break;
if (dskupdated && gptinit() != 0)
break;
@@ -366,7 +366,7 @@
getstr(cmd, sizeof(cmd));
else if (!OPT_CHECK(RBX_QUIET))
putchar('\n');
- if (parse(cmd, &dskupdated)) {
+ if (parse_cmds(cmd, &dskupdated)) {
putchar('\a');
continue;
}
@@ -489,7 +489,7 @@
}
static int
-parse(char *cmdstr, int *dskupdated)
+parse_cmds(char *cmdstr, int *dskupdated)
{
char *arg = cmdstr;
char *ep, *p, *q;
Index: sys/boot/i386/libi386/bootinfo32.c
===================================================================
--- sys/boot/i386/libi386/bootinfo32.c
+++ sys/boot/i386/libi386/bootinfo32.c
@@ -32,10 +32,18 @@
#include <sys/reboot.h>
#include <sys/linker.h>
#include <machine/bootinfo.h>
+#include <machine/metadata.h>
#include "bootstrap.h"
#include "libi386.h"
#include "btxv86.h"
+#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;
/*
@@ -146,11 +154,15 @@
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);
- /*
- * Allow the environment variable 'rootdev' to override the supplied device
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
* This should perhaps go to MI code and/or have $rootdev tested/set by
* MI code before launching the kernel.
*/
@@ -185,7 +197,7 @@
case DEVT_NET:
case DEVT_ZFS:
break;
-
+
default:
printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
}
@@ -221,6 +233,11 @@
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
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));
+#endif
/* Figure out the size and location of the metadata */
*modulep = addr;
Index: sys/boot/i386/libi386/bootinfo64.c
===================================================================
--- sys/boot/i386/libi386/bootinfo64.c
+++ sys/boot/i386/libi386/bootinfo64.c
@@ -40,6 +40,13 @@
#include "libi386.h"
#include "btxv86.h"
+#ifdef LOADER_GELI_SUPPORT
+#include "geliboot.h"
+
+static const size_t keybuf_size = sizeof(struct keybuf) +
+ (GELI_MAX_KEYS * sizeof(struct keybuf_ent));
+#endif
+
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
@@ -189,6 +196,10 @@
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");
@@ -197,8 +208,8 @@
howto = bi_getboothowto(args);
- /*
- * Allow the environment variable 'rootdev' to override the supplied device
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
* This should perhaps go to MI code and/or have $rootdev tested/set by
* MI code before launching the kernel.
*/
@@ -238,6 +249,12 @@
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));
+#endif
+
size = bi_copymodules64(0);
/* copy our environment */
Index: sys/boot/i386/zfsboot/zfsboot.c
===================================================================
--- sys/boot/i386/zfsboot/zfsboot.c
+++ sys/boot/i386/zfsboot/zfsboot.c
@@ -121,7 +121,7 @@
void exit(int);
void reboot(void);
static void load(void);
-static int parse(void);
+static int parse_cmd(void);
static void bios_getmem(void);
void *malloc(size_t n);
void free(void *ptr);
@@ -398,7 +398,7 @@
v86.ctl = 0;
v86.addr = 0x12; /* int 0x12 */
v86int();
-
+
bios_basemem = (v86.eax & 0xffff) * 1024;
}
@@ -442,7 +442,7 @@
v86.eax = 0x800;
v86.edx = drive;
v86int();
-
+
if (!V86_CY(v86.efl) && /* carry clear */
((v86.edx & 0xff) != (drive & DRV_MASK))) { /* unit # OK */
if ((v86.ecx & 0x3f) == 0) { /* absurd sector size */
@@ -729,7 +729,7 @@
*/
nextboot = 1;
memcpy(cmddup, cmd, sizeof(cmd));
- if (parse()) {
+ if (parse_cmd()) {
printf("failed to parse pad2 area of primary vdev\n");
reboot();
}
@@ -756,11 +756,11 @@
if (*cmd) {
/*
- * Note that parse() is destructive to cmd[] and we also want
+ * Note that parse_cmd() is destructive to cmd[] and we also want
* to honor RBX_QUIET option that could be present in cmd[].
*/
memcpy(cmddup, cmd, sizeof(cmd));
- if (parse())
+ if (parse_cmd())
autoboot = 0;
if (!OPT_CHECK(RBX_QUIET))
printf("%s: %s\n", PATH_CONFIG, cmddup);
@@ -810,7 +810,7 @@
else if (!autoboot || !OPT_CHECK(RBX_QUIET))
putchar('\n');
autoboot = 0;
- if (parse())
+ if (parse_cmd())
putchar('\a');
else
load();
@@ -979,7 +979,7 @@
}
static int
-parse(void)
+parse_cmd(void)
{
char *arg = cmd;
char *ep, *p, *q;
Index: sys/crypto/intake.h
===================================================================
--- /dev/null
+++ sys/crypto/intake.h
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2016 Eric McCorkle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _INTAKE_H_
+#define _INTAKE_H_
+
+#include <sys/param.h>
+
+/*
+ * This file provides an interface for providing keys to the kernel
+ * during boot time.
+ */
+
+#define MAX_KEY_BITS 4096
+#define MAX_KEY_BYTES (MAX_KEY_BITS / NBBY)
+
+enum {
+ KEYBUF_TYPE_NONE,
+ KEYBUF_TYPE_GELI
+};
+
+struct keybuf_ent {
+ unsigned int ke_type;
+ char ke_data[MAX_KEY_BYTES];
+};
+
+struct keybuf {
+ unsigned int kb_nents;
+ struct keybuf_ent kb_ents[];
+};
+
+#ifdef _KERNEL
+/* Get the key intake buffer */
+extern struct keybuf* get_keybuf(void);
+#endif
+
+#endif
Index: sys/geom/eli/g_eli.h
===================================================================
--- sys/geom/eli/g_eli.h
+++ sys/geom/eli/g_eli.h
@@ -41,6 +41,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <geom/geom.h>
+#include <crypto/intake.h>
#else
#include <assert.h>
#include <stdio.h>
@@ -139,6 +140,10 @@
#define G_ELI_CRYPTO_SW 2
#ifdef _KERNEL
+#if (MAX_KEY_BYTES < G_ELI_DATAKEYLEN)
+#error "MAX_KEY_BYTES is less than G_ELI_DATAKEYLEN"
+#endif
+
extern int g_eli_debug;
extern u_int g_eli_overwrites;
extern u_int g_eli_batch;
Index: sys/geom/eli/g_eli.c
===================================================================
--- sys/geom/eli/g_eli.c
+++ sys/geom/eli/g_eli.c
@@ -53,6 +53,8 @@
#include <geom/eli/g_eli.h>
#include <geom/eli/pkcs5v2.h>
+#include <crypto/intake.h>
+
FEATURE(geom_eli, "GEOM crypto module");
MALLOC_DEFINE(M_ELI, "eli data", "GEOM_ELI Data");
@@ -111,13 +113,39 @@
}
SYSINIT(geli_fetch_loader_passphrase, SI_SUB_KMEM + 1, SI_ORDER_ANY,
fetch_loader_passphrase, NULL);
+
static void
-zero_boot_passcache(void * dummy)
+zero_boot_passcache(void)
{
- memset(cached_passphrase, 0, sizeof(cached_passphrase));
+ explicit_bzero(cached_passphrase, sizeof(cached_passphrase));
+}
+
+static void
+zero_geli_intake_keys(void)
+{
+ struct keybuf *keybuf;
+ int i;
+
+ if ((keybuf = get_keybuf()) != NULL) {
+ /* Scan the key buffer, clear all GELI keys. */
+ for (i = 0; i < keybuf->kb_nents; i++) {
+ if (keybuf->kb_ents[i].ke_type == KEYBUF_TYPE_GELI) {
+ explicit_bzero(keybuf->kb_ents[i].ke_data,
+ sizeof(keybuf->kb_ents[i].ke_data));
+ keybuf->kb_ents[i].ke_type = KEYBUF_TYPE_NONE;
+ }
+ }
+ }
+}
+
+static void
+zero_intake_passcache(void *dummy)
+{
+ zero_boot_passcache();
+ zero_geli_intake_keys();
}
-EVENTHANDLER_DEFINE(mountroot, zero_boot_passcache, NULL, 0);
+EVENTHANDLER_DEFINE(mountroot, zero_intake_passcache, NULL, 0);
static eventhandler_tag g_eli_pre_sync = NULL;
@@ -997,6 +1025,7 @@
u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN];
u_int i, nkey, nkeyfiles, tries;
int error;
+ struct keybuf *keybuf;
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name);
g_topology_assert();
@@ -1035,97 +1064,114 @@
tries = g_eli_tries;
}
- for (i = 0; i <= tries; i++) {
- g_eli_crypto_hmac_init(&ctx, NULL, 0);
-
- /*
- * Load all key files.
- */
- nkeyfiles = g_eli_keyfiles_load(&ctx, pp->name);
-
- if (nkeyfiles == 0 && md.md_iterations == -1) {
- /*
- * No key files and no passphrase, something is
- * definitely wrong here.
- * geli(8) doesn't allow for such situation, so assume
- * that there was really no passphrase and in that case
- * key files are no properly defined in loader.conf.
- */
- G_ELI_DEBUG(0,
- "Found no key files in loader.conf for %s.",
- pp->name);
- return (NULL);
- }
-
- /* Ask for the passphrase if defined. */
- if (md.md_iterations >= 0) {
- /* 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));
- }
- }
-
- /*
- * Prepare Derived-Key from the user passphrase.
- */
- if (md.md_iterations == 0) {
- g_eli_crypto_hmac_update(&ctx, md.md_salt,
- sizeof(md.md_salt));
- g_eli_crypto_hmac_update(&ctx, passphrase,
- strlen(passphrase));
- bzero(passphrase, sizeof(passphrase));
- } else if (md.md_iterations > 0) {
- u_char dkey[G_ELI_USERKEYLEN];
-
- pkcs5v2_genkey(dkey, sizeof(dkey), md.md_salt,
- sizeof(md.md_salt), passphrase, md.md_iterations);
- bzero(passphrase, sizeof(passphrase));
- g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
- bzero(dkey, sizeof(dkey));
- }
-
- g_eli_crypto_hmac_final(&ctx, key, 0);
-
- /*
- * Decrypt Master-Key.
- */
- error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
- bzero(key, sizeof(key));
- if (error == -1) {
- if (i == tries) {
- G_ELI_DEBUG(0,
- "Wrong key for %s. No tries left.",
- pp->name);
- g_eli_keyfiles_clear(pp->name);
- return (NULL);
- }
- 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).",
- 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;
- }
+ if ((keybuf = get_keybuf()) != NULL) {
+ /* Scan the key buffer, try all GELI keys. */
+ for (i = 0; i < keybuf->kb_nents; i++) {
+ if (keybuf->kb_ents[i].ke_type == KEYBUF_TYPE_GELI) {
+ memcpy(key, keybuf->kb_ents[i].ke_data,
+ sizeof(key));
+
+ if (g_eli_mkey_decrypt(&md, key,
+ mkey, &nkey) == 0 ) {
+ explicit_bzero(key, sizeof(key));
+ goto have_key;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i <= tries; i++) {
+ g_eli_crypto_hmac_init(&ctx, NULL, 0);
+
+ /*
+ * Load all key files.
+ */
+ nkeyfiles = g_eli_keyfiles_load(&ctx, pp->name);
+
+ if (nkeyfiles == 0 && md.md_iterations == -1) {
+ /*
+ * No key files and no passphrase, something is
+ * definitely wrong here.
+ * geli(8) doesn't allow for such situation, so assume
+ * that there was really no passphrase and in that case
+ * key files are no properly defined in loader.conf.
+ */
+ G_ELI_DEBUG(0,
+ "Found no key files in loader.conf for %s.",
+ pp->name);
+ return (NULL);
+ }
+
+ /* Ask for the passphrase if defined. */
+ if (md.md_iterations >= 0) {
+ /* 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));
+ }
+ }
+
+ /*
+ * Prepare Derived-Key from the user passphrase.
+ */
+ if (md.md_iterations == 0) {
+ g_eli_crypto_hmac_update(&ctx, md.md_salt,
+ sizeof(md.md_salt));
+ g_eli_crypto_hmac_update(&ctx, passphrase,
+ strlen(passphrase));
+ explicit_bzero(passphrase, sizeof(passphrase));
+ } else if (md.md_iterations > 0) {
+ u_char dkey[G_ELI_USERKEYLEN];
+
+ pkcs5v2_genkey(dkey, sizeof(dkey), md.md_salt,
+ sizeof(md.md_salt), passphrase, md.md_iterations);
+ bzero(passphrase, sizeof(passphrase));
+ g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
+ explicit_bzero(dkey, sizeof(dkey));
+ }
+
+ g_eli_crypto_hmac_final(&ctx, key, 0);
+
+ /*
+ * Decrypt Master-Key.
+ */
+ error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
+ bzero(key, sizeof(key));
+ if (error == -1) {
+ if (i == tries) {
+ G_ELI_DEBUG(0,
+ "Wrong key for %s. No tries left.",
+ pp->name);
+ g_eli_keyfiles_clear(pp->name);
+ return (NULL);
+ }
+ 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).",
+ 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;
+ }
+have_key:
/*
* We have correct key, let's attach provider.
Index: sys/opencrypto/crypto.c
===================================================================
--- sys/opencrypto/crypto.c
+++ sys/opencrypto/crypto.c
@@ -63,6 +63,7 @@
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
+#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
@@ -74,6 +75,7 @@
#include <ddb/ddb.h>
#include <vm/uma.h>
+#include <crypto/intake.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform.h> /* XXX for M_XDATA */
@@ -84,6 +86,7 @@
#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
#include <machine/pcb.h>
#endif
+#include <machine/metadata.h>
SDT_PROVIDER_DEFINE(opencrypto);
@@ -186,6 +189,37 @@
&crypto_timing, 0, "Enable/disable crypto timing support");
#endif
+/* Try to avoid directly exposing the key buffer as a symbol */
+static struct keybuf *keybuf;
+
+static struct keybuf empty_keybuf = {
+ .kb_nents = 0
+};
+
+/* Obtain the key buffer from boot metadata */
+static void
+keybuf_init(void)
+{
+ caddr_t kmdp;
+
+ kmdp = preload_search_by_type("elf kernel");
+
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type("elf64 kernel");
+
+ keybuf = (struct keybuf *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_KEYBUF);
+
+ if (keybuf == NULL)
+ keybuf = &empty_keybuf;
+}
+
+/* It'd be nice if we could store these in some kind of secure memory... */
+struct keybuf * get_keybuf(void) {
+
+ return (keybuf);
+}
+
static int
crypto_init(void)
{
@@ -238,6 +272,9 @@
error);
goto bad;
}
+
+ keybuf_init();
+
return 0;
bad:
crypto_destroy();
@@ -282,7 +319,7 @@
/* XXX flush queues??? */
- /*
+ /*
* Reclaim dynamically allocated resources.
*/
if (crypto_drivers != NULL)
Index: sys/sys/linker.h
===================================================================
--- sys/sys/linker.h
+++ sys/sys/linker.h
@@ -217,6 +217,7 @@
#define MODINFOMD_CTORS_ADDR 0x000a /* address of .ctors */
#define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */
#define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */
+#define MODINFOMD_KEYBUF 0x000d /* Crypto key intake buffer */
#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 29, 5:46 AM (2 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26319587
Default Alt Text
D9575.id25355.diff (22 KB)

Event Timeline