已开启
add hygon tpcm support #314
会飞的猫咪创建于 7月27日
add hygon tpcm support #314
已开启
共 2 个文件变更+300-1
| @@ -0,0 +1,295 @@ | |||
| 1 | +From 94f1699682120a0c9235ba8994f520ae37ee6595 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: rpm-build <rpm-build> | ||
| 3 | +Date: Tue, 28 Jul 2026 10:21:35 +0800 | ||
| 4 | +Subject: [PATCH] Add hygon tpcm measure support | ||
| 5 | + | ||
| 6 | +--- | ||
| 7 | + Makefile | 4 +- | ||
| 8 | + hygon_tpcm.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 9 | + hygon_tpcm.h | 46 ++++++++++++++ | ||
| 10 | + shim.c | 16 +++++ | ||
| 11 | + 4 files changed, 234 insertions(+), 2 deletions(-) | ||
| 12 | + create mode 100644 hygon_tpcm.c | ||
| 13 | + create mode 100644 hygon_tpcm.h | ||
| 14 | + | ||
| 15 | +diff --git a/Makefile b/Makefile | ||
| 16 | +index 43213ce..952b97a 100644 | ||
| 17 | +--- a/Makefile | ||
| 18 | ++++ b/Makefile | ||
| 19 | +@@ -41,9 +41,9 @@ endif | ||
| 20 | + ifneq ($(origin ENABLE_SHIM_SM),undefined) | ||
| 21 | + CFLAGS += -DENABLE_SHIM_SM | ||
| 22 | + endif | ||
| 23 | +-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 | ||
| 24 | ++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 hygon_tpcm.o | ||
| 25 | + KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer | ||
| 26 | +-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 | ||
| 27 | ++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 hygon_tpcm.c | ||
| 28 | + MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o | ||
| 29 | + ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h) | ||
| 30 | + FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o | ||
| 31 | +diff --git a/hygon_tpcm.c b/hygon_tpcm.c | ||
| 32 | +new file mode 100644 | ||
| 33 | +index 0000000..3071a9d | ||
| 34 | +--- /dev/null | ||
| 35 | ++++ b/hygon_tpcm.c | ||
| 36 | +@@ -0,0 +1,170 @@ | ||
| 37 | ++/* | ||
| 38 | ++tpcm -- The main function file that implements the tpcm measurement. | ||
| 39 | ++*/ | ||
| 40 | ++ | ||
| 41 | ++#include "hygon_tpcm.h" | ||
| 42 | ++#include "shim.h" | ||
| 43 | ++ | ||
| 44 | ++static EFI_GUID gTpcmInterfaceProtocolGuid = C2PGUID; | ||
| 45 | ++ | ||
| 46 | ++static EFI_HANDLE gC2pHandle = NULL; | ||
| 47 | ++ | ||
| 48 | ++static c2p_protocol_t *gC2pProtocol = NULL; | ||
| 49 | ++ | ||
| 50 | ++static tpcm_stage_t g_measured_id = STAGE_START; | ||
| 51 | ++ | ||
| 52 | ++/* | ||
| 53 | ++ Update g_measured_id +1 every time, g_measured_id will never be decreased. | ||
| 54 | ++ */ | ||
| 55 | ++static void | ||
| 56 | ++update_measured_id(void) | ||
| 57 | ++{ | ||
| 58 | ++ g_measured_id++; | ||
| 59 | ++} | ||
| 60 | ++ | ||
| 61 | ++static tpcm_stage_t | ||
| 62 | ++get_tpcm_stage(void) | ||
| 63 | ++{ | ||
| 64 | ++ tpcm_stage_t stage = STAGE_INVALID; | ||
| 65 | ++ | ||
| 66 | ++ stage = g_measured_id; | ||
| 67 | ++ | ||
| 68 | ++ if (stage < STAGE_START || stage > STAGE_END) | ||
| 69 | ++ stage = STAGE_INVALID; | ||
| 70 | ++ | ||
| 71 | ++ return stage; | ||
| 72 | ++} | ||
| 73 | ++ | ||
| 74 | ++/* | ||
| 75 | ++ check gC2pProtocol exists. | ||
| 76 | ++ */ | ||
| 77 | ++static EFI_STATUS | ||
| 78 | ++tpcm_do_check(EFI_HANDLE image_handle) | ||
| 79 | ++{ | ||
| 80 | ++ EFI_STATUS status; | ||
| 81 | ++ EFI_HANDLE *HandleBuffer = NULL; | ||
| 82 | ++ UINTN NumHandles = 0; | ||
| 83 | ++ | ||
| 84 | ++ // step 1: Search C2P Protocol Handles | ||
| 85 | ++ status = gBS->LocateHandleBuffer(ByProtocol, &gTpcmInterfaceProtocolGuid, | ||
| 86 | ++ NULL, &NumHandles, &HandleBuffer); | ||
| 87 | ++ | ||
| 88 | ++ if (EFI_ERROR(status) || NumHandles == 0) { | ||
| 89 | ++ console_print(L"TPCM: LocateHandleBuffer failed: %r\n", status); | ||
| 90 | ++ return EFI_NOT_FOUND; | ||
| 91 | ++ } | ||
| 92 | ++ | ||
| 93 | ++ gC2pHandle = HandleBuffer[0]; | ||
| 94 | ++ FreePool(HandleBuffer); | ||
| 95 | ++ | ||
| 96 | ++ // step 2: Open the first C2P Protocol | ||
| 97 | ++ status = gBS->OpenProtocol(gC2pHandle, &gTpcmInterfaceProtocolGuid, | ||
| 98 | ++ (VOID **)&gC2pProtocol, image_handle, NULL, | ||
| 99 | ++ EFI_OPEN_PROTOCOL_GET_PROTOCOL); | ||
| 100 | ++ | ||
| 101 | ++ if (EFI_ERROR(status)) { | ||
| 102 | ++ console_print(L"TPCM: OpenProtocol failed: %r\n", status); | ||
| 103 | ++ } | ||
| 104 | ++ | ||
| 105 | ++ return status; | ||
| 106 | ++} | ||
| 107 | ++ | ||
| 108 | ++/* | ||
| 109 | ++ Measure the memery region--(buf, size) through the TPCM protocol. | ||
| 110 | ++ if TPCM protocol is not exist in BIOS, it will return SUCC to keep | ||
| 111 | ++ compatible with non-measurement-support bios; if TPCM protocol is | ||
| 112 | ++ exist but not enabled, it will also return FAIL. | ||
| 113 | ++ */ | ||
| 114 | ++static EFI_STATUS | ||
| 115 | ++tpcm_do_measure(UINT64 buf, UINT32 size, CHAR16 *description) | ||
| 116 | ++{ | ||
| 117 | ++ EFI_STATUS status = EFI_SUCCESS; | ||
| 118 | ++ UINT32 measure_result; | ||
| 119 | ++ UINT32 control_result; | ||
| 120 | ++ tpcm_stage_t stage; | ||
| 121 | ++ struct addr_range range; | ||
| 122 | ++ | ||
| 123 | ++ // check cp2 protocol | ||
| 124 | ++ if (!gC2pProtocol || !gC2pProtocol->verify_raw) { | ||
| 125 | ++ console_print(L"tpcm_measure_efi: Invalid c2p protocol\n"); | ||
| 126 | ++ return EFI_SUCCESS; | ||
| 127 | ++ } | ||
| 128 | ++ | ||
| 129 | ++ // set range addr and len | ||
| 130 | ++ range.start = (UINT64)(UINTN)buf; | ||
| 131 | ++ range.length = (UINT64)size; | ||
| 132 | ++ | ||
| 133 | ++ // set stage | ||
| 134 | ++ stage = get_tpcm_stage(); | ||
| 135 | ++ update_measured_id(); | ||
| 136 | ++ | ||
| 137 | ++ // call verify_raw | ||
| 138 | ++ status = gC2pProtocol->verify_raw(gC2pProtocol, (UINT32)stage, | ||
| 139 | ++ (UINT64)(UINTN)description, | ||
| 140 | ++ (UINT32)(StrLen(description) + 1) * 2, | ||
| 141 | ++ 1, &range, &measure_result, | ||
| 142 | ++ &control_result); | ||
| 143 | ++ | ||
| 144 | ++ // console_print(L"Measurement measure_result:%d control_result:%d\n", measure_result, control_result); | ||
| 145 | ++ if (EFI_ERROR(status)) { | ||
| 146 | ++ console_print(L"verify_raw failed: %r\n", status); | ||
| 147 | ++ } else { | ||
| 148 | ++ console_print(L"tpcm grub measurement succeeded.\n"); | ||
| 149 | ++ } | ||
| 150 | ++ | ||
| 151 | ++ return status; | ||
| 152 | ++} | ||
| 153 | ++ | ||
| 154 | ++static EFI_STATUS | ||
| 155 | ++tpcm_measure_memory(VOID *buf, UINT32 size, CHAR16 *description, | ||
| 156 | ++ EFI_HANDLE image_handle) | ||
| 157 | ++{ | ||
| 158 | ++ EFI_STATUS efi_status = EFI_SUCCESS; | ||
| 159 | ++ BOOLEAN verify_enabled = FALSE; | ||
| 160 | ++ | ||
| 161 | ++ /* step1: check if the tpcm c2p protocol is existed. */ | ||
| 162 | ++ efi_status = tpcm_do_check(image_handle); | ||
| 163 | ++ if (EFI_ERROR(efi_status)) { | ||
| 164 | ++ return EFI_SUCCESS; | ||
| 165 | ++ } | ||
| 166 | ++ console_print(L"get tpcm measure protocol success.\n"); | ||
| 167 | ++ | ||
| 168 | ++ /* step2: check if the tpcm switch is on. */ | ||
| 169 | ++ if (gC2pProtocol && gC2pProtocol->verify_is_enabled) { | ||
| 170 | ++ verify_enabled = gC2pProtocol->verify_is_enabled(gC2pProtocol); | ||
| 171 | ++ } | ||
| 172 | ++ // If the control switch is not turned on, the communication failure does not affect the startup. | ||
| 173 | ++ if (!verify_enabled) { | ||
| 174 | ++ console_print(L"WORNING: tpcm measure control switch is disabled.\n"); | ||
| 175 | ++ efi_status = EFI_SUCCESS; | ||
| 176 | ++ } | ||
| 177 | ++ console_print(L"tpcm measure control switch is enabled.\n"); | ||
| 178 | ++ | ||
| 179 | ++ /* step3: do measure if the tpcm switch is on. */ | ||
| 180 | ++ if (verify_enabled) { | ||
| 181 | ++ efi_status = tpcm_do_measure((UINT64)buf, size, description); | ||
| 182 | ++ } | ||
| 183 | ++ | ||
| 184 | ++ /* step4: close gC2pProtocol */ | ||
| 185 | ++ if (gC2pHandle && gC2pProtocol) { | ||
| 186 | ++ gBS->CloseProtocol(gC2pHandle, &gTpcmInterfaceProtocolGuid, | ||
| 187 | ++ image_handle, NULL); | ||
| 188 | ++ gC2pHandle = NULL; | ||
| 189 | ++ gC2pProtocol = NULL; | ||
| 190 | ++ } | ||
| 191 | ++ | ||
| 192 | ++ return efi_status; | ||
| 193 | ++} | ||
| 194 | ++ | ||
| 195 | ++EFI_STATUS | ||
| 196 | ++tpcm_measure_efi(CHAR16 *ImagePath, VOID *buf, UINT32 size, | ||
| 197 | ++ EFI_HANDLE image_handle) | ||
| 198 | ++{ | ||
| 199 | ++ if (ImagePath == NULL || buf == NULL || size == 0) { | ||
| 200 | ++ perror(L"the parameter passed to tpcm_measure_memory is error!\n"); | ||
| 201 | ++ return EFI_INVALID_PARAMETER; | ||
| 202 | ++ } | ||
| 203 | ++ | ||
| 204 | ++ return tpcm_measure_memory(buf, size, ImagePath, image_handle); | ||
| 205 | ++} | ||
| 206 | ++ | ||
| 207 | +diff --git a/hygon_tpcm.h b/hygon_tpcm.h | ||
| 208 | +new file mode 100644 | ||
| 209 | +index 0000000..2614776 | ||
| 210 | +--- /dev/null | ||
| 211 | ++++ b/hygon_tpcm.h | ||
| 212 | +@@ -0,0 +1,46 @@ | ||
| 213 | ++#ifndef HYGON_SHIM_EFI_TPCM_HEADER | ||
| 214 | ++#define HYGON_SHIM_EFI_TPCM_HEADER 1 | ||
| 215 | ++ | ||
| 216 | ++#include <openssl/bn.h> | ||
| 217 | ++#include <openssl/crypto.h> | ||
| 218 | ++#include <openssl/dh.h> | ||
| 219 | ++#include <openssl/dso.h> | ||
| 220 | ++#include <openssl/err.h> | ||
| 221 | ++#include <openssl/ocsp.h> | ||
| 222 | ++#include <openssl/pkcs12.h> | ||
| 223 | ++#include <openssl/rand.h> | ||
| 224 | ++#include <openssl/rsa.h> | ||
| 225 | ++#include <openssl/ssl.h> | ||
| 226 | ++#include <openssl/x509.h> | ||
| 227 | ++#include <openssl/x509v3.h> | ||
| 228 | ++ | ||
| 229 | ++#include <Library/BaseCryptLib.h> | ||
| 230 | ++ | ||
| 231 | ++#define C2PGUID { 0xf89ab5cd, 0x2829,0x422f, \ | ||
| 232 | ++ { 0xa5, 0xf3, 0x03, 0x28, 0xe0, 0x6c, 0xfc, 0xbb }} | ||
| 233 | ++ | ||
| 234 | ++typedef enum { | ||
| 235 | ++ STAGE_START = 1001, | ||
| 236 | ++ STAGE_END = 1999, | ||
| 237 | ++ STAGE_INVALID = 2000 | ||
| 238 | ++} tpcm_stage_t; | ||
| 239 | ++ | ||
| 240 | ++struct addr_range { | ||
| 241 | ++ UINT64 start; | ||
| 242 | ++ UINT64 length; | ||
| 243 | ++}; | ||
| 244 | ++ | ||
| 245 | ++struct c2p_protocol { | ||
| 246 | ++ EFI_STATUS (EFIAPI *verify_raw)(struct c2p_protocol *this, | ||
| 247 | ++ UINT32 measure_stage, UINT64 image_info, | ||
| 248 | ++ UINT32 image_info_size, UINT32 num_addr_range, | ||
| 249 | ++ struct addr_range ranges[], | ||
| 250 | ++ UINT32 *measure_result, | ||
| 251 | ++ UINT32 *control_result); | ||
| 252 | ++ BOOLEAN (EFIAPI *verify_is_enabled)(struct c2p_protocol *this); | ||
| 253 | ++}; | ||
| 254 | ++typedef struct c2p_protocol c2p_protocol_t; | ||
| 255 | ++ | ||
| 256 | ++EFI_STATUS tpcm_measure_efi(CHAR16 *context, VOID *buf, UINT32 size, | ||
| 257 | ++ EFI_HANDLE image_handle); | ||
| 258 | ++#endif | ||
| 259 | +diff --git a/shim.c b/shim.c | ||
| 260 | +index aa74610..87fd2d5 100644 | ||
| 261 | +--- a/shim.c | ||
| 262 | ++++ b/shim.c | ||
| 263 | +@@ -33,6 +33,9 @@ | ||
| 264 | + | ||
| 265 | + #include <stdint.h> | ||
| 266 | + #include "tpcm.h" | ||
| 267 | ++#ifdef __x86_64__ | ||
| 268 | ++#include "hygon_tpcm.h" | ||
| 269 | ++#endif | ||
| 270 | + #define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2" | ||
| 271 | + | ||
| 272 | + static EFI_SYSTEM_TABLE *systab; | ||
| 273 | +@@ -1256,6 +1259,19 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) | ||
| 274 | + goto restore; | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | ++#ifdef __x86_64__ | ||
| 278 | ++ /* | ||
| 279 | ++ * measure the image binary by the tpcm | ||
| 280 | ++ */ | ||
| 281 | ++ efi_status = tpcm_measure_efi(ImagePath, data, datasize, image_handle); | ||
| 282 | ++ if (EFI_ERROR(efi_status)) { | ||
| 283 | ++ perror(L"Failed to measure %s by tpcm: %r\n", ImagePath, efi_status); | ||
| 284 | ++ PrintErrors(); | ||
| 285 | ++ ClearErrors(); | ||
| 286 | ++ goto restore; | ||
| 287 | ++ } | ||
| 288 | ++#endif | ||
| 289 | ++ | ||
| 290 | + /* | ||
| 291 | + * Verify and, if appropriate, relocate and execute the executable | ||
| 292 | + */ | ||
| 293 | +-- | ||
| 294 | +2.43.0 | ||
| 295 | + | ||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | Name: shim | 26 | Name: shim |
| 27 | Version: 15.7 | 27 | Version: 15.7 |
| 28 | -Release: 23 | 28 | +Release: 24 |
| 29 | Summary: First-stage UEFI bootloader | 29 | Summary: First-stage UEFI bootloader |
| 30 | ExclusiveArch: x86_64 aarch64 | 30 | ExclusiveArch: x86_64 aarch64 |
| 31 | License: BSD | 31 | License: BSD |
| @@ -75,6 +75,7 @@ Patch9003:Feature-shim-cryptlib-support-sm2-signature-verify.patch | |||
| 75 | Patch9004:Feature-shim-support-sm2-and-sm3-algorithm.patch | 75 | Patch9004:Feature-shim-support-sm2-and-sm3-algorithm.patch |
| 76 | # Feature for shim TPCM support | 76 | # Feature for shim TPCM support |
| 77 | Patch9005:Feature-add-tpcm-support-with-ipmi-channel.patch | 77 | Patch9005:Feature-add-tpcm-support-with-ipmi-channel.patch |
| 78 | +Patch9006:Feature-add-hygon-tpcm-measure-support.patch | ||
| 78 | 79 | ||
| 79 | BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc vim-common efivar-devel | 80 | BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc vim-common efivar-devel |
| 80 | 81 | ||
| @@ -227,6 +228,9 @@ make test | |||
| 227 | /usr/src/debug/%{name}-%{version}-%{release}/* | 228 | /usr/src/debug/%{name}-%{version}-%{release}/* |
| 228 | 229 | ||
| 229 | %changelog | 230 | %changelog |
| 231 | +* Tue Jul 28 2026 jinlun <xueguanteng@hygon.cn> - 15.7-24 | ||
| 232 | +- add hygon tpcm support | ||
| 233 | + | ||
| 230 | * Wed Jun 17 2026 fly_fzc <2385803914@qq.com> - 15.7-23 | 234 | * Wed Jun 17 2026 fly_fzc <2385803914@qq.com> - 15.7-23 |
| 231 | - Fix CVE-2026-7383 CVE-2026-34180 CVE-2026-45447 | 235 | - Fix CVE-2026-7383 CVE-2026-34180 CVE-2026-45447 |
| 232 | 236 | ||