From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web10.14911.1679043720870874677 for ; Fri, 17 Mar 2023 02:02:10 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=iqrm4M01; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: wenxing.hou@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679043729; x=1710579729; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ug3WfY4xAMIesPhl63zw28l1RtxSoYJl+N09u3JcqGw=; b=iqrm4M01336w4mAk61gfv1kGCrCJHvSZIJsGpjnonJJfDR3hI+mlViPR +1mAGZZBkyPpFEE47MEc8CpLfW5LfGYFXoTajdYrAVfTkoVLFJdNJzrv8 e9S7Gas9t8oCy456Lj4JW0bS1iQhmnp1KnRB5rr49LBsatP9cJE0+Vh+u 9wRZgScoiKp+HjdhJ/cj4vvmACc1g543mpUfVoutXx4vmE0etwNGTpPSJ c62WLXPPQUZ3Qlju5psVCP9sVKCanAl7RM0hUjNwwKpxlf/d/9bl3VAFe Ficxz3pYouOGtKkPHyWMLVCsILjv6/95aFZmf0s4TjGhLuTQwPTONhhse Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10651"; a="317871159" X-IronPort-AV: E=Sophos;i="5.98,268,1673942400"; d="scan'208";a="317871159" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2023 02:02:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10651"; a="926066882" X-IronPort-AV: E=Sophos;i="5.98,268,1673942400"; d="scan'208";a="926066882" Received: from shwdejointd777.ccr.corp.intel.com ([10.239.157.39]) by fmsmga006.fm.intel.com with ESMTP; 17 Mar 2023 02:02:08 -0700 From: "Wenxing Hou" To: devel@edk2.groups.io Cc: Wenxing Hou Subject: [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC api based on MbedTlsLib for CryptoPkg Date: Fri, 17 Mar 2023 17:00:51 +0800 Message-Id: <20230317090053.1895-6-wenxing.hou@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 In-Reply-To: <20230317090053.1895-1-wenxing.hou@intel.com> References: <20230317090053.1895-1-wenxing.hou@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Signed-off-by: Wenxing Hou --- .../Library/BaseCryptLibMbedTls/Pk/CryptEc.c | 634 +++++++++++++++++- 1 file changed, 621 insertions(+), 13 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c b/CryptoPkg= /Library/BaseCryptLibMbedTls/Pk/CryptEc.c index 88684c9fa2..36bc294c20 100644 --- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptEc.c @@ -15,6 +15,532 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D =0D +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +// Basic Elliptic Curve Primitives=0D +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +=0D +/**=0D + Return the Nid of certain ECC curve.=0D +=0D + @param[in] CryptoNid Identifying number for the ECC curve (Defined in= =0D + BaseCryptLib.h).=0D +=0D + @retval !=3D-1 On success.=0D + @retval -1 ECC curve not supported.=0D +**/=0D +STATIC=0D +INT32=0D +CryptoNidToMbedtlsNid (=0D + IN UINTN CryptoNid=0D + )=0D +{=0D + INT32 Nid;=0D +=0D + switch (CryptoNid) {=0D + case CRYPTO_NID_SECP256R1:=0D + Nid =3D MBEDTLS_ECP_DP_SECP256R1;=0D + break;=0D + case CRYPTO_NID_SECP384R1:=0D + Nid =3D MBEDTLS_ECP_DP_SECP384R1;=0D + break;=0D + case CRYPTO_NID_SECP521R1:=0D + Nid =3D MBEDTLS_ECP_DP_SECP521R1;=0D + break;=0D + default:=0D + return -1;=0D + }=0D +=0D + return Nid;=0D +}=0D +=0D +/**=0D + Initialize new opaque EcGroup object. This object represents an EC curve= and=0D + and is used for calculation within this group. This object should be fre= ed=0D + using EcGroupFree() function.=0D +=0D + @param[in] CryptoNid Identifying number for the ECC curve (Defined in= =0D + BaseCryptLib.h).=0D +=0D + @retval EcGroup object On success.=0D + @retval NULL On failure.=0D +**/=0D +VOID *=0D +EFIAPI=0D +EcGroupInit (=0D + IN UINTN CryptoNid=0D + )=0D +{=0D + INT32 Nid;=0D + mbedtls_ecp_group *grp;=0D +=0D + Nid =3D CryptoNidToMbedtlsNid (CryptoNid);=0D +=0D + if (Nid < 0) {=0D + return NULL;=0D + }=0D +=0D + grp =3D AllocateZeroPool (sizeof(mbedtls_ecp_group));=0D + if (grp =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + mbedtls_ecp_group_init(grp);=0D +=0D + mbedtls_ecp_group_load(grp, Nid);=0D +=0D + return grp;=0D +}=0D +=0D +/**=0D + Get EC curve parameters. While elliptic curve equation is Y^2 mod P =3D = (X^3 + AX + B) Mod P.=0D + This function will set the provided Big Number objects to the correspon= ding=0D + values. The caller needs to make sure all the "out" BigNumber parameters= =0D + are properly initialized.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[out] BnPrime Group prime number.=0D + @param[out] BnA A coefficient.=0D + @param[out] BnB B coefficient..=0D + @param[in] BnCtx BN context.=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcGroupGetCurve (=0D + IN CONST VOID *EcGroup,=0D + OUT VOID *BnPrime,=0D + OUT VOID *BnA,=0D + OUT VOID *BnB,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + mbedtls_ecp_group *grp;=0D +=0D + grp =3D ( mbedtls_ecp_group *)EcGroup;=0D +=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnPrime, &grp->P) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (BnA !=3D NULL) {=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnA, &grp->A) !=3D 0) {=0D + return FALSE;=0D + }=0D + }=0D +=0D + if (BnB !=3D NULL) {=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnB, &grp->B) !=3D 0) {=0D + return FALSE;=0D + }=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Get EC group order.=0D + This function will set the provided Big Number object to the correspondi= ng=0D + value. The caller needs to make sure that the "out" BigNumber parameter= =0D + is properly initialized.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[out] BnOrder Group prime number.=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcGroupGetOrder (=0D + IN VOID *EcGroup,=0D + OUT VOID *BnOrder=0D + )=0D +{=0D + mbedtls_ecp_group *grp;=0D +=0D + grp =3D ( mbedtls_ecp_group *)EcGroup;=0D +=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnOrder, &grp->N) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Free previously allocated EC group object using EcGroupInit().=0D +=0D + @param[in] EcGroup EC group object to free.=0D +**/=0D +VOID=0D +EFIAPI=0D +EcGroupFree (=0D + IN VOID *EcGroup=0D + )=0D +{=0D + mbedtls_ecp_group_free(EcGroup);=0D +}=0D +=0D +/**=0D + Initialize new opaque EC Point object. This object represents an EC poin= t=0D + within the given EC group (curve).=0D +=0D + @param[in] EC Group, properly initialized using EcGroupInit().=0D +=0D + @retval EC Point object On success.=0D + @retval NULL On failure.=0D +**/=0D +VOID *=0D +EFIAPI=0D +EcPointInit (=0D + IN CONST VOID *EcGroup=0D + )=0D +{=0D + mbedtls_ecp_point *pt;=0D +=0D + pt =3D AllocateZeroPool (sizeof(mbedtls_ecp_point));=0D + if (pt =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + mbedtls_ecp_point_init (pt);=0D +=0D + return pt;=0D +}=0D +=0D +/**=0D + Free previously allocated EC Point object using EcPointInit().=0D +=0D + @param[in] EcPoint EC Point to free.=0D + @param[in] Clear TRUE iff the memory should be cleared.=0D +**/=0D +VOID=0D +EFIAPI=0D +EcPointDeInit (=0D + IN VOID *EcPoint,=0D + IN BOOLEAN Clear=0D + )=0D +{=0D + mbedtls_ecp_point_free(EcPoint);=0D +}=0D +=0D +/**=0D + Get EC point affine (x,y) coordinates.=0D + This function will set the provided Big Number objects to the correspond= ing=0D + values. The caller needs to make sure all the "out" BigNumber parameters= =0D + are properly initialized.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPoint EC point object.=0D + @param[out] BnX X coordinate.=0D + @param[out] BnY Y coordinate.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointGetAffineCoordinates (=0D + IN CONST VOID *EcGroup,=0D + IN CONST VOID *EcPoint,=0D + OUT VOID *BnX,=0D + OUT VOID *BnY,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + mbedtls_ecp_point *pt;=0D +=0D + pt =3D ( mbedtls_ecp_point *)EcPoint;=0D +=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnX, &pt->X) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_mpi_copy((mbedtls_mpi *)BnY, &pt->Y) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Set EC point affine (x,y) coordinates.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPoint EC point object.=0D + @param[in] BnX X coordinate.=0D + @param[in] BnY Y coordinate.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointSetAffineCoordinates (=0D + IN CONST VOID *EcGroup,=0D + IN VOID *EcPoint,=0D + IN CONST VOID *BnX,=0D + IN CONST VOID *BnY,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + mbedtls_ecp_point *pt;=0D +=0D + pt =3D ( mbedtls_ecp_point *)EcPoint;=0D +=0D + if (mbedtls_mpi_copy(&pt->X, (mbedtls_mpi *)BnX) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_mpi_copy(&pt->Y, (mbedtls_mpi *)BnY) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_mpi_lset( &pt->Z , 1);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + EC Point addition. EcPointResult =3D EcPointA + EcPointB.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[out] EcPointResult EC point to hold the result. The point shou= ld=0D + be properly initialized.=0D + @param[in] EcPointA EC Point.=0D + @param[in] EcPointB EC Point.=0D + @param[in] BnCtx BN context, created with BigNumNewContext()= .=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointAdd (=0D + IN CONST VOID *EcGroup,=0D + OUT VOID *EcPointResult,=0D + IN CONST VOID *EcPointA,=0D + IN CONST VOID *EcPointB,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + mbedtls_mpi *m;=0D + mbedtls_mpi *n;=0D +=0D + m =3D AllocateZeroPool(sizeof(mbedtls_mpi));=0D + n =3D AllocateZeroPool(sizeof(mbedtls_mpi));=0D +=0D + if(mbedtls_mpi_lset(m, 1) !=3D 0 ) {=0D + FreePool(m);=0D + FreePool(n);=0D + return FALSE;=0D + }=0D + if(mbedtls_mpi_lset(n, 1) !=3D 0 ) {=0D + FreePool(m);=0D + FreePool(n);=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_ecp_muladd((mbedtls_ecp_group *)EcGroup, (mbedtls_ecp_point = *)EcPointResult, (const mbedtls_mpi *)m,=0D + (const mbedtls_ecp_point *)EcPointA, (const mbedtls_mpi *)n, (const = mbedtls_ecp_point *)EcPointB) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + FreePool(m);=0D + FreePool(n);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Variable EC point multiplication. EcPointResult =3D EcPoint * BnPScalar.= =0D +=0D + @param[in] EcGroup EC group object.=0D + @param[out] EcPointResult EC point to hold the result. The point shou= ld=0D + be properly initialized.=0D + @param[in] EcPoint EC Point.=0D + @param[in] BnPScalar P Scalar.=0D + @param[in] BnCtx BN context, created with BigNumNewContext()= .=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointMul (=0D + IN CONST VOID *EcGroup,=0D + OUT VOID *EcPointResult,=0D + IN CONST VOID *EcPoint,=0D + IN CONST VOID *BnPScalar,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + return (mbedtls_ecp_mul((mbedtls_ecp_group *)EcGroup, EcPointResult, BnP= Scalar, EcPoint, myrand, NULL) =3D=3D 0);=0D +}=0D +=0D +/**=0D + Calculate the inverse of the supplied EC point.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in,out] EcPoint EC point to invert.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointInvert (=0D + IN CONST VOID *EcGroup,=0D + IN OUT VOID *EcPoint,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + mbedtls_ecp_point *pt;=0D + mbedtls_ecp_group *grp;=0D + mbedtls_mpi InvBnY;=0D +=0D + mbedtls_mpi_init(&InvBnY);=0D +=0D + pt =3D ( mbedtls_ecp_point *)EcPoint;=0D + grp =3D ( mbedtls_ecp_group *)EcGroup;=0D +=0D + if (mbedtls_mpi_copy(&InvBnY, &pt->Y) !=3D 0) {=0D + mbedtls_mpi_free(&InvBnY);=0D + return FALSE;=0D + }=0D +=0D + mbedtls_mpi P;=0D +=0D + mbedtls_mpi_init(&P);=0D +=0D + if (mbedtls_mpi_copy(&P, &grp->P) !=3D 0) {=0D + mbedtls_mpi_free(&P);=0D + return FALSE;=0D + }=0D +=0D +=0D + InvBnY.s =3D 0 - InvBnY.s;=0D +=0D + if (mbedtls_mpi_mod_mpi(&InvBnY, &InvBnY, &P) !=3D 0) {=0D + mbedtls_mpi_free(&InvBnY);=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_mpi_copy(&pt->Y, &InvBnY) !=3D 0) {=0D + mbedtls_mpi_free(&InvBnY);=0D + return FALSE;=0D + }=0D +=0D + mbedtls_mpi_free(&InvBnY);=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Check if the supplied point is on EC curve.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPoint EC point to check.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE On curve.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointIsOnCurve (=0D + IN CONST VOID *EcGroup,=0D + IN CONST VOID *EcPoint,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + return (mbedtls_ecp_check_pubkey(EcGroup, EcPoint) =3D=3D 0);=0D +}=0D +=0D +/**=0D + Check if the supplied point is at infinity.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPoint EC point to check.=0D +=0D + @retval TRUE At infinity.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointIsAtInfinity (=0D + IN CONST VOID *EcGroup,=0D + IN CONST VOID *EcPoint=0D + )=0D +{=0D + mbedtls_ecp_point *pt;=0D +=0D + pt =3D ( mbedtls_ecp_point *)EcPoint;=0D +=0D + return (mbedtls_ecp_is_zero(pt) =3D=3D 1);=0D +}=0D +=0D +/**=0D + Check if EC points are equal.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPointA EC point A.=0D + @param[in] EcPointB EC point B.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE A =3D=3D B.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointEqual (=0D + IN CONST VOID *EcGroup,=0D + IN CONST VOID *EcPointA,=0D + IN CONST VOID *EcPointB,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + return mbedtls_ecp_point_cmp (EcPointA, EcPointB) =3D=3D 0;=0D +}=0D +=0D +/**=0D + Set EC point compressed coordinates. Points can be described in terms of= =0D + their compressed coordinates. For a point (x, y), for any given value fo= r x=0D + such that the point is on the curve there will only ever be two possible= =0D + values for y. Therefore, a point can be set using this function where Bn= X is=0D + the x coordinate and YBit is a value 0 or 1 to identify which of the two= =0D + possible values for y should be used.=0D +=0D + @param[in] EcGroup EC group object.=0D + @param[in] EcPoint EC Point.=0D + @param[in] BnX X coordinate.=0D + @param[in] YBit 0 or 1 to identify which Y value is used.=0D + @param[in] BnCtx BN context, created with BigNumNewContext().=0D +=0D + @retval TRUE On success.=0D + @retval FALSE Otherwise.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcPointSetCompressedCoordinates (=0D + IN CONST VOID *EcGroup,=0D + IN VOID *EcPoint,=0D + IN CONST VOID *BnX,=0D + IN UINT8 YBit,=0D + IN VOID *BnCtx=0D + )=0D +{=0D + return FALSE;=0D +}=0D +=0D +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +// Elliptic Curve Diffie Hellman Primitives=0D +// =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +=0D /**=0D Allocates and Initializes one Elliptic Curve Context for subsequent use= =0D with the NID.=0D @@ -220,26 +746,108 @@ EcGetPubKey ( }=0D =0D /**=0D - Validates key components of EC context.=0D - NOTE: This function performs integrity checks on all the EC key material= , so=0D - the EC key structure must contain all the private key data.=0D -=0D + Computes exchanged common key.=0D + Given peer's public key (X, Y), this function computes the exchanged com= mon key,=0D + based on its own context including value of curve parameter and random s= ecret.=0D + X is the first half of PeerPublic with size being PeerPublicSize / 2,=0D + Y is the second half of PeerPublic with size being PeerPublicSize / 2.=0D + If public key is compressed, the PeerPublic will only contain half key (= X).=0D If EcContext is NULL, then return FALSE.=0D -=0D - @param[in] EcContext Pointer to EC context to check.=0D -=0D - @retval TRUE EC key components are valid.=0D - @retval FALSE EC key components are not valid.=0D -=0D + If PeerPublic is NULL, then return FALSE.=0D + If PeerPublicSize is 0, then return FALSE.=0D + If Key is NULL, then return FALSE.=0D + If KeySize is not large enough, then return FALSE.=0D + For P-256, the PeerPublicSize is 64. First 32-byte is X, Second 32-byte = is Y.=0D + For P-384, the PeerPublicSize is 96. First 48-byte is X, Second 48-byte = is Y.=0D + For P-521, the PeerPublicSize is 132. First 66-byte is X, Second 66-byte= is Y.=0D + @param[in, out] EcContext Pointer to the EC context.=0D + @param[in] PeerPublic Pointer to the peer's public X,Y.=0D + @param[in] PeerPublicSize Size of peer's public X,Y in bytes.= =0D + @param[in] CompressFlag Flag of PeerPublic is compressed or = not.=0D + @param[out] Key Pointer to the buffer to receive gen= erated key.=0D + @param[in, out] KeySize On input, the size of Key buffer in = bytes.=0D + On output, the size of data returned= in Key buffer in bytes.=0D + @retval TRUE EC exchanged key generation succeeded.=0D + @retval FALSE EC exchanged key generation failed.=0D + @retval FALSE KeySize is not large enough.=0D **/=0D BOOLEAN=0D EFIAPI=0D -EcCheckKey (=0D - IN VOID *EcContext=0D +EcDhComputeKey (=0D + IN OUT VOID *EcContext,=0D + IN CONST UINT8 *PeerPublic,=0D + IN UINTN PeerPublicSize,=0D + IN CONST INT32 *CompressFlag,=0D + OUT UINT8 *Key,=0D + IN OUT UINTN *KeySize=0D )=0D {=0D - // TBD=0D + UINTN HalfSize;=0D + mbedtls_ecdh_context *EcdCtx;=0D + INT32 Ret;=0D +=0D + if ((EcContext =3D=3D NULL) || (PeerPublic =3D=3D NULL) || (KeySize =3D= =3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + if ((Key =3D=3D NULL) && (*KeySize !=3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + if (PeerPublicSize > INT_MAX) {=0D + return FALSE;=0D + }=0D +=0D + EcdCtx =3D EcContext;=0D + switch (EcdCtx->grp.id) {=0D + case MBEDTLS_ECP_DP_SECP256R1:=0D + HalfSize =3D 32;=0D + break;=0D + case MBEDTLS_ECP_DP_SECP384R1:=0D + HalfSize =3D 48;=0D + break;=0D + case MBEDTLS_ECP_DP_SECP521R1:=0D + HalfSize =3D 66;=0D + break;=0D + default:=0D + return FALSE;=0D + }=0D + if (PeerPublicSize !=3D HalfSize * 2) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_mpi_read_binary(&EcdCtx->Qp.X, PeerPublic, HalfSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D + Ret =3D mbedtls_mpi_read_binary(&EcdCtx->Qp.Y, PeerPublic + HalfSize,=0D + HalfSize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D + Ret =3D mbedtls_mpi_lset(&EcdCtx->Qp.Z, 1);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_ecdh_compute_shared(&EcdCtx->grp, &EcdCtx->z, &EcdCtx->Q= p, &EcdCtx->d,=0D + myrand, NULL);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_mpi_size(&EcdCtx->z) > *KeySize) {=0D + return FALSE;=0D + }=0D +=0D + *KeySize =3D EcdCtx->grp.pbits / 8 + ((EcdCtx->grp.pbits % 8) !=3D 0);=0D + Ret =3D mbedtls_mpi_write_binary(&EcdCtx->z, Key, *KeySize);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D return TRUE;=0D +=0D }=0D =0D /**=0D --=20 2.26.2.windows.1