]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Library / DxeSecurityManagementLib / DxeSecurityManagementLib.c
CommitLineData
cd98f305
LG
1/** @file\r
2 Provides generic security measurement functions for DXE module.\r
3\r
cd5ebaa0
HT
4Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
cd98f305
LG
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/DxeServicesLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/SecurityManagementLib.h>\r
20\r
21#define SECURITY_HANDLER_TABLE_SIZE 0x10\r
22\r
350cefd3 23#define EFI_AUTH_OPERATION_MASK (EFI_AUTH_OPERATION_VERIFY_IMAGE \\r
cd98f305 24 | EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD \\r
350cefd3 25 | EFI_AUTH_OPERATION_MEASURE_IMAGE)\r
cd98f305
LG
26\r
27typedef struct {\r
28 UINT32 SecurityOperation;\r
29 SECURITY_FILE_AUTHENTICATION_STATE_HANDLER SecurityHandler;\r
30} SECURITY_INFO;\r
31\r
32UINT32 mCurrentAuthOperation = 0;\r
33UINT32 mNumberOfSecurityHandler = 0;\r
34UINT32 mMaxNumberOfSecurityHandler = 0;\r
35SECURITY_INFO *mSecurityTable = NULL;\r
36\r
37/**\r
38 Reallocates more global memory to store the registered Handler list.\r
39\r
40 @retval RETURN_SUCCESS Reallocate memory successfully.\r
41 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.\r
42**/\r
43RETURN_STATUS\r
44EFIAPI\r
45ReallocateSecurityHandlerTable (\r
46 )\r
47{\r
48 //\r
49 // Reallocate memory for security info structure.\r
50 //\r
51 mSecurityTable = ReallocatePool (\r
52 mMaxNumberOfSecurityHandler * sizeof (SECURITY_INFO), \r
53 (mMaxNumberOfSecurityHandler + SECURITY_HANDLER_TABLE_SIZE) * sizeof (SECURITY_INFO), \r
54 mSecurityTable\r
55 );\r
56\r
57 //\r
58 // No enough resource is allocated.\r
59 //\r
60 if (mSecurityTable == NULL) {\r
61 return RETURN_OUT_OF_RESOURCES;\r
62 }\r
63\r
64 //\r
65 // Increase max handler number\r
66 //\r
67 mMaxNumberOfSecurityHandler = mMaxNumberOfSecurityHandler + SECURITY_HANDLER_TABLE_SIZE;\r
68 return RETURN_SUCCESS;\r
69}\r
70\r
71/**\r
72 Check whether an operation is valid according to the requirement of current operation, \r
73 which must make sure that the measure image operation is the last one.\r
74\r
75 @param CurrentAuthOperation Current operation.\r
76 @param CheckAuthOperation Operation to be checked.\r
77\r
78 @retval TRUE Operation is valid for current operation.\r
79 @retval FALSE Operation is invalid for current operation.\r
80**/\r
81BOOLEAN\r
82CheckAuthenticationOperation (\r
83 IN UINT32 CurrentAuthOperation,\r
84 IN UINT32 CheckAuthOperation\r
85 )\r
86{ \r
87 //\r
88 // Make sure new auth operation can be recognized.\r
89 //\r
90 ASSERT ((CheckAuthOperation & ~(EFI_AUTH_OPERATION_MASK | EFI_AUTH_OPERATION_IMAGE_REQUIRED)) == 0);\r
91 \r
92 //\r
93 // When current operation includes measure image operation, \r
94 // only another measure image operation or none operation will be allowed.\r
95 //\r
96 if ((CurrentAuthOperation & EFI_AUTH_OPERATION_MEASURE_IMAGE) == EFI_AUTH_OPERATION_MEASURE_IMAGE) {\r
97 if (((CheckAuthOperation & EFI_AUTH_OPERATION_MEASURE_IMAGE) == EFI_AUTH_OPERATION_MEASURE_IMAGE) ||\r
98 ((CheckAuthOperation & EFI_AUTH_OPERATION_MASK) == EFI_AUTH_OPERATION_NONE)) {\r
99 return TRUE;\r
100 } else {\r
101 return FALSE;\r
102 }\r
103 }\r
104 \r
105 //\r
106 // When current operation doesn't include measure image operation, \r
107 // any new operation will be allowed.\r
108 //\r
109 return TRUE;\r
110}\r
111\r
112/**\r
113 Register security measurement handler with its operation type. The different\r
114 handler with the same operation can all be registered.\r
115\r
116 If SecurityHandler is NULL, then ASSERT().\r
117 If no enough resources available to register new handler, then ASSERT().\r
118 If AuthenticationOperation is not recongnized, then ASSERT().\r
119 If the previous register handler can't be executed before the later register handler, then ASSERT().\r
120\r
121 @param[in] SecurityHandler Security measurement service handler to be registered.\r
122 @param[in] AuthenticationOperation Operation type is specified for the registered handler.\r
123\r
124 @retval EFI_SUCCESS The handlers were registered successfully.\r
125**/\r
126EFI_STATUS\r
127EFIAPI\r
128RegisterSecurityHandler (\r
129 IN SECURITY_FILE_AUTHENTICATION_STATE_HANDLER SecurityHandler,\r
130 IN UINT32 AuthenticationOperation\r
131 )\r
132{\r
133 EFI_STATUS Status;\r
134\r
135 ASSERT (SecurityHandler != NULL);\r
136\r
137 //\r
138 // Make sure AuthenticationOperation is valid in the register order.\r
139 //\r
140 ASSERT (CheckAuthenticationOperation (mCurrentAuthOperation, AuthenticationOperation));\r
141 mCurrentAuthOperation = mCurrentAuthOperation | AuthenticationOperation;\r
142\r
143 //\r
144 // Check whether the handler lists is enough to store new handler.\r
145 //\r
146 if (mNumberOfSecurityHandler == mMaxNumberOfSecurityHandler) {\r
147 //\r
148 // Allocate more resources for new handler.\r
149 //\r
150 Status = ReallocateSecurityHandlerTable();\r
151 ASSERT_EFI_ERROR (Status);\r
152 }\r
153\r
154 //\r
155 // Register new handler into the handler list.\r
156 //\r
157 mSecurityTable[mNumberOfSecurityHandler].SecurityOperation = AuthenticationOperation;\r
158 mSecurityTable[mNumberOfSecurityHandler].SecurityHandler = SecurityHandler;\r
159 mNumberOfSecurityHandler ++;\r
160\r
161 return EFI_SUCCESS;\r
162}\r
163\r
164/**\r
165 Execute registered handlers until one returns an error and that error is returned.\r
166 If none of the handlers return an error, then EFI_SUCCESS is returned.\r
167\r
168 Before exectue handler, get the image buffer by file device path if a handler \r
169 requires the image file. And return the image buffer to each handler when exectue handler.\r
170\r
171 The handlers are executed in same order to their registered order.\r
172\r
173 @param[in] AuthenticationStatus \r
174 This is the authentication type returned from the Section\r
175 Extraction protocol. See the Section Extraction Protocol\r
176 Specification for details on this type.\r
177 @param[in] FilePath This is a pointer to the device path of the file that is\r
178 being dispatched. This will optionally be used for logging.\r
179\r
180 @retval EFI_SUCCESS The file specified by File did authenticate when more\r
181 than one security handler services were registered, \r
182 or the file did not authenticate when no security \r
183 handler service was registered. And the platform policy \r
184 dictates that the DXE Core may use File.\r
185 @retval EFI_INVALID_PARAMETER File is NULL.\r
186 @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
187 the platform policy dictates that File should be placed\r
188 in the untrusted state. A file may be promoted from\r
189 the untrusted to the trusted state at a future time\r
190 with a call to the Trust() DXE Service.\r
191 @retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and\r
192 the platform policy dictates that File should not be\r
193 used for any purpose.\r
194**/\r
195EFI_STATUS\r
196EFIAPI\r
197ExecuteSecurityHandlers (\r
198 IN UINT32 AuthenticationStatus,\r
199 IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath\r
200 )\r
201{\r
202 UINT32 Index;\r
203 EFI_STATUS Status;\r
204 UINT32 HandlerAuthenticationStatus;\r
205 VOID *FileBuffer;\r
206 UINTN FileSize;\r
207 \r
208 if (FilePath == NULL) {\r
209 return EFI_INVALID_PARAMETER;\r
210 }\r
211\r
212 //\r
213 // Directly return successfully when no handler is registered.\r
214 //\r
215 if (mNumberOfSecurityHandler == 0) {\r
216 return EFI_SUCCESS;\r
217 }\r
218 \r
219 Status = EFI_SUCCESS;\r
220 FileBuffer = NULL;\r
221 FileSize = 0;\r
222 HandlerAuthenticationStatus = AuthenticationStatus;\r
223 //\r
224 // Run security handler in same order to their registered list\r
225 //\r
226 for (Index = 0; Index < mNumberOfSecurityHandler; Index ++) {\r
227 if ((mSecurityTable[Index].SecurityOperation & EFI_AUTH_OPERATION_IMAGE_REQUIRED) == EFI_AUTH_OPERATION_IMAGE_REQUIRED) {\r
228 //\r
229 // Try get file buffer when the handler requires image buffer.\r
230 //\r
231 if (FileBuffer == NULL) {\r
2983a79d
LG
232 //\r
233 // Try to get image by FALSE boot policy for the exact boot file path.\r
234 //\r
cd98f305 235 FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &AuthenticationStatus);\r
2983a79d
LG
236 if (FileBuffer == NULL) {\r
237 //\r
238 // Try to get image by TRUE boot policy for the inexact boot file path.\r
239 //\r
240 FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &AuthenticationStatus);\r
241 }\r
cd98f305
LG
242 }\r
243 }\r
244 Status = mSecurityTable[Index].SecurityHandler (\r
245 HandlerAuthenticationStatus,\r
246 FilePath,\r
247 FileBuffer,\r
248 FileSize\r
249 );\r
250 if (EFI_ERROR (Status)) {\r
251 break;\r
252 }\r
253 }\r
254\r
255 if (FileBuffer != NULL) {\r
256 FreePool (FileBuffer);\r
257 }\r
258\r
259 return Status;\r
260}\r