1 /** @file
2   Provides services to initialize and process authenticated variables.
3 
4 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef _AUTH_VARIABLE_LIB_H_
10 #define _AUTH_VARIABLE_LIB_H_
11 
12 #include <Protocol/VarCheck.h>
13 
14 ///
15 /// Size of AuthInfo prior to the data payload.
16 ///
17 #define AUTHINFO_SIZE ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \
18                        (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \
19                        sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))
20 
21 #define AUTHINFO2_SIZE(VarAuth2) ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
22                                   (UINTN) ((EFI_VARIABLE_AUTHENTICATION_2 *) (VarAuth2))->AuthInfo.Hdr.dwLength)
23 
24 #define OFFSET_OF_AUTHINFO2_CERT_DATA ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
25                                        (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)))
26 
27 typedef struct {
28   CHAR16        *VariableName;
29   EFI_GUID      *VendorGuid;
30   UINT32        Attributes;
31   UINTN         DataSize;
32   VOID          *Data;
33   UINT32        PubKeyIndex;
34   UINT64        MonotonicCount;
35   EFI_TIME      *TimeStamp;
36 } AUTH_VARIABLE_INFO;
37 
38 /**
39   Finds variable in storage blocks of volatile and non-volatile storage areas.
40 
41   This code finds variable in storage blocks of volatile and non-volatile storage areas.
42   If VariableName is an empty string, then we just return the first
43   qualified variable without comparing VariableName and VendorGuid.
44 
45   @param[in]  VariableName          Name of the variable to be found.
46   @param[in]  VendorGuid            Variable vendor GUID to be found.
47   @param[out] AuthVariableInfo      Pointer to AUTH_VARIABLE_INFO structure for
48                                     output of the variable found.
49 
50   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
51                                     while VendorGuid is NULL.
52   @retval EFI_SUCCESS               Variable successfully found.
53   @retval EFI_NOT_FOUND             Variable not found
54 
55 **/
56 typedef
57 EFI_STATUS
58 (EFIAPI *AUTH_VAR_LIB_FIND_VARIABLE) (
59   IN  CHAR16                *VariableName,
60   IN  EFI_GUID              *VendorGuid,
61   OUT AUTH_VARIABLE_INFO    *AuthVariableInfo
62   );
63 
64 /**
65   Finds next variable in storage blocks of volatile and non-volatile storage areas.
66 
67   This code finds next variable in storage blocks of volatile and non-volatile storage areas.
68   If VariableName is an empty string, then we just return the first
69   qualified variable without comparing VariableName and VendorGuid.
70 
71   @param[in]  VariableName          Name of the variable to be found.
72   @param[in]  VendorGuid            Variable vendor GUID to be found.
73   @param[out] AuthVariableInfo      Pointer to AUTH_VARIABLE_INFO structure for
74                                     output of the next variable.
75 
76   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
77                                     while VendorGuid is NULL.
78   @retval EFI_SUCCESS               Variable successfully found.
79   @retval EFI_NOT_FOUND             Variable not found
80 
81 **/
82 typedef
83 EFI_STATUS
84 (EFIAPI *AUTH_VAR_LIB_FIND_NEXT_VARIABLE) (
85   IN  CHAR16                *VariableName,
86   IN  EFI_GUID              *VendorGuid,
87   OUT AUTH_VARIABLE_INFO    *AuthVariableInfo
88   );
89 
90 /**
91   Update the variable region with Variable information.
92 
93   @param[in] AuthVariableInfo       Pointer AUTH_VARIABLE_INFO structure for
94                                     input of the variable.
95 
96   @retval EFI_SUCCESS               The update operation is success.
97   @retval EFI_INVALID_PARAMETER     Invalid parameter.
98   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
99   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
100 
101 **/
102 typedef
103 EFI_STATUS
104 (EFIAPI *AUTH_VAR_LIB_UPDATE_VARIABLE) (
105   IN AUTH_VARIABLE_INFO     *AuthVariableInfo
106   );
107 
108 /**
109   Get scratch buffer.
110 
111   @param[in, out] ScratchBufferSize Scratch buffer size. If input size is greater than
112                                     the maximum supported buffer size, this value contains
113                                     the maximum supported buffer size as output.
114   @param[out]     ScratchBuffer     Pointer to scratch buffer address.
115 
116   @retval EFI_SUCCESS       Get scratch buffer successfully.
117   @retval EFI_UNSUPPORTED   If input size is greater than the maximum supported buffer size.
118 
119 **/
120 typedef
121 EFI_STATUS
122 (EFIAPI *AUTH_VAR_LIB_GET_SCRATCH_BUFFER) (
123   IN OUT UINTN      *ScratchBufferSize,
124   OUT    VOID       **ScratchBuffer
125   );
126 
127 /**
128   This function is to check if the remaining variable space is enough to set
129   all Variables from argument list successfully. The purpose of the check
130   is to keep the consistency of the Variables to be in variable storage.
131 
132   Note: Variables are assumed to be in same storage.
133   The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
134   so follow the argument sequence to check the Variables.
135 
136   @param[in] Attributes         Variable attributes for Variable entries.
137   @param ...                    The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
138                                 A NULL terminates the list. The VariableSize of
139                                 VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
140                                 It will be changed to variable total size as output.
141 
142   @retval TRUE                  Have enough variable space to set the Variables successfully.
143   @retval FALSE                 No enough variable space to set the Variables successfully.
144 
145 **/
146 typedef
147 BOOLEAN
148 (EFIAPI *AUTH_VAR_LIB_CHECK_REMAINING_SPACE) (
149   IN UINT32                     Attributes,
150   ...
151   );
152 
153 /**
154   Return TRUE if at OS runtime.
155 
156   @retval TRUE If at OS runtime.
157   @retval FALSE If at boot time.
158 
159 **/
160 typedef
161 BOOLEAN
162 (EFIAPI *AUTH_VAR_LIB_AT_RUNTIME) (
163   VOID
164   );
165 
166 #define AUTH_VAR_LIB_CONTEXT_IN_STRUCT_VERSION  0x01
167 
168 typedef struct {
169   UINTN                                 StructVersion;
170   UINTN                                 StructSize;
171   //
172   // Reflect the overhead associated with the saving
173   // of a single EFI authenticated variable with the exception
174   // of the overhead associated with the length
175   // of the string name of the EFI variable.
176   //
177   UINTN                                 MaxAuthVariableSize;
178   AUTH_VAR_LIB_FIND_VARIABLE            FindVariable;
179   AUTH_VAR_LIB_FIND_NEXT_VARIABLE       FindNextVariable;
180   AUTH_VAR_LIB_UPDATE_VARIABLE          UpdateVariable;
181   AUTH_VAR_LIB_GET_SCRATCH_BUFFER       GetScratchBuffer;
182   AUTH_VAR_LIB_CHECK_REMAINING_SPACE    CheckRemainingSpaceForConsistency;
183   AUTH_VAR_LIB_AT_RUNTIME               AtRuntime;
184 } AUTH_VAR_LIB_CONTEXT_IN;
185 
186 #define AUTH_VAR_LIB_CONTEXT_OUT_STRUCT_VERSION 0x01
187 
188 typedef struct {
189   UINTN                                 StructVersion;
190   UINTN                                 StructSize;
191   //
192   // Caller needs to set variable property for the variables.
193   //
194   VARIABLE_ENTRY_PROPERTY               *AuthVarEntry;
195   UINTN                                 AuthVarEntryCount;
196   //
197   // Caller needs to ConvertPointer() for the pointers.
198   //
199   VOID                                  ***AddressPointer;
200   UINTN                                 AddressPointerCount;
201 } AUTH_VAR_LIB_CONTEXT_OUT;
202 
203 /**
204   Initialization for authenticated varibale services.
205   If this initialization returns error status, other APIs will not work
206   and expect to be not called then.
207 
208   @param[in]  AuthVarLibContextIn   Pointer to input auth variable lib context.
209   @param[out] AuthVarLibContextOut  Pointer to output auth variable lib context.
210 
211   @retval EFI_SUCCESS               Function successfully executed.
212   @retval EFI_INVALID_PARAMETER     If AuthVarLibContextIn == NULL or AuthVarLibContextOut == NULL.
213   @retval EFI_OUT_OF_RESOURCES      Fail to allocate enough resource.
214   @retval EFI_UNSUPPORTED           Unsupported to process authenticated variable.
215 
216 **/
217 EFI_STATUS
218 EFIAPI
219 AuthVariableLibInitialize (
220   IN  AUTH_VAR_LIB_CONTEXT_IN   *AuthVarLibContextIn,
221   OUT AUTH_VAR_LIB_CONTEXT_OUT  *AuthVarLibContextOut
222   );
223 
224 /**
225   Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
226 
227   @param[in] VariableName           Name of the variable.
228   @param[in] VendorGuid             Variable vendor GUID.
229   @param[in] Data                   Data pointer.
230   @param[in] DataSize               Size of Data.
231   @param[in] Attributes             Attribute value of the variable.
232 
233   @retval EFI_SUCCESS               The firmware has successfully stored the variable and its data as
234                                     defined by the Attributes.
235   @retval EFI_INVALID_PARAMETER     Invalid parameter.
236   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
237   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
238   @retval EFI_SECURITY_VIOLATION    The variable is with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS
239                                     set, but the AuthInfo does NOT pass the validation
240                                     check carried out by the firmware.
241   @retval EFI_UNSUPPORTED           Unsupported to process authenticated variable.
242 
243 **/
244 EFI_STATUS
245 EFIAPI
246 AuthVariableLibProcessVariable (
247   IN CHAR16         *VariableName,
248   IN EFI_GUID       *VendorGuid,
249   IN VOID           *Data,
250   IN UINTN          DataSize,
251   IN UINT32         Attributes
252   );
253 
254 #endif
255