From e1f5fc87be6581b63550218d991c713ad0f23113 Mon Sep 17 00:00:00 2001
From: Huaxin Lu <luhuaxin1@huawei.com>
Date: Mon, 7 Nov 2022 11:47:42 +0800
Subject: [PATCH 2/2] shim support sm2 and sm3 algorithm

Co-authored-by: Yusong Gao <gaoyusong2@huawei.com>
Signed-off-by: Yusong Gao <gaoyusong2@huawei.com>
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
---
 Makefile          |   5 ++-
 MokManager.c      |   8 ++++
 include/pe.h      |   7 ++++
 include/peimage.h |   3 ++
 pe.c              | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 shim.c            |  74 ++++++++++++++++++++++++++++++++--
 shim.h            |  20 ++++++++++
 7 files changed, 212 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 24ac314..9b8d7e8 100644
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT
 else
 TARGETS += $(MMNAME) $(FBNAME)
 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
 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
@@ -163,7 +166,7 @@ Cryptlib/libcryptlib.a:
 	$(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile
 
 Cryptlib/OpenSSL/libopenssl.a:
-	for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done
+	for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes ec sm3 sm2 ecdsa; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done
 	$(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib/OpenSSL -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile
 
 lib/lib.a: | $(TOPDIR)/lib/Makefile $(wildcard $(TOPDIR)/include/*.[ch])
diff --git a/MokManager.c b/MokManager.c
index ffcd6a6..8b7fd4b 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1910,6 +1910,9 @@ static EFI_STATUS enroll_file(void *data, UINTN datasize, BOOLEAN hash)
 	if (hash) {
 		UINT8 sha256[SHA256_DIGEST_SIZE];
 		UINT8 sha1[SHA1_DIGEST_SIZE];
+#ifdef ENABLE_SHIM_SM
+		UINT8 sm3[SM3_DIGEST_SIZE];
+#endif
 		SHIM_LOCK *shim_lock;
 		PE_COFF_LOADER_IMAGE_CONTEXT context;
 
@@ -1929,8 +1932,13 @@ static EFI_STATUS enroll_file(void *data, UINTN datasize, BOOLEAN hash)
 		if (EFI_ERROR(efi_status))
 			goto out;
 
+#ifdef ENABLE_SHIM_SM
+		efi_status = shim_lock->Hash(data, datasize, &context, sha256,
+					     sha1, sm3);
+#else
 		efi_status = shim_lock->Hash(data, datasize, &context, sha256,
 					     sha1);
+#endif
 		if (EFI_ERROR(efi_status))
 			goto out;
 
diff --git a/include/pe.h b/include/pe.h
index ccc8798..93af091 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -28,10 +28,17 @@ handle_image (void *data, unsigned int datasize,
 	      EFI_PHYSICAL_ADDRESS *alloc_address,
 	      UINTN *alloc_pages);
 
+#ifdef ENABLE_SHIM_SM
+EFI_STATUS
+generate_hash (char *data, unsigned int datasize,
+	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
+	       UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash);
+#else
 EFI_STATUS
 generate_hash (char *data, unsigned int datasize,
 	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
 	       UINT8 *sha256hash, UINT8 *sha1hash);
+#endif
 
 EFI_STATUS
 relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
diff --git a/include/peimage.h b/include/peimage.h
index e97b29c..7a4f356 100644
--- a/include/peimage.h
+++ b/include/peimage.h
@@ -807,6 +807,9 @@ typedef struct {
 
 #define SHA1_DIGEST_SIZE	20
 #define SHA256_DIGEST_SIZE	32
+#ifdef ENABLE_SHIM_SM
+#define SM3_DIGEST_SIZE	32
+#endif
 #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
 
 typedef struct {
diff --git a/pe.c b/pe.c
index ba3e2bb..f48d635 100644
--- a/pe.c
+++ b/pe.c
@@ -297,13 +297,24 @@ get_section_vma_by_name (char *name, size_t namesz,
  * Calculate the SHA1 and SHA256 hashes of a binary
  */
 
+#ifdef ENABLE_SHIM_SM
+EFI_STATUS
+generate_hash(char *data, unsigned int datasize,
+	      PE_COFF_LOADER_IMAGE_CONTEXT *context, UINT8 *sha256hash,
+	      UINT8 *sha1hash, UINT8 *sm3hash)
+#else
 EFI_STATUS
 generate_hash(char *data, unsigned int datasize,
 	      PE_COFF_LOADER_IMAGE_CONTEXT *context, UINT8 *sha256hash,
 	      UINT8 *sha1hash)
+#endif
 {
 	unsigned int sha256ctxsize, sha1ctxsize;
 	void *sha256ctx = NULL, *sha1ctx = NULL;
+#ifdef ENABLE_SHIM_SM
+	unsigned int sm3ctxsize;
+	void *sm3ctx = NULL;
+#endif
 	char *hashbase;
 	unsigned int hashsize;
 	unsigned int SumOfBytesHashed, SumOfSectionBytes;
@@ -327,12 +338,25 @@ generate_hash(char *data, unsigned int datasize,
 	sha1ctxsize = Sha1GetContextSize();
 	sha1ctx = AllocatePool(sha1ctxsize);
 
+#ifdef ENABLE_SHIM_SM
+	sm3ctxsize = Sm3GetContextSize();
+	sm3ctx = AllocatePool(sm3ctxsize);
+#endif
+
+#ifdef ENABLE_SHIM_SM
+	if (!sha256ctx || !sha1ctx || !sm3ctx) {
+#else
 	if (!sha256ctx || !sha1ctx) {
+#endif
 		perror(L"Unable to allocate memory for hash context\n");
 		return EFI_OUT_OF_RESOURCES;
 	}
 
+#ifdef ENABLE_SHIM_SM
+	if (!Sha256Init(sha256ctx) || !Sha1Init(sha1ctx) || !Sm3Init(sm3ctx)) {
+#else
 	if (!Sha256Init(sha256ctx) || !Sha1Init(sha1ctx)) {
+#endif
 		perror(L"Unable to initialise hash\n");
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto done;
@@ -344,8 +368,14 @@ generate_hash(char *data, unsigned int datasize,
 		hashbase;
 	check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+	    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+	    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 	    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 		perror(L"Unable to generate hash\n");
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto done;
@@ -357,8 +387,14 @@ generate_hash(char *data, unsigned int datasize,
 	hashsize = (char *)context->SecDir - hashbase;
 	check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+	    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+	    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 	    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 		perror(L"Unable to generate hash\n");
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto done;
@@ -375,8 +411,14 @@ generate_hash(char *data, unsigned int datasize,
 	}
 	check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+	    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+	    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 	    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 		perror(L"Unable to generate hash\n");
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto done;
@@ -505,8 +547,14 @@ generate_hash(char *data, unsigned int datasize,
 		hashsize  = (unsigned int) Section->SizeOfRawData;
 		check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+		    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+		    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 		    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 			perror(L"Unable to generate hash\n");
 			efi_status = EFI_OUT_OF_RESOURCES;
 			goto done;
@@ -531,8 +579,14 @@ generate_hash(char *data, unsigned int datasize,
 		}
 		check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+		    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+		    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 		    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 			perror(L"Unable to generate hash\n");
 			efi_status = EFI_OUT_OF_RESOURCES;
 			goto done;
@@ -551,8 +605,14 @@ generate_hash(char *data, unsigned int datasize,
 
 		check_size(data, datasize, hashbase, hashsize);
 
+#ifdef ENABLE_SHIM_SM
+		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+		    !(Sha1Update(sha1ctx, hashbase, hashsize)) ||
+		    !(Sm3Update(sm3ctx, hashbase, hashsize))) {
+#else
 		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
 		    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+#endif
 			perror(L"Unable to generate hash\n");
 			efi_status = EFI_OUT_OF_RESOURCES;
 			goto done;
@@ -562,8 +622,14 @@ generate_hash(char *data, unsigned int datasize,
 	}
 #endif
 
+#ifdef ENABLE_SHIM_SM
+	if (!(Sha256Final(sha256ctx, sha256hash)) ||
+	    !(Sha1Final(sha1ctx, sha1hash)) ||
+	    !(Sm3Final(sm3ctx, sm3hash))) {
+#else
 	if (!(Sha256Final(sha256ctx, sha256hash)) ||
 	    !(Sha1Final(sha1ctx, sha1hash))) {
+#endif
 		perror(L"Unable to finalise hash\n");
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto done;
@@ -573,6 +639,10 @@ generate_hash(char *data, unsigned int datasize,
 	dhexdumpat(sha1hash, SHA1_DIGEST_SIZE, 0);
 	dprint(L"sha256 authenticode hash:\n");
 	dhexdumpat(sha256hash, SHA256_DIGEST_SIZE, 0);
+#ifdef ENABLE_SHIM_SM
+	dprint(L"sm3 authenticode hash:\n");
+	dhexdumpat(sm3hash, SM3_DIGEST_SIZE, 0);
+#endif
 
 done:
 	if (SectionHeader)
@@ -581,6 +651,10 @@ done:
 		FreePool(sha1ctx);
 	if (sha256ctx)
 		FreePool(sha256ctx);
+#ifdef ENABLE_SHIM_SM
+	if (sm3ctx)
+		FreePool(sm3ctx);
+#endif
 
 	return efi_status;
 }
@@ -1027,6 +1101,9 @@ EFI_STATUS verify_image(void *data, unsigned int datasize,
 	EFI_STATUS efi_status;
 	UINT8 sha1hash[SHA1_DIGEST_SIZE];
 	UINT8 sha256hash[SHA256_DIGEST_SIZE];
+#ifdef ENABLE_SHIM_SM
+	UINT8 sm3hash[SHA256_DIGEST_SIZE];
+#endif
 
 	/*
 	 * The binary header contains relevant context and section pointers
@@ -1042,8 +1119,13 @@ EFI_STATUS verify_image(void *data, unsigned int datasize,
 	 * in order to load it.
 	 */
 	if (secure_mode()) {
+#ifdef ENABLE_SHIM_SM
+		efi_status = verify_buffer(data, datasize,
+					   context, sha256hash, sha1hash, sm3hash);
+#else
 		efi_status = verify_buffer(data, datasize,
 					   context, sha256hash, sha1hash);
+#endif
 		if (EFI_ERROR(efi_status)) {
 			if (verbose)
 				console_print(L"Verification failed: %r\n", efi_status);
@@ -1061,8 +1143,13 @@ EFI_STATUS verify_image(void *data, unsigned int datasize,
 	 *  this is only useful for the TPM1.2 case. We should try to fix
 	 *  this in a follow-up.
 	 */
+#ifdef ENABLE_SHIM_SM
+	efi_status = generate_hash(data, datasize, context, sha256hash,
+				   sha1hash, sm3hash);
+#else
 	efi_status = generate_hash(data, datasize, context, sha256hash,
 				   sha1hash);
+#endif
 	if (EFI_ERROR(efi_status))
 		return efi_status;
 
@@ -1103,6 +1190,9 @@ handle_image (void *data, unsigned int datasize,
 	int found_entry_point = 0;
 	UINT8 sha1hash[SHA1_DIGEST_SIZE];
 	UINT8 sha256hash[SHA256_DIGEST_SIZE];
+#ifdef ENABLE_SHIM_SM
+	UINT8 sm3hash[SM3_DIGEST_SIZE];
+#endif
 
 	/*
 	 * The binary header contains relevant context and section pointers
@@ -1118,8 +1208,13 @@ handle_image (void *data, unsigned int datasize,
 	 * in order to load it.
 	 */
 	if (secure_mode ()) {
+#ifdef ENABLE_SHIM_SM
+		efi_status = verify_buffer(data, datasize, &context, sha256hash,
+					   sha1hash, sm3hash);
+#else
 		efi_status = verify_buffer(data, datasize, &context, sha256hash,
 					   sha1hash);
+#endif
 
 		if (EFI_ERROR(efi_status)) {
 			if (verbose)
@@ -1140,8 +1235,13 @@ handle_image (void *data, unsigned int datasize,
 	 *  this is only useful for the TPM1.2 case. We should try to fix
 	 *  this in a follow-up.
 	 */
+#ifdef ENABLE_SHIM_SM
+	efi_status = generate_hash(data, datasize, &context, sha256hash,
+				   sha1hash, sm3hash);
+#else
 	efi_status = generate_hash(data, datasize, &context, sha256hash,
 				   sha1hash);
+#endif
 	if (EFI_ERROR(efi_status))
 		return efi_status;
 
diff --git a/shim.c b/shim.c
index fdd205e..400bd9a 100644
--- a/shim.c
+++ b/shim.c
@@ -458,11 +458,20 @@ BOOLEAN secure_mode (void)
 	return TRUE;
 }
 
+#ifdef ENABLE_SHIM_SM
+static EFI_STATUS
+verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
+		     UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash)
+#else
 static EFI_STATUS
 verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
 		     UINT8 *sha256hash, UINT8 *sha1hash)
+#endif
 {
 	EFI_STATUS efi_status;
+#ifdef ENABLE_SHIM_SM
+	sm3hash = sm3hash;
+#endif
 
 	/*
 	 * Ensure that the binary isn't forbidden
@@ -532,11 +541,17 @@ verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
 	if (vendor_cert_size) {
 		dprint("verifying against vendor_cert\n");
 	}
+#ifdef ENABLE_SHIM_SM
 	if (vendor_cert_size &&
-	    AuthenticodeVerify(sig->CertData,
-			       sig->Hdr.dwLength - sizeof(sig->Hdr),
-			       vendor_cert, vendor_cert_size,
-			       sha256hash, SHA256_DIGEST_SIZE)) {
+	    (AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr),
+							vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE) ||
+	     AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr),
+							vendor_cert, vendor_cert_size, sm3hash, SM3_DIGEST_SIZE))) {
+#else
+	if (vendor_cert_size &&
+	    (AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr),
+							vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE))) {
+#endif
 		dprint(L"AuthenticodeVerify(vendor_cert) succeeded\n");
 		update_verification_method(VERIFIED_BY_CERT);
 		tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
@@ -558,10 +573,17 @@ verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
 /*
  * Check that the signature is valid and matches the binary
  */
+#ifdef ENABLE_SHIM_SM
+EFI_STATUS
+verify_buffer_authenticode (char *data, int datasize,
+			    PE_COFF_LOADER_IMAGE_CONTEXT *context,
+			    UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash)
+#else
 EFI_STATUS
 verify_buffer_authenticode (char *data, int datasize,
 			    PE_COFF_LOADER_IMAGE_CONTEXT *context,
 			    UINT8 *sha256hash, UINT8 *sha1hash)
+#endif
 {
 	EFI_STATUS ret_efi_status;
 	size_t size = datasize;
@@ -578,7 +600,12 @@ verify_buffer_authenticode (char *data, int datasize,
 	 */
 	drain_openssl_errors();
 
+#ifdef ENABLE_SHIM_SM
+	ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash, sm3hash);
+#else
 	ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash);
+#endif
+
 	if (EFI_ERROR(ret_efi_status)) {
 		dprint(L"generate_hash: %r\n", ret_efi_status);
 		PrintErrors();
@@ -665,7 +692,11 @@ verify_buffer_authenticode (char *data, int datasize,
 
 			dprint(L"Attempting to verify signature %d:\n", i++);
 
+#ifdef ENABLE_SHIM_SM
+			efi_status = verify_one_signature(sig, sha256hash, sha1hash, sm3hash);
+#else
 			efi_status = verify_one_signature(sig, sha256hash, sha1hash);
+#endif
 
 			/*
 			 * If we didn't get EFI_SECURITY_VIOLATION from
@@ -746,10 +777,17 @@ verify_buffer_sbat (char *data, int datasize,
  * Check that the signature is valid and matches the binary and that
  * the binary is permitted to load by SBAT.
  */
+#ifdef ENABLE_SHIM_SM
+EFI_STATUS
+verify_buffer (char *data, int datasize,
+	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
+	       UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash)
+#else
 EFI_STATUS
 verify_buffer (char *data, int datasize,
 	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
 	       UINT8 *sha256hash, UINT8 *sha1hash)
+#endif
 {
 	EFI_STATUS efi_status;
 
@@ -757,7 +795,11 @@ verify_buffer (char *data, int datasize,
 	if (EFI_ERROR(efi_status))
 		return efi_status;
 
+#ifdef ENABLE_SHIM_SM
+	return verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash, sm3hash);
+#else
 	return verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash);
+#endif
 }
 
 static int
@@ -970,6 +1012,9 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size)
 	PE_COFF_LOADER_IMAGE_CONTEXT context;
 	UINT8 sha1hash[SHA1_DIGEST_SIZE];
 	UINT8 sha256hash[SHA256_DIGEST_SIZE];
+#ifdef ENABLE_SHIM_SM
+	UINT8 sm3hash[SM3_DIGEST_SIZE];
+#endif
 
 	if ((INT32)size < 0)
 		return EFI_INVALID_PARAMETER;
@@ -981,8 +1026,13 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size)
 	if (EFI_ERROR(efi_status))
 		goto done;
 
+#ifdef ENABLE_SHIM_SM
+	efi_status = generate_hash(buffer, size, &context,
+				   sha256hash, sha1hash, sm3hash);
+#else
 	efi_status = generate_hash(buffer, size, &context,
 				   sha256hash, sha1hash);
+#endif
 	if (EFI_ERROR(efi_status))
 		goto done;
 
@@ -1002,16 +1052,27 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size)
 		goto done;
 	}
 
+#ifdef ENABLE_SHIM_SM
+	efi_status = verify_buffer(buffer, size,
+				   &context, sha256hash, sha1hash, sm3hash);
+#else
 	efi_status = verify_buffer(buffer, size,
 				   &context, sha256hash, sha1hash);
+#endif
 done:
 	in_protocol = 0;
 	return efi_status;
 }
 
+#ifdef ENABLE_SHIM_SM
+static EFI_STATUS shim_hash (char *data, int datasize,
+			     PE_COFF_LOADER_IMAGE_CONTEXT *context,
+			     UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash)
+#else
 static EFI_STATUS shim_hash (char *data, int datasize,
 			     PE_COFF_LOADER_IMAGE_CONTEXT *context,
 			     UINT8 *sha256hash, UINT8 *sha1hash)
+#endif
 {
 	EFI_STATUS efi_status;
 
@@ -1019,8 +1080,13 @@ static EFI_STATUS shim_hash (char *data, int datasize,
 		return EFI_INVALID_PARAMETER;
 
 	in_protocol = 1;
+#ifdef ENABLE_SHIM_SM
+	efi_status = generate_hash(data, datasize, context,
+				   sha256hash, sha1hash, sm3hash);
+#else
 	efi_status = generate_hash(data, datasize, context,
 				   sha256hash, sha1hash);
+#endif
 	in_protocol = 0;
 
 	return efi_status;
diff --git a/shim.h b/shim.h
index b5272b9..b9aa982 100644
--- a/shim.h
+++ b/shim.h
@@ -208,6 +208,18 @@ EFI_STATUS
 	IN UINT32 size
 	);
 
+#ifdef ENABLE_SHIM_SM
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_HASH) (
+	IN char *data,
+	IN int datasize,
+	PE_COFF_LOADER_IMAGE_CONTEXT *context,
+	UINT8 *sha256hash,
+	UINT8 *sha1hash,
+	UINT8 *sm3hash
+	);
+#else
 typedef
 EFI_STATUS
 (*EFI_SHIM_LOCK_HASH) (
@@ -217,6 +229,7 @@ EFI_STATUS
 	UINT8 *sha256hash,
 	UINT8 *sha1hash
 	);
+#endif
 
 typedef
 EFI_STATUS
@@ -271,10 +284,17 @@ extern UINT32 load_options_size;
 
 BOOLEAN secure_mode (void);
 
+#ifdef ENABLE_SHIM_SM
+EFI_STATUS
+verify_buffer (char *data, int datasize,
+	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
+	       UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash);
+#else
 EFI_STATUS
 verify_buffer (char *data, int datasize,
 	       PE_COFF_LOADER_IMAGE_CONTEXT *context,
 	       UINT8 *sha256hash, UINT8 *sha1hash);
+#endif
 
 #ifndef SHIM_UNIT_TEST
 #define perror_(file, line, func, fmt, ...) ({					\
-- 
2.33.0

