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