/** @file This library provides wrapper functions for common platform security event actions. ;****************************************************************************** ;* Copyright (c) 2021, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** This function handles the standard reporting process. @param[in] Event Pointer to the security event information structure. @param[out] EventAction Points to unsigned integer that specifies the action to take for the event. @retval EFI_SUCCESS Function completed successfully. @retval EFI_INVALID_PARAMETER The parameters are invalid. @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated. **/ EFI_STATUS H2OSecurityEventReport ( IN CONST H2O_SECURITY_EVENT *Event, OUT UINT32 *EventAction ) { H2O_SECURITY_EVENT EventData; H2O_STATUS_CODE_SECURITY_EVENT_DATA *StatusCodeData; EFI_STATUS Status; H2O_SECURITY_EVENT_HOB *SecurityEventHob; UINT8 *ExtratData; CHAR8 *ExtraDesc; CHAR8 *HobExtraData; CHAR8 *HobExtraDesc; UINTN DescSize; UINTN Buffersize; if (Event == NULL || EventAction == NULL) { return EFI_INVALID_PARAMETER; } CopyMem (&EventData, Event, sizeof (H2O_SECURITY_EVENT)); if (FeaturePcdGet (PcdH2OBaseCpSecurityEventReportSupported)) { H2O_BASE_CP_SECURITY_EVENT_REPORT_DATA SecurityEventReportData; SecurityEventReportData.Size = sizeof (H2O_BASE_CP_SECURITY_EVENT_REPORT_DATA); SecurityEventReportData.Status = H2O_CP_TASK_NORMAL; CopyMem (&SecurityEventReportData.Event, Event, sizeof (H2O_SECURITY_EVENT)); DEBUG_CP ((DEBUG_INFO, "Checkpoint Trigger: %g\n", &gH2OBaseCpSecurityEventReportGuid)); Status = H2OCpTrigger (&gH2OBaseCpSecurityEventReportGuid, &SecurityEventReportData); DEBUG_CP ((DEBUG_INFO, "Checkpoint Result: %x\n", SecurityEventReportData.Status)); if (SecurityEventReportData.Status == H2O_CP_TASK_UPDATE) { CopyMem (&EventData, &SecurityEventReportData.Event, sizeof (H2O_SECURITY_EVENT)); } else if (SecurityEventReportData.Status == H2O_CP_TASK_SKIP) { goto Done; } } *EventAction = EventData.Event.Action; DescSize = (EventData.EventDesc == NULL) ? 0 : MIN (AsciiStrSize(EventData.EventDesc), H2O_SECURITY_EVENT_DESC_SIZE); if ((EventData.Event.Action & H2O_SECURITY_EVENT_ACTION_POSTCODE) != 0) { PostCodeWithDescription (EventData.Event.PostCode, EventData.EventDesc); } if ((EventData.Event.Action & H2O_SECURITY_EVENT_ACTION_STATUS_CODE) != 0) { Buffersize = sizeof (H2O_STATUS_CODE_SECURITY_EVENT_DATA) + EventData.Event.EventDataSize + DescSize; StatusCodeData = AllocatePages (EFI_SIZE_TO_PAGES(Buffersize)); if (StatusCodeData == NULL) { return EFI_OUT_OF_RESOURCES; } StatusCodeData->Hdr.HeaderSize = sizeof (EFI_STATUS_CODE_DATA); StatusCodeData->Hdr.Size = (UINT16 ) (Buffersize - sizeof (EFI_STATUS_CODE_DATA)); CopyGuid (&StatusCodeData->Hdr.Type, &gEfiStatusCodeDataTypeH2OSecurityEventGuid); CopyMem (&StatusCodeData->Event, &EventData.Event, sizeof (H2O_SECURITY_EVENT_DATA)); if (EventData.Event.EventDataSize > 0) { ExtratData = (UINT8 *) ((UINTN) StatusCodeData + sizeof (H2O_STATUS_CODE_SECURITY_EVENT_DATA)); CopyMem (ExtratData, EventData.EventData, EventData.Event.EventDataSize); } if (EventData.EventDesc != NULL && DescSize > 0) { ExtraDesc = (CHAR8 *) ((UINTN) StatusCodeData + sizeof (H2O_STATUS_CODE_SECURITY_EVENT_DATA) + (UINTN) EventData.Event.EventDataSize); CopyMem (ExtraDesc, EventData.EventDesc, DescSize - 1); ExtraDesc[DescSize - 1] = 0; } REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( StatusCodeData->Event.StatusCodeType, StatusCodeData->Event.StatusCodeValue, (VOID *) StatusCodeData, Buffersize ); FreePages (StatusCodeData, EFI_SIZE_TO_PAGES (Buffersize)); } if ((EventData.Event.Action & H2O_SECURITY_EVENT_ACTION_LOG) != 0) { Buffersize = sizeof (H2O_SECURITY_EVENT_HOB) + (UINTN) EventData.Event.EventDataSize + DescSize; SecurityEventHob = BuildGuidHob (&gH2OSecurityEventHobGuid, Buffersize); CopyGuid (&SecurityEventHob->Hdr.Name, &gH2OSecurityEventHobGuid); CopyMem (&SecurityEventHob->Event, &EventData, sizeof (H2O_SECURITY_EVENT)); if (EventData.Event.EventDataSize > 0) { HobExtraData = (CHAR8 *) ((UINTN) SecurityEventHob + sizeof (H2O_SECURITY_EVENT_HOB)); CopyMem (HobExtraData, EventData.EventData, EventData.Event.EventDataSize); } if (EventData.EventDesc != NULL && DescSize > 0) { HobExtraDesc = (CHAR8 *) ((UINTN) SecurityEventHob + sizeof (H2O_SECURITY_EVENT_HOB) + (UINTN) EventData.Event.EventDataSize); CopyMem (HobExtraDesc, EventData.EventDesc, DescSize - 1); HobExtraDesc[DescSize - 1] = 0; } } if ((EventData.Event.Action & H2O_SECURITY_EVENT_ACTION_SHUTDOWN) != 0) { ResetShutdown (); } if ((EventData.Event.Action & H2O_SECURITY_EVENT_ACTION_RESET) != 0) { ResetWarm (); } Done: return EFI_SUCCESS; }