之前我们介绍过在UEFI 下实现MD5【参考1】和SHA-1 【参考2】的方法,这次介绍一下如何计算 SHA256 。同样的, SHA256也是一种 HASH 算法。
与之前不同,这次使用的是前面提到的CryptoPkg,在正常编译完成上述 Package后,会生成一个:CryptRuntimeDxe的EFI文件,我们需要做的是先在Shell 下加载这个 Driver。
加载Driver之后,就可以使用EFI_RUNTIME_CRYPT_PROTOCOL :
///
/// Runtime Cryptographic Protocol Structure.
///
typedef struct {
EFI_RUNTIME_CRYPT_SHA256_GET_CONTEXT_SIZE Sha256GetContextSize;
EFI_RUNTIME_CRYPT_SHA256_INIT Sha256Init;
EFI_RUNTIME_CRYPT_SHA256_UPDATE Sha256Update;
EFI_RUNTIME_CRYPT_SHA256_FINAL Sha256Final;
EFI_RUNTIME_CRYPT_RSA_NEW RsaNew;
EFI_RUNTIME_CRYPT_RSA_FREE RsaFree;
EFI_RUNTIME_CRYPT_RSA_SET_KEY RsaSetKey;
EFI_RUNTIME_CRYPT_RSA_PKCS1_VERIFY RsaPkcs1Verify;
} EFI_RUNTIME_CRYPT_PROTOCOL;
在 AppPkg 中编写代码如下:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <stdlib.h>
#include "RuntimeCrypt.h"
//
// Max Known Digest Size is SHA512 Output (64 bytes) by far
//
#define MAX_DIGEST_SIZE 64
//
// Message string for digest validation
//
CHAR8 *HashData = "www.lab-z.com";
extern EFI_BOOT_SERVICES *gBS;
///
/// Runtime Cryptographic Protocol GUID.
///
EFI_GUID gEfiRuntimeCryptProtocolGuid =
{0xe1475e0c, 0x1746, 0x4802,
{ 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }};
int
EFIAPI
main (
IN int Argc,
IN CHAR16 **Argv
)
{
EFI_RUNTIME_CRYPT_PROTOCOL *mCryptProtocol = NULL;
EFI_STATUS Status;
UINT8 Digest[MAX_DIGEST_SIZE];
UINTN CtxSize;
VOID *HashCtx;
UINTN DataSize;
UINTN Index;
DataSize = AsciiStrLen (HashData);
//
// Pointer to the runtime cryptographic protocol.
//
Status = gBS->LocateProtocol(
&gEfiRuntimeCryptProtocolGuid,
NULL,
(VOID **) &mCryptProtocol);
if (EFI_ERROR(Status)) {
Print(L"Can't find the runtime cryptographic protocol\n");
return Status;
}
Print (L"- SHA256: \n");
//
// SHA256 Digest Validation
//
ZeroMem (Digest, MAX_DIGEST_SIZE);
CtxSize = mCryptProtocol->Sha256GetContextSize ();
HashCtx = AllocatePool (CtxSize);
Print (L"Init... \n");
Status = mCryptProtocol->Sha256Init (HashCtx);
if (!Status) {
Print (L"[Fail]\n");
return EFI_ABORTED;
}
Print (L"Update... \n");
Status = mCryptProtocol->Sha256Update (HashCtx, HashData, DataSize);
if (!Status) {
Print (L"[Fail]\n");
return EFI_ABORTED;
}
Print (L"Finalize... \n");
Status = mCryptProtocol->Sha256Final (HashCtx, Digest);
if (!Status) {
Print (L"[Fail]\n");
return EFI_ABORTED;
}
for (Index=0;Index<SHA256_DIGEST_SIZE;Index++) {
Print (L"%2X ",Digest[Index]);
}
Print (L"\n");
FreePool (HashCtx);
return EFI_SUCCESS;
}
上面的程序中,我们计算的是 “www.lab-z.com”的SHA256值,结果如下:
我们可以使用【参考3】提供的在线工具进行计算,结果如下:
可以看到,这个Protocol工作正常,能够准确的计算出 SHA256的值。
本文提到的完整的代码下载:
SHA256
参考:
1. 计算MD5 http://www.lab-z.com/uefimd5/
2. SHA-1的实现http://www.lab-z.com/sha1/
3. Hash在线计算、md5计算、sha1计算、sha256计算、sha512计算 https://1024tools.com/hash


Hi Sir,
我build 出來, 執行的結果 都是 00 也,
Init Update, Finalize 的 Status 都是 Boolean 的 True,
LocateProtocol 也沒有錯誤發生
我是在KabyLake U的機器執行, 請問你有遇過嗎?
Hi , 文章中的实验是在 UDK2017 的NT32 环境做的. 刚才我在 Kabylake-R 的平台上实验了一下, 也是可以的.
建议你先试试 UDK2017 的 NT32 环境.