1 /** @file
2   This module implements Hash2 Protocol.
3 
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #include <Uefi.h>
11 #include <Protocol/Hash2.h>
12 #include <Library/BaseLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseCryptLib.h>
18 
19 #include "Driver.h"
20 
21 /**
22   Retrieves the size, in bytes, of the context buffer required for hash operations.
23 
24   If this interface is not supported, then return zero.
25 
26   @return  The size, in bytes, of the context buffer required for hash operations.
27   @retval  0   This interface is not supported.
28 
29 **/
30 typedef
31 UINTN
32 (EFIAPI *EFI_HASH_GET_CONTEXT_SIZE) (
33   VOID
34   );
35 
36 /**
37   Initializes user-supplied memory pointed by Sha1Context as hash context for
38   subsequent use.
39 
40   If HashContext is NULL, then return FALSE.
41   If this interface is not supported, then return FALSE.
42 
43   @param[out]  HashContext  Pointer to Hashcontext being initialized.
44 
45   @retval TRUE   Hash context initialization succeeded.
46   @retval FALSE  Hash context initialization failed.
47   @retval FALSE  This interface is not supported.
48 
49 **/
50 typedef
51 BOOLEAN
52 (EFIAPI *EFI_HASH_INIT) (
53   OUT  VOID  *HashContext
54   );
55 
56 /**
57   Digests the input data and updates Hash context.
58 
59   This function performs Hash digest on a data buffer of the specified size.
60   It can be called multiple times to compute the digest of long or discontinuous data streams.
61   Hash context should be already correctly initialized by HashInit(), and should not be finalized
62   by HashFinal(). Behavior with invalid context is undefined.
63 
64   If HashContext is NULL, then return FALSE.
65   If this interface is not supported, then return FALSE.
66 
67   @param[in, out]  HashContext  Pointer to the Hash context.
68   @param[in]       Data         Pointer to the buffer containing the data to be hashed.
69   @param[in]       DataSize     Size of Data buffer in bytes.
70 
71   @retval TRUE   SHA-1 data digest succeeded.
72   @retval FALSE  SHA-1 data digest failed.
73   @retval FALSE  This interface is not supported.
74 
75 **/
76 typedef
77 BOOLEAN
78 (EFIAPI *EFI_HASH_UPDATE) (
79   IN OUT  VOID        *HashContext,
80   IN      CONST VOID  *Data,
81   IN      UINTN       DataSize
82   );
83 
84 /**
85   Completes computation of the Hash digest value.
86 
87   This function completes hash computation and retrieves the digest value into
88   the specified memory. After this function has been called, the Hash context cannot
89   be used again.
90   Hash context should be already correctly initialized by HashInit(), and should not be
91   finalized by HashFinal(). Behavior with invalid Hash context is undefined.
92 
93   If HashContext is NULL, then return FALSE.
94   If HashValue is NULL, then return FALSE.
95   If this interface is not supported, then return FALSE.
96 
97   @param[in, out]  HashContext  Pointer to the Hash context.
98   @param[out]      HashValue    Pointer to a buffer that receives the Hash digest
99                                 value.
100 
101   @retval TRUE   Hash digest computation succeeded.
102   @retval FALSE  Hash digest computation failed.
103   @retval FALSE  This interface is not supported.
104 
105 **/
106 typedef
107 BOOLEAN
108 (EFIAPI *EFI_HASH_FINAL) (
109   IN OUT  VOID   *HashContext,
110   OUT     UINT8  *HashValue
111   );
112 
113 typedef struct {
114   EFI_GUID                   *Guid;
115   UINT32                     HashSize;
116   EFI_HASH_GET_CONTEXT_SIZE  GetContextSize;
117   EFI_HASH_INIT              Init;
118   EFI_HASH_UPDATE            Update;
119   EFI_HASH_FINAL             Final;
120 } EFI_HASH_INFO;
121 
122 EFI_HASH_INFO  mHashInfo[] = {
123   {&gEfiHashAlgorithmMD5Guid,     sizeof(EFI_MD5_HASH2),    Md5GetContextSize,    Md5Init,    Md5Update,    Md5Final  },
124   {&gEfiHashAlgorithmSha1Guid,    sizeof(EFI_SHA1_HASH2),   Sha1GetContextSize,   Sha1Init,   Sha1Update,   Sha1Final   },
125   {&gEfiHashAlgorithmSha256Guid,  sizeof(EFI_SHA256_HASH2), Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },
126   {&gEfiHashAlgorithmSha384Guid,  sizeof(EFI_SHA384_HASH2), Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },
127   {&gEfiHashAlgorithmSha512Guid,  sizeof(EFI_SHA512_HASH2), Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final },
128 };
129 
130 /**
131   Returns the size of the hash which results from a specific algorithm.
132 
133   @param[in]  This                  Points to this instance of EFI_HASH2_PROTOCOL.
134   @param[in]  HashAlgorithm         Points to the EFI_GUID which identifies the algorithm to use.
135   @param[out] HashSize              Holds the returned size of the algorithm's hash.
136 
137   @retval EFI_SUCCESS           Hash size returned successfully.
138   @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
139   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
140                                 or HashAlgorithm is null.
141 
142 **/
143 EFI_STATUS
144 EFIAPI
145 BaseCrypto2GetHashSize (
146   IN  CONST EFI_HASH2_PROTOCOL     *This,
147   IN  CONST EFI_GUID               *HashAlgorithm,
148   OUT UINTN                        *HashSize
149   );
150 
151 /**
152   Creates a hash for the specified message text. The hash is not extendable.
153   The output is final with any algorithm-required padding added by the function.
154 
155   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
156   @param[in]  HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
157   @param[in]  Message       Points to the start of the message.
158   @param[in]  MessageSize   The size of Message, in bytes.
159   @param[in,out]  Hash      On input, points to a caller-allocated buffer of the size
160                               returned by GetHashSize() for the specified HashAlgorithm.
161                             On output, the buffer holds the resulting hash computed from the message.
162 
163   @retval EFI_SUCCESS           Hash returned successfully.
164   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
165   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
166                                 or HashAlgorithm is Null.
167   @retval EFI_OUT_OF_RESOURCES  Some resource required by the function is not available
168                                 or MessageSize is greater than platform maximum.
169 
170 **/
171 EFI_STATUS
172 EFIAPI
173 BaseCrypto2Hash (
174   IN CONST EFI_HASH2_PROTOCOL      *This,
175   IN CONST EFI_GUID                *HashAlgorithm,
176   IN CONST UINT8                   *Message,
177   IN UINTN                         MessageSize,
178   IN OUT EFI_HASH2_OUTPUT          *Hash
179   );
180 
181 /**
182   This function must be called to initialize a digest calculation to be subsequently performed using the
183   EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
184 
185   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
186   @param[in]  HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
187 
188   @retval EFI_SUCCESS           Initialized successfully.
189   @retval EFI_INVALID_PARAMETER This is NULL.
190   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
191                                 or HashAlgorithm is Null.
192   @retval EFI_OUT_OF_RESOURCES  Process failed due to lack of required resource.
193   @retval EFI_ALREADY_STARTED   This function is called when the operation in progress is still in processing Hash(),
194                                 or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
195 
196 **/
197 EFI_STATUS
198 EFIAPI
199 BaseCrypto2HashInit (
200   IN CONST EFI_HASH2_PROTOCOL      *This,
201   IN CONST EFI_GUID                *HashAlgorithm
202   );
203 
204 /**
205   Updates the hash of a computation in progress by adding a message text.
206 
207   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
208   @param[in]  Message       Points to the start of the message.
209   @param[in]  MessageSize   The size of Message, in bytes.
210 
211   @retval EFI_SUCCESS           Digest in progress updated successfully.
212   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
213   @retval EFI_OUT_OF_RESOURCES  Some resource required by the function is not available
214                                 or MessageSize is greater than platform maximum.
215   @retval EFI_NOT_READY         This call was not preceded by a valid call to HashInit(),
216                                 or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
217 
218 **/
219 EFI_STATUS
220 EFIAPI
221 BaseCrypto2HashUpdate (
222   IN CONST EFI_HASH2_PROTOCOL      *This,
223   IN CONST UINT8                   *Message,
224   IN UINTN                         MessageSize
225   );
226 
227 /**
228   Finalizes a hash operation in progress and returns calculation result.
229   The output is final with any necessary padding added by the function.
230   The hash may not be further updated or extended after HashFinal().
231 
232   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
233   @param[in,out]  Hash      On input, points to a caller-allocated buffer of the size
234                               returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
235                             On output, the buffer holds the resulting hash computed from the message.
236 
237   @retval EFI_SUCCESS           Hash returned successfully.
238   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
239   @retval EFI_NOT_READY         This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
240                                 or the operation in progress was canceled by a call to Hash() on the same instance.
241 
242 **/
243 EFI_STATUS
244 EFIAPI
245 BaseCrypto2HashFinal (
246   IN CONST EFI_HASH2_PROTOCOL      *This,
247   IN OUT EFI_HASH2_OUTPUT          *Hash
248   );
249 
250 EFI_HASH2_PROTOCOL mHash2Protocol = {
251   BaseCrypto2GetHashSize,
252   BaseCrypto2Hash,
253   BaseCrypto2HashInit,
254   BaseCrypto2HashUpdate,
255   BaseCrypto2HashFinal,
256 };
257 
258 /**
259   Returns hash information.
260 
261   @param[in]  HashAlgorithm         Points to the EFI_GUID which identifies the algorithm to use.
262 
263   @return Hash information.
264 **/
265 EFI_HASH_INFO *
GetHashInfo(IN CONST EFI_GUID * HashAlgorithm)266 GetHashInfo (
267   IN CONST EFI_GUID              *HashAlgorithm
268   )
269 {
270   UINTN      Index;
271 
272   for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {
273     if (CompareGuid (HashAlgorithm, mHashInfo[Index].Guid)) {
274       return &mHashInfo[Index];
275     }
276   }
277   return NULL;
278 }
279 
280 /**
281   Returns the size of the hash which results from a specific algorithm.
282 
283   @param[in]  This                  Points to this instance of EFI_HASH2_PROTOCOL.
284   @param[in]  HashAlgorithm         Points to the EFI_GUID which identifies the algorithm to use.
285   @param[out] HashSize              Holds the returned size of the algorithm's hash.
286 
287   @retval EFI_SUCCESS           Hash size returned successfully.
288   @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
289   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
290                                 or HashAlgorithm is null.
291 
292 **/
293 EFI_STATUS
294 EFIAPI
BaseCrypto2GetHashSize(IN CONST EFI_HASH2_PROTOCOL * This,IN CONST EFI_GUID * HashAlgorithm,OUT UINTN * HashSize)295 BaseCrypto2GetHashSize (
296   IN  CONST EFI_HASH2_PROTOCOL     *This,
297   IN  CONST EFI_GUID              *HashAlgorithm,
298   OUT UINTN                       *HashSize
299   )
300 {
301   EFI_HASH_INFO *HashInfo;
302 
303   if ((This == NULL) || (HashSize == NULL)) {
304     return EFI_INVALID_PARAMETER;
305   }
306 
307   if (HashAlgorithm == NULL) {
308     return EFI_UNSUPPORTED;
309   }
310 
311   HashInfo = GetHashInfo (HashAlgorithm);
312   if (HashInfo == NULL) {
313     return EFI_UNSUPPORTED;
314   }
315 
316   *HashSize = HashInfo->HashSize;
317   return EFI_SUCCESS;
318 }
319 
320 /**
321   Creates a hash for the specified message text. The hash is not extendable.
322   The output is final with any algorithm-required padding added by the function.
323 
324   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
325   @param[in]  HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
326   @param[in]  Message       Points to the start of the message.
327   @param[in]  MessageSize   The size of Message, in bytes.
328   @param[in,out]  Hash      On input, points to a caller-allocated buffer of the size
329                               returned by GetHashSize() for the specified HashAlgorithm.
330                             On output, the buffer holds the resulting hash computed from the message.
331 
332   @retval EFI_SUCCESS           Hash returned successfully.
333   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
334   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
335                                 or HashAlgorithm is Null.
336   @retval EFI_OUT_OF_RESOURCES  Some resource required by the function is not available
337                                 or MessageSize is greater than platform maximum.
338 
339 **/
340 EFI_STATUS
341 EFIAPI
BaseCrypto2Hash(IN CONST EFI_HASH2_PROTOCOL * This,IN CONST EFI_GUID * HashAlgorithm,IN CONST UINT8 * Message,IN UINTN MessageSize,IN OUT EFI_HASH2_OUTPUT * Hash)342 BaseCrypto2Hash (
343   IN CONST EFI_HASH2_PROTOCOL      *This,
344   IN CONST EFI_GUID                *HashAlgorithm,
345   IN CONST UINT8                   *Message,
346   IN UINTN                         MessageSize,
347   IN OUT EFI_HASH2_OUTPUT          *Hash
348   )
349 {
350   EFI_HASH_INFO            *HashInfo;
351   VOID                     *HashCtx;
352   UINTN                    CtxSize;
353   BOOLEAN                  Ret;
354   EFI_STATUS               Status;
355   HASH2_INSTANCE_DATA      *Instance;
356 
357   Status = EFI_SUCCESS;
358 
359   if ((This == NULL) || (Hash == NULL)) {
360     return EFI_INVALID_PARAMETER;
361   }
362 
363   if (HashAlgorithm == NULL) {
364     return EFI_UNSUPPORTED;
365   }
366 
367   HashInfo = GetHashInfo (HashAlgorithm);
368   if (HashInfo == NULL) {
369     return EFI_UNSUPPORTED;
370   }
371 
372   Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
373   if (Instance->HashContext != NULL) {
374     FreePool (Instance->HashContext);
375   }
376   Instance->HashInfoContext = NULL;
377   Instance->HashContext = NULL;
378 
379   //
380   // Start hash sequence
381   //
382   CtxSize = HashInfo->GetContextSize ();
383   if (CtxSize == 0) {
384     return EFI_UNSUPPORTED;
385   }
386   HashCtx = AllocatePool (CtxSize);
387   if (HashCtx == NULL) {
388     return EFI_OUT_OF_RESOURCES;
389   }
390 
391   Ret = HashInfo->Init (HashCtx);
392   if (!Ret) {
393     Status = EFI_OUT_OF_RESOURCES;
394     goto Done;
395   }
396 
397   //
398   // Setup the context
399   //
400   Instance->HashContext = HashCtx;
401   Instance->HashInfoContext = HashInfo;
402 
403   Ret = HashInfo->Update (HashCtx, Message, MessageSize);
404   if (!Ret) {
405     Status = EFI_OUT_OF_RESOURCES;
406     goto Done;
407   }
408 
409   Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);
410   if (!Ret) {
411     Status = EFI_OUT_OF_RESOURCES;
412     goto Done;
413   }
414 Done:
415   //
416   // Cleanup the context
417   //
418   FreePool (HashCtx);
419   Instance->HashInfoContext = NULL;
420   Instance->HashContext = NULL;
421   return Status;
422 }
423 
424 /**
425   This function must be called to initialize a digest calculation to be subsequently performed using the
426   EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
427 
428   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
429   @param[in]  HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
430 
431   @retval EFI_SUCCESS           Initialized successfully.
432   @retval EFI_INVALID_PARAMETER This is NULL.
433   @retval EFI_UNSUPPORTED       The algorithm specified by HashAlgorithm is not supported by this driver
434                                 or HashAlgorithm is Null.
435   @retval EFI_OUT_OF_RESOURCES  Process failed due to lack of required resource.
436   @retval EFI_ALREADY_STARTED   This function is called when the operation in progress is still in processing Hash(),
437                                 or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
438 
439 **/
440 EFI_STATUS
441 EFIAPI
BaseCrypto2HashInit(IN CONST EFI_HASH2_PROTOCOL * This,IN CONST EFI_GUID * HashAlgorithm)442 BaseCrypto2HashInit (
443   IN CONST EFI_HASH2_PROTOCOL      *This,
444   IN CONST EFI_GUID                *HashAlgorithm
445   )
446 {
447   EFI_HASH_INFO            *HashInfo;
448   VOID                     *HashCtx;
449   UINTN                    CtxSize;
450   BOOLEAN                  Ret;
451   HASH2_INSTANCE_DATA      *Instance;
452 
453   if (This == NULL) {
454     return EFI_INVALID_PARAMETER;
455   }
456 
457   if (HashAlgorithm == NULL) {
458     return EFI_UNSUPPORTED;
459   }
460 
461   HashInfo = GetHashInfo (HashAlgorithm);
462   if (HashInfo == NULL) {
463     return EFI_UNSUPPORTED;
464   }
465 
466   //
467   // Consistency Check
468   //
469   Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
470   if ((Instance->HashContext != NULL) || (Instance->HashInfoContext != NULL)) {
471     return EFI_ALREADY_STARTED;
472   }
473 
474   //
475   // Start hash sequence
476   //
477   CtxSize = HashInfo->GetContextSize ();
478   if (CtxSize == 0) {
479     return EFI_UNSUPPORTED;
480   }
481   HashCtx = AllocatePool (CtxSize);
482   if (HashCtx == NULL) {
483     return EFI_OUT_OF_RESOURCES;
484   }
485 
486   Ret = HashInfo->Init (HashCtx);
487   if (!Ret) {
488     FreePool (HashCtx);
489     return EFI_OUT_OF_RESOURCES;
490   }
491 
492   //
493   // Setup the context
494   //
495   Instance->HashContext = HashCtx;
496   Instance->HashInfoContext = HashInfo;
497   Instance->Updated = FALSE;
498 
499   return EFI_SUCCESS;
500 }
501 
502 /**
503   Updates the hash of a computation in progress by adding a message text.
504 
505   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
506   @param[in]  Message       Points to the start of the message.
507   @param[in]  MessageSize   The size of Message, in bytes.
508 
509   @retval EFI_SUCCESS           Digest in progress updated successfully.
510   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
511   @retval EFI_OUT_OF_RESOURCES  Some resource required by the function is not available
512                                 or MessageSize is greater than platform maximum.
513   @retval EFI_NOT_READY         This call was not preceded by a valid call to HashInit(),
514                                 or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
515 
516 **/
517 EFI_STATUS
518 EFIAPI
BaseCrypto2HashUpdate(IN CONST EFI_HASH2_PROTOCOL * This,IN CONST UINT8 * Message,IN UINTN MessageSize)519 BaseCrypto2HashUpdate (
520   IN CONST EFI_HASH2_PROTOCOL      *This,
521   IN CONST UINT8                   *Message,
522   IN UINTN                         MessageSize
523   )
524 {
525   EFI_HASH_INFO            *HashInfo;
526   VOID                     *HashCtx;
527   BOOLEAN                  Ret;
528   HASH2_INSTANCE_DATA      *Instance;
529 
530   if (This == NULL) {
531     return EFI_INVALID_PARAMETER;
532   }
533 
534   //
535   // Consistency Check
536   //
537   Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
538   if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) {
539     return EFI_NOT_READY;
540   }
541   HashInfo = Instance->HashInfoContext;
542   HashCtx  = Instance->HashContext;
543 
544   Ret = HashInfo->Update (HashCtx, Message, MessageSize);
545   if (!Ret) {
546     return EFI_OUT_OF_RESOURCES;
547   }
548 
549   Instance->Updated = TRUE;
550 
551   return EFI_SUCCESS;
552 }
553 
554 /**
555   Finalizes a hash operation in progress and returns calculation result.
556   The output is final with any necessary padding added by the function.
557   The hash may not be further updated or extended after HashFinal().
558 
559   @param[in]  This          Points to this instance of EFI_HASH2_PROTOCOL.
560   @param[in,out]  Hash      On input, points to a caller-allocated buffer of the size
561                               returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
562                             On output, the buffer holds the resulting hash computed from the message.
563 
564   @retval EFI_SUCCESS           Hash returned successfully.
565   @retval EFI_INVALID_PARAMETER This or Hash is NULL.
566   @retval EFI_NOT_READY         This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
567                                 or the operation in progress was canceled by a call to Hash() on the same instance.
568 
569 **/
570 EFI_STATUS
571 EFIAPI
BaseCrypto2HashFinal(IN CONST EFI_HASH2_PROTOCOL * This,IN OUT EFI_HASH2_OUTPUT * Hash)572 BaseCrypto2HashFinal (
573   IN CONST EFI_HASH2_PROTOCOL      *This,
574   IN OUT EFI_HASH2_OUTPUT          *Hash
575   )
576 {
577   EFI_HASH_INFO            *HashInfo;
578   VOID                     *HashCtx;
579   BOOLEAN                  Ret;
580   HASH2_INSTANCE_DATA      *Instance;
581 
582   if ((This == NULL) || (Hash == NULL)) {
583     return EFI_INVALID_PARAMETER;
584   }
585 
586   //
587   // Consistency Check
588   //
589   Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);
590   if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL) ||
591       (!Instance->Updated)) {
592     return EFI_NOT_READY;
593   }
594   HashInfo = Instance->HashInfoContext;
595   HashCtx  = Instance->HashContext;
596 
597   Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);
598 
599   //
600   // Cleanup the context
601   //
602   FreePool (HashCtx);
603   Instance->HashInfoContext = NULL;
604   Instance->HashContext = NULL;
605   Instance->Updated = FALSE;
606 
607   if (!Ret) {
608     return EFI_OUT_OF_RESOURCES;
609   }
610 
611   return EFI_SUCCESS;
612 }
613