前面介绍了 MD5 的实现,这里介绍一下 SHA-1 算法的实现。具体代码来自【参考1】。
和之前 MD5 程序有一些差别在于这个程序不是一次性将所有文件都放入内存中,而是放入一部分,计算一部分,再用中间结果继续计算下一部分。这样,再大的文件也可以正常处理。
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <Protocol/EfiShell.h>
#include <Library/ShellLib.h>
#include <Library/MemoryAllocationLib.h>
#include "sha1.h"
#define BUFFERSIZE 2048
extern EFI_BOOT_SERVICES *gBS;
extern EFI_SYSTEM_TABLE *gST;
extern EFI_RUNTIME_SERVICES *gRT;
extern EFI_SHELL_PROTOCOL *gEfiShellProtocol;
int
EFIAPI
main (
IN int Argc,
IN CHAR16 **Argv
)
{
EFI_FILE_HANDLE FileHandle;
RETURN_STATUS Status;
EFI_FILE_INFO *FileInfo = NULL;
EFI_HANDLE *HandleBuffer=NULL;
UINTN ReadSize=BUFFERSIZE;
SHA1Context sha;
//Check if there is a parameter
if (Argc == 1) {
Print(L"Usage: crctest [filename]\n");
return 0;
}
//Open the file given by the parameter
Status = ShellOpenFileByName(Argv[1], (SHELL_FILE_HANDLE *)&FileHandle,
EFI_FILE_MODE_READ , 0);
if(Status != RETURN_SUCCESS) {
Print(L"OpenFile failed!\n");
return EFI_SUCCESS;
}
//Get file size
FileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)FileHandle);
/*
* Reset the SHA-1 context and process input
*/
SHA1Reset(&sha);
//Allocate a memory buffer
HandleBuffer = AllocateZeroPool(BUFFERSIZE);
if (HandleBuffer == NULL) {
return (SHELL_OUT_OF_RESOURCES); }
while (BUFFERSIZE == ReadSize)
{
ReadSize=BUFFERSIZE;
//Load the whole file to the buffer
Status = ShellReadFile(FileHandle,&ReadSize,HandleBuffer);
SHA1Input(&sha,(unsigned char *) HandleBuffer, ReadSize);
}
//Output
Print(L"File Name: %s\n",Argv[1]);
Print(L"File Size: %d\n",(UINTN)FileInfo-> FileSize);
if (!SHA1Result(&sha))
{
Print(L"sha: could not compute message digest\n");
}
else
{
Print(L"%08X %08X %08X %08X %08X\n",
sha.Message_Digest[0],
sha.Message_Digest[1],
sha.Message_Digest[2],
sha.Message_Digest[3],
sha.Message_Digest[4]);
}
FreePool(HandleBuffer);
return EFI_SUCCESS;
}
运行结果:
完整的代码下载:
参考:
1.https://www.packetizer.com/
