[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GRUB PATCH RFC 21/22] i386/skinit: Add AMD SKINIT core implementation
From: |
Krystian Hebel |
Subject: |
[GRUB PATCH RFC 21/22] i386/skinit: Add AMD SKINIT core implementation |
Date: |
Tue, 10 Nov 2020 15:44:59 +0100 |
Signed-off-by: Krystian Hebel <krystian.hebel@3mdeb.com>
---
grub-core/loader/i386/skinit.c | 162 +++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
create mode 100644 grub-core/loader/i386/skinit.c
diff --git a/grub-core/loader/i386/skinit.c b/grub-core/loader/i386/skinit.c
new file mode 100644
index 000000000000..0090102aae40
--- /dev/null
+++ b/grub-core/loader/i386/skinit.c
@@ -0,0 +1,162 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/memory.h>
+#include <grub/normal.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/i386/skinit.h>
+#include <grub/i386/tpm.h>
+#include <grub/crypto.h>
+
+#define LZ_TAG_CLASS_MASK 0xF0
+
+/* Tags with no particular class */
+#define LZ_TAG_NO_CLASS 0x00
+#define LZ_TAG_END 0x00
+#define LZ_TAG_UNAWARE_OS 0x01
+#define LZ_TAG_TAGS_SIZE 0x0F /* Always first */
+
+/* Tags specifying kernel type */
+#define LZ_TAG_BOOT_CLASS 0x10
+#define LZ_TAG_BOOT_LINUX 0x10
+#define LZ_TAG_BOOT_MB2 0x11
+
+/* Tags specific to TPM event log */
+#define LZ_TAG_EVENT_LOG_CLASS 0x20
+#define LZ_TAG_EVENT_LOG 0x20
+#define LZ_TAG_LZ_HASH 0x21
+
+struct lz_tag_hdr {
+ grub_uint8_t type;
+ grub_uint8_t len;
+} __attribute__ (( packed ));
+
+struct lz_tag_tags_size {
+ struct lz_tag_hdr hdr;
+ grub_uint16_t size;
+} __attribute__ (( packed ));
+
+struct lz_tag_boot_linux {
+ struct lz_tag_hdr hdr;
+ grub_uint32_t zero_page;
+} __attribute__ (( packed ));
+
+struct lz_tag_boot_mb2 {
+ struct lz_tag_hdr hdr;
+ grub_uint32_t mbi;
+ grub_uint32_t kernel_entry;
+ grub_uint32_t kernel_size;
+} __attribute__ (( packed ));
+
+struct lz_tag_evtlog {
+ struct lz_tag_hdr hdr;
+ grub_uint32_t address;
+ grub_uint32_t size;
+} __attribute__ (( packed ));
+
+struct lz_tag_hash {
+ struct lz_tag_hdr hdr;
+ grub_uint16_t algo_id;
+ grub_uint8_t digest[];
+} __attribute__ (( packed ));
+
+static inline struct lz_tag_tags_size *get_bootloader_data_addr (
+ struct grub_slaunch_params *slparams)
+{
+ return (struct lz_tag_tags_size *)(slparams->lz_base + slparams->lz_size);
+}
+
+static inline void *next_tag(struct lz_tag_tags_size *tags)
+{
+ return (void *)(((grub_uint8_t *)tags) + tags->size);
+}
+
+grub_err_t
+grub_skinit_boot_prepare (struct grub_slaunch_params *slparams)
+{
+ void *lz_base = (void *)(grub_addr_t) slparams->lz_base;
+ grub_memset (lz_base, 0, GRUB_SKINIT_SLB_SIZE);
+ grub_memcpy (lz_base, grub_slaunch_module(), slparams->lz_size);
+
+ struct lz_tag_tags_size *tags = get_bootloader_data_addr (slparams);
+ grub_uint32_t *apic = (grub_uint32_t *)0xfee00300ULL;
+
+ /* Tags header */
+ tags->hdr.type = LZ_TAG_TAGS_SIZE;
+ tags->hdr.len = sizeof(struct lz_tag_tags_size);
+ tags->size = sizeof(struct lz_tag_tags_size);
+
+ /* Hashes of LZ */
+ {
+ grub_uint8_t buff[GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE]; /* SHA1 ctx is
smaller */
+ struct lz_tag_hash *h = next_tag(tags);
+ h->hdr.type = LZ_TAG_LZ_HASH;
+ h->hdr.len = sizeof(struct lz_tag_hash) + GRUB_MD_SHA256->mdlen;
+ h->algo_id = 0x000B;
+ GRUB_MD_SHA256->init(buff);
+ GRUB_MD_SHA256->write(buff, lz_base, slparams->lz_size);
+ GRUB_MD_SHA256->final(buff);
+ grub_memcpy(h->digest, GRUB_MD_SHA256->read(buff), GRUB_MD_SHA256->mdlen);
+ tags->size += h->hdr.len;
+
+ h = next_tag(tags);
+ h->hdr.type = LZ_TAG_LZ_HASH;
+ h->hdr.len = sizeof(struct lz_tag_hash) + GRUB_MD_SHA1->mdlen;
+ h->algo_id = 0x0004;
+ GRUB_MD_SHA1->init(buff);
+ GRUB_MD_SHA1->write(buff, lz_base, slparams->lz_size);
+ GRUB_MD_SHA1->final(buff);
+ grub_memcpy(h->digest, GRUB_MD_SHA1->read(buff), GRUB_MD_SHA1->mdlen);
+ tags->size += h->hdr.len;
+ }
+
+ /* Boot protocol data */
+ struct lz_tag_boot_linux *b = next_tag(tags);
+ b->hdr.type = LZ_TAG_BOOT_LINUX;
+ b->hdr.len = sizeof(struct lz_tag_boot_linux);
+ b->zero_page = (grub_uint32_t)slparams->params;
+ tags->size += b->hdr.len;
+
+ if (slparams->tpm_evt_log_size != 0) {
+ struct lz_tag_evtlog *e = next_tag(tags);
+ e->hdr.type = LZ_TAG_EVENT_LOG;
+ e->hdr.len = sizeof(struct lz_tag_evtlog);
+ e->address = slparams->tpm_evt_log_base;
+ e->size = slparams->tpm_evt_log_size;
+ tags->size += e->hdr.len;
+ }
+
+ /* Mark end of tags */
+ struct lz_tag_hdr *end = next_tag(tags);
+ end->type = LZ_TAG_END;
+ end->len = sizeof(struct lz_tag_hdr);
+ tags->size += end->len;
+
+ grub_dprintf ("slaunch", "broadcasting INIT\r\n");
+ *apic = 0x000c0500; // INIT, all excluding self
+ grub_dprintf ("slaunch", "grub_tpm_relinquish_lcl\r\n");
+ grub_tpm_relinquish_lcl (0);
+
+ grub_dprintf("slaunch", "Invoke SKINIT\r\n");
+
+ return GRUB_ERR_NONE;
+}
--
2.17.1
- [GRUB PATCH RFC 10/22] efi: Return grub_efi_status_t from grub_efi_get_variable(), (continued)
- [GRUB PATCH RFC 10/22] efi: Return grub_efi_status_t from grub_efi_get_variable(), Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 11/22] efi: Add a function to read EFI variables with attributes, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 15/22] i386/txt: Add Intel TXT core implementation, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 17/22] i386/txt: Add Intel TXT verification routines, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 16/22] i386/txt: Add Intel TXT ACM module support, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 14/22] i386/txt: Add Intel TXT definitions header file, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 13/22] i386/slaunch: Add basic platform support for secure launch, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 18/22] i386/slaunch: Add secure launch framework and commands, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 19/22] i386/slaunch: Add code for searching for DRTM event log in ACPI, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 20/22] i386/skinit: Add AMD SKINIT definitions header file, Krystian Hebel, 2020/11/10
- [GRUB PATCH RFC 21/22] i386/skinit: Add AMD SKINIT core implementation,
Krystian Hebel <=
- [GRUB PATCH RFC 22/22] i386/slaunch: Add support for AMD SKINIT, Krystian Hebel, 2020/11/10
- Re: [GRUB RFC PATCH 00/22] i386: Intel TXT and AMD SKINIT secure launcher, Konrad Rzeszutek Wilk, 2020/11/10