From 9f79b8e6cd1d105f01778f92b387c405c784da68 Mon Sep 17 00:00:00 2001 From: jinlun Date: Tue, 11 Jun 2024 14:51:24 +0800 Subject: [PATCH] Synchronize the code to be consistent with 22.03-LTS-SP3 --- ...e-add-tpcm-support-with-ipmi-channel.patch | 706 ++++++++++++++++++ shim.spec | 20 +- 2 files changed, 725 insertions(+), 1 deletion(-) create mode 100644 Feature-add-tpcm-support-with-ipmi-channel.patch diff --git a/Feature-add-tpcm-support-with-ipmi-channel.patch b/Feature-add-tpcm-support-with-ipmi-channel.patch new file mode 100644 index 0000000..8601945 --- /dev/null +++ b/Feature-add-tpcm-support-with-ipmi-channel.patch @@ -0,0 +1,706 @@ +From 1dc5fe582bca752d2bafd6496132c63fa72b5e53 Mon Sep 17 00:00:00 2001 +From: jinlun +Date: Tue, 21 Nov 2023 14:43:26 +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 9b8d7e8..b619f78 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 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 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 ++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 tpcm.h + 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 400bd9a..c90c1a5 100644 +--- a/shim.c ++++ b/shim.c +@@ -32,7 +32,7 @@ + #include + + #include +- ++#include "tpcm.h" + #define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2" + + static EFI_SYSTEM_TABLE *systab; +@@ -1227,6 +1227,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..42fcc2f +--- /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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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.27.0 + diff --git a/shim.spec b/shim.spec index 26ac261..eabc3ce 100644 --- a/shim.spec +++ b/shim.spec @@ -25,7 +25,7 @@ Name: shim Version: 15.6 -Release: 20 +Release: 23 Summary: First-stage UEFI bootloader ExclusiveArch: x86_64 aarch64 License: BSD @@ -95,6 +95,9 @@ Patch9002:Feature-shim-openssl-add-sm2-and-sm3-support.patch Patch9003:Feature-shim-cryptlib-support-sm2-signature-verify.patch Patch9004:Feature-shim-support-sm2-and-sm3-algorithm.patch +# Feature for shim TPCM support +Patch9005:Feature-add-tpcm-support-with-ipmi-channel.patch + BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc vim-common efivar-devel %if 0%{?openEuler_sign_rsa} @@ -190,6 +193,12 @@ install -m 0700 %{SOURCE1} ${RPM_BUILD_ROOT}/%{shimefivendor} install -m 0700 %{SOURCE2} ${RPM_BUILD_ROOT}/%{shimefivendor} %endif +%if "%{_vendor}" != "openEuler" + iconv -f UTF-16LE -t UTF-8 ${RPM_BUILD_ROOT}/%{shimefivendor}/%{bootcsv} > /tmp/%{bootcsv}.tmp + sed -i -e 's/openeuler/%{_vendor}/g' -e 's/openEuler/%{_vendor}/g' /tmp/%{bootcsv}.tmp + iconv -f UTF-8 -t UTF-16LE /tmp/%{bootcsv}.tmp > ${RPM_BUILD_ROOT}/%{shimefivendor}/%{bootcsv} +%endif + # install the debug symbols install -d ${RPM_BUILD_ROOT}/usr/lib/debug/%{shimefivendor} install -m 644 fb%{efi_arch}.efi.debug ${RPM_BUILD_ROOT}/usr/lib/debug/%{shimefivendor} @@ -221,6 +230,15 @@ make test /usr/src/debug/%{name}-%{version}-%{release}/* %changelog +* Tue May 7 2024 jinlun - 15.6-23 +- Fix the TPCM feature issue + +* Tue Apr 23 2024 lijuzhang - 15.6-22 +- replace vendor for BOOTX64.CSV or BOOTAA64.CSV + +* Tue Apr 23 2024 jinlun - 15.6-21 +- add tpcm support with ipmi channel + * Tue Mar 26 2024 yixiangzhike - 15.6-20 - backport patch from upstream -- Gitee