加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Feature-add-tpcm-support-with-ipmi-channel.patch 24.42 KB
一键复制 编辑 原始数据 按行查看 历史
jinlun 提交于 2024-02-05 10:46 . add tpcm support with ipmi channel
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
From ba0b864ac8cf562f94796da99b9c0d1f55f8ee09 Mon Sep 17 00:00:00 2001
From: jinlun <jinlun@huawei.com>
Date: Mon, 5 Feb 2024 10:59:30 +0800
Subject: [PATCH] add tpcm support with ipmi channel
---
Makefile | 4 +-
shim.c | 13 +-
tpcm.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
tpcm.h | 202 ++++++++++++++++++++++++++
4 files changed, 644 insertions(+), 3 deletions(-)
create mode 100644 tpcm.c
create mode 100644 tpcm.h
diff --git a/Makefile b/Makefile
index 81cefba..43213ce 100644
--- a/Makefile
+++ b/Makefile
@@ -41,9 +41,9 @@ endif
ifneq ($(origin ENABLE_SHIM_SM),undefined)
CFLAGS += -DENABLE_SHIM_SM
endif
-OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o
+OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o tpcm.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
-ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
+ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S tpcm.c
MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o
ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o
diff --git a/shim.c b/shim.c
index b60cf15..547b052 100644
--- a/shim.c
+++ b/shim.c
@@ -32,7 +32,7 @@
#include <Library/BaseCryptLib.h>
#include <stdint.h>
-
+#include "tpcm.h"
#define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2"
static EFI_SYSTEM_TABLE *systab;
@@ -1245,6 +1245,17 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
goto restore;
}
+ /*
+ * measure the grub binary by the tpcm
+ */
+ efi_status = tpcm_measure_grub(ImagePath, data, datasize, image_handle);
+ if (EFI_ERROR(efi_status)) {
+ perror(L"Failed to measure the grub by tpcm: %r\n", efi_status);
+ PrintErrors();
+ ClearErrors();
+ goto restore;
+ }
+
/*
* Verify and, if appropriate, relocate and execute the executable
*/
diff --git a/tpcm.c b/tpcm.c
new file mode 100644
index 0000000..a086620
--- /dev/null
+++ b/tpcm.c
@@ -0,0 +1,428 @@
+/*
+ tpcm -- The main function file that implements the tpcm measurement.
+*/
+
+#include "tpcm.h"
+#include "shim.h"
+
+#define TRANS(value) \
+ ((((UINT32)(value) << 24) & 0xFF000000) | (((UINT32)(value) << 8) & 0x00FF0000) | \
+ (((UINT32)(value) >> 8) & 0x0000FF00) | (((UINT32)(value) >> 24) & 0x000000FF))
+
+#define WAIT_TIME_UNIT 200
+
+static EFI_GUID hash2_service_binding_guid = SHIM_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID;
+static EFI_GUID hash2_guid = SHIM_EFI_HASH2_PROTOCOL_GUID;
+static EFI_GUID sm3_guid = SHIM_HASH_ALGORITHM_SM3_GUID;
+static EFI_GUID gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID;
+
+static UINT8 oemSignature[OEM_SIG_SIZE] = {0xDB, 0x07, 0x00};
+
+static shim_efi_ipmi_interface_protocol_t *tpcm_ipmi;
+static UINT32 bm_stage_base = 1500;
+
+static void tpcm_dump_hex(const CHAR16 *name, void *p, int bytes)
+{
+ int i = 0;
+ unsigned char *data = p;
+ int add_newline = 1;
+
+ console_print(L"%s length=%d:\n", name, bytes);
+ while (i < bytes) {
+ console_print(L"%02x ", (unsigned char)data[i]);
+ i++;
+ if (i % 16 == 0) {
+ console_print(L"\n");
+ add_newline = 0;
+ } else {
+ add_newline = 1;
+ }
+ }
+ if (add_newline) {
+ console_print(L"\n");
+ }
+}
+
+static EFI_STATUS tpcm_get_response_blocked(void)
+{
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_GET_RESULT_REQUSET get_result_request_data;
+ OEM_BMC_GET_RESULT_RESPONSE get_result_response_data;
+ UINT16 timeout_ms = SHIM_IPMI_TIMEOUT_MS;
+ UINT8 response_length;
+ EFI_STATUS efi_status;
+
+ memset(&get_result_request_data, 0, sizeof(get_result_request_data));
+ memset(&get_result_response_data, 0, sizeof(get_result_response_data));
+
+ get_result_request_data.OemSignature[0] = oemSignature[0];
+ get_result_request_data.OemSignature[1] = oemSignature[1];
+ get_result_request_data.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ get_result_request_data.SubCmd = IPMI_SUB_CMD_CONTROL_REQ;
+ get_result_request_data.FirmwareType = IPMI_FW_SHIM_GRUB;
+ get_result_request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+
+ // Polling for 7 seconds
+ while (timeout_ms > 0) {
+ response_length = sizeof(OEM_BMC_GET_RESULT_RESPONSE);
+ msleep(WAIT_TIME_UNIT);
+ timeout_ms -= WAIT_TIME_UNIT;
+
+ console_print(L"get result request: request_size[%d], response_length[%d]\n",
+ sizeof(get_result_request_data), response_length);
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &get_result_request_data,
+ sizeof(get_result_request_data), &get_result_response_data, &response_length, NULL);
+ console_print(L"OemSignature iana = [ 0x%X %X %X ], ControlResult = %d\n",
+ get_result_response_data.OemSignature[0],
+ get_result_response_data.OemSignature[1],
+ get_result_response_data.OemSignature[OEM_SIG_SIZE - 1],
+ get_result_response_data.ControlResult);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"EFI : attempt to get measurement result failed, ret=%d\n", efi_status);
+ continue;
+ }
+ if (response_length == sizeof(OEM_BMC_GET_RESULT_RESPONSE) &&
+ get_result_response_data.ControlResult != IPMI_MEASURE_UNKNOW) {
+ console_print(L"ipmi protocol: get tpcm measurement result success\n");
+ break;
+ }
+ }
+
+ if (get_result_response_data.ControlResult == IPMI_MEASURE_SUCCESS) {
+ efi_status = EFI_SUCCESS;
+ } else {
+ efi_status = EFI_INVALID_PARAMETER;
+ console_print(L"Error: the tpcm measurement result does not pass, and the startup is rejected");
+ }
+
+ return efi_status;
+}
+
+static void wide_char_to_multi_byte(CHAR16 *description, UINT8 *filename, UINT32 *filename_len)
+{
+ UINT8 *str = (UINT8 *)description;
+ UINT32 len = *filename_len;
+ UINT32 i;
+ *filename_len = 0;
+ for (i = 0; i < len; i++) {
+ if (str[i] == 0 || str[i] == '\\') {
+ continue;
+ }
+ filename[*filename_len] = str[i];
+ (*filename_len)++;
+ }
+ filename[*filename_len] = '\0';
+}
+
+static EFI_STATUS tpcm_fillup_hash_content(OEM_BMC_MEASURE_REQUSET *request_data, unsigned char *content,
+ CHAR16 *description)
+{
+ UINT32 filename_len = StrLen(description) * 2 + 1;
+ UINT32 stage_base = bm_stage_base++;
+ UINT8 filename[FIRMWARE_NAME_SIZE] = {0};
+
+ if (filename_len > FIRMWARE_NAME_SIZE) {
+ console_print(L"the path strings is pass the size of FirmwareHashContent.uaObj!\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ wide_char_to_multi_byte(description, filename, &filename_len);
+ console_print(L"start filling the hash content.\n");
+ request_data->FirmwareHashContent.uiCmdTag = TRANS(TPCM_TAG_REQ_COMMAND);
+ request_data->FirmwareHashContent.uiCmdLength = TRANS(sizeof(extern_simple_bmeasure_req_st));
+ request_data->FirmwareHashContent.uiCmdCode = TRANS(TPCM_ORD_ExternSimpleBootMeasure);
+ request_data->FirmwareHashContent.uiPcr = TRANS(0);
+
+ request_data->FirmwareHashContent.uiStage = TRANS(stage_base);
+
+ memcpy((UINT8 *)(request_data->FirmwareHashContent.uaDigest), content, DEFAULT_HASH_SIZE);
+ request_data->FirmwareHashContent.uiObjLen = TRANS(filename_len);
+
+ memcpy((UINT8 *)(request_data->FirmwareHashContent.uaObj), filename, filename_len);
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS tpcm_send_request(unsigned char *content, CHAR16 *description)
+{
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_MEASURE_REQUSET request_data;
+ OEM_BMC_MEASURE_RESPONSE response_data;
+ UINT8 response_length = sizeof(OEM_BMC_MEASURE_RESPONSE);
+ UINT8 cmd_len = sizeof(extern_simple_bmeasure_req_st);
+
+ memset(&request_data, 0, sizeof(request_data));
+ memset(&response_data, 0, sizeof(response_data));
+
+ request_data.OemSignature[0] = oemSignature[0];
+ request_data.OemSignature[1] = oemSignature[1];
+ request_data.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ request_data.SubCmd = IPMI_SUB_CMD_MEASURE_REQ;
+ request_data.FirmwareType = IPMI_FW_SHIM_GRUB;
+ request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+ request_data.FirmwareHashAlgorithmType = SM3_HASH;
+ request_data.FirmwareHashLen = cmd_len;
+
+ /* filling the hash content of request data */
+ efi_status = tpcm_fillup_hash_content(&request_data, content, description);
+ if (efi_status != EFI_SUCCESS) {
+ goto out;
+ }
+ console_print(L"sizeof(request_data)=%d\n", sizeof(request_data));
+
+ /* send the hash request to tpcm chips by ipmi */
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &request_data, (UINT8)sizeof(OEM_BMC_MEASURE_REQUSET),
+ &response_data, &response_length, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"ipmi protocol: excute_ipmi_cmd send request failed.\n");
+ goto out;
+ }
+ console_print(L"ipmi protocol: send tpcm measure request success\n");
+
+out:
+ return efi_status;
+}
+
+static EFI_HANDLE tpcm_efi_service_binding(EFI_GUID *service_binding_guid)
+{
+ EFI_STATUS efi_status;
+ EFI_SERVICE_BINDING *service = NULL;
+ EFI_HANDLE child_dev = NULL;
+
+ efi_status = LibLocateProtocol(service_binding_guid, (VOID **)&service);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"LibLocateProtocol failed\n");
+ return NULL;
+ }
+ if (!service) {
+ console_print(L"couldn't open efi service binding protocol\n");
+ return NULL;
+ }
+ efi_status = service->CreateChild(service, &child_dev);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"Failed to create child device of http service %x\n", efi_status);
+ return NULL;
+ }
+
+ return child_dev;
+}
+
+static EFI_STATUS tpcm_efi_hash2(shim_efi_hash2_protocol_t *hash2, unsigned char *buf, size_t size,
+ unsigned char *output)
+{
+ EFI_STATUS efi_status;
+
+ if (!hash2->hash_init || !hash2->hash_update || !hash2->hash_final) {
+ efi_status = EFI_INVALID_PARAMETER;
+ console_print(L"the functions of hash2 has NULL!\n");
+ goto out;
+ }
+ efi_status = hash2->hash_init(hash2, &sm3_guid);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_init failed.\n");
+ goto out;
+ }
+ efi_status = hash2->hash_update(hash2, buf, size);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_update failed.\n");
+ goto out;
+ }
+ efi_status = hash2->hash_final(hash2, (shim_efi_hash2_output *)output);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"hash_final failed.\n");
+ goto out;
+ }
+
+out:
+ return efi_status;
+}
+
+static EFI_STATUS tpcm_get_hash(unsigned char *buf, size_t size, EFI_HANDLE image_handle, unsigned char *content)
+{
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_efi_hash2_protocol_t *hash2 = NULL;
+ EFI_HANDLE hash_handle = NULL;
+ unsigned char output[DEFAULT_HASH_SIZE] = {0};
+
+ console_print(L"tpcm_get_hash start binding service.\n");
+ hash_handle = tpcm_efi_service_binding(&hash2_service_binding_guid);
+ if (!hash_handle) {
+ console_print(L"hash2 service binding failed.\n");
+ efi_status = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ console_print(L"tpcm_get_hash binding service success.\n");
+
+ efi_status = gBS->OpenProtocol(
+ hash_handle, &hash2_guid, (VOID **)&hash2, image_handle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"tpcm_get_hash: gBS->OpenProtocol fail\n");
+ goto out;
+ }
+ if (!hash2) {
+ console_print(L"hash2 protocol open failed.\n");
+ efi_status = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ console_print(L"tpcm_get_hash get protocol success.\n");
+
+ efi_status = tpcm_efi_hash2(hash2, buf, size, output);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_efi_hash2 failed.\n");
+ goto out;
+ }
+
+ tpcm_dump_hex(L"tpcm BIOS hash output: ", output, DEFAULT_HASH_SIZE);
+ memcpy(content, output, DEFAULT_HASH_SIZE);
+
+out:
+ return efi_status;
+}
+
+static EFI_STATUS tpcm_do_measure(unsigned char *buf, size_t size, CHAR16 *description, EFI_HANDLE image_handle)
+{
+ EFI_STATUS efi_status;
+ unsigned char content[DEFAULT_HASH_SIZE] = {0};
+
+ /* step1: get the hash of grub */
+ efi_status = tpcm_get_hash(buf, size, image_handle, content);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"get firmware hash content failed\n");
+ goto out;
+ }
+
+ /* step2: send the measure request to tpcm */
+ efi_status = tpcm_send_request(content, description);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_send_request send request failed\n");
+ goto out;
+ }
+
+ /* step3: get the result of measure request */
+ efi_status = tpcm_get_response_blocked();
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"tpcm_get_response_blocked get result failed\n");
+ goto out;
+ }
+
+out:
+ return efi_status;
+}
+
+static void tpcm_get_switch(int *control_flag, int *measure_flag)
+{
+ UINT8 response_length;
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ shim_ipmi_cmd_header request = {IPMI_BMC_LUN, IPMI_NETFN_OEM, IPMI_CMD_GET_MEASURE_PARM};
+ OEM_BMC_GET_RESULT_REQUSET get_tpcm_request_value;
+ OEM_BMC_GET_RESULT_RESPONSE get_tpcm_response_value;
+
+ memset(&get_tpcm_request_value, 0, sizeof(get_tpcm_request_value));
+ memset(&get_tpcm_response_value, 0, sizeof(get_tpcm_response_value));
+
+ get_tpcm_request_value.OemSignature[0] = oemSignature[0];
+ get_tpcm_request_value.OemSignature[1] = oemSignature[1];
+ get_tpcm_request_value.OemSignature[OEM_SIG_SIZE - 1] = oemSignature[OEM_SIG_SIZE - 1];
+ get_tpcm_request_value.SubCmd = IPMI_SUB_CMD_SWITCH_REQ;
+ get_tpcm_request_value.FirmwareType = IPMI_FW_OS;
+ get_tpcm_request_value.FirmwareDetailType = IPMI_FW_DETAIL_GRUB;
+ response_length = sizeof(OEM_BMC_GET_RESULT_RESPONSE);
+
+ if (!tpcm_ipmi->excute_ipmi_cmd) {
+ console_print(L"tpcm_ipmi->excute_ipmi_cmd is NULL, some error may occur below shim!\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ return;
+ }
+ efi_status = tpcm_ipmi->excute_ipmi_cmd(tpcm_ipmi, request, &get_tpcm_request_value, sizeof(get_tpcm_request_value),
+ &get_tpcm_response_value, &response_length, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_print(L"ipmi get tpcm switch failed.\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ return;
+ }
+
+ switch (get_tpcm_response_value.ControlResult) {
+ case IPMI_SWITCH_MEASURE_ENABLE_CONTROL_ENABLE:
+ *control_flag = 1;
+ *measure_flag = 1;
+ break;
+ case IPMI_SWITCH_MEASURE_ENABLE_CONTROL_DISABLE:
+ *control_flag = 0;
+ *measure_flag = 1;
+ break;
+ case IPMI_SWITCH_CLOSE:
+ case IPMI_SWITCH_UNKNOW:
+ default:
+ console_print(L"tpcm switch close, skip measure.\n");
+ *control_flag = 0;
+ *measure_flag = 0;
+ break;
+ }
+
+ return;
+}
+
+static EFI_STATUS tpcm_check_ipmi(void)
+{
+ EFI_STATUS efi_status;
+
+ efi_status = LibLocateProtocol(&gIpmiInterfaceProtocolGuid, (VOID **)&tpcm_ipmi);
+ if (EFI_ERROR(efi_status)) {
+ console_print(L"tpcm is not support.");
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!tpcm_ipmi) {
+ console_print(L"Error: tpcm_ipmi is NULL");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS tpcm_ipmi_measure(unsigned char *buf, size_t size, void *description, EFI_HANDLE image_handle)
+{
+ EFI_STATUS efi_status;
+ int control_flag, measure_flag;
+
+ /* step1: check if the tpcm chips is existed. */
+ efi_status = tpcm_check_ipmi();
+ if (EFI_ERROR(efi_status)) {
+ return EFI_SUCCESS;
+ }
+
+ /* step2: check if the tpcm switch is on. */
+ efi_status = EFI_SUCCESS;
+ tpcm_get_switch(&control_flag, &measure_flag);
+
+ /* step3: do measure if the tpcm switch is on. */
+ if (measure_flag) {
+ efi_status = tpcm_do_measure(buf, size, description, image_handle);
+ }
+ // If the control switch is not turned on, the communication failure does not affect the startup.
+ if (!control_flag && EFI_ERROR(efi_status)) {
+ console_print(L"WORNING: control switch disable, The tpcm_do_measure() fail doesn't affect the startup.\n");
+ efi_status = EFI_SUCCESS;
+ }
+
+ return efi_status;
+}
+
+EFI_STATUS
+tpcm_measure_grub(void *context, unsigned char *buf, size_t size, EFI_HANDLE image_handle)
+{
+ if (context == NULL || buf == NULL || size == 0) {
+ perror(L"the parameter passed to tpcm_measure_grub is error!\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (StrCmp((CHAR16 *)context, DEFAULT_LOADER)) {
+ console_print(L"only grub is measured by tpcm, not for FALLBACK and MOK_MANAGER.\n");
+ return EFI_SUCCESS;
+ }
+
+ return tpcm_ipmi_measure(buf, size, context, image_handle);
+}
+
diff --git a/tpcm.h b/tpcm.h
new file mode 100644
index 0000000..606c824
--- /dev/null
+++ b/tpcm.h
@@ -0,0 +1,202 @@
+#ifndef SHIM_EFI_TPCM_HEADER
+#define SHIM_EFI_TPCM_HEADER 1
+
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/ocsp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/rsa.h>
+#include <openssl/dso.h>
+
+#include <Library/BaseCryptLib.h>
+
+#define EFI_TPCM_GUID \
+ { \
+ 0xa37e200e, 0xda90, 0x473b, \
+ { \
+ 0x8b, 0xb5, 0x1d, 0x7b, 0x11, 0xba, 0x32, 0x33 \
+ } \
+ }
+#define SHIM_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0xda836f8d, 0x217f, 0x4ca0, \
+ { \
+ 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea \
+ } \
+ }
+#define SHIM_EFI_HASH2_PROTOCOL_GUID \
+ { \
+ 0x55b1d734, 0xc5e1, 0x49db, \
+ { \
+ 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b \
+ } \
+ }
+#define SHIM_HASH_ALGORITHM_SM3_GUID \
+ { \
+ 0x9DCD754B, 0x3479, 0x27AD, \
+ { \
+ 0x56, 0x4C, 0x68, 0x7C, 0x68, 0xEC, 0xF9, 0xB9 \
+ } \
+ }
+
+#define OEM_SIG_SIZE 3
+#define FIRMWARE_VERSION_SIZE 32
+#define FIRMWARE_HASH_CONYENT_SIZE 32
+#define FIRMWARE_NAME_SIZE 32
+#define SHIM_IPMI_TIMEOUT_MS 2000
+
+#define IPMI_BMC_LUN 0x00
+/* Net Function Definition */
+#define IPMI_NETFN_OEM 0x30
+
+#define IPMI_CMD_GET_MEASURE_PARM 0x92 // change a name
+
+#define IPMI_SUB_CMD_MEASURE_REQ 0x57 // change a name
+#define IPMI_SUB_CMD_CONTROL_REQ 0x58
+#define IPMI_SUB_CMD_SWITCH_REQ 0x59
+
+#define DEFAULT_HASH_SIZE 32
+#define MEASURE_DATA_MEM_SIZE 0x100000
+
+#define TPCM_TAG_REQ_COMMAND 0x000000C1
+#define TPCM_ORD_ExternSimpleBootMeasure 0x00001053
+
+typedef struct {
+ UINT32 uiCmdTag;
+ UINT32 uiCmdLength;
+ UINT32 uiCmdCode;
+ UINT32 uiPcr;
+ UINT32 uiStage;
+ UINT8 uaDigest[DEFAULT_HASH_SIZE];
+ UINT32 uiObjLen;
+ UINT8 uaObj[FIRMWARE_NAME_SIZE];
+} extern_simple_bmeasure_req_st;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 SubCmd;
+ UINT8 FirmwareType;
+ UINT8 FirmwareDetailType;
+ UINT8 FirmwareHashAlgorithmType;
+ UINT8 FirmwareHashLen;
+ extern_simple_bmeasure_req_st FirmwareHashContent;
+ UINT8 FirmwareVerionLen;
+ UINT8 FirmwareVerion[FIRMWARE_VERSION_SIZE];
+} OEM_BMC_MEASURE_REQUSET;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 OemSignature[OEM_SIG_SIZE];
+} OEM_BMC_MEASURE_RESPONSE;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 SubCmd;
+ UINT8 FirmwareType;
+ UINT8 FirmwareDetailType;
+} OEM_BMC_GET_RESULT_REQUSET;
+
+typedef struct {
+ UINT8 OemSignature[OEM_SIG_SIZE];
+ UINT8 ControlResult;
+} OEM_BMC_GET_RESULT_RESPONSE;
+
+typedef enum {
+ IPMI_SYSTEM_INTERFACE_UNKNOWN, // IPMI_SYSTEM_INTERFACE_TYPE->UNKNOWN
+ IPMI_SYSTEM_INTERFACE_KCS,
+ IPMI_SYSTEM_INTERFACE_SMIC,
+ IPMI_SYSTEM_INTERFACE_BT, // IPMI_SYSTEM_INTERFACE_TYPE->BT
+ IPMI_SYSTEM_INTERFACE_SSIF,
+ IPMI_SYSTEM_INTERFACE_MAX_TYPE // IPMI_SYSTEM_INTERFACE_TYPE->MAX_TYPE
+} shim_ipmi_system_interface_type;
+
+typedef struct {
+ UINT8 lun : 2;
+ UINT8 net_fn : 6;
+ UINT8 cmd;
+} shim_ipmi_cmd_header;
+
+typedef enum {
+ IPMI_MEMORY,
+ IPMI_IO,
+ IPMI_MAX_INTERFACE_ADDRESS_TYPE
+} shim_ipmi_interface_address_type;
+
+typedef enum {
+ IPMI_FW_SHIM,
+ IPMI_FW_SHIM_GRUB,
+ IPMI_FW_OS
+} shim_ipmi_firmware_type;
+
+typedef enum {
+ IPMI_FW_DETAIL_GRUB,
+ RESERVED1,
+ RESERVED2
+} shim_ipmi_firmware_detail_type;
+
+typedef enum {
+ SM3_HASH,
+ HASH_RESERVED1,
+ HASH_RESERVED2
+} shim_ipmi_firmware_hash_type;
+
+typedef enum {
+ IPMI_MEASURE_UNKNOW,
+ IPMI_MEASURE_SUCCESS,
+ IPMI_MEASURE_FAIL
+} shim_ipmi_measure_result_type;
+
+typedef enum {
+ IPMI_SWITCH_UNKNOW,
+ IPMI_SWITCH_MEASURE_ENABLE_CONTROL_ENABLE,
+ IPMI_SWITCH_CLOSE,
+ IPMI_SWITCH_MEASURE_ENABLE_CONTROL_DISABLE
+} shim_ipmi_get_switch_result_type;
+
+typedef union {
+ UINT8 Md5Hash[16];
+ UINT8 Sha1Hash[20];
+ UINT8 Sha224Hash[28];
+ UINT8 Sha256Hash[32];
+ UINT8 Sha384Hash[48];
+ UINT8 Sha512Hash[64];
+ UINT8 Sm3Hash[32];
+} shim_efi_hash2_output;
+
+struct shim_efi_hash2_protocol {
+ EFI_STATUS (*get_hash_size)(struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm, UINT64 hash_size);
+
+ EFI_STATUS (*hash)
+ (struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm, UINT8 *message, UINT64 message_size,
+ shim_efi_hash2_output *hash);
+
+ EFI_STATUS (*hash_init)(struct shim_efi_hash2_protocol *this, EFI_GUID *hash_algorithm);
+
+ EFI_STATUS (*hash_update)(struct shim_efi_hash2_protocol *this, UINT8 *message, UINT64 message_size);
+
+ EFI_STATUS (*hash_final)(struct shim_efi_hash2_protocol *this, shim_efi_hash2_output *hash);
+};
+
+typedef struct shim_efi_hash2_protocol shim_efi_hash2_protocol_t;
+
+struct shim_efi_ipmi_interface_protocol {
+ EFI_STATUS (*excute_ipmi_cmd)
+ (struct shim_efi_ipmi_interface_protocol *this, shim_ipmi_cmd_header request, void *send_data, UINT8 send_length,
+ void *recv_data, UINT8 *recv_length, UINT16 *status_codes);
+ shim_ipmi_system_interface_type (*get_ipmi_interface_type)(struct shim_efi_ipmi_interface_protocol *this);
+ UINT16 (*get_ipmi_base_address)(struct shim_efi_ipmi_interface_protocol *this);
+ shim_ipmi_interface_address_type (*get_ipmi_base_address_type)(struct shim_efi_ipmi_interface_protocol *this);
+ UINT8 (*get_ipmi_version)(struct shim_efi_ipmi_interface_protocol *this);
+};
+
+typedef struct shim_efi_ipmi_interface_protocol shim_efi_ipmi_interface_protocol_t;
+
+EFI_STATUS tpcm_measure_grub(void *context, unsigned char *buf, size_t size, EFI_HANDLE image_handle);
+
+#endif
--
2.33.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化