Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F138020594
D9575.id25355.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D9575.id25355.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9575: Boot-time Key Intake Metadata
Attached
Detach File
Event Timeline
Log In to Comment