From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.120]) by mx.groups.io with SMTP id smtpd.web10.21298.1600259980881640641 for ; Wed, 16 Sep 2020 05:39:41 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Pti8VwJm; spf=pass (domain: redhat.com, ip: 207.211.31.120, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1600259980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XTTPgmS0kO0PuqiLeiYV6MtFHiPyHdjSWzIoGWl5beg=; b=Pti8VwJmNy2XOr9f+X7wxWTLL//xKJ+IWJPf0psUmW2XimpJd5NuobOCpwu9QAeice6ua6 4MOo3EEn2CcwobLWYo+YgcwXiXq2mdpGe3tCRHkJAYhRHoFRpVKaZvELYMTgFSDSxz+42U wIL1o8BAQzV8ol2geq1OwLQ0plREsaE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-475-qI0Agoq1MtKHd2F9bGv4zQ-1; Wed, 16 Sep 2020 08:39:35 -0400 X-MC-Unique: qI0Agoq1MtKHd2F9bGv4zQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9C4B010060C1; Wed, 16 Sep 2020 12:39:34 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-113-213.ams2.redhat.com [10.36.113.213]) by smtp.corp.redhat.com (Postfix) with ESMTP id E4BE05DE77; Wed, 16 Sep 2020 12:39:32 +0000 (UTC) Subject: Re: [edk2-devel] [PATCH v3 1/3] CryptoPkg/BaseCryptLib: Add EVP (Envelope) Digest interface To: "Yao, Jiewen" , "devel@edk2.groups.io" , "Zurcher, Christopher J" Cc: "Wang, Jian J" , "Lu, XiaoyuX" References: From: "Laszlo Ersek" Message-ID: <1096735a-182d-6ea1-99c2-d06e3caf4523@redhat.com> Date: Wed, 16 Sep 2020 14:39:31 +0200 MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0.003 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-Language: en-US On 09/16/20 14:07, Yao, Jiewen wrote: > I overlooked the behavior that NULL DigestValue will take side effect to free Context. > > Hi Christopher > May I understand why we need free the context? > This does not align with other existing HASH or HMAC functions. I requested that. It makes no sense to keep a finalized context. In other words, it makes no sense to separate finalization from freeing. A context that has been finalized is unusable for anything except freeing. Thanks Laszlo > > Thank you > Yao Jiewen > >> -----Original Message----- >> From: devel@edk2.groups.io On Behalf Of Yao, Jiewen >> Sent: Wednesday, September 16, 2020 7:45 PM >> To: Laszlo Ersek ; devel@edk2.groups.io; Zurcher, >> Christopher J >> Cc: Wang, Jian J ; Lu, XiaoyuX >> Subject: Re: [edk2-devel] [PATCH v3 1/3] CryptoPkg/BaseCryptLib: Add EVP >> (Envelope) Digest interface >> >> Hi Laszlo >> I disagree to put OPTIONAL for DigestValue, just because NULL is checked. >> If we need follow this, then we need add OPTIONAL to almost all pointer, which >> is unnecessary. >> >>> +BOOLEAN >>> +EFIAPI >>> +EvpMdFinal ( >>> + IN OUT VOID *EvpMdContext, >>> + OUT UINT8 *DigestValue >> >> (3) DigestValue should be marked OPTIONAL in my opinion, as NULL is >> deliberately permitted (for just freeing the context). >> >> >> >> >>> -----Original Message----- >>> From: Laszlo Ersek >>> Sent: Wednesday, September 16, 2020 7:07 PM >>> To: devel@edk2.groups.io; Zurcher, Christopher J >>> >>> Cc: Yao, Jiewen ; Wang, Jian J >> ; >>> Lu, XiaoyuX >>> Subject: Re: [edk2-devel] [PATCH v3 1/3] CryptoPkg/BaseCryptLib: Add EVP >>> (Envelope) Digest interface >>> >>> Hello Christopher, >>> >>> On 09/16/20 02:59, Zurcher, Christopher J wrote: >>>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545 >>>> >>>> The EVP interface should be used in place of discrete digest function >>>> calls. >>>> >>>> Cc: Laszlo Ersek >>>> Cc: Jiewen Yao >>>> Cc: Jian J Wang >>>> Cc: Xiaoyu Lu >>>> Signed-off-by: Christopher J Zurcher >>>> --- >>>> CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 + >>>> CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 + >>>> CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 + >>>> CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 + >>>> CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf | 1 + >>>> CryptoPkg/Include/Library/BaseCryptLib.h | 129 ++++++++++ >>>> CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c | 257 >>> ++++++++++++++++++++ >>>> CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c | 128 ++++++++++ >>>> CryptoPkg/Library/BaseCryptLibNull/Evp/CryptEvpMdNull.c | 128 >> ++++++++++ >>>> 9 files changed, 647 insertions(+) >>> >>> I agree that "CryptoPkg/Library/BaseCryptLibNull/Evp/CryptEvpMdNull.c" >>> is necessary. (If I understand correctly, that file was missing from >>> your v2 posting.) >>> >>> But "CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c" seems >>> superfluous. This file is never referenced in the INF files. >>> >>> The point of this file would be to allow *some* of the Base / Pei / >>> Runtime / Smm instances to "stub out" the EVP MD functions (i.e. provide >>> only stub implementations). But this isn't what's happening -- all of >>> the Base / Pei / Runtime / Smm instances are getting the real deal >>> ("CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c"). >>> >>> (1) So I think "CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c" >>> should be dropped. Only the Null instance of the library needs null >>> versions of the new functions. The Base / Pei / Runtime / Smm instances >>> don't. >>> >>>> >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf >>> b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf >>>> index 4aae2aba95..3968f29412 100644 >>>> --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf >>>> +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf >>>> @@ -50,6 +50,7 @@ >>>> Pk/CryptAuthenticode.c >>>> Pk/CryptTs.c >>>> Pem/CryptPem.c >>>> + Evp/CryptEvpMd.c >>>> >>>> SysCall/CrtWrapper.c >>>> SysCall/TimerWrapper.c >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf >>> b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf >>>> index dc28e3a11d..d0b91716d0 100644 >>>> --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf >>>> +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf >>>> @@ -57,6 +57,7 @@ >>>> Pk/CryptTsNull.c >>>> Pem/CryptPemNull.c >>>> Rand/CryptRandNull.c >>>> + Evp/CryptEvpMd.c >>>> >>>> SysCall/CrtWrapper.c >>>> SysCall/ConstantTimeClock.c >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf >>> b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf >>>> index 5005beed02..9f3accd35b 100644 >>>> --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf >>>> +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf >>>> @@ -56,6 +56,7 @@ >>>> Pk/CryptAuthenticodeNull.c >>>> Pk/CryptTsNull.c >>>> Pem/CryptPem.c >>>> + Evp/CryptEvpMd.c >>>> >>>> SysCall/CrtWrapper.c >>>> SysCall/TimerWrapper.c >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf >>> b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf >>>> index 91ec3e03bf..420623cdc6 100644 >>>> --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf >>>> +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf >>>> @@ -54,6 +54,7 @@ >>>> Pk/CryptAuthenticodeNull.c >>>> Pk/CryptTsNull.c >>>> Pem/CryptPem.c >>>> + Evp/CryptEvpMd.c >>>> >>>> SysCall/CrtWrapper.c >>>> SysCall/ConstantTimeClock.c >>>> diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf >>> b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf >>>> index 689af4fedd..542ac2e2e1 100644 >>>> --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf >>>> +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf >>>> @@ -50,6 +50,7 @@ >>>> Pk/CryptTsNull.c >>>> Pem/CryptPemNull.c >>>> Rand/CryptRandNull.c >>>> + Evp/CryptEvpMdNull.c >>>> >>>> [Packages] >>>> MdePkg/MdePkg.dec >>>> diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h >>> b/CryptoPkg/Include/Library/BaseCryptLib.h >>>> index ae9bde9e37..5e1b408b54 100644 >>>> --- a/CryptoPkg/Include/Library/BaseCryptLib.h >>>> +++ b/CryptoPkg/Include/Library/BaseCryptLib.h >>>> @@ -1012,6 +1012,135 @@ HmacSha256Final ( >>>> OUT UINT8 *HmacValue >>>> ); >>>> >>>> >>> >> +//============================================================== >>> ======================= >>>> +// EVP (Envelope) Primitive >>>> >>> >> +//============================================================== >>> ======================= >>>> + >>>> +/** >>>> + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD >>> use. >>>> + >>>> + If DigestName is NULL, then return FALSE. >>>> + >>>> + @param[in] DigestName Pointer to the digest name as a NULL- >>> terminated ASCII string. >>>> + Valid digest names are: >>>> + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 >>>> + SHA3-224, SHA3-256, SHA3-384, SHA3-512 >>>> + SM3 >>>> + >>>> + @return Pointer to the EVP_MD_CTX context that has been allocated and >>> initialized. >>>> + If DigestName is invalid, returns NULL. >>>> + If the allocations fails, returns NULL. >>>> + If initialization fails, returns NULL. >>>> + >>>> +**/ >>>> +VOID * >>>> +EFIAPI >>>> +EvpMdInit ( >>>> + IN CONST CHAR8 *DigestName >>>> + ); >>>> + >>>> +/** >>>> + Makes a copy of an existing EVP_MD context. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If NewEvpMdContext is NULL, then return FALSE. >>>> + >>>> + @param[in] EvpMdContext Pointer to EVP_MD context being copied. >>>> + @param[out] NewEvpMdContext Pointer to new EVP_MD context. >>>> + >>>> + @retval TRUE EVP_MD context copy succeeded. >>>> + @retval FALSE EVP_MD context copy failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdDuplicate ( >>>> + IN CONST VOID *EvpMdContext, >>>> + OUT VOID *NewEvpMdContext >>>> + ); >>>> + >>>> +/** >>>> + Digests the input data and updates EVP_MD context. >>>> + >>>> + This function performs EVP digest on a data buffer of the specified size. >>>> + It can be called multiple times to compute the digest of long or >>> discontinuous data streams. >>>> + EVP_MD context should be already correctly initialized by EvpMdInit(), and >>> should not >>>> + be finalized by EvpMdFinal(). Behavior with invalid context is undefined. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If Data is NULL and DataSize is not zero, return FALSE. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP_MD context. >>>> + @param[in] Data Pointer to the buffer containing the data to >> be >>> digested. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + >>>> + @retval TRUE EVP data digest succeeded. >>>> + @retval FALSE EVP data digest failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdUpdate ( >>>> + IN OUT VOID *EvpMdContext, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize >>>> + ); >>>> + >>>> +/** >>>> + Completes computation of the EVP digest value. >>>> + Releases the specified EVP_MD_CTX context. >>>> + >>>> + This function completes EVP hash computation and retrieves the digest >>> value into >>>> + the specified memory. After this function has been called, the EVP context >>> cannot >>>> + be used again. >>>> + EVP context should be already correctly initialized by EvpMdInit(), and >>> should >>>> + not be finalized by EvpMdFinal(). Behavior with invalid EVP context is >>> undefined. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If DigestValue is NULL, free the Context then return FALSE. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP context. >>>> + @param[out] Digest Pointer to a buffer that receives the EVP >> digest >>> value. >>> >>> (2) Please extend the comment on Digest with the following: >>> >>> The caller is responsible for providing enough storage for the digest >>> algorithm selected with EvpMdInit(). Providing EVP_MAX_MD_SIZE bytes >>> will suffice for storing the digest regardless of the algorithm chosen >>> in EvpMdInit(). >>> >>> (EVP_MAX_MD_SIZE is a public OpenSSL macro and I think we should openly >>> advertise it to consumers in edk2.) >>> >>>> + >>>> + @retval TRUE EVP digest computation succeeded. >>>> + @retval FALSE EVP digest computation failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdFinal ( >>>> + IN OUT VOID *EvpMdContext, >>>> + OUT UINT8 *DigestValue >>> >>> (3) DigestValue should be marked OPTIONAL in my opinion, as NULL is >>> deliberately permitted (for just freeing the context). >>> >>>> + ); >>>> + >>>> +/** >>>> + Computes the message digest of an input data buffer. >>>> + >>>> + This function performs the message digest of a given data buffer, and >> places >>>> + the digest value into the specified memory. >>>> + >>>> + If DigestName is NULL, return FALSE. >>>> + If Data is NULL and DataSize is not zero, return FALSE. >>>> + If HashValue is NULL, return FALSE. >>>> + >>>> + @param[in] DigestName Pointer to the digest name. >>>> + @param[in] Data Pointer to the buffer containing the data to be >>> hashed. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + @param[out] HashValue Pointer to a buffer that receives the digest >>> value. >>>> + >>>> + @retval TRUE Digest computation succeeded. >>>> + @retval FALSE Digest computation failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdHashAll ( >>>> + IN CONST CHAR8 *DigestName, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize, >>>> + OUT UINT8 *HashValue >>>> + ); >>>> + >>>> >>> >> //=============================================================== >>> ====================== >>>> // Symmetric Cryptography Primitive >>>> >>> >> //=============================================================== >>> ====================== >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c >>> b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c >>>> new file mode 100644 >>>> index 0000000000..b2770a9186 >>>> --- /dev/null >>>> +++ b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMd.c >>>> @@ -0,0 +1,257 @@ >>>> +/** @file >>>> + EVP MD Wrapper Implementation for OpenSSL. >>>> + >>>> +Copyright (c) 2020, Intel Corporation. All rights reserved.
>>>> +SPDX-License-Identifier: BSD-2-Clause-Patent >>>> + >>>> +**/ >>>> + >>>> +#include "InternalCryptLib.h" >>>> +#include >>>> + >>>> +/** >>>> + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD >>> use. >>>> + >>>> + If DigestName is NULL, then return FALSE. >>>> + >>>> + @param[in] DigestName Pointer to the digest name as a NULL- >>> terminated ASCII string. >>>> + Valid digest names are: >>>> + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 >>>> + SHA3-224, SHA3-256, SHA3-384, SHA3-512 >>>> + SM3 >>>> + >>>> + @return Pointer to the EVP_MD_CTX context that has been allocated and >>> initialized. >>>> + If DigestName is invalid, returns NULL. >>>> + If the allocations fails, returns NULL. >>>> + If initialization fails, returns NULL. >>>> + >>>> +**/ >>>> +VOID * >>>> +EFIAPI >>>> +EvpMdInit ( >>>> + IN CONST CHAR8 *DigestName >>>> + ) >>>> +{ >>>> + EVP_MD *Digest; >>>> + VOID *EvpMdContext; >>>> + >>>> + // >>>> + // Check input parameters. >>>> + // >>>> + if (DigestName == NULL) { >>>> + return NULL; >>>> + } >>>> + >>>> + // >>>> + // Allocate EVP_MD_CTX Context >>>> + // >>>> + EvpMdContext = EVP_MD_CTX_new (); >>>> + if (EvpMdContext == NULL) { >>>> + return NULL; >>>> + } >>>> + >>>> + Digest = EVP_get_digestbyname (DigestName); >>> >>> I think this may not compile with gcc (and correctly so). The pointer >>> returned by EVP_get_digestbyname() is const-qualified, but with the >>> assignment, we're throwing away the const-ness. >>> >>> (4) Please const-qualify the "Digest" local pointer. >>> >>>> + if (Digest == NULL) { >>>> + return NULL; >>>> + } >>> >>> (5) This is a memory leak I believe; "EvpMdContext" is leaked. >>> >>> For keeping the control flow simple, consider moving >>> EVP_get_digestbyname() above EVP_MD_CTX_new(). >>> >>>> + >>>> + // >>>> + // Initialize Context >>>> + // >>>> + if (EVP_DigestInit_ex (EvpMdContext, Digest, NULL) != 1) { >>>> + EVP_MD_CTX_free (EvpMdContext); >>>> + return NULL; >>>> + } >>>> + >>>> + return EvpMdContext; >>>> +} >>>> + >>>> +/** >>>> + Makes a copy of an existing EVP_MD context. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If NewEvpMdContext is NULL, then return FALSE. >>>> + >>>> + @param[in] EvpMdContext Pointer to EVP_MD context being copied. >>>> + @param[out] NewEvpMdContext Pointer to new EVP_MD context. >>>> + >>>> + @retval TRUE EVP_MD context copy succeeded. >>>> + @retval FALSE EVP_MD context copy failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdDuplicate ( >>>> + IN CONST VOID *EvpMdContext, >>>> + OUT VOID *NewEvpMdContext >>>> + ) >>>> +{ >>>> + // >>>> + // Check input parameters. >>>> + // >>>> + if (EvpMdContext == NULL || NewEvpMdContext == NULL) { >>>> + return FALSE; >>>> + } >>>> + >>>> + if (EVP_MD_CTX_copy (NewEvpMdContext, EvpMdContext) != 1) { >>>> + return FALSE; >>>> + } >>>> + >>>> + return TRUE; >>>> +} >>> >>> (6) Can you please confirm that the caller is supposed to initialize >>> "NewEvpMdContext" with EvpMdInit() first, before calling EvpMdDuplicate()? >>> >>>> + >>>> +/** >>>> + Digests the input data and updates EVP_MD context. >>>> + >>>> + This function performs EVP digest on a data buffer of the specified size. >>>> + It can be called multiple times to compute the digest of long or >>> discontinuous data streams. >>>> + EVP_MD context should be already correctly initialized by EvpMdInit(), and >>> should not >>>> + be finalized by EvpMdFinal(). Behavior with invalid context is undefined. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If Data is NULL and DataSize is not zero, return FALSE. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP_MD context. >>>> + @param[in] Data Pointer to the buffer containing the data to >> be >>> digested. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + >>>> + @retval TRUE EVP data digest succeeded. >>>> + @retval FALSE EVP data digest failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdUpdate ( >>>> + IN OUT VOID *EvpMdContext, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize >>>> + ) >>>> +{ >>>> + // >>>> + // Check input parameters. >>>> + // >>>> + if (EvpMdContext == NULL) { >>>> + return FALSE; >>>> + } >>>> + >>>> + // >>>> + // Check invalid parameters, in case only DataLength was checked in >>> OpenSSL >>>> + // >>>> + if (Data == NULL && DataSize != 0) { >>>> + return FALSE; >>>> + } >>>> + >>>> + // >>>> + // OpenSSL EVP digest update >>>> + // >>>> + if (EVP_DigestUpdate (EvpMdContext, Data, DataSize) != 1) { >>>> + return FALSE; >>>> + } >>>> + >>>> + return TRUE; >>>> +} >>>> + >>>> +/** >>>> + Completes computation of the EVP digest value. >>>> + Releases the specified EVP_MD_CTX context. >>>> + >>>> + This function completes EVP hash computation and retrieves the digest >>> value into >>>> + the specified memory. After this function has been called, the EVP context >>> cannot >>>> + be used again. >>>> + EVP context should be already correctly initialized by EvpMdInit(), and >>> should >>>> + not be finalized by EvpMdFinal(). Behavior with invalid EVP context is >>> undefined. >>>> + >>>> + If EvpMdContext is NULL, then return FALSE. >>>> + If DigestValue is NULL, free the Context then return FALSE. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP context. >>>> + @param[out] Digest Pointer to a buffer that receives the EVP >> digest >>> value. >>>> + >>>> + @retval TRUE EVP digest computation succeeded. >>>> + @retval FALSE EVP digest computation failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdFinal ( >>>> + IN OUT VOID *EvpMdContext, >>>> + OUT UINT8 *DigestValue >>>> + ) >>>> +{ >>>> + UINT32 Length; >>>> + BOOLEAN ReturnValue; >>>> + >>>> + ReturnValue = TRUE; >>>> + >>>> + // >>>> + // Check input parameters. >>>> + // >>>> + if (EvpMdContext == NULL) { >>>> + return FALSE; >>>> + } >>>> + if (DigestValue == NULL) { >>>> + EVP_MD_CTX_free (EvpMdContext); >>>> + return FALSE; >>>> + } >>>> + >>>> + // >>>> + // OpenSSL EVP digest finalization >>>> + // >>>> + if (EVP_DigestFinal_ex (EvpMdContext, DigestValue, &Length) != 1) { >>>> + ReturnValue = FALSE; >>>> + } >>> >>> >>> (7) I suggest dropping the "Length" local variable. EVP_DigestFinal_ex() >>> deals fine with the third parameter being NULL, according to the docs >>> (and the code). >>> >>> >>>> + >>>> + // >>>> + // Free OpenSSL EVP_MD_CTX Context >>>> + // >>>> + EVP_MD_CTX_free (EvpMdContext); >>>> + >>>> + return ReturnValue; >>>> +} >>>> + >>>> +/** >>>> + Computes the message digest of an input data buffer. >>>> + >>>> + This function performs the message digest of a given data buffer, and >> places >>>> + the digest value into the specified memory. >>>> + >>>> + If DigestName is NULL, return FALSE. >>>> + If Data is NULL and DataSize is not zero, return FALSE. >>>> + If HashValue is NULL, return FALSE. >>>> + >>>> + @param[in] DigestName Pointer to the digest name. >>>> + @param[in] Data Pointer to the buffer containing the data to be >>> hashed. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + @param[out] HashValue Pointer to a buffer that receives the digest >>> value. >>>> + >>>> + @retval TRUE Digest computation succeeded. >>>> + @retval FALSE Digest computation failed. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdHashAll ( >>>> + IN CONST CHAR8 *DigestName, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize, >>>> + OUT UINT8 *HashValue >>>> + ) >>>> +{ >>>> + BOOLEAN Result; >>>> + VOID *EvpMdContext; >>>> + >>>> + EvpMdContext = EvpMdInit (DigestName); >>>> + if (EvpMdContext == NULL) { >>>> + return FALSE; >>>> + } >>>> + >>>> + Result = EvpMdUpdate (EvpMdContext, Data, DataSize); >>>> + if (Result == FALSE) { >>> >>> (8) Style: please write (!Result). >>> >>> >>>> + EvpMdFinal (EvpMdContext, NULL); >>>> + return FALSE; >>>> + } >>>> + >>>> + Result = EvpMdFinal (EvpMdContext, HashValue); >>>> + >>>> + return Result; >>>> +} >>>> diff --git a/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c >>> b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c >>>> new file mode 100644 >>>> index 0000000000..038f63801f >>>> --- /dev/null >>>> +++ b/CryptoPkg/Library/BaseCryptLib/Evp/CryptEvpMdNull.c >>>> @@ -0,0 +1,128 @@ >>>> +/** @file >>>> + EVP MD Wrapper Null Library. >>>> + >>>> +Copyright (c) 2020, Intel Corporation. All rights reserved.
>>>> +SPDX-License-Identifier: BSD-2-Clause-Patent >>>> + >>>> +**/ >>>> + >>>> +#include "InternalCryptLib.h" >>>> + >>>> +/** >>>> + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD >>> use. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] DigestName Pointer to the digest name as a NULL- >>> terminated ASCII string. >>>> + Valid digest names are: >>>> + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 >>>> + SHA3-224, SHA3-256, SHA3-384, SHA3-512 >>>> + SM3 >>>> + >>>> + @return NULL This interface is not supported. >>>> + >>>> +**/ >>>> +VOID * >>>> +EFIAPI >>>> +EvpMdInit ( >>>> + IN CONST CHAR8 *DigestName >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return NULL; >>>> +} >>>> + >>>> +/** >>>> + Makes a copy of an existing EVP_MD context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] EvpMdContext Pointer to EVP_MD context being copied. >>>> + @param[out] NewEvpMdContext Pointer to new EVP_MD context. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdDuplicate ( >>>> + IN CONST VOID *EvpMdContext, >>>> + OUT VOID *NewEvpMdContext >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Digests the input data and updates EVP_MD context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP_MD context. >>>> + @param[in] Data Pointer to the buffer containing the data to >> be >>> digested. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdUpdate ( >>>> + IN OUT VOID *EvpMdContext, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Completes computation of the EVP digest value. >>>> + Releases the specified EVP_MD_CTX context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP context. >>>> + @param[out] Digest Pointer to a buffer that receives the EVP >> digest >>> value. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdFinal ( >>>> + IN OUT VOID *EvpMdContext, >>>> + OUT UINT8 *DigestValue >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Computes the message digest of an input data buffer. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] DigestName Pointer to the digest name. >>>> + @param[in] Data Pointer to the buffer containing the data to be >>> hashed. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + @param[out] HashValue Pointer to a buffer that receives the digest >>> value. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdHashAll ( >>>> + IN CONST CHAR8 *DigestName, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize, >>>> + OUT UINT8 *HashValue >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> diff --git a/CryptoPkg/Library/BaseCryptLibNull/Evp/CryptEvpMdNull.c >>> b/CryptoPkg/Library/BaseCryptLibNull/Evp/CryptEvpMdNull.c >>>> new file mode 100644 >>>> index 0000000000..038f63801f >>>> --- /dev/null >>>> +++ b/CryptoPkg/Library/BaseCryptLibNull/Evp/CryptEvpMdNull.c >>>> @@ -0,0 +1,128 @@ >>>> +/** @file >>>> + EVP MD Wrapper Null Library. >>>> + >>>> +Copyright (c) 2020, Intel Corporation. All rights reserved.
>>>> +SPDX-License-Identifier: BSD-2-Clause-Patent >>>> + >>>> +**/ >>>> + >>>> +#include "InternalCryptLib.h" >>>> + >>>> +/** >>>> + Allocates and initializes one EVP_MD_CTX context for subsequent EVP_MD >>> use. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] DigestName Pointer to the digest name as a NULL- >>> terminated ASCII string. >>>> + Valid digest names are: >>>> + MD5, SHA1, SHA224, SHA256, SHA384, SHA512 >>>> + SHA3-224, SHA3-256, SHA3-384, SHA3-512 >>>> + SM3 >>>> + >>>> + @return NULL This interface is not supported. >>>> + >>>> +**/ >>>> +VOID * >>>> +EFIAPI >>>> +EvpMdInit ( >>>> + IN CONST CHAR8 *DigestName >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return NULL; >>>> +} >>>> + >>>> +/** >>>> + Makes a copy of an existing EVP_MD context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] EvpMdContext Pointer to EVP_MD context being copied. >>>> + @param[out] NewEvpMdContext Pointer to new EVP_MD context. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdDuplicate ( >>>> + IN CONST VOID *EvpMdContext, >>>> + OUT VOID *NewEvpMdContext >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Digests the input data and updates EVP_MD context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP_MD context. >>>> + @param[in] Data Pointer to the buffer containing the data to >> be >>> digested. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdUpdate ( >>>> + IN OUT VOID *EvpMdContext, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Completes computation of the EVP digest value. >>>> + Releases the specified EVP_MD_CTX context. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in, out] EvpMdContext Pointer to the EVP context. >>>> + @param[out] Digest Pointer to a buffer that receives the EVP >> digest >>> value. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdFinal ( >>>> + IN OUT VOID *EvpMdContext, >>>> + OUT UINT8 *DigestValue >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> + >>>> +/** >>>> + Computes the message digest of an input data buffer. >>>> + >>>> + Return FALSE to indicate this interface is not supported. >>>> + >>>> + @param[in] DigestName Pointer to the digest name. >>>> + @param[in] Data Pointer to the buffer containing the data to be >>> hashed. >>>> + @param[in] DataSize Size of Data buffer in bytes. >>>> + @param[out] HashValue Pointer to a buffer that receives the digest >>> value. >>>> + >>>> + @retval FALSE This interface is not supported. >>>> + >>>> +**/ >>>> +BOOLEAN >>>> +EFIAPI >>>> +EvpMdHashAll ( >>>> + IN CONST CHAR8 *DigestName, >>>> + IN CONST VOID *Data, >>>> + IN UINTN DataSize, >>>> + OUT UINT8 *HashValue >>>> + ) >>>> +{ >>>> + ASSERT (FALSE); >>>> + return FALSE; >>>> +} >>>> >>> >>> Thanks, >>> Laszlo >> >> >> >