Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144507407
D12698.id43475.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
43 KB
Referenced Files
None
Subscribers
None
D12698.id43475.diff
View Options
Index: stand/efi/include/efi_drivers.h
===================================================================
--- stand/efi/include/efi_drivers.h
+++ stand/efi/include/efi_drivers.h
@@ -36,10 +36,11 @@
void (*init)(void);
} efi_driver_t;
-extern struct devsw efipart_dev;
+extern const efi_driver_t *efi_drivers[];
+
extern int efipart_getdesc(struct devdesc *dev, char **out);
/* EFI drivers. */
-extern const efi_driver_t fs_driver;
+extern const efi_driver_t key_inject_driver;
#endif
Index: stand/efi/include/efisec.h
===================================================================
--- /dev/null
+++ stand/efi/include/efisec.h
@@ -0,0 +1,294 @@
+/*-
+ * 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$
+ */
+
+#include <efi.h>
+
+#ifndef _EFISEC_H_
+#define _EFISEC_H_
+
+#define EFI_KMS_PROTOCOL \
+ { 0xec3a978d, 0x7c4e, 0x48fa, { 0x9a, 0xbe, 0x6a, 0xd9, 0x1c, 0xc8, 0xf8, 0x11 } }
+
+#define EFI_KMS_DATA_TYPE_NONE 0
+#define EFI_KMS_DATA_TYPE_BINARY 1
+#define EFI_KMS_DATA_TYPE_ASCII 2
+#define EFI_KMS_DATA_TYPE_UNICODE 4
+#define EFI_KMS_DATA_TYPE_UTF8 8
+
+typedef struct {
+ UINT16 ClientIdSize;
+ VOID *ClientId;
+ UINT8 ClientNameType;
+ UINT8 ClientNameCount;
+ VOID *ClientName;
+} EFI_KMS_CLIENT_INFO;
+
+/* Note: GUIDs for insecure crypto have been omitted */
+#define EFI_KMS_FORMAT_GENERIC_128_GUID \
+ { 0xec8a3d69, 0x6ddf, 0x4108, { 0x94, 0x76, 0x73, 0x37, 0xfc, 0x52, 0x21, 0x36 } }
+
+#define EFI_KMS_FORMAT_GENERIC_160_GUID \
+ { 0xa3b3e6f8, 0xefca, 0x4bc1, { 0x88, 0xfb, 0xcb, 0x87, 0x33, 0x9b, 0x25, 0x79 } }
+
+#define EFI_KMS_FORMAT_GENERIC_256_GUID \
+ { 0x70f64793, 0xc323, 0x4261, { 0xac, 0x2c, 0xd8, 0x76, 0xf2, 0x7c, 0x53, 0x45 } }
+
+#define EFI_KMS_FORMAT_GENERIC_512_GUID \
+ { 0x978fe043, 0xd7af, 0x422e, { 0x8a, 0x92, 0x2b, 0x48, 0xe4, 0x63, 0xbd, 0xe6 } }
+
+#define EFI_KMS_FORMAT_GENERIC_1024_GUID \
+ { 0x43be0b44, 0x874b, 0x4ead, { 0xb0, 0x9c, 0x24, 0x1a, 0x4f, 0xbd, 0x7e, 0xb3 } }
+
+#define EFI_KMS_FORMAT_GENERIC_2048_GUID \
+ { 0x40093f23, 0x630c, 0x4626, { 0x9c, 0x48, 0x40, 0x37, 0x3b, 0x19, 0xcb, 0xbe } }
+
+#define EFI_KMS_FORMAT_GENERIC_3072_GUID \
+ { 0xb9237513, 0x6c44, 0x4411, { 0xa9, 0x90, 0x21, 0xe5, 0x56, 0xe0, 0x5a, 0xde } }
+
+#define EFI_KMS_FORMAT_SHA256_GUID \
+ { 0x6bb4f5cd, 0x8022, 0x448d, { 0xbc, 0x6d, 0x77, 0x1b, 0xae, 0x93, 0x5f, 0xc6 } }
+
+#define EFI_KMS_FORMAT_SHA512_GUID \
+ { 0x2f240e12, 0xe1d4, 0x475c, { 0x83, 0xb0, 0xef, 0xff, 0x22, 0xd7, 0x7b, 0xe7 } }
+
+#define EFI_KMS_FORMAT_AESXTS_128_GUID \
+ { 0x4776e33f, 0xdb47, 0x479a, { 0xa2, 0x5f, 0xa1, 0xcd, 0x0a, 0xfa, 0xb2, 0x8b } }
+
+#define EFI_KMS_FORMAT_AESXTS_256_GUID \
+ { 0xdc7e8613, 0xc4bb, 0x4db0, { 0x84, 0x62, 0x13, 0x51, 0x13, 0x57, 0xab, 0xe2 } }
+
+#define EFI_KMS_FORMAT_AESCBC_128_GUID \
+ { 0xa0e8ee89, 0x0e92, 0x44d4, { 0x86, 0x1b, 0x0e, 0xaa, 0x4a, 0xca, 0x44, 0xa2 } }
+
+#define EFI_KMS_FORMAT_AESCBC_256_GUID \
+ { 0xd7e69789, 0x1f68, 0x45e8, { 0x96, 0xef, 0x3b, 0xe8, 0xbb, 0x17, 0xf8, 0xf9 } }
+
+#define EFI_KMS_FORMAT_RSASHA256_2048_GUID \
+ { 0xa477af13, 0x877d, 0x4060, { 0xba, 0xa1, 0x25, 0xb1, 0xbe, 0xa0, 0x8a, 0xd3 } }
+
+#define EFI_KMS_FORMAT_RSASHA256_3072_GUID \
+ { 0x4e1356c2, 0x0eed, 0x463f, { 0x81, 0x47, 0x99, 0x33, 0xab, 0xdb, 0xc7, 0xd5 } }
+
+#define EFI_KMS_KEY_IDENTIFIER_MAX_SIZE 255
+#define EFI_KMS_KEY_ATTRIBUTE_ID_MAX_SIZE 255
+
+typedef struct {
+ UINT8 KeyIdentifierSize;
+ VOID *KeyIdentifier;
+ EFI_GUID KeyFormat;
+ VOID *KeyValue;
+ EFI_STATUS KeyStatus;
+} EFI_KMS_KEY_DESCRIPTOR;
+
+#define EFI_KMS_ATTRIBUTE_TYPE_NONE 0x00
+#define EFI_KMS_ATTRIBUTE_TYPE_INTEGER 0x01
+#define EFI_KMS_ATTRIBUTE_TYPE_LONG_INTEGER 0x02
+#define EFI_KMS_ATTRIBUTE_TYPE_BIG_INTEGER 0x03
+#define EFI_KMS_ATTRIBUTE_TYPE_ENUMERATION 0x04
+#define EFI_KMS_ATTRIBUTE_TYPE_BOOLEAN 0x05
+#define EFI_KMS_ATTRIBUTE_TYPE_BYTE_STRING 0x06
+#define EFI_KMS_ATTRIBUTE_TYPE_TEXT_STRING 0x07
+#define EFI_KMS_ATTRIBUTE_TYPE_DATE_TIME 0x08
+#define EFI_KMS_ATTRIBUTE_TYPE_INTERVAL 0x09
+#define EFI_KMS_ATTRIBUTE_TYPE_STRUCTURE 0x0a
+#define EFI_KMS_ATTRIBUTE_TYPE_DYNAMIC 0x0b
+
+typedef struct {
+ UINT16 Tag;
+ UINT16 Type;
+ UINT32 Length;
+ UINT8 KeyAttributeData[];
+} EFI_KMS_DYNAMIC_FIELD;
+
+typedef struct {
+ UINT32 FieldCount;
+ EFI_KMS_DYNAMIC_FIELD Field[];
+} EFI_KMS_DYNAMIC_ATTRIBUTE;
+
+typedef struct {
+ UINT8 KeyAttributeIdentifierType;
+ UINT8 KeyAttributeIdentifierCount;
+ VOID *KeyAttributeIdentifier;
+ UINT16 KeyAttributeInstance;
+ UINT16 KeyAttributeType;
+ UINT16 KeyAttributeValueSize;
+ VOID *KeyAttributeValue;
+ EFI_STATUS KeyAttributeStatus;
+} EFI_KMS_KEY_ATTRIBUTE;
+
+INTERFACE_DECL(_EFI_KMS_SERVICE);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_GET_SERVICE_STATUS) (
+ IN struct _EFI_KMS_SERVICE *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_REGISTER_CLIENT) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN OUT UINTN *ClientDataState OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_CREATE_KEY) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN OUT UINT16 *KeyDescriptorCount,
+ IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_GET_KEY) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN OUT UINT16 *KeyDescriptorCount,
+ IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_ADD_KEY) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN OUT UINT16 *KeyDescriptorCount,
+ IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_DELETE_KEY) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN OUT UINT16 *KeyDescriptorCount,
+ IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_GET_KEY_ATTRIBUTES) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN UINT8 *KeyIdentifierSize,
+ IN const VOID *KeyIdentifier,
+ IN OUT UINT16 *KeyAttributesCount,
+ IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_ADD_KEY_ATTRIBUTES) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN UINT8 *KeyIdentifierSize,
+ IN const VOID *KeyIdentifier,
+ IN OUT UINT16 *KeyAttributesCount,
+ IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_DELETE_KEY_ATTRIBUTES) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN UINT8 *KeyIdentifierSize,
+ IN const VOID *KeyIdentifier,
+ IN OUT UINT16 *KeyAttributesCount,
+ IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KMS_GET_KEY_BY_ATTRIBUTES) (
+ IN struct _EFI_KMS_SERVICE *This,
+ IN EFI_KMS_CLIENT_INFO *Client,
+ IN UINTN *KeyAttributeCount,
+ IN OUT EFI_KMS_KEY_ATTRIBUTE *KeyAttributes,
+ IN OUT UINTN *KeyDescriptorCount,
+ IN OUT EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ IN OUT UINTN *ClientDataSize OPTIONAL,
+ IN OUT VOID **ClientData OPTIONAL
+ );
+
+#define EFI_KMS_PROTOCOL_VERSION 0x00020040
+
+typedef struct _EFI_KMS_SERVICE {
+ EFI_KMS_GET_SERVICE_STATUS GetServiceStatus;
+ EFI_KMS_REGISTER_CLIENT RegisterClient;
+ EFI_KMS_CREATE_KEY CreateKey;
+ EFI_KMS_GET_KEY GetKey;
+ EFI_KMS_ADD_KEY AddKey;
+ EFI_KMS_DELETE_KEY DeleteKey;
+ EFI_KMS_GET_KEY_ATTRIBUTES GetKeyAttributes;
+ EFI_KMS_ADD_KEY_ATTRIBUTES AddKeyAttributes;
+ EFI_KMS_DELETE_KEY_ATTRIBUTES DeleteKeyAttributes;
+ EFI_KMS_GET_KEY_BY_ATTRIBUTES GetKeyByAttributes;
+ UINT32 ProtocolVersion;
+ EFI_GUID ServiceId;
+ CHAR16 *ServiceName;
+ UINT32 ServiceVersion;
+ BOOLEAN ServiceAvailable;
+ BOOLEAN ClientIdSupported;
+ BOOLEAN ClientIdRequired;
+ UINT16 ClientIdMaxSize;
+ UINT8 ClientNameStringTypes;
+ BOOLEAN ClientNameRequired;
+ UINT16 ClientNameMaxCount;
+ BOOLEAN ClientDataSupported;
+ UINTN ClientDataMaxSize;
+ BOOLEAN KeyIdVariableLenSupported;
+ UINTN KeyIdMaxSize;
+ UINTN KeyFormatsCount;
+ EFI_GUID *KeyFormats;
+ BOOLEAN KeyAttributesSupported;
+ UINT8 KeyAttributeIdStringTypes;
+ UINT16 KeyAttributeIdMaxCount;
+ UINTN KeyAttributesCount;
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttributes;
+} EFI_KMS_SERVICE;
+
+#endif
Index: stand/efi/include/key_inject.h
===================================================================
--- /dev/null
+++ stand/efi/include/key_inject.h
@@ -0,0 +1,50 @@
+/*-
+ * 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 _KEY_INJECT_H_
+#define _KEY_INJECT_H_
+
+/* Registering a client with the name KERNEL and an ID structure as
+ * shown below sets the injection point for keys into the kernel.
+ */
+#define KERNEL_CLIENT_NAME "KERNEL"
+#define KERNEL_CLIENT_NAME_LEN 6
+
+#define KERNEL_KEY_INJECTOR_GUID \
+ { 0x53badd16, 0x1e9c, 0x493b, { 0x9d, 0x22, 0xe0, 0xab, 0x24, 0xb1, 0xc0, 0x11 } }
+
+extern EFI_KMS_KEY_ATTRIBUTE * const key_attr_service_id_geli;
+extern EFI_KMS_KEY_ATTRIBUTE * const key_attr_service_id_passphrase;
+
+/* Structure used as client ID for the "KERNEL" client */
+typedef struct {
+ void *keybuf;
+ size_t nents;
+} kernel_client_id_t;
+
+#endif
Index: stand/efi/libefi/Makefile
===================================================================
--- stand/efi/libefi/Makefile
+++ stand/efi/libefi/Makefile
@@ -18,6 +18,7 @@
env.c \
errno.c \
handles.c \
+ key_inject.c \
libefi.c \
wchar.c
Index: stand/efi/libefi/key_inject.c
===================================================================
--- /dev/null
+++ stand/efi/libefi/key_inject.c
@@ -0,0 +1,744 @@
+/*-
+ * 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$
+ */
+
+#include <crypto/intake.h>
+#include <efi.h>
+#include <efilib.h>
+#include <efisec.h>
+#include <stdbool.h>
+#include <string.h>
+#include <bootstrap.h>
+
+#include <sys/linker.h>
+
+#include "efi_drivers.h"
+#include "key_inject.h"
+
+#define MAX_KEYS 64
+
+#define KEY_ATTR_SERVICE_ID_NAME "SERVICE_ID"
+#define KEY_ATTR_SERVICE_ID_NAME_LEN 10
+
+enum key_attr_id_t {
+ KEY_ATTR_SERVICE_ID_GELI,
+ KEY_ATTR_SERVICE_ID_PASSPHRASE
+};
+
+/* Tell who provided the key */
+enum service_id_t {
+ SERVICE_ID_NONE,
+ SERVICE_ID_GELI,
+ SERVICE_ID_PASSPHRASE
+};
+
+typedef struct key_entry_t {
+ UINT8 k_id_size;
+ UINT8 k_id[EFI_KMS_KEY_IDENTIFIER_MAX_SIZE];
+ enum service_id_t k_service;
+ EFI_GUID k_format;
+ char k_data[MAX_KEY_BYTES];
+} key_entry_t;
+
+static key_entry_t keys[MAX_KEYS];
+
+static int service_id_geli = SERVICE_ID_GELI;
+static int service_id_passphrase = SERVICE_ID_PASSPHRASE;
+static EFI_GUID Generic128Guid = EFI_KMS_FORMAT_GENERIC_128_GUID;
+static EFI_GUID Generic256Guid = EFI_KMS_FORMAT_GENERIC_256_GUID;
+static EFI_GUID Generic512Guid = EFI_KMS_FORMAT_GENERIC_512_GUID;
+static EFI_GUID Generic1024Guid = EFI_KMS_FORMAT_GENERIC_1024_GUID;
+static EFI_GUID Generic2048Guid = EFI_KMS_FORMAT_GENERIC_2048_GUID;
+static EFI_GUID Generic3072Guid = EFI_KMS_FORMAT_GENERIC_3072_GUID;
+static EFI_GUID AesXts128Guid = EFI_KMS_FORMAT_AESXTS_128_GUID;
+static EFI_GUID AesXts256Guid = EFI_KMS_FORMAT_AESXTS_256_GUID;
+static EFI_GUID AesCbc128Guid = EFI_KMS_FORMAT_AESCBC_128_GUID;
+static EFI_GUID AesCbc256Guid = EFI_KMS_FORMAT_AESCBC_256_GUID;
+static EFI_GUID RsaSha2048Guid = EFI_KMS_FORMAT_RSASHA256_2048_GUID;
+static EFI_GUID RsaSha3072Guid = EFI_KMS_FORMAT_RSASHA256_3072_GUID;
+static EFI_GUID EfiKmsProtocolGuid = EFI_KMS_PROTOCOL;
+static EFI_GUID KernelKeyInjectorGuid = KERNEL_KEY_INJECTOR_GUID;
+
+static EFI_KMS_SERVICE key_inject_kms;
+
+static void
+fill_keybuf(struct keybuf *keybuf)
+{
+ int i, idx;
+
+ for (i = 0, idx = 0; i < MAX_KEYS; i++) {
+ switch (keys[i].k_service) {
+ default:
+ printf("Unknown service type %u\n", keys[i].k_service);
+
+ case SERVICE_ID_PASSPHRASE:
+ case SERVICE_ID_NONE:
+ break;
+
+ case SERVICE_ID_GELI:
+ keybuf->kb_ents[idx].ke_type = KEYBUF_TYPE_GELI;
+ memcpy(keybuf->kb_ents[idx].ke_data, keys[i].k_data,
+ MAX_KEY_BYTES);
+ idx++;
+ break;
+ }
+ }
+
+ keybuf->kb_nents = idx;
+}
+
+static EFI_STATUS EFIAPI
+register_client_impl(EFI_KMS_SERVICE *This, EFI_KMS_CLIENT_INFO *Client,
+ UINTN *ClientDataState __unused, VOID **ClientData __unused)
+{
+ size_t keybuf_size = sizeof(struct keybuf) +
+ (MAX_KEYS * sizeof(struct keybuf_ent));
+ char buf[keybuf_size];
+ struct preloaded_file *kfp;
+
+ /* Spec compliance */
+ if (This == NULL || Client == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if (Client->ClientIdSize != sizeof(struct preloaded_file *)) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ kfp = (struct preloaded_file *)Client->ClientId;
+ fill_keybuf((struct keybuf *)buf);
+ file_addmetadata(kfp, MODINFOMD_KEYBUF, keybuf_size, buf);
+
+ return (EFI_SUCCESS);
+}
+
+/* We don't support secure creation of keys at runtime! */
+static EFI_STATUS EFIAPI
+create_key_impl(EFI_KMS_SERVICE *This __unused,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT16 *KeyDescriptorCount __unused,
+ EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor __unused,
+ UINTN *ClientDataSize __unused, VOID **ClientData __unused)
+{
+ return (EFI_UNSUPPORTED);
+}
+
+static EFI_STATUS
+key_size(const EFI_GUID *format, size_t *size)
+{
+ if (!memcmp(format, &Generic128Guid, sizeof(EFI_GUID))) {
+ *size = 128 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &Generic256Guid, sizeof(EFI_GUID))) {
+ *size = 256 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &Generic512Guid, sizeof(EFI_GUID))) {
+ *size = 512 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &Generic1024Guid, sizeof(EFI_GUID))) {
+ *size = 1024 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &Generic2048Guid, sizeof(EFI_GUID))) {
+ *size = 2048 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &Generic3072Guid, sizeof(EFI_GUID))) {
+ *size = 3072 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &AesXts128Guid, sizeof(EFI_GUID))) {
+ *size = 128 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &AesXts256Guid, sizeof(EFI_GUID))) {
+ *size = 256 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &AesCbc128Guid, sizeof(EFI_GUID))) {
+ *size = 128 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &AesCbc256Guid, sizeof(EFI_GUID))) {
+ *size = 256 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &RsaSha2048Guid, sizeof(EFI_GUID))) {
+ *size = 2048 / 8;
+ return (EFI_SUCCESS);
+ } else if (!memcmp(format, &RsaSha3072Guid, sizeof(EFI_GUID))) {
+ *size = 3072 / 8;
+ return (EFI_SUCCESS);
+ } else {
+ return (EFI_INVALID_PARAMETER);
+ }
+}
+
+static EFI_STATUS
+copy_key(void *dst, const void *src, const EFI_GUID *format)
+{
+ EFI_STATUS status;
+ size_t size;
+
+ status = key_size(format, &size);
+
+ if (EFI_ERROR(status)) {
+ return (status);
+ }
+
+ memcpy(dst, src, size);
+
+ return (EFI_SUCCESS);
+}
+
+static void
+get_one_key(EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor)
+{
+ EFI_STATUS status;
+ int i;
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if (keys[i].k_id_size != 0 &&
+ keys[i].k_id_size == KeyDescriptor->KeyIdentifierSize &&
+ !memcmp(keys[i].k_id, KeyDescriptor->KeyIdentifier,
+ keys[i].k_id_size)) {
+ memcpy(&(KeyDescriptor->KeyFormat), &keys[i].k_format,
+ sizeof(EFI_GUID));
+ status = copy_key(KeyDescriptor->KeyValue,
+ keys[i].k_data, &keys[i].k_format);
+ KeyDescriptor->KeyStatus = status;
+
+ return;
+ }
+ }
+
+ KeyDescriptor->KeyStatus = EFI_NOT_FOUND;
+}
+
+static EFI_STATUS EFIAPI
+get_key_impl(EFI_KMS_SERVICE *This, EFI_KMS_CLIENT_INFO *Client,
+ UINT16 *KeyDescriptorCount, EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor,
+ UINTN *ClientDataSize __unused, VOID **ClientData __unused)
+{
+ int i;
+
+ /* Spec compliance */
+ if (This == NULL || KeyDescriptorCount == NULL ||
+ KeyDescriptor == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for(i = 0; i < *KeyDescriptorCount; i++) {
+ get_one_key(KeyDescriptor + i);
+ }
+
+ return (EFI_SUCCESS);
+}
+
+static void
+add_one_key(EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor)
+{
+ EFI_STATUS status;
+ int i;
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if (keys[i].k_id_size == 0) {
+ keys[i].k_id_size = KeyDescriptor->KeyIdentifierSize;
+ memcpy(keys[i].k_id, KeyDescriptor->KeyIdentifier,
+ keys[i].k_id_size);
+ memcpy(&(keys[i].k_format), &(KeyDescriptor->KeyFormat),
+ sizeof(EFI_GUID));
+ status = copy_key(keys[i].k_data,
+ KeyDescriptor->KeyValue, &(keys[i].k_format));
+ KeyDescriptor->KeyStatus = status;
+
+ return;
+ }
+ }
+
+ KeyDescriptor->KeyStatus = EFI_OUT_OF_RESOURCES;
+}
+
+static EFI_STATUS EFIAPI
+add_key_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT16 *KeyDescriptorCount,
+ EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ int i;
+
+ /* Spec compliance */
+ if (This == NULL || KeyDescriptorCount == NULL ||
+ KeyDescriptor == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for (i = 0; i < *KeyDescriptorCount; i++) {
+ add_one_key(KeyDescriptor + i);
+ }
+
+ return (EFI_SUCCESS);
+}
+
+static void
+delete_one_key(EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor)
+{
+ int i;
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if (keys[i].k_id_size != 0 &&
+ keys[i].k_id_size == KeyDescriptor->KeyIdentifierSize &&
+ !memcmp(keys[i].k_id, KeyDescriptor->KeyIdentifier,
+ keys[i].k_id_size)) {
+ memset(keys + i, 0, sizeof(key_entry_t));
+
+ return;
+ }
+ }
+
+ KeyDescriptor->KeyStatus = EFI_NOT_FOUND;
+}
+
+static EFI_STATUS EFIAPI
+delete_key_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT16 *KeyDescriptorCount,
+ EFI_KMS_KEY_DESCRIPTOR *KeyDescriptor, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ int i;
+
+ /* Spec compliance */
+ if (This == NULL || KeyDescriptorCount == NULL ||
+ KeyDescriptor == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for (i = 0; i < *KeyDescriptorCount; i++) {
+ delete_one_key(KeyDescriptor + i);
+ }
+
+
+ return (EFI_SUCCESS);
+}
+
+static EFI_STATUS EFIAPI
+get_service_status_impl(EFI_KMS_SERVICE *This __unused)
+{
+ return (EFI_SUCCESS);
+}
+
+static void
+do_get_key_attributes(key_entry_t *entry, EFI_KMS_KEY_ATTRIBUTE *KeyAttributes)
+{
+ KeyAttributes[0].KeyAttributeIdentifierType = EFI_KMS_DATA_TYPE_UTF8;
+ KeyAttributes[0].KeyAttributeIdentifierCount =
+ sizeof KEY_ATTR_SERVICE_ID_NAME;
+ KeyAttributes[0].KeyAttributeIdentifier = KEY_ATTR_SERVICE_ID_NAME;
+ KeyAttributes[0].KeyAttributeInstance = 1;
+ KeyAttributes[0].KeyAttributeType = EFI_KMS_ATTRIBUTE_TYPE_INTEGER;
+ KeyAttributes[0].KeyAttributeValueSize = sizeof(int);
+ *((int*)(KeyAttributes[0].KeyAttributeValue)) = entry->k_service;
+ KeyAttributes[0].KeyAttributeStatus = EFI_SUCCESS;
+}
+
+static EFI_STATUS EFIAPI
+get_key_attributes_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT8 *KeyIdentifierSize,
+ const VOID *KeyIdentifier, UINT16 *KeyAttributesCount,
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ UINTN i;
+
+ if (This == NULL || KeyIdentifierSize == NULL ||
+ KeyIdentifier == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ if (*KeyAttributesCount < 1) {
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if (keys[i].k_id_size != 0 &&
+ keys[i].k_id_size == *KeyIdentifierSize &&
+ !memcmp(keys[i].k_id, KeyIdentifier, *KeyIdentifierSize)) {
+ do_get_key_attributes(keys + i, KeyAttributes);
+
+ return (EFI_SUCCESS);
+ }
+ }
+
+ return (EFI_NOT_FOUND);
+}
+
+static void
+do_add_key_attributes(key_entry_t *entry, EFI_KMS_KEY_ATTRIBUTE *KeyAttribute)
+{
+ if (KeyAttribute->KeyAttributeIdentifierCount ==
+ KEY_ATTR_SERVICE_ID_NAME_LEN &&
+ !memcmp(KEY_ATTR_SERVICE_ID_NAME,
+ KeyAttribute->KeyAttributeIdentifier,
+ KEY_ATTR_SERVICE_ID_NAME_LEN)) {
+ entry->k_service = *((int*)(KeyAttribute->KeyAttributeValue));
+ KeyAttribute->KeyAttributeStatus = EFI_SUCCESS;
+ } else {
+ KeyAttribute->KeyAttributeStatus = EFI_INVALID_PARAMETER;
+ }
+}
+
+static EFI_STATUS EFIAPI
+add_key_attributes_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT8 *KeyIdentifierSize,
+ const VOID *KeyIdentifier, UINT16 *KeyAttributesCount,
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ UINTN i, j;
+
+ if (This == NULL || KeyIdentifierSize == NULL ||
+ KeyIdentifier == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if(keys[i].k_id_size != 0 &&
+ keys[i].k_id_size == *KeyIdentifierSize &&
+ !memcmp(keys[i].k_id, KeyIdentifier, *KeyIdentifierSize)) {
+ for (j = 0; j < *KeyAttributesCount; j++) {
+ do_add_key_attributes(keys + i,
+ KeyAttributes + j);
+
+ }
+
+ return (EFI_SUCCESS);
+ }
+ }
+
+ return (EFI_NOT_FOUND);
+}
+
+static void
+do_delete_key_attributes(key_entry_t *entry,
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttribute)
+{
+ if (KeyAttribute->KeyAttributeIdentifierCount ==
+ KEY_ATTR_SERVICE_ID_NAME_LEN &&
+ !memcmp(KEY_ATTR_SERVICE_ID_NAME,
+ KeyAttribute->KeyAttributeIdentifier,
+ KEY_ATTR_SERVICE_ID_NAME_LEN)) {
+ entry->k_service = SERVICE_ID_NONE;
+ KeyAttribute->KeyAttributeStatus = EFI_SUCCESS;
+ } else {
+ KeyAttribute->KeyAttributeStatus = EFI_INVALID_PARAMETER;
+ }
+}
+
+static EFI_STATUS EFIAPI
+delete_key_attributes_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINT8 *KeyIdentifierSize,
+ const VOID *KeyIdentifier, UINT16 *KeyAttributesCount,
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ UINTN i, j;
+
+ if (This == NULL || KeyIdentifierSize == NULL ||
+ KeyIdentifier == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ if(keys[i].k_id_size != 0 &&
+ keys[i].k_id_size == *KeyIdentifierSize &&
+ !memcmp(keys[i].k_id, KeyIdentifier, *KeyIdentifierSize)) {
+ for (j = 0; j < *KeyAttributesCount; j++) {
+ do_delete_key_attributes(keys + i,
+ KeyAttributes + j);
+ }
+
+ return (EFI_SUCCESS);
+ }
+ }
+
+ return (EFI_NOT_FOUND);
+}
+
+static EFI_STATUS
+check_match(key_entry_t *entry, EFI_KMS_KEY_ATTRIBUTE *KeyAttribute,
+ bool *match)
+{
+ if (KeyAttribute->KeyAttributeIdentifierCount ==
+ KEY_ATTR_SERVICE_ID_NAME_LEN &&
+ !memcmp(KEY_ATTR_SERVICE_ID_NAME,
+ KeyAttribute->KeyAttributeIdentifier,
+ KEY_ATTR_SERVICE_ID_NAME_LEN)) {
+ *match = (entry->k_service ==
+ *((int*)(KeyAttribute->KeyAttributeValue)));
+
+ return (EFI_SUCCESS);
+ } else {
+ return (EFI_INVALID_PARAMETER);
+ }
+}
+
+static EFI_STATUS EFIAPI
+get_key_by_attributes_impl(EFI_KMS_SERVICE *This,
+ EFI_KMS_CLIENT_INFO *Client __unused, UINTN *KeyAttributesCount,
+ EFI_KMS_KEY_ATTRIBUTE *KeyAttributes, UINTN *KeyDescriptorCount,
+ EFI_KMS_KEY_DESCRIPTOR *KeyDescriptors, UINTN *ClientDataSize __unused,
+ VOID **ClientData __unused)
+{
+ EFI_STATUS status;
+ UINT8 idxs[MAX_KEYS];
+ UINT8 nmatches = 0;
+ UINTN i, j;
+ bool match;
+
+ if (This == NULL || KeyAttributesCount == NULL ||
+ KeyAttributes == NULL || KeyDescriptorCount == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ for (i = 0; i < MAX_KEYS; i++) {
+ match = true;
+
+ for (j = 0; j < *KeyAttributesCount && match; j++) {
+ status = check_match(keys + i, KeyAttributes + j,
+ &match);
+
+ if (EFI_ERROR(status)) {
+ return (status);
+ }
+ }
+
+ if (match) {
+ idxs[nmatches] = i;
+ nmatches++;
+ }
+ }
+
+ if (nmatches == 0) {
+ return (EFI_NOT_FOUND);
+ }
+
+ if (*KeyDescriptorCount < nmatches) {
+ *KeyDescriptorCount = nmatches;
+
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ if (KeyDescriptors == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ *KeyDescriptorCount = nmatches;
+
+ for (i = 0; i < nmatches; i++) {
+ KeyDescriptors[i].KeyIdentifierSize = keys[idxs[i]].k_id_size;
+ KeyDescriptors[i].KeyIdentifier = keys[idxs[i]].k_id;
+ memcpy(&(KeyDescriptors[i].KeyFormat),
+ &(keys[idxs[i]].k_format), sizeof(EFI_GUID));
+ status = copy_key(KeyDescriptors[i].KeyValue,
+ keys[idxs[i]].k_data, &keys[idxs[i]].k_format);
+ KeyDescriptors[i].KeyStatus = status;
+ }
+
+ return (EFI_SUCCESS);
+}
+
+static void
+register_kms(void)
+{
+ EFI_STATUS status;
+ EFI_HANDLE handle = NULL;
+
+ status = BS->InstallMultipleProtocolInterfaces(&handle,
+ &EfiKmsProtocolGuid, &key_inject_kms, NULL);
+
+ if (EFI_ERROR(status)) {
+ printf("Could not register kernel KMS (%lu)\n",
+ EFI_ERROR_CODE(status));
+ }
+}
+
+static void
+init(void)
+{
+ EFI_HANDLE *handles;
+ EFI_KMS_SERVICE *kms;
+ EFI_STATUS status;
+ UINTN sz;
+ u_int n, nin;
+ bool found;
+
+ /* Try and find an instance of our KMS */
+ sz = 0;
+ handles = NULL;
+ status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid, 0, &sz, 0);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid,
+ 0, &sz, handles);
+
+ if (status == EFI_NOT_FOUND) {
+ /* No handles found, just register our KMS */
+ register_kms();
+
+ return;
+ } else if (EFI_ERROR(status)) {
+ printf("Could not get KMS device handles (%lu)\n",
+ EFI_ERROR_CODE(status));
+ free(handles);
+
+ return;
+ }
+ } else if (status == EFI_NOT_FOUND) {
+ register_kms();
+
+ return;
+ } else {
+ printf("Could not get KMS device handles (%lu)\n",
+ EFI_ERROR_CODE(status));
+
+ return;
+ }
+
+ nin = sz / sizeof(EFI_HANDLE);
+
+ for (n = 0; n < nin && !found; n++) {
+ status = BS->OpenProtocol(handles[n], &KernelKeyInjectorGuid,
+ (void**)&kms, IH, handles[n],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(status)) {
+ printf("Could not open KMS service (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return;
+ }
+
+ if (!memcmp(&KernelKeyInjectorGuid, &(kms->ServiceId),
+ sizeof(EFI_GUID))) {
+ found = true;
+ }
+
+ BS->CloseProtocol(handles[n], &KernelKeyInjectorGuid,
+ IH, handles[n]);
+ }
+
+ free(handles);
+
+ if (!found) {
+ register_kms();
+ }
+}
+
+static CHAR16 kernel_inject_str[] = {
+ 'F', 'r', 'e', 'e', 'B', 'S', 'D', ' ',
+ 'K', 'e', 'r', 'n', 'e', 'l', ' ',
+ 'I', 'n', 'j', 'e', 'c', 't', 'i', 'o', 'n', ' ',
+ 'K', 'M', 'S', '\0'
+};
+
+static EFI_GUID key_formats[] = {
+ EFI_KMS_FORMAT_GENERIC_128_GUID,
+ EFI_KMS_FORMAT_GENERIC_160_GUID,
+ EFI_KMS_FORMAT_GENERIC_256_GUID,
+ EFI_KMS_FORMAT_GENERIC_512_GUID,
+ EFI_KMS_FORMAT_GENERIC_1024_GUID,
+ EFI_KMS_FORMAT_GENERIC_2048_GUID,
+ EFI_KMS_FORMAT_GENERIC_3072_GUID,
+ EFI_KMS_FORMAT_SHA256_GUID,
+ EFI_KMS_FORMAT_SHA512_GUID,
+ EFI_KMS_FORMAT_AESXTS_128_GUID,
+ EFI_KMS_FORMAT_AESXTS_256_GUID,
+ EFI_KMS_FORMAT_AESCBC_128_GUID,
+ EFI_KMS_FORMAT_AESCBC_256_GUID,
+ EFI_KMS_FORMAT_RSASHA256_2048_GUID,
+ EFI_KMS_FORMAT_RSASHA256_3072_GUID
+};
+
+
+static EFI_KMS_KEY_ATTRIBUTE key_attributes[] = {
+ [KEY_ATTR_SERVICE_ID_GELI] = {
+ .KeyAttributeIdentifierType = EFI_KMS_DATA_TYPE_UTF8,
+ .KeyAttributeIdentifierCount = KEY_ATTR_SERVICE_ID_NAME_LEN,
+ .KeyAttributeIdentifier = KEY_ATTR_SERVICE_ID_NAME,
+ .KeyAttributeInstance = 1,
+ .KeyAttributeType = EFI_KMS_ATTRIBUTE_TYPE_INTEGER,
+ .KeyAttributeValueSize = sizeof(int),
+ .KeyAttributeValue = &service_id_geli,
+ },
+ [KEY_ATTR_SERVICE_ID_PASSPHRASE] = {
+ .KeyAttributeIdentifierType = EFI_KMS_DATA_TYPE_UTF8,
+ .KeyAttributeIdentifierCount = KEY_ATTR_SERVICE_ID_NAME_LEN,
+ .KeyAttributeIdentifier = KEY_ATTR_SERVICE_ID_NAME,
+ .KeyAttributeInstance = 2,
+ .KeyAttributeType = EFI_KMS_ATTRIBUTE_TYPE_INTEGER,
+ .KeyAttributeValueSize = sizeof(int),
+ .KeyAttributeValue = &service_id_passphrase,
+ }
+};
+
+EFI_KMS_KEY_ATTRIBUTE * const key_attr_service_id_geli =
+ &(key_attributes[KEY_ATTR_SERVICE_ID_GELI]);
+
+EFI_KMS_KEY_ATTRIBUTE * const key_attr_service_id_passphrase =
+ &(key_attributes[KEY_ATTR_SERVICE_ID_PASSPHRASE]);
+
+static EFI_KMS_SERVICE key_inject_kms = {
+ .GetServiceStatus = get_service_status_impl,
+ .RegisterClient = register_client_impl,
+ .CreateKey = create_key_impl,
+ .GetKey = get_key_impl,
+ .AddKey = add_key_impl,
+ .DeleteKey = delete_key_impl,
+ .GetKeyAttributes = get_key_attributes_impl,
+ .AddKeyAttributes = add_key_attributes_impl,
+ .DeleteKeyAttributes = delete_key_attributes_impl,
+ .GetKeyByAttributes = get_key_by_attributes_impl,
+ .ProtocolVersion = EFI_KMS_PROTOCOL_VERSION,
+ .ServiceId = KERNEL_KEY_INJECTOR_GUID,
+ .ServiceName = kernel_inject_str,
+ .ServiceVersion = 1,
+ .ServiceAvailable = true,
+ .ClientIdSupported = true,
+ .ClientIdRequired = false,
+ .ClientNameStringTypes = EFI_KMS_DATA_TYPE_UTF8,
+ .ClientNameRequired = true,
+ .ClientNameMaxCount = 255,
+ .ClientDataSupported = true,
+ .ClientDataMaxSize = 0xffffffffffffffff,
+ .KeyIdVariableLenSupported = true,
+ .KeyIdMaxSize = EFI_KMS_KEY_IDENTIFIER_MAX_SIZE,
+ .KeyFormatsCount = sizeof key_formats / sizeof key_formats[0],
+ .KeyFormats = key_formats,
+ .KeyAttributesSupported = true,
+ .KeyAttributeIdStringTypes = EFI_KMS_DATA_TYPE_UTF8,
+ .KeyAttributeIdMaxCount = EFI_KMS_KEY_ATTRIBUTE_ID_MAX_SIZE,
+ .KeyAttributesCount = sizeof key_attributes / sizeof key_attributes[0],
+ .KeyAttributes = key_attributes
+};
+
+const efi_driver_t key_inject_driver =
+{
+ .name = "Key Inject KMS",
+ .init = init,
+};
Index: stand/efi/loader/bootinfo.c
===================================================================
--- stand/efi/loader/bootinfo.c
+++ stand/efi/loader/bootinfo.c
@@ -31,6 +31,7 @@
#include <stand.h>
#include <string.h>
+#include <stdbool.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/linker.h>
@@ -42,9 +43,11 @@
#include <efi.h>
#include <efilib.h>
+#include <efisec.h>
#include "bootstrap.h"
#include "loader_efi.h"
+#include "key_inject.h"
#if defined(__amd64__)
#include <machine/specialreg.h>
@@ -59,6 +62,8 @@
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
extern EFI_SYSTEM_TABLE *ST;
+static EFI_GUID EfiKmsProtocolGuid = EFI_KMS_PROTOCOL;
+static EFI_GUID KernelKeyInjectorGuid = KERNEL_KEY_INJECTOR_GUID;
static const char howto_switches[] = "aCdrgDmphsv";
static int howto_masks[] = {
@@ -265,6 +270,76 @@
return (ret);
}
+static void
+key_inject_set_client(struct preloaded_file *kfp)
+{
+ EFI_KMS_CLIENT_INFO client;
+ EFI_KMS_SERVICE *kms;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN sz;
+ u_int n, nin;
+
+ /* Try and find a usable KMS instance */
+ sz = 0;
+ handles = NULL;
+ status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid, 0, &sz, 0);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ handles = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid,
+ 0, &sz, handles);
+ if (EFI_ERROR(status)) {
+ printf("Error getting handles for kernel KMS %lu\n",
+ EFI_ERROR_CODE(status));
+ free(handles);
+ }
+ } else {
+ printf("Error getting handles for kernel KMS %lu\n",
+ EFI_ERROR_CODE(status));
+ return;
+ }
+
+ nin = sz / sizeof(EFI_HANDLE);
+
+ for (n = 0; n < nin; n++) {
+ status = BS->OpenProtocol(handles[n], &EfiKmsProtocolGuid,
+ (void**)&kms, IH, handles[n],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(status)) {
+ printf("Error getting protocol for kernel KMS %lu\n",
+ EFI_ERROR_CODE(status));
+ return;
+ }
+
+
+ if (!memcmp(&KernelKeyInjectorGuid, &(kms->ServiceId),
+ sizeof(EFI_GUID))) {
+ client.ClientIdSize = sizeof(struct preloaded_file *);
+ client.ClientId = kfp;
+ client.ClientNameType = EFI_KMS_DATA_TYPE_UTF8;
+ client.ClientNameCount = strlen(kfp->f_name);
+ client.ClientName = kfp->f_name;
+ status = kms->RegisterClient(kms, &client, NULL, NULL);
+
+ if (EFI_ERROR(status)) {
+ printf("Error registering client for kernel KMS %lu\n",
+ EFI_ERROR_CODE(status));
+ }
+
+ BS->CloseProtocol(handles[n], &EfiKmsProtocolGuid,
+ IH, handles[n]);
+ free(handles);
+
+ return;
+ }
+
+ BS->CloseProtocol(handles[n], &EfiKmsProtocolGuid,
+ IH, handles[n]);
+ }
+}
+
static int
bi_load_efi_data(struct preloaded_file *kfp)
{
@@ -279,6 +354,7 @@
struct efi_map_header *efihdr;
bool do_vmap;
+ key_inject_set_client(kfp);
#if defined(__amd64__) || defined(__aarch64__)
struct efi_fb efifb;
@@ -455,7 +531,7 @@
/* Handle device tree blob */
dtbp = addr;
dtb_size = fdt_copy(addr);
-
+
/* Pad to a page boundary */
if (dtb_size)
addr += roundup(dtb_size, PAGE_SIZE);
@@ -464,8 +540,10 @@
kfp = file_findfile(NULL, "elf kernel");
if (kfp == NULL)
kfp = file_findfile(NULL, "elf64 kernel");
- if (kfp == NULL)
- panic("can't find kernel file");
+
+ if (kfp == NULL)
+ panic("can't find kernel file");
+
kernend = 0; /* fill it in later */
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
Index: stand/efi/loader/conf.c
===================================================================
--- stand/efi/loader/conf.c
+++ stand/efi/loader/conf.c
@@ -35,6 +35,13 @@
#include <libzfs.h>
#endif
+#include "efi_drivers.h"
+
+const efi_driver_t *efi_drivers[] = {
+ &key_inject_driver,
+ NULL
+};
+
struct devsw *devsw[] = {
&efipart_fddev,
&efipart_cddev,
Index: stand/efi/loader/main.c
===================================================================
--- stand/efi/loader/main.c
+++ stand/efi/loader/main.c
@@ -52,6 +52,7 @@
#include "efizfs.h"
#endif
+#include "efi_drivers.h"
#include "loader_efi.h"
extern char bootprog_info[];
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 11:42 PM (1 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28588851
Default Alt Text
D12698.id43475.diff (43 KB)
Attached To
Mode
D12698: Add EFI KMS and keybuf integration
Attached
Detach File
Event Timeline
Log In to Comment