From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web10.3133.1600131480635216724 for ; Mon, 14 Sep 2020 17:58:00 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: christopher.j.zurcher@intel.com) IronPort-SDR: qyvSSrH1H9Gado6i+8HVaoKZl8IpzuYgtdoRCtt5jC70wNWRdMcwvebn5wJt76Fz5HGzMEFhb2 39eA3k6Hnuww== X-IronPort-AV: E=McAfee;i="6000,8403,9744"; a="220738221" X-IronPort-AV: E=Sophos;i="5.76,427,1592895600"; d="scan'208";a="220738221" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Sep 2020 17:57:58 -0700 IronPort-SDR: TtvwNnGZhBv7o+y8FGhXkzBy3j5juN0A8sfMPDUbzhv4MGS9OtSEN+E+w1CXAhk0SQZPaDa6Ur 2m1/XEMma7kw== X-IronPort-AV: E=Sophos;i="5.76,427,1592895600"; d="scan'208";a="301949621" Received: from cjzurch-desk.amr.corp.intel.com ([10.9.70.181]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Sep 2020 17:57:58 -0700 From: "Zurcher, Christopher J" To: devel@edk2.groups.io Cc: Laszlo Ersek , Jiewen Yao , Jian J Wang , Xiaoyu Lu Subject: [PATCH v2 2/3] CryptoPkg: Add EVP to Crypto Service driver interface Date: Mon, 14 Sep 2020 17:57:48 -0700 Message-Id: <20200915005749.5331-3-christopher.j.zurcher@intel.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20200915005749.5331-1-christopher.j.zurcher@intel.com> References: <20200915005749.5331-1-christopher.j.zurcher@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2545 Cc: Laszlo Ersek Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Signed-off-by: Christopher J Zurcher --- CryptoPkg/CryptoPkg.dsc | 3 + CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h | 10 ++ CryptoPkg/Private/Protocol/Crypto.h | 127 +++++++++++++++++ CryptoPkg/Driver/Crypto.c | 148 +++++++++++++++++++- CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c | 140 ++++++++++++++++++ 5 files changed, 427 insertions(+), 1 deletion(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 1af78468a1..af3fceb99f 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -159,6 +159,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Tls.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif !if $(CRYPTO_SERVICES) == MIN_PEI @@ -173,6 +174,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.Free | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.SetKey | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Pkcs.Services.Pkcs5HashPassword | TRUE + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif !if $(CRYPTO_SERVICES) == MIN_DXE_MIN_SMM @@ -203,6 +205,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.Init | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcEncrypt | TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Aes.Services.CbcDecrypt | TRUE + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.EvpMd.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif ################################################################################################### diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 44fb0262f4..b79c98d679 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -288,6 +288,16 @@ typedef struct { } Services; UINT32 Family; } TlsGet; + union { + struct { + UINT8 Init:1; + UINT8 Duplicate:1; + UINT8 Update:1; + UINT8 Final:1; + UINT8 HashAll:1; + } Services; + UINT32 Family; + } EvpMd; } PCD_CRYPTO_SERVICE_FAMILY_ENABLE; #endif diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index c399e0d67a..84f1bc3f50 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -3434,6 +3434,127 @@ EFI_STATUS IN OUT UINTN *DataSize ); +/** + 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. + + @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. + +**/ +typedef +VOID * +(EFIAPI* EDKII_CRYPTO_EVPMD_INIT)( + 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. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_DUPLICATE)( + 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. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_UPDATE)( + 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. + + @retval TRUE EVP digest computation succeeded. + @retval FALSE EVP digest computation failed. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_FINAL)( + IN OUT VOID *EvpMdContext, + OUT UINT8 *DigestValue + ); + +/** + 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. + +**/ +typedef +BOOLEAN +(EFIAPI* EDKII_CRYPTO_EVPMD_HASH_ALL)( + IN CONST CHAR8 *DigestName, + IN CONST VOID *Data, + IN UINTN DataSize, + OUT UINT8 *HashValue + ); + /// /// EDK II Crypto Protocol @@ -3619,6 +3740,12 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert; EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey; EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationList; + /// Digest Envelope (EVP MD) + EDKII_CRYPTO_EVPMD_INIT EvpMdInit; + EDKII_CRYPTO_EVPMD_DUPLICATE EvpMdDuplicate; + EDKII_CRYPTO_EVPMD_UPDATE EvpMdUpdate; + EDKII_CRYPTO_EVPMD_FINAL EvpMdFinal; + EDKII_CRYPTO_EVPMD_HASH_ALL EvpMdHashAll; }; extern GUID gEdkiiCryptoProtocolGuid; diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index d9096ea603..a49af46e38 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -4463,6 +4463,146 @@ CryptoServiceTlsGetCertRevocationList ( return CALL_BASECRYPTLIB (TlsGet.Services.CertRevocationList, TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED); } +//===================================================================================== +// 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. + + @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 +CryptoServiceEvpMdInit ( + IN CONST CHAR8 *DigestName + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Init, EvpMdInit, (DigestName), NULL); +} + +/** + 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 +CryptoServiceEvpMdDuplicate ( + IN CONST VOID *EvpMdContext, + OUT VOID *NewEvpMdContext + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Duplicate, EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE); +} + +/** + 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 +CryptoServiceEvpMdUpdate ( + IN OUT VOID *EvpMdContext, + IN CONST VOID *Data, + IN UINTN DataSize + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Update, EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE); +} + +/** + 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 +CryptoServiceEvpMdFinal ( + IN OUT VOID *EvpMdContext, + OUT UINT8 *DigestValue + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.Final, EvpMdFinal, (EvpMdContext, DigestValue), FALSE); +} + +/** + 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 +CryptoServiceEvpMdHashAll ( + IN CONST CHAR8 *DigestName, + IN CONST VOID *Data, + IN UINTN DataSize, + OUT UINT8 *HashValue + ) +{ + return CALL_BASECRYPTLIB (EvpMd.Services.HashAll, EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE); +} + const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { /// Version CryptoServiceGetCryptoVersion, @@ -4663,5 +4803,11 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceTlsGetCaCertificate, CryptoServiceTlsGetHostPublicCert, CryptoServiceTlsGetHostPrivateKey, - CryptoServiceTlsGetCertRevocationList + CryptoServiceTlsGetCertRevocationList, + /// Digest Envelope (EVP MD) + CryptoServiceEvpMdInit, + CryptoServiceEvpMdDuplicate, + CryptoServiceEvpMdUpdate, + CryptoServiceEvpMdFinal, + CryptoServiceEvpMdHashAll }; diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 3f14c6d262..0d98bcb09c 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -3499,3 +3499,143 @@ TlsGetCertRevocationList ( { CALL_CRYPTO_SERVICE (TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED); } + +//===================================================================================== +// 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. + + @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 + ) +{ + CALL_CRYPTO_SERVICE (EvpMdInit, (DigestName), NULL); +} + +/** + 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 + ) +{ + CALL_CRYPTO_SERVICE (EvpMdDuplicate, (EvpMdContext, NewEvpMdContext), FALSE); +} + +/** + 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 + ) +{ + CALL_CRYPTO_SERVICE (EvpMdUpdate, (EvpMdContext, Data, DataSize), FALSE); +} + +/** + 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 + ) +{ + CALL_CRYPTO_SERVICE (EvpMdFinal, (EvpMdContext, DigestValue), FALSE); +} + +/** + 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 + ) +{ + CALL_CRYPTO_SERVICE (EvpMdHashAll, (DigestName, Data, DataSize, HashValue), FALSE); +} -- 2.28.0.windows.1