1 /** @file
2   Provides variable driver extended services.
3 
4 Copyright (c) 2015, 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 "Variable.h"
16 
17 /**
18   Finds variable in storage blocks of volatile and non-volatile storage areas.
19 
20   This code finds variable in storage blocks of volatile and non-volatile storage areas.
21   If VariableName is an empty string, then we just return the first
22   qualified variable without comparing VariableName and VendorGuid.
23 
24   @param[in]  VariableName          Name of the variable to be found.
25   @param[in]  VendorGuid            Variable vendor GUID to be found.
26   @param[out] AuthVariableInfo      Pointer to AUTH_VARIABLE_INFO structure for
27                                     output of the variable found.
28 
29   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
30                                     while VendorGuid is NULL.
31   @retval EFI_SUCCESS               Variable successfully found.
32   @retval EFI_NOT_FOUND             Variable not found
33 
34 **/
35 EFI_STATUS
36 EFIAPI
VariableExLibFindVariable(IN CHAR16 * VariableName,IN EFI_GUID * VendorGuid,OUT AUTH_VARIABLE_INFO * AuthVariableInfo)37 VariableExLibFindVariable (
38   IN  CHAR16                *VariableName,
39   IN  EFI_GUID              *VendorGuid,
40   OUT AUTH_VARIABLE_INFO    *AuthVariableInfo
41   )
42 {
43   EFI_STATUS                    Status;
44   VARIABLE_POINTER_TRACK        Variable;
45   AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
46 
47   Status = FindVariable (
48              VariableName,
49              VendorGuid,
50              &Variable,
51              &mVariableModuleGlobal->VariableGlobal,
52              FALSE
53              );
54   if (EFI_ERROR (Status)) {
55     AuthVariableInfo->Data = NULL;
56     AuthVariableInfo->DataSize = 0;
57     AuthVariableInfo->Attributes = 0;
58     AuthVariableInfo->PubKeyIndex = 0;
59     AuthVariableInfo->MonotonicCount = 0;
60     AuthVariableInfo->TimeStamp = NULL;
61     return Status;
62   }
63 
64   AuthVariableInfo->DataSize        = DataSizeOfVariable (Variable.CurrPtr);
65   AuthVariableInfo->Data            = GetVariableDataPtr (Variable.CurrPtr);
66   AuthVariableInfo->Attributes      = Variable.CurrPtr->Attributes;
67   if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
68     AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable.CurrPtr;
69     AuthVariableInfo->PubKeyIndex     = AuthVariable->PubKeyIndex;
70     AuthVariableInfo->MonotonicCount  = ReadUnaligned64 (&(AuthVariable->MonotonicCount));
71     AuthVariableInfo->TimeStamp       = &AuthVariable->TimeStamp;
72   }
73 
74   return EFI_SUCCESS;
75 }
76 
77 /**
78   Finds next variable in storage blocks of volatile and non-volatile storage areas.
79 
80   This code finds next variable in storage blocks of volatile and non-volatile storage areas.
81   If VariableName is an empty string, then we just return the first
82   qualified variable without comparing VariableName and VendorGuid.
83 
84   @param[in]  VariableName          Name of the variable to be found.
85   @param[in]  VendorGuid            Variable vendor GUID to be found.
86   @param[out] AuthVariableInfo      Pointer to AUTH_VARIABLE_INFO structure for
87                                     output of the next variable.
88 
89   @retval EFI_INVALID_PARAMETER     If VariableName is not an empty string,
90                                     while VendorGuid is NULL.
91   @retval EFI_SUCCESS               Variable successfully found.
92   @retval EFI_NOT_FOUND             Variable not found
93 
94 **/
95 EFI_STATUS
96 EFIAPI
VariableExLibFindNextVariable(IN CHAR16 * VariableName,IN EFI_GUID * VendorGuid,OUT AUTH_VARIABLE_INFO * AuthVariableInfo)97 VariableExLibFindNextVariable (
98   IN  CHAR16                *VariableName,
99   IN  EFI_GUID              *VendorGuid,
100   OUT AUTH_VARIABLE_INFO    *AuthVariableInfo
101   )
102 {
103   EFI_STATUS                    Status;
104   VARIABLE_HEADER               *VariablePtr;
105   AUTHENTICATED_VARIABLE_HEADER *AuthVariablePtr;
106 
107   Status = VariableServiceGetNextVariableInternal (
108              VariableName,
109              VendorGuid,
110              &VariablePtr
111              );
112   if (EFI_ERROR (Status)) {
113     AuthVariableInfo->VariableName = NULL;
114     AuthVariableInfo->VendorGuid = NULL;
115     AuthVariableInfo->Data = NULL;
116     AuthVariableInfo->DataSize = 0;
117     AuthVariableInfo->Attributes = 0;
118     AuthVariableInfo->PubKeyIndex = 0;
119     AuthVariableInfo->MonotonicCount = 0;
120     AuthVariableInfo->TimeStamp = NULL;
121     return Status;
122   }
123 
124   AuthVariableInfo->VariableName    = GetVariableNamePtr (VariablePtr);
125   AuthVariableInfo->VendorGuid      = GetVendorGuidPtr (VariablePtr);
126   AuthVariableInfo->DataSize        = DataSizeOfVariable (VariablePtr);
127   AuthVariableInfo->Data            = GetVariableDataPtr (VariablePtr);
128   AuthVariableInfo->Attributes      = VariablePtr->Attributes;
129   if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
130     AuthVariablePtr = (AUTHENTICATED_VARIABLE_HEADER *) VariablePtr;
131     AuthVariableInfo->PubKeyIndex     = AuthVariablePtr->PubKeyIndex;
132     AuthVariableInfo->MonotonicCount  = ReadUnaligned64 (&(AuthVariablePtr->MonotonicCount));
133     AuthVariableInfo->TimeStamp       = &AuthVariablePtr->TimeStamp;
134   }
135 
136   return EFI_SUCCESS;
137 }
138 
139 /**
140   Update the variable region with Variable information.
141 
142   @param[in] AuthVariableInfo       Pointer AUTH_VARIABLE_INFO structure for
143                                     input of the variable.
144 
145   @retval EFI_SUCCESS               The update operation is success.
146   @retval EFI_INVALID_PARAMETER     Invalid parameter.
147   @retval EFI_WRITE_PROTECTED       Variable is write-protected.
148   @retval EFI_OUT_OF_RESOURCES      There is not enough resource.
149 
150 **/
151 EFI_STATUS
152 EFIAPI
VariableExLibUpdateVariable(IN AUTH_VARIABLE_INFO * AuthVariableInfo)153 VariableExLibUpdateVariable (
154   IN AUTH_VARIABLE_INFO     *AuthVariableInfo
155   )
156 {
157   VARIABLE_POINTER_TRACK    Variable;
158 
159   FindVariable (AuthVariableInfo->VariableName, AuthVariableInfo->VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
160   return UpdateVariable (
161            AuthVariableInfo->VariableName,
162            AuthVariableInfo->VendorGuid,
163            AuthVariableInfo->Data,
164            AuthVariableInfo->DataSize,
165            AuthVariableInfo->Attributes,
166            AuthVariableInfo->PubKeyIndex,
167            AuthVariableInfo->MonotonicCount,
168            &Variable,
169            AuthVariableInfo->TimeStamp
170            );
171 }
172 
173 /**
174   Get scratch buffer.
175 
176   @param[in, out] ScratchBufferSize Scratch buffer size. If input size is greater than
177                                     the maximum supported buffer size, this value contains
178                                     the maximum supported buffer size as output.
179   @param[out]     ScratchBuffer     Pointer to scratch buffer address.
180 
181   @retval EFI_SUCCESS       Get scratch buffer successfully.
182   @retval EFI_UNSUPPORTED   If input size is greater than the maximum supported buffer size.
183 
184 **/
185 EFI_STATUS
186 EFIAPI
VariableExLibGetScratchBuffer(IN OUT UINTN * ScratchBufferSize,OUT VOID ** ScratchBuffer)187 VariableExLibGetScratchBuffer (
188   IN OUT UINTN      *ScratchBufferSize,
189   OUT    VOID       **ScratchBuffer
190   )
191 {
192   UINTN MaxBufferSize;
193 
194   MaxBufferSize = mVariableModuleGlobal->ScratchBufferSize;
195   if (*ScratchBufferSize > MaxBufferSize) {
196     *ScratchBufferSize = MaxBufferSize;
197     return EFI_UNSUPPORTED;
198   }
199 
200   *ScratchBuffer = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
201   return EFI_SUCCESS;
202 }
203 
204 /**
205   This function is to check if the remaining variable space is enough to set
206   all Variables from argument list successfully. The purpose of the check
207   is to keep the consistency of the Variables to be in variable storage.
208 
209   Note: Variables are assumed to be in same storage.
210   The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
211   so follow the argument sequence to check the Variables.
212 
213   @param[in] Attributes         Variable attributes for Variable entries.
214   @param ...                    The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
215                                 A NULL terminates the list. The VariableSize of
216                                 VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
217                                 It will be changed to variable total size as output.
218 
219   @retval TRUE                  Have enough variable space to set the Variables successfully.
220   @retval FALSE                 No enough variable space to set the Variables successfully.
221 
222 **/
223 BOOLEAN
224 EFIAPI
VariableExLibCheckRemainingSpaceForConsistency(IN UINT32 Attributes,...)225 VariableExLibCheckRemainingSpaceForConsistency (
226   IN UINT32                     Attributes,
227   ...
228   )
229 {
230   VA_LIST Marker;
231   BOOLEAN Return;
232 
233   VA_START (Marker, Attributes);
234 
235   Return = CheckRemainingSpaceForConsistencyInternal (Attributes, Marker);
236 
237   VA_END (Marker);
238 
239   return Return;
240 }
241 
242 /**
243   Return TRUE if at OS runtime.
244 
245   @retval TRUE If at OS runtime.
246   @retval FALSE If at boot time.
247 
248 **/
249 BOOLEAN
250 EFIAPI
VariableExLibAtRuntime(VOID)251 VariableExLibAtRuntime (
252   VOID
253   )
254 {
255   return AtRuntime ();
256 }
257