1 /** @file
2   EFI PEI Core Security services
3 
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include "PeiMain.h"
10 
11 
12 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
13    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
14    &gEfiPeiSecurity2PpiGuid,
15    SecurityPpiNotifyCallback
16 };
17 
18 /**
19   Initialize the security services.
20 
21   @param PeiServices     An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
22   @param OldCoreData     Pointer to the old core data.
23                          NULL if being run in non-permanent memory mode.
24 
25 **/
26 VOID
InitializeSecurityServices(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_CORE_INSTANCE * OldCoreData)27 InitializeSecurityServices (
28   IN EFI_PEI_SERVICES  **PeiServices,
29   IN PEI_CORE_INSTANCE *OldCoreData
30   )
31 {
32   if (OldCoreData == NULL) {
33     PeiServicesNotifyPpi (&mNotifyList);
34   }
35   return;
36 }
37 
38 /**
39 
40   Provide a callback for when the security PPI is installed.
41   This routine will cache installed security PPI into PeiCore's private data.
42 
43   @param PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
44   @param NotifyDescriptor   The descriptor for the notification event.
45   @param Ppi                Pointer to the PPI in question.
46 
47   @return Always success
48 
49 **/
50 EFI_STATUS
51 EFIAPI
SecurityPpiNotifyCallback(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDescriptor,IN VOID * Ppi)52 SecurityPpiNotifyCallback (
53   IN EFI_PEI_SERVICES           **PeiServices,
54   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
55   IN VOID                       *Ppi
56   )
57 {
58   PEI_CORE_INSTANCE                       *PrivateData;
59 
60   //
61   // Get PEI Core private data
62   //
63   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
64 
65   //
66   // If there isn't a security PPI installed, use the one from notification
67   //
68   if (PrivateData->PrivateSecurityPpi == NULL) {
69     PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi;
70   }
71   return EFI_SUCCESS;
72 }
73 
74 /**
75   Provide a callout to the security verification service.
76 
77   @param PrivateData     PeiCore's private data structure
78   @param VolumeHandle    Handle of FV
79   @param FileHandle      Handle of PEIM's FFS
80   @param AuthenticationStatus Authentication status
81 
82   @retval EFI_SUCCESS              Image is OK
83   @retval EFI_SECURITY_VIOLATION   Image is illegal
84   @retval EFI_NOT_FOUND            If security PPI is not installed.
85 **/
86 EFI_STATUS
VerifyPeim(IN PEI_CORE_INSTANCE * PrivateData,IN EFI_PEI_FV_HANDLE VolumeHandle,IN EFI_PEI_FILE_HANDLE FileHandle,IN UINT32 AuthenticationStatus)87 VerifyPeim (
88   IN PEI_CORE_INSTANCE      *PrivateData,
89   IN EFI_PEI_FV_HANDLE      VolumeHandle,
90   IN EFI_PEI_FILE_HANDLE    FileHandle,
91   IN UINT32                 AuthenticationStatus
92   )
93 {
94   EFI_STATUS                      Status;
95   BOOLEAN                         DeferExecution;
96 
97   Status = EFI_NOT_FOUND;
98   if (PrivateData->PrivateSecurityPpi == NULL) {
99     //
100     // Check AuthenticationStatus first.
101     //
102     if ((AuthenticationStatus & EFI_AUTH_STATUS_IMAGE_SIGNED) != 0) {
103       if ((AuthenticationStatus & (EFI_AUTH_STATUS_TEST_FAILED | EFI_AUTH_STATUS_NOT_TESTED)) != 0) {
104         Status = EFI_SECURITY_VIOLATION;
105       }
106     }
107   } else {
108     //
109     // Check to see if the image is OK
110     //
111     Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
112                                                 (CONST EFI_PEI_SERVICES **) &PrivateData->Ps,
113                                                 PrivateData->PrivateSecurityPpi,
114                                                 AuthenticationStatus,
115                                                 VolumeHandle,
116                                                 FileHandle,
117                                                 &DeferExecution
118                                                 );
119     if (DeferExecution) {
120       Status = EFI_SECURITY_VIOLATION;
121     }
122   }
123   return Status;
124 }
125 
126 
127 /**
128   Verify a Firmware volume.
129 
130   @param CurrentFvAddress   Pointer to the current Firmware Volume under consideration
131 
132   @retval EFI_SUCCESS       Firmware Volume is legal
133 
134 **/
135 EFI_STATUS
VerifyFv(IN EFI_FIRMWARE_VOLUME_HEADER * CurrentFvAddress)136 VerifyFv (
137   IN EFI_FIRMWARE_VOLUME_HEADER  *CurrentFvAddress
138   )
139 {
140   //
141   // Right now just pass the test.  Future can authenticate and/or check the
142   // FV-header or other metric for goodness of binary.
143   //
144   return EFI_SUCCESS;
145 }
146