From nobody Wed May 15 16:43:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+94289+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94289+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1664097996; cv=none; d=zohomail.com; s=zohoarc; b=fRKcS85PcoEQPBjWalMbO4fUBTz/DBH6HvV9SBOJFNZvj3qmN1LZ69i5dEEJzUL8HvnQBxFk02SXayjVojNqotUx5mTAmVuVymgQka7xDLFcyT0Yi3NJY5kkoue0hQRUj2+E9bFtfpRX5OizT+5q6Ud92XOiYWsBMDX4ua32HR8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1664097996; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=0y8rtl2RavHuAVxHN/TYSl6tiJ2Nz+iPwUNjgVzn03E=; b=ZP7dxl1rsN2TIDht7K0MdKys8o/JKGPoDHF6Cw6LmXgA3CkfZTEHWcvd3WVNvmlip8fGRKsc2gSqayXdJk9SQ4Xm5zrAE0toe/r0p7A92+zRj0jO0FcST/ThmhYeHDspEizgkiKXHOaQKg6Aual2QRd1vuSje4nwqwHWmfJKtsE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94289+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1664097996585426.77452253637534; Sun, 25 Sep 2022 02:26:36 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id uO3KYY1788612xN0UroNoXEk; Sun, 25 Sep 2022 02:26:35 -0700 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web09.15664.1664097994062735551 for ; Sun, 25 Sep 2022 02:26:34 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10480"; a="327184321" X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="327184321" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:31 -0700 X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="683184410" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:29 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [edk2-devel] [PATCH V5 1/4] CryptoPkg: Add EC support Date: Sun, 25 Sep 2022 17:26:18 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yi1.li@intel.com X-Gm-Message-State: 1gxxxogmqksGr56oH8i4NceUx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1664097995; bh=BLWZPPZAgnO55qyC9I1tvjlO76CD19tPMQS3C/gsJJg=; h=Cc:Date:From:Reply-To:Subject:To; b=EBzyfyvupA2lQpED/+Ilryx88CvMqXzjgzZcC8gQRGZC91ltcOIvbM6soFwCyP6bPlP 1cY+4/VnKOBh8AA9thOMnsFSlGTFhS2O/a2WtUcjF+F8+ZhKSPLjLWUvm8FF2Ms5KpUDk O3ygPo7IWIBdzc/fqDlxzC2Fskw5v3FNY+E= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1664097997005100005 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3828 This patch is used to add CryptEc library, which is wrapped over OpenSSL. Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li Reviewed-by: Jiewen Yao Tested-by: Yi Li --- CryptoPkg/Include/Library/BaseCryptLib.h | 424 ++++++++++ .../Library/BaseCryptLib/BaseCryptLib.inf | 2 + .../Library/BaseCryptLib/PeiCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c | 765 ++++++++++++++++++ .../Library/BaseCryptLib/Pk/CryptEcNull.c | 496 ++++++++++++ .../Library/BaseCryptLib/SmmCryptLib.inf | 1 + .../BaseCryptLibNull/BaseCryptLibNull.inf | 1 + .../Library/BaseCryptLibNull/Pk/CryptEcNull.c | 496 ++++++++++++ 8 files changed, 2186 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c create mode 100644 CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/L= ibrary/BaseCryptLib.h index 3026299e29..63c6228368 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -14,6 +14,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 #include =20 +#define CRYPTO_NID_NULL 0x0000 + +// Key Exchange +#define CRYPTO_NID_SECP256R1 0x0204 +#define CRYPTO_NID_SECP384R1 0x0205 +#define CRYPTO_NID_SECP521R1 0x0206 + /// /// MD5 digest size in bytes /// @@ -3254,4 +3261,421 @@ BigNumAddMod ( OUT VOID *BnRes ); =20 +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Basic Elliptic Curve Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ); + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ); + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ); + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ); + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ); + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ); + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ); + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ); + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ); + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ); + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ); + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Elliptic Curve Diffie Hellman Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ); + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ); + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ); + #endif // __BASE_CRYPT_LIB_H__ diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Li= brary/BaseCryptLib/BaseCryptLib.inf index 0208d706b8..9634bd5fea 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -53,6 +53,8 @@ Pk/CryptTs.c Pk/CryptRsaPss.c Pk/CryptRsaPssSign.c + Pk/CryptEcNull.c |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnab= led + Pk/CryptEc.c |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled Pem/CryptPem.c Bn/CryptBn.c =20 diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Lib= rary/BaseCryptLib/PeiCryptLib.inf index 82b97bc6d3..3799780c9f 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -59,6 +59,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Bn/CryptBnNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c b/CryptoPkg/Librar= y/BaseCryptLib/Pk/CryptEc.c new file mode 100644 index 0000000000..396c819834 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c @@ -0,0 +1,765 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "InternalCryptLib.h" +#include +#include +#include + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Basic Elliptic Curve Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Return the Nid of certain ECC curve. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval !=3D-1 On success. + @retval -1 ECC curve not supported. +**/ +STATIC +INT32 +CryptoNidToOpensslNid ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + switch (CryptoNid) { + case CRYPTO_NID_SECP256R1: + Nid =3D NID_X9_62_prime256v1; + break; + case CRYPTO_NID_SECP384R1: + Nid =3D NID_secp384r1; + break; + case CRYPTO_NID_SECP521R1: + Nid =3D NID_secp521r1; + break; + default: + return -1; + } + + return Nid; +} + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + INT32 Nid; + + Nid =3D CryptoNidToOpensslNid (CryptoNid); + + if (Nid < 0) { + return NULL; + } + + return EC_GROUP_new_by_curve_name (Nid); +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA, BnB, BnCtx); +} + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder, NULL); +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + EC_GROUP_free (EcGroup); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + return EC_POINT_new (EcGroup); +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + if (Clear) { + EC_POINT_clear_free (EcPoint); + } else { + EC_POINT_free (EcPoint); + } +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup, EcPoint, BnX, = BnY, BnCtx); +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup, EcPoint, BnX, = BnY, BnCtx); +} + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult, EcPointA, EcPointB= , BnCtx); +} + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult, NULL, EcPoint, BnP= Scalar, BnCtx); +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx); +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) =3D=3D 1; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + return EC_POINT_is_at_infinity (EcGroup, EcPoint) =3D=3D 1; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) =3D=3D 0; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + return (BOOLEAN)EC_POINT_set_compressed_coordinates (EcGroup, EcPoint, B= nX, YBit, BnCtx); +} + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Elliptic Curve Diffie Hellman Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + INT32 OpenSslNid; + + OpenSslNid =3D CryptoNidToOpensslNid (Nid); + if (OpenSslNid < 0) { + return NULL; + } + + return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid); +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + EC_KEY_free ((EC_KEY *)EcContext); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + + if ((EcContext =3D=3D NULL) || (PublicKeySize =3D=3D NULL)) { + return FALSE; + } + + if ((PublicKey =3D=3D NULL) && (*PublicKeySize !=3D 0)) { + return FALSE; + } + + EcKey =3D (EC_KEY *)EcContext; + Group =3D EC_KEY_get0_group (EcKey); + HalfSize =3D (EC_GROUP_get_degree (Group) + 7) / 8; + + // Assume RAND_seed was called + if (EC_KEY_generate_key (EcKey) !=3D 1) { + return FALSE; + } + + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize =3D HalfSize * 2; + return FALSE; + } + + *PublicKeySize =3D HalfSize * 2; + + EcPoint =3D EC_KEY_get0_public_key (EcKey); + if (EcPoint =3D=3D NULL) { + return FALSE; + } + + RetVal =3D FALSE; + BnX =3D BN_new (); + BnY =3D BN_new (); + if ((BnX =3D=3D NULL) || (BnY =3D=3D NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != =3D 1) { + goto fail; + } + + XSize =3D BN_num_bytes (BnX); + YSize =3D BN_num_bytes (BnY); + if ((XSize <=3D 0) || (YSize <=3D 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <=3D HalfSize && (UINTN)YSize <=3D HalfSize); + + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + + RetVal =3D TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + EC_KEY *EcKey; + CONST EC_GROUP *Group; + CONST EC_POINT *EcPoint; + BIGNUM *BnX; + BIGNUM *BnY; + UINTN HalfSize; + INTN XSize; + INTN YSize; + BOOLEAN RetVal; + + if ((EcContext =3D=3D NULL) || (PublicKeySize =3D=3D NULL)) { + return FALSE; + } + + if ((PublicKey =3D=3D NULL) && (*PublicKeySize !=3D 0)) { + return FALSE; + } + + EcKey =3D (EC_KEY *)EcContext; + Group =3D EC_KEY_get0_group (EcKey); + HalfSize =3D (EC_GROUP_get_degree (Group) + 7) / 8; + if (*PublicKeySize < HalfSize * 2) { + *PublicKeySize =3D HalfSize * 2; + return FALSE; + } + + *PublicKeySize =3D HalfSize * 2; + + EcPoint =3D EC_KEY_get0_public_key (EcKey); + if (EcPoint =3D=3D NULL) { + return FALSE; + } + + RetVal =3D FALSE; + BnX =3D BN_new (); + BnY =3D BN_new (); + if ((BnX =3D=3D NULL) || (BnY =3D=3D NULL)) { + goto fail; + } + + if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY, NULL) != =3D 1) { + goto fail; + } + + XSize =3D BN_num_bytes (BnX); + YSize =3D BN_num_bytes (BnY); + if ((XSize <=3D 0) || (YSize <=3D 0)) { + goto fail; + } + + ASSERT ((UINTN)XSize <=3D HalfSize && (UINTN)YSize <=3D HalfSize); + + if (PublicKey !=3D NULL) { + ZeroMem (PublicKey, *PublicKeySize); + BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]); + BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]); + } + + RetVal =3D TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + return RetVal; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If public key is compressed, the PeerPublic will only contain half key (= X). + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + EC_KEY *EcKey; + EC_KEY *PeerEcKey; + CONST EC_GROUP *Group; + BOOLEAN RetVal; + BIGNUM *BnX; + BIGNUM *BnY; + EC_POINT *Point; + INT32 OpenSslNid; + UINTN HalfSize; + + if ((EcContext =3D=3D NULL) || (PeerPublic =3D=3D NULL) || (KeySize =3D= =3D NULL)) { + return FALSE; + } + + if ((Key =3D=3D NULL) && (*KeySize !=3D 0)) { + return FALSE; + } + + if (PeerPublicSize > INT_MAX) { + return FALSE; + } + + EcKey =3D (EC_KEY *)EcContext; + Group =3D EC_KEY_get0_group (EcKey); + HalfSize =3D (EC_GROUP_get_degree (Group) + 7) / 8; + if ((CompressFlag =3D=3D NULL) && (PeerPublicSize !=3D HalfSize * 2)) { + return FALSE; + } + + if ((CompressFlag !=3D NULL) && (PeerPublicSize !=3D HalfSize)) { + return FALSE; + } + + if (*KeySize < HalfSize) { + *KeySize =3D HalfSize; + return FALSE; + } + + *KeySize =3D HalfSize; + + RetVal =3D FALSE; + Point =3D NULL; + BnX =3D BN_bin2bn (PeerPublic, (INT32)HalfSize, NULL); + BnY =3D NULL; + Point =3D EC_POINT_new (Group); + PeerEcKey =3D NULL; + if ((BnX =3D=3D NULL) || (Point =3D=3D NULL)) { + goto fail; + } + + if (CompressFlag =3D=3D NULL) { + BnY =3D BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize, NULL); + if (BnY =3D=3D NULL) { + goto fail; + } + + if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY, NULL) != =3D 1) { + goto fail; + } + } else { + if (EC_POINT_set_compressed_coordinates (Group, Point, BnX, *CompressF= lag, NULL) !=3D 1) { + goto fail; + } + } + + // Validate NIST ECDH public key + OpenSslNid =3D EC_GROUP_get_curve_name (Group); + PeerEcKey =3D EC_KEY_new_by_curve_name (OpenSslNid); + if (PeerEcKey =3D=3D NULL) { + goto fail; + } + + if (EC_KEY_set_public_key (PeerEcKey, Point) !=3D 1) { + goto fail; + } + + if (EC_KEY_check_key (PeerEcKey) !=3D 1) { + goto fail; + } + + if (ECDH_compute_key (Key, *KeySize, Point, EcKey, NULL) <=3D 0) { + goto fail; + } + + RetVal =3D TRUE; + +fail: + BN_free (BnX); + BN_free (BnY); + EC_POINT_free (Point); + EC_KEY_free (PeerEcKey); + return RetVal; +} diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c b/CryptoPkg/Li= brary/BaseCryptLib/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Lib= rary/BaseCryptLib/SmmCryptLib.inf index 986581319c..9318052a51 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -60,6 +60,7 @@ Pk/CryptTsNull.c Pk/CryptRsaPss.c Pk/CryptRsaPssSignNull.c + Pk/CryptEcNull.c Pem/CryptPem.c Bn/CryptBnNull.c =20 diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/Cryp= toPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf index 88ada0430d..9cb8d42ff4 100644 --- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf +++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf @@ -50,6 +50,7 @@ Pk/CryptX509Null.c Pk/CryptAuthenticodeNull.c Pk/CryptTsNull.c + Pk/CryptEcNull.c Pem/CryptPemNull.c Rand/CryptRandNull.c Pk/CryptRsaPssNull.c diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c b/CryptoPk= g/Library/BaseCryptLibNull/Pk/CryptEcNull.c new file mode 100644 index 0000000000..d9f1004f6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptEcNull.c @@ -0,0 +1,496 @@ +/** @file + Elliptic Curve and ECDH API implementation based on OpenSSL + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient.. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + ASSERT (FALSE); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + ASSERT (FALSE); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + ASSERT (FALSE); + return NULL; +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + ASSERT (FALSE); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + ASSERT (FALSE); + return FALSE; +} --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94289): https://edk2.groups.io/g/devel/message/94289 Mute This Topic: https://groups.io/mt/93904007/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 16:43:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+94288+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94288+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1664097995; cv=none; d=zohomail.com; s=zohoarc; b=c0JgutrjECT9y9ClyeKzmWY7/XwV0mUvXvlH+RsqSwNbAinrjevUcdTeAciZFOdLciOLC/j3eoVsIwpIWHi98422P3R6AShntLYqBkqUwizUmNVILdFb7s8y0IdJtfCNdKk2DuWyMgqtsfsYmn/Exdb+ngfJOti1RMIGlMW3UW0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1664097995; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=rBDm0FkAlVN7OPnbM6HDhQVqqs9aXpdX9arVOYWYWks=; b=UvCwHMhx6utMZ/iWX0gEenAVWgq/hcXDCJNr5+y/wzN0BJxIr/xJTW9unLp2vN5oLkSnlqau0/ih0DRHIkssmSbdQcpH57wTPZqiFHbD0LvsODZUSnL5VJem/S+BoFVFNdsxSOreq6UOpvch1m6wGyQ8ncDfByQZeGzJozM6QbQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94288+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 166409799506640.125348729230836; Sun, 25 Sep 2022 02:26:35 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id gDs9YY1788612xI2sTeU5UTX; Sun, 25 Sep 2022 02:26:34 -0700 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web12.15630.1664097993446262916 for ; Sun, 25 Sep 2022 02:26:33 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10480"; a="327184325" X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="327184325" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:33 -0700 X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="683184415" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:31 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [edk2-devel] [PATCH V5 2/4] CryptoPkg: Add EC APIs to DXE and protocol Date: Sun, 25 Sep 2022 17:26:19 +0800 Message-Id: <9a6b184ca408badcfc2ad619c21ab2f88b32af43.1664097766.git.yi1.li@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yi1.li@intel.com X-Gm-Message-State: R52KYXfLU049VFTi5NXfEYXRx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1664097994; bh=029u9VRX0Rg8Z3/BmDC4p3Pw/i3lxt7i+6IgTG/i6p4=; h=Cc:Date:From:Reply-To:Subject:To; b=BOkLkdX9AxJh24iiZlHqLeezyDfwdVXzXvooQoDsB+b3DItiKpibQWCZLL6cbNnwSxQ 7QJlTVpyldctI7q7YHKGtaLNZG5mV+VdSLhNpVsZ0Yr9yUy/S2mIdWtar0/zFdd2mRHZ3 QwEtcLvFq3F1x1hu5Q/AZKg13AQuldWK7N0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1664097997037100006 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3828 The implementation provides CryptEc library functions for EFI Driveer and EFI BaseCrypt Protocol. Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li Reviewed-by: Jiewen Yao Tested-by: Yi Li --- CryptoPkg/CryptoPkg.dsc | 1 + CryptoPkg/Driver/Crypto.c | 496 +++++++++++ .../Pcd/PcdCryptoServiceFamilyEnable.h | 25 + .../BaseCryptLibOnProtocolPpi/CryptLib.c | 469 ++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 831 +++++++++++++----- 5 files changed, 1622 insertions(+), 200 deletions(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 7034e8a412..e4e7bc0dbf 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -172,6 +172,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.ParallelHash.Fa= mily | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.AeadAesGcm.Fami= ly | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Bn.Family = | PCD_CRYPTO_SERVICE_ENABLE_FAMILY + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Ec.Family = | 0 !endif =20 !if $(CRYPTO_SERVICES) =3D=3D MIN_PEI diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index 9872b5bf70..7a8266aaba 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -5519,6 +5519,481 @@ CryptoServiceBigNumAddMod ( return CALL_BASECRYPTLIB (Bn.Services.AddMod, BigNumAddMod, (BnA, BnB, B= nM, BnRes), FALSE); } =20 +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Basic Elliptic Curve Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +CryptoServiceEcGroupInit ( + IN UINTN CryptoNid + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.GroupInit, EcGroupInit, (CryptoNid= ), NULL); +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.GroupGetCurve, EcGroupGetCurve, (E= cGroup, BnPrime, BnA, BnB, BnCtx), FALSE); +} + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.GroupGetOrder, EcGroupGetOrder, (E= cGroup, BnOrder), FALSE); +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +CryptoServiceEcGroupFree ( + IN VOID *EcGroup + ) +{ + CALL_VOID_BASECRYPTLIB (Ec.Services.GroupFree, EcGroupFree, (EcGroup)); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +CryptoServiceEcPointInit ( + IN CONST VOID *EcGroup + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointInit, EcPointInit, (EcGroup),= NULL); +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +CryptoServiceEcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + CALL_VOID_BASECRYPTLIB (Ec.Services.PointDeInit, EcPointDeInit, (EcPoint= , Clear)); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointGetAffineCoordinates, EcPoint= GetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), FALSE); +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointSetAffineCoordinates, EcPoint= SetAffineCoordinates, (EcGroup, EcPoint, BnX, BnY, BnCtx), FALSE); +} + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointAdd, EcPointAdd, (EcGroup, Ec= PointResult, EcPointA, EcPointB, BnCtx), FALSE); +} + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointMul, EcPointMul, (EcGroup, Ec= PointResult, EcPoint, BnPScalar, BnCtx), FALSE); +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointInvert, EcPointInvert, (EcGro= up, EcPoint, BnCtx), FALSE); +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointIsOnCurve, EcPointIsOnCurve, = (EcGroup, EcPoint, BnCtx), FALSE); +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointIsAtInfinity, EcPointIsAtInfi= nity, (EcGroup, EcPoint), FALSE); +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointEqual, EcPointEqual, (EcGroup= , EcPointA, EcPointB, BnCtx), FALSE); +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.PointSetCompressedCoordinates, EcP= ointSetCompressedCoordinates, (EcGroup, EcPoint, BnX, YBit, BnCtx), FALSE); +} + +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// Elliptic Curve Diffie Hellman Primitives +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +CryptoServiceEcNewByNid ( + IN UINTN Nid + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.NewByNid, EcNewByNid, (Nid), NULL); +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +CryptoServiceEcFree ( + IN VOID *EcContext + ) +{ + CALL_VOID_BASECRYPTLIB (Ec.Services.Free, EcFree, (EcContext)); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.GenerateKey, EcGenerateKey, (EcCon= text, PublicKey, PublicKeySize), FALSE); +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.GetPubKey, EcGetPubKey, (EcContext= , PublicKey, PublicKeySize), FALSE); +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +CryptoServiceEcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + return CALL_BASECRYPTLIB (Ec.Services.DhComputeKey, EcDhComputeKey, (EcC= ontext, PeerPublic, PeerPublicSize, CompressFlag, Key, KeySize), FALSE); +} + const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto =3D { /// Version CryptoServiceGetCryptoVersion, @@ -5770,4 +6245,25 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto =3D { CryptoServiceBigNumContextFree, CryptoServiceBigNumSetUint, CryptoServiceBigNumAddMod, + /// EC + CryptoServiceEcGroupInit, + CryptoServiceEcGroupGetCurve, + CryptoServiceEcGroupGetOrder, + CryptoServiceEcGroupFree, + CryptoServiceEcPointInit, + CryptoServiceEcPointDeInit, + CryptoServiceEcPointGetAffineCoordinates, + CryptoServiceEcPointSetAffineCoordinates, + CryptoServiceEcPointAdd, + CryptoServiceEcPointMul, + CryptoServiceEcPointInvert, + CryptoServiceEcPointIsOnCurve, + CryptoServiceEcPointIsAtInfinity, + CryptoServiceEcPointEqual, + CryptoServiceEcPointSetCompressedCoordinates, + CryptoServiceEcNewByNid, + CryptoServiceEcFree, + CryptoServiceEcGenerateKey, + CryptoServiceEcGetPubKey, + CryptoServiceEcDhComputeKey, }; diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoP= kg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 52b44ca4f8..45bafc2161 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -356,6 +356,31 @@ typedef struct { } Services; UINT32 Family; } Bn; + union { + struct { + UINT8 GroupInit : 1; + UINT8 GroupGetCurve : 1; + UINT8 GroupGetOrder : 1; + UINT8 GroupFree : 1; + UINT8 PointInit : 1; + UINT8 PointDeInit : 1; + UINT8 PointGetAffineCoordinates : 1; + UINT8 PointSetAffineCoordinates : 1; + UINT8 PointAdd : 1; + UINT8 PointMul : 1; + UINT8 PointInvert : 1; + UINT8 PointIsOnCurve : 1; + UINT8 PointIsAtInfinity : 1; + UINT8 PointEqual : 1; + UINT8 PointSetCompressedCoordinates : 1; + UINT8 NewByNid : 1; + UINT8 Free : 1; + UINT8 GenerateKey : 1; + UINT8 GetPubKey : 1; + UINT8 DhComputeKey : 1; + } Services; + UINT32 Family; + } Ec; } PCD_CRYPTO_SERVICE_FAMILY_ENABLE; =20 #endif diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/Crypt= oPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index ce6981f091..791e2ef599 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -4553,3 +4553,472 @@ BigNumAddMod ( { CALL_CRYPTO_SERVICE (BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE); } + +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcGroupInit ( + IN UINTN CryptoNid + ) +{ + CALL_CRYPTO_SERVICE (EcGroupInit, (CryptoNid), NULL); +} + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetCurve ( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcGroupGetCurve, (EcGroup, BnPrime, BnA, BnB, BnCtx= ), FALSE); +} + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnOrder Group prime number. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcGroupGetOrder ( + IN VOID *EcGroup, + OUT VOID *BnOrder + ) +{ + CALL_CRYPTO_SERVICE (EcGroupGetOrder, (EcGroup, BnOrder), FALSE); +} + +/** + Free previously allocated EC group object using EcGroupInit(). + + @param[in] EcGroup EC group object to free. +**/ +VOID +EFIAPI +EcGroupFree ( + IN VOID *EcGroup + ) +{ + CALL_VOID_CRYPTO_SERVICE (EcGroupFree, (EcGroup)); +} + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit(). + + @retval EC Point object On success. + @retval NULL On failure. +**/ +VOID * +EFIAPI +EcPointInit ( + IN CONST VOID *EcGroup + ) +{ + CALL_CRYPTO_SERVICE (EcPointInit, (EcGroup), NULL); +} + +/** + Free previously allocated EC Point object using EcPointInit(). + + @param[in] EcPoint EC Point to free. + @param[in] Clear TRUE iff the memory should be cleared. +**/ +VOID +EFIAPI +EcPointDeInit ( + IN VOID *EcPoint, + IN BOOLEAN Clear + ) +{ + CALL_VOID_CRYPTO_SERVICE (EcPointDeInit, (EcPoint, Clear)); +} + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[out] BnX X coordinate. + @param[out] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointGetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointGetAffineCoordinates, (EcGroup, EcPoint, BnX= , BnY, BnCtx), FALSE); +} + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point object. + @param[in] BnX X coordinate. + @param[in] BnY Y coordinate. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetAffineCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointSetAffineCoordinates, (EcGroup, EcPoint, BnX= , BnY, BnCtx), FALSE); +} + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point. + @param[in] EcPointB EC Point. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointAdd ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointAdd, (EcGroup, EcPointResult, EcPointA, EcPo= intB, BnCtx), FALSE); +} + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar. + + @param[in] EcGroup EC group object. + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point. + @param[in] BnPScalar P Scalar. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointMul ( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointMul, (EcGroup, EcPointResult, EcPoint, BnPSc= alar, BnCtx), FALSE); +} + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object. + @param[in,out] EcPoint EC point to invert. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointInvert ( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointInvert, (EcGroup, EcPoint, BnCtx), FALSE); +} + +/** + Check if the supplied point is on EC curve. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On curve. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsOnCurve ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointIsOnCurve, (EcGroup, EcPoint, BnCtx), FALSE); +} + +/** + Check if the supplied point is at infinity. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC point to check. + + @retval TRUE At infinity. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointIsAtInfinity ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ) +{ + CALL_CRYPTO_SERVICE (EcPointIsAtInfinity, (EcGroup, EcPoint), FALSE); +} + +/** + Check if EC points are equal. + + @param[in] EcGroup EC group object. + @param[in] EcPointA EC point A. + @param[in] EcPointB EC point B. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE A =3D=3D B. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointEqual ( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointEqual, (EcGroup, EcPointA, EcPointB, BnCtx),= FALSE); +} + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object. + @param[in] EcPoint EC Point. + @param[in] BnX X coordinate. + @param[in] YBit 0 or 1 to identify which Y value is used. + @param[in] BnCtx BN context, created with BigNumNewContext(). + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +EcPointSetCompressedCoordinates ( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ) +{ + CALL_CRYPTO_SERVICE (EcPointSetCompressedCoordinates, (EcGroup, EcPoint,= BnX, YBit, BnCtx), FALSE); +} + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +VOID * +EFIAPI +EcNewByNid ( + IN UINTN Nid + ) +{ + CALL_CRYPTO_SERVICE (EcNewByNid, (Nid), NULL); +} + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +VOID +EFIAPI +EcFree ( + IN VOID *EcContext + ) +{ + CALL_VOID_CRYPTO_SERVICE (EcFree, (EcContext)); +} + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to the buffer to receive generat= ed public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcGenerateKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + CALL_CRYPTO_SERVICE (EcGenerateKey, (EcContext, PublicKey, PublicKeySize= ), FALSE); +} + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +BOOLEAN +EFIAPI +EcGetPubKey ( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ) +{ + CALL_CRYPTO_SERVICE (EcGetPubKey, (EcContext, PublicKey, PublicKeySize),= FALSE); +} + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +BOOLEAN +EFIAPI +EcDhComputeKey ( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ) +{ + CALL_CRYPTO_SERVICE (EcDhComputeKey, (EcContext, PeerPublic, PeerPublicS= ize, CompressFlag, Key, KeySize), FALSE); +} diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protoc= ol/Crypto.h index 3bf37575e9..2f267c7f55 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -21,7 +21,7 @@ /// the EDK II Crypto Protocol is extended, this version define must be /// increased. /// -#define EDKII_CRYPTO_VERSION 12 +#define EDKII_CRYPTO_VERSION 13 =20 /// /// EDK II Crypto Protocol forward declaration @@ -4289,240 +4289,671 @@ BOOLEAN OUT VOID *BnRes ); =20 +/** + Initialize new opaque EcGroup object. This object represents an EC curve= and + and is used for calculation within this group. This object should be fre= ed + using EcGroupFree() function. + + @param[in] CryptoNid Identifying number for the ECC curve (Defined in + BaseCryptLib.h). + + @retval EcGroup object On success + @retval NULL On failure +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_EC_GROUP_INIT)( + IN UINTN CryptoNid + ); + +/** + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P. + This function will set the provided Big Number objects to the correspon= ding + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object. + @param[out] BnPrime Group prime number. + @param[out] BnA A coefficient. + @param[out] BnB B coefficient. + @param[in] BnCtx BN context. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_GROUP_GET_CURVE)( + IN CONST VOID *EcGroup, + OUT VOID *BnPrime, + OUT VOID *BnA, + OUT VOID *BnB, + IN VOID *BnCtx + ); + +/** + Get EC group order. + This function will set the provided Big Number object to the correspondi= ng + value. The caller needs to make sure that the "out" BigNumber parameter + is properly initialized. + + @param[in] EcGroup EC group object + @param[out] BnOrder Group prime number + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_GROUP_GET_ORDER)( + IN VOID *EcGroup, + OUT VOID *BnOrder + ); + +/** + Free previously allocated EC group object using EcGroupInit() + + @param[in] EcGroup EC group object to free +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_EC_GROUP_FREE)( + IN VOID *EcGroup + ); + +/** + Initialize new opaque EC Point object. This object represents an EC point + within the given EC group (curve). + + @param[in] EC Group, properly initialized using EcGroupInit() + + @retval EC Point object On success + @retval NULL On failure +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_EC_POINT_INIT)( + IN CONST VOID *EcGroup + ); + +/** + Free previously allocated EC Point object using EcPointInit() + + @param[in] EcPoint EC Point to free + @param[in] Clear TRUE iff the memory should be cleared +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_EC_POINT_DE_INIT)( + IN VOID *EcPoint, + IN BOOLEAN Clear + ); + +/** + Get EC point affine (x,y) coordinates. + This function will set the provided Big Number objects to the correspond= ing + values. The caller needs to make sure all the "out" BigNumber parameters + are properly initialized. + + @param[in] EcGroup EC group object + @param[in] EcPoint EC point object + @param[out] BnX X coordinate + @param[out] BnY Y coordinate + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_GET_AFFINE_COORDINATES)( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + OUT VOID *BnX, + OUT VOID *BnY, + IN VOID *BnCtx + ); + +/** + Set EC point affine (x,y) coordinates. + + @param[in] EcGroup EC group object + @param[in] EcPoint EC point object + @param[in] BnX X coordinate + @param[in] BnY Y coordinate + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_SET_AFFINE_COORDINATES)( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN CONST VOID *BnY, + IN VOID *BnCtx + ); + +/** + EC Point addition. EcPointResult =3D EcPointA + EcPointB + + @param[in] EcGroup EC group object + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPointA EC Point + @param[in] EcPointB EC Point + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_ADD)( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar + + @param[in] EcGroup EC group object + @param[out] EcPointResult EC point to hold the result. The point shou= ld + be properly initialized. + @param[in] EcPoint EC Point + @param[in] BnPScalar P Scalar + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_MUL)( + IN CONST VOID *EcGroup, + OUT VOID *EcPointResult, + IN CONST VOID *EcPoint, + IN CONST VOID *BnPScalar, + IN VOID *BnCtx + ); + +/** + Calculate the inverse of the supplied EC point. + + @param[in] EcGroup EC group object + @param[in,out] EcPoint EC point to invert + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_INVERT)( + IN CONST VOID *EcGroup, + IN OUT VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is on EC curve + + @param[in] EcGroup EC group object + @param[in] EcPoint EC point to check + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On curve + @retval FALSE Otherwise +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_IS_ON_CURVE)( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint, + IN VOID *BnCtx + ); + +/** + Check if the supplied point is at infinity + + @param[in] EcGroup EC group object + @param[in] EcPoint EC point to check + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE At infinity + @retval FALSE Otherwise +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_IS_AT_INFINITY)( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPoint + ); + +/** + Check if EC points are equal + + @param[in] EcGroup EC group object + @param[in] EcPointA EC point A + @param[in] EcPointB EC point B + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE A =3D=3D B + @retval FALSE Otherwise +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_EQUAL)( + IN CONST VOID *EcGroup, + IN CONST VOID *EcPointA, + IN CONST VOID *EcPointB, + IN VOID *BnCtx + ); + +/** + Set EC point compressed coordinates. Points can be described in terms of + their compressed coordinates. For a point (x, y), for any given value fo= r x + such that the point is on the curve there will only ever be two possible + values for y. Therefore, a point can be set using this function where Bn= X is + the x coordinate and YBit is a value 0 or 1 to identify which of the two + possible values for y should be used. + + @param[in] EcGroup EC group object + @param[in] EcPoint EC Point + @param[in] BnX X coordinate + @param[in] YBit 0 or 1 to identify which Y value is used + @param[in] BnCtx BN context, created with BigNumNewContext() + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_POINT_SET_COMPRESSED_COORDINATES)( + IN CONST VOID *EcGroup, + IN VOID *EcPoint, + IN CONST VOID *BnX, + IN UINT8 YBit, + IN VOID *BnCtx + ); + +/** + Allocates and Initializes one Elliptic Curve Context for subsequent use + with the NID. + + @param[in] Nid cipher NID + @return Pointer to the Elliptic Curve Context that has been initiali= zed. + If the allocations fails, EcNewByNid() returns NULL. +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_EC_NEW_BY_NID)( + IN UINTN Nid + ); + +/** + Release the specified EC context. + + @param[in] EcContext Pointer to the EC context to be released. +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_EC_FREE)( + IN VOID *EcContext + ); + +/** + Generates EC key and returns EC public key (X, Y), Please note, this fun= ction uses + pseudo random number generator. The caller must make sure RandomSeed() + function was properly called before. + The Ec context should be correctly initialized by EcNewByNid. + This function generates random secret, and computes the public key (X, Y= ), which is + returned via parameter Public, PublicSize. + X is the first half of Public with size being PublicSize / 2, + Y is the second half of Public with size being PublicSize / 2. + EC context is updated accordingly. + If the Public buffer is too small to hold the public X, Y, FALSE is retu= rned and + PublicSize is set to the required buffer size to obtain the public X, Y. + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + If EcContext is NULL, then return FALSE. + If PublicSize is NULL, then return FALSE. + If PublicSize is large enough but Public is NULL, then return FALSE. + @param[in, out] EcContext Pointer to the EC context. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC public X,Y generation succeeded. + @retval FALSE EC public X,Y generation failed. + @retval FALSE PublicKeySize is not large enough. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_GENERATE_KEY)( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Gets the public key component from the established EC context. + The Ec context should be correctly initialized by EcNewByNid, and succes= sfully + generate key pair from EcGenerateKey(). + For P-256, the PublicSize is 64. First 32-byte is X, Second 32-byte is Y. + For P-384, the PublicSize is 96. First 48-byte is X, Second 48-byte is Y. + For P-521, the PublicSize is 132. First 66-byte is X, Second 66-byte is = Y. + @param[in, out] EcContext Pointer to EC context being set. + @param[out] PublicKey Pointer to t buffer to receive generated= public X,Y. + @param[in, out] PublicKeySize On input, the size of Public buffer in b= ytes. + On output, the size of data returned in = Public buffer in bytes. + @retval TRUE EC key component was retrieved successfully. + @retval FALSE Invalid EC key component. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_GET_PUB_KEY)( + IN OUT VOID *EcContext, + OUT UINT8 *PublicKey, + IN OUT UINTN *PublicKeySize + ); + +/** + Computes exchanged common key. + Given peer's public key (X, Y), this function computes the exchanged com= mon key, + based on its own context including value of curve parameter and random s= ecret. + X is the first half of PeerPublic with size being PeerPublicSize / 2, + Y is the second half of PeerPublic with size being PeerPublicSize / 2. + If EcContext is NULL, then return FALSE. + If PeerPublic is NULL, then return FALSE. + If PeerPublicSize is 0, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y. + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y. + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y. + @param[in, out] EcContext Pointer to the EC context. + @param[in] PeerPublic Pointer to the peer's public X,Y. + @param[in] PeerPublicSize Size of peer's public X,Y in bytes. + @param[in] CompressFlag Flag of PeerPublic is compressed or = not. + @param[out] Key Pointer to the buffer to receive gen= erated key. + @param[in, out] KeySize On input, the size of Key buffer in = bytes. + On output, the size of data returned= in Key buffer in bytes. + @retval TRUE EC exchanged key generation succeeded. + @retval FALSE EC exchanged key generation failed. + @retval FALSE KeySize is not large enough. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_EC_DH_COMPUTE_KEY)( + IN OUT VOID *EcContext, + IN CONST UINT8 *PeerPublic, + IN UINTN PeerPublicSize, + IN CONST INT32 *CompressFlag, + OUT UINT8 *Key, + IN OUT UINTN *KeySize + ); + /// /// EDK II Crypto Protocol /// struct _EDKII_CRYPTO_PROTOCOL { /// Version - EDKII_CRYPTO_GET_VERSION GetVersion; + EDKII_CRYPTO_GET_VERSION GetVersion; /// HMAC MD5 - deprecated and unsupported - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_NEW DeprecatedHmacMd5New; - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FREE DeprecatedHmacMd5Free; - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_SET_KEY DeprecatedHmacMd5SetK= ey; - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_DUPLICATE DeprecatedHmacMd5Dupl= icate; - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_UPDATE DeprecatedHmacMd5Upda= te; - DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FINAL DeprecatedHmacMd5Fina= l; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_NEW DeprecatedHmacMd5New; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FREE DeprecatedHmacMd5Fre= e; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_SET_KEY DeprecatedHmacMd5Set= Key; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_DUPLICATE DeprecatedHmacMd5Dup= licate; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_UPDATE DeprecatedHmacMd5Upd= ate; + DEPRECATED_EDKII_CRYPTO_HMAC_MD5_FINAL DeprecatedHmacMd5Fin= al; /// HMAC SHA1 - deprecated and unsupported - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_NEW DeprecatedHmacSha1New; - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FREE DeprecatedHmacSha1Fre= e; - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_SET_KEY DeprecatedHmacSha1Set= Key; - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_DUPLICATE DeprecatedHmacSha1Dup= licate; - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_UPDATE DeprecatedHmacSha1Upd= ate; - DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FINAL DeprecatedHmacSha1Fin= al; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_NEW DeprecatedHmacSha1Ne= w; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FREE DeprecatedHmacSha1Fr= ee; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_SET_KEY DeprecatedHmacSha1Se= tKey; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_DUPLICATE DeprecatedHmacSha1Du= plicate; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_UPDATE DeprecatedHmacSha1Up= date; + DEPRECATED_EDKII_CRYPTO_HMAC_SHA1_FINAL DeprecatedHmacSha1Fi= nal; /// HMAC SHA256 - EDKII_CRYPTO_HMAC_SHA256_NEW HmacSha256New; - EDKII_CRYPTO_HMAC_SHA256_FREE HmacSha256Free; - EDKII_CRYPTO_HMAC_SHA256_SET_KEY HmacSha256SetKey; - EDKII_CRYPTO_HMAC_SHA256_DUPLICATE HmacSha256Duplicate; - EDKII_CRYPTO_HMAC_SHA256_UPDATE HmacSha256Update; - EDKII_CRYPTO_HMAC_SHA256_FINAL HmacSha256Final; + EDKII_CRYPTO_HMAC_SHA256_NEW HmacSha256New; + EDKII_CRYPTO_HMAC_SHA256_FREE HmacSha256Free; + EDKII_CRYPTO_HMAC_SHA256_SET_KEY HmacSha256SetKey; + EDKII_CRYPTO_HMAC_SHA256_DUPLICATE HmacSha256Duplicate; + EDKII_CRYPTO_HMAC_SHA256_UPDATE HmacSha256Update; + EDKII_CRYPTO_HMAC_SHA256_FINAL HmacSha256Final; /// Md4 - deprecated and unsupported - DEPRECATED_EDKII_CRYPTO_MD4_GET_CONTEXT_SIZE DeprecatedMd4GetConte= xtSize; - DEPRECATED_EDKII_CRYPTO_MD4_INIT DeprecatedMd4Init; - DEPRECATED_EDKII_CRYPTO_MD4_DUPLICATE DeprecatedMd4Duplicat= e; - DEPRECATED_EDKII_CRYPTO_MD4_UPDATE DeprecatedMd4Update; - DEPRECATED_EDKII_CRYPTO_MD4_FINAL DeprecatedMd4Final; - DEPRECATED_EDKII_CRYPTO_MD4_HASH_ALL DeprecatedMd4HashAll; + DEPRECATED_EDKII_CRYPTO_MD4_GET_CONTEXT_SIZE DeprecatedMd4GetCont= extSize; + DEPRECATED_EDKII_CRYPTO_MD4_INIT DeprecatedMd4Init; + DEPRECATED_EDKII_CRYPTO_MD4_DUPLICATE DeprecatedMd4Duplica= te; + DEPRECATED_EDKII_CRYPTO_MD4_UPDATE DeprecatedMd4Update; + DEPRECATED_EDKII_CRYPTO_MD4_FINAL DeprecatedMd4Final; + DEPRECATED_EDKII_CRYPTO_MD4_HASH_ALL DeprecatedMd4HashAll; /// Md5 - EDKII_CRYPTO_MD5_GET_CONTEXT_SIZE Md5GetContextSize; - EDKII_CRYPTO_MD5_INIT Md5Init; - EDKII_CRYPTO_MD5_DUPLICATE Md5Duplicate; - EDKII_CRYPTO_MD5_UPDATE Md5Update; - EDKII_CRYPTO_MD5_FINAL Md5Final; - EDKII_CRYPTO_MD5_HASH_ALL Md5HashAll; + EDKII_CRYPTO_MD5_GET_CONTEXT_SIZE Md5GetContextSize; + EDKII_CRYPTO_MD5_INIT Md5Init; + EDKII_CRYPTO_MD5_DUPLICATE Md5Duplicate; + EDKII_CRYPTO_MD5_UPDATE Md5Update; + EDKII_CRYPTO_MD5_FINAL Md5Final; + EDKII_CRYPTO_MD5_HASH_ALL Md5HashAll; /// Pkcs - EDKII_CRYPTO_PKCS1_ENCRYPT_V2 Pkcs1v2Encrypt; - EDKII_CRYPTO_PKCS5_PW_HASH Pkcs5HashPassword; - EDKII_CRYPTO_PKCS7_VERIFY Pkcs7Verify; - EDKII_CRYPTO_PKCS7_VERIFY_EKU VerifyEKUsInPkcs7Sign= ature; - EDKII_CRYPTO_PKCS7_GET_SIGNERS Pkcs7GetSigners; - EDKII_CRYPTO_PKCS7_FREE_SIGNERS Pkcs7FreeSigners; - EDKII_CRYPTO_PKCS7_SIGN Pkcs7Sign; - EDKII_CRYPTO_PKCS7_GET_ATTACHED_CONTENT Pkcs7GetAttachedConte= nt; - EDKII_CRYPTO_PKCS7_GET_CERTIFICATES_LIST Pkcs7GetCertificatesL= ist; - EDKII_CRYPTO_AUTHENTICODE_VERIFY AuthenticodeVerify; - EDKII_CRYPTO_IMAGE_TIMESTAMP_VERIFY ImageTimestampVerify; + EDKII_CRYPTO_PKCS1_ENCRYPT_V2 Pkcs1v2Encrypt; + EDKII_CRYPTO_PKCS5_PW_HASH Pkcs5HashPassword; + EDKII_CRYPTO_PKCS7_VERIFY Pkcs7Verify; + EDKII_CRYPTO_PKCS7_VERIFY_EKU VerifyEKUsInPkcs7Sig= nature; + EDKII_CRYPTO_PKCS7_GET_SIGNERS Pkcs7GetSigners; + EDKII_CRYPTO_PKCS7_FREE_SIGNERS Pkcs7FreeSigners; + EDKII_CRYPTO_PKCS7_SIGN Pkcs7Sign; + EDKII_CRYPTO_PKCS7_GET_ATTACHED_CONTENT Pkcs7GetAttachedCont= ent; + EDKII_CRYPTO_PKCS7_GET_CERTIFICATES_LIST Pkcs7GetCertificates= List; + EDKII_CRYPTO_AUTHENTICODE_VERIFY AuthenticodeVerify; + EDKII_CRYPTO_IMAGE_TIMESTAMP_VERIFY ImageTimestampVerify; /// DH - EDKII_CRYPTO_DH_NEW DhNew; - EDKII_CRYPTO_DH_FREE DhFree; - EDKII_CRYPTO_DH_GENERATE_PARAMETER DhGenerateParameter; - EDKII_CRYPTO_DH_SET_PARAMETER DhSetParameter; - EDKII_CRYPTO_DH_GENERATE_KEY DhGenerateKey; - EDKII_CRYPTO_DH_COMPUTE_KEY DhComputeKey; + EDKII_CRYPTO_DH_NEW DhNew; + EDKII_CRYPTO_DH_FREE DhFree; + EDKII_CRYPTO_DH_GENERATE_PARAMETER DhGenerateParameter; + EDKII_CRYPTO_DH_SET_PARAMETER DhSetParameter; + EDKII_CRYPTO_DH_GENERATE_KEY DhGenerateKey; + EDKII_CRYPTO_DH_COMPUTE_KEY DhComputeKey; /// Random - EDKII_CRYPTO_RANDOM_SEED RandomSeed; - EDKII_CRYPTO_RANDOM_BYTES RandomBytes; + EDKII_CRYPTO_RANDOM_SEED RandomSeed; + EDKII_CRYPTO_RANDOM_BYTES RandomBytes; /// RSA - EDKII_CRYPTO_RSA_VERIFY_PKCS1 RsaVerifyPkcs1; - EDKII_CRYPTO_RSA_NEW RsaNew; - EDKII_CRYPTO_RSA_FREE RsaFree; - EDKII_CRYPTO_RSA_SET_KEY RsaSetKey; - EDKII_CRYPTO_RSA_GET_KEY RsaGetKey; - EDKII_CRYPTO_RSA_GENERATE_KEY RsaGenerateKey; - EDKII_CRYPTO_RSA_CHECK_KEY RsaCheckKey; - EDKII_CRYPTO_RSA_PKCS1_SIGN RsaPkcs1Sign; - EDKII_CRYPTO_RSA_PKCS1_VERIFY RsaPkcs1Verify; - EDKII_CRYPTO_RSA_GET_PRIVATE_KEY_FROM_PEM RsaGetPrivateKeyFromP= em; - EDKII_CRYPTO_RSA_GET_PUBLIC_KEY_FROM_X509 RsaGetPublicKeyFromX5= 09; + EDKII_CRYPTO_RSA_VERIFY_PKCS1 RsaVerifyPkcs1; + EDKII_CRYPTO_RSA_NEW RsaNew; + EDKII_CRYPTO_RSA_FREE RsaFree; + EDKII_CRYPTO_RSA_SET_KEY RsaSetKey; + EDKII_CRYPTO_RSA_GET_KEY RsaGetKey; + EDKII_CRYPTO_RSA_GENERATE_KEY RsaGenerateKey; + EDKII_CRYPTO_RSA_CHECK_KEY RsaCheckKey; + EDKII_CRYPTO_RSA_PKCS1_SIGN RsaPkcs1Sign; + EDKII_CRYPTO_RSA_PKCS1_VERIFY RsaPkcs1Verify; + EDKII_CRYPTO_RSA_GET_PRIVATE_KEY_FROM_PEM RsaGetPrivateKeyFrom= Pem; + EDKII_CRYPTO_RSA_GET_PUBLIC_KEY_FROM_X509 RsaGetPublicKeyFromX= 509; /// Sha1 - EDKII_CRYPTO_SHA1_GET_CONTEXT_SIZE Sha1GetContextSize; - EDKII_CRYPTO_SHA1_INIT Sha1Init; - EDKII_CRYPTO_SHA1_DUPLICATE Sha1Duplicate; - EDKII_CRYPTO_SHA1_UPDATE Sha1Update; - EDKII_CRYPTO_SHA1_FINAL Sha1Final; - EDKII_CRYPTO_SHA1_HASH_ALL Sha1HashAll; + EDKII_CRYPTO_SHA1_GET_CONTEXT_SIZE Sha1GetContextSize; + EDKII_CRYPTO_SHA1_INIT Sha1Init; + EDKII_CRYPTO_SHA1_DUPLICATE Sha1Duplicate; + EDKII_CRYPTO_SHA1_UPDATE Sha1Update; + EDKII_CRYPTO_SHA1_FINAL Sha1Final; + EDKII_CRYPTO_SHA1_HASH_ALL Sha1HashAll; /// Sha256 - EDKII_CRYPTO_SHA256_GET_CONTEXT_SIZE Sha256GetContextSize; - EDKII_CRYPTO_SHA256_INIT Sha256Init; - EDKII_CRYPTO_SHA256_DUPLICATE Sha256Duplicate; - EDKII_CRYPTO_SHA256_UPDATE Sha256Update; - EDKII_CRYPTO_SHA256_FINAL Sha256Final; - EDKII_CRYPTO_SHA256_HASH_ALL Sha256HashAll; + EDKII_CRYPTO_SHA256_GET_CONTEXT_SIZE Sha256GetContextSize; + EDKII_CRYPTO_SHA256_INIT Sha256Init; + EDKII_CRYPTO_SHA256_DUPLICATE Sha256Duplicate; + EDKII_CRYPTO_SHA256_UPDATE Sha256Update; + EDKII_CRYPTO_SHA256_FINAL Sha256Final; + EDKII_CRYPTO_SHA256_HASH_ALL Sha256HashAll; /// Sha384 - EDKII_CRYPTO_SHA384_GET_CONTEXT_SIZE Sha384GetContextSize; - EDKII_CRYPTO_SHA384_INIT Sha384Init; - EDKII_CRYPTO_SHA384_DUPLICATE Sha384Duplicate; - EDKII_CRYPTO_SHA384_UPDATE Sha384Update; - EDKII_CRYPTO_SHA384_FINAL Sha384Final; - EDKII_CRYPTO_SHA384_HASH_ALL Sha384HashAll; + EDKII_CRYPTO_SHA384_GET_CONTEXT_SIZE Sha384GetContextSize; + EDKII_CRYPTO_SHA384_INIT Sha384Init; + EDKII_CRYPTO_SHA384_DUPLICATE Sha384Duplicate; + EDKII_CRYPTO_SHA384_UPDATE Sha384Update; + EDKII_CRYPTO_SHA384_FINAL Sha384Final; + EDKII_CRYPTO_SHA384_HASH_ALL Sha384HashAll; /// Sha512 - EDKII_CRYPTO_SHA512_GET_CONTEXT_SIZE Sha512GetContextSize; - EDKII_CRYPTO_SHA512_INIT Sha512Init; - EDKII_CRYPTO_SHA512_DUPLICATE Sha512Duplicate; - EDKII_CRYPTO_SHA512_UPDATE Sha512Update; - EDKII_CRYPTO_SHA512_FINAL Sha512Final; - EDKII_CRYPTO_SHA512_HASH_ALL Sha512HashAll; + EDKII_CRYPTO_SHA512_GET_CONTEXT_SIZE Sha512GetContextSize; + EDKII_CRYPTO_SHA512_INIT Sha512Init; + EDKII_CRYPTO_SHA512_DUPLICATE Sha512Duplicate; + EDKII_CRYPTO_SHA512_UPDATE Sha512Update; + EDKII_CRYPTO_SHA512_FINAL Sha512Final; + EDKII_CRYPTO_SHA512_HASH_ALL Sha512HashAll; /// X509 - EDKII_CRYPTO_X509_GET_SUBJECT_NAME X509GetSubjectName; - EDKII_CRYPTO_X509_GET_COMMON_NAME X509GetCommonName; - EDKII_CRYPTO_X509_GET_ORGANIZATION_NAME X509GetOrganizationNa= me; - EDKII_CRYPTO_X509_VERIFY_CERT X509VerifyCert; - EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE X509ConstructCertific= ate; - EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK X509ConstructCertific= ateStack; - EDKII_CRYPTO_X509_FREE X509Free; - EDKII_CRYPTO_X509_STACK_FREE X509StackFree; - EDKII_CRYPTO_X509_GET_TBS_CERT X509GetTBSCert; + EDKII_CRYPTO_X509_GET_SUBJECT_NAME X509GetSubjectName; + EDKII_CRYPTO_X509_GET_COMMON_NAME X509GetCommonName; + EDKII_CRYPTO_X509_GET_ORGANIZATION_NAME X509GetOrganizationN= ame; + EDKII_CRYPTO_X509_VERIFY_CERT X509VerifyCert; + EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE X509ConstructCertifi= cate; + EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK X509ConstructCertifi= cateStack; + EDKII_CRYPTO_X509_FREE X509Free; + EDKII_CRYPTO_X509_STACK_FREE X509StackFree; + EDKII_CRYPTO_X509_GET_TBS_CERT X509GetTBSCert; /// TDES - deprecated and unsupported - DEPRECATED_EDKII_CRYPTO_TDES_GET_CONTEXT_SIZE DeprecatedTdesGetCont= extSize; - DEPRECATED_EDKII_CRYPTO_TDES_INIT DeprecatedTdesInit; - DEPRECATED_EDKII_CRYPTO_TDES_ECB_ENCRYPT DeprecatedTdesEcbEncr= ypt; - DEPRECATED_EDKII_CRYPTO_TDES_ECB_DECRYPT DeprecatedTdesEcbDecr= ypt; - DEPRECATED_EDKII_CRYPTO_TDES_CBC_ENCRYPT DeprecatedTdesCbcEncr= ypt; - DEPRECATED_EDKII_CRYPTO_TDES_CBC_DECRYPT DeprecatedTdesCbcDecr= ypt; + DEPRECATED_EDKII_CRYPTO_TDES_GET_CONTEXT_SIZE DeprecatedTdesGetCon= textSize; + DEPRECATED_EDKII_CRYPTO_TDES_INIT DeprecatedTdesInit; + DEPRECATED_EDKII_CRYPTO_TDES_ECB_ENCRYPT DeprecatedTdesEcbEnc= rypt; + DEPRECATED_EDKII_CRYPTO_TDES_ECB_DECRYPT DeprecatedTdesEcbDec= rypt; + DEPRECATED_EDKII_CRYPTO_TDES_CBC_ENCRYPT DeprecatedTdesCbcEnc= rypt; + DEPRECATED_EDKII_CRYPTO_TDES_CBC_DECRYPT DeprecatedTdesCbcDec= rypt; /// AES - ECB Mode is deprecated and unsupported - EDKII_CRYPTO_AES_GET_CONTEXT_SIZE AesGetContextSize; - EDKII_CRYPTO_AES_INIT AesInit; - DEPRECATED_EDKII_CRYPTO_AES_ECB_ENCRYPT DeprecatedAesEcbEncry= pt; - DEPRECATED_EDKII_CRYPTO_AES_ECB_DECRYPT DeprecatedAesEcbDecry= pt; - EDKII_CRYPTO_AES_CBC_ENCRYPT AesCbcEncrypt; - EDKII_CRYPTO_AES_CBC_DECRYPT AesCbcDecrypt; + EDKII_CRYPTO_AES_GET_CONTEXT_SIZE AesGetContextSize; + EDKII_CRYPTO_AES_INIT AesInit; + DEPRECATED_EDKII_CRYPTO_AES_ECB_ENCRYPT DeprecatedAesEcbEncr= ypt; + DEPRECATED_EDKII_CRYPTO_AES_ECB_DECRYPT DeprecatedAesEcbDecr= ypt; + EDKII_CRYPTO_AES_CBC_ENCRYPT AesCbcEncrypt; + EDKII_CRYPTO_AES_CBC_DECRYPT AesCbcDecrypt; /// Arc4 - deprecated and unsupported - DEPRECATED_EDKII_CRYPTO_ARC4_GET_CONTEXT_SIZE DeprecatedArc4GetCont= extSize; - DEPRECATED_EDKII_CRYPTO_ARC4_INIT DeprecatedArc4Init; - DEPRECATED_EDKII_CRYPTO_ARC4_ENCRYPT DeprecatedArc4Encrypt; - DEPRECATED_EDKII_CRYPTO_ARC4_DECRYPT DeprecatedArc4Decrypt; - DEPRECATED_EDKII_CRYPTO_ARC4_RESET DeprecatedArc4Reset; + DEPRECATED_EDKII_CRYPTO_ARC4_GET_CONTEXT_SIZE DeprecatedArc4GetCon= textSize; + DEPRECATED_EDKII_CRYPTO_ARC4_INIT DeprecatedArc4Init; + DEPRECATED_EDKII_CRYPTO_ARC4_ENCRYPT DeprecatedArc4Encryp= t; + DEPRECATED_EDKII_CRYPTO_ARC4_DECRYPT DeprecatedArc4Decryp= t; + DEPRECATED_EDKII_CRYPTO_ARC4_RESET DeprecatedArc4Reset; /// SM3 - EDKII_CRYPTO_SM3_GET_CONTEXT_SIZE Sm3GetContextSize; - EDKII_CRYPTO_SM3_INIT Sm3Init; - EDKII_CRYPTO_SM3_DUPLICATE Sm3Duplicate; - EDKII_CRYPTO_SM3_UPDATE Sm3Update; - EDKII_CRYPTO_SM3_FINAL Sm3Final; - EDKII_CRYPTO_SM3_HASH_ALL Sm3HashAll; + EDKII_CRYPTO_SM3_GET_CONTEXT_SIZE Sm3GetContextSize; + EDKII_CRYPTO_SM3_INIT Sm3Init; + EDKII_CRYPTO_SM3_DUPLICATE Sm3Duplicate; + EDKII_CRYPTO_SM3_UPDATE Sm3Update; + EDKII_CRYPTO_SM3_FINAL Sm3Final; + EDKII_CRYPTO_SM3_HASH_ALL Sm3HashAll; /// HKDF - EDKII_CRYPTO_HKDF_SHA_256_EXTRACT_AND_EXPAND HkdfSha256ExtractAndE= xpand; + EDKII_CRYPTO_HKDF_SHA_256_EXTRACT_AND_EXPAND HkdfSha256ExtractAnd= Expand; /// X509 (Continued) - EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK_V X509ConstructCertific= ateStackV; + EDKII_CRYPTO_X509_CONSTRUCT_CERTIFICATE_STACK_V X509ConstructCertifi= cateStackV; /// TLS - EDKII_CRYPTO_TLS_INITIALIZE TlsInitialize; - EDKII_CRYPTO_TLS_CTX_FREE TlsCtxFree; - EDKII_CRYPTO_TLS_CTX_NEW TlsCtxNew; - EDKII_CRYPTO_TLS_FREE TlsFree; - EDKII_CRYPTO_TLS_NEW TlsNew; - EDKII_CRYPTO_TLS_IN_HANDSHAKE TlsInHandshake; - EDKII_CRYPTO_TLS_DO_HANDSHAKE TlsDoHandshake; - EDKII_CRYPTO_TLS_HANDLE_ALERT TlsHandleAlert; - EDKII_CRYPTO_TLS_CLOSE_NOTIFY TlsCloseNotify; - EDKII_CRYPTO_TLS_CTRL_TRAFFIC_OUT TlsCtrlTrafficOut; - EDKII_CRYPTO_TLS_CTRL_TRAFFIC_IN TlsCtrlTrafficIn; - EDKII_CRYPTO_TLS_READ TlsRead; - EDKII_CRYPTO_TLS_WRITE TlsWrite; + EDKII_CRYPTO_TLS_INITIALIZE TlsInitialize; + EDKII_CRYPTO_TLS_CTX_FREE TlsCtxFree; + EDKII_CRYPTO_TLS_CTX_NEW TlsCtxNew; + EDKII_CRYPTO_TLS_FREE TlsFree; + EDKII_CRYPTO_TLS_NEW TlsNew; + EDKII_CRYPTO_TLS_IN_HANDSHAKE TlsInHandshake; + EDKII_CRYPTO_TLS_DO_HANDSHAKE TlsDoHandshake; + EDKII_CRYPTO_TLS_HANDLE_ALERT TlsHandleAlert; + EDKII_CRYPTO_TLS_CLOSE_NOTIFY TlsCloseNotify; + EDKII_CRYPTO_TLS_CTRL_TRAFFIC_OUT TlsCtrlTrafficOut; + EDKII_CRYPTO_TLS_CTRL_TRAFFIC_IN TlsCtrlTrafficIn; + EDKII_CRYPTO_TLS_READ TlsRead; + EDKII_CRYPTO_TLS_WRITE TlsWrite; /// TLS Set - EDKII_CRYPTO_TLS_SET_VERSION TlsSetVersion; - EDKII_CRYPTO_TLS_SET_CONNECTION_END TlsSetConnectionEnd; - EDKII_CRYPTO_TLS_SET_CIPHER_LIST TlsSetCipherList; - EDKII_CRYPTO_TLS_SET_COMPRESSION_METHOD TlsSetCompressionMeth= od; - EDKII_CRYPTO_TLS_SET_VERIFY TlsSetVerify; - EDKII_CRYPTO_TLS_SET_VERIFY_HOST TlsSetVerifyHost; - EDKII_CRYPTO_TLS_SET_SESSIONID TlsSetSessionId; - EDKII_CRYPTO_TLS_SET_CA_CERTIFICATE TlsSetCaCertificate; - EDKII_CRYPTO_TLS_SET_HOST_PUBLIC_CERT TlsSetHostPublicCert; - EDKII_CRYPTO_TLS_SET_HOST_PRIVATE_KEY TlsSetHostPrivateKey; - EDKII_CRYPTO_TLS_SET_CERT_REVOCATION_LIST TlsSetCertRevocationL= ist; + EDKII_CRYPTO_TLS_SET_VERSION TlsSetVersion; + EDKII_CRYPTO_TLS_SET_CONNECTION_END TlsSetConnectionEnd; + EDKII_CRYPTO_TLS_SET_CIPHER_LIST TlsSetCipherList; + EDKII_CRYPTO_TLS_SET_COMPRESSION_METHOD TlsSetCompressionMet= hod; + EDKII_CRYPTO_TLS_SET_VERIFY TlsSetVerify; + EDKII_CRYPTO_TLS_SET_VERIFY_HOST TlsSetVerifyHost; + EDKII_CRYPTO_TLS_SET_SESSIONID TlsSetSessionId; + EDKII_CRYPTO_TLS_SET_CA_CERTIFICATE TlsSetCaCertificate; + EDKII_CRYPTO_TLS_SET_HOST_PUBLIC_CERT TlsSetHostPublicCert; + EDKII_CRYPTO_TLS_SET_HOST_PRIVATE_KEY TlsSetHostPrivateKey; + EDKII_CRYPTO_TLS_SET_CERT_REVOCATION_LIST TlsSetCertRevocation= List; /// TLS Get - EDKII_CRYPTO_TLS_GET_VERSION TlsGetVersion; - EDKII_CRYPTO_TLS_GET_CONNECTION_END TlsGetConnectionEnd; - EDKII_CRYPTO_TLS_GET_CURRENT_CIPHER TlsGetCurrentCipher; - EDKII_CRYPTO_TLS_GET_CURRENT_COMPRESSION_ID TlsGetCurrentCompress= ionId; - EDKII_CRYPTO_TLS_GET_VERIFY TlsGetVerify; - EDKII_CRYPTO_TLS_GET_SESSION_ID TlsGetSessionId; - EDKII_CRYPTO_TLS_GET_CLIENT_RANDOM TlsGetClientRandom; - EDKII_CRYPTO_TLS_GET_SERVER_RANDOM TlsGetServerRandom; - EDKII_CRYPTO_TLS_GET_KEY_MATERIAL TlsGetKeyMaterial; - EDKII_CRYPTO_TLS_GET_CA_CERTIFICATE TlsGetCaCertificate; - EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert; - EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey; - EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocationL= ist; + EDKII_CRYPTO_TLS_GET_VERSION TlsGetVersion; + EDKII_CRYPTO_TLS_GET_CONNECTION_END TlsGetConnectionEnd; + EDKII_CRYPTO_TLS_GET_CURRENT_CIPHER TlsGetCurrentCipher; + EDKII_CRYPTO_TLS_GET_CURRENT_COMPRESSION_ID TlsGetCurrentCompres= sionId; + EDKII_CRYPTO_TLS_GET_VERIFY TlsGetVerify; + EDKII_CRYPTO_TLS_GET_SESSION_ID TlsGetSessionId; + EDKII_CRYPTO_TLS_GET_CLIENT_RANDOM TlsGetClientRandom; + EDKII_CRYPTO_TLS_GET_SERVER_RANDOM TlsGetServerRandom; + EDKII_CRYPTO_TLS_GET_KEY_MATERIAL TlsGetKeyMaterial; + EDKII_CRYPTO_TLS_GET_CA_CERTIFICATE TlsGetCaCertificate; + EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT TlsGetHostPublicCert; + EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY TlsGetHostPrivateKey; + EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST TlsGetCertRevocation= List; /// RSA PSS - EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign; - EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify; + EDKII_CRYPTO_RSA_PSS_SIGN RsaPssSign; + EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify; /// Parallel hash - EDKII_CRYPTO_PARALLEL_HASH_ALL ParallelHash256HashAl= l; + EDKII_CRYPTO_PARALLEL_HASH_ALL ParallelHash256HashA= ll; /// HMAC SHA256 (continued) - EDKII_CRYPTO_HMAC_SHA256_ALL HmacSha256All; + EDKII_CRYPTO_HMAC_SHA256_ALL HmacSha256All; /// HMAC SHA384 - EDKII_CRYPTO_HMAC_SHA384_NEW HmacSha384New; - EDKII_CRYPTO_HMAC_SHA384_FREE HmacSha384Free; - EDKII_CRYPTO_HMAC_SHA384_SET_KEY HmacSha384SetKey; - EDKII_CRYPTO_HMAC_SHA384_DUPLICATE HmacSha384Duplicate; - EDKII_CRYPTO_HMAC_SHA384_UPDATE HmacSha384Update; - EDKII_CRYPTO_HMAC_SHA384_FINAL HmacSha384Final; - EDKII_CRYPTO_HMAC_SHA384_ALL HmacSha384All; + EDKII_CRYPTO_HMAC_SHA384_NEW HmacSha384New; + EDKII_CRYPTO_HMAC_SHA384_FREE HmacSha384Free; + EDKII_CRYPTO_HMAC_SHA384_SET_KEY HmacSha384SetKey; + EDKII_CRYPTO_HMAC_SHA384_DUPLICATE HmacSha384Duplicate; + EDKII_CRYPTO_HMAC_SHA384_UPDATE HmacSha384Update; + EDKII_CRYPTO_HMAC_SHA384_FINAL HmacSha384Final; + EDKII_CRYPTO_HMAC_SHA384_ALL HmacSha384All; /// HKDF (continued) - EDKII_CRYPTO_HKDF_SHA_256_EXTRACT HkdfSha256Extract; - EDKII_CRYPTO_HKDF_SHA_256_EXPAND HkdfSha256Expand; - EDKII_CRYPTO_HKDF_SHA_384_EXTRACT_AND_EXPAND HkdfSha384ExtractAndE= xpand; - EDKII_CRYPTO_HKDF_SHA_384_EXTRACT HkdfSha384Extract; - EDKII_CRYPTO_HKDF_SHA_384_EXPAND HkdfSha384Expand; + EDKII_CRYPTO_HKDF_SHA_256_EXTRACT HkdfSha256Extract; + EDKII_CRYPTO_HKDF_SHA_256_EXPAND HkdfSha256Expand; + EDKII_CRYPTO_HKDF_SHA_384_EXTRACT_AND_EXPAND HkdfSha384ExtractAnd= Expand; + EDKII_CRYPTO_HKDF_SHA_384_EXTRACT HkdfSha384Extract; + EDKII_CRYPTO_HKDF_SHA_384_EXPAND HkdfSha384Expand; /// AEAD AES-GCM - EDKII_AEAD_AES_GCM_ENCRYPT AeadAesGcmEncrypt; - EDKII_AEAD_AES_GCM_DECRYPT AeadAesGcmDecrypt; + EDKII_AEAD_AES_GCM_ENCRYPT AeadAesGcmEncrypt; + EDKII_AEAD_AES_GCM_DECRYPT AeadAesGcmDecrypt; /// BIGNUM - EDKII_CRYPTO_BIGNUM_INIT BigNumInit; - EDKII_CRYPTO_BIGNUM_FROM_BIN BigNumFromBin; - EDKII_CRYPTO_BIGNUM_TO_BIN BigNumToBin; - EDKII_CRYPTO_BIGNUM_FREE BigNumFree; - EDKII_CRYPTO_BIGNUM_ADD BigNumAdd; - EDKII_CRYPTO_BIGNUM_SUB BigNumSub; - EDKII_CRYPTO_BIGNUM_MOD BigNumMod; - EDKII_CRYPTO_BIGNUM_EXP_MOD BigNumExpMod; - EDKII_CRYPTO_BIGNUM_INVERSE_MOD BigNumInverseMod; - EDKII_CRYPTO_BIGNUM_DIV BigNumDiv; - EDKII_CRYPTO_BIGNUM_MUL_MOD BigNumMulMod; - EDKII_CRYPTO_BIGNUM_CMP BigNumCmp; - EDKII_CRYPTO_BIGNUM_BITS BigNumBits; - EDKII_CRYPTO_BIGNUM_BYTES BigNumBytes; - EDKII_CRYPTO_BIGNUM_IS_WORD BigNumIsWord; - EDKII_CRYPTO_BIGNUM_IS_ODD BigNumIsOdd; - EDKII_CRYPTO_BIGNUM_COPY BigNumCopy; - EDKII_CRYPTO_BIGNUM_VALUE_ONE BigNumValueOne; - EDKII_CRYPTO_BIGNUM_R_SHIFT BigNumRShift; - EDKII_CRYPTO_BIGNUM_CONST_TIME BigNumConstTime; - EDKII_CRYPTO_BIGNUM_SQR_MOD BigNumSqrMod; - EDKII_CRYPTO_BIGNUM_NEW_CONTEXT BigNumNewContext; - EDKII_CRYPTO_BIGNUM_CONTEXT_FREE BigNumContextFree; - EDKII_CRYPTO_BIGNUM_SET_UINT BigNumSetUint; - EDKII_CRYPTO_BIGNUM_ADD_MOD BigNumAddMod; + EDKII_CRYPTO_BIGNUM_INIT BigNumInit; + EDKII_CRYPTO_BIGNUM_FROM_BIN BigNumFromBin; + EDKII_CRYPTO_BIGNUM_TO_BIN BigNumToBin; + EDKII_CRYPTO_BIGNUM_FREE BigNumFree; + EDKII_CRYPTO_BIGNUM_ADD BigNumAdd; + EDKII_CRYPTO_BIGNUM_SUB BigNumSub; + EDKII_CRYPTO_BIGNUM_MOD BigNumMod; + EDKII_CRYPTO_BIGNUM_EXP_MOD BigNumExpMod; + EDKII_CRYPTO_BIGNUM_INVERSE_MOD BigNumInverseMod; + EDKII_CRYPTO_BIGNUM_DIV BigNumDiv; + EDKII_CRYPTO_BIGNUM_MUL_MOD BigNumMulMod; + EDKII_CRYPTO_BIGNUM_CMP BigNumCmp; + EDKII_CRYPTO_BIGNUM_BITS BigNumBits; + EDKII_CRYPTO_BIGNUM_BYTES BigNumBytes; + EDKII_CRYPTO_BIGNUM_IS_WORD BigNumIsWord; + EDKII_CRYPTO_BIGNUM_IS_ODD BigNumIsOdd; + EDKII_CRYPTO_BIGNUM_COPY BigNumCopy; + EDKII_CRYPTO_BIGNUM_VALUE_ONE BigNumValueOne; + EDKII_CRYPTO_BIGNUM_R_SHIFT BigNumRShift; + EDKII_CRYPTO_BIGNUM_CONST_TIME BigNumConstTime; + EDKII_CRYPTO_BIGNUM_SQR_MOD BigNumSqrMod; + EDKII_CRYPTO_BIGNUM_NEW_CONTEXT BigNumNewContext; + EDKII_CRYPTO_BIGNUM_CONTEXT_FREE BigNumContextFree; + EDKII_CRYPTO_BIGNUM_SET_UINT BigNumSetUint; + EDKII_CRYPTO_BIGNUM_ADD_MOD BigNumAddMod; + /// EC + EDKII_CRYPTO_EC_GROUP_INIT EcGroupInit; + EDKII_CRYPTO_EC_GROUP_GET_CURVE EcGroupGetCurve; + EDKII_CRYPTO_EC_GROUP_GET_ORDER EcGroupGetOrder; + EDKII_CRYPTO_EC_GROUP_FREE EcGroupFree; + EDKII_CRYPTO_EC_POINT_INIT EcPointInit; + EDKII_CRYPTO_EC_POINT_DE_INIT EcPointDeInit; + EDKII_CRYPTO_EC_POINT_GET_AFFINE_COORDINATES EcPointGetAffineCoor= dinates; + EDKII_CRYPTO_EC_POINT_SET_AFFINE_COORDINATES EcPointSetAffineCoor= dinates; + EDKII_CRYPTO_EC_POINT_ADD EcPointAdd; + EDKII_CRYPTO_EC_POINT_MUL EcPointMul; + EDKII_CRYPTO_EC_POINT_INVERT EcPointInvert; + EDKII_CRYPTO_EC_POINT_IS_ON_CURVE EcPointIsOnCurve; + EDKII_CRYPTO_EC_POINT_IS_AT_INFINITY EcPointIsAtInfinity; + EDKII_CRYPTO_EC_POINT_EQUAL EcPointEqual; + EDKII_CRYPTO_EC_POINT_SET_COMPRESSED_COORDINATES EcPointSetCompressed= Coordinates; + EDKII_CRYPTO_EC_NEW_BY_NID EcNewByNid; + EDKII_CRYPTO_EC_FREE EcFree; + EDKII_CRYPTO_EC_GENERATE_KEY EcGenerateKey; + EDKII_CRYPTO_EC_GET_PUB_KEY EcGetPubKey; + EDKII_CRYPTO_EC_DH_COMPUTE_KEY EcDhComputeKey; }; =20 extern GUID gEdkiiCryptoProtocolGuid; --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94288): https://edk2.groups.io/g/devel/message/94288 Mute This Topic: https://groups.io/mt/93904006/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 16:43:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+94290+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94290+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1664097997; cv=none; d=zohomail.com; s=zohoarc; b=gHJvPnXRTbD5myB7wbWmByVMAluoLXOwV50JpZuTEyv/KrFRyZ+zxwjrcUNP3ycGcSEtMMY5UxyDozE8nh4BpniFNW6KpTjhKbFBB2aj6mafjRqToSo9FFIvdE0rGMy90yxWSJmiIzdm0SR1rmBq0nOxbv1EPAC1PIRCUrVDoXQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1664097997; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=vWL3Bl5UHxSlepexSVGnePO+RJQvLB0rYPQ0n42Sawg=; b=gcmU4YUHw5f/Xin46xwzi8ap5T4nkD7VmlHgQiikkbckLH04LW+RJnJl+9v/jtwbI+WOyebqIuwaWbxKEM33L9ANS+a2K9ju8tgWuxTjAC49j/+HwhZmXKVy/z+3DY9Ux3OEmNdN4a/oGPk3rsSDOmoYEEtKyACyz8MK8AUx3Xs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94290+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1664097997133132.8265499898498; Sun, 25 Sep 2022 02:26:37 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8ApnYY1788612xAlGqvikKmJ; Sun, 25 Sep 2022 02:26:36 -0700 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.15349.1664097995730274692 for ; Sun, 25 Sep 2022 02:26:36 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10480"; a="327184333" X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="327184333" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:35 -0700 X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="683184422" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:33 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang , Michael D Kinney Subject: [edk2-devel] [PATCH V5 3/4] CryptoPkg: Add ECC related usage reference Date: Sun, 25 Sep 2022 17:26:20 +0800 Message-Id: <16a6dae98cf537151236ae1558b9a1b58bfa4e4d.1664097766.git.yi1.li@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yi1.li@intel.com X-Gm-Message-State: cXvVAKwELbXWx1RAiN96pPCQx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1664097996; bh=1tkuSEwI+JOfRykj7YwQvGBLHVLW2cfOg1VHjhgVbqg=; h=Cc:Date:From:Reply-To:Subject:To; b=kVcmBnD2jdiVR5tM32wyCDU65gdtsBEBtuwoum0ODQRcXwlFFcnuIfi4N37gXfBT4HM kv+4jIVNssNjACBUYwF1U5rn9y/o3WgR1yjnpZqxrQDq46MEmcIm9wat6EqTiUcdBYzmJ Q/W94gHpLUv2P1KvqXiWl7BZB0dqRiSWuSA= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1664097998936100013 Content-Type: text/plain; charset="utf-8" Describes the use cases under which ECC needs to be enabled, and provides the impact on memory size for developers' reference. Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Cc: Michael D Kinney Signed-off-by: Yi Li Reviewed-by: Jiewen Yao Tested-by: Yi Li --- CryptoPkg/CryptoPkg.dec | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec index d9b64e5763..a3716864fd 100644 --- a/CryptoPkg/CryptoPkg.dec +++ b/CryptoPkg/CryptoPkg.dec @@ -83,7 +83,36 @@ =20 ## Enable/Disable the ECC feature in openssl library. The default is dis= abled. # If ECC feature is disabled, all related source files will not be comp= iled. + # @Prompt Enable/Disable ECC feature in EDK II Crypto gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled|FALSE|BOOLEAN|0x0000003 + # Set it to TRUE if: + # 1) Platform needs ECC in TLS, or asymmetric cryptography services such= as + # X509 certificate or PEM format data processing. + # 2) Platform needs to enable PcdCryptoServiceFamilyEnable.Ec service. + # Please note: + # ECC feature will cause a significant memory increase, approximate memo= ry impact + # in below table for reference by platform developers with FW size limit= ations. + # Uncompressed LZMA Compressed + # CPU CRYPTO_SERVICES Module EC=3DFALSE EC=3DTRUE EC=3DFALSE EC= =3DTRUE Increase + # =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D= =3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D + # IA32 NONE CryptoPei 21536 21568 = 0 KB + # IA32 NONE CryptoDxe 21632 21696 = 0 KB + # IA32 NONE CryptoSmm 22976 23072 = 0 KB + # IA32 MIN_PEI CryptoPei 248992 249120 = 0 KB + # IA32 MIN_DXE_MIN_SMM CryptoDxe 636672 829568 288520 401034 = 113 KB + # IA32 MIN_DXE_MIN_SMM CryptoSmm 426048 601472 191517 296022 = 105 KB + # IA32 ALL CryptoPei 423840 598976 189047 293759 = 104 KB + # IA32 ALL CryptoDxe 645280 838144 292955 405277 = 113 KB + # IA32 ALL CryptoSmm 441888 617184 198779 303628 = 105 KB + # X64 NONE CryptoPei 29632 29664 = 0 KB + # X64 NONE CryptoDxe 29792 29792 = 0 KB + # X64 NONE CryptoSmm 31296 31296 = 0 KB + # X64 MIN_PEI CryptoPei 310784 310848 = 0 KB + # X64 MIN_DXE_MIN_SMM CryptoDxe 804288 1016256 311436 426596 = 115 KB + # X64 MIN_DXE_MIN_SMM CryptoSmm 543776 733920 204483 310775 = 106 KB + # X64 ALL CryptoPei 540384 730240 202494 308467 = 106 KB + # X64 ALL CryptoDxe 815392 1027296 316228 431321 = 115 KB + # X64 ALL CryptoSmm 563648 753696 213488 319644 = 106 KB =20 [UserExtensions.TianoCore."ExtraFiles"] CryptoPkgExtra.uni --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94290): https://edk2.groups.io/g/devel/message/94290 Mute This Topic: https://groups.io/mt/93904008/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 16:43:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+94291+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94291+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1664097999; cv=none; d=zohomail.com; s=zohoarc; b=jNp0PtQMOljdLul6NIPaRtxt/jy/O5hBlzwP0VKNK0SLDjBq1nvO4TOqvmahoXLqvKv0Vu0Nt0A9h6nYP3lYXReK1hYtGXS/JaziHScjDUTsnYdtojv30hKFsMGRh3UfLlb/knenyDXCwB+yVq4epN4PtsKJ1+cPHpoVHl5zdkE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1664097999; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=rX4xanSdtvseBGx9d3gnyYb5KeHr52I2lyjzZCjn1JU=; b=l8B9MLwmlEjCswDZAoJ+oHe1i3u/YuI8PDSY6lFv+YVz+sWFsQ4BRiIauIJxv1Ev2jMKOdJUxYUiJO5VPW3RYgXHdLXFdRA2LoNx7w59YY5SWZ6Yhq1aMkrRoBV3oih/BqnvnXJzIeNV7XF/rolKpDHWsjriZ8DuWI5Rn1QZ8Z8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+94291+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1664097999120482.6118410133854; Sun, 25 Sep 2022 02:26:39 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id e2GTYY1788612xXRRigqkeBX; Sun, 25 Sep 2022 02:26:38 -0700 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.15349.1664097995730274692 for ; Sun, 25 Sep 2022 02:26:37 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10480"; a="327184350" X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="327184350" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:37 -0700 X-IronPort-AV: E=Sophos;i="5.93,344,1654585200"; d="scan'208";a="683184432" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2022 02:26:35 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [edk2-devel] [PATCH V5 4/4] CryptoPkg/Test: Add unit test for CryptoEc Date: Sun, 25 Sep 2022 17:26:21 +0800 Message-Id: <15498cc4e39cbb9bdc8447a6a8a04faca892397b.1664097766.git.yi1.li@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yi1.li@intel.com X-Gm-Message-State: jLkx2OOTQKadQpxKskxe9t1gx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1664097998; bh=Dff/8124MH4YIhkvma0bV2WeZ3w3Mp6aP+F4WhfRWRQ=; h=Cc:Date:From:Reply-To:Subject:To; b=smz/TDKhjwsPxb3aifmq88vFDIo5mdak1GLIZ6N7Jzf0/OE8H7DveloagDLxP6l2np8 0cFmbilHQptBfLRcbNRCXkvS4pkPUKKzBeQLhjEdb0DmhlOFdLXdMlbVnErCpK614kdIT UzL+mMztv6nLcSP2Sj/UWlsnu9kcjL/DTfM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1664098000983100018 Content-Type: text/plain; charset="utf-8" Add unit test for CryptoEc. Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li Reviewed-by: Jiewen Yao Tested-by: Yi Li --- .../BaseCryptLib/UnitTestHostBaseCryptLib.inf | 2 + CryptoPkg/Test/CryptoPkgHostUnitTest.dsc | 3 + .../BaseCryptLib/BaseCryptLibUnitTests.c | 1 + .../UnitTest/Library/BaseCryptLib/EcTests.c | 290 ++++++++++++++++++ .../Library/BaseCryptLib/TestBaseCryptLib.h | 2 + .../BaseCryptLib/TestBaseCryptLibHost.inf | 1 + .../BaseCryptLib/TestBaseCryptLibShell.inf | 1 + 7 files changed, 300 insertions(+) create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/EcTests.c diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf b/= CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf index 6891db97fb..168e24e4c0 100644 --- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf @@ -48,6 +48,8 @@ Pk/CryptRsaPss.c Pk/CryptRsaPssSign.c Bn/CryptBn.c + Pk/CryptEcNull.c |*|*|*|!gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnab= led + Pk/CryptEc.c |*|*|*|gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled =20 SysCall/UnitTestHostCrtWrapper.c =20 diff --git a/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc b/CryptoPkg/Test/Cryp= toPkgHostUnitTest.dsc index 16478f4a57..b6e1a66198 100644 --- a/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc +++ b/CryptoPkg/Test/CryptoPkgHostUnitTest.dsc @@ -19,6 +19,9 @@ =20 !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc =20 +[PcdsFixedAtBuild] + gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled|TRUE + [LibraryClasses] OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitT= ests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests= .c index 8450e95172..63bae35b80 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c @@ -28,6 +28,7 @@ SUITE_DESC mSuiteDesc[] =3D { { "Hkdf extract and expand tests", "CryptoPkg.BaseCryptLib", NULL, NULL,= &mHkdfTestNum, mHkdfTest }, { "Aead AES Gcm tests", "CryptoPkg.BaseCryptLib", NULL, NULL,= &mAeadAesGcmTestNum, mAeadAesGcmTest }, { "Bn verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,= &mBnTestNum, mBnTest }, + { "EC verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL,= &mEcTestNum, mEcTest }, }; =20 EFI_STATUS diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/EcTests.c b/Crypt= oPkg/Test/UnitTest/Library/BaseCryptLib/EcTests.c new file mode 100644 index 0000000000..54ce0b22df --- /dev/null +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/EcTests.c @@ -0,0 +1,290 @@ +/** @file + Application for Diffie-Hellman Primitives Validation. + +Copyright (c) 2022, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "TestBaseCryptLib.h" + +#define EC_CURVE_NUM_SUPPORTED 3 +UINTN EcCurveList[EC_CURVE_NUM_SUPPORTED] =3D { CRYPTO_NID_SECP256R1, C= RYPTO_NID_SECP384R1, CRYPTO_NID_SECP521R1 }; +UINTN EcKeyHalfSize[EC_CURVE_NUM_SUPPORTED] =3D { 32, 48, 66 }; + +struct Generator { + UINT8 X[66]; + UINT8 Y[66]; +}; + +// Generator points of all ec curve +struct Generator EcCurveGenerator[EC_CURVE_NUM_SUPPORTED] =3D +{ + // CRYPTO_NID_SECP256R1 + { + { 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0x= E5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0x= A0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 }, + + { 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x= 4a, + 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0x= ce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 } + }, + // CRYPTO_NID_SECP384R1 + { + { 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x= 1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x= 98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x= 5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0x= B7 }, + + { 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0x= bf, + 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x= 7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0x= ce, + 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x= 5f } + }, + // CRYPTO_NID_SECP521R1 + { + { 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x= 3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x= 3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x= 4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0x= FF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x= 7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 }, + + { 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x= 8a, + 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x= 9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0x= ee, + 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0x= ad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0x= be, + 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50 } + } +}; + +VOID *Ec1; +VOID *Ec2; +VOID *Group; +VOID *Point1; +VOID *Point2; +VOID *PointRes; +VOID *BnX; +VOID *BnY; +VOID *BnP; +VOID *BnOrder; + +UNIT_TEST_STATUS +EFIAPI +TestVerifyEcPreReq ( + UNIT_TEST_CONTEXT Context + ) +{ + Ec1 =3D NULL; + Ec2 =3D NULL; + Group =3D NULL; + Point1 =3D NULL; + Point2 =3D NULL; + PointRes =3D NULL; + BnX =3D NULL; + BnY =3D NULL; + BnP =3D BigNumInit (); + BnOrder =3D BigNumInit (); + if ((BnP =3D=3D NULL) || (BnOrder =3D=3D NULL)) { + return UNIT_TEST_ERROR_TEST_FAILED; + } + + return UNIT_TEST_PASSED; +} + +VOID +EFIAPI +TestVerifyEcCleanUp ( + UNIT_TEST_CONTEXT Context + ) +{ + BigNumFree (BnX, TRUE); + BigNumFree (BnY, TRUE); + BigNumFree (BnP, TRUE); + BigNumFree (BnOrder, TRUE); + EcGroupFree (Group); + EcPointDeInit (Point1, TRUE); + EcPointDeInit (Point2, TRUE); + EcPointDeInit (PointRes, TRUE); + EcFree (Ec1); + EcFree (Ec2); +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyEcBasic ( + UNIT_TEST_CONTEXT Context + ) +{ + UINTN CurveCount; + BOOLEAN Status; + + // + // Initialize BigNumbers + // + for (CurveCount =3D 0; CurveCount < EC_CURVE_NUM_SUPPORTED; CurveCount++= ) { + // + // Basic EC functions unit test + // + Group =3D EcGroupInit (EcCurveList[CurveCount]); + if (Group =3D=3D NULL) { + return UNIT_TEST_ERROR_TEST_FAILED; + } + + Point1 =3D EcPointInit (Group); + Point2 =3D EcPointInit (Group); + PointRes =3D EcPointInit (Group); + BnX =3D BigNumFromBin (EcCurveGenerator[CurveCount].X, EcKeyHalfS= ize[CurveCount]); + BnY =3D BigNumFromBin (EcCurveGenerator[CurveCount].Y, EcKeyHalfS= ize[CurveCount]); + if ((Point1 =3D=3D NULL) || (Point2 =3D=3D NULL) || (PointRes =3D=3D N= ULL) || (BnX =3D=3D NULL) || (BnY =3D=3D NULL)) { + return UNIT_TEST_ERROR_TEST_FAILED; + } + + Status =3D EcGroupGetCurve (Group, BnP, NULL, NULL, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcGroupGetOrder (Group, BnOrder); + UT_ASSERT_TRUE (Status); + + // Point G should on curve + Status =3D EcPointSetAffineCoordinates (Group, Point1, BnX, BnY, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointSetAffineCoordinates (Group, Point2, BnX, BnY, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointEqual (Group, Point1, Point2, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointIsOnCurve (Group, Point1, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointIsAtInfinity (Group, Point1); + UT_ASSERT_FALSE (Status); + + // Point 2G should on curve + Status =3D EcPointAdd (Group, PointRes, Point1, Point1, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointIsOnCurve (Group, PointRes, NULL); + UT_ASSERT_TRUE (Status); + + // Point Order * G should at infinity + Status =3D EcPointMul (Group, PointRes, Point1, BnOrder, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointIsAtInfinity (Group, PointRes); + UT_ASSERT_TRUE (Status); + + // -(-G) =3D=3D G + Status =3D EcPointInvert (Group, Point2, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointEqual (Group, Point2, Point1, NULL); + UT_ASSERT_FALSE (Status); + + Status =3D EcPointInvert (Group, Point2, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointEqual (Group, Point2, Point1, NULL); + UT_ASSERT_TRUE (Status); + + // Compress point test + Status =3D EcPointSetCompressedCoordinates (Group, Point1, BnX, 0, NUL= L); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointSetCompressedCoordinates (Group, Point2, BnX, 1, NUL= L); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointEqual (Group, Point2, Point1, NULL); + UT_ASSERT_FALSE (Status); + + Status =3D EcPointInvert (Group, Point2, NULL); + UT_ASSERT_TRUE (Status); + + Status =3D EcPointEqual (Group, Point2, Point1, NULL); + UT_ASSERT_TRUE (Status); + } + + return UNIT_TEST_PASSED; +} + +UNIT_TEST_STATUS +EFIAPI +TestVerifyEcDh ( + UNIT_TEST_CONTEXT Context + ) +{ + UINT8 Public1[66 * 2]; + UINTN Public1Length; + UINT8 Public2[66 * 2]; + UINTN Public2Length; + UINT8 Key1[66]; + UINTN Key1Length; + UINT8 Key2[66]; + UINTN Key2Length; + UINTN CurveCount; + BOOLEAN Status; + + for (CurveCount =3D 0; CurveCount < EC_CURVE_NUM_SUPPORTED; CurveCount++= ) { + // + // Initial key length + // + Public1Length =3D sizeof (Public1); + Public2Length =3D sizeof (Public2); + Key1Length =3D sizeof (Key1); + Key2Length =3D sizeof (Key2); + // + // ECDH functions unit test + // + Ec1 =3D EcNewByNid (EcCurveList[CurveCount]); + if (Ec1 =3D=3D NULL) { + return UNIT_TEST_ERROR_TEST_FAILED; + } + + Ec2 =3D EcNewByNid (EcCurveList[CurveCount]); + if (Ec2 =3D=3D NULL) { + return UNIT_TEST_ERROR_TEST_FAILED; + } + + Status =3D EcGenerateKey (Ec1, Public1, &Public1Length); + UT_ASSERT_TRUE (Status); + UT_ASSERT_EQUAL (Public1Length, EcKeyHalfSize[CurveCount] * 2); + + Status =3D EcGenerateKey (Ec2, Public2, &Public2Length); + UT_ASSERT_TRUE (Status); + UT_ASSERT_EQUAL (Public2Length, EcKeyHalfSize[CurveCount] * 2); + + Status =3D EcDhComputeKey (Ec1, Public2, Public2Length, NULL, Key1, &K= ey1Length); + UT_ASSERT_TRUE (Status); + UT_ASSERT_EQUAL (Key1Length, EcKeyHalfSize[CurveCount]); + + Status =3D EcDhComputeKey (Ec2, Public1, Public1Length, NULL, Key2, &K= ey2Length); + UT_ASSERT_TRUE (Status); + UT_ASSERT_EQUAL (Key2Length, EcKeyHalfSize[CurveCount]); + + UT_ASSERT_EQUAL (Key1Length, Key2Length); + UT_ASSERT_MEM_EQUAL (Key1, Key2, Key1Length); + + Status =3D EcGetPubKey (Ec1, Public2, &Public2Length); + UT_ASSERT_TRUE (Status); + UT_ASSERT_EQUAL (Public2Length, EcKeyHalfSize[CurveCount] * 2); + + UT_ASSERT_EQUAL (Public1Length, Public2Length); + UT_ASSERT_MEM_EQUAL (Public1, Public2, Public1Length); + } + + return UNIT_TEST_PASSED; +} + +TEST_DESC mEcTest[] =3D { + // + // -----Description-----------------Class------------------Function----P= re----Post----Context + // + { "TestVerifyEcBasic()", "CryptoPkg.BaseCryptLib.Ec", TestVerifyEcBasic,= TestVerifyEcPreReq, TestVerifyEcCleanUp, NULL }, + { "TestVerifyEcDh()", "CryptoPkg.BaseCryptLib.Ec", TestVerifyEcDh, = TestVerifyEcPreReq, TestVerifyEcCleanUp, NULL }, +}; + +UINTN mEcTestNum =3D ARRAY_SIZE (mEcTest); diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.= h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h index fc44030ff6..3a84e63a87 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h @@ -95,6 +95,8 @@ extern TEST_DESC mAeadAesGcmTest[]; extern UINTN mBnTestNum; extern TEST_DESC mBnTest[]; =20 +extern UINTN mEcTestNum; +extern TEST_DESC mEcTest[]; /** Creates a framework you can use */ EFI_STATUS EFIAPI diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibH= ost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost= .inf index 40dfade717..023b796946 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf @@ -40,6 +40,7 @@ HkdfTests.c AeadAesGcmTests.c BnTests.c + EcTests.c =20 [Packages] MdePkg/MdePkg.dec diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibS= hell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShe= ll.inf index 00e6b088b8..5bfd190236 100644 --- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf +++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf @@ -39,6 +39,7 @@ HkdfTests.c AeadAesGcmTests.c BnTests.c + EcTests.c =20 [Packages] MdePkg/MdePkg.dec --=20 2.31.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#94291): https://edk2.groups.io/g/devel/message/94291 Mute This Topic: https://groups.io/mt/93904010/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-