From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1kcUvc-0005kq-5K for mharc-grub-devel@gnu.org; Tue, 10 Nov 2020 09:47:24 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40104) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kcUvZ-0005g3-SL for grub-devel@gnu.org; Tue, 10 Nov 2020 09:47:21 -0500 Received: from 5.mo2.mail-out.ovh.net ([87.98.181.248]:54616) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kcUvX-00036X-E2 for grub-devel@gnu.org; Tue, 10 Nov 2020 09:47:21 -0500 Received: from player770.ha.ovh.net (unknown [10.108.54.237]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 3F5511EBEE8 for ; Tue, 10 Nov 2020 15:47:17 +0100 (CET) Received: from 3mdeb.com (231.85-237-190.tkchopin.pl [85.237.190.231]) (Authenticated sender: krystian.hebel@3mdeb.com) by player770.ha.ovh.net (Postfix) with ESMTPSA id 852F3181EAD0B; Tue, 10 Nov 2020 14:47:14 +0000 (UTC) Authentication-Results: garm.ovh; auth=pass (GARM-97G002b8c03413-c2e6-44cf-a300-d778dd6d46f9, 5ACF1FF395264E632C6C78FAA4B0D4185B0C945F) smtp.auth=krystian.hebel@3mdeb.com From: Krystian Hebel To: grub-devel@gnu.org Cc: Krystian Hebel Subject: [GRUB PATCH RFC 21/22] i386/skinit: Add AMD SKINIT core implementation Date: Tue, 10 Nov 2020 15:44:59 +0100 Message-Id: <20201110144500.31606-22-krystian.hebel@3mdeb.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201110144500.31606-1-krystian.hebel@3mdeb.com> References: <20201110144500.31606-1-krystian.hebel@3mdeb.com> X-Ovh-Tracer-Id: 12102579574866369421 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedruddujedgieelucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvffufffkofgjfhestddtredtredttdenucfhrhhomhepmfhrhihsthhirghnucfjvggsvghluceokhhrhihsthhirghnrdhhvggsvghlseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpeefjeegfeejleefudeitdejhfeklefgleekgfejffehtdduhfeuhefhudduteelleenucffohhmrghinhepghhnuhdrohhrghenucfkpheptddrtddrtddrtddpkeehrddvfeejrdduledtrddvfedunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmohguvgepshhmthhpqdhouhhtpdhhvghlohepphhlrgihvghrjeejtddrhhgrrdhovhhhrdhnvghtpdhinhgvtheptddrtddrtddrtddpmhgrihhlfhhrohhmpehkrhihshhtihgrnhdrhhgvsggvlhesfehmuggvsgdrtghomhdprhgtphhtthhopehgrhhusgdquggvvhgvlhesghhnuhdrohhrgh Received-SPF: pass client-ip=87.98.181.248; envelope-from=krystian.hebel@3mdeb.com; helo=5.mo2.mail-out.ovh.net X-detected-operating-system: by eggs.gnu.org: First seen = 2020/11/10 09:47:17 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Nov 2020 14:47:22 -0000 Signed-off-by: Krystian Hebel --- 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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