-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- CoreSectionExtraction.c\r
- \r
-Abstract:\r
-\r
+/** @file\r
Section Extraction Protocol implementation.\r
\r
Stream database is implemented as a linked list of section streams,\r
\r
3) A support protocol is not found, and the data is not available to be read\r
without it. This results in EFI_PROTOCOL_ERROR.\r
- \r
---*/\r
+ \r
+Copyright (c) 2006 - 2008, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+**/\r
\r
#include <DxeMain.h>\r
\r
// Local prototypes\r
//\r
\r
+/**\r
+ Worker function. Determine if the input stream:child matches the input type.\r
+\r
+ @param Stream Indicates the section stream associated with the \r
+ child \r
+ @param Child Indicates the child to check \r
+ @param SearchType Indicates the type of section to check against \r
+ for \r
+ @param SectionDefinitionGuid Indicates the GUID to check against if the type \r
+ is EFI_SECTION_GUID_DEFINED \r
+\r
+ @retval TRUE The child matches \r
+ @retval FALSE The child doesn't match\r
+\r
+**/\r
STATIC\r
BOOLEAN\r
ChildIsType (\r
IN EFI_GUID *SectionDefinitionGuid\r
);\r
\r
+#if 0\r
+/**\r
+ RPN callback function. Removes a stale section stream and re-initializes it\r
+ with an updated AuthenticationStatus.\r
+\r
+ @param Event The event that fired \r
+ @param RpnContext A pointer to the context that allows us to \r
+ identify the relevent encapsulation...\r
+\r
+**/\r
STATIC\r
VOID\r
EFIAPI\r
IN EFI_EVENT Event,\r
IN VOID *RpnContext\r
);\r
+#endif\r
+\r
+#if 0\r
+/**\r
+ Worker function. Constructor for RPN event if needed to keep AuthenticationStatus\r
+ cache correct when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears.\r
+\r
+ @param ParentStream Indicates the parent of the ecnapsulation \r
+ section (child) \r
+ @param ChildNode Indicates the child node that is the \r
+ encapsulation section.\r
\r
+**/\r
STATIC\r
VOID\r
CreateGuidedExtractionRpnEvent (\r
IN CORE_SECTION_STREAM_NODE *ParentStream,\r
IN CORE_SECTION_CHILD_NODE *ChildNode\r
);\r
+#endif\r
\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-OpenSectionStream (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
- IN UINTN SectionStreamLength,\r
- IN VOID *SectionStream,\r
- OUT UINTN *SectionStreamHandle\r
- );\r
- \r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-GetSection (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
- IN UINTN SectionStreamHandle,\r
- IN EFI_SECTION_TYPE *SectionType,\r
- IN EFI_GUID *SectionDefinitionGuid,\r
- IN UINTN SectionInstance,\r
- IN VOID **Buffer,\r
- IN OUT UINTN *BufferSize,\r
- OUT UINT32 *AuthenticationStatus\r
- );\r
- \r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-CloseSectionStream (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
- IN UINTN StreamHandleToClose\r
- );\r
- \r
+/**\r
+ Worker function. Search stream database for requested stream handle.\r
+\r
+ @param SearchHandle Indicates which stream to look for. \r
+ @param FoundStream Output pointer to the found stream. \r
+\r
+ @retval EFI_SUCCESS StreamHandle was found and *FoundStream contains \r
+ the stream node. \r
+ @retval EFI_NOT_FOUND SearchHandle was not found in the stream \r
+ database.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FindStreamNode (\r
OUT CORE_SECTION_STREAM_NODE **FoundStream\r
);\r
\r
+/**\r
+ Worker function Recursively searches / builds section stream database\r
+ looking for requested section.\r
+\r
+ @param SourceStream Indicates the section stream in which to do the \r
+ search. \r
+ @param SearchType Indicates the type of section to search for. \r
+ @param SectionInstance Indicates which instance of section to find. \r
+ This is an in/out parameter to deal with \r
+ recursions. \r
+ @param SectionDefinitionGuid Guid of section definition \r
+ @param FoundChild Output indicating the child node that is found. \r
+ @param FoundStream Output indicating which section stream the child \r
+ was found in. If this stream was generated as a \r
+ result of an encapsulation section, the \r
+ streamhandle is visible within the SEP driver \r
+ only.\r
+ @param AuthenticationStatus Indicates the authentication status of the found section. \r
+\r
+ @retval EFI_SUCCESS Child node was found and returned. \r
+ EFI_OUT_OF_RESOURCES- Memory allocation failed. \r
+ @retval EFI_NOT_FOUND Requested child node does not exist. \r
+ @retval EFI_PROTOCOL_ERROR a required GUIDED section extraction protocol \r
+ does not exist\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FindChildNode (\r
OUT UINT32 *AuthenticationStatus\r
);\r
\r
+/**\r
+ Worker function. Constructor for new child nodes.\r
+\r
+ @param Stream Indicates the section stream in which to add the \r
+ child. \r
+ @param ChildOffset Indicates the offset in Stream that is the \r
+ beginning of the child section. \r
+ @param ChildNode Indicates the Callee allocated and initialized \r
+ child. \r
+\r
+ @retval EFI_SUCCESS Child node was found and returned. \r
+ EFI_OUT_OF_RESOURCES- Memory allocation failed. \r
+ @retval EFI_PROTOCOL_ERROR Encapsulation sections produce new stream \r
+ handles when the child node is created. If the \r
+ section type is GUID defined, and the extraction \r
+ GUID does not exist, and producing the stream \r
+ requires the GUID, then a protocol error is \r
+ generated and no child is produced. Values \r
+ returned by OpenSectionStreamEx.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
CreateChildNode (\r
OUT CORE_SECTION_CHILD_NODE **ChildNode\r
);\r
\r
+/**\r
+ Worker function. Destructor for child nodes.\r
+\r
+ @param ChildNode Indicates the node to destroy\r
+\r
+**/\r
STATIC\r
VOID\r
FreeChildNode (\r
IN CORE_SECTION_CHILD_NODE *ChildNode\r
);\r
\r
+/**\r
+ Worker function. Constructor for section streams.\r
+\r
+ @param SectionStreamLength Size in bytes of the section stream. \r
+ @param SectionStream Buffer containing the new section stream. \r
+ @param AllocateBuffer Indicates whether the stream buffer is to be \r
+ copied or the input buffer is to be used in \r
+ place. AuthenticationStatus- Indicates the \r
+ default authentication status for the new \r
+ stream. \r
+ @param AuthenticationStatus A pointer to a caller-allocated UINT32 that\r
+ indicates the authentication status of the\r
+ output buffer. If the input section¡¯s\r
+ GuidedSectionHeader.Attributes field\r
+ has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
+ bit as clear, AuthenticationStatus must return\r
+ zero. Both local bits (19:16) and aggregate\r
+ bits (3:0) in AuthenticationStatus are returned\r
+ by ExtractSection(). These bits reflect the\r
+ status of the extraction operation. The bit\r
+ pattern in both regions must be the same, as\r
+ the local and aggregate authentication statuses\r
+ have equivalent meaning at this level. If the\r
+ function returns anything other than\r
+ EFI_SUCCESS, the value of *AuthenticationStatus\r
+ is undefined.\r
+ @param SectionStreamHandle A pointer to a caller allocated section stream \r
+ handle. \r
+\r
+ @retval EFI_SUCCESS Stream was added to stream database. \r
+ @retval EFI_OUT_OF_RESOURCES memory allocation failed.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
OpenSectionStreamEx (\r
OUT UINTN *SectionStreamHandle\r
);\r
\r
+/**\r
+ Check if a stream is valid.\r
+\r
+ @param SectionStream The section stream to be checked \r
+ @param SectionStreamLength The length of section stream \r
+\r
+ @return A boolean value indicating the validness of the section stream.\r
+\r
+**/\r
STATIC\r
BOOLEAN\r
IsValidSectionStream (\r
IN VOID *SectionStream,\r
IN UINTN SectionStreamLength\r
);\r
+\r
+/**\r
+ The ExtractSection() function processes the input section and\r
+ allocates a buffer from the pool in which it returns the section\r
+ contents. If the section being extracted contains\r
+ authentication information (the section's\r
+ GuidedSectionHeader.Attributes field has the\r
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values\r
+ returned in AuthenticationStatus must reflect the results of\r
+ the authentication operation. Depending on the algorithm and\r
+ size of the encapsulated data, the time that is required to do\r
+ a full authentication may be prohibitively long for some\r
+ classes of systems. To indicate this, use\r
+ EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by\r
+ the security policy driver (see the Platform Initialization\r
+ Driver Execution Environment Core Interface Specification for\r
+ more details and the GUID definition). If the\r
+ EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle\r
+ database, then, if possible, full authentication should be\r
+ skipped and the section contents simply returned in the\r
+ OutputBuffer. In this case, the\r
+ EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus\r
+ must be set on return. ExtractSection() is callable only from\r
+ TPL_NOTIFY and below. Behavior of ExtractSection() at any\r
+ EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is\r
+ defined in RaiseTPL() in the UEFI 2.0 specification.\r
+\r
\r
+ @param This Indicates the\r
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.\r
+\r
+ @param InputSection Buffer containing the input GUIDed section\r
+ to be processed. OutputBuffer OutputBuffer\r
+ is allocated from boot services pool\r
+ memory and contains the new section\r
+ stream. The caller is responsible for\r
+ freeing this buffer.\r
+ @param OutputBuffer *OutputBuffer is allocated from boot services\r
+ pool memory and contains the new section stream.\r
+ The caller is responsible for freeing this buffer.\r
+ @param OutputSize A pointer to a caller-allocated UINTN in\r
+ which the size of OutputBuffer allocation\r
+ is stored. If the function returns\r
+ anything other than EFI_SUCCESS, the value\r
+ of OutputSize is undefined.\r
+\r
+ @param AuthenticationStatus A pointer to a caller-allocated\r
+ UINT32 that indicates the\r
+ authentication status of the\r
+ output buffer. If the input\r
+ section's\r
+ GuidedSectionHeader.Attributes\r
+ field has the\r
+ EFI_GUIDED_SECTION_AUTH_STATUS_VAL\r
+ bit as clear, AuthenticationStatus\r
+ must return zero. Both local bits\r
+ (19:16) and aggregate bits (3:0)\r
+ in AuthenticationStatus are\r
+ returned by ExtractSection().\r
+ These bits reflect the status of\r
+ the extraction operation. The bit\r
+ pattern in both regions must be\r
+ the same, as the local and\r
+ aggregate authentication statuses\r
+ have equivalent meaning at this\r
+ level. If the function returns\r
+ anything other than EFI_SUCCESS,\r
+ the value of AuthenticationStatus\r
+ is undefined.\r
+\r
+\r
+ @retval EFI_SUCCESS The InputSection was successfully\r
+ processed and the section contents were\r
+ returned.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
+ resources to process the\r
+ request.\r
+\r
+ @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
+ not match this instance of the\r
+ GUIDed Section Extraction\r
+ Protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CustomGuidedSectionExtract (\r
+ IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,\r
+ IN CONST VOID *InputSection,\r
+ OUT VOID **OutputBuffer,\r
+ OUT UINTN *OutputSize,\r
+ OUT UINT32 *AuthenticationStatus\r
+ ); \r
//\r
// Module globals\r
//\r
\r
EFI_HANDLE mSectionExtractionHandle = NULL;\r
\r
-EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = { \r
- OpenSectionStream, \r
- GetSection, \r
- CloseSectionStream\r
+EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomGuidedSectionExtractionProtocol = {\r
+ CustomGuidedSectionExtract\r
};\r
-\r
\r
+\r
+/**\r
+ Entry point of the section extraction code. Initializes an instance of the\r
+ section extraction interface and installs it on a new handle.\r
+\r
+ @param ImageHandle A handle for the image that is initializing this driver\r
+ @param SystemTable A pointer to the EFI system table\r
+\r
+ @retval EFI_SUCCESS Driver initialized successfully\r
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
InitializeSectionExtraction (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
-/*++\r
-\r
-Routine Description: \r
- Entry point of the section extraction code. Initializes an instance of the \r
- section extraction interface and installs it on a new handle.\r
-\r
-Arguments: \r
- ImageHandle EFI_HANDLE: A handle for the image that is initializing this driver\r
- SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table \r
-\r
-Returns: \r
- EFI_SUCCESS: Driver initialized successfully\r
- EFI_OUT_OF_RESOURCES: Could not allocate needed resources\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
+ EFI_GUID *ExtractHandlerGuidTable;\r
+ UINTN ExtractHandlerNumber;\r
\r
//\r
- // Install SEP to a new handle\r
+ // Get custom extract guided section method guid list \r
+ //\r
+ ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
+ \r
+ Status = EFI_SUCCESS;\r
+ //\r
+ // Install custom guided extraction protocol \r
//\r
- Status = CoreInstallProtocolInterface (\r
- &mSectionExtractionHandle,\r
- &gEfiSectionExtractionProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mSectionExtraction\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ while (ExtractHandlerNumber-- > 0) {\r
+ Status = CoreInstallProtocolInterface (\r
+ &mSectionExtractionHandle,\r
+ &ExtractHandlerGuidTable [ExtractHandlerNumber],\r
+ EFI_NATIVE_INTERFACE,\r
+ &mCustomGuidedSectionExtractionProtocol\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
\r
return Status;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ SEP member function. This function creates and returns a new section stream\r
+ handle to represent the new section stream.\r
+\r
+ @param SectionStreamLength Size in bytes of the section stream. \r
+ @param SectionStream Buffer containing the new section stream. \r
+ @param SectionStreamHandle A pointer to a caller allocated UINTN that on \r
+ output contains the new section stream handle. \r
+\r
+ @retval EFI_SUCCESS The section stream is created successfully.\r
+ @retval EFI_OUT_OF_RESOURCES memory allocation failed. \r
+ @retval EFI_INVALID_PARAMETER Section stream does not end concident with end \r
+ of last section.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
OpenSectionStream (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
IN UINTN SectionStreamLength,\r
IN VOID *SectionStream,\r
OUT UINTN *SectionStreamHandle\r
)\r
-/*++\r
-\r
-Routine Description:\r
- SEP member function. This function creates and returns a new section stream\r
- handle to represent the new section stream.\r
-\r
-Arguments:\r
- This - Indicates the calling context.\r
- SectionStreamLength - Size in bytes of the section stream.\r
- SectionStream - Buffer containing the new section stream.\r
- SectionStreamHandle - A pointer to a caller allocated UINTN that on output\r
- contains the new section stream handle.\r
-\r
-Returns:\r
- EFI_SUCCESS\r
- EFI_OUT_OF_RESOURCES - memory allocation failed.\r
- EFI_INVALID_PARAMETER - section stream does not end concident with end of\r
- last section.\r
-\r
---*/\r
{\r
//\r
// Check to see section stream looks good...\r
);\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ SEP member function. Retrieves requested section from section stream.\r
+\r
+ @param SectionStreamHandle The section stream from which to extract the\r
+ requested section.\r
+ @param SectionType A pointer to the type of section to search for.\r
+ @param SectionDefinitionGuid If the section type is EFI_SECTION_GUID_DEFINED,\r
+ then SectionDefinitionGuid indicates which of\r
+ these types of sections to search for.\r
+ @param SectionInstance Indicates which instance of the requested\r
+ section to return.\r
+ @param Buffer Double indirection to buffer. If *Buffer is\r
+ non-null on input, then the buffer is caller\r
+ allocated. If Buffer is NULL, then the buffer\r
+ is callee allocated. In either case, the\r
+ requried buffer size is returned in *BufferSize.\r
+ @param BufferSize On input, indicates the size of *Buffer if\r
+ *Buffer is non-null on input. On output,\r
+ indicates the required size (allocated size if\r
+ callee allocated) of *Buffer.\r
+ @param AuthenticationStatus A pointer to a caller-allocated UINT32 that\r
+ indicates the authentication status of the\r
+ output buffer. If the input section¡¯s\r
+ GuidedSectionHeader.Attributes field\r
+ has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
+ bit as clear, AuthenticationStatus must return\r
+ zero. Both local bits (19:16) and aggregate\r
+ bits (3:0) in AuthenticationStatus are returned\r
+ by ExtractSection(). These bits reflect the\r
+ status of the extraction operation. The bit\r
+ pattern in both regions must be the same, as\r
+ the local and aggregate authentication statuses\r
+ have equivalent meaning at this level. If the\r
+ function returns anything other than\r
+ EFI_SUCCESS, the value of *AuthenticationStatus\r
+ is undefined.\r
+\r
+ @retval EFI_SUCCESS Section was retrieved successfully\r
+ @retval EFI_PROTOCOL_ERROR A GUID defined section was encountered in the\r
+ section stream with its\r
+ EFI_GUIDED_SECTION_PROCESSING_REQUIRED bit set,\r
+ but there was no corresponding GUIDed Section\r
+ Extraction Protocol in the handle database.\r
+ *Buffer is unmodified.\r
+ @retval EFI_NOT_FOUND An error was encountered when parsing the\r
+ SectionStream. This indicates the SectionStream\r
+ is not correctly formatted.\r
+ @retval EFI_NOT_FOUND The requested section does not exist.\r
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to process\r
+ the request.\r
+ @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.\r
+ @retval EFI_WARN_TOO_SMALL The size of the caller allocated input buffer is\r
+ insufficient to contain the requested section.\r
+ The input buffer is filled and section contents\r
+ are truncated.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
GetSection (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
IN UINTN SectionStreamHandle,\r
IN EFI_SECTION_TYPE *SectionType,\r
IN EFI_GUID *SectionDefinitionGuid,\r
IN OUT UINTN *BufferSize,\r
OUT UINT32 *AuthenticationStatus\r
)\r
-/*++\r
-\r
-Routine Description:\r
- SEP member function. Retrieves requested section from section stream.\r
-\r
-Arguments: \r
- This: Pointer to SEP instance.\r
- SectionStreamHandle: The section stream from which to extract the requested\r
- section.\r
- SectionType: A pointer to the type of section to search for.\r
- SectionDefinitionGuid: If the section type is EFI_SECTION_GUID_DEFINED, then\r
- SectionDefinitionGuid indicates which of these types\r
- of sections to search for.\r
- SectionInstance: Indicates which instance of the requested section to\r
- return.\r
- Buffer: Double indirection to buffer. If *Buffer is non-null on\r
- input, then the buffer is caller allocated. If\r
- *Buffer is NULL, then the buffer is callee allocated.\r
- In either case, the requried buffer size is returned\r
- in *BufferSize.\r
- BufferSize: On input, indicates the size of *Buffer if *Buffer is\r
- non-null on input. On output, indicates the required\r
- size (allocated size if callee allocated) of *Buffer.\r
- AuthenticationStatus: Indicates the authentication status of the retrieved\r
- section.\r
-\r
-Returns: \r
- EFI_SUCCESS: Section was retrieved successfully\r
- EFI_PROTOCOL_ERROR: A GUID defined section was encountered in the section \r
- stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED\r
- bit set, but there was no corresponding GUIDed Section \r
- Extraction Protocol in the handle database. *Buffer is \r
- unmodified.\r
- EFI_NOT_FOUND: An error was encountered when parsing the SectionStream.\r
- This indicates the SectionStream is not correctly \r
- formatted.\r
- EFI_NOT_FOUND: The requested section does not exist.\r
- EFI_OUT_OF_RESOURCES: The system has insufficient resources to process the \r
- request.\r
- EFI_INVALID_PARAMETER: The SectionStreamHandle does not exist.\r
- EFI_WARN_TOO_SMALL: The size of the caller allocated input buffer is \r
- insufficient to contain the requested section. The \r
- input buffer is filled and contents are section contents\r
- are truncated.\r
-\r
---*/\r
{\r
CORE_SECTION_STREAM_NODE *StreamNode;\r
EFI_TPL OldTpl;\r
}\r
\r
\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-CloseSectionStream (\r
- IN EFI_SECTION_EXTRACTION_PROTOCOL *This,\r
- IN UINTN StreamHandleToClose\r
- )\r
-/*++\r
\r
-Routine Description:\r
+/**\r
SEP member function. Deletes an existing section stream\r
\r
-Arguments:\r
- This - Indicates the calling context.\r
- StreamHandleToClose - Indicates the stream to close\r
+ @param StreamHandleToClose Indicates the stream to close \r
\r
-Returns:\r
- EFI_SUCCESS\r
- EFI_OUT_OF_RESOURCES - memory allocation failed.\r
- EFI_INVALID_PARAMETER - section stream does not end concident with end of\r
- last section.\r
+ @retval EFI_SUCCESS The section stream is closed sucessfully.\r
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed. \r
+ @retval EFI_INVALID_PARAMETER Section stream does not end concident with end \r
+ of last section.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CloseSectionStream (\r
+ IN UINTN StreamHandleToClose\r
+ )\r
{\r
CORE_SECTION_STREAM_NODE *StreamNode;\r
EFI_TPL OldTpl;\r
}\r
\r
\r
+\r
+/**\r
+ Worker function. Determine if the input stream:child matches the input type.\r
+\r
+ @param Stream Indicates the section stream associated with the \r
+ child \r
+ @param Child Indicates the child to check \r
+ @param SearchType Indicates the type of section to check against \r
+ for \r
+ @param SectionDefinitionGuid Indicates the GUID to check against if the type \r
+ is EFI_SECTION_GUID_DEFINED \r
+\r
+ @retval TRUE The child matches \r
+ @retval FALSE The child doesn't match\r
+\r
+**/\r
STATIC\r
BOOLEAN\r
ChildIsType (\r
IN EFI_SECTION_TYPE SearchType,\r
IN EFI_GUID *SectionDefinitionGuid\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Worker function. Determine if the input stream:child matches the input type.\r
-\r
-Arguments:\r
- Stream - Indicates the section stream associated with the child\r
- Child - Indicates the child to check\r
- SearchType - Indicates the type of section to check against for\r
- SectionDefinitionGuid - Indicates the GUID to check against if the type is\r
- EFI_SECTION_GUID_DEFINED\r
-Returns:\r
- TRUE - The child matches\r
- FALSE - The child doesn't match\r
-\r
---*/\r
{\r
EFI_GUID_DEFINED_SECTION *GuidedSection;\r
\r
}\r
\r
\r
+\r
+/**\r
+ Worker function Recursively searches / builds section stream database\r
+ looking for requested section.\r
+\r
+ @param SourceStream Indicates the section stream in which to do the \r
+ search. \r
+ @param SearchType Indicates the type of section to search for. \r
+ @param SectionInstance Indicates which instance of section to find. \r
+ This is an in/out parameter to deal with \r
+ recursions. \r
+ @param SectionDefinitionGuid Guid of section definition \r
+ @param FoundChild Output indicating the child node that is found. \r
+ @param FoundStream Output indicating which section stream the child \r
+ was found in. If this stream was generated as a \r
+ result of an encapsulation section, the \r
+ streamhandle is visible within the SEP driver \r
+ only.\r
+ @param AuthenticationStatus Indicates the authentication status of the found section. \r
+\r
+ @retval EFI_SUCCESS Child node was found and returned. \r
+ EFI_OUT_OF_RESOURCES- Memory allocation failed. \r
+ @retval EFI_NOT_FOUND Requested child node does not exist. \r
+ @retval EFI_PROTOCOL_ERROR a required GUIDED section extraction protocol \r
+ does not exist\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FindChildNode (\r
OUT CORE_SECTION_STREAM_NODE **FoundStream,\r
OUT UINT32 *AuthenticationStatus\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Worker function Recursively searches / builds section stream database\r
- looking for requested section.\r
-\r
-Arguments:\r
- SourceStream - Indicates the section stream in which to do the search.\r
- SearchType - Indicates the type of section to search for.\r
- SectionInstance - Indicates which instance of section to find. This is\r
- an in/out parameter to deal with recursions.\r
- SectionDefinitionGuid - Guid of section definition\r
- FoundChild - Output indicating the child node that is found.\r
- FoundStream - Output indicating which section stream the child was\r
- found in. If this stream was generated as a result of\r
- an encapsulation section, the streamhandle is visible\r
- within the SEP driver only.\r
- AuthenticationStatus- Indicates the authentication status of the found section.\r
-\r
-Returns:\r
- EFI_SUCCESS - Child node was found and returned.\r
- EFI_OUT_OF_RESOURCES- Memory allocation failed.\r
- EFI_NOT_FOUND - Requested child node does not exist.\r
- EFI_PROTOCOL_ERROR - a required GUIDED section extraction protocol does not\r
- exist\r
-\r
---*/\r
{\r
CORE_SECTION_CHILD_NODE *CurrentChildNode;\r
CORE_SECTION_CHILD_NODE *RecursedChildNode;\r
}\r
\r
if (IsListEmpty (&SourceStream->Children) && \r
- SourceStream->StreamLength > sizeof (EFI_COMMON_SECTION_HEADER)) {\r
+ SourceStream->StreamLength >= sizeof (EFI_COMMON_SECTION_HEADER)) {\r
//\r
// This occurs when a section stream exists, but no child sections\r
// have been parsed out yet. Therefore, extract the first child and add it\r
// to the list of children so we can get started.\r
+ // Section stream may contain an array of zero or more bytes. \r
+ // So, its size should be >= the size of commen section header.\r
//\r
Status = CreateChildNode (SourceStream, 0, &CurrentChildNode);\r
if (EFI_ERROR (Status)) {\r
}\r
\r
\r
+\r
+/**\r
+ Worker function. Constructor for new child nodes.\r
+\r
+ @param Stream Indicates the section stream in which to add the \r
+ child. \r
+ @param ChildOffset Indicates the offset in Stream that is the \r
+ beginning of the child section. \r
+ @param ChildNode Indicates the Callee allocated and initialized \r
+ child. \r
+\r
+ @retval EFI_SUCCESS Child node was found and returned. \r
+ EFI_OUT_OF_RESOURCES- Memory allocation failed. \r
+ @retval EFI_PROTOCOL_ERROR Encapsulation sections produce new stream \r
+ handles when the child node is created. If the \r
+ section type is GUID defined, and the extraction \r
+ GUID does not exist, and producing the stream \r
+ requires the GUID, then a protocol error is \r
+ generated and no child is produced. Values \r
+ returned by OpenSectionStreamEx.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
CreateChildNode (\r
IN UINT32 ChildOffset,\r
OUT CORE_SECTION_CHILD_NODE **ChildNode\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Worker function. Constructor for new child nodes.\r
-\r
-Arguments:\r
- Stream - Indicates the section stream in which to add the child.\r
- ChildOffset - Indicates the offset in Stream that is the beginning\r
- of the child section.\r
- ChildNode - Indicates the Callee allocated and initialized child.\r
-\r
-Returns:\r
- EFI_SUCCESS - Child node was found and returned.\r
- EFI_OUT_OF_RESOURCES- Memory allocation failed.\r
- EFI_PROTOCOL_ERROR - Encapsulation sections produce new stream handles when\r
- the child node is created. If the section type is GUID\r
- defined, and the extraction GUID does not exist, and\r
- producing the stream requires the GUID, then a protocol\r
- error is generated and no child is produced.\r
- Values returned by OpenSectionStreamEx.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_COMMON_SECTION_HEADER *SectionHeader;\r
EFI_COMPRESSION_SECTION *CompressionHeader;\r
EFI_GUID_DEFINED_SECTION *GuidedHeader;\r
- EFI_TIANO_DECOMPRESS_PROTOCOL *Decompress;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction;\r
VOID *NewStreamBuffer;\r
VOID *ScratchBuffer;\r
//\r
// OR in the parent stream's aggregate status.\r
//\r
- AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;\r
+ AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AUTH_STATUS_ALL;\r
} else {\r
//\r
// since there's no authentication data contributed by the section,\r
// Figure out the proper authentication status\r
//\r
AuthenticationStatus = Stream->AuthenticationStatus;\r
- if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {\r
- //\r
- // The local status of the new stream is contained in \r
- // AuthenticaionStatus. This value needs to be ORed into the\r
- // Aggregate bits also...\r
- //\r
- \r
- //\r
- // Clear out and initialize the local status\r
- //\r
- AuthenticationStatus &= ~EFI_LOCAL_AUTH_STATUS_ALL;\r
- AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED;\r
- //\r
- // OR local status into aggregate status\r
- //\r
- AuthenticationStatus |= AuthenticationStatus >> 16;\r
- }\r
\r
SectionLength = SECTION_SIZE (GuidedHeader);\r
Status = OpenSectionStreamEx (\r
}\r
}\r
\r
- if ((AuthenticationStatus & EFI_LOCAL_AUTH_STATUS_ALL) == \r
- (EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED)) {\r
- //\r
- // Need to register for RPN for when the required GUIDed extraction\r
- // protocol becomes available. This will enable us to refresh the\r
- // AuthenticationStatus cached in the Stream if it's ever requested\r
- // again.\r
- //\r
- CreateGuidedExtractionRpnEvent (Stream, Node);\r
- }\r
- \r
break;\r
\r
default:\r
}\r
\r
\r
+#if 0\r
+/**\r
+ Worker function. Constructor for RPN event if needed to keep AuthenticationStatus\r
+ cache correct when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...\r
+\r
+ @param ParentStream Indicates the parent of the ecnapsulation \r
+ section (child) \r
+ @param ChildNode Indicates the child node that is the \r
+ encapsulation section.\r
+\r
+**/\r
STATIC\r
VOID\r
CreateGuidedExtractionRpnEvent (\r
IN CORE_SECTION_STREAM_NODE *ParentStream,\r
IN CORE_SECTION_CHILD_NODE *ChildNode\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Worker function. Constructor for RPN event if needed to keep AuthenticationStatus\r
- cache correct when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...\r
-\r
-Arguments:\r
- ParentStream - Indicates the parent of the ecnapsulation section (child)\r
- ChildNode - Indicates the child node that is the encapsulation section.\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
{\r
RPN_EVENT_CONTEXT *Context;\r
\r
FALSE\r
);\r
}\r
- \r
- \r
+#endif\r
+\r
+\r
+#if 0\r
+/**\r
+ RPN callback function. Removes a stale section stream and re-initializes it\r
+ with an updated AuthenticationStatus.\r
+\r
+ @param Event The event that fired \r
+ @param RpnContext A pointer to the context that allows us to \r
+ identify the relevent encapsulation...\r
+\r
+**/\r
STATIC\r
VOID\r
EFIAPI\r
IN EFI_EVENT Event,\r
IN VOID *RpnContext\r
)\r
-/*++\r
-\r
-Routine Description:\r
- RPN callback function. Removes a stale section stream and re-initializes it\r
- with an updated AuthenticationStatus.\r
-\r
-Arguments:\r
- Event - The event that fired\r
- RpnContext - A pointer to the context that allows us to identify\r
- the relevent encapsulation...\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_GUID_DEFINED_SECTION *GuidedHeader;\r
\r
Context = RpnContext;\r
\r
- Status = CloseSectionStream (&mSectionExtraction, Context->ChildNode->EncapsulatedStreamHandle);\r
+ Status = CloseSectionStream (Context->ChildNode->EncapsulatedStreamHandle);\r
if (!EFI_ERROR (Status)) {\r
//\r
// The stream closed successfully, so re-open the stream with correct AuthenticationStatus\r
//\r
// OR in the parent stream's aggregagate status.\r
//\r
- AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;\r
+ AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AUTH_STATUS_ALL;\r
Status = OpenSectionStreamEx (\r
NewStreamBufferSize,\r
NewStreamBuffer,\r
CoreCloseEvent (Event);\r
CoreFreePool (Context);\r
} \r
- \r
+#endif\r
+\r
+/**\r
+ Worker function. Destructor for child nodes.\r
+\r
+ @param ChildNode Indicates the node to destroy\r
\r
+**/\r
STATIC\r
VOID\r
FreeChildNode (\r
IN CORE_SECTION_CHILD_NODE *ChildNode\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Worker function. Destructor for child nodes.\r
-\r
-Arguments:\r
- ChildNode - Indicates the node to destroy\r
-\r
-Returns:\r
- none\r
-\r
---*/\r
{\r
ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);\r
//\r
// If it's an encapsulating section, we close the resulting section stream.\r
// CloseSectionStream will free all memory associated with the stream.\r
//\r
- CloseSectionStream (&mSectionExtraction, ChildNode->EncapsulatedStreamHandle);\r
+ CloseSectionStream (ChildNode->EncapsulatedStreamHandle);\r
}\r
//\r
// Last, free the child node itself\r
} \r
\r
\r
+\r
+/**\r
+ Worker function. Constructor for section streams.\r
+\r
+ @param SectionStreamLength Size in bytes of the section stream. \r
+ @param SectionStream Buffer containing the new section stream. \r
+ @param AllocateBuffer Indicates whether the stream buffer is to be \r
+ copied or the input buffer is to be used in \r
+ place. AuthenticationStatus- Indicates the \r
+ default authentication status for the new \r
+ stream. \r
+ @param AuthenticationStatus A pointer to a caller-allocated UINT32 that\r
+ indicates the authentication status of the\r
+ output buffer. If the input section¡¯s\r
+ GuidedSectionHeader.Attributes field\r
+ has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
+ bit as clear, AuthenticationStatus must return\r
+ zero. Both local bits (19:16) and aggregate\r
+ bits (3:0) in AuthenticationStatus are returned\r
+ by ExtractSection(). These bits reflect the\r
+ status of the extraction operation. The bit\r
+ pattern in both regions must be the same, as\r
+ the local and aggregate authentication statuses\r
+ have equivalent meaning at this level. If the\r
+ function returns anything other than\r
+ EFI_SUCCESS, the value of *AuthenticationStatus\r
+ is undefined.\r
+ @param SectionStreamHandle A pointer to a caller allocated section stream \r
+ handle. \r
+\r
+ @retval EFI_SUCCESS Stream was added to stream database. \r
+ @retval EFI_OUT_OF_RESOURCES memory allocation failed.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
OpenSectionStreamEx (\r
IN UINT32 AuthenticationStatus, \r
OUT UINTN *SectionStreamHandle\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Worker function. Constructor for section streams.\r
-\r
- Arguments:\r
- SectionStreamLength - Size in bytes of the section stream.\r
- SectionStream - Buffer containing the new section stream.\r
- AllocateBuffer - Indicates whether the stream buffer is to be copied\r
- or the input buffer is to be used in place.\r
- AuthenticationStatus- Indicates the default authentication status for the\r
- new stream.\r
- SectionStreamHandle - A pointer to a caller allocated section stream handle.\r
-\r
- Returns:\r
- EFI_SUCCESS - Stream was added to stream database.\r
- EFI_OUT_OF_RESOURCES - memory allocation failed.\r
-\r
---*/\r
{\r
CORE_SECTION_STREAM_NODE *NewStream;\r
EFI_TPL OldTpl;\r
}\r
\r
\r
+\r
+/**\r
+ Worker function. Search stream database for requested stream handle.\r
+\r
+ @param SearchHandle Indicates which stream to look for. \r
+ @param FoundStream Output pointer to the found stream. \r
+\r
+ @retval EFI_SUCCESS StreamHandle was found and *FoundStream contains \r
+ the stream node. \r
+ @retval EFI_NOT_FOUND SearchHandle was not found in the stream \r
+ database.\r
+\r
+**/\r
STATIC\r
EFI_STATUS\r
FindStreamNode (\r
IN UINTN SearchHandle,\r
OUT CORE_SECTION_STREAM_NODE **FoundStream\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Worker function. Search stream database for requested stream handle.\r
-\r
- Arguments:\r
- SearchHandle - Indicates which stream to look for.\r
- FoundStream - Output pointer to the found stream.\r
-\r
- Returns:\r
- EFI_SUCCESS - StreamHandle was found and *FoundStream contains\r
- the stream node.\r
- EFI_NOT_FOUND - SearchHandle was not found in the stream database.\r
-\r
---*/\r
{ \r
CORE_SECTION_STREAM_NODE *StreamNode;\r
\r
}\r
\r
\r
+\r
+/**\r
+ Check if a stream is valid.\r
+\r
+ @param SectionStream The section stream to be checked \r
+ @param SectionStreamLength The length of section stream \r
+\r
+ @return A boolean value indicating the validness of the section stream.\r
+\r
+**/\r
STATIC\r
BOOLEAN\r
IsValidSectionStream (\r
IN VOID *SectionStream,\r
IN UINTN SectionStreamLength\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Check if a stream is valid.\r
-\r
-Arguments:\r
- SectionStream - The section stream to be checked\r
- SectionStreamLength - The length of section stream\r
-\r
-Returns:\r
- TRUE\r
- FALSE\r
-\r
---*/\r
{\r
UINTN TotalLength;\r
UINTN SectionLength;\r
ASSERT (FALSE);\r
return FALSE;\r
}\r
+\r
+/**\r
+ The ExtractSection() function processes the input section and\r
+ allocates a buffer from the pool in which it returns the section\r
+ contents. If the section being extracted contains\r
+ authentication information (the section's\r
+ GuidedSectionHeader.Attributes field has the\r
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values\r
+ returned in AuthenticationStatus must reflect the results of\r
+ the authentication operation. Depending on the algorithm and\r
+ size of the encapsulated data, the time that is required to do\r
+ a full authentication may be prohibitively long for some\r
+ classes of systems. To indicate this, use\r
+ EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by\r
+ the security policy driver (see the Platform Initialization\r
+ Driver Execution Environment Core Interface Specification for\r
+ more details and the GUID definition). If the\r
+ EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle\r
+ database, then, if possible, full authentication should be\r
+ skipped and the section contents simply returned in the\r
+ OutputBuffer. In this case, the\r
+ EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus\r
+ must be set on return. ExtractSection() is callable only from\r
+ TPL_NOTIFY and below. Behavior of ExtractSection() at any\r
+ EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is\r
+ defined in RaiseTPL() in the UEFI 2.0 specification.\r
+\r
+ \r
+ @param This Indicates the\r
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.\r
+\r
+ @param InputSection Buffer containing the input GUIDed section\r
+ to be processed. OutputBuffer OutputBuffer\r
+ is allocated from boot services pool\r
+ memory and contains the new section\r
+ stream. The caller is responsible for\r
+ freeing this buffer.\r
+ @param OutputBuffer *OutputBuffer is allocated from boot services\r
+ pool memory and contains the new section stream.\r
+ The caller is responsible for freeing this buffer.\r
+ @param OutputSize A pointer to a caller-allocated UINTN in\r
+ which the size of OutputBuffer allocation\r
+ is stored. If the function returns\r
+ anything other than EFI_SUCCESS, the value\r
+ of OutputSize is undefined.\r
+\r
+ @param AuthenticationStatus A pointer to a caller-allocated\r
+ UINT32 that indicates the\r
+ authentication status of the\r
+ output buffer. If the input\r
+ section's\r
+ GuidedSectionHeader.Attributes\r
+ field has the\r
+ EFI_GUIDED_SECTION_AUTH_STATUS_VAL\r
+ bit as clear, AuthenticationStatus\r
+ must return zero. Both local bits\r
+ (19:16) and aggregate bits (3:0)\r
+ in AuthenticationStatus are\r
+ returned by ExtractSection().\r
+ These bits reflect the status of\r
+ the extraction operation. The bit\r
+ pattern in both regions must be\r
+ the same, as the local and\r
+ aggregate authentication statuses\r
+ have equivalent meaning at this\r
+ level. If the function returns\r
+ anything other than EFI_SUCCESS,\r
+ the value of AuthenticationStatus\r
+ is undefined.\r
+\r
+\r
+ @retval EFI_SUCCESS The InputSection was successfully\r
+ processed and the section contents were\r
+ returned.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
+ resources to process the\r
+ request.\r
+\r
+ @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
+ not match this instance of the\r
+ GUIDed Section Extraction\r
+ Protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CustomGuidedSectionExtract (\r
+ IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,\r
+ IN CONST VOID *InputSection,\r
+ OUT VOID **OutputBuffer,\r
+ OUT UINTN *OutputSize,\r
+ OUT UINT32 *AuthenticationStatus\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *ScratchBuffer;\r
+ VOID *AllocatedOutputBuffer;\r
+ UINT32 OutputBufferSize;\r
+ UINT32 ScratchBufferSize;\r
+ UINT16 SectionAttribute;\r
+ \r
+ //\r
+ // Init local variable\r
+ //\r
+ ScratchBuffer = NULL;\r
+ AllocatedOutputBuffer = NULL;\r
+\r
+ //\r
+ // Call GetInfo to get the size and attribute of input guided section data.\r
+ //\r
+ Status = ExtractGuidedSectionGetInfo (\r
+ InputSection,\r
+ &OutputBufferSize,\r
+ &ScratchBufferSize,\r
+ &SectionAttribute\r
+ );\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
+ return Status;\r
+ }\r
+ \r
+ if (ScratchBufferSize != 0) {\r
+ //\r
+ // Allocate scratch buffer\r
+ //\r
+ ScratchBuffer = CoreAllocateBootServicesPool (ScratchBufferSize);\r
+ if (ScratchBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+ if (OutputBufferSize > 0) { \r
+ //\r
+ // Allocate output buffer\r
+ //\r
+ AllocatedOutputBuffer = CoreAllocateBootServicesPool (OutputBufferSize);\r
+ if (AllocatedOutputBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ *OutputBuffer = AllocatedOutputBuffer;\r
+ }\r
+\r
+ //\r
+ // Call decode function to extract raw data from the guided section.\r
+ //\r
+ Status = ExtractGuidedSectionDecode (\r
+ InputSection, \r
+ OutputBuffer,\r
+ ScratchBuffer,\r
+ AuthenticationStatus\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Decode failed\r
+ //\r
+ if (AllocatedOutputBuffer != NULL) {\r
+ CoreFreePool (AllocatedOutputBuffer);\r
+ }\r
+ if (ScratchBuffer != NULL) {\r
+ CoreFreePool (ScratchBuffer);\r
+ }\r
+ DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ if (*OutputBuffer != AllocatedOutputBuffer) {\r
+ //\r
+ // OutputBuffer was returned as a different value, \r
+ // so copy section contents to the allocated memory buffer.\r
+ // \r
+ CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize);\r
+ *OutputBuffer = AllocatedOutputBuffer;\r
+ }\r
+\r
+ //\r
+ // Set real size of output buffer.\r
+ //\r
+ *OutputSize = (UINTN) OutputBufferSize;\r
+\r
+ //\r
+ // Free unused scratch buffer.\r
+ //\r
+ if (ScratchBuffer != NULL) {\r
+ CoreFreePool (ScratchBuffer);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r