之前我们介绍过在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 环境.