2 EDKII System Capsule library.
4 EDKII System Capsule library instance.
6 CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive
7 untrusted input and do basic validation.
9 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include <Guid/SystemResourceTable.h>
17 #include <Guid/FirmwareContentsSigned.h>
18 #include <Guid/WinCertificate.h>
19 #include <Guid/EdkiiSystemFmpCapsule.h>
20 #include <Guid/WinCertificate.h>
21 #include <Guid/ImageAuthentication.h>
23 #include <Library/BaseLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/EdkiiSystemCapsuleLib.h>
29 #include <Library/FmpAuthenticationLib.h>
31 #include <Protocol/FirmwareManagement.h>
33 EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
*mImageFmpInfo
;
34 UINTN mImageFmpInfoSize
;
35 EFI_GUID mEdkiiSystemFirmwareFileGuid
;
38 Check if a block of buffer is erased.
40 @param[in] ErasePolarity Erase polarity attribute of the firmware volume
41 @param[in] InBuffer The buffer to be checked
42 @param[in] BufferSize Size of the buffer in bytes
44 @retval TRUE The block of buffer is erased
45 @retval FALSE The block of buffer is not erased
49 IN UINT8 ErasePolarity
,
58 if(ErasePolarity
== 1) {
65 for (Count
= 0; Count
< BufferSize
; Count
++) {
66 if (Buffer
[Count
] != EraseByte
) {
75 Get Section buffer pointer by SectionType and SectionInstance.
77 @param[in] SectionBuffer The buffer of section
78 @param[in] SectionBufferSize The size of SectionBuffer in bytes
79 @param[in] SectionType The SectionType of Section to be found
80 @param[in] SectionInstance The Instance of Section to be found
81 @param[out] OutSectionBuffer The section found, including SECTION_HEADER
82 @param[out] OutSectionSize The size of section found, including SECTION_HEADER
84 @retval TRUE The FFS buffer is found.
85 @retval FALSE The FFS buffer is not found.
89 IN VOID
*SectionBuffer
,
90 IN UINT32 SectionBufferSize
,
91 IN EFI_SECTION_TYPE SectionType
,
92 IN UINTN SectionInstance
,
93 OUT VOID
**OutSectionBuffer
,
94 OUT UINTN
*OutSectionSize
97 EFI_COMMON_SECTION_HEADER
*SectionHeader
;
101 DEBUG ((DEBUG_INFO
, "GetSectionByType - Buffer: 0x%08x - 0x%08x\n", SectionBuffer
, SectionBufferSize
));
106 SectionHeader
= SectionBuffer
;
109 while ((UINTN
)SectionHeader
< (UINTN
)SectionBuffer
+ SectionBufferSize
) {
110 DEBUG ((DEBUG_INFO
, "GetSectionByType - Section: 0x%08x\n", SectionHeader
));
111 if (IS_SECTION2(SectionHeader
)) {
112 SectionSize
= SECTION2_SIZE(SectionHeader
);
114 SectionSize
= SECTION_SIZE(SectionHeader
);
117 if (SectionHeader
->Type
== SectionType
) {
118 if (Instance
== SectionInstance
) {
119 *OutSectionBuffer
= (UINT8
*)SectionHeader
;
120 *OutSectionSize
= SectionSize
;
121 DEBUG((DEBUG_INFO
, "GetSectionByType - 0x%x - 0x%x\n", *OutSectionBuffer
, *OutSectionSize
));
124 DEBUG((DEBUG_INFO
, "GetSectionByType - find section instance %x\n", Instance
));
129 // Skip other section type
131 DEBUG ((DEBUG_INFO
, "GetSectionByType - other section type 0x%x\n", SectionHeader
->Type
));
137 SectionHeader
= (EFI_COMMON_SECTION_HEADER
*)((UINTN
)SectionHeader
+ ALIGN_VALUE(SectionSize
, 4));
144 Get FFS buffer pointer by FileName GUID and FileType.
146 @param[in] FdStart The System Firmware FD image
147 @param[in] FdSize The size of System Firmware FD image
148 @param[in] FileName The FileName GUID of FFS to be found
149 @param[in] Type The FileType of FFS to be found
150 @param[out] OutFfsBuffer The FFS buffer found, including FFS_FILE_HEADER
151 @param[out] OutFfsBufferSize The size of FFS buffer found, including FFS_FILE_HEADER
153 @retval TRUE The FFS buffer is found.
154 @retval FALSE The FFS buffer is not found.
160 IN EFI_GUID
*FileName
,
161 IN EFI_FV_FILETYPE Type
,
162 OUT VOID
**OutFfsBuffer
,
163 OUT UINTN
*OutFfsBufferSize
167 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
168 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FvExtHeader
;
169 EFI_FFS_FILE_HEADER
*FfsHeader
;
174 DEBUG ((DEBUG_INFO
, "GetFfsByName - FV: 0x%08x - 0x%08x\n", (UINTN
)FdStart
, (UINTN
)FdSize
));
177 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FdStart
;
178 while ((UINTN
)FvHeader
< (UINTN
)FdStart
+ FdSize
- 1) {
179 FvSize
= (UINTN
)FdStart
+ FdSize
- (UINTN
)FvHeader
;
181 if (FvHeader
->Signature
!= EFI_FVH_SIGNATURE
) {
182 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)((UINTN
)FvHeader
+ SIZE_4KB
);
185 DEBUG((DEBUG_INFO
, "checking FV....0x%08x - 0x%x\n", FvHeader
, FvHeader
->FvLength
));
187 if (FvHeader
->FvLength
> FvSize
) {
188 DEBUG((DEBUG_ERROR
, "GetFfsByName - FvSize: 0x%08x, MaxSize - 0x%08x\n", (UINTN
)FvHeader
->FvLength
, (UINTN
)FvSize
));
191 FvSize
= (UINTN
)FvHeader
->FvLength
;
196 if (FvHeader
->ExtHeaderOffset
!= 0) {
197 FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)((UINT8
*)FvHeader
+ FvHeader
->ExtHeaderOffset
);
198 FfsHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FvExtHeader
+ FvExtHeader
->ExtHeaderSize
);
200 FfsHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FvHeader
+ FvHeader
->HeaderLength
);
202 FfsHeader
= (EFI_FFS_FILE_HEADER
*)((UINTN
)FvHeader
+ ALIGN_VALUE((UINTN
)FfsHeader
- (UINTN
)FvHeader
, 8));
204 while ((UINTN
)FfsHeader
< (UINTN
)FvHeader
+ FvSize
- 1) {
205 DEBUG((DEBUG_INFO
, "GetFfsByName - FFS: 0x%08x\n", FfsHeader
));
206 TestLength
= (UINTN
)((UINTN
)FvHeader
+ FvSize
- (UINTN
)FfsHeader
);
207 if (TestLength
> sizeof(EFI_FFS_FILE_HEADER
)) {
208 TestLength
= sizeof(EFI_FFS_FILE_HEADER
);
210 if (IsBufferErased(1, FfsHeader
, TestLength
)) {
214 if (IS_FFS_FILE2(FfsHeader
)) {
215 FfsSize
= FFS_FILE2_SIZE(FfsHeader
);
217 FfsSize
= FFS_FILE_SIZE(FfsHeader
);
220 if (CompareGuid(FileName
, &FfsHeader
->Name
) &&
221 ((Type
== EFI_FV_FILETYPE_ALL
) || (FfsHeader
->Type
== Type
))) {
222 *OutFfsBuffer
= FfsHeader
;
223 *OutFfsBufferSize
= FfsSize
;
227 // Any other type is not allowed
229 DEBUG((DEBUG_INFO
, "GetFfsByName - other FFS type 0x%x, name %g\n", FfsHeader
->Type
, &FfsHeader
->Name
));
235 FfsHeader
= (EFI_FFS_FILE_HEADER
*)((UINTN
)FfsHeader
+ ALIGN_VALUE(FfsSize
, 8));
241 FvHeader
= (VOID
*)(UINTN
)((UINTN
)FvHeader
+ FvHeader
->FvLength
);
245 DEBUG((DEBUG_ERROR
, "GetFfsByName - NO FV Found\n"));
251 Extract the driver FV from an authenticated image.
253 @param[in] AuthenticatedImage The authenticated capsule image.
254 @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
255 @param[out] DriverFvImage The driver FV image.
256 @param[out] DriverFvImageSize The size of the driver FV image in bytes.
258 @retval TRUE The driver Fv is extracted.
259 @retval FALSE The driver Fv is not extracted.
263 ExtractDriverFvImage (
264 IN VOID
*AuthenticatedImage
,
265 IN UINTN AuthenticatedImageSize
,
266 OUT VOID
**DriverFvImage
,
267 OUT UINTN
*DriverFvImageSize
271 UINT32 FileHeaderSize
;
273 *DriverFvImage
= NULL
;
274 *DriverFvImageSize
= 0;
276 Result
= GetFfsByName(AuthenticatedImage
, AuthenticatedImageSize
, &gEdkiiSystemFmpCapsuleDriverFvFileGuid
, EFI_FV_FILETYPE_RAW
, DriverFvImage
, DriverFvImageSize
);
281 if (IS_FFS_FILE2(*DriverFvImage
)) {
282 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER2
);
284 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER
);
286 *DriverFvImage
= (UINT8
*)*DriverFvImage
+ FileHeaderSize
;
287 *DriverFvImageSize
= *DriverFvImageSize
- FileHeaderSize
;
293 Extract the config image from an authenticated image.
295 @param[in] AuthenticatedImage The authenticated capsule image.
296 @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
297 @param[out] ConfigImage The config image.
298 @param[out] ConfigImageSize The size of the config image in bytes.
300 @retval TRUE The config image is extracted.
301 @retval FALSE The config image is not extracted.
306 IN VOID
*AuthenticatedImage
,
307 IN UINTN AuthenticatedImageSize
,
308 OUT VOID
**ConfigImage
,
309 OUT UINTN
*ConfigImageSize
313 UINT32 FileHeaderSize
;
316 *ConfigImageSize
= 0;
318 Result
= GetFfsByName(AuthenticatedImage
, AuthenticatedImageSize
, &gEdkiiSystemFmpCapsuleConfigFileGuid
, EFI_FV_FILETYPE_RAW
, ConfigImage
, ConfigImageSize
);
323 if (IS_FFS_FILE2(*ConfigImage
)) {
324 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER2
);
326 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER
);
328 *ConfigImage
= (UINT8
*)*ConfigImage
+ FileHeaderSize
;
329 *ConfigImageSize
= *ConfigImageSize
- FileHeaderSize
;
335 Extract the authenticated image from an FMP capsule image.
337 Caution: This function may receive untrusted input.
339 @param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
340 @param[in] ImageSize The size of FMP capsule image in bytes.
341 @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
342 @param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
343 @param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
345 @retval TRUE The authenticated image is extracted.
346 @retval FALSE The authenticated image is not extracted.
350 ExtractAuthenticatedImage (
353 OUT UINT32
*LastAttemptStatus
,
354 OUT VOID
**AuthenticatedImage
,
355 OUT UINTN
*AuthenticatedImageSize
358 EFI_FIRMWARE_IMAGE_AUTHENTICATION
*ImageAuth
;
362 UINTN PublicKeyDataLength
;
364 DEBUG((DEBUG_INFO
, "ExtractAuthenticatedImage - Image: 0x%08x - 0x%08x\n", (UINTN
)Image
, (UINTN
)ImageSize
));
366 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT
;
367 if ((Image
== NULL
) || (ImageSize
== 0)) {
371 ImageAuth
= (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
;
372 if (ImageSize
< sizeof(EFI_FIRMWARE_IMAGE_AUTHENTICATION
)) {
373 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - ImageSize too small\n"));
376 if (ImageAuth
->AuthInfo
.Hdr
.dwLength
<= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID
, CertData
)) {
377 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - dwLength too small\n"));
380 if ((UINTN
) ImageAuth
->AuthInfo
.Hdr
.dwLength
> MAX_UINTN
- sizeof(UINT64
)) {
381 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - dwLength too big\n"));
384 if (ImageSize
<= sizeof(ImageAuth
->MonotonicCount
) + ImageAuth
->AuthInfo
.Hdr
.dwLength
) {
385 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - ImageSize too small\n"));
388 if (ImageAuth
->AuthInfo
.Hdr
.wRevision
!= 0x0200) {
389 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - wRevision: 0x%02x, expect - 0x%02x\n", (UINTN
)ImageAuth
->AuthInfo
.Hdr
.wRevision
, (UINTN
)0x0200));
392 if (ImageAuth
->AuthInfo
.Hdr
.wCertificateType
!= WIN_CERT_TYPE_EFI_GUID
) {
393 DEBUG((DEBUG_ERROR
, "ExtractAuthenticatedImage - wCertificateType: 0x%02x, expect - 0x%02x\n", (UINTN
)ImageAuth
->AuthInfo
.Hdr
.wCertificateType
, (UINTN
)WIN_CERT_TYPE_EFI_GUID
));
397 CertType
= &ImageAuth
->AuthInfo
.CertType
;
398 DEBUG((DEBUG_INFO
, "ExtractAuthenticatedImage - CertType: %g\n", CertType
));
400 if (CompareGuid(&gEfiCertPkcs7Guid
, CertType
)) {
401 PublicKeyData
= PcdGetPtr(PcdPkcs7CertBuffer
);
402 PublicKeyDataLength
= PcdGetSize(PcdPkcs7CertBuffer
);
403 } else if (CompareGuid(&gEfiCertTypeRsa2048Sha256Guid
, CertType
)) {
404 PublicKeyData
= PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer
);
405 PublicKeyDataLength
= PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer
);
409 ASSERT (PublicKeyData
!= NULL
);
410 ASSERT (PublicKeyDataLength
!= 0);
412 Status
= AuthenticateFmpImage(
420 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
422 case RETURN_SECURITY_VIOLATION
:
423 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR
;
425 case RETURN_INVALID_PARAMETER
:
426 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT
;
428 case RETURN_UNSUPPORTED
:
429 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT
;
431 case RETURN_OUT_OF_RESOURCES
:
432 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES
;
435 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL
;
438 if (EFI_ERROR(Status
)) {
442 if (AuthenticatedImage
!= NULL
) {
443 *AuthenticatedImage
= (UINT8
*)ImageAuth
+ ImageAuth
->AuthInfo
.Hdr
.dwLength
+ sizeof(ImageAuth
->MonotonicCount
);
445 if (AuthenticatedImageSize
!= NULL
) {
446 *AuthenticatedImageSize
= ImageSize
- ImageAuth
->AuthInfo
.Hdr
.dwLength
- sizeof(ImageAuth
->MonotonicCount
);
452 Extract ImageFmpInfo from system firmware.
454 @param[in] SystemFirmwareImage The System Firmware image.
455 @param[in] SystemFirmwareImageSize The size of the System Firmware image in bytes.
456 @param[out] ImageFmpInfo The ImageFmpInfo.
457 @param[out] ImageFmpInfoSize The size of the ImageFmpInfo in bytes.
459 @retval TRUE The ImageFmpInfo is extracted.
460 @retval FALSE The ImageFmpInfo is not extracted.
464 ExtractSystemFirmwareImageFmpInfo (
465 IN VOID
*SystemFirmwareImage
,
466 IN UINTN SystemFirmwareImageSize
,
467 OUT EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
**ImageFmpInfo
,
468 OUT UINTN
*ImageFmpInfoSize
472 UINT32 SectionHeaderSize
;
473 UINT32 FileHeaderSize
;
475 *ImageFmpInfo
= NULL
;
476 *ImageFmpInfoSize
= 0;
478 Result
= GetFfsByName(SystemFirmwareImage
, SystemFirmwareImageSize
, &gEdkiiSystemFirmwareImageDescriptorFileGuid
, EFI_FV_FILETYPE_ALL
, (VOID
**)ImageFmpInfo
, ImageFmpInfoSize
);
482 if (IS_FFS_FILE2 (*ImageFmpInfo
)) {
483 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER2
);
485 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER
);
487 *ImageFmpInfo
= (VOID
*)((UINT8
*)*ImageFmpInfo
+ FileHeaderSize
);
488 *ImageFmpInfoSize
= *ImageFmpInfoSize
- FileHeaderSize
;
490 Result
= GetSectionByType(*ImageFmpInfo
, (UINT32
)*ImageFmpInfoSize
, EFI_SECTION_RAW
, 0, (VOID
**)ImageFmpInfo
, ImageFmpInfoSize
);
494 if (IS_SECTION2(*ImageFmpInfo
)) {
495 SectionHeaderSize
= sizeof(EFI_RAW_SECTION2
);
497 SectionHeaderSize
= sizeof(EFI_RAW_SECTION
);
499 *ImageFmpInfo
= (VOID
*)((UINT8
*)*ImageFmpInfo
+ SectionHeaderSize
);
500 *ImageFmpInfoSize
= *ImageFmpInfoSize
- SectionHeaderSize
;
506 Extract the System Firmware image from an authenticated image.
508 @param[in] AuthenticatedImage The authenticated capsule image.
509 @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
510 @param[out] SystemFirmwareImage The System Firmware image.
511 @param[out] SystemFirmwareImageSize The size of the System Firmware image in bytes.
513 @retval TRUE The System Firmware image is extracted.
514 @retval FALSE The System Firmware image is not extracted.
518 ExtractSystemFirmwareImage (
519 IN VOID
*AuthenticatedImage
,
520 IN UINTN AuthenticatedImageSize
,
521 OUT VOID
**SystemFirmwareImage
,
522 OUT UINTN
*SystemFirmwareImageSize
526 UINT32 FileHeaderSize
;
528 *SystemFirmwareImage
= NULL
;
529 *SystemFirmwareImageSize
= 0;
531 Result
= GetFfsByName(AuthenticatedImage
, AuthenticatedImageSize
, &mEdkiiSystemFirmwareFileGuid
, EFI_FV_FILETYPE_RAW
, SystemFirmwareImage
, SystemFirmwareImageSize
);
533 // no nested FV, just return all data.
534 *SystemFirmwareImage
= AuthenticatedImage
;
535 *SystemFirmwareImageSize
= AuthenticatedImageSize
;
539 if (IS_FFS_FILE2 (*SystemFirmwareImage
)) {
540 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER2
);
542 FileHeaderSize
= sizeof(EFI_FFS_FILE_HEADER
);
544 *SystemFirmwareImage
= (UINT8
*)*SystemFirmwareImage
+ FileHeaderSize
;
545 *SystemFirmwareImageSize
= *SystemFirmwareImageSize
- FileHeaderSize
;
551 Authenticated system firmware FMP capsule image.
553 Caution: This function may receive untrusted input.
555 @param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION.
556 @param[in] ImageSize The size of FMP capsule image in bytes.
557 @param[in] ForceVersionMatch TRUE: The version of capsule must be as same as the version of current image.
558 FALSE: The version of capsule must be as same as greater than the lowest
559 supported version of current image.
560 @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
561 @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR.
562 @param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION.
563 @param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes.
565 @retval TRUE Authentication passes and the authenticated image is extracted.
566 @retval FALSE Authentication fails and the authenticated image is not extracted.
570 CapsuleAuthenticateSystemFirmware (
573 IN BOOLEAN ForceVersionMatch
,
574 OUT UINT32
*LastAttemptVersion
,
575 OUT UINT32
*LastAttemptStatus
,
576 OUT VOID
**AuthenticatedImage
,
577 OUT UINTN
*AuthenticatedImageSize
581 EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
*ImageFmpInfo
;
582 UINTN ImageFmpInfoSize
;
583 EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
*CurrentImageFmpInfo
;
584 UINTN CurrentImageFmpInfoSize
;
585 VOID
*SystemFirmwareImage
;
586 UINTN SystemFirmwareImageSize
;
588 *LastAttemptVersion
= 0;
591 // NOTE: This function need run in an isolated environment.
592 // Do not touch FMP protocol and its private structure.
594 if (mImageFmpInfo
== NULL
) {
595 DEBUG((DEBUG_INFO
, "ImageFmpInfo is not set\n"));
596 return EFI_SECURITY_VIOLATION
;
599 Result
= ExtractAuthenticatedImage((VOID
*)Image
, ImageSize
, LastAttemptStatus
, AuthenticatedImage
, AuthenticatedImageSize
);
601 DEBUG((DEBUG_INFO
, "ExtractAuthenticatedImage - fail\n"));
602 return EFI_SECURITY_VIOLATION
;
605 DEBUG((DEBUG_INFO
, "AuthenticatedImage - 0x%x - 0x%x\n", *AuthenticatedImage
, *AuthenticatedImageSize
));
607 Result
= ExtractSystemFirmwareImage(*AuthenticatedImage
, *AuthenticatedImageSize
, &SystemFirmwareImage
, &SystemFirmwareImageSize
);
609 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT
;
610 DEBUG((DEBUG_INFO
, "ExtractSystemFirmwareImage - fail\n"));
611 return EFI_SECURITY_VIOLATION
;
613 DEBUG((DEBUG_INFO
, "SystemFirmwareImage - 0x%x - 0x%x\n", SystemFirmwareImage
, SystemFirmwareImageSize
));
615 Result
= ExtractSystemFirmwareImageFmpInfo(SystemFirmwareImage
, SystemFirmwareImageSize
, &ImageFmpInfo
, &ImageFmpInfoSize
);
617 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT
;
618 DEBUG((DEBUG_INFO
, "ExtractSystemFirmwareImageFmpInfo - fail\n"));
619 return EFI_SECURITY_VIOLATION
;
622 *LastAttemptVersion
= ImageFmpInfo
->Version
;
623 DEBUG((DEBUG_INFO
, "ImageFmpInfo - 0x%x - 0x%x\n", ImageFmpInfo
, ImageFmpInfoSize
));
624 DEBUG((DEBUG_INFO
, "NewImage Version - 0x%x\n", ImageFmpInfo
->Version
));
625 DEBUG((DEBUG_INFO
, "NewImage LowestSupportedImageVersion - 0x%x\n", ImageFmpInfo
->LowestSupportedImageVersion
));
627 CurrentImageFmpInfo
= mImageFmpInfo
;
628 CurrentImageFmpInfoSize
= mImageFmpInfoSize
;
630 DEBUG((DEBUG_INFO
, "ImageFmpInfo - 0x%x - 0x%x\n", CurrentImageFmpInfo
, CurrentImageFmpInfoSize
));
631 DEBUG((DEBUG_INFO
, "Current Version - 0x%x\n", CurrentImageFmpInfo
->Version
));
632 DEBUG((DEBUG_INFO
, "Current LowestSupportedImageVersion - 0x%x\n", CurrentImageFmpInfo
->LowestSupportedImageVersion
));
634 if (ForceVersionMatch
) {
635 if (CurrentImageFmpInfo
->Version
!= ImageFmpInfo
->Version
) {
636 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION
;
637 DEBUG((DEBUG_INFO
, "ForceVersionMatch check - fail\n"));
638 return EFI_SECURITY_VIOLATION
;
641 if (ImageFmpInfo
->Version
< CurrentImageFmpInfo
->LowestSupportedImageVersion
) {
642 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION
;
643 DEBUG((DEBUG_INFO
, "LowestSupportedImageVersion check - fail\n"));
644 return EFI_SECURITY_VIOLATION
;
648 *LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
653 PcdCallBack gets the real set PCD value
655 @param[in] CallBackGuid The PCD token GUID being set.
656 @param[in] CallBackToken The PCD token number being set.
657 @param[in, out] TokenData A pointer to the token data being set.
658 @param[in] TokenDataSize The size, in bytes, of the data being set.
663 EdkiiSystemCapsuleLibPcdCallBack (
664 IN CONST GUID
*CallBackGuid
, OPTIONAL
665 IN UINTN CallBackToken
,
666 IN OUT VOID
*TokenData
,
667 IN UINTN TokenDataSize
670 if (CompareGuid (CallBackGuid
, &gEfiSignedCapsulePkgTokenSpaceGuid
) &&
671 CallBackToken
== PcdToken (PcdEdkiiSystemFirmwareImageDescriptor
)) {
672 mImageFmpInfoSize
= TokenDataSize
;
673 mImageFmpInfo
= AllocateCopyPool (mImageFmpInfoSize
, TokenData
);
674 ASSERT(mImageFmpInfo
!= NULL
);
676 // Cancel Callback after get the real set value
678 LibPcdCancelCallback (
679 &gEfiSignedCapsulePkgTokenSpaceGuid
,
680 PcdToken (PcdEdkiiSystemFirmwareImageDescriptor
),
681 EdkiiSystemCapsuleLibPcdCallBack
685 if (CompareGuid (CallBackGuid
, &gEfiSignedCapsulePkgTokenSpaceGuid
) &&
686 CallBackToken
== PcdToken (PcdEdkiiSystemFirmwareFileGuid
)) {
687 CopyGuid(&mEdkiiSystemFirmwareFileGuid
, TokenData
);
689 // Cancel Callback after get the real set value
691 LibPcdCancelCallback (
692 &gEfiSignedCapsulePkgTokenSpaceGuid
,
693 PcdToken (PcdEdkiiSystemFirmwareFileGuid
),
694 EdkiiSystemCapsuleLibPcdCallBack
700 The constructor function.
702 @retval EFI_SUCCESS The constructor successfully .
706 EdkiiSystemCapsuleLibConstructor (
710 mImageFmpInfoSize
= PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor
);
711 mImageFmpInfo
= PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor
);
713 // Verify Firmware Image Descriptor first
715 if (mImageFmpInfoSize
< sizeof (EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR
) ||
716 mImageFmpInfo
->Signature
!= EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE
) {
718 // SystemFirmwareImageDescriptor is not set.
719 // Register PCD set callback to hook PCD value set.
721 mImageFmpInfo
= NULL
;
722 mImageFmpInfoSize
= 0;
723 LibPcdCallbackOnSet (
724 &gEfiSignedCapsulePkgTokenSpaceGuid
,
725 PcdToken (PcdEdkiiSystemFirmwareImageDescriptor
),
726 EdkiiSystemCapsuleLibPcdCallBack
729 mImageFmpInfo
= AllocateCopyPool (mImageFmpInfoSize
, mImageFmpInfo
);
730 ASSERT(mImageFmpInfo
!= NULL
);
733 CopyGuid(&mEdkiiSystemFirmwareFileGuid
, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid
));
735 // Verify GUID value first
737 if (CompareGuid (&mEdkiiSystemFirmwareFileGuid
, &gZeroGuid
)) {
738 LibPcdCallbackOnSet (
739 &gEfiSignedCapsulePkgTokenSpaceGuid
,
740 PcdToken (PcdEdkiiSystemFirmwareFileGuid
),
741 EdkiiSystemCapsuleLibPcdCallBack