1 /** @file
2   The internal header file includes the common header files, defines
3   internal structure and functions used by AuthService module.
4 
5   Caution: This module requires additional review when modified.
6   This driver will have external input - variable data. It may be input in SMM mode.
7   This external input must be validated carefully to avoid security issue like
8   buffer overflow, integer overflow.
9   Variable attribute should also be checked to avoid authentication bypass.
10      The whole SMM authentication variable design relies on the integrity of flash part and SMM.
11   which is assumed to be protected by platform.  All variable code and metadata in flash/SMM Memory
12   may not be modified without authorization. If platform fails to protect these resources,
13   the authentication service provided in this driver will be broken, and the behavior is undefined.
14 
15 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
16 This program and the accompanying materials
17 are licensed and made available under the terms and conditions of the BSD License
18 which accompanies this distribution.  The full text of the license may be found at
19 http://opensource.org/licenses/bsd-license.php
20 
21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
22 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 
24 **/
25 
26 #ifndef _AUTHSERVICE_INTERNAL_H_
27 #define _AUTHSERVICE_INTERNAL_H_
28 
29 #include <Library/AuthVariableLib.h>
30 #include <Library/BaseLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/MemoryAllocationLib.h>
34 #include <Library/BaseCryptLib.h>
35 #include <Library/PlatformSecureLib.h>
36 
37 #include <Guid/AuthenticatedVariableFormat.h>
38 #include <Guid/ImageAuthentication.h>
39 
40 ///
41 /// Struct to record signature requirement defined by UEFI spec.
42 /// For SigHeaderSize and SigDataSize, ((UINT32) ~0) means NO exact length requirement for this field.
43 ///
44 typedef struct {
45   EFI_GUID    SigType;
46   // Expected SignatureHeader size in Bytes.
47   UINT32      SigHeaderSize;
48   // Expected SignatureData size in Bytes.
49   UINT32      SigDataSize;
50 } EFI_SIGNATURE_ITEM;
51 
52 typedef enum {
53   AuthVarTypePk,
54   AuthVarTypeKek,
55   AuthVarTypePriv,
56   AuthVarTypePayload
57 } AUTHVAR_TYPE;
58 
59 ///
60 /// "AuthVarKeyDatabase" variable for the Public Key store
61 /// of variables with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
62 ///
63 /// GUID: gEfiAuthenticatedVariableGuid
64 ///
65 /// We need maintain atomicity.
66 ///
67 /// Format:
68 /// +----------------------------+
69 /// | AUTHVAR_KEY_DB_DATA        | <-- First AuthVarKey
70 /// +----------------------------+
71 /// | ......                     |
72 /// +----------------------------+
73 /// | AUTHVAR_KEY_DB_DATA        | <-- Last AuthKey
74 /// +----------------------------+
75 ///
76 #define AUTHVAR_KEYDB_NAME      L"AuthVarKeyDatabase"
77 
78 #define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
79 #define EFI_CERT_TYPE_RSA2048_SIZE        256
80 
81 #pragma pack(1)
82 typedef struct {
83   UINT32    KeyIndex;
84   UINT8     KeyData[EFI_CERT_TYPE_RSA2048_SIZE];
85 } AUTHVAR_KEY_DB_DATA;
86 #pragma pack()
87 
88 ///
89 /// "certdb" variable stores the signer's certificates for non PK/KEK/DB/DBX
90 /// variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
91 ///
92 /// GUID: gEfiCertDbGuid
93 ///
94 /// We need maintain atomicity.
95 ///
96 /// Format:
97 /// +----------------------------+
98 /// | UINT32                     | <-- CertDbListSize, including this UINT32
99 /// +----------------------------+
100 /// | AUTH_CERT_DB_DATA          | <-- First CERT
101 /// +----------------------------+
102 /// | ........                   |
103 /// +----------------------------+
104 /// | AUTH_CERT_DB_DATA          | <-- Last CERT
105 /// +----------------------------+
106 ///
107 #define EFI_CERT_DB_NAME        L"certdb"
108 
109 #pragma pack(1)
110 typedef struct {
111   EFI_GUID    VendorGuid;
112   UINT32      CertNodeSize;
113   UINT32      NameSize;
114   UINT32      CertDataSize;
115   /// CHAR16  VariableName[NameSize];
116   /// UINT8   CertData[CertDataSize];
117 } AUTH_CERT_DB_DATA;
118 #pragma pack()
119 
120 ///
121 /// "SecureBootMode" variable stores current secure boot mode.
122 /// The value type is SECURE_BOOT_MODE_TYPE.
123 ///
124 #define EDKII_SECURE_BOOT_MODE_NAME    L"SecureBootMode"
125 
126 typedef enum {
127   SecureBootModeTypeUserMode,
128   SecureBootModeTypeSetupMode,
129   SecureBootModeTypeAuditMode,
130   SecureBootModeTypeDeployedMode,
131   SecureBootModeTypeMax
132 } SECURE_BOOT_MODE_TYPE;
133 
134 //
135 // Record status info of Customized Secure Boot Mode.
136 //
137 typedef struct {
138   ///
139   /// AuditMode variable value
140   ///
141   UINT8   AuditMode;
142   ///
143   /// AuditMode variable RW
144   ///
145   BOOLEAN IsAuditModeRO;
146   ///
147   /// DeployedMode variable value
148   ///
149   UINT8   DeployedMode;
150   ///
151   /// AuditMode variable RW
152   ///
153   BOOLEAN IsDeployedModeRO;
154   ///
155   /// SetupMode variable value
156   ///
157   UINT8   SetupMode;
158   ///
159   /// SetupMode is always RO. Skip IsSetupModeRO;
160   ///
161 
162   ///
163   /// SecureBoot variable value
164   ///
165   UINT8   SecureBoot;
166 } SECURE_BOOT_MODE;
167 
168 extern UINT8    *mPubKeyStore;
169 extern UINT32   mPubKeyNumber;
170 extern UINT32   mMaxKeyNumber;
171 extern UINT32   mMaxKeyDbSize;
172 extern UINT8    *mCertDbStore;
173 extern UINT32   mMaxCertDbSize;
174 extern UINT32   mPlatformMode;
175 extern UINT8    mVendorKeyState;
176 
177 extern VOID     *mHashCtx;
178 
179 extern AUTH_VAR_LIB_CONTEXT_IN *mAuthVarLibContextIn;
180 
181 /**
182   Initialize Secure Boot variables.
183 
184   @retval EFI_SUCCESS               The initialization operation is successful.
185   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
186 
187 **/
188 EFI_STATUS
189 InitSecureBootVariables (
190   VOID
191   );
192 
193 /**
194   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
195 
196   Caution: This function may receive untrusted input.
197   This function may be invoked in SMM mode, and datasize and data are external input.
198   This function will do basic validation, before parse the data.
199   This function will parse the authentication carefully to avoid security issues, like
200   buffer overflow, integer overflow.
201 
202   @param[in]  VariableName                Name of Variable to be found.
203   @param[in]  VendorGuid                  Variable vendor GUID.
204   @param[in]  Data                        Data pointer.
205   @param[in]  DataSize                    Size of Data found. If size is less than the
206                                           data, this value contains the required size.
207   @param[in]  Attributes                  Attribute value of the variable.
208   @param[in]  AuthVarType                 Verify against PK, KEK database, private database or certificate in data payload.
209   @param[out] VarDel                      Delete the variable or not.
210 
211   @retval EFI_INVALID_PARAMETER           Invalid parameter.
212   @retval EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
213                                           check carried out by the firmware.
214   @retval EFI_OUT_OF_RESOURCES            Failed to process variable due to lack
215                                           of resources.
216   @retval EFI_SUCCESS                     Variable pass validation successfully.
217 
218 **/
219 EFI_STATUS
220 VerifyTimeBasedPayloadAndUpdate (
221   IN     CHAR16                             *VariableName,
222   IN     EFI_GUID                           *VendorGuid,
223   IN     VOID                               *Data,
224   IN     UINTN                              DataSize,
225   IN     UINT32                             Attributes,
226   IN     AUTHVAR_TYPE                       AuthVarType,
227   OUT    BOOLEAN                            *VarDel
228   );
229 
230 /**
231   Delete matching signer's certificates when deleting common authenticated
232   variable by corresponding VariableName and VendorGuid from "certdb".
233 
234   @param[in]  VariableName   Name of authenticated Variable.
235   @param[in]  VendorGuid     Vendor GUID of authenticated Variable.
236 
237   @retval  EFI_INVALID_PARAMETER Any input parameter is invalid.
238   @retval  EFI_NOT_FOUND         Fail to find "certdb" or matching certs.
239   @retval  EFI_OUT_OF_RESOURCES  The operation is failed due to lack of resources.
240   @retval  EFI_SUCCESS           The operation is completed successfully.
241 
242 **/
243 EFI_STATUS
244 DeleteCertsFromDb (
245   IN     CHAR16           *VariableName,
246   IN     EFI_GUID         *VendorGuid
247   );
248 
249 /**
250   Clean up signer's certificates for common authenticated variable
251   by corresponding VariableName and VendorGuid from "certdb".
252   Sytem may break down during Timebased Variable update & certdb update,
253   make them inconsistent,  this function is called in AuthVariable Init to ensure
254   consistency
255 
256   @retval  EFI_NOT_FOUND         Fail to find matching certs.
257   @retval  EFI_SUCCESS           Find matching certs and output parameters.
258 
259 **/
260 EFI_STATUS
261 CleanCertsFromDb (
262   VOID
263   );
264 
265 /**
266   Filter out the duplicated EFI_SIGNATURE_DATA from the new data by comparing to the original data.
267 
268   @param[in]        Data          Pointer to original EFI_SIGNATURE_LIST.
269   @param[in]        DataSize      Size of Data buffer.
270   @param[in, out]   NewData       Pointer to new EFI_SIGNATURE_LIST.
271   @param[in, out]   NewDataSize   Size of NewData buffer.
272 
273 **/
274 EFI_STATUS
275 FilterSignatureList (
276   IN     VOID       *Data,
277   IN     UINTN      DataSize,
278   IN OUT VOID       *NewData,
279   IN OUT UINTN      *NewDataSize
280   );
281 
282 /**
283   Process Secure Boot Mode variable.
284 
285   Caution: This function may receive untrusted input.
286   This function may be invoked in SMM mode, and datasize and data are external input.
287   This function will do basic validation, before parse the data.
288   This function will parse the authentication carefully to avoid security issues, like
289   buffer overflow, integer overflow.
290   This function will check attribute carefully to avoid authentication bypass.
291 
292   @param[in]  VariableName                Name of Variable to be found.
293   @param[in]  VendorGuid                  Variable vendor GUID.
294   @param[in]  Data                        Data pointer.
295   @param[in]  DataSize                    Size of Data found. If size is less than the
296                                           data, this value contains the required size.
297   @param[in]  Attributes                  Attribute value of the variable
298 
299   @return EFI_INVALID_PARAMETER           Invalid parameter
300   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
301                                           check carried out by the firmware.
302   @return EFI_WRITE_PROTECTED             Variable is Read-Only.
303   @return EFI_SUCCESS                     Variable passed validation successfully.
304 
305 **/
306 EFI_STATUS
307 ProcessSecureBootModeVar (
308   IN  CHAR16         *VariableName,
309   IN  EFI_GUID       *VendorGuid,
310   IN  VOID           *Data,
311   IN  UINTN          DataSize,
312   IN  UINT32         Attributes OPTIONAL
313   );
314 
315 /**
316   Process variable with platform key for verification.
317 
318   Caution: This function may receive untrusted input.
319   This function may be invoked in SMM mode, and datasize and data are external input.
320   This function will do basic validation, before parse the data.
321   This function will parse the authentication carefully to avoid security issues, like
322   buffer overflow, integer overflow.
323   This function will check attribute carefully to avoid authentication bypass.
324 
325   @param[in]  VariableName                Name of Variable to be found.
326   @param[in]  VendorGuid                  Variable vendor GUID.
327   @param[in]  Data                        Data pointer.
328   @param[in]  DataSize                    Size of Data found. If size is less than the
329                                           data, this value contains the required size.
330   @param[in]  Attributes                  Attribute value of the variable
331   @param[in]  IsPk                        Indicate whether it is to process pk.
332 
333   @return EFI_INVALID_PARAMETER           Invalid parameter.
334   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation.
335                                           check carried out by the firmware.
336   @return EFI_SUCCESS                     Variable passed validation successfully.
337 
338 **/
339 EFI_STATUS
340 ProcessVarWithPk (
341   IN  CHAR16                    *VariableName,
342   IN  EFI_GUID                  *VendorGuid,
343   IN  VOID                      *Data,
344   IN  UINTN                     DataSize,
345   IN  UINT32                    Attributes OPTIONAL,
346   IN  BOOLEAN                   IsPk
347   );
348 
349 /**
350   Process variable with key exchange key for verification.
351 
352   Caution: This function may receive untrusted input.
353   This function may be invoked in SMM mode, and datasize and data are external input.
354   This function will do basic validation, before parse the data.
355   This function will parse the authentication carefully to avoid security issues, like
356   buffer overflow, integer overflow.
357   This function will check attribute carefully to avoid authentication bypass.
358 
359   @param[in]  VariableName                Name of Variable to be found.
360   @param[in]  VendorGuid                  Variable vendor GUID.
361   @param[in]  Data                        Data pointer.
362   @param[in]  DataSize                    Size of Data found. If size is less than the
363                                           data, this value contains the required size.
364   @param[in]  Attributes                  Attribute value of the variable.
365 
366   @return EFI_INVALID_PARAMETER           Invalid parameter.
367   @return EFI_SECURITY_VIOLATION          The variable does NOT pass the validation
368                                           check carried out by the firmware.
369   @return EFI_SUCCESS                     Variable pass validation successfully.
370 
371 **/
372 EFI_STATUS
373 ProcessVarWithKek (
374   IN  CHAR16                               *VariableName,
375   IN  EFI_GUID                             *VendorGuid,
376   IN  VOID                                 *Data,
377   IN  UINTN                                DataSize,
378   IN  UINT32                               Attributes OPTIONAL
379   );
380 
381 /**
382   Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
383 
384   Caution: This function may receive untrusted input.
385   This function may be invoked in SMM mode, and datasize and data are external input.
386   This function will do basic validation, before parse the data.
387   This function will parse the authentication carefully to avoid security issues, like
388   buffer overflow, integer overflow.
389   This function will check attribute carefully to avoid authentication bypass.
390 
391   @param[in]  VariableName                Name of the variable.
392   @param[in]  VendorGuid                  Variable vendor GUID.
393   @param[in]  Data                        Data pointer.
394   @param[in]  DataSize                    Size of Data.
395   @param[in]  Attributes                  Attribute value of the variable.
396 
397   @return EFI_INVALID_PARAMETER           Invalid parameter.
398   @return EFI_WRITE_PROTECTED             Variable is write-protected and needs authentication with
399                                           EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
400   @return EFI_OUT_OF_RESOURCES            The Database to save the public key is full.
401   @return EFI_SECURITY_VIOLATION          The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
402                                           set, but the AuthInfo does NOT pass the validation
403                                           check carried out by the firmware.
404   @return EFI_SUCCESS                     Variable is not write-protected or pass validation successfully.
405 
406 **/
407 EFI_STATUS
408 ProcessVariable (
409   IN     CHAR16                             *VariableName,
410   IN     EFI_GUID                           *VendorGuid,
411   IN     VOID                               *Data,
412   IN     UINTN                              DataSize,
413   IN     UINT32                             Attributes OPTIONAL
414   );
415 
416 /**
417   Finds variable in storage blocks of volatile and non-volatile storage areas.
418 
419   This code finds variable in storage blocks of volatile and non-volatile storage areas.
420   If VariableName is an empty string, then we just return the first
421   qualified variable without comparing VariableName and VendorGuid.
422 
423   @param[in]  VariableName          Name of the variable to be found.
424   @param[in]  VendorGuid            Variable vendor GUID to be found.
425   @param[out] Data                  Pointer to data address.
426   @param[out] DataSize              Pointer to data size.
427 
428   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
429                                     while VendorGuid is NULL.
430   @retval EFI_SUCCESS               Variable successfully found.
431   @retval EFI_NOT_FOUND             Variable not found
432 
433 **/
434 EFI_STATUS
435 AuthServiceInternalFindVariable (
436   IN  CHAR16        *VariableName,
437   IN  EFI_GUID      *VendorGuid,
438   OUT VOID          **Data,
439   OUT UINTN         *DataSize
440   );
441 
442 /**
443   Update the variable region with Variable information.
444 
445   @param[in] VariableName           Name of variable.
446   @param[in] VendorGuid             Guid of variable.
447   @param[in] Data                   Data pointer.
448   @param[in] DataSize               Size of Data.
449   @param[in] Attributes             Attribute value of the variable.
450 
451   @retval EFI_SUCCESS               The update operation is success.
452   @retval EFI_INVALID_PARAMETER     Invalid parameter.
453   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
454   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
455 
456 **/
457 EFI_STATUS
458 AuthServiceInternalUpdateVariable (
459   IN CHAR16         *VariableName,
460   IN EFI_GUID       *VendorGuid,
461   IN VOID           *Data,
462   IN UINTN          DataSize,
463   IN UINT32         Attributes
464   );
465 
466 /**
467   Update the variable region with Variable information.
468 
469   @param[in] VariableName           Name of variable.
470   @param[in] VendorGuid             Guid of variable.
471   @param[in] Data                   Data pointer.
472   @param[in] DataSize               Size of Data.
473   @param[in] Attributes             Attribute value of the variable.
474   @param[in] KeyIndex               Index of associated public key.
475   @param[in] MonotonicCount         Value of associated monotonic count.
476 
477   @retval EFI_SUCCESS               The update operation is success.
478   @retval EFI_INVALID_PARAMETER     Invalid parameter.
479   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
480   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
481 
482 **/
483 EFI_STATUS
484 AuthServiceInternalUpdateVariableWithMonotonicCount (
485   IN CHAR16         *VariableName,
486   IN EFI_GUID       *VendorGuid,
487   IN VOID           *Data,
488   IN UINTN          DataSize,
489   IN UINT32         Attributes,
490   IN UINT32         KeyIndex,
491   IN UINT64         MonotonicCount
492   );
493 
494 /**
495   Update the variable region with Variable information.
496 
497   @param[in] VariableName           Name of variable.
498   @param[in] VendorGuid             Guid of variable.
499   @param[in] Data                   Data pointer.
500   @param[in] DataSize               Size of Data.
501   @param[in] Attributes             Attribute value of the variable.
502   @param[in] TimeStamp              Value of associated TimeStamp.
503 
504   @retval EFI_SUCCESS               The update operation is success.
505   @retval EFI_INVALID_PARAMETER     Invalid parameter.
506   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
507   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
508 
509 **/
510 EFI_STATUS
511 AuthServiceInternalUpdateVariableWithTimeStamp (
512   IN CHAR16         *VariableName,
513   IN EFI_GUID       *VendorGuid,
514   IN VOID           *Data,
515   IN UINTN          DataSize,
516   IN UINT32         Attributes,
517   IN EFI_TIME       *TimeStamp
518   );
519 
520 #endif
521