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