Home | History | Annotate | Download | only in Hash2DxeCrypto
      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 *
    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
    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
    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
    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
    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
    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