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