X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FLibrary%2FDxeTpmMeasureBootLib%2FDxeTpmMeasureBootLib.c;h=d990eb2ad3a9f8007cb49bb50075e2cfc9bcddc3;hp=8ab60d871d8440921bcf598d32384512ce20fa0b;hb=HEAD;hpb=e39d0569a67f2cac31ad79f8d16f059c27ed82e2 diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c index 8ab60d871d..220393dd2b 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c @@ -1,5 +1,5 @@ /** @file - The library instance provides security service of TPM measure boot. + The library instance provides security service of TPM measure boot. Caution: This file requires additional review when modified. This library will have external input - PE/COFF image and GPT partition. @@ -15,14 +15,8 @@ TcgMeasureGptTable() function will receive untrusted GPT partition table, and parse partition data carefully. -Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -34,7 +28,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include -#include #include #include @@ -50,15 +43,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // // Flag to check GPT partition. It only need be measured once. // -BOOLEAN mMeasureGptTableFlag = FALSE; -UINTN mMeasureGptCount = 0; -VOID *mFileBuffer; -UINTN mTpmImageSize; +BOOLEAN mMeasureGptTableFlag = FALSE; +UINTN mMeasureGptCount = 0; +VOID *mFileBuffer; +UINTN mTpmImageSize; // // Measured FV handle cache // -EFI_HANDLE mCacheMeasuredHandle = NULL; -MEASURED_HOB_DATA *mMeasuredHobData = NULL; +EFI_HANDLE mCacheMeasuredHandle = NULL; +MEASURED_HOB_DATA *mMeasuredHobData = NULL; /** Reads contents of a PE/COFF image in memory buffer. @@ -69,24 +62,24 @@ MEASURED_HOB_DATA *mMeasuredHobData = NULL; @param FileHandle Pointer to the file handle to read the PE/COFF image. @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. + @param ReadSize On input, the size in bytes of the requested read operation. On output, the number of bytes actually read. @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size + + @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size **/ EFI_STATUS EFIAPI DxeTpmMeasureBootLibImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer ) { - UINTN EndPosition; + UINTN EndPosition; - if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) { + if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } @@ -103,7 +96,7 @@ DxeTpmMeasureBootLibImageRead ( *ReadSize = 0; } - CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize); + CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); return EFI_SUCCESS; } @@ -126,43 +119,46 @@ DxeTpmMeasureBootLibImageRead ( EFI_STATUS EFIAPI TcgMeasureGptTable ( - IN EFI_TCG_PROTOCOL *TcgProtocol, - IN EFI_HANDLE GptHandle + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN EFI_HANDLE GptHandle ) { - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - EFI_PARTITION_TABLE_HEADER *PrimaryHeader; - EFI_PARTITION_ENTRY *PartitionEntry; - UINT8 *EntryPtr; - UINTN NumberOfPartition; - UINT32 Index; - TCG_PCR_EVENT *TcgEvent; - EFI_GPT_DATA *GptData; - UINT32 EventSize; - UINT32 EventNumber; - EFI_PHYSICAL_ADDRESS EventLogLastEntry; + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_PARTITION_TABLE_HEADER *PrimaryHeader; + EFI_PARTITION_ENTRY *PartitionEntry; + UINT8 *EntryPtr; + UINTN NumberOfPartition; + UINT32 Index; + TCG_PCR_EVENT *TcgEvent; + EFI_GPT_DATA *GptData; + UINT32 EventSize; + UINT32 EventNumber; + EFI_PHYSICAL_ADDRESS EventLogLastEntry; if (mMeasureGptCount > 0) { return EFI_SUCCESS; } - Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo); + Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } - Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID**)&DiskIo); + + Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } + // // Read the EFI Partition Table Header - // - PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->Media->BlockSize); + // + PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *)AllocatePool (BlockIo->Media->BlockSize); if (PrimaryHeader == NULL) { return EFI_OUT_OF_RESOURCES; - } + } + Status = DiskIo->ReadDisk ( DiskIo, BlockIo->Media->MediaId, @@ -171,10 +167,11 @@ TcgMeasureGptTable ( (UINT8 *)PrimaryHeader ); if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n")); + DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); FreePool (PrimaryHeader); return EFI_DEVICE_ERROR; - } + } + // // Read the partition entry. // @@ -183,10 +180,11 @@ TcgMeasureGptTable ( FreePool (PrimaryHeader); return EFI_OUT_OF_RESOURCES; } + Status = DiskIo->ReadDisk ( DiskIo, BlockIo->Media->MediaId, - MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), + MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, EntryPtr ); @@ -195,48 +193,49 @@ TcgMeasureGptTable ( FreePool (EntryPtr); return EFI_DEVICE_ERROR; } - + // // Count the valid partition // PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr; NumberOfPartition = 0; for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) { - if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &gZeroGuid)) { - NumberOfPartition++; + if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) { + NumberOfPartition++; } + PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry); } // // Prepare Data for Measurement - // - EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) - + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); - TcgEvent = (TCG_PCR_EVENT *) AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR)); + // + EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); + TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR)); if (TcgEvent == NULL) { FreePool (PrimaryHeader); FreePool (EntryPtr); return EFI_OUT_OF_RESOURCES; } - TcgEvent->PCRIndex = 5; - TcgEvent->EventType = EV_EFI_GPT_EVENT; - TcgEvent->EventSize = EventSize; - GptData = (EFI_GPT_DATA *) TcgEvent->Event; + TcgEvent->PCRIndex = 5; + TcgEvent->EventType = EV_EFI_GPT_EVENT; + TcgEvent->EventSize = EventSize; + GptData = (EFI_GPT_DATA *)TcgEvent->Event; // // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition - // - CopyMem ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER)); + // + CopyMem ((UINT8 *)GptData, (UINT8 *)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER)); GptData->NumberOfPartitions = NumberOfPartition; // // Copy the valid partition entry // - PartitionEntry = (EFI_PARTITION_ENTRY*)EntryPtr; + PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr; NumberOfPartition = 0; for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) { - if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &gZeroGuid)) { + if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) { CopyMem ( (UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry, (UINT8 *)PartitionEntry, @@ -244,22 +243,23 @@ TcgMeasureGptTable ( ); NumberOfPartition++; } - PartitionEntry =(EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry); + + PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry); } // // Measure the GPT data // EventNumber = 1; - Status = TcgProtocol->HashLogExtendEvent ( - TcgProtocol, - (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData, - (UINT64) TcgEvent->EventSize, - TPM_ALG_SHA, - TcgEvent, - &EventNumber, - &EventLogLastEntry - ); + Status = TcgProtocol->HashLogExtendEvent ( + TcgProtocol, + (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, + (UINT64)TcgEvent->EventSize, + TPM_ALG_SHA, + TcgEvent, + &EventNumber, + &EventLogLastEntry + ); if (!EFI_ERROR (Status)) { mMeasureGptCount++; } @@ -279,7 +279,7 @@ TcgMeasureGptTable ( PE/COFF image is external input, so this function will validate its data structure within this image buffer before use. - Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in its caller function DxeTpmMeasureBootHandler(). @param[in] TcgProtocol Pointer to the located TCG protocol instance. @@ -291,7 +291,7 @@ TcgMeasureGptTable ( @retval EFI_SUCCESS Successfully measure image. @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. - @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format. + @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format. @retval other error value **/ @@ -321,7 +321,6 @@ TcgMeasurePeImage ( EFI_IMAGE_SECTION_HEADER *SectionHeader; UINTN Index; UINTN Pos; - UINT16 Magic; UINT32 EventSize; UINT32 EventNumber; EFI_PHYSICAL_ADDRESS EventLogLastEntry; @@ -334,19 +333,19 @@ TcgMeasurePeImage ( ImageLoad = NULL; SectionHeader = NULL; Sha1Ctx = NULL; - FilePathSize = (UINT32) GetDevicePathSize (FilePath); + FilePathSize = (UINT32)GetDevicePathSize (FilePath); // // Determine destination PCR by BootPolicy // EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; - TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); + TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); if (TcgEvent == NULL) { return EFI_OUT_OF_RESOURCES; } TcgEvent->EventSize = EventSize; - ImageLoad = (EFI_IMAGE_LOAD_EVENT *) TcgEvent->Event; + ImageLoad = (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event; switch (ImageType) { case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: @@ -363,7 +362,7 @@ TcgMeasurePeImage ( break; default: DEBUG (( - EFI_D_ERROR, + DEBUG_ERROR, "TcgMeasurePeImage: Unknown subsystem type %d", ImageType )); @@ -381,13 +380,13 @@ TcgMeasurePeImage ( // // Check PE/COFF image // - DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress; + DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress; PeCoffHeaderOffset = 0; if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { PeCoffHeaderOffset = DosHdr->e_lfanew; } - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset); + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { goto Finish; } @@ -419,44 +418,30 @@ TcgMeasurePeImage ( // Measuring PE/COFF Image Header; // But CheckSum field and SECURITY data directory (certificate) are excluded // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } else { - // - // Get the magic value from the PE/COFF Optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - + // // 3. Calculate the distance from the base of the image header to the image checksum address. // 4. Hash the image header from its base to beginning of the image checksum. // - HashBase = (UINT8 *) (UINTN) ImageAddress; - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + HashBase = (UINT8 *)(UINTN)ImageAddress; + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase); + HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; } else { // // Use PE32+ offset // NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase); + HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; } HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { goto Finish; - } + } // // 5. Skip over the image checksum (it occupies a single ULONG). @@ -466,46 +451,46 @@ TcgMeasurePeImage ( // 6. Since there is no Cert Directory in optional header, hash everything // from the end of the checksum to the end of image header. // - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset. // - HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); + HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } else { // // Use PE32+ offset. // - HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); + HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); + HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { goto Finish; } - } + } } else { // // 7. Hash everything from the end of the checksum to the start of the Cert Directory. // - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase); + HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); + HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; } else { // // Use PE32+ offset - // - HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase); + // + HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); + HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; } if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); + HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { goto Finish; } @@ -515,22 +500,22 @@ TcgMeasurePeImage ( // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) // 9. Hash everything from the end of the Cert Directory to the end of image header. // - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; + HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } else { // // Use PE32+ offset // - HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; + HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } - + if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); + HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { goto Finish; } @@ -540,7 +525,7 @@ TcgMeasurePeImage ( // // 10. Set the SUM_OF_BYTES_HASHED to the size of the header // - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // @@ -558,7 +543,7 @@ TcgMeasurePeImage ( // header indicates how big the table should be. Do not include any // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections); + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections); if (SectionHeader == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Finish; @@ -570,20 +555,21 @@ TcgMeasurePeImage ( // words, sort the section headers according to the disk-file offset of // the section. // - Section = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) (UINTN) ImageAddress + - PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); + Section = (EFI_IMAGE_SECTION_HEADER *)( + (UINT8 *)(UINTN)ImageAddress + + PeCoffHeaderOffset + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + Hdr.Pe32->FileHeader.SizeOfOptionalHeader + ); for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { Pos = Index; while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { - CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER)); + CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); Pos--; } - CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER)); + + CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER)); Section += 1; } @@ -595,12 +581,13 @@ TcgMeasurePeImage ( // 15. Repeat steps 13 and 14 for all the sections in the sorted table. // for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Section = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index]; + Section = (EFI_IMAGE_SECTION_HEADER *)&SectionHeader[Index]; if (Section->SizeOfRawData == 0) { continue; } - HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData; - HashSize = (UINTN) Section->SizeOfRawData; + + HashBase = (UINT8 *)(UINTN)ImageAddress + Section->PointerToRawData; + HashSize = (UINTN)Section->SizeOfRawData; HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { @@ -617,12 +604,12 @@ TcgMeasurePeImage ( // FileSize - (CertDirectory->Size) // if (ImageSize > SumOfBytesHashed) { - HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed; + HashBase = (UINT8 *)(UINTN)ImageAddress + SumOfBytesHashed; if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { CertSize = 0; } else { - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset. // @@ -636,7 +623,7 @@ TcgMeasurePeImage ( } if (ImageSize > CertSize + SumOfBytesHashed) { - HashSize = (UINTN) (ImageSize - CertSize - SumOfBytesHashed); + HashSize = (UINTN)(ImageSize - CertSize - SumOfBytesHashed); HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); if (!HashStatus) { @@ -650,7 +637,7 @@ TcgMeasurePeImage ( // // 17. Finalize the SHA hash. // - HashStatus = Sha1Final (Sha1Ctx, (UINT8 *) &TcgEvent->Digest); + HashStatus = Sha1Final (Sha1Ctx, (UINT8 *)&TcgEvent->Digest); if (!HashStatus) { goto Finish; } @@ -659,19 +646,19 @@ TcgMeasurePeImage ( // Log the PE data // EventNumber = 1; - Status = TcgProtocol->HashLogExtendEvent ( - TcgProtocol, - (EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) NULL, - 0, - TPM_ALG_SHA, - TcgEvent, - &EventNumber, - &EventLogLastEntry - ); + Status = TcgProtocol->HashLogExtendEvent ( + TcgProtocol, + (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)NULL, + 0, + TPM_ALG_SHA, + TcgEvent, + &EventNumber, + &EventLogLastEntry + ); if (Status == EFI_OUT_OF_RESOURCES) { // // Out of resource here means the image is hashed and its result is extended to PCR. - // But the event log cann't be saved since log area is full. + // But the event log can't be saved since log area is full. // Just return EFI_SUCCESS in order not to block the image load. // Status = EFI_SUCCESS; @@ -687,33 +674,34 @@ Finish: if (Sha1Ctx != NULL ) { FreePool (Sha1Ctx); } + return Status; } /** - The security handler is used to abstract platform-specific policy - from the DXE core response to an attempt to use a file that returns a - given status for the authentication check from the section extraction protocol. + The security handler is used to abstract platform-specific policy + from the DXE core response to an attempt to use a file that returns a + given status for the authentication check from the section extraction protocol. - The possible responses in a given SAP implementation may include locking - flash upon failure to authenticate, attestation logging for all signed drivers, - and other exception operations. The File parameter allows for possible logging + The possible responses in a given SAP implementation may include locking + flash upon failure to authenticate, attestation logging for all signed drivers, + and other exception operations. The File parameter allows for possible logging within the SAP of the driver. - If File is NULL, then EFI_INVALID_PARAMETER is returned. - - If the file specified by File with an authentication status specified by + If the file specified by File with an authentication status specified by AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned. - If the file specified by File with an authentication status specified by - AuthenticationStatus is not safe for the DXE Core to use under any circumstances, + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use under any circumstances, then EFI_ACCESS_DENIED is returned. - If the file specified by File with an authentication status specified by - AuthenticationStatus is not safe for the DXE Core to use right now, but it - might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is + If the file specified by File with an authentication status specified by + AuthenticationStatus is not safe for the DXE Core to use right now, but it + might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is returned. + If check image specified by FileBuffer and File is NULL meanwhile, return EFI_ACCESS_DENIED. + @param[in] AuthenticationStatus This is the authentication status returned from the securitymeasurement services for the input file. @@ -731,11 +719,11 @@ Finish: EFI_STATUS EFIAPI DxeTpmMeasureBootHandler ( - IN UINT32 AuthenticationStatus, - IN CONST EFI_DEVICE_PATH_PROTOCOL *File, - IN VOID *FileBuffer, - IN UINTN FileSize, - IN BOOLEAN BootPolicy + IN UINT32 AuthenticationStatus, + IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL, + IN VOID *FileBuffer, + IN UINTN FileSize, + IN BOOLEAN BootPolicy ) { EFI_TCG_PROTOCOL *TcgProtocol; @@ -754,7 +742,7 @@ DxeTpmMeasureBootHandler ( EFI_PHYSICAL_ADDRESS FvAddress; UINT32 Index; - Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol); + Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); if (EFI_ERROR (Status)) { // // TCG protocol is not installed. So, TPM is not present. @@ -763,14 +751,14 @@ DxeTpmMeasureBootHandler ( return EFI_SUCCESS; } - ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability); - Status = TcgProtocol->StatusCheck ( - TcgProtocol, - &ProtocolCapability, - &TCGFeatureFlags, - &EventLogLocation, - &EventLogLastEntry - ); + ProtocolCapability.Size = (UINT8)sizeof (ProtocolCapability); + Status = TcgProtocol->StatusCheck ( + TcgProtocol, + &ProtocolCapability, + &TCGFeatureFlags, + &EventLogLocation, + &EventLogLastEntry + ); if (EFI_ERROR (Status) || ProtocolCapability.TPMDeactivatedFlag || (!ProtocolCapability.TPMPresentFlag)) { // // TPM device doesn't work or activate. @@ -782,16 +770,16 @@ DxeTpmMeasureBootHandler ( // Copy File Device Path // OrigDevicePathNode = DuplicateDevicePath (File); - + // // 1. Check whether this device path support BlockIo protocol. // Is so, this device path may be a GPT device path. // DevicePathNode = OrigDevicePathNode; - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle); + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status) && !mMeasureGptTableFlag) { // - // Find the gpt partion on the given devicepath + // Find the gpt partition on the given devicepath // DevicePathNode = OrigDevicePathNode; ASSERT (DevicePathNode != NULL); @@ -799,25 +787,26 @@ DxeTpmMeasureBootHandler ( // // Find the Gpt partition // - if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH && - DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) { + if ((DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP)) + { // // Check whether it is a gpt partition or not - // - if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER && - ((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) { - + // + if ((((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) && + (((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID)) + { // // Change the partition device path to its parent device path (disk) and get the handle. // DevicePathNode->Type = END_DEVICE_PATH_TYPE; DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; DevicePathNode = OrigDevicePathNode; - Status = gBS->LocateDevicePath ( - &gEfiDiskIoProtocolGuid, - &DevicePathNode, - &Handle - ); + Status = gBS->LocateDevicePath ( + &gEfiDiskIoProtocolGuid, + &DevicePathNode, + &Handle + ); if (!EFI_ERROR (Status)) { // // Measure GPT disk. @@ -830,16 +819,18 @@ DxeTpmMeasureBootHandler ( mMeasureGptTableFlag = TRUE; } } + FreePool (OrigDevicePathNode); OrigDevicePathNode = DuplicateDevicePath (File); ASSERT (OrigDevicePathNode != NULL); break; } } - DevicePathNode = NextDevicePathNode (DevicePathNode); + + DevicePathNode = NextDevicePathNode (DevicePathNode); } } - + // // 2. Measure PE image. // @@ -849,7 +840,7 @@ DxeTpmMeasureBootHandler ( // Check whether this device path support FVB protocol. // DevicePathNode = OrigDevicePathNode; - Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle); + Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { // // Don't check FV image, and directly return EFI_SUCCESS. @@ -858,40 +849,41 @@ DxeTpmMeasureBootHandler ( if (IsDevicePathEnd (DevicePathNode)) { return EFI_SUCCESS; } + // // The PE image from unmeasured Firmware volume need be measured - // The PE image from measured Firmware volume will be mearsured according to policy below. + // The PE image from measured Firmware volume will be measured according to policy below. // If it is driver, do not measure // If it is application, still measure. // ApplicationRequired = TRUE; - if (mCacheMeasuredHandle != Handle && mMeasuredHobData != NULL) { + if ((mCacheMeasuredHandle != Handle) && (mMeasuredHobData != NULL)) { // // Search for Root FV of this PE image // TempHandle = Handle; do { - Status = gBS->HandleProtocol( - TempHandle, + Status = gBS->HandleProtocol ( + TempHandle, &gEfiFirmwareVolumeBlockProtocolGuid, - (VOID**)&FvbProtocol + (VOID **)&FvbProtocol ); TempHandle = FvbProtocol->ParentHandle; - } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL); + } while (!EFI_ERROR (Status) && FvbProtocol->ParentHandle != NULL); // // Search in measured FV Hob // - Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress); - if (EFI_ERROR(Status)){ + Status = FvbProtocol->GetPhysicalAddress (FvbProtocol, &FvAddress); + if (EFI_ERROR (Status)) { return Status; } ApplicationRequired = FALSE; for (Index = 0; Index < mMeasuredHobData->Num; Index++) { - if(mMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) { + if (mMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) { // // Cache measured FV for next measurement // @@ -911,48 +903,57 @@ DxeTpmMeasureBootHandler ( goto Finish; } - mTpmImageSize = FileSize; - mFileBuffer = FileBuffer; + mTpmImageSize = FileSize; + mFileBuffer = FileBuffer; // // Measure PE Image // DevicePathNode = OrigDevicePathNode; ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeTpmMeasureBootLibImageRead; + ImageContext.Handle = (VOID *)FileBuffer; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeTpmMeasureBootLibImageRead; // // Get information about the image being loaded // Status = PeCoffLoaderGetImageInfo (&ImageContext); if (EFI_ERROR (Status)) { + // + // Check for invalid parameters. + // + if (File == NULL) { + return EFI_ACCESS_DENIED; + } + // // The information can't be got from the invalid PeImage // goto Finish; } - + // // Measure only application if Application flag is set // Measure drivers and applications if Application flag is not set // - if ((!ApplicationRequired) || - (ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) { + if ((!ApplicationRequired) || + (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION))) + { // // Print the image path to be measured. - // + // DEBUG_CODE_BEGIN (); - CHAR16 *ToText; - ToText = ConvertDevicePathToText ( - DevicePathNode, - FALSE, - TRUE - ); - if (ToText != NULL) { - DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText)); - FreePool (ToText); - } + CHAR16 *ToText; + ToText = ConvertDevicePathToText ( + DevicePathNode, + FALSE, + TRUE + ); + if (ToText != NULL) { + DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText)); + FreePool (ToText); + } + DEBUG_CODE_END (); // @@ -960,10 +961,10 @@ DxeTpmMeasureBootHandler ( // Status = TcgMeasurePeImage ( TcgProtocol, - (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, - FileSize, - (UINTN) ImageContext.ImageAddress, - ImageContext.ImageType, + (EFI_PHYSICAL_ADDRESS)(UINTN)FileBuffer, + FileSize, + (UINTN)ImageContext.ImageAddress, + ImageContext.ImageType, DevicePathNode ); } @@ -1006,7 +1007,7 @@ DxeTpmMeasureBootLibConstructor ( } return RegisterSecurity2Handler ( - DxeTpmMeasureBootHandler, - EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED - ); + DxeTpmMeasureBootHandler, + EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED + ); }