Step to UEFI (145)Crypto 实现的 SHA256

之前我们介绍过在UEFI 下实现MD5【参考1】和SHA-1 【参考2】的方法,这次介绍一下如何计算 SHA256 。同样的, SHA256也是一种 HASH 算法。
与之前不同,这次使用的是前面提到的CryptoPkg,在正常编译完成上述 Package后,会生成一个:CryptRuntimeDxe的EFI文件,我们需要做的是先在Shell 下加载这个 Driver。

sha2561

加载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值,结果如下:

sha2562

我们可以使用【参考3】提供的在线工具进行计算,结果如下:

sha2563

可以看到,这个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

Step to UEFI (145)Crypto 实现的 SHA256》上有 2 条评论

  1. ChiChen

    Hi Sir,
    我build 出來, 執行的結果 都是 00 也,
    Init Update, Finalize 的 Status 都是 Boolean 的 True,
    LocateProtocol 也沒有錯誤發生

    我是在KabyLake U的機器執行, 請問你有遇過嗎?

    回复
    1. ziv2013 文章作者

      Hi , 文章中的实验是在 UDK2017 的NT32 环境做的. 刚才我在 Kabylake-R 的平台上实验了一下, 也是可以的.

      建议你先试试 UDK2017 的 NT32 环境.

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注