From nobody Sun Feb 8 16:05:56 2026 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+94277+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+94277+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1664077149; cv=none; d=zohomail.com; s=zohoarc; b=FtmivvBysApWyEfcvmaxId0lx/Fo+f1cWM2EXsfnsedHtPxLOyrgXqloyqIwj7/E6RDnvB5fUkx/iVhXW6oc78k4a8851C+rVh+RatUULm1+sFw66yAIYHdpd9oSfsKtVj3z8NMaKh+j9ywJIE1WkfBNkmjz3xxuDYCzmNaUNHk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1664077149; 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=Ih0LqC7szkn0Z2aCA/jaUso+c8AbefMfZmwOz2wIHl0=; b=K2aA7ubx3kSLUaynzi7VWSXi1l63WdLOlUTAd/MTE1u9N8W6dabwCRCZzQXxavTY6aELcvVWJFbTkafOCizOF69VPmrfxPUGuEqePctghDJi2u/PxwHmvjDg4zdIPiYllLLmdqEvjqeNZIJ0Kgb6jvosyn70thEXSxkIuWf66GA= 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+94277+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 1664077149011515.2501481511416; Sat, 24 Sep 2022 20:39:09 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id zVztYY1788612xoRPsIBhplr; Sat, 24 Sep 2022 20:39:08 -0700 X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web09.14167.1664077144999759383 for ; Sat, 24 Sep 2022 20:39:07 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10480"; a="364859436" X-IronPort-AV: E=Sophos;i="5.93,343,1654585200"; d="scan'208";a="364859436" X-Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2022 20:39:06 -0700 X-IronPort-AV: E=Sophos;i="5.93,343,1654585200"; d="scan'208";a="689158104" X-Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2022 20:39:05 -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 V4 1/4] CryptoPkg: Add EC support Date: Sun, 25 Sep 2022 11:38:46 +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: Sp9h2cvrBPXCYTwgCTxFqOqqx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1664077148; bh=yfvgKwv2KKEKlT3/0uwFSfelkQtlJhYZsaxMx4/XR98=; h=Cc:Date:From:Reply-To:Subject:To; b=asNk4GYMTUU3Vn/pvnlfVGhi+i72s5fnxcfrnwIx0hU6w9Wu2R3URbyCEOwAT6rBJlq CP8BUfHvJ2u5f4gJ3r9769Dr1KkVI7fh7LVI76SHBr9tJj5tdjiQWeK468/JWGok/ll1N uLdzJUlhytcnofjBL0kDbsFXw94mYDgA1nU= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1664077150631100006 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 --- 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 (#94277): https://edk2.groups.io/g/devel/message/94277 Mute This Topic: https://groups.io/mt/93901844/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-