mirror of
https://github.com/stefanberger/libtpms
synced 2026-01-07 02:26:50 +00:00
rev180: Sync ECC and dependencies with upstream
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
67820395b9
commit
3e0cf3eb45
@ -197,6 +197,7 @@ libtpms_tpm2_la_SOURCES = \
|
||||
tpm2/Attest_spt.c \
|
||||
tpm2/AuditCommands.c \
|
||||
tpm2/Bits.c \
|
||||
tpm2/BnEccConstants.c \
|
||||
tpm2/BnConvert.c \
|
||||
tpm2/BnMath.c \
|
||||
tpm2/BnMemory.c \
|
||||
@ -275,6 +276,8 @@ libtpms_tpm2_la_SOURCES = \
|
||||
tpm2/TpmEcc_Signature_Schnorr.c \
|
||||
tpm2/TpmEcc_Signature_SM2.c \
|
||||
tpm2/TpmEcc_Signature_Util.c \
|
||||
tpm2/TpmEcc_Util.c \
|
||||
tpm2/TpmMath_Debug.c \
|
||||
tpm2/TpmMath_Util.c \
|
||||
tpm2/TpmSizeChecks.c \
|
||||
tpm2/TPMCmdp.c \
|
||||
@ -329,6 +332,7 @@ noinst_HEADERS += \
|
||||
tpm2/Attest_spt_fp.h \
|
||||
tpm2/BaseTypes.h \
|
||||
tpm2/Bits_fp.h \
|
||||
tpm2/BnEccConstants.c \
|
||||
tpm2/BnSupport_Interface.h \
|
||||
tpm2/BnUtil_fp.h \
|
||||
tpm2/Capabilities.h \
|
||||
@ -363,6 +367,7 @@ noinst_HEADERS += \
|
||||
tpm2/DictionaryAttackLockReset_fp.h \
|
||||
tpm2/DictionaryAttackParameters_fp.h \
|
||||
tpm2/Duplicate_fp.h \
|
||||
tpm2/EccConstantData.inl \
|
||||
tpm2/EccTestData.h \
|
||||
tpm2/ECC_Parameters_fp.h \
|
||||
tpm2/ECDH_KeyGen_fp.h \
|
||||
@ -521,6 +526,7 @@ noinst_HEADERS += \
|
||||
tpm2/TpmEcc_Signature_SM2_fp.h \
|
||||
tpm2/TpmEcc_Signature_Util_fp.h \
|
||||
tpm2/TpmFail_fp.h \
|
||||
tpm2/TpmMath_Debug_fp.h \
|
||||
tpm2/TpmMath_Util_fp.h \
|
||||
tpm2/TpmProfile.h \
|
||||
tpm2/TpmProfile_CommandList.h \
|
||||
@ -536,6 +542,7 @@ noinst_HEADERS += \
|
||||
tpm2/_TPM_Hash_Start_fp.h \
|
||||
tpm2/_TPM_Init_fp.h \
|
||||
tpm2/TpmCalculatedAttributes.h \
|
||||
tpm2/TpmEcc_Util_fp.h \
|
||||
tpm2/TpmSizeChecks_fp.h \
|
||||
tpm2/TpmTcpProtocol.h \
|
||||
tpm2/TpmTypes.h \
|
||||
@ -582,6 +589,7 @@ libtpms_tpm2_la_SOURCES += \
|
||||
tpm2/crypto/openssl/TpmToOsslSupport.c
|
||||
|
||||
noinst_HEADERS += \
|
||||
tpm2/crypto/openssl/BnToOsslMath_fp.h \
|
||||
tpm2/crypto/openssl/BnToOsslMath.h \
|
||||
tpm2/crypto/openssl/ConsttimeUtils.h \
|
||||
tpm2/crypto/openssl/BnConvert_fp.h \
|
||||
@ -594,7 +602,6 @@ noinst_HEADERS += \
|
||||
tpm2/crypto/openssl/TpmToTpmBigNumMath.h \
|
||||
tpm2/crypto/openssl/TpmToOsslDesSupport_fp.h \
|
||||
tpm2/crypto/openssl/TpmToOsslHash.h \
|
||||
tpm2/crypto/openssl/TpmToOsslMath_fp.h \
|
||||
tpm2/crypto/openssl/TpmToOsslSupport_fp.h \
|
||||
tpm2/crypto/openssl/TpmToOsslSym.h \
|
||||
tpm2/crypto/openssl/tpm_radix.h
|
||||
|
||||
@ -129,51 +129,6 @@ LIB_EXPORT bigNum BnFrom2B(bigNum bn, // OUT:
|
||||
BnSetTop(bn, 0); // Function accepts NULL
|
||||
return NULL;
|
||||
}
|
||||
/* 10.2.2.3.3 BnFromHex() */
|
||||
/* Convert a hex string into a bigNum. This is primarily used in debugging. */
|
||||
#ifdef _SM2_SIGN_DEBUG // libtpms added
|
||||
LIB_EXPORT bigNum
|
||||
BnFromHex(
|
||||
bigNum bn, // OUT:
|
||||
const char *hex // IN:
|
||||
)
|
||||
{
|
||||
#define FromHex(a) ((a) - (((a) > 'a') ? ('a' + 10) \
|
||||
: ((a) > 'A') ? ('A' - 10) : '0'))
|
||||
unsigned i;
|
||||
unsigned wordCount;
|
||||
const char *p;
|
||||
BYTE *d = (BYTE *)&(bn->d[0]);
|
||||
//
|
||||
pAssert(bn && hex);
|
||||
i = (unsigned)strlen(hex);
|
||||
wordCount = BYTES_TO_CRYPT_WORDS((i + 1) / 2);
|
||||
if((i == 0) || (wordCount >= BnGetAllocated(bn)))
|
||||
BnSetWord(bn, 0);
|
||||
else
|
||||
{
|
||||
bn->d[wordCount - 1] = 0;
|
||||
p = hex + i - 1;
|
||||
for(;i > 1; i -= 2)
|
||||
{
|
||||
BYTE a;
|
||||
a = FromHex(*p);
|
||||
p--;
|
||||
*d++ = a + (FromHex(*p) << 4);
|
||||
p--;
|
||||
}
|
||||
if(i == 1)
|
||||
*d = FromHex(*p);
|
||||
}
|
||||
#if !BIG_ENDIAN_TPM
|
||||
for(i = 0; i < wordCount; i++)
|
||||
bn->d[i] = SWAP_CRYPT_WORD(bn->d[i]);
|
||||
#endif // BIG_ENDIAN_TPM
|
||||
BnSetTop(bn, wordCount);
|
||||
return bn;
|
||||
}
|
||||
#endif // libtpms added
|
||||
|
||||
|
||||
//*** BnToBytes()
|
||||
// This function converts a BIG_NUM to a byte array. It converts the bigNum to a
|
||||
@ -263,49 +218,48 @@ LIB_EXPORT BOOL BnTo2B(bigConst bn, // IN:
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
/* 10.2.2.3.6 BnPointFrom2B() */
|
||||
/* Function to create a BIG_POINT structure from a 2B point. A point is going to be two ECC values
|
||||
in the same buffer. The values are going to be the size of the modulus. They are in modular
|
||||
form. */
|
||||
LIB_EXPORT bn_point_t *
|
||||
BnPointFrom2B(
|
||||
bigPoint ecP, // OUT: the preallocated point structure
|
||||
TPMS_ECC_POINT *p // IN: the number to convert
|
||||
)
|
||||
//*** BnPointFromBytes()
|
||||
// Function to create a BIG_POINT structure from a byte buffer in big-endian order.
|
||||
// A point is going to be two ECC values in the same buffer. The values are going
|
||||
// to be the size of the modulus. They are in modular form.
|
||||
LIB_EXPORT bn_point_t* BnPointFromBytes(
|
||||
bigPoint ecP, // OUT: the preallocated point structure
|
||||
const BYTE* x,
|
||||
NUMBYTES nBytesX,
|
||||
const BYTE* y,
|
||||
NUMBYTES nBytesY)
|
||||
{
|
||||
if(p == NULL)
|
||||
if(x == NULL || y == NULL)
|
||||
return NULL;
|
||||
|
||||
if(NULL != ecP)
|
||||
{
|
||||
BnFrom2B(ecP->x, &p->x.b);
|
||||
BnFrom2B(ecP->y, &p->y.b);
|
||||
BnFromBytes(ecP->x, x, nBytesX);
|
||||
BnFromBytes(ecP->y, y, nBytesY);
|
||||
BnSetWord(ecP->z, 1);
|
||||
}
|
||||
return ecP;
|
||||
}
|
||||
|
||||
/* 10.2.2.3.7 BnPointTo2B() */
|
||||
/* This function converts a BIG_POINT into a TPMS_ECC_POINT. A TPMS_ECC_POINT contains two
|
||||
TPM2B_ECC_PARAMETER values. The maximum size of the parameters is dependent on the maximum EC key
|
||||
size used in an implementation. The presumption is that the TPMS_ECC_POINT is large enough to
|
||||
hold 2 TPM2B values, each as large as a MAX_ECC_PARAMETER_BYTES */
|
||||
LIB_EXPORT BOOL
|
||||
BnPointTo2B(
|
||||
TPMS_ECC_POINT *p, // OUT: the converted 2B structure
|
||||
bigPoint ecP, // IN: the values to be converted
|
||||
bigCurve E // IN: curve descriptor for the point
|
||||
)
|
||||
//*** BnPointToBytes()
|
||||
// This function extracts coordinates from a BIG_POINT into
|
||||
// most-significant-byte-first memory buffers (the native format of
|
||||
// a TPMS_ECC_POINT.)
|
||||
// on input the NUMBYTES* parameters indicate the maximum buffer size.
|
||||
// on output, they represent the amount of significant data in that buffer.
|
||||
LIB_EXPORT BOOL BnPointToBytes(
|
||||
pointConst ecP, // OUT: the preallocated point structure
|
||||
BYTE* x,
|
||||
NUMBYTES* pBytesX,
|
||||
BYTE* y,
|
||||
NUMBYTES* pBytesY)
|
||||
{
|
||||
UINT16 size;
|
||||
//
|
||||
pAssert(p && ecP && E);
|
||||
pAssert(ecP && x && y && pBytesX && pBytesY);
|
||||
pAssert(BnEqualWord(ecP->z, 1));
|
||||
// BnMsb is the bit number of the MSB. This is one less than the number of bits
|
||||
size = (UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(AccessCurveData(E))));
|
||||
BnTo2B(ecP->x, &p->x.b, size);
|
||||
BnTo2B(ecP->y, &p->y.b, size);
|
||||
return TRUE;
|
||||
BOOL result = BnToBytes(ecP->x, x, pBytesX);
|
||||
result = result && BnToBytes(ecP->y, y, pBytesY);
|
||||
// TODO: zeroize on error?
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // ALG_ECC
|
||||
|
||||
250
src/tpm2/BnEccConstants.c
Normal file
250
src/tpm2/BnEccConstants.c
Normal file
@ -0,0 +1,250 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/*(Auto-generated)
|
||||
* Created by TpmStructures; Version 4.4 Mar 26, 2019
|
||||
* Date: Aug 30, 2019 Time: 02:11:52PM
|
||||
*/
|
||||
#include "TpmBigNum.h"
|
||||
//#include "Tpm.h"
|
||||
// TODO_RENAME_INC_FOLDER:private refers to the TPM_CoreLib private headers
|
||||
#include "OIDs.h"
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
// define macros expected by EccConstantData to convert the data to BigNum format
|
||||
|
||||
# define TO_ECC_64 TO_CRYPT_WORD_64
|
||||
# define TO_ECC_56(a, b, c, d, e, f, g) TO_ECC_64(0, a, b, c, d, e, f, g)
|
||||
# define TO_ECC_48(a, b, c, d, e, f) TO_ECC_64(0, 0, a, b, c, d, e, f)
|
||||
# define TO_ECC_40(a, b, c, d, e) TO_ECC_64(0, 0, 0, a, b, c, d, e)
|
||||
# if RADIX_BITS > 32
|
||||
# define TO_ECC_32(a, b, c, d) TO_ECC_64(0, 0, 0, 0, a, b, c, d)
|
||||
# define TO_ECC_24(a, b, c) TO_ECC_64(0, 0, 0, 0, 0, a, b, c)
|
||||
# define TO_ECC_16(a, b) TO_ECC_64(0, 0, 0, 0, 0, 0, a, b)
|
||||
# define TO_ECC_8(a) TO_ECC_64(0, 0, 0, 0, 0, 0, 0, a)
|
||||
# else // RADIX_BITS == 32
|
||||
# define TO_ECC_32 BIG_ENDIAN_BYTES_TO_UINT32
|
||||
# define TO_ECC_24(a, b, c) TO_ECC_32(0, a, b, c)
|
||||
# define TO_ECC_16(a, b) TO_ECC_32(0, 0, a, b)
|
||||
# define TO_ECC_8(a) TO_ECC_32(0, 0, 0, a)
|
||||
# endif
|
||||
# define TO_ECC_192(a, b, c) c, b, a
|
||||
# define TO_ECC_224(a, b, c, d) d, c, b, a
|
||||
# define TO_ECC_256(a, b, c, d) d, c, b, a
|
||||
# define TO_ECC_384(a, b, c, d, e, f) f, e, d, c, b, a
|
||||
# define TO_ECC_528(a, b, c, d, e, f, g, h, i) i, h, g, f, e, d, c, b, a
|
||||
# define TO_ECC_640(a, b, c, d, e, f, g, h, i, j) j, i, h, g, f, e, d, c, b, a
|
||||
|
||||
# define BN_MIN_ALLOC(bytes) \
|
||||
(BYTES_TO_CRYPT_WORDS(bytes) == 0) ? 1 : BYTES_TO_CRYPT_WORDS(bytes)
|
||||
# define ECC_CONST(NAME, bytes, initializer) \
|
||||
const struct \
|
||||
{ \
|
||||
crypt_uword_t allocate, size, d[BN_MIN_ALLOC(bytes)]; \
|
||||
} NAME = {BN_MIN_ALLOC(bytes), BYTES_TO_CRYPT_WORDS(bytes), {initializer}}
|
||||
|
||||
// This file contains the raw data for ECC curve constants. The data is wrapped
|
||||
// in macros so this file can be included in other files that format the data in
|
||||
// a memory format desired by the user. This file itself is never used alone.
|
||||
# include "EccConstantData.inl"
|
||||
|
||||
// now define the TPMBN_ECC_CURVE_CONSTANTS objects for the known curves
|
||||
|
||||
# if ECC_NIST_P192
|
||||
const TPMBN_ECC_CURVE_CONSTANTS NIST_P192 = {TPM_ECC_NIST_P192,
|
||||
(bigNum)&NIST_P192_p,
|
||||
(bigNum)&NIST_P192_n,
|
||||
(bigNum)&NIST_P192_h,
|
||||
(bigNum)&NIST_P192_a,
|
||||
(bigNum)&NIST_P192_b,
|
||||
{(bigNum)&NIST_P192_gX,
|
||||
(bigNum)&NIST_P192_gY,
|
||||
(bigNum)&NIST_P192_gZ}};
|
||||
# endif // ECC_NIST_P192
|
||||
|
||||
# if ECC_NIST_P224
|
||||
const TPMBN_ECC_CURVE_CONSTANTS NIST_P224 = {TPM_ECC_NIST_P224,
|
||||
(bigNum)&NIST_P224_p,
|
||||
(bigNum)&NIST_P224_n,
|
||||
(bigNum)&NIST_P224_h,
|
||||
(bigNum)&NIST_P224_a,
|
||||
(bigNum)&NIST_P224_b,
|
||||
{(bigNum)&NIST_P224_gX,
|
||||
(bigNum)&NIST_P224_gY,
|
||||
(bigNum)&NIST_P224_gZ}};
|
||||
# endif // ECC_NIST_P224
|
||||
|
||||
# if ECC_NIST_P256
|
||||
const TPMBN_ECC_CURVE_CONSTANTS NIST_P256 = {TPM_ECC_NIST_P256,
|
||||
(bigNum)&NIST_P256_p,
|
||||
(bigNum)&NIST_P256_n,
|
||||
(bigNum)&NIST_P256_h,
|
||||
(bigNum)&NIST_P256_a,
|
||||
(bigNum)&NIST_P256_b,
|
||||
{(bigNum)&NIST_P256_gX,
|
||||
(bigNum)&NIST_P256_gY,
|
||||
(bigNum)&NIST_P256_gZ}};
|
||||
# endif // ECC_NIST_P256
|
||||
|
||||
# if ECC_NIST_P384
|
||||
const TPMBN_ECC_CURVE_CONSTANTS NIST_P384 = {TPM_ECC_NIST_P384,
|
||||
(bigNum)&NIST_P384_p,
|
||||
(bigNum)&NIST_P384_n,
|
||||
(bigNum)&NIST_P384_h,
|
||||
(bigNum)&NIST_P384_a,
|
||||
(bigNum)&NIST_P384_b,
|
||||
{(bigNum)&NIST_P384_gX,
|
||||
(bigNum)&NIST_P384_gY,
|
||||
(bigNum)&NIST_P384_gZ}};
|
||||
# endif // ECC_NIST_P384
|
||||
|
||||
# if ECC_NIST_P521
|
||||
const TPMBN_ECC_CURVE_CONSTANTS NIST_P521 = {TPM_ECC_NIST_P521,
|
||||
(bigNum)&NIST_P521_p,
|
||||
(bigNum)&NIST_P521_n,
|
||||
(bigNum)&NIST_P521_h,
|
||||
(bigNum)&NIST_P521_a,
|
||||
(bigNum)&NIST_P521_b,
|
||||
{(bigNum)&NIST_P521_gX,
|
||||
(bigNum)&NIST_P521_gY,
|
||||
(bigNum)&NIST_P521_gZ}};
|
||||
# endif // ECC_NIST_P521
|
||||
|
||||
# if ECC_BN_P256
|
||||
const TPMBN_ECC_CURVE_CONSTANTS BN_P256 = {TPM_ECC_BN_P256,
|
||||
(bigNum)&BN_P256_p,
|
||||
(bigNum)&BN_P256_n,
|
||||
(bigNum)&BN_P256_h,
|
||||
(bigNum)&BN_P256_a,
|
||||
(bigNum)&BN_P256_b,
|
||||
{(bigNum)&BN_P256_gX,
|
||||
(bigNum)&BN_P256_gY,
|
||||
(bigNum)&BN_P256_gZ}};
|
||||
# endif // ECC_BN_P256
|
||||
|
||||
# if ECC_BN_P638
|
||||
const TPMBN_ECC_CURVE_CONSTANTS BN_P638 = {TPM_ECC_BN_P638,
|
||||
(bigNum)&BN_P638_p,
|
||||
(bigNum)&BN_P638_n,
|
||||
(bigNum)&BN_P638_h,
|
||||
(bigNum)&BN_P638_a,
|
||||
(bigNum)&BN_P638_b,
|
||||
{(bigNum)&BN_P638_gX,
|
||||
(bigNum)&BN_P638_gY,
|
||||
(bigNum)&BN_P638_gZ}};
|
||||
# endif // ECC_BN_P638
|
||||
|
||||
# if ECC_SM2_P256
|
||||
const TPMBN_ECC_CURVE_CONSTANTS SM2_P256 = {TPM_ECC_SM2_P256,
|
||||
(bigNum)&SM2_P256_p,
|
||||
(bigNum)&SM2_P256_n,
|
||||
(bigNum)&SM2_P256_h,
|
||||
(bigNum)&SM2_P256_a,
|
||||
(bigNum)&SM2_P256_b,
|
||||
{(bigNum)&SM2_P256_gX,
|
||||
(bigNum)&SM2_P256_gY,
|
||||
(bigNum)&SM2_P256_gZ}};
|
||||
# endif // ECC_SM2_P256
|
||||
|
||||
# define comma
|
||||
const TPMBN_ECC_CURVE_CONSTANTS* bnEccCurveData[] = {
|
||||
# if ECC_NIST_P192
|
||||
&NIST_P192,
|
||||
# endif
|
||||
# if ECC_NIST_P224
|
||||
&NIST_P224,
|
||||
# endif
|
||||
# if ECC_NIST_P256
|
||||
&NIST_P256,
|
||||
# endif
|
||||
# if ECC_NIST_P384
|
||||
&NIST_P384,
|
||||
# endif
|
||||
# if ECC_NIST_P521
|
||||
&NIST_P521,
|
||||
# endif
|
||||
# if ECC_BN_P256
|
||||
&BN_P256,
|
||||
# endif
|
||||
# if ECC_BN_P638
|
||||
&BN_P638,
|
||||
# endif
|
||||
# if ECC_SM2_P256
|
||||
&SM2_P256,
|
||||
# endif
|
||||
};
|
||||
|
||||
MUST_BE((sizeof(bnEccCurveData) / sizeof(bnEccCurveData[0])) == (ECC_CURVE_COUNT));
|
||||
|
||||
//*** BnGetCurveData()
|
||||
// This function returns the pointer for the constant parameter data
|
||||
// associated with a curve.
|
||||
const TPMBN_ECC_CURVE_CONSTANTS* BnGetCurveData(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
for(int i = 0; i < ECC_CURVE_COUNT; i++)
|
||||
{
|
||||
if(bnEccCurveData[i]->curveId == curveId)
|
||||
return bnEccCurveData[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // TPM_ALG_ECC
|
||||
@ -507,6 +507,41 @@ LIB_EXPORT BOOL BnShiftRight(bigNum result, bigConst toShift, uint32_t shiftAmou
|
||||
BnSetTop(result, finalSize);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//*** BnIsPointOnCurve()
|
||||
// This function checks if a point is on the curve.
|
||||
BOOL BnIsPointOnCurve(pointConst Q, const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
BN_VAR(right, (MAX_ECC_KEY_BITS * 3));
|
||||
BN_VAR(left, (MAX_ECC_KEY_BITS * 2));
|
||||
bigConst prime = BnCurveGetPrime(C);
|
||||
//
|
||||
// Show that point is on the curve y^2 = x^3 + ax + b;
|
||||
// Or y^2 = x(x^2 + a) + b
|
||||
// y^2
|
||||
BnMult(left, Q->y, Q->y);
|
||||
|
||||
BnMod(left, prime);
|
||||
// x^2
|
||||
BnMult(right, Q->x, Q->x);
|
||||
|
||||
// x^2 + a
|
||||
BnAdd(right, right, BnCurveGet_a(C));
|
||||
|
||||
// ExtMath_Mod(right, CurveGetPrime(C));
|
||||
// x(x^2 + a)
|
||||
BnMult(right, right, Q->x);
|
||||
|
||||
// x(x^2 + a) + b
|
||||
BnAdd(right, right, BnCurveGet_b(C));
|
||||
|
||||
BnMod(right, prime);
|
||||
if(BnUnsignedCmp(left, right) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 10.2.3.3.20 BnGetRandomBits() */
|
||||
/* Return Value Meaning */
|
||||
/* TRUE(1) success */
|
||||
|
||||
@ -133,18 +133,19 @@ LIB_EXPORT BOOL BnModInverse(bigNum result, bigConst number, bigConst modulus);
|
||||
// structure is a set of pointers to bigNum values. The curve-dependent values are
|
||||
// set by a different function. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT bigCurve BnCurveInitialize(bigCurve E, TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT bigCurveData* BnCurveInitialize(bigCurveData* E, TPM_ECC_CURVE curveId);
|
||||
|
||||
//*** BnCurveFree()
|
||||
// This function will free the allocated components of the curve and end the
|
||||
// frame in which the curve data exists
|
||||
LIB_EXPORT void BnCurveFree(bigCurve E);
|
||||
LIB_EXPORT void BnCurveFree(bigCurveData* E);
|
||||
|
||||
//** BnEccModMult()
|
||||
// This function does a point multiply of the form R = [d]S. A return of FALSE
|
||||
// indicates that the result was the point at infinity. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL BnEccModMult(bigPoint R, pointConst S, bigConst d, bigCurve E);
|
||||
LIB_EXPORT BOOL BnEccModMult(
|
||||
bigPoint R, pointConst S, bigConst d, const bigCurveData* E);
|
||||
|
||||
//** BnEccModMult2()
|
||||
// This function does a point multiply of the form R = [d]S + [u]Q. A return of
|
||||
@ -155,15 +156,23 @@ LIB_EXPORT BOOL BnEccModMult2(bigPoint R,
|
||||
bigConst d,
|
||||
pointConst Q,
|
||||
bigConst u,
|
||||
const bigCurve E);
|
||||
const bigCurveData* E);
|
||||
|
||||
//** BnEccAdd()
|
||||
// This function does a point add R = S + Q. A return of FALSE
|
||||
// indicates that the result was the point at infinity. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL BnEccAdd(
|
||||
bigPoint R, pointConst S, pointConst Q, const bigCurve E);
|
||||
bigPoint R, pointConst S, pointConst Q, const bigCurveData* E);
|
||||
|
||||
#endif // ALG_ECC
|
||||
|
||||
// libtpms: added begin
|
||||
bigCurveData*
|
||||
BnCurveInitialize(
|
||||
bigCurveData* E, // IN: curve structure to initialize
|
||||
TPM_ECC_CURVE curveId // IN: curve identifier
|
||||
);
|
||||
// libtpms: added end
|
||||
|
||||
#endif //BN_SUPPORT_INTERFACE_H
|
||||
|
||||
@ -73,550 +73,79 @@
|
||||
// The CURVE_NAME macro is used to remove the name string from normal builds, but leaves the
|
||||
// string available in the initialization lists for potenial use during debugging by changing this
|
||||
// macro (and the structure declaration)
|
||||
#if USE_BN_ECC_DATA
|
||||
# define TO_ECC_64 TO_CRYPT_WORD_64
|
||||
# define TO_ECC_56(a, b, c, d, e, f, g) TO_ECC_64(0, a, b, c, d, e, f, g)
|
||||
# define TO_ECC_48(a, b, c, d, e, f) TO_ECC_64(0, 0, a, b, c, d, e, f)
|
||||
# define TO_ECC_40(a, b, c, d, e) TO_ECC_64(0, 0, 0, a, b, c, d, e)
|
||||
# if RADIX_BITS > 32
|
||||
# define TO_ECC_32(a, b, c, d) TO_ECC_64(0, 0, 0, 0, a, b, c, d)
|
||||
# define TO_ECC_24(a, b, c) TO_ECC_64(0, 0, 0, 0, 0, a, b, c)
|
||||
# define TO_ECC_16(a, b) TO_ECC_64(0, 0, 0, 0, 0, 0, a, b)
|
||||
# define TO_ECC_8(a) TO_ECC_64(0, 0, 0, 0, 0, 0, 0, a)
|
||||
# else // RADIX_BITS == 32
|
||||
# define TO_ECC_32 BIG_ENDIAN_BYTES_TO_UINT32
|
||||
# define TO_ECC_24(a, b, c) TO_ECC_32(0, a, b, c)
|
||||
# define TO_ECC_16(a, b) TO_ECC_32(0, 0, a, b)
|
||||
# define TO_ECC_8(a) TO_ECC_32(0, 0, 0, a)
|
||||
# endif
|
||||
#else // TPM2B_
|
||||
# define TO_ECC_64(a, b, c, d, e, f, g, h) a, b, c, d, e, f, g, h
|
||||
# define TO_ECC_56(a, b, c, d, e, f, g) a, b, c, d, e, f, g
|
||||
# define TO_ECC_48(a, b, c, d, e, f) a, b, c, d, e, f
|
||||
# define TO_ECC_40(a, b, c, d, e) a, b, c, d, e
|
||||
# define TO_ECC_32(a, b, c, d) a, b, c, d
|
||||
# define TO_ECC_24(a, b, c) a, b, c
|
||||
# define TO_ECC_16(a, b) a, b
|
||||
# define TO_ECC_8(a) a
|
||||
#endif
|
||||
#if USE_BN_ECC_DATA
|
||||
#define BN_MIN_ALLOC(bytes) \
|
||||
(BYTES_TO_CRYPT_WORDS(bytes) == 0) ? 1 : BYTES_TO_CRYPT_WORDS(bytes)
|
||||
# define ECC_CONST(NAME, bytes, initializer) \
|
||||
const struct { \
|
||||
crypt_uword_t allocate, size, d[BN_MIN_ALLOC(bytes)]; \
|
||||
} NAME = {BN_MIN_ALLOC(bytes), BYTES_TO_CRYPT_WORDS(bytes),{initializer}}
|
||||
ECC_CONST(ECC_ZERO, 0, 0);
|
||||
#else
|
||||
# define ECC_CONST(NAME, bytes, initializer) \
|
||||
const TPM2B_##bytes##_BYTE_VALUE NAME = {bytes, {initializer}}
|
||||
/* Have to special case ECC_ZERO */
|
||||
TPM2B_BYTE_VALUE(1);
|
||||
TPM2B_1_BYTE_VALUE ECC_ZERO = {1, {0}};
|
||||
#endif
|
||||
ECC_CONST(ECC_ONE, 1, 1);
|
||||
#if !USE_BN_ECC_DATA
|
||||
TPM2B_BYTE_VALUE(24);
|
||||
#define TO_ECC_192(a, b, c) a, b, c
|
||||
TPM2B_BYTE_VALUE(28);
|
||||
#define TO_ECC_224(a, b, c, d) a, b, c, d
|
||||
TPM2B_BYTE_VALUE(32);
|
||||
#define TO_ECC_256(a, b, c, d) a, b, c, d
|
||||
TPM2B_BYTE_VALUE(48);
|
||||
#define TO_ECC_384(a, b, c, d, e, f) a, b, c, d, e, f
|
||||
TPM2B_BYTE_VALUE(66);
|
||||
#define TO_ECC_528(a, b, c, d, e, f, g, h, i) a, b, c, d, e, f, g, h, i
|
||||
TPM2B_BYTE_VALUE(80);
|
||||
#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j) a, b, c, d, e, f, g, h, i, j
|
||||
#else
|
||||
#define TO_ECC_192(a, b, c) c, b, a
|
||||
#define TO_ECC_224(a, b, c, d) d, c, b, a
|
||||
#define TO_ECC_256(a, b, c, d) d, c, b, a
|
||||
#define TO_ECC_384(a, b, c, d, e, f) f, e, d, c, b, a
|
||||
#define TO_ECC_528(a, b, c, d, e, f, g, h, i) i, h, g, f, e, d, c, b, a
|
||||
#define TO_ECC_640(a, b, c, d, e, f, g, h, i, j) j, i, h, g, f, e, d, c, b, a
|
||||
#endif // !USE_BN_ECC_DATA
|
||||
#if ECC_NIST_P192
|
||||
ECC_CONST(NIST_P192_p, 24, TO_ECC_192(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P192_a, 24, TO_ECC_192(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P192_b, 24, TO_ECC_192(
|
||||
TO_ECC_64(0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7),
|
||||
TO_ECC_64(0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49),
|
||||
TO_ECC_64(0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1)));
|
||||
ECC_CONST(NIST_P192_gX, 24, TO_ECC_192(
|
||||
TO_ECC_64(0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6),
|
||||
TO_ECC_64(0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00),
|
||||
TO_ECC_64(0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12)));
|
||||
ECC_CONST(NIST_P192_gY, 24, TO_ECC_192(
|
||||
TO_ECC_64(0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78),
|
||||
TO_ECC_64(0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5),
|
||||
TO_ECC_64(0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11)));
|
||||
ECC_CONST(NIST_P192_n, 24, TO_ECC_192(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36),
|
||||
TO_ECC_64(0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31)));
|
||||
#define NIST_P192_h ECC_ONE
|
||||
#define NIST_P192_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA NIST_P192 = {
|
||||
(bigNum)&NIST_P192_p, (bigNum)&NIST_P192_n, (bigNum)&NIST_P192_h,
|
||||
(bigNum)&NIST_P192_a, (bigNum)&NIST_P192_b,
|
||||
{(bigNum)&NIST_P192_gX, (bigNum)&NIST_P192_gY, (bigNum)&NIST_P192_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA NIST_P192 = {
|
||||
&NIST_P192_p.b, &NIST_P192_n.b, &NIST_P192_h.b,
|
||||
&NIST_P192_a.b, &NIST_P192_b.b,
|
||||
{&NIST_P192_gX.b, &NIST_P192_gY.b, &NIST_P192_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_NIST_P192
|
||||
#if ECC_NIST_P224
|
||||
ECC_CONST(NIST_P224_p, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)));
|
||||
ECC_CONST(NIST_P224_a, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE)));
|
||||
ECC_CONST(NIST_P224_b, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xB4, 0x05, 0x0A, 0x85),
|
||||
TO_ECC_64(0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56),
|
||||
TO_ECC_64(0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA),
|
||||
TO_ECC_64(0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4)));
|
||||
ECC_CONST(NIST_P224_gX, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xB7, 0x0E, 0x0C, 0xBD),
|
||||
TO_ECC_64(0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9),
|
||||
TO_ECC_64(0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22),
|
||||
TO_ECC_64(0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21)));
|
||||
ECC_CONST(NIST_P224_gY, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xBD, 0x37, 0x63, 0x88),
|
||||
TO_ECC_64(0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6),
|
||||
TO_ECC_64(0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64),
|
||||
TO_ECC_64(0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34)));
|
||||
ECC_CONST(NIST_P224_n, 28, TO_ECC_224(
|
||||
TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E),
|
||||
TO_ECC_64(0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D)));
|
||||
#define NIST_P224_h ECC_ONE
|
||||
#define NIST_P224_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA NIST_P224 = {
|
||||
(bigNum)&NIST_P224_p, (bigNum)&NIST_P224_n, (bigNum)&NIST_P224_h,
|
||||
(bigNum)&NIST_P224_a, (bigNum)&NIST_P224_b,
|
||||
{(bigNum)&NIST_P224_gX, (bigNum)&NIST_P224_gY, (bigNum)&NIST_P224_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA NIST_P224 = {
|
||||
&NIST_P224_p.b, &NIST_P224_n.b, &NIST_P224_h.b,
|
||||
&NIST_P224_a.b, &NIST_P224_b.b,
|
||||
{&NIST_P224_gX.b, &NIST_P224_gY.b, &NIST_P224_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_NIST_P224
|
||||
#if ECC_NIST_P256
|
||||
ECC_CONST(NIST_P256_p, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P256_a, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P256_b, 32, TO_ECC_256(
|
||||
TO_ECC_64(0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7),
|
||||
TO_ECC_64(0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC),
|
||||
TO_ECC_64(0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6),
|
||||
TO_ECC_64(0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B)));
|
||||
ECC_CONST(NIST_P256_gX, 32, TO_ECC_256(
|
||||
TO_ECC_64(0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47),
|
||||
TO_ECC_64(0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2),
|
||||
TO_ECC_64(0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0),
|
||||
TO_ECC_64(0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96)));
|
||||
ECC_CONST(NIST_P256_gY, 32, TO_ECC_256(
|
||||
TO_ECC_64(0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B),
|
||||
TO_ECC_64(0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16),
|
||||
TO_ECC_64(0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE),
|
||||
TO_ECC_64(0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5)));
|
||||
ECC_CONST(NIST_P256_n, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84),
|
||||
TO_ECC_64(0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51)));
|
||||
#define NIST_P256_h ECC_ONE
|
||||
#define NIST_P256_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA NIST_P256 = {
|
||||
(bigNum)&NIST_P256_p, (bigNum)&NIST_P256_n, (bigNum)&NIST_P256_h,
|
||||
(bigNum)&NIST_P256_a, (bigNum)&NIST_P256_b,
|
||||
{(bigNum)&NIST_P256_gX, (bigNum)&NIST_P256_gY, (bigNum)&NIST_P256_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA NIST_P256 = {
|
||||
&NIST_P256_p.b, &NIST_P256_n.b, &NIST_P256_h.b,
|
||||
&NIST_P256_a.b, &NIST_P256_b.b,
|
||||
{&NIST_P256_gX.b, &NIST_P256_gY.b, &NIST_P256_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_NIST_P256
|
||||
#if ECC_NIST_P384
|
||||
ECC_CONST(NIST_P384_p, 48, TO_ECC_384(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P384_a, 48, TO_ECC_384(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P384_b, 48, TO_ECC_384(
|
||||
TO_ECC_64(0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4),
|
||||
TO_ECC_64(0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19),
|
||||
TO_ECC_64(0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12),
|
||||
TO_ECC_64(0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A),
|
||||
TO_ECC_64(0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D),
|
||||
TO_ECC_64(0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF)));
|
||||
ECC_CONST(NIST_P384_gX, 48, TO_ECC_384(
|
||||
TO_ECC_64(0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37),
|
||||
TO_ECC_64(0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74),
|
||||
TO_ECC_64(0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98),
|
||||
TO_ECC_64(0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38),
|
||||
TO_ECC_64(0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C),
|
||||
TO_ECC_64(0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7)));
|
||||
ECC_CONST(NIST_P384_gY, 48, TO_ECC_384(
|
||||
TO_ECC_64(0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F),
|
||||
TO_ECC_64(0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29),
|
||||
TO_ECC_64(0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C),
|
||||
TO_ECC_64(0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0),
|
||||
TO_ECC_64(0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D),
|
||||
TO_ECC_64(0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F)));
|
||||
ECC_CONST(NIST_P384_n, 48, TO_ECC_384(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF),
|
||||
TO_ECC_64(0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A),
|
||||
TO_ECC_64(0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73)));
|
||||
#define NIST_P384_h ECC_ONE
|
||||
#define NIST_P384_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA NIST_P384 = {
|
||||
(bigNum)&NIST_P384_p, (bigNum)&NIST_P384_n, (bigNum)&NIST_P384_h,
|
||||
(bigNum)&NIST_P384_a, (bigNum)&NIST_P384_b,
|
||||
{(bigNum)&NIST_P384_gX, (bigNum)&NIST_P384_gY, (bigNum)&NIST_P384_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA NIST_P384 = {
|
||||
&NIST_P384_p.b, &NIST_P384_n.b, &NIST_P384_h.b,
|
||||
&NIST_P384_a.b, &NIST_P384_b.b,
|
||||
{&NIST_P384_gX.b, &NIST_P384_gY.b, &NIST_P384_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_NIST_P384
|
||||
#if ECC_NIST_P521
|
||||
ECC_CONST(NIST_P521_p, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P521_a, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P521_b, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x00, 0x51),
|
||||
TO_ECC_64(0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F),
|
||||
TO_ECC_64(0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE),
|
||||
TO_ECC_64(0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3),
|
||||
TO_ECC_64(0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1),
|
||||
TO_ECC_64(0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B),
|
||||
TO_ECC_64(0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07),
|
||||
TO_ECC_64(0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1),
|
||||
TO_ECC_64(0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00)));
|
||||
ECC_CONST(NIST_P521_gX, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x00, 0xC6),
|
||||
TO_ECC_64(0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD),
|
||||
TO_ECC_64(0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42),
|
||||
TO_ECC_64(0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21),
|
||||
TO_ECC_64(0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA),
|
||||
TO_ECC_64(0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28),
|
||||
TO_ECC_64(0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE),
|
||||
TO_ECC_64(0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B),
|
||||
TO_ECC_64(0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66)));
|
||||
ECC_CONST(NIST_P521_gY, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x01, 0x18),
|
||||
TO_ECC_64(0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04),
|
||||
TO_ECC_64(0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9),
|
||||
TO_ECC_64(0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68),
|
||||
TO_ECC_64(0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C),
|
||||
TO_ECC_64(0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40),
|
||||
TO_ECC_64(0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61),
|
||||
TO_ECC_64(0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40),
|
||||
TO_ECC_64(0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50)));
|
||||
ECC_CONST(NIST_P521_n, 66, TO_ECC_528(
|
||||
TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA),
|
||||
TO_ECC_64(0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B),
|
||||
TO_ECC_64(0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0),
|
||||
TO_ECC_64(0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE),
|
||||
TO_ECC_64(0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09)));
|
||||
#define NIST_P521_h ECC_ONE
|
||||
#define NIST_P521_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA NIST_P521 = {
|
||||
(bigNum)&NIST_P521_p, (bigNum)&NIST_P521_n, (bigNum)&NIST_P521_h,
|
||||
(bigNum)&NIST_P521_a, (bigNum)&NIST_P521_b,
|
||||
{(bigNum)&NIST_P521_gX, (bigNum)&NIST_P521_gY, (bigNum)&NIST_P521_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA NIST_P521 = {
|
||||
&NIST_P521_p.b, &NIST_P521_n.b, &NIST_P521_h.b,
|
||||
&NIST_P521_a.b, &NIST_P521_b.b,
|
||||
{&NIST_P521_gX.b, &NIST_P521_gY.b, &NIST_P521_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_NIST_P521
|
||||
#if ECC_BN_P256
|
||||
ECC_CONST(BN_P256_p, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
|
||||
TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9F),
|
||||
TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x98, 0x0A, 0x82),
|
||||
TO_ECC_64(0xD3, 0x29, 0x2D, 0xDB, 0xAE, 0xD3, 0x30, 0x13)));
|
||||
#define BN_P256_a ECC_ZERO
|
||||
ECC_CONST(BN_P256_b, 1, TO_ECC_8(3));
|
||||
#define BN_P256_gX ECC_ONE
|
||||
ECC_CONST(BN_P256_gY, 1, TO_ECC_8(2));
|
||||
ECC_CONST(BN_P256_n, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
|
||||
TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E),
|
||||
TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A),
|
||||
TO_ECC_64(0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D)));
|
||||
#define BN_P256_h ECC_ONE
|
||||
#define BN_P256_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA BN_P256 = {
|
||||
(bigNum)&BN_P256_p, (bigNum)&BN_P256_n, (bigNum)&BN_P256_h,
|
||||
(bigNum)&BN_P256_a, (bigNum)&BN_P256_b,
|
||||
{(bigNum)&BN_P256_gX, (bigNum)&BN_P256_gY, (bigNum)&BN_P256_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA BN_P256 = {
|
||||
&BN_P256_p.b, &BN_P256_n.b, &BN_P256_h.b,
|
||||
&BN_P256_a.b, &BN_P256_b.b,
|
||||
{&BN_P256_gX.b, &BN_P256_gY.b, &BN_P256_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_BN_P256
|
||||
#if ECC_BN_P638
|
||||
ECC_CONST(BN_P638_p, 80, TO_ECC_640(
|
||||
TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67)));
|
||||
#define BN_P638_a ECC_ZERO
|
||||
ECC_CONST(BN_P638_b, 2, TO_ECC_16(0x01,0x01));
|
||||
ECC_CONST(BN_P638_gX, 80, TO_ECC_640(
|
||||
TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66)));
|
||||
ECC_CONST(BN_P638_gY, 1, TO_ECC_8(0x10));
|
||||
ECC_CONST(BN_P638_n, 80, TO_ECC_640(
|
||||
TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61)));
|
||||
#define BN_P638_h ECC_ONE
|
||||
#define BN_P638_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA BN_P638 = {
|
||||
(bigNum)&BN_P638_p, (bigNum)&BN_P638_n, (bigNum)&BN_P638_h,
|
||||
(bigNum)&BN_P638_a, (bigNum)&BN_P638_b,
|
||||
{(bigNum)&BN_P638_gX, (bigNum)&BN_P638_gY, (bigNum)&BN_P638_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA BN_P638 = {
|
||||
&BN_P638_p.b, &BN_P638_n.b, &BN_P638_h.b,
|
||||
&BN_P638_a.b, &BN_P638_b.b,
|
||||
{&BN_P638_gX.b, &BN_P638_gY.b, &BN_P638_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_BN_P638
|
||||
#if ECC_SM2_P256
|
||||
ECC_CONST(SM2_P256_p, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(SM2_P256_a, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(SM2_P256_b, 32, TO_ECC_256(
|
||||
TO_ECC_64(0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34),
|
||||
TO_ECC_64(0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7),
|
||||
TO_ECC_64(0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92),
|
||||
TO_ECC_64(0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93)));
|
||||
ECC_CONST(SM2_P256_gX, 32, TO_ECC_256(
|
||||
TO_ECC_64(0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19),
|
||||
TO_ECC_64(0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94),
|
||||
TO_ECC_64(0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1),
|
||||
TO_ECC_64(0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7)));
|
||||
ECC_CONST(SM2_P256_gY, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C),
|
||||
TO_ECC_64(0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53),
|
||||
TO_ECC_64(0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40),
|
||||
TO_ECC_64(0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0)));
|
||||
ECC_CONST(SM2_P256_n, 32, TO_ECC_256(
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B),
|
||||
TO_ECC_64(0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23)));
|
||||
#define SM2_P256_h ECC_ONE
|
||||
#define SM2_P256_gZ ECC_ONE
|
||||
#if USE_BN_ECC_DATA
|
||||
const ECC_CURVE_DATA SM2_P256 = {
|
||||
(bigNum)&SM2_P256_p, (bigNum)&SM2_P256_n, (bigNum)&SM2_P256_h,
|
||||
(bigNum)&SM2_P256_a, (bigNum)&SM2_P256_b,
|
||||
{(bigNum)&SM2_P256_gX, (bigNum)&SM2_P256_gY, (bigNum)&SM2_P256_gZ}};
|
||||
#else
|
||||
const ECC_CURVE_DATA SM2_P256 = {
|
||||
&SM2_P256_p.b, &SM2_P256_n.b, &SM2_P256_h.b,
|
||||
&SM2_P256_a.b, &SM2_P256_b.b,
|
||||
{&SM2_P256_gX.b, &SM2_P256_gY.b, &SM2_P256_gZ.b}};
|
||||
#endif // USE_BN_ECC_DATA
|
||||
#endif // ECC_SM2_P256
|
||||
# define CURVE_NAME(N)
|
||||
|
||||
# define comma
|
||||
const ECC_CURVE eccCurves[] = {
|
||||
const TPM_ECC_CURVE_METADATA eccCurves[] = {
|
||||
# if ECC_NIST_P192
|
||||
comma
|
||||
{TPM_ECC_NIST_P192,
|
||||
192,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&NIST_P192,
|
||||
OID_ECC_NIST_P192
|
||||
CURVE_NAME("NIST_P192")}
|
||||
comma{TPM_ECC_NIST_P192,
|
||||
192,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_NIST_P192 CURVE_NAME("NIST_P192")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_NIST_P192
|
||||
# if ECC_NIST_P224
|
||||
comma
|
||||
{TPM_ECC_NIST_P224,
|
||||
224,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&NIST_P224,
|
||||
OID_ECC_NIST_P224
|
||||
CURVE_NAME("NIST_P224")}
|
||||
comma{TPM_ECC_NIST_P224,
|
||||
224,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_NIST_P224 CURVE_NAME("NIST_P224")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_NIST_P224
|
||||
# if ECC_NIST_P256
|
||||
comma
|
||||
{TPM_ECC_NIST_P256,
|
||||
256,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&NIST_P256,
|
||||
OID_ECC_NIST_P256
|
||||
CURVE_NAME("NIST_P256")}
|
||||
comma{TPM_ECC_NIST_P256,
|
||||
256,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_NIST_P256 CURVE_NAME("NIST_P256")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_NIST_P256
|
||||
# if ECC_NIST_P384
|
||||
comma
|
||||
{TPM_ECC_NIST_P384,
|
||||
384,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA384}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&NIST_P384,
|
||||
OID_ECC_NIST_P384
|
||||
CURVE_NAME("NIST_P384")}
|
||||
comma{TPM_ECC_NIST_P384,
|
||||
384,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA384}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_NIST_P384 CURVE_NAME("NIST_P384")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_NIST_P384
|
||||
# if ECC_NIST_P521
|
||||
comma
|
||||
{TPM_ECC_NIST_P521,
|
||||
521,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA512}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&NIST_P521,
|
||||
OID_ECC_NIST_P521
|
||||
CURVE_NAME("NIST_P521")}
|
||||
comma{TPM_ECC_NIST_P521,
|
||||
521,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SHA512}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_NIST_P521 CURVE_NAME("NIST_P521")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_NIST_P521
|
||||
# if ECC_BN_P256
|
||||
comma
|
||||
{TPM_ECC_BN_P256,
|
||||
256,
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&BN_P256,
|
||||
OID_ECC_BN_P256
|
||||
CURVE_NAME("BN_P256")}
|
||||
comma{TPM_ECC_BN_P256,
|
||||
256,
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_BN_P256 CURVE_NAME("BN_P256")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_BN_P256
|
||||
# if ECC_BN_P638
|
||||
comma
|
||||
{TPM_ECC_BN_P638,
|
||||
638,
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&BN_P638,
|
||||
OID_ECC_BN_P638
|
||||
CURVE_NAME("BN_P638")}
|
||||
comma{TPM_ECC_BN_P638,
|
||||
638,
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_BN_P638 CURVE_NAME("BN_P638")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_BN_P638
|
||||
# if ECC_SM2_P256
|
||||
comma
|
||||
{TPM_ECC_SM2_P256,
|
||||
256,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SM3_256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
&SM2_P256,
|
||||
OID_ECC_SM2_P256
|
||||
CURVE_NAME("SM2_P256")}
|
||||
comma{TPM_ECC_SM2_P256,
|
||||
256,
|
||||
{TPM_ALG_KDF1_SP800_56A, {{TPM_ALG_SM3_256}}},
|
||||
{TPM_ALG_NULL, {{TPM_ALG_NULL}}},
|
||||
OID_ECC_SM2_P256 CURVE_NAME("SM2_P256")}
|
||||
# undef comma
|
||||
# define comma ,
|
||||
# endif // ECC_SM2_P256
|
||||
|
||||
474
src/tpm2/EccConstantData.inl
Normal file
474
src/tpm2/EccConstantData.inl
Normal file
@ -0,0 +1,474 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* Microsoft Reference Implementation for TPM 2.0
|
||||
*
|
||||
* The copyright in this software is being made available under the BSD License,
|
||||
* included below. This software may be subject to other third party and
|
||||
* contributor rights, including patent rights, and no such rights are granted
|
||||
* under this license.
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// This file contains the ECC curve data. The data is contained in macros so this
|
||||
// file can be included in other format-specific header files that reformat the
|
||||
// constant data in any format desired. This file itself is never used alone.
|
||||
|
||||
// Expected macros:
|
||||
//
|
||||
// TO_ECC_<bits>:
|
||||
// <bits> <= 64:
|
||||
// "N" byte arguments in most-significant to least-significant order The number
|
||||
// of arguments depends on the bit length, which must be a multiple of 8.
|
||||
// <bits> > 64:
|
||||
// "Q" macro arguments from the <bits> <= 64 group to produce the total number
|
||||
// of requested bits.
|
||||
//
|
||||
// ECC_CONST:
|
||||
// Parameters:
|
||||
// Name, Bytes, initial value; either a single byte value or a combination of TO_ECC macros
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
ECC_CONST(ECC_ZERO, 1, 0);
|
||||
ECC_CONST(ECC_ONE, 1, 1);
|
||||
|
||||
# if ECC_NIST_P192
|
||||
ECC_CONST(NIST_P192_p,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P192_a,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P192_b,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7),
|
||||
TO_ECC_64(0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49),
|
||||
TO_ECC_64(0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1)));
|
||||
ECC_CONST(NIST_P192_gX,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6),
|
||||
TO_ECC_64(0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00),
|
||||
TO_ECC_64(0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12)));
|
||||
ECC_CONST(NIST_P192_gY,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78),
|
||||
TO_ECC_64(0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5),
|
||||
TO_ECC_64(0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11)));
|
||||
ECC_CONST(NIST_P192_n,
|
||||
24,
|
||||
TO_ECC_192(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36),
|
||||
TO_ECC_64(0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31)));
|
||||
# define NIST_P192_h ECC_ONE
|
||||
# define NIST_P192_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_NIST_P192
|
||||
|
||||
# if ECC_NIST_P224
|
||||
ECC_CONST(NIST_P224_p,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)));
|
||||
ECC_CONST(NIST_P224_a,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE)));
|
||||
ECC_CONST(NIST_P224_b,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xB4, 0x05, 0x0A, 0x85),
|
||||
TO_ECC_64(0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56),
|
||||
TO_ECC_64(0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA),
|
||||
TO_ECC_64(0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4)));
|
||||
ECC_CONST(NIST_P224_gX,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xB7, 0x0E, 0x0C, 0xBD),
|
||||
TO_ECC_64(0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9),
|
||||
TO_ECC_64(0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22),
|
||||
TO_ECC_64(0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21)));
|
||||
ECC_CONST(NIST_P224_gY,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xBD, 0x37, 0x63, 0x88),
|
||||
TO_ECC_64(0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6),
|
||||
TO_ECC_64(0xCD, 0x43, 0x75, 0xA0, 0x5A, 0x07, 0x47, 0x64),
|
||||
TO_ECC_64(0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34)));
|
||||
ECC_CONST(NIST_P224_n,
|
||||
28,
|
||||
TO_ECC_224(TO_ECC_32(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E),
|
||||
TO_ECC_64(0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D)));
|
||||
# define NIST_P224_h ECC_ONE
|
||||
# define NIST_P224_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_NIST_P224
|
||||
|
||||
# if ECC_NIST_P256
|
||||
ECC_CONST(NIST_P256_p,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P256_a,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P256_b,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7),
|
||||
TO_ECC_64(0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC),
|
||||
TO_ECC_64(0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6),
|
||||
TO_ECC_64(0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B)));
|
||||
ECC_CONST(NIST_P256_gX,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47),
|
||||
TO_ECC_64(0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2),
|
||||
TO_ECC_64(0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0),
|
||||
TO_ECC_64(0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96)));
|
||||
ECC_CONST(NIST_P256_gY,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B),
|
||||
TO_ECC_64(0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16),
|
||||
TO_ECC_64(0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE),
|
||||
TO_ECC_64(0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5)));
|
||||
ECC_CONST(NIST_P256_n,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84),
|
||||
TO_ECC_64(0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51)));
|
||||
# define NIST_P256_h ECC_ONE
|
||||
# define NIST_P256_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_NIST_P256
|
||||
|
||||
# if ECC_NIST_P384
|
||||
ECC_CONST(NIST_P384_p,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P384_a,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P384_b,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4),
|
||||
TO_ECC_64(0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19),
|
||||
TO_ECC_64(0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12),
|
||||
TO_ECC_64(0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A),
|
||||
TO_ECC_64(0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D),
|
||||
TO_ECC_64(0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF)));
|
||||
ECC_CONST(NIST_P384_gX,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37),
|
||||
TO_ECC_64(0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74),
|
||||
TO_ECC_64(0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98),
|
||||
TO_ECC_64(0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38),
|
||||
TO_ECC_64(0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C),
|
||||
TO_ECC_64(0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7)));
|
||||
ECC_CONST(NIST_P384_gY,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F),
|
||||
TO_ECC_64(0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29),
|
||||
TO_ECC_64(0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C),
|
||||
TO_ECC_64(0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0),
|
||||
TO_ECC_64(0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D),
|
||||
TO_ECC_64(0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F)));
|
||||
ECC_CONST(NIST_P384_n,
|
||||
48,
|
||||
TO_ECC_384(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF),
|
||||
TO_ECC_64(0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A),
|
||||
TO_ECC_64(0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73)));
|
||||
# define NIST_P384_h ECC_ONE
|
||||
# define NIST_P384_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_NIST_P384
|
||||
|
||||
# if ECC_NIST_P521
|
||||
ECC_CONST(NIST_P521_p,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(NIST_P521_a,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(NIST_P521_b,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x00, 0x51),
|
||||
TO_ECC_64(0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F),
|
||||
TO_ECC_64(0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE),
|
||||
TO_ECC_64(0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3),
|
||||
TO_ECC_64(0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1),
|
||||
TO_ECC_64(0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B),
|
||||
TO_ECC_64(0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 0xBF, 0x07),
|
||||
TO_ECC_64(0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1),
|
||||
TO_ECC_64(0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00)));
|
||||
ECC_CONST(NIST_P521_gX,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x00, 0xC6),
|
||||
TO_ECC_64(0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD),
|
||||
TO_ECC_64(0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42),
|
||||
TO_ECC_64(0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21),
|
||||
TO_ECC_64(0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA),
|
||||
TO_ECC_64(0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28),
|
||||
TO_ECC_64(0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 0xA8, 0xDE),
|
||||
TO_ECC_64(0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B),
|
||||
TO_ECC_64(0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66)));
|
||||
ECC_CONST(NIST_P521_gY,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x01, 0x18),
|
||||
TO_ECC_64(0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04),
|
||||
TO_ECC_64(0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9),
|
||||
TO_ECC_64(0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68),
|
||||
TO_ECC_64(0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C),
|
||||
TO_ECC_64(0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40),
|
||||
TO_ECC_64(0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 0x07, 0x61),
|
||||
TO_ECC_64(0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40),
|
||||
TO_ECC_64(0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50)));
|
||||
ECC_CONST(NIST_P521_n,
|
||||
66,
|
||||
TO_ECC_528(TO_ECC_16(0x01, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA),
|
||||
TO_ECC_64(0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B),
|
||||
TO_ECC_64(0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 0xA5, 0xD0),
|
||||
TO_ECC_64(0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE),
|
||||
TO_ECC_64(0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09)));
|
||||
# define NIST_P521_h ECC_ONE
|
||||
# define NIST_P521_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_NIST_P521
|
||||
|
||||
# if ECC_BN_P256
|
||||
ECC_CONST(BN_P256_p,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
|
||||
TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9F),
|
||||
TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x98, 0x0A, 0x82),
|
||||
TO_ECC_64(0xD3, 0x29, 0x2D, 0xDB, 0xAE, 0xD3, 0x30, 0x13)));
|
||||
# define BN_P256_a ECC_ZERO
|
||||
ECC_CONST(BN_P256_b, 1, TO_ECC_8(3));
|
||||
# define BN_P256_gX ECC_ONE
|
||||
ECC_CONST(BN_P256_gY, 1, TO_ECC_8(2));
|
||||
ECC_CONST(BN_P256_n,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xCD),
|
||||
TO_ECC_64(0x46, 0xE5, 0xF2, 0x5E, 0xEE, 0x71, 0xA4, 0x9E),
|
||||
TO_ECC_64(0x0C, 0xDC, 0x65, 0xFB, 0x12, 0x99, 0x92, 0x1A),
|
||||
TO_ECC_64(0xF6, 0x2D, 0x53, 0x6C, 0xD1, 0x0B, 0x50, 0x0D)));
|
||||
# define BN_P256_h ECC_ONE
|
||||
# define BN_P256_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_BN_P256
|
||||
|
||||
# if ECC_BN_P638
|
||||
ECC_CONST(BN_P638_p,
|
||||
80,
|
||||
TO_ECC_640(TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67)));
|
||||
# define BN_P638_a ECC_ZERO
|
||||
ECC_CONST(BN_P638_b, 2, TO_ECC_16(0x01, 0x01));
|
||||
ECC_CONST(BN_P638_gX,
|
||||
80,
|
||||
TO_ECC_640(TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0xC0, 0x00, 0x86, 0x52, 0x00, 0x21, 0xE5, 0x5B),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x1F, 0xFF, 0xF4, 0xEB, 0x80),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x4C, 0x80, 0x01, 0x5A, 0xCD),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEC, 0xE0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66)));
|
||||
ECC_CONST(BN_P638_gY, 1, TO_ECC_8(0x10));
|
||||
ECC_CONST(BN_P638_n,
|
||||
80,
|
||||
TO_ECC_640(TO_ECC_64(0x23, 0xFF, 0xFF, 0xFD, 0xC0, 0x00, 0x00, 0x0D),
|
||||
TO_ECC_64(0x7F, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x01, 0xD3),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF9, 0x42, 0xD0, 0x00, 0x16, 0x5E),
|
||||
TO_ECC_64(0x3F, 0xFF, 0x94, 0x87, 0x00, 0x00, 0xD5, 0x2F),
|
||||
TO_ECC_64(0xFF, 0xFD, 0xD0, 0xE0, 0x00, 0x08, 0xDE, 0x55),
|
||||
TO_ECC_64(0x60, 0x00, 0x86, 0x55, 0x00, 0x21, 0xE5, 0x55),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xF5, 0x4F, 0xFF, 0xF4, 0xEA, 0xC0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x49, 0x80, 0x01, 0x54, 0xD9),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0xA0),
|
||||
TO_ECC_64(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61)));
|
||||
# define BN_P638_h ECC_ONE
|
||||
# define BN_P638_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_BN_P638
|
||||
|
||||
# if ECC_SM2_P256
|
||||
ECC_CONST(SM2_P256_p,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)));
|
||||
ECC_CONST(SM2_P256_a,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC)));
|
||||
ECC_CONST(SM2_P256_b,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34),
|
||||
TO_ECC_64(0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7),
|
||||
TO_ECC_64(0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92),
|
||||
TO_ECC_64(0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93)));
|
||||
ECC_CONST(SM2_P256_gX,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19),
|
||||
TO_ECC_64(0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94),
|
||||
TO_ECC_64(0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1),
|
||||
TO_ECC_64(0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7)));
|
||||
ECC_CONST(SM2_P256_gY,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C),
|
||||
TO_ECC_64(0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53),
|
||||
TO_ECC_64(0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40),
|
||||
TO_ECC_64(0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0)));
|
||||
ECC_CONST(SM2_P256_n,
|
||||
32,
|
||||
TO_ECC_256(TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
TO_ECC_64(0x72, 0x03, 0xDF, 0x6B, 0x21, 0xC6, 0x05, 0x2B),
|
||||
TO_ECC_64(0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23)));
|
||||
# define SM2_P256_h ECC_ONE
|
||||
# define SM2_P256_gZ ECC_ONE
|
||||
|
||||
# endif // ECC_SM2_P256
|
||||
|
||||
#endif // TPM_ALG_ECC
|
||||
@ -60,6 +60,7 @@
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "Commit_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#if CC_Commit // Conditional expansion of this file
|
||||
|
||||
@ -115,7 +116,7 @@ TPM2_Commit(Commit_In* in, // IN: input parameter list
|
||||
|
||||
// Get prime modulus for the curve. This is needed later but getting this now
|
||||
// allows confirmation that the curve exists.
|
||||
if(!CryptEccGetParameter(&p, 'p', parms->curveID))
|
||||
if(!TpmMath_IntTo2B(ExtEcc_CurveGetPrime(parms->curveID), &p.b, 0))
|
||||
return TPM_RCS_KEY + RC_Commit_signHandle;
|
||||
|
||||
// Get the random value that will be used in the point multiplications
|
||||
|
||||
@ -116,7 +116,6 @@
|
||||
#include "CryptHash_fp.h"
|
||||
#include "CryptSym_fp.h"
|
||||
#include "CryptDes_fp.h"
|
||||
#include "TpmToTpmBigNumMath.h" // libtpms: temp
|
||||
#include "CryptPrime_fp.h"
|
||||
#include "CryptRand_fp.h"
|
||||
#include "CryptSelfTest_fp.h"
|
||||
@ -147,6 +146,4 @@
|
||||
// TODO_RENAME_INC_FOLDER:platform_interface refers to the TPM_CoreLib platform interface
|
||||
#include "tpm_to_platform_interface.h"
|
||||
|
||||
#include "TpmMath_Util_fp.h" // libtpms: temporary
|
||||
|
||||
#endif
|
||||
|
||||
@ -179,6 +179,13 @@ LIB_EXPORT BOOL ExtMath_SubtractWord(
|
||||
// Modular Arithmetic, writ large
|
||||
// ###############################
|
||||
|
||||
//** ExtMath_Mod()
|
||||
// compute valueAndResult = valueAndResult mod modulus
|
||||
// This function divides two Crypt_Int* values and returns only the remainder,
|
||||
// replacing the original dividend. The function returns FALSE if there is an
|
||||
// error in the operation.
|
||||
LIB_EXPORT BOOL ExtMath_Mod(Crypt_Int* valueAndResult, const Crypt_Int* modulus);
|
||||
|
||||
//** ExtMath_ModMult()
|
||||
// Compute result = (op1 * op2) mod modulus
|
||||
LIB_EXPORT BOOL ExtMath_ModMult(Crypt_Int* result,
|
||||
@ -202,6 +209,17 @@ LIB_EXPORT BOOL ExtMath_ModExp(Crypt_Int* result,
|
||||
LIB_EXPORT BOOL ExtMath_ModInverse(
|
||||
Crypt_Int* result, const Crypt_Int* number, const Crypt_Int* modulus);
|
||||
|
||||
//** ExtMath_ModInversePrime()
|
||||
// Compute the modular multiplicative inverse. This is an optimized function for
|
||||
// the case where the modulus is known to be prime.
|
||||
//
|
||||
// CAUTION: Depending on the library implementation this may be much faster than
|
||||
// the normal ModInverse, and therefore is subject to exposing the fact the
|
||||
// modulus is prime via a timing side-channel. In many cases (e.g. ECC primes),
|
||||
// the prime is not sensitive and this optimized route can be used.
|
||||
LIB_EXPORT BOOL ExtMath_ModInversePrime(
|
||||
Crypt_Int* result, const Crypt_Int* number, const Crypt_Int* primeModulus);
|
||||
|
||||
//*** ExtMath_ModWord()
|
||||
// compute numerator
|
||||
// This function does modular division of a big number when the modulus is a
|
||||
@ -270,6 +288,17 @@ LIB_EXPORT unsigned ExtMath_SizeInBits(const Crypt_Int* n);
|
||||
// Bitwise Operations
|
||||
// ###############################
|
||||
|
||||
//*** ExtMath_SetBit()
|
||||
//
|
||||
// This function will SET a bit in a Crypt_Int*. Bit 0 is the least-significant
|
||||
// bit in the 0th digit_t. The function returns TRUE if the bitNum is within the
|
||||
// range valid for the given number. If bitNum is too large, the function
|
||||
// should return FALSE, and the TPM will enter failure mode.
|
||||
// Return Type: BOOL
|
||||
LIB_EXPORT BOOL ExtMath_SetBit(Crypt_Int* bn, // IN/OUT: big number to modify
|
||||
unsigned int bitNum // IN: Bit number to SET
|
||||
);
|
||||
|
||||
//*** ExtMath_TestBit()
|
||||
// This function is used to check to see if a bit is SET in a bignum_t. The 0th bit
|
||||
// is the LSb of d[0].
|
||||
@ -280,10 +309,125 @@ LIB_EXPORT BOOL ExtMath_TestBit(Crypt_Int* bn, // IN: number to check
|
||||
unsigned int bitNum // IN: bit to test
|
||||
);
|
||||
|
||||
//***ExtMath_MaskBits()
|
||||
// This function is used to mask off high order bits of a big number.
|
||||
// The returned value will have no more than 'maskBit' bits
|
||||
// set.
|
||||
// Note: There is a requirement that unused words of a bignum_t are set to zero.
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) result masked
|
||||
// FALSE(0) the input was not as large as the mask
|
||||
LIB_EXPORT BOOL ExtMath_MaskBits(
|
||||
Crypt_Int* bn, // IN/OUT: number to mask
|
||||
crypt_uword_t maskBit // IN: the bit number for the mask.
|
||||
);
|
||||
|
||||
//*** ExtMath_ShiftRight()
|
||||
// This function will shift a Crypt_Int* to the right by the shiftAmount.
|
||||
// This function always returns TRUE.
|
||||
LIB_EXPORT BOOL ExtMath_ShiftRight(
|
||||
Crypt_Int* result, const Crypt_Int* toShift, uint32_t shiftAmount);
|
||||
|
||||
// ***************************************************************************
|
||||
// ECC Functions
|
||||
// ***************************************************************************
|
||||
// #################
|
||||
// type initializers
|
||||
// #################
|
||||
|
||||
//** initialize point structure given memory size of each coordinate
|
||||
LIB_EXPORT Crypt_Point* ExtEcc_Initialize_Point(Crypt_Point* buffer,
|
||||
NUMBYTES bitsPerCoord);
|
||||
|
||||
//** ExtEcc_CurveInitialize()
|
||||
// This function is used to initialize a Crypt_EccCurve structure. The
|
||||
// structure is a set of pointers to Crypt_Int* values. The curve-dependent values are
|
||||
// set by a different function. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT const Crypt_EccCurve* ExtEcc_CurveInitialize(Crypt_EccCurve* E,
|
||||
TPM_ECC_CURVE curveId);
|
||||
|
||||
// #################
|
||||
// DESTRUCTOR - See Warning
|
||||
// #################
|
||||
|
||||
//*** ExtEcc_CurveFree()
|
||||
// This function will free the allocated components of the curve and end the
|
||||
// frame in which the curve data exists.
|
||||
// WARNING: Not guaranteed to be called in presence of LONGJMP.
|
||||
LIB_EXPORT void ExtEcc_CurveFree(const Crypt_EccCurve* E);
|
||||
|
||||
// #################
|
||||
// Buffer Converters
|
||||
// #################
|
||||
//** point structure to/from raw coordinate buffers.
|
||||
LIB_EXPORT Crypt_Point* ExtEcc_PointFromBytes(Crypt_Point* buffer,
|
||||
const BYTE* x,
|
||||
NUMBYTES nBytesX,
|
||||
const BYTE* y,
|
||||
NUMBYTES nBytesY);
|
||||
|
||||
LIB_EXPORT BOOL ExtEcc_PointToBytes(
|
||||
const Crypt_Point* point, BYTE* x, NUMBYTES* nBytesX, BYTE* y, NUMBYTES* nBytesY);
|
||||
|
||||
// ####################
|
||||
// ECC Point Operations
|
||||
// ####################
|
||||
|
||||
//** ExtEcc_PointMultiply()
|
||||
// This function does a point multiply of the form R = [d]S. A return of FALSE
|
||||
// indicates that the result was the point at infinity. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL ExtEcc_PointMultiply(Crypt_Point* R,
|
||||
const Crypt_Point* S,
|
||||
const Crypt_Int* d,
|
||||
const Crypt_EccCurve* E);
|
||||
|
||||
//** ExtEcc_PointMultiplyAndAdd()
|
||||
// This function does a point multiply of the form R = [d]S + [u]Q. A return of
|
||||
// FALSE indicates that the result was the point at infinity. This function is only
|
||||
// needed if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL ExtEcc_PointMultiplyAndAdd(Crypt_Point* R,
|
||||
const Crypt_Point* S,
|
||||
const Crypt_Int* d,
|
||||
const Crypt_Point* Q,
|
||||
const Crypt_Int* u,
|
||||
const Crypt_EccCurve* E);
|
||||
|
||||
//** ExtEcc_PointAdd()
|
||||
// This function does a point add R = S + Q. A return of FALSE
|
||||
// indicates that the result was the point at infinity. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL ExtEcc_PointAdd(Crypt_Point* R,
|
||||
const Crypt_Point* S,
|
||||
const Crypt_Point* Q,
|
||||
const Crypt_EccCurve* E);
|
||||
|
||||
// #####################
|
||||
// ECC Point Information
|
||||
// #####################
|
||||
LIB_EXPORT BOOL ExtEcc_IsPointOnCurve(const Crypt_Point* Q, const Crypt_EccCurve* E);
|
||||
LIB_EXPORT BOOL ExtEcc_IsInfinityPoint(const Crypt_Point* pt);
|
||||
// extract the X-Coordinate of a point
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_PointX(const Crypt_Point* pt);
|
||||
|
||||
// extract the Y-Coordinate of a point
|
||||
// (no current use case for the Y coordinate alone, signatures use X)
|
||||
// LIB_EXPORT const Crypt_Int* ExtEcc_PointY(const Crypt_Point* pt);
|
||||
|
||||
// #####################
|
||||
// ECC Curve Information
|
||||
// #####################
|
||||
// These functions are expected to be fast, returning pre-built constants without
|
||||
// allocation or copying.
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetPrime(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetOrder(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetCofactor(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGet_a(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGet_b(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Point* ExtEcc_CurveGetG(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetGx(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetGy(TPM_ECC_CURVE curveId);
|
||||
LIB_EXPORT TPM_ECC_CURVE ExtEcc_CurveGetCurveId(const Crypt_EccCurve* E);
|
||||
|
||||
#endif
|
||||
|
||||
@ -70,12 +70,20 @@
|
||||
#ifndef CRYPT_INT_BUF
|
||||
# error CRYPT_INT_BUF must be defined before including this file.
|
||||
#endif
|
||||
#ifndef CRYPT_POINT_BUF
|
||||
# error CRYPT_POINT_BUF must be defined before including this file.
|
||||
#endif
|
||||
#ifndef CRYPT_CURVE_BUF
|
||||
# error CRYPT_CURVE_BUF must be defined before including this file.
|
||||
#endif
|
||||
|
||||
// Crypt_Int underlying types Crypt_Int is an abstract type that is used as a
|
||||
// pointer. The underlying math library is expected to be able to find the
|
||||
// actual allocated size for a given Crypt_Int object given a pointer to it, and
|
||||
// therefore we typedef here to a size 1 (smallest possible).
|
||||
typedef CRYPT_INT_BUF(one, 1) Crypt_Int;
|
||||
typedef CRYPT_POINT_BUF(pointone, 1) Crypt_Point;
|
||||
typedef CRYPT_CURVE_BUF(curvebuft, MAX_ECC_KEY_BITS) Crypt_EccCurve;
|
||||
|
||||
// produces bare typedef ci_<typename>_t
|
||||
#define CRYPT_INT_TYPE(typename, bits) \
|
||||
@ -106,5 +114,32 @@ typedef CRYPT_INT_BUF(one, 1) Crypt_Int;
|
||||
// A single RADIX_BITS value.
|
||||
#define CRYPT_INT_WORD(name) CRYPT_INT_VAR(name, RADIX_BITS)
|
||||
|
||||
#define CRYPT_INT_WORD_INITIALIZED(varname, initializer) \
|
||||
CRYPT_INT_BUF(cibuf##varname, RADIX_BITS) varname##_buf; \
|
||||
Crypt_Int* varname = ExtMath_SetWord( \
|
||||
ExtMath_Initialize_Int((Crypt_Int*)&(varname##_buf), RADIX_BITS), \
|
||||
initializer);
|
||||
|
||||
// Crypt_EccCurve underlying types
|
||||
#define CRYPT_CURVE_INITIALIZED(varname, initializer) \
|
||||
CRYPT_CURVE_BUF(cv##varname, MAX_ECC_KEY_BITS) varname##_buf; \
|
||||
const Crypt_EccCurve* varname = \
|
||||
ExtEcc_CurveInitialize(&(varname##_buf), initializer)
|
||||
|
||||
/* no guarantee free will be called in the presence of longjmp */
|
||||
#define CRYPT_CURVE_FREE(varname) ExtEcc_CurveFree(varname)
|
||||
|
||||
#define CRYPT_POINT_VAR(varname) \
|
||||
CRYPT_POINT_BUF(cp_##varname##_buf_t, MAX_ECC_KEY_BITS) varname##_buf; \
|
||||
Crypt_Point* varname = \
|
||||
ExtEcc_Initialize_Point((Crypt_Point*)&(varname##_buf), MAX_ECC_KEY_BITS);
|
||||
|
||||
|
||||
#define CRYPT_POINT_INITIALIZED(varname, initValue) \
|
||||
CRYPT_POINT_BUF(cp_##varname##_buf_t, MAX_ECC_KEY_BITS) varname##_buf; \
|
||||
Crypt_Point* varname = TpmEcc_PointFrom2B( \
|
||||
ExtEcc_Initialize_Point((Crypt_Point*)&(varname##_buf), MAX_ECC_KEY_BITS), \
|
||||
initValue);
|
||||
|
||||
#endif //MATH_LIBRARY_INTERFACE_TYPES_H
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@ LIB_EXPORT BOOL ExtMath_Divide(Crypt_Int* quotient,
|
||||
(bigNum)quotient, (bigNum)remainder, (bigConst)dividend, (bigConst)divisor);
|
||||
}
|
||||
|
||||
#if ALG_RSA && !RSA_KEY_SIEVE
|
||||
#if ALG_RSA && !RSA_KEY_SIEVE // libtpms: changed
|
||||
//** ExtMath_GCD()
|
||||
// Get the greatest common divisor of two numbers. This function is only needed
|
||||
// when the TPM implements RSA.
|
||||
@ -200,6 +200,10 @@ LIB_EXPORT BOOL ExtMath_SubtractWord(
|
||||
// Modular Arithmetic, writ large
|
||||
// ###############################
|
||||
// define Mod in terms of Divide
|
||||
LIB_EXPORT BOOL ExtMath_Mod(Crypt_Int* valueAndResult, const Crypt_Int* modulus)
|
||||
{
|
||||
return ExtMath_Divide(NULL, valueAndResult, valueAndResult, modulus);
|
||||
}
|
||||
|
||||
//** ExtMath_ModMult()
|
||||
// Does 'op1' * 'op2' and divide by 'modulus' returning the remainder of the divide.
|
||||
@ -313,6 +317,11 @@ LIB_EXPORT unsigned ExtMath_SizeInBits(const Crypt_Int* n)
|
||||
// Bitwise Operations
|
||||
// ###############################
|
||||
|
||||
LIB_EXPORT BOOL ExtMath_SetBit(Crypt_Int* bn, unsigned int bitNum)
|
||||
{
|
||||
return BnSetBit((bigNum)bn, bitNum);
|
||||
}
|
||||
|
||||
// This function is used to check to see if a bit is SET in a bigNum_t. The 0th bit
|
||||
//*** ExtMath_TestBit()
|
||||
// is the LSb of d[0].
|
||||
@ -326,6 +335,22 @@ LIB_EXPORT BOOL ExtMath_TestBit(Crypt_Int* bn, // IN: number to check
|
||||
return BnTestBit((bigNum)bn, bitNum);
|
||||
}
|
||||
|
||||
//***ExtMath_MaskBits()
|
||||
// This function is used to mask off high order bits of a big number.
|
||||
// The returned value will have no more than 'maskBit' bits
|
||||
// set.
|
||||
// Note: There is a requirement that unused words of a bigNum_t are set to zero.
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) result masked
|
||||
// FALSE(0) the input was not as large as the mask
|
||||
LIB_EXPORT BOOL ExtMath_MaskBits(
|
||||
Crypt_Int* bn, // IN/OUT: number to mask
|
||||
crypt_uword_t maskBit // IN: the bit number for the mask.
|
||||
)
|
||||
{
|
||||
return BnMaskBits((bigNum)bn, maskBit);
|
||||
}
|
||||
|
||||
//*** ExtMath_ShiftRight()
|
||||
// This function will shift a Crypt_Int* to the right by the shiftAmount.
|
||||
// This function always returns TRUE.
|
||||
@ -335,3 +360,172 @@ LIB_EXPORT BOOL ExtMath_ShiftRight(
|
||||
return BnShiftRight((bigNum)result, (bigConst)toShift, shiftAmount);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// ECC Functions
|
||||
// ***************************************************************************
|
||||
// ##################
|
||||
// Point initializers
|
||||
// ##################
|
||||
LIB_EXPORT Crypt_Point* ExtEcc_Initialize_Point(Crypt_Point* point, NUMBYTES bitCount)
|
||||
{
|
||||
// Since we define the structure, we know that BN_POINT_BUFs are a bn_point_t followed by bignums.
|
||||
// and that the size is always the MAX_ECC_KEY_SIZE
|
||||
// tell the individual bignums how large they are:
|
||||
bn_fullpoint_t* pBuf = (bn_fullpoint_t*)point;
|
||||
BnInit((bigNum) & (pBuf->x), BN_STRUCT_ALLOCATION(bitCount));
|
||||
BnInit((bigNum) & (pBuf->y), BN_STRUCT_ALLOCATION(bitCount));
|
||||
BnInit((bigNum) & (pBuf->z), BN_STRUCT_ALLOCATION(bitCount));
|
||||
|
||||
// now feed the addresses of those coordinates to the bn_point_t structure
|
||||
bn_point_t* bnPoint = (bn_point_t*)point;
|
||||
BnInitializePoint(
|
||||
bnPoint, (bigNum) & (pBuf->x), (bigNum) & (pBuf->y), (bigNum) & (pBuf->z));
|
||||
return point;
|
||||
}
|
||||
|
||||
// ##################
|
||||
// Curve initializers
|
||||
// ##################
|
||||
LIB_EXPORT const Crypt_EccCurve* ExtEcc_CurveInitialize(Crypt_EccCurve* E,
|
||||
TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return BnCurveInitialize((bigCurveData*)E, curveId);
|
||||
}
|
||||
|
||||
// #################
|
||||
// Curve DESTRUCTOR
|
||||
// #################
|
||||
// WARNING: Not guaranteed to be called in presence of LONGJMP.
|
||||
LIB_EXPORT void ExtEcc_CurveFree(const Crypt_EccCurve* E)
|
||||
{
|
||||
BnCurveFree((bigCurveData*)E);
|
||||
}
|
||||
|
||||
// #################
|
||||
// Buffer Converters
|
||||
// #################
|
||||
//*** BnPointFromBytes()
|
||||
// Function to create a BIG_POINT structure from a 2B point.
|
||||
// A point is going to be two ECC values in the same buffer. The values are going
|
||||
// to be the size of the modulus. They are in modular form.
|
||||
LIB_EXPORT Crypt_Point* ExtEcc_PointFromBytes(Crypt_Point* point,
|
||||
const BYTE* x,
|
||||
NUMBYTES nBytesX,
|
||||
const BYTE* y,
|
||||
NUMBYTES nBytesY)
|
||||
{
|
||||
return (Crypt_Point*)BnPointFromBytes((bigPoint)point, x, nBytesX, y, nBytesY);
|
||||
}
|
||||
|
||||
LIB_EXPORT BOOL ExtEcc_PointToBytes(const Crypt_Point* point,
|
||||
BYTE* x, NUMBYTES* pBytesX,
|
||||
BYTE* y, NUMBYTES* pBytesY)
|
||||
{
|
||||
return BnPointToBytes((pointConst)point, x, pBytesX, y, pBytesY);
|
||||
}
|
||||
|
||||
// ####################
|
||||
// ECC Point Operations
|
||||
// ####################
|
||||
//** ExtEcc_PointMultiply()
|
||||
// This function does a point multiply of the form R = [d]S. A return of FALSE
|
||||
// indicates that the result was the point at infinity. This function is only needed
|
||||
// if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL ExtEcc_PointMultiply(
|
||||
Crypt_Point* R, const Crypt_Point* S, const Crypt_Int* d, const Crypt_EccCurve* E)
|
||||
{
|
||||
return BnEccModMult((bigPoint)R, (pointConst)S, (bigConst)d, (bigCurveData*)E);
|
||||
}
|
||||
|
||||
//** ExtEcc_PointMultiplyAndAdd()
|
||||
// This function does a point multiply of the form R = [d]S + [u]Q. A return of
|
||||
// FALSE indicates that the result was the point at infinity. This function is only
|
||||
// needed if the TPM supports ECC.
|
||||
LIB_EXPORT BOOL ExtEcc_PointMultiplyAndAdd(Crypt_Point* R,
|
||||
const Crypt_Point* S,
|
||||
const Crypt_Int* d,
|
||||
const Crypt_Point* Q,
|
||||
const Crypt_Int* u,
|
||||
const Crypt_EccCurve* E)
|
||||
{
|
||||
return BnEccModMult2((bigPoint)R,
|
||||
(pointConst)S,
|
||||
(bigConst)d,
|
||||
(pointConst)Q,
|
||||
(bigConst)u,
|
||||
(bigCurveData*)E);
|
||||
}
|
||||
|
||||
LIB_EXPORT BOOL ExtEcc_PointAdd(Crypt_Point* R,
|
||||
const Crypt_Point* S,
|
||||
const Crypt_Point* Q,
|
||||
const Crypt_EccCurve* E)
|
||||
{
|
||||
return BnEccAdd((bigPoint)R, (pointConst)S, (pointConst)Q, (bigCurveData*)E);
|
||||
}
|
||||
|
||||
// #####################
|
||||
// ECC Point Information
|
||||
// #####################
|
||||
LIB_EXPORT BOOL ExtEcc_IsPointOnCurve(const Crypt_Point* Q, const Crypt_EccCurve* E)
|
||||
{
|
||||
return BnIsPointOnCurve((pointConst)Q, AccessCurveConstants(E));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_PointX(const Crypt_Point* point)
|
||||
{
|
||||
return (const Crypt_Int*)(((pointConst)point)->x);
|
||||
}
|
||||
|
||||
LIB_EXPORT BOOL ExtEcc_IsInfinityPoint(const Crypt_Point* point)
|
||||
{
|
||||
return BnEqualZero(((pointConst)point)->z);
|
||||
}
|
||||
|
||||
// #####################
|
||||
// ECC Curve Information
|
||||
// #####################
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetPrime(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGetPrime(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetOrder(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGetOrder(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetCofactor(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGetCofactor(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGet_a(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGet_a(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGet_b(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGet_b(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Point* ExtEcc_CurveGetG(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Point*)BnCurveGetG(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetGx(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGetGx(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT const Crypt_Int* ExtEcc_CurveGetGy(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
return (const Crypt_Int*)BnCurveGetGy(BnGetCurveData(curveId));
|
||||
}
|
||||
|
||||
LIB_EXPORT TPM_ECC_CURVE ExtEcc_CurveGetCurveId(const Crypt_EccCurve* E)
|
||||
{
|
||||
return BnCurveGetCurveId(AccessCurveConstants(E));
|
||||
}
|
||||
|
||||
@ -104,12 +104,6 @@
|
||||
# define DEBUG YES // Default: Either YES or NO
|
||||
#endif
|
||||
|
||||
// This definition is required for the re-factored code
|
||||
#if (!defined USE_BN_ECC_DATA) || ((USE_BN_ECC_DATA != NO) && (USE_BN_ECC_DATA != YES))
|
||||
# undef USE_BN_ECC_DATA
|
||||
# define USE_BN_ECC_DATA YES // Default: Either YES or NO
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// DEBUG OPTIONS
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -61,44 +61,47 @@
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Signature_ECDAA_fp.h"
|
||||
#include "TpmEcc_Signature_Util_fp.h"
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#if ALG_ECC && ALG_ECDAA
|
||||
|
||||
/* 10.2.12.3.2 BnSignEcdaa() */
|
||||
/* This function performs s = r + T * d mod q where */
|
||||
/* a) 'r is a random, or pseudo-random value created in the commit phase */
|
||||
/* b) nonceK is a TPM-generated, random value 0 < nonceK < n */
|
||||
/* c) T is mod q of Hash(nonceK || digest), and */
|
||||
/* d) d is a private key. */
|
||||
/* The signature is the tuple (nonceK, s) */
|
||||
/* Regrettably, the parameters in this function kind of collide with the parameter names used in
|
||||
ECSCHNORR making for a lot of confusion. In particular, the k value in this function is value in
|
||||
this function u */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SCHEME unsupported hash algorithm */
|
||||
/* TPM_RC_NO_RESULT cannot get values from random number generator */
|
||||
TPM_RC
|
||||
BnSignEcdaa(
|
||||
TPM2B_ECC_PARAMETER *nonceK, // OUT: nonce component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the private key
|
||||
const TPM2B_DIGEST *digest, // IN: the value to sign (mod q)
|
||||
TPMT_ECC_SCHEME *scheme, // IN: signing scheme (contains the
|
||||
// commit count value).
|
||||
OBJECT *eccKey, // IN: The signing key
|
||||
RAND_STATE *rand // IN: a random number state
|
||||
)
|
||||
//*** TpmEcc_SignEcdaa()
|
||||
//
|
||||
// This function performs 's' = 'r' + 'T' * 'd' mod 'q' where
|
||||
// 1) 'r' is a random, or pseudo-random value created in the commit phase
|
||||
// 2) 'nonceK' is a TPM-generated, random value 0 < 'nonceK' < 'n'
|
||||
// 3) 'T' is mod 'q' of "Hash"('nonceK' || 'digest'), and
|
||||
// 4) 'd' is a private key.
|
||||
//
|
||||
// The signature is the tuple ('nonceK', 's')
|
||||
//
|
||||
// Regrettably, the parameters in this function kind of collide with the parameter
|
||||
// names used in ECSCHNORR making for a lot of confusion.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SCHEME unsupported hash algorithm
|
||||
// TPM_RC_NO_RESULT cannot get values from random number generator
|
||||
TPM_RC TpmEcc_SignEcdaa(
|
||||
TPM2B_ECC_PARAMETER* nonceK, // OUT: 'nonce' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the private key
|
||||
const TPM2B_DIGEST* digest, // IN: the value to sign (mod 'q')
|
||||
TPMT_ECC_SCHEME* scheme, // IN: signing scheme (contains the
|
||||
// commit count value).
|
||||
OBJECT* eccKey, // IN: The signing key
|
||||
RAND_STATE* rand // IN: a random number state
|
||||
)
|
||||
{
|
||||
TPM_RC retVal;
|
||||
TPM2B_ECC_PARAMETER r;
|
||||
HASH_STATE state;
|
||||
TPM2B_DIGEST T;
|
||||
BN_MAX(bnT);
|
||||
TPM_RC retVal;
|
||||
TPM2B_ECC_PARAMETER r;
|
||||
HASH_STATE state;
|
||||
TPM2B_DIGEST T;
|
||||
CRYPT_INT_MAX(bnT);
|
||||
//
|
||||
NOT_REFERENCED(rand);
|
||||
if(!CryptGenerateR(&r, &scheme->details.ecdaa.count,
|
||||
if(!CryptGenerateR(&r,
|
||||
&scheme->details.ecdaa.count,
|
||||
eccKey->publicArea.parameters.eccDetail.curveID,
|
||||
&eccKey->name))
|
||||
retVal = TPM_RC_VALUE;
|
||||
@ -106,21 +109,22 @@ BnSignEcdaa(
|
||||
{
|
||||
// This allocation is here because 'r' doesn't have a value until
|
||||
// CrypGenerateR() is done.
|
||||
ECC_INITIALIZED(bnR, &r);
|
||||
CRYPT_ECC_INITIALIZED(bnR, &r);
|
||||
do
|
||||
{
|
||||
// generate nonceK such that 0 < nonceK < n
|
||||
// use bnT as a temp.
|
||||
#if USE_OPENSSL_FUNCTIONS_EC // libtpms added begin
|
||||
if(!BnEccGetPrivate(bnT, AccessCurveData(E), E->G, false, rand))
|
||||
if(!TpmEcc_GenPrivateScalar(bnT, E, E->G, false, rand))
|
||||
#else // libtpms added end
|
||||
if(!BnEccGetPrivate(bnT, AccessCurveData(E), rand))
|
||||
if(!TpmEcc_GenPrivateScalar(bnT, E, rand))
|
||||
#endif // libtpms added
|
||||
{
|
||||
retVal = TPM_RC_NO_RESULT;
|
||||
break;
|
||||
}
|
||||
BnTo2B(bnT, &nonceK->b, 0);
|
||||
TpmMath_IntTo2B(bnT, &nonceK->b, 0);
|
||||
|
||||
T.t.size = CryptHashStart(&state, scheme->details.ecdaa.hashAlg);
|
||||
if(T.t.size == 0)
|
||||
{
|
||||
@ -131,11 +135,15 @@ BnSignEcdaa(
|
||||
CryptDigestUpdate2B(&state, &nonceK->b);
|
||||
CryptDigestUpdate2B(&state, &digest->b);
|
||||
CryptHashEnd2B(&state, &T.b);
|
||||
BnFrom2B(bnT, &T.b);
|
||||
TpmMath_IntFrom2B(bnT, &T.b);
|
||||
// libtpms: Note: T is NOT a concern for constant-timeness
|
||||
// Watch out for the name collisions in this call!!
|
||||
retVal = BnSchnorrSign(bnS, bnR, bnT, bnD,
|
||||
AccessCurveData(E)->order);
|
||||
retVal = TpmEcc_SchnorrCalculateS(
|
||||
bnS,
|
||||
bnR,
|
||||
bnT,
|
||||
bnD,
|
||||
ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E)));
|
||||
}
|
||||
} while(retVal == TPM_RC_NO_RESULT);
|
||||
// Because the rule is that internal state is not modified if the command
|
||||
|
||||
@ -62,18 +62,32 @@
|
||||
#define _TPMECC_SIGNATURE_ECDAA_FP_H_
|
||||
#if ALG_ECC && ALG_ECDAA
|
||||
|
||||
TPM_RC
|
||||
BnSignEcdaa(
|
||||
TPM2B_ECC_PARAMETER *nonceK, // OUT: nonce component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the private key
|
||||
const TPM2B_DIGEST *digest, // IN: the value to sign (mod q)
|
||||
TPMT_ECC_SCHEME *scheme, // IN: signing scheme (contains the
|
||||
// commit count value).
|
||||
OBJECT *eccKey, // IN: The signing key
|
||||
RAND_STATE *rand // IN: a random number state
|
||||
);
|
||||
//*** TpmEcc_SignEcdaa()
|
||||
//
|
||||
// This function performs 's' = 'r' + 'T' * 'd' mod 'q' where
|
||||
// 1) 'r' is a random, or pseudo-random value created in the commit phase
|
||||
// 2) 'nonceK' is a TPM-generated, random value 0 < 'nonceK' < 'n'
|
||||
// 3) 'T' is mod 'q' of "Hash"('nonceK' || 'digest'), and
|
||||
// 4) 'd' is a private key.
|
||||
//
|
||||
// The signature is the tuple ('nonceK', 's')
|
||||
//
|
||||
// Regrettably, the parameters in this function kind of collide with the parameter
|
||||
// names used in ECSCHNORR making for a lot of confusion.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SCHEME unsupported hash algorithm
|
||||
// TPM_RC_NO_RESULT cannot get values from random number generator
|
||||
TPM_RC TpmEcc_SignEcdaa(
|
||||
TPM2B_ECC_PARAMETER* nonceK, // OUT: 'nonce' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the private key
|
||||
const TPM2B_DIGEST* digest, // IN: the value to sign (mod 'q')
|
||||
TPMT_ECC_SCHEME* scheme, // IN: signing scheme (contains the
|
||||
// commit count value).
|
||||
OBJECT* eccKey, // IN: The signing key
|
||||
RAND_STATE* rand // IN: a random number state
|
||||
);
|
||||
|
||||
#endif // ALG_ECC && ALG_ECDAA
|
||||
#endif // _TPMECC_SIGNATURE_ECDAA_FP_H_
|
||||
|
||||
@ -60,62 +60,63 @@
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Signature_ECDSA_fp.h"
|
||||
#include "TpmToOsslMath_fp.h" // libtpms added
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "BnToOsslMath_fp.h"
|
||||
|
||||
#if ALG_ECC && ALG_ECDSA
|
||||
/* 10.2.12.2 Utility Functions */
|
||||
/* 10.2.12.2.1 EcdsaDigest() */
|
||||
/* Function to adjust the digest so that it is no larger than the order of the curve. This is used
|
||||
for ECDSA sign and verification. */
|
||||
//*** TpmEcc_AdjustEcdsaDigest()
|
||||
// Function to adjust the digest so that it is no larger than the order of the
|
||||
// curve. This is used for ECDSA sign and verification.
|
||||
#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
|
||||
static bigNum
|
||||
EcdsaDigest(
|
||||
bigNum bnD, // OUT: the adjusted digest
|
||||
const TPM2B_DIGEST *digest, // IN: digest to adjust
|
||||
bigConst max // IN: value that indicates the maximum
|
||||
// number of bits in the results
|
||||
)
|
||||
static Crypt_Int* TpmEcc_AdjustEcdsaDigest(
|
||||
Crypt_Int* bnD, // OUT: the adjusted digest
|
||||
const TPM2B_DIGEST* digest, // IN: digest to adjust
|
||||
const Crypt_Int* max // IN: value that indicates the maximum
|
||||
// number of bits in the results
|
||||
)
|
||||
{
|
||||
int bitsInMax = BnSizeInBits(max);
|
||||
int shift;
|
||||
int bitsInMax = ExtMath_SizeInBits(max);
|
||||
int shift;
|
||||
//
|
||||
if(digest == NULL)
|
||||
BnSetWord(bnD, 0);
|
||||
ExtMath_SetWord(bnD, 0);
|
||||
else
|
||||
{
|
||||
BnFromBytes(bnD, digest->t.buffer,
|
||||
(NUMBYTES)MIN(digest->t.size, BITS_TO_BYTES(bitsInMax)));
|
||||
shift = BnSizeInBits(bnD) - bitsInMax;
|
||||
ExtMath_IntFromBytes(bnD,
|
||||
digest->t.buffer,
|
||||
(NUMBYTES)MIN(digest->t.size, BITS_TO_BYTES(bitsInMax)));
|
||||
shift = ExtMath_SizeInBits(bnD) - bitsInMax;
|
||||
if(shift > 0)
|
||||
BnShiftRight(bnD, bnD, shift);
|
||||
ExtMath_ShiftRight(bnD, bnD, shift);
|
||||
}
|
||||
return bnD;
|
||||
}
|
||||
#endif // libtpms added
|
||||
|
||||
/* 10.2.12.3.1 BnSignEcdsa() */
|
||||
/* This function implements the ECDSA signing algorithm. The method is described in the comments
|
||||
below. This version works with internal numbers. */
|
||||
//*** TpmEcc_SignEcdsa()
|
||||
// This function implements the ECDSA signing algorithm. The method is described
|
||||
// in the comments below.
|
||||
#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
|
||||
TPM_RC
|
||||
BnSignEcdsa(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigNum bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
RAND_STATE *rand // IN: used in debug of signing
|
||||
)
|
||||
TpmEcc_SignEcdsa(Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Int* bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
RAND_STATE* rand // IN: used in debug of signing
|
||||
)
|
||||
{
|
||||
ECC_NUM(bnK);
|
||||
ECC_NUM(bnIk);
|
||||
BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
|
||||
POINT(ecR);
|
||||
bigConst order = CurveGetOrder(AccessCurveData(E));
|
||||
TPM_RC retVal = TPM_RC_SUCCESS;
|
||||
INT32 tries = 10;
|
||||
BOOL OK = FALSE;
|
||||
CRYPT_ECC_NUM(bnK);
|
||||
CRYPT_ECC_NUM(bnIk);
|
||||
CRYPT_INT_VAR(bnE, MAX_ECC_KEY_BITS);
|
||||
CRYPT_POINT_VAR(ecR);
|
||||
CRYPT_ECC_NUM(bnX);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
TPM_RC retVal = TPM_RC_SUCCESS;
|
||||
INT32 tries = 10;
|
||||
BOOL OK = FALSE;
|
||||
//
|
||||
pAssert(digest != NULL);
|
||||
// The algorithm as described in "Suite B Implementer's Guide to FIPS
|
||||
@ -132,63 +133,68 @@ BnSignEcdsa(
|
||||
// 6. Compute s = (k^-1 * (e + d * r)) mod q. If s = 0, return to Step 1.2.
|
||||
// 7. Return (r, s).
|
||||
// In the code below, q is n (that it, the order of the curve is p)
|
||||
do // This implements the loop at step 6. If s is zero, start over.
|
||||
|
||||
do // This implements the loop at step 6. If s is zero, start over.
|
||||
{
|
||||
for(; tries > 0; tries--)
|
||||
{
|
||||
// Step 1 and 2 -- generate an ephemeral key and the modular inverse
|
||||
// of the private key.
|
||||
if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
|
||||
if(!TpmEcc_GenerateKeyPair(bnK, ecR, E, rand))
|
||||
continue;
|
||||
// get mutable copy of X coordinate
|
||||
ExtMath_Copy(bnX, ExtEcc_PointX(ecR));
|
||||
// x coordinate is mod p. Make it mod q
|
||||
BnMod(ecR->x, order);
|
||||
ExtMath_Mod(bnX, order);
|
||||
// Make sure that it is not zero;
|
||||
if(BnEqualZero(ecR->x))
|
||||
if(ExtMath_IsZero(bnX))
|
||||
continue;
|
||||
// write the modular reduced version of r as part of the signature
|
||||
BnCopy(bnR, ecR->x);
|
||||
ExtMath_Copy(bnR, bnX);
|
||||
// Make sure that a modular inverse exists and try again if not
|
||||
OK = (BnModInverse(bnIk, bnK, order));
|
||||
OK = (ExtMath_ModInverse(bnIk, bnK, order));
|
||||
if(OK)
|
||||
break;
|
||||
}
|
||||
if(!OK)
|
||||
goto Exit;
|
||||
EcdsaDigest(bnE, digest, order);
|
||||
|
||||
TpmEcc_AdjustEcdsaDigest(bnE, digest, order);
|
||||
|
||||
// now have inverse of K (bnIk), e (bnE), r (bnR), d (bnD) and
|
||||
// CurveGetOrder(E)
|
||||
// ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E))
|
||||
// Compute s = k^-1 (e + r*d)(mod q)
|
||||
// first do s = r*d mod q
|
||||
BnModMult(bnS, bnR, bnD, order);
|
||||
ExtMath_ModMult(bnS, bnR, bnD, order);
|
||||
// s = e + s = e + r * d
|
||||
BnAdd(bnS, bnE, bnS);
|
||||
ExtMath_Add(bnS, bnE, bnS);
|
||||
// s = k^(-1)s (mod n) = k^(-1)(e + r * d)(mod n)
|
||||
BnModMult(bnS, bnIk, bnS, order);
|
||||
ExtMath_ModMult(bnS, bnIk, bnS, order);
|
||||
|
||||
// If S is zero, try again
|
||||
} while(BnEqualZero(bnS));
|
||||
} while(ExtMath_IsZero(bnS));
|
||||
Exit:
|
||||
return retVal;
|
||||
}
|
||||
#else // !USE_OPENSSL_FUNCTIONS_ECDSA libtpms added begin
|
||||
TPM_RC
|
||||
BnSignEcdsa(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigNum bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
RAND_STATE *rand // IN: used in debug of signing
|
||||
)
|
||||
TpmEcc_SignEcdsa(Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Int* bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
RAND_STATE* rand // IN: used in debug of signing
|
||||
)
|
||||
{
|
||||
ECDSA_SIG *sig = NULL;
|
||||
EC_KEY *eckey;
|
||||
int retVal;
|
||||
const BIGNUM *r;
|
||||
const BIGNUM *s;
|
||||
BIGNUM *d = BN_new();
|
||||
ECDSA_SIG* sig = NULL;
|
||||
EC_KEY* eckey;
|
||||
int retVal;
|
||||
const BIGNUM* r;
|
||||
const BIGNUM* s;
|
||||
BIGNUM* d = BN_new();
|
||||
|
||||
d = BigInitialized(d, bnD);
|
||||
d = BigInitialized(d, (bigConst)bnD);
|
||||
|
||||
eckey = EC_KEY_new();
|
||||
|
||||
@ -206,8 +212,8 @@ BnSignEcdsa(
|
||||
ERROR_EXIT(TPM_RC_FAILURE);
|
||||
|
||||
ECDSA_SIG_get0(sig, &r, &s);
|
||||
OsslToTpmBn(bnR, r);
|
||||
OsslToTpmBn(bnS, s);
|
||||
OsslToTpmBn((bigNum)bnR, r);
|
||||
OsslToTpmBn((bigNum)bnS, s);
|
||||
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
|
||||
@ -220,33 +226,35 @@ BnSignEcdsa(
|
||||
}
|
||||
#endif // USE_OPENSSL_FUNCTIONS_ECDSA libtpms added end
|
||||
|
||||
/* 10.2.12.3.7 BnValidateSignatureEcdsa() */
|
||||
/* This function validates an ECDSA signature. rIn and sIn should have been checked to make sure
|
||||
that they are in the range 0 < v < n */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SIGNATURE signature not valid */
|
||||
//*** TpmEcc_ValidateSignatureEcdsa()
|
||||
// This function validates an ECDSA signature. rIn and sIn should have been checked
|
||||
// to make sure that they are in the range 0 < 'v' < 'n'
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
#if !USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added
|
||||
TPM_RC
|
||||
BnValidateSignatureEcdsa(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bn_point_t *ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
)
|
||||
TpmEcc_ValidateSignatureEcdsa(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
const Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
)
|
||||
{
|
||||
// Make sure that the allocation for the digest is big enough for a maximum
|
||||
// digest
|
||||
BN_VAR(bnE, MAX(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE) * 8);
|
||||
POINT(ecR);
|
||||
ECC_NUM(bnU1);
|
||||
ECC_NUM(bnU2);
|
||||
ECC_NUM(bnW);
|
||||
bigConst order = CurveGetOrder(AccessCurveData(E));
|
||||
TPM_RC retVal = TPM_RC_SIGNATURE;
|
||||
CRYPT_INT_VAR(bnE, MAX_ECC_KEY_BITS);
|
||||
CRYPT_POINT_VAR(ecR);
|
||||
CRYPT_ECC_NUM(bnU1);
|
||||
CRYPT_ECC_NUM(bnU2);
|
||||
CRYPT_ECC_NUM(bnW);
|
||||
CRYPT_ECC_NUM(bnV);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
TPM_RC retVal = TPM_RC_SIGNATURE;
|
||||
//
|
||||
// Get adjusted digest
|
||||
EcdsaDigest(bnE, digest, order);
|
||||
TpmEcc_AdjustEcdsaDigest(bnE, digest, order);
|
||||
// 1. If r and s are not both integers in the interval [1, n - 1], output
|
||||
// INVALID.
|
||||
// bnR and bnS were validated by the caller
|
||||
@ -255,47 +263,50 @@ BnValidateSignatureEcdsa(
|
||||
// 3. Convert the bit string H0 to an integer e as described in Appendix B.2.
|
||||
// Done at entry
|
||||
// 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1.
|
||||
if(!BnModInverse(bnW, bnS, order))
|
||||
if(!ExtMath_ModInverse(bnW, bnS, order))
|
||||
goto Exit;
|
||||
// 5. Compute u1 = (e' * w) mod n, and compute u2 = (r' * w) mod n.
|
||||
BnModMult(bnU1, bnE, bnW, order);
|
||||
BnModMult(bnU2, bnR, bnW, order);
|
||||
ExtMath_ModMult(bnU1, bnE, bnW, order);
|
||||
ExtMath_ModMult(bnU2, bnR, bnW, order);
|
||||
// 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC
|
||||
// scalar multiplication and EC addition (see [Routines]). If R is equal to
|
||||
// the point at infinity O, output INVALID.
|
||||
if(BnPointMult(ecR, CurveGetG(AccessCurveData(E)), bnU1, ecQ, bnU2, E)
|
||||
if(TpmEcc_PointMult(
|
||||
ecR, ExtEcc_CurveGetG(ExtEcc_CurveGetCurveId(E)), bnU1, ecQ, bnU2, E)
|
||||
!= TPM_RC_SUCCESS)
|
||||
goto Exit;
|
||||
// 7. Compute v = Rx mod n.
|
||||
BnMod(ecR->x, order);
|
||||
ExtMath_Copy(bnV, ExtEcc_PointX(ecR));
|
||||
ExtMath_Mod(bnV, order);
|
||||
// 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID
|
||||
if(BnUnsignedCmp(ecR->x, bnR) != 0)
|
||||
if(ExtMath_UnsignedCmp(bnV, bnR) != 0)
|
||||
goto Exit;
|
||||
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
Exit:
|
||||
return retVal;
|
||||
}
|
||||
#else // USE_OPENSSL_FUNCTIONS_ECDSA libtpms added begin
|
||||
TPM_RC
|
||||
BnValidateSignatureEcdsa(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bn_point_t *ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
)
|
||||
TpmEcc_ValidateSignatureEcdsa(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
const Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
)
|
||||
{
|
||||
int retVal;
|
||||
int rc;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
EC_KEY *eckey = NULL;
|
||||
BIGNUM *r = BN_new();
|
||||
BIGNUM *s = BN_new();
|
||||
EC_POINT *q = EcPointInitialized(ecQ, E);
|
||||
int retVal;
|
||||
int rc;
|
||||
ECDSA_SIG* sig = NULL;
|
||||
EC_KEY* eckey = NULL;
|
||||
BIGNUM* r = BN_new();
|
||||
BIGNUM* s = BN_new();
|
||||
EC_POINT* q = EcPointInitialized((bn_point_t*)ecQ, E);
|
||||
|
||||
r = BigInitialized(r, bnR);
|
||||
s = BigInitialized(s, bnS);
|
||||
r = BigInitialized(r, (bigConst)bnR);
|
||||
s = BigInitialized(s, (bigConst)bnS);
|
||||
|
||||
sig = ECDSA_SIG_new();
|
||||
eckey = EC_KEY_new();
|
||||
|
||||
@ -62,28 +62,33 @@
|
||||
#define _TPMECC_SIGNATURE_ECDSA_FP_H_
|
||||
#if ALG_ECC && ALG_ECDSA
|
||||
|
||||
//*** TpmEcc_SignEcdsa()
|
||||
// This function implements the ECDSA signing algorithm. The method is described
|
||||
// in the comments below.
|
||||
TPM_RC
|
||||
BnSignEcdsa(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigNum bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
RAND_STATE *rand // IN: used in debug of signing
|
||||
);
|
||||
|
||||
TpmEcc_SignEcdsa(Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Int* bnD, // IN: private signing key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
RAND_STATE* rand // IN: used in debug of signing
|
||||
);
|
||||
|
||||
//*** TpmEcc_ValidateSignatureEcdsa()
|
||||
// This function validates an ECDSA signature. rIn and sIn should have been checked
|
||||
// to make sure that they are in the range 0 < 'v' < 'n'
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
TPM_RC
|
||||
BnValidateSignatureEcdsa(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bn_point_t *ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
);
|
||||
|
||||
TpmEcc_ValidateSignatureEcdsa(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
const Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
);
|
||||
|
||||
#endif // ALG_ECC && ALG_ECDSA
|
||||
#endif // _TPMECC_SIGNATURE_ECDSA_FP_H_
|
||||
|
||||
@ -60,65 +60,51 @@
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Signature_SM2_fp.h"
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#if ALG_ECC && ALG_SM2
|
||||
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
/* 10.2.12.3.5 BnHexEqual() */
|
||||
/* This function compares a bignum value to a hex string. */
|
||||
/* Return Value Meaning */
|
||||
/* TRUE(1) values equal */
|
||||
/* FALSE(0) values not equal */
|
||||
static BOOL
|
||||
BnHexEqual(
|
||||
bigNum bn, //IN: big number value
|
||||
const char *c //IN: character string number
|
||||
)
|
||||
//*** TpmEcc_SignEcSm2()
|
||||
// This function signs a digest using the method defined in SM2 Part 2. The method
|
||||
// in the standard will add a header to the message to be signed that is a hash of
|
||||
// the values that define the key. This then hashed with the message to produce a
|
||||
// digest ('e'). This function signs 'e'.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_VALUE bad curve
|
||||
TPM_RC TpmEcc_SignEcSm2(Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the private key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
RAND_STATE* rand // IN: random number generator (mostly for
|
||||
// debug)
|
||||
)
|
||||
{
|
||||
ECC_NUM(bnC);
|
||||
BnFromHex(bnC, c);
|
||||
return (BnUnsignedCmp(bn, bnC) == 0);
|
||||
}
|
||||
#endif // _SM2_SIGN_DEBUG
|
||||
/* 10.2.12.3.5 BnSignEcSm2() */
|
||||
/* This function signs a digest using the method defined in SM2 Part 2. The method in the standard
|
||||
will add a header to the message to be signed that is a hash of the values that define the
|
||||
key. This then hashed with the message to produce a digest (e) that is signed. This function
|
||||
signs e. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_VALUE bad curve */
|
||||
TPM_RC
|
||||
BnSignEcSm2(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the private key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
RAND_STATE *rand // IN: random number generator (mostly for
|
||||
// debug)
|
||||
)
|
||||
{
|
||||
BN_MAX_INITIALIZED(bnE, digest); // Don't know how big digest might be
|
||||
ECC_NUM(bnN);
|
||||
ECC_NUM(bnK);
|
||||
ECC_NUM(bnT); // temp
|
||||
POINT(Q1);
|
||||
bigConst order = (E != NULL)
|
||||
? CurveGetOrder(AccessCurveData(E)) : NULL;
|
||||
CRYPT_INT_MAX_INITIALIZED(bnE, digest); // Don't know how big digest might be
|
||||
CRYPT_ECC_NUM(bnN);
|
||||
CRYPT_ECC_NUM(bnK);
|
||||
CRYPT_ECC_NUM(bnT); // temp
|
||||
CRYPT_POINT_VAR(Q1);
|
||||
const Crypt_Int* order =
|
||||
(E != NULL) ? ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E)) : NULL;
|
||||
// libtpms added begin
|
||||
UINT32 orderBits = BnSizeInBits(order);
|
||||
UINT32 orderBits = ExtMath_SizeInBits(order);
|
||||
BOOL atByteBoundary = (orderBits & 7) == 0;
|
||||
ECC_NUM(bnK1);
|
||||
CRYPT_ECC_NUM(bnK1);
|
||||
// libtpms added end
|
||||
|
||||
//
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
BnFromHex(bnE, "B524F552CD82B8B028476E005C377FB1"
|
||||
"9A87E6FC682D48BB5D42E3D9B9EFFE76");
|
||||
BnFromHex(bnD, "128B2FA8BD433C6C068C8D803DFF7979"
|
||||
"2A519A55171B1B650C23661D15897263");
|
||||
#endif
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
TpmEccDebug_FromHex(bnE,
|
||||
"B524F552CD82B8B028476E005C377FB1"
|
||||
"9A87E6FC682D48BB5D42E3D9B9EFFE76",
|
||||
MAX_ECC_KEY_BYTES);
|
||||
TpmEccDebug_FromHex(bnD,
|
||||
"128B2FA8BD433C6C068C8D803DFF7979"
|
||||
"2A519A55171B1B650C23661D15897263",
|
||||
MAX_ECC_KEY_BYTES);
|
||||
# endif
|
||||
// A3: Use random number generator to generate random number 1 <= k <= n-1;
|
||||
// NOTE: Ax: numbers are from the SM2 standard
|
||||
loop:
|
||||
@ -134,129 +120,140 @@ BnSignEcSm2(
|
||||
// byte boundary we require that the random number bnK comes back with
|
||||
// a requested number of bytes.
|
||||
if (!atByteBoundary) {
|
||||
BnGenerateRandomInRange(bnK, order, rand);
|
||||
BnAdd(bnK1, bnK, order);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
BnFromHex(bnK1, "6CB28D99385C175C94F94E934817663F"
|
||||
"C176D925DD72B727260DBAAE1FB2F96F");
|
||||
#endif
|
||||
BnGenerateRandomInRange((bigNum)bnK, (bigConst)order, rand);
|
||||
ExtMath_Add(bnK1, bnK, order);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
TpmEccDebug_FromHex(bnK,
|
||||
"6CB28D99385C175C94F94E934817663F"
|
||||
"C176D925DD72B727260DBAAE1FB2F96F",
|
||||
MAX_ECC_KEY_BYTES);
|
||||
# endif
|
||||
// A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according
|
||||
// to details specified in 4.2.7 in Part 1 of this document, transform the
|
||||
// data type of x1 into an integer;
|
||||
if(!BnEccModMult(Q1, NULL, bnK1, E))
|
||||
if(!ExtEcc_PointMultiply(Q1, NULL, bnK1, E))
|
||||
goto loop;
|
||||
} else {
|
||||
BnGenerateRandomInRangeAllBytes(bnK, order, rand);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
BnFromHex(bnK, "6CB28D99385C175C94F94E934817663F"
|
||||
"C176D925DD72B727260DBAAE1FB2F96F");
|
||||
#endif
|
||||
if(!BnEccModMult(Q1, NULL, bnK, E))
|
||||
BnGenerateRandomInRangeAllBytes((bigNum)bnK, (bigNum)order, rand);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
TpmEccDebug_FromHex(bnK,
|
||||
"6CB28D99385C175C94F94E934817663F"
|
||||
"C176D925DD72B727260DBAAE1FB2F96F",
|
||||
MAX_ECC_KEY_BYTES);
|
||||
# endif
|
||||
if(!ExtEcc_PointMultiply(Q1, NULL, bnK, E))
|
||||
goto loop;
|
||||
} // libtpms modified end
|
||||
// A5: Figure out r = (e + x1) mod n,
|
||||
BnAdd(bnR, bnE, Q1->x);
|
||||
BnMod(bnR, order);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
#endif
|
||||
// A5: Figure out 'r' = ('e' + 'x1') mod 'n',
|
||||
ExtMath_Add(bnR, bnE, ExtEcc_PointX(Q1));
|
||||
ExtMath_Mod(bnR, order);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(TpmEccDebug_HexEqual(bnR,
|
||||
"40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
# endif
|
||||
// if r=0 or r+k=n, return to A3;
|
||||
if(BnEqualZero(bnR))
|
||||
if(ExtMath_IsZero(bnR))
|
||||
goto loop;
|
||||
BnAdd(bnT, bnK, bnR);
|
||||
if(BnUnsignedCmp(bnT, bnN) == 0)
|
||||
ExtMath_Add(bnT, bnK, bnR);
|
||||
if(ExtMath_UnsignedCmp(bnT, bnN) == 0)
|
||||
goto loop;
|
||||
// A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n,
|
||||
// if s=0, return to A3;
|
||||
// compute t = (1+dA)^-1
|
||||
BnAddWord(bnT, bnD, 1);
|
||||
BnModInverse(bnT, bnT, order);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(BnHexEqual(bnT, "79BFCF3052C80DA7B939E0C6914A18CB"
|
||||
"B2D96D8555256E83122743A7D4F5F956"));
|
||||
#endif
|
||||
ExtMath_AddWord(bnT, bnD, 1);
|
||||
ExtMath_ModInverse(bnT, bnT, order);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(TpmEccDebug_HexEqual(bnT,
|
||||
"79BFCF3052C80DA7B939E0C6914A18CB"
|
||||
"B2D96D8555256E83122743A7D4F5F956"));
|
||||
# endif
|
||||
// compute s = t * (k - r * dA) mod n
|
||||
BnModMult(bnS, bnR, bnD, order);
|
||||
ExtMath_ModMult(bnS, bnR, bnD, order);
|
||||
// k - r * dA mod n = k + n - ((r * dA) mod n)
|
||||
BnSub(bnS, order, bnS);
|
||||
BnAdd(bnS, bnK, bnS);
|
||||
BnModMult(bnS, bnS, bnT, order);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
#endif
|
||||
if(BnEqualZero(bnS))
|
||||
ExtMath_Subtract(bnS, order, bnS);
|
||||
ExtMath_Add(bnS, bnK, bnS);
|
||||
ExtMath_ModMult(bnS, bnS, bnT, order);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(TpmEccDebug_HexEqual(bnS,
|
||||
"6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
# endif
|
||||
if(ExtMath_IsZero(bnS))
|
||||
goto loop;
|
||||
}
|
||||
// A7: According to details specified in 4.2.1 in Part 1 of this document,
|
||||
// transform the data type of r, s into bit strings, signature of message M
|
||||
// is (r, s).
|
||||
// This is handled by the common return code
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(BnHexEqual(bnR, "40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
pAssert(BnHexEqual(bnS, "6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
#endif
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(TpmEccDebug_HexEqual(bnR,
|
||||
"40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
pAssert(TpmEccDebug_HexEqual(bnS,
|
||||
"6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
# endif
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
/* 10.2.12.3.8 BnValidateSignatureEcSm2() */
|
||||
/* This function is used to validate an SM2 signature. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SIGNATURE signature not valid */
|
||||
TPM_RC
|
||||
BnValidateSignatureEcSm2(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigPoint ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
)
|
||||
//*** TpmEcc_ValidateSignatureEcSm2()
|
||||
// This function is used to validate an SM2 signature.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
TPM_RC TpmEcc_ValidateSignatureEcSm2(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
)
|
||||
{
|
||||
POINT(P);
|
||||
ECC_NUM(bnRp);
|
||||
ECC_NUM(bnT);
|
||||
BN_MAX_INITIALIZED(bnE, digest);
|
||||
BOOL OK;
|
||||
bigConst order = CurveGetOrder(AccessCurveData(E));
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
CRYPT_POINT_VAR(P);
|
||||
CRYPT_ECC_NUM(bnRp);
|
||||
CRYPT_ECC_NUM(bnT);
|
||||
CRYPT_INT_MAX_INITIALIZED(bnE, digest);
|
||||
BOOL OK;
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
// Make sure that the input signature is the test signature
|
||||
pAssert(BnHexEqual(bnR,
|
||||
"40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
pAssert(BnHexEqual(bnS,
|
||||
"6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
#endif
|
||||
pAssert(TpmEccDebug_HexEqual(bnR,
|
||||
"40F1EC59F793D9F49E09DCEF49130D41"
|
||||
"94F79FB1EED2CAA55BACDB49C4E755D1"));
|
||||
pAssert(TpmEccDebug_HexEqual(bnS,
|
||||
"6FC6DAC32C5D5CF10C77DFB20F7C2EB6"
|
||||
"67A457872FB09EC56327A67EC7DEEBE7"));
|
||||
# endif
|
||||
// b) compute t := (r + s) mod n
|
||||
BnAdd(bnT, bnR, bnS);
|
||||
BnMod(bnT, order);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(BnHexEqual(bnT,
|
||||
"2B75F07ED7ECE7CCC1C8986B991F441A"
|
||||
"D324D6D619FE06DD63ED32E0C997C801"));
|
||||
#endif
|
||||
ExtMath_Add(bnT, bnR, bnS);
|
||||
ExtMath_Mod(bnT, order);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(TpmEccDebug_HexEqual(bnT,
|
||||
"2B75F07ED7ECE7CCC1C8986B991F441A"
|
||||
"D324D6D619FE06DD63ED32E0C997C801"));
|
||||
# endif
|
||||
// c) verify that t > 0
|
||||
OK = !BnEqualZero(bnT);
|
||||
OK = !ExtMath_IsZero(bnT);
|
||||
if(!OK)
|
||||
// set T to a value that should allow rest of the computations to run
|
||||
// without trouble
|
||||
BnCopy(bnT, bnS);
|
||||
ExtMath_Copy(bnT, bnS);
|
||||
// d) compute (x, y) := [s]G + [t]Q
|
||||
OK = BnEccModMult2(P, NULL, bnS, ecQ, bnT, E);
|
||||
#ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(OK && BnHexEqual(P->x,
|
||||
"110FCDA57615705D5E7B9324AC4B856D"
|
||||
"23E6D9188B2AE47759514657CE25D112"));
|
||||
#endif
|
||||
OK = ExtEcc_PointMultiplyAndAdd(P, NULL, bnS, ecQ, bnT, E);
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
pAssert(OK
|
||||
&& TpmEccDebug_HexEqual(ExtEcc_PointX(P),
|
||||
"110FCDA57615705D5E7B9324AC4B856D"
|
||||
"23E6D9188B2AE47759514657CE25D112"));
|
||||
# endif
|
||||
// e) compute r' := (e + x) mod n (the x coordinate is in bnT)
|
||||
OK = OK && BnAdd(bnRp, bnE, P->x);
|
||||
OK = OK && BnMod(bnRp, order);
|
||||
OK = OK && ExtMath_Add(bnRp, bnE, ExtEcc_PointX(P));
|
||||
OK = OK && ExtMath_Mod(bnRp, order);
|
||||
|
||||
// f) verify that r' = r
|
||||
OK = OK && (BnUnsignedCmp(bnR, bnRp) == 0);
|
||||
OK = OK && (ExtMath_UnsignedCmp(bnR, bnRp) == 0);
|
||||
|
||||
if(!OK)
|
||||
return TPM_RC_SIGNATURE;
|
||||
|
||||
@ -62,26 +62,34 @@
|
||||
#define _TPMECC_SIGNATURE_SM2_FP_H_
|
||||
|
||||
#if ALG_ECC && ALG_SM2
|
||||
TPM_RC
|
||||
BnSignEcSm2(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the private key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
RAND_STATE *rand // IN: random number generator (mostly for
|
||||
// debug)
|
||||
);
|
||||
//*** TpmEcc_SignEcSm2()
|
||||
// This function signs a digest using the method defined in SM2 Part 2. The method
|
||||
// in the standard will add a header to the message to be signed that is a hash of
|
||||
// the values that define the key. This then hashed with the message to produce a
|
||||
// digest ('e'). This function signs 'e'.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_VALUE bad curve
|
||||
TPM_RC TpmEcc_SignEcSm2(Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the private key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
RAND_STATE* rand // IN: random number generator (mostly for
|
||||
// debug)
|
||||
);
|
||||
|
||||
TPM_RC
|
||||
BnValidateSignatureEcSm2(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigPoint ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
);
|
||||
//*** TpmEcc_ValidateSignatureEcSm2()
|
||||
// This function is used to validate an SM2 signature.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
TPM_RC TpmEcc_ValidateSignatureEcSm2(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
);
|
||||
|
||||
#endif // ALG_ECC && ALG_SM2
|
||||
#endif // _TPMECC_SIGNATURE_SM2_FP_H_
|
||||
|
||||
@ -61,80 +61,84 @@
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Signature_Schnorr_fp.h"
|
||||
#include "TpmEcc_Signature_Util_fp.h"
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#if ALG_ECC && ALG_ECSCHNORR
|
||||
|
||||
/* 10.2.12.3.3 SchnorrReduce() */
|
||||
/* Function to reduce a hash result if it's magnitude is to large. The size of number is set so that
|
||||
it has no more bytes of significance than the reference value. If the resulting number can have
|
||||
more bits of significance than the reference. */
|
||||
static void
|
||||
SchnorrReduce(
|
||||
TPM2B *number, // IN/OUT: Value to reduce
|
||||
bigConst reference // IN: the reference value
|
||||
)
|
||||
//*** SchnorrReduce()
|
||||
// Function to reduce a hash result if it's magnitude is too large. The size of
|
||||
// 'number' is set so that it has no more bytes of significance than 'reference'
|
||||
// value. If the resulting number can have more bits of significance than
|
||||
// 'reference'.
|
||||
static void SchnorrReduce(TPM2B* number, // IN/OUT: Value to reduce
|
||||
const Crypt_Int* reference // IN: the reference value
|
||||
)
|
||||
{
|
||||
UINT16 maxBytes = (UINT16)BITS_TO_BYTES(BnSizeInBits(reference));
|
||||
UINT16 maxBytes = (UINT16)BITS_TO_BYTES(ExtMath_SizeInBits(reference));
|
||||
if(number->size > maxBytes)
|
||||
number->size = maxBytes;
|
||||
}
|
||||
/* 10.2.12.3.4 SchnorrEcc() */
|
||||
/* This function is used to perform a modified Schnorr signature. */
|
||||
/* This function will generate a random value k and compute */
|
||||
/* a) (xR, yR) = [k]G */
|
||||
/* b) r = hash(xR || P)(mod q) */
|
||||
/* c) rT = truncated r */
|
||||
/* d) s= k + rT * ds (mod q) */
|
||||
/* e) return the tuple rT, s */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_NO_RESULT failure in the Schnorr sign process */
|
||||
/* TPM_RC_SCHEME hashAlg can't produce zero-length digest */
|
||||
TPM_RC
|
||||
BnSignEcSchnorr(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the signing key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
TPM_ALG_ID hashAlg, // IN: signing scheme (contains a hash)
|
||||
RAND_STATE *rand // IN: non-NULL when testing
|
||||
)
|
||||
|
||||
//*** SchnorrEcc()
|
||||
// This function is used to perform a modified Schnorr signature.
|
||||
//
|
||||
// This function will generate a random value 'k' and compute
|
||||
// a) ('xR', 'yR') = ['k']'G'
|
||||
// b) 'r' = "Hash"('xR' || 'P')(mod 'q')
|
||||
// c) 'rT' = truncated 'r'
|
||||
// d) 's'= 'k' + 'rT' * 'ds' (mod 'q')
|
||||
// e) return the tuple 'rT', 's'
|
||||
//
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_NO_RESULT failure in the Schnorr sign process
|
||||
// TPM_RC_SCHEME hashAlg can't produce zero-length digest
|
||||
TPM_RC TpmEcc_SignEcSchnorr(
|
||||
Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the signing key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
TPM_ALG_ID hashAlg, // IN: signing scheme (contains a hash)
|
||||
RAND_STATE* rand // IN: non-NULL when testing
|
||||
)
|
||||
{
|
||||
HASH_STATE hashState;
|
||||
UINT16 digestSize
|
||||
= CryptHashGetDigestSize(hashAlg);
|
||||
HASH_STATE hashState;
|
||||
UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_KEY_BYTES));
|
||||
TPM2B_T T2b;
|
||||
TPM2B *e = &T2b.b;
|
||||
TPM_RC retVal = TPM_RC_NO_RESULT;
|
||||
const ECC_CURVE_DATA *C;
|
||||
bigConst order;
|
||||
bigConst prime;
|
||||
ECC_NUM(bnK);
|
||||
POINT(ecR);
|
||||
TPM2B_T T2b;
|
||||
TPM2B* e = &T2b.b;
|
||||
TPM_RC retVal = TPM_RC_NO_RESULT;
|
||||
const Crypt_Int* order;
|
||||
const Crypt_Int* prime;
|
||||
CRYPT_ECC_NUM(bnK);
|
||||
CRYPT_POINT_VAR(ecR);
|
||||
//
|
||||
// Parameter checks
|
||||
if(E == NULL)
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
C = AccessCurveData(E);
|
||||
order = CurveGetOrder(C);
|
||||
prime = CurveGetOrder(C);
|
||||
|
||||
order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
prime = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
|
||||
// If the digest does not produce a hash, then null the signature and return
|
||||
// a failure.
|
||||
if(digestSize == 0)
|
||||
{
|
||||
BnSetWord(bnR, 0);
|
||||
BnSetWord(bnS, 0);
|
||||
ExtMath_SetWord(bnR, 0);
|
||||
ExtMath_SetWord(bnS, 0);
|
||||
ERROR_EXIT(TPM_RC_SCHEME);
|
||||
}
|
||||
do
|
||||
{
|
||||
// Generate a random key pair
|
||||
if(!BnEccGenerateKeyPair(bnK, ecR, E, rand))
|
||||
if(!TpmEcc_GenerateKeyPair(bnK, ecR, E, rand))
|
||||
break;
|
||||
// Convert R.x to a string
|
||||
BnTo2B(ecR->x, e, (NUMBYTES)BITS_TO_BYTES(BnSizeInBits(prime)));
|
||||
TpmMath_IntTo2B(ExtEcc_PointX(ecR),
|
||||
e,
|
||||
(NUMBYTES)BITS_TO_BYTES(ExtMath_SizeInBits(prime)));
|
||||
|
||||
// f) compute r = Hash(e || P) (mod n)
|
||||
CryptHashStart(&hashState, hashAlg);
|
||||
CryptDigestUpdate2B(&hashState, e);
|
||||
@ -143,52 +147,55 @@ BnSignEcSchnorr(
|
||||
// Reduce the hash size if it is larger than the curve order
|
||||
SchnorrReduce(e, order);
|
||||
// Convert hash to number
|
||||
BnFrom2B(bnR, e);
|
||||
TpmMath_IntFrom2B(bnR, e);
|
||||
// libtpms: Note: e is NOT a concern for constant-timeness
|
||||
// Do the Schnorr computation
|
||||
retVal = BnSchnorrSign(bnS, bnK, bnR, bnD, CurveGetOrder(C));
|
||||
retVal = TpmEcc_SchnorrCalculateS(
|
||||
bnS, bnK, bnR, bnD, ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E)));
|
||||
} while(retVal == TPM_RC_NO_RESULT);
|
||||
Exit:
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/* 10.2.12.3.9 BnValidateSignatureEcSchnorr() */
|
||||
/* This function is used to validate an EC Schnorr signature. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SIGNATURE signature not valid */
|
||||
TPM_RC
|
||||
BnValidateSignatureEcSchnorr(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigPoint ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
)
|
||||
//*** TpmEcc_ValidateSignatureEcSchnorr()
|
||||
// This function is used to validate an EC Schnorr signature.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
TPM_RC TpmEcc_ValidateSignatureEcSchnorr(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
)
|
||||
{
|
||||
BN_MAX(bnRn);
|
||||
POINT(ecE);
|
||||
BN_MAX(bnEx);
|
||||
const ECC_CURVE_DATA *C = AccessCurveData(E);
|
||||
bigConst order = CurveGetOrder(C);
|
||||
UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
HASH_STATE hashState;
|
||||
CRYPT_INT_MAX(bnRn);
|
||||
CRYPT_POINT_VAR(ecE);
|
||||
CRYPT_INT_MAX(bnEx);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
HASH_STATE hashState;
|
||||
TPM2B_TYPE(BUFFER, MAX(MAX_ECC_PARAMETER_BYTES, MAX_DIGEST_SIZE));
|
||||
TPM2B_BUFFER Ex2 = {{sizeof(Ex2.t.buffer),{ 0 }}};
|
||||
BOOL OK;
|
||||
TPM2B_BUFFER Ex2 = {{sizeof(Ex2.t.buffer), {0}}};
|
||||
BOOL OK;
|
||||
//
|
||||
// E = [s]G - [r]Q
|
||||
BnMod(bnR, order);
|
||||
ExtMath_Mod(bnR, order);
|
||||
// Make -r = n - r
|
||||
BnSub(bnRn, order, bnR);
|
||||
ExtMath_Subtract(bnRn, order, bnR);
|
||||
// E = [s]G + [-r]Q
|
||||
OK = BnPointMult(ecE, CurveGetG(C), bnS, ecQ, bnRn, E) == TPM_RC_SUCCESS;
|
||||
OK = TpmEcc_PointMult(
|
||||
ecE, ExtEcc_CurveGetG(ExtEcc_CurveGetCurveId(E)), bnS, ecQ, bnRn, E)
|
||||
== TPM_RC_SUCCESS;
|
||||
// // reduce the x portion of E mod q
|
||||
// OK = OK && BnMod(ecE->x, order);
|
||||
// OK = OK && ExtMath_Mod(ecE->x, order);
|
||||
// Convert to byte string
|
||||
OK = OK && BnTo2B(ecE->x, &Ex2.b,
|
||||
(NUMBYTES)(BITS_TO_BYTES(BnSizeInBits(order))));
|
||||
OK = OK
|
||||
&& TpmMath_IntTo2B(ExtEcc_PointX(ecE),
|
||||
&Ex2.b,
|
||||
(NUMBYTES)(BITS_TO_BYTES(ExtMath_SizeInBits(order))));
|
||||
if(OK)
|
||||
{
|
||||
// Ex = h(pE.x || digest)
|
||||
@ -197,9 +204,9 @@ BnValidateSignatureEcSchnorr(
|
||||
CryptDigestUpdate(&hashState, digest->t.size, digest->t.buffer);
|
||||
Ex2.t.size = CryptHashEnd(&hashState, digestSize, Ex2.t.buffer);
|
||||
SchnorrReduce(&Ex2.b, order);
|
||||
BnFrom2B(bnEx, &Ex2.b);
|
||||
TpmMath_IntFrom2B(bnEx, &Ex2.b);
|
||||
// see if Ex matches R
|
||||
OK = BnUnsignedCmp(bnEx, bnR) == 0;
|
||||
OK = ExtMath_UnsignedCmp(bnEx, bnR) == 0;
|
||||
}
|
||||
return (OK) ? TPM_RC_SUCCESS : TPM_RC_SIGNATURE;
|
||||
}
|
||||
|
||||
@ -62,28 +62,29 @@
|
||||
#define _TPMECC_SIGNATURE_SCHNORR_FP_H_
|
||||
|
||||
#if ALG_ECC && ALG_ECSCHNORR
|
||||
TPM_RC TpmEcc_SignEcSchnorr(
|
||||
Crypt_Int* bnR, // OUT: 'r' component of the signature
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in signing
|
||||
Crypt_Int* bnD, // IN: the signing key
|
||||
const TPM2B_DIGEST* digest, // IN: the digest to sign
|
||||
TPM_ALG_ID hashAlg, // IN: signing scheme (contains a hash)
|
||||
RAND_STATE* rand // IN: non-NULL when testing
|
||||
);
|
||||
|
||||
TPM_RC
|
||||
BnSignEcSchnorr(
|
||||
bigNum bnR, // OUT: r component of the signature
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigCurve E, // IN: the curve used in signing
|
||||
bigNum bnD, // IN: the signing key
|
||||
const TPM2B_DIGEST *digest, // IN: the digest to sign
|
||||
TPM_ALG_ID hashAlg, // IN: signing scheme (contains a hash)
|
||||
RAND_STATE *rand // IN: non-NULL when testing
|
||||
);
|
||||
|
||||
TPM_RC
|
||||
BnValidateSignatureEcSchnorr(
|
||||
bigNum bnR, // IN: r component of the signature
|
||||
bigNum bnS, // IN: s component of the signature
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
|
||||
bigCurve E, // IN: the curve used in the signature
|
||||
// process
|
||||
bigPoint ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST *digest // IN: the digest that was signed
|
||||
);
|
||||
//*** TpmEcc_ValidateSignatureEcSchnorr()
|
||||
// This function is used to validate an EC Schnorr signature.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SIGNATURE signature not valid
|
||||
TPM_RC TpmEcc_ValidateSignatureEcSchnorr(
|
||||
Crypt_Int* bnR, // IN: 'r' component of the signature
|
||||
Crypt_Int* bnS, // IN: 's' component of the signature
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature
|
||||
const Crypt_EccCurve* E, // IN: the curve used in the signature
|
||||
// process
|
||||
Crypt_Point* ecQ, // IN: the public point of the key
|
||||
const TPM2B_DIGEST* digest // IN: the digest that was signed
|
||||
);
|
||||
|
||||
#endif // ALG_ECC && ALG_ECSCHNORR
|
||||
#endif // _TPMECC_SIGNATURE_SCHNORR_FP_H_
|
||||
|
||||
@ -61,45 +61,47 @@
|
||||
// functions shared by multiple signature algorithms
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Signature_Util_fp.h"
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#if(ALG_ECC && (ALG_ECSCHNORR || ALG_ECDAA))
|
||||
|
||||
/* 10.2.12.2.2 BnSchnorrSign() */
|
||||
/* This contains the Schnorr signature computation. It is used by both ECDSA and Schnorr
|
||||
signing. The result is computed as: [s = k + r * d (mod n)] where */
|
||||
/* a) s is the signature */
|
||||
/* b) k is a random value */
|
||||
/* c) r is the value to sign */
|
||||
/* d) d is the private EC key */
|
||||
/* e) n is the order of the curve */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_NO_RESULT the result of the operation was zero or r (mod n) is zero */
|
||||
TPM_RC
|
||||
BnSchnorrSign(
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigConst bnK, // IN: a random value
|
||||
bigNum bnR, // IN: the signature 'r' value
|
||||
bigConst bnD, // IN: the private key
|
||||
bigConst bnN // IN: the order of the curve
|
||||
)
|
||||
//*** TpmEcc_SchnorrCalculateS()
|
||||
// This contains the Schnorr signature (S) computation. It is used by both ECDAA and
|
||||
// Schnorr signing. The result is computed as: ['s' = 'k' + 'r' * 'd' (mod 'n')]
|
||||
// where
|
||||
// 1) 's' is the signature
|
||||
// 2) 'k' is a random value
|
||||
// 3) 'r' is the value to sign
|
||||
// 4) 'd' is the private EC key
|
||||
// 5) 'n' is the order of the curve
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_NO_RESULT the result of the operation was zero or 'r' (mod 'n')
|
||||
// is zero
|
||||
TPM_RC TpmEcc_SchnorrCalculateS(
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_Int* bnK, // IN: a random value
|
||||
Crypt_Int* bnR, // IN: the signature 'r' value
|
||||
const Crypt_Int* bnD, // IN: the private key
|
||||
const Crypt_Int* bnN // IN: the order of the curve
|
||||
)
|
||||
{
|
||||
// Need a local temp value to store the intermediate computation because product
|
||||
// size can be larger than will fit in bnS.
|
||||
BN_VAR(bnT1, MAX_ECC_PARAMETER_BYTES * 2 * 8);
|
||||
CRYPT_INT_VAR(bnT1, MAX_ECC_PARAMETER_BYTES * 2 * 8);
|
||||
//
|
||||
// Reduce bnR without changing the input value
|
||||
BnDiv(NULL, bnT1, bnR, bnN);
|
||||
if(BnEqualZero(bnT1))
|
||||
ExtMath_Divide(NULL, bnT1, bnR, bnN);
|
||||
if(ExtMath_IsZero(bnT1))
|
||||
return TPM_RC_NO_RESULT;
|
||||
// compute s = (k + r * d)(mod n)
|
||||
// r * d
|
||||
BnMult(bnT1, bnT1, bnD);
|
||||
// k * r * d
|
||||
BnAdd(bnT1, bnT1, bnK);
|
||||
ExtMath_Multiply(bnT1, bnT1, bnD);
|
||||
// k + r * d
|
||||
ExtMath_Add(bnT1, bnT1, bnK);
|
||||
// k + r * d (mod n)
|
||||
BnDiv(NULL, bnS, bnT1, bnN);
|
||||
return (BnEqualZero(bnS)) ? TPM_RC_NO_RESULT : TPM_RC_SUCCESS;
|
||||
ExtMath_Divide(NULL, bnS, bnT1, bnN);
|
||||
return (ExtMath_IsZero(bnS)) ? TPM_RC_NO_RESULT : TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
#endif // (ALG_ECC && (ALG_ECSCHNORR || ALG_ECDAA))
|
||||
|
||||
@ -63,15 +63,25 @@
|
||||
#define _TPMECC_SIGNATURE_UTIL_FP_H_
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
TPM_RC
|
||||
BnSchnorrSign(
|
||||
bigNum bnS, // OUT: s component of the signature
|
||||
bigConst bnK, // IN: a random value
|
||||
bigNum bnR, // IN: the signature 'r' value
|
||||
bigConst bnD, // IN: the private key
|
||||
bigConst bnN // IN: the order of the curve
|
||||
);
|
||||
//*** TpmEcc_SchnorrCalculateS()
|
||||
// This contains the Schnorr signature (S) computation. It is used by both ECDSA and
|
||||
// Schnorr signing. The result is computed as: ['s' = 'k' + 'r' * 'd' (mod 'n')]
|
||||
// where
|
||||
// 1) 's' is the signature
|
||||
// 2) 'k' is a random value
|
||||
// 3) 'r' is the value to sign
|
||||
// 4) 'd' is the private EC key
|
||||
// 5) 'n' is the order of the curve
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_NO_RESULT the result of the operation was zero or 'r' (mod 'n')
|
||||
// is zero
|
||||
TPM_RC TpmEcc_SchnorrCalculateS(
|
||||
Crypt_Int* bnS, // OUT: 's' component of the signature
|
||||
const Crypt_Int* bnK, // IN: a random value
|
||||
Crypt_Int* bnR, // IN: the signature 'r' value
|
||||
const Crypt_Int* bnD, // IN: the private key
|
||||
const Crypt_Int* bnN // IN: the order of the curve
|
||||
);
|
||||
|
||||
#endif // ALG_ECC
|
||||
#endif // _TPMECC_SIGNATURE_UTIL_FP_H_
|
||||
|
||||
123
src/tpm2/TpmEcc_Util.c
Normal file
123
src/tpm2/TpmEcc_Util.c
Normal file
@ -0,0 +1,123 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
//** Introduction
|
||||
// This file contains utility functions to help using the external Math library
|
||||
// for Ecc functions.
|
||||
#include "Tpm.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
//***
|
||||
// TpmEcc_PointFrom2B() Function to create a Crypt_Point structure from a 2B
|
||||
// point. The target point is expected to have memory allocated and
|
||||
// uninitialized. A TPMS_ECC_POINT is going to be two ECC values in the same
|
||||
// buffer. The values are going to be the size of the modulus. They are in
|
||||
// modular form.
|
||||
//
|
||||
// NOTE: This function considers both parameters optional because of use
|
||||
// cases where points may not be specified in the calling function. If the
|
||||
// initializer or point buffer is NULL, then NULL is returned. As a result, the
|
||||
// only error detection when the initializer value is invalid is to return NULL
|
||||
// in that error case as well. If a caller wants to handle that error case
|
||||
// differently, then the caller must perform the correct validation before/after
|
||||
// this function.
|
||||
LIB_EXPORT Crypt_Point* TpmEcc_PointFrom2B(
|
||||
Crypt_Point* ecP, // OUT: the preallocated point structure
|
||||
TPMS_ECC_POINT* p // IN: the number to convert
|
||||
)
|
||||
{
|
||||
if(p == NULL)
|
||||
return NULL;
|
||||
|
||||
if(ecP != NULL)
|
||||
{
|
||||
return ExtEcc_PointFromBytes(
|
||||
ecP, p->x.t.buffer, p->x.t.size, p->y.t.buffer, p->y.t.size);
|
||||
}
|
||||
return ecP; // will return NULL if ecP is NULL.
|
||||
}
|
||||
|
||||
//*** TpmEcc_PointTo2B()
|
||||
// This function converts a BIG_POINT into a TPMS_ECC_POINT. A TPMS_ECC_POINT
|
||||
// contains two TPM2B_ECC_PARAMETER values. The maximum size of the parameters
|
||||
// is dependent on the maximum EC key size used in an implementation.
|
||||
// The presumption is that the TPMS_ECC_POINT is large enough to hold 2 TPM2B
|
||||
// values, each as large as a MAX_ECC_PARAMETER_BYTES
|
||||
LIB_EXPORT BOOL TpmEcc_PointTo2B(
|
||||
TPMS_ECC_POINT* p, // OUT: the converted 2B structure
|
||||
const Crypt_Point* ecP, // IN: the values to be converted
|
||||
const Crypt_EccCurve* E // IN: curve descriptor for the point
|
||||
)
|
||||
{
|
||||
pAssert(p && ecP && E);
|
||||
TPM_ECC_CURVE curveId = ExtEcc_CurveGetCurveId(E);
|
||||
NUMBYTES size = CryptEccGetKeySizeForCurve(curveId);
|
||||
size = (UINT16)BITS_TO_BYTES(size);
|
||||
MemorySet(p, 0, sizeof(*p));
|
||||
p->x.t.size = size;
|
||||
p->y.t.size = size;
|
||||
return ExtEcc_PointToBytes(
|
||||
ecP, p->x.t.buffer, &p->x.t.size, p->y.t.buffer, &p->y.t.size);
|
||||
}
|
||||
|
||||
#endif // ALG_ECC
|
||||
89
src/tpm2/TpmEcc_Util_fp.h
Normal file
89
src/tpm2/TpmEcc_Util_fp.h
Normal file
@ -0,0 +1,89 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
#ifndef _TPMECC_UTIL_FP_H_
|
||||
#define _TPMECC_UTIL_FP_H_
|
||||
|
||||
#if ALG_ECC
|
||||
|
||||
//*** TpmEcc_PointFrom2B()
|
||||
// Function to create a Crypt_Point structure from a 2B point.
|
||||
// This function doesn't take an Crypt_EccCurve for legacy reasons -
|
||||
// this should probably be changed.
|
||||
// returns NULL if the input value is invalid or doesn't fit.
|
||||
LIB_EXPORT Crypt_Point* TpmEcc_PointFrom2B(
|
||||
Crypt_Point* ecP, // OUT: the preallocated point structure
|
||||
TPMS_ECC_POINT* p // IN: the number to convert
|
||||
);
|
||||
|
||||
//*** TpmEcc_PointTo2B()
|
||||
// This function converts a Crypt_Point into a TPMS_ECC_POINT. A TPMS_ECC_POINT
|
||||
// contains two TPM2B_ECC_PARAMETER values. The maximum size of the parameters
|
||||
// is dependent on the maximum EC key size used in an implementation.
|
||||
// The presumption is that the TPMS_ECC_POINT is large enough to hold 2 TPM2B
|
||||
// values, each as large as a MAX_ECC_PARAMETER_BYTES
|
||||
LIB_EXPORT BOOL TpmEcc_PointTo2B(
|
||||
TPMS_ECC_POINT* p, // OUT: the converted 2B structure
|
||||
const Crypt_Point* ecP, // IN: the values to be converted
|
||||
const Crypt_EccCurve* E // IN: curve descriptor for the point
|
||||
);
|
||||
|
||||
#endif // ALG_ECC
|
||||
#endif // _TPMECC_UTIL_FP_H_
|
||||
170
src/tpm2/TpmMath_Debug.c
Normal file
170
src/tpm2/TpmMath_Debug.c
Normal file
@ -0,0 +1,170 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
//** Introduction
|
||||
// This file contains debug utility functions to help testing Ecc.
|
||||
#include "Tpm.h"
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
#include "TpmMath_Debug_fp.h"
|
||||
|
||||
#if ALG_SM2
|
||||
# ifdef _SM2_SIGN_DEBUG
|
||||
|
||||
//*** SafeGetStringLength()
|
||||
// self-implemented version of strnlen_s. This is necessary because
|
||||
// some environments don't have a C-runtime library, or are limited to
|
||||
// C99, and strnlen_s was standardized in C11.
|
||||
static size_t SafeGetStringLength(const char* string, size_t maxsize)
|
||||
{
|
||||
// strnlen_s has two boundary conditions:
|
||||
// return 0 if pointer is nullptr, or
|
||||
// maxsize if no null character is found.
|
||||
if(string == NULL)
|
||||
return 0;
|
||||
|
||||
const char* pos = string;
|
||||
size_t size = 0;
|
||||
|
||||
while(*pos != '\0' && size < maxsize)
|
||||
{
|
||||
pos++;
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
// convert from hex value. If invalid, result will be out of range.
|
||||
static LIB_EXPORT BYTE FromHex(unsigned char c)
|
||||
{
|
||||
// hack for the ASCII characters we care about
|
||||
BYTE upper = (c & (~0x20));
|
||||
if(c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
else if(c >= 'A' && c <= 'F')
|
||||
return c - 'A';
|
||||
|
||||
return 255;
|
||||
}
|
||||
|
||||
//*** TpmEccDebug_FromHex()
|
||||
// Convert a hex string into a Crypt_Int*. This is primarily used in debugging.
|
||||
LIB_EXPORT Crypt_Int* TpmEccDebug_FromHex(
|
||||
Crypt_Int* bn, // OUT:
|
||||
const unsigned char* hex, // IN:
|
||||
size_t maxsizeHex // IN: maximum size of hex
|
||||
)
|
||||
{
|
||||
// if value is larger than this, then fail
|
||||
BYTE tempBuf[MAX_ECC_KEY_BYTES];
|
||||
MemorySet(tempBuf, 0, sizeof(tempBuf));
|
||||
ExtMath_SetWord(bn, 0);
|
||||
|
||||
size_t len = SafeGetStringLength(hex, maxsizeHex);
|
||||
BOOL OK = FALSE;
|
||||
if((len % 2) == 0)
|
||||
{
|
||||
OK = TRUE;
|
||||
for(size_t i = 0; i < len; i += 2)
|
||||
{
|
||||
BYTE highNibble = FromHex(*hex);
|
||||
hex++;
|
||||
BYTE lowNibble = FromHex(*hex);
|
||||
hex++;
|
||||
// unsigned, no need to check zero
|
||||
if(highNibble > 15 || lowNibble > 15)
|
||||
{
|
||||
OK = FALSE;
|
||||
break;
|
||||
}
|
||||
BYTE b = ((highNibble << 4) | lowNibble);
|
||||
tempBuf[i / 2] = b;
|
||||
}
|
||||
if(OK)
|
||||
{
|
||||
ExtMath_IntFromBytes(bn, tempBuf, (NUMBYTES)(len / 2));
|
||||
}
|
||||
}
|
||||
|
||||
if(!OK)
|
||||
{
|
||||
// this should only be called in testing, so any
|
||||
// errors are fatal.
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
}
|
||||
return bn;
|
||||
}
|
||||
|
||||
//*** TpmEccDebug_HexEqual()
|
||||
// This function compares a bignum value to a hex string.
|
||||
// using TpmEcc namespace because code assumes the max size
|
||||
// is correct for ECC.
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) values equal
|
||||
// FALSE(0) values not equal
|
||||
BOOL TpmEccDebug_HexEqual(const Crypt_Int* bn, //IN: big number value
|
||||
const char* c //IN: character string number
|
||||
)
|
||||
{
|
||||
CRYPT_ECC_NUM(bnC);
|
||||
TpmEccDebug_FromHex(bnC, c, MAX_ECC_KEY_BYTES * 2 + 1);
|
||||
return (ExtMath_UnsignedCmp(bn, bnC) == 0);
|
||||
}
|
||||
# endif // _SM2_SIGN_DEBUG
|
||||
#endif // ALG_SM2
|
||||
86
src/tpm2/TpmMath_Debug_fp.h
Normal file
86
src/tpm2/TpmMath_Debug_fp.h
Normal file
@ -0,0 +1,86 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - Redistributions of Source Code must retain the above copyright licenses, */
|
||||
/* this list of conditions and the following disclaimers. */
|
||||
/* */
|
||||
/* - Redistributions in binary form must reproduce the above copyright */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
//
|
||||
// debug and test utilities. Not expected to be compiled into final products
|
||||
#ifndef _TPMMATH_DEBUG_FP_H_
|
||||
#define _TPMMATH_DEBUG_FP_H_
|
||||
|
||||
#if ALG_ECC || ALG_RSA
|
||||
|
||||
//*** TpmEccDebug_HexEqual()
|
||||
// This function compares a bignum value to a hex string.
|
||||
// using TpmEcc namespace because code assumes the max size
|
||||
// is correct for ECC.
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) values equal
|
||||
// FALSE(0) values not equal
|
||||
BOOL TpmMath_Debug_HexEqual(const Crypt_Int* bn, //IN: big number value
|
||||
const char* c //IN: character string number
|
||||
);
|
||||
|
||||
LIB_EXPORT Crypt_Int* TpmMath_Debug_FromHex(
|
||||
Crypt_Int* bn, // OUT:
|
||||
const unsigned char* hex, // IN:
|
||||
size_t maxsizeHex // IN: maximum size of hex
|
||||
);
|
||||
|
||||
#endif // ALG_ECC or ALG_RSA
|
||||
#endif //_TPMMATH_DEBUG_FP_H_
|
||||
@ -97,35 +97,24 @@
|
||||
|
||||
//** Structures
|
||||
|
||||
typedef struct ECC_CURVE
|
||||
{
|
||||
const TPM_ECC_CURVE curveId;
|
||||
const UINT16 keySizeBits;
|
||||
const TPMT_KDF_SCHEME kdf;
|
||||
const TPMT_ECC_SCHEME sign;
|
||||
const ECC_CURVE_DATA *curveData; // the address of the curve data
|
||||
const BYTE *OID;
|
||||
} ECC_CURVE;
|
||||
#define ECC_BITS (MAX_ECC_KEY_BYTES * 8)
|
||||
CRYPT_INT_TYPE(ecc, ECC_BITS);
|
||||
|
||||
#define CRYPT_ECC_NUM(name) CRYPT_INT_VAR(name, ECC_BITS)
|
||||
|
||||
#define CRYPT_ECC_INITIALIZED(name, initializer) \
|
||||
CRYPT_INT_INITIALIZED(name, ECC_BITS, initializer)
|
||||
|
||||
typedef struct TPM_ECC_CURVE_METADATA
|
||||
{
|
||||
const TPM_ECC_CURVE curveId;
|
||||
const UINT16 keySizeBits;
|
||||
const TPMT_KDF_SCHEME kdf;
|
||||
const TPMT_ECC_SCHEME sign;
|
||||
const BYTE* OID;
|
||||
} TPM_ECC_CURVE_METADATA;
|
||||
|
||||
//*** Macros
|
||||
#define CURVE_DATA_DEF(CURVE) \
|
||||
const ECC_CURVE_DATA CURVE = { \
|
||||
(bigNum)&CURVE##_p_DATA, (bigNum)&CURVE##_n_DATA, (bigNum)&CURVE##_h_DATA, \
|
||||
(bigNum)&CURVE##_a_DATA, (bigNum)&CURVE##_b_DATA, \
|
||||
{(bigNum)&CURVE##_gX_DATA, (bigNum)&CURVE##_gY_DATA, (bigNum)&BN_ONE} };
|
||||
|
||||
extern const ECC_CURVE eccCurves[ECC_CURVE_COUNT];
|
||||
|
||||
#define CURVE_DEF(CURVE) \
|
||||
{ \
|
||||
TPM_ECC_##CURVE, \
|
||||
CURVE##_KEY_SIZE, \
|
||||
CURVE##_KDF, \
|
||||
CURVE##_SIGN, \
|
||||
&##CURVE, \
|
||||
OID_ECC_##CURVE \
|
||||
}
|
||||
#define CURVE_NAME(N)
|
||||
extern const TPM_ECC_CURVE_METADATA eccCurves[ECC_CURVE_COUNT];
|
||||
|
||||
#endif
|
||||
|
||||
@ -69,7 +69,9 @@
|
||||
#if ALG_ECC
|
||||
|
||||
//** Functions
|
||||
# if SIMULATION
|
||||
void EccSimulationEnd(void);
|
||||
# endif // SIMULATION
|
||||
|
||||
//*** CryptEccInit()
|
||||
// This function is called at _TPM_Init
|
||||
@ -92,7 +94,7 @@ void ClearPoint2B(TPMS_ECC_POINT* p // IN: the point
|
||||
// Return Type: const TPM_ECC_CURVE_METADATA
|
||||
// NULL curve with the indicated TPM_ECC_CURVE is not implemented
|
||||
// != NULL pointer to the curve data
|
||||
LIB_EXPORT const ECC_CURVE* CryptEccGetParametersByCurveId(
|
||||
LIB_EXPORT const TPM_ECC_CURVE_METADATA* CryptEccGetParametersByCurveId(
|
||||
TPM_ECC_CURVE curveId // IN: the curveID
|
||||
);
|
||||
|
||||
@ -101,11 +103,6 @@ LIB_EXPORT const ECC_CURVE* CryptEccGetParametersByCurveId(
|
||||
LIB_EXPORT UINT16 CryptEccGetKeySizeForCurve(TPM_ECC_CURVE curveId // IN: the curve
|
||||
);
|
||||
|
||||
const ECC_CURVE_DATA *
|
||||
GetCurveData(
|
||||
TPM_ECC_CURVE curveId // IN: the curveID
|
||||
);
|
||||
|
||||
//***CryptEccGetOID()
|
||||
const BYTE* CryptEccGetOID(TPM_ECC_CURVE curveId);
|
||||
|
||||
@ -115,13 +112,6 @@ const BYTE* CryptEccGetOID(TPM_ECC_CURVE curveId);
|
||||
// than or equal to the number of implemented curves, TPM_ECC_NONE is returned.
|
||||
LIB_EXPORT TPM_ECC_CURVE CryptEccGetCurveByIndex(UINT16 i);
|
||||
|
||||
LIB_EXPORT BOOL
|
||||
CryptEccGetParameter(
|
||||
TPM2B_ECC_PARAMETER *out, // OUT: place to put parameter
|
||||
char p, // IN: the parameter selector
|
||||
TPM_ECC_CURVE curveId // IN: the curve id
|
||||
);
|
||||
|
||||
//*** CryptCapGetECCCurve()
|
||||
// This function returns the list of implemented ECC curves.
|
||||
// Return Type: TPMI_YES_NO
|
||||
@ -181,62 +171,75 @@ BOOL CryptEccGetParameters(
|
||||
TPMS_ALGORITHM_DETAIL_ECC* parameters // OUT: ECC parameters
|
||||
);
|
||||
|
||||
const bignum_t *
|
||||
BnGetCurvePrime(
|
||||
TPM_ECC_CURVE curveId
|
||||
);
|
||||
const bignum_t *
|
||||
BnGetCurveOrder(
|
||||
TPM_ECC_CURVE curveId
|
||||
);
|
||||
BOOL
|
||||
BnIsOnCurve(
|
||||
pointConst Q,
|
||||
const ECC_CURVE_DATA *C
|
||||
);
|
||||
|
||||
BOOL
|
||||
BnIsValidPrivateEcc(
|
||||
bigConst x, // IN: private key to check
|
||||
bigCurve E // IN: the curve to check
|
||||
);
|
||||
//*** TpmEcc_IsValidPrivateEcc()
|
||||
// Checks that 0 < 'x' < 'q'
|
||||
BOOL TpmEcc_IsValidPrivateEcc(const Crypt_Int* x, // IN: private key to check
|
||||
const Crypt_EccCurve* E // IN: the curve to check
|
||||
);
|
||||
|
||||
LIB_EXPORT BOOL CryptEccIsValidPrivateKey(TPM2B_ECC_PARAMETER* d,
|
||||
TPM_ECC_CURVE curveId);
|
||||
|
||||
//*** TpmEcc_PointMult()
|
||||
// This function does a point multiply of the form 'R' = ['d']'S' + ['u']'Q' where the
|
||||
// parameters are Crypt_Int* values. If 'S' is NULL and d is not NULL, then it computes
|
||||
// 'R' = ['d']'G' + ['u']'Q' or just 'R' = ['d']'G' if 'u' and 'Q' are NULL.
|
||||
// If 'skipChecks' is TRUE, then the function will not verify that the inputs are
|
||||
// correct for the domain. This would be the case when the values were created by the
|
||||
// CryptoEngine code.
|
||||
// It will return TPM_RC_NO_RESULT if the resulting point is the point at infinity.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_NO_RESULT result of multiplication is a point at infinity
|
||||
// TPM_RC_ECC_POINT 'S' or 'Q' is not on the curve
|
||||
// TPM_RC_VALUE 'd' or 'u' is not < n
|
||||
TPM_RC
|
||||
BnPointMult(
|
||||
bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: optional point to multiply by 'd'
|
||||
bigConst d, // IN: scalar for [d]S or [d]G
|
||||
pointConst Q, // IN: optional second point
|
||||
bigConst u, // IN: optional second scalar
|
||||
bigCurve E // IN: curve parameters
|
||||
);
|
||||
TpmEcc_PointMult(Crypt_Point* R, // OUT: computed point
|
||||
const Crypt_Point* S, // IN: optional point to multiply by 'd'
|
||||
const Crypt_Int* d, // IN: scalar for [d]S or [d]G
|
||||
const Crypt_Point* Q, // IN: optional second point
|
||||
const Crypt_Int* u, // IN: optional second scalar
|
||||
const Crypt_EccCurve* E // IN: curve parameters
|
||||
);
|
||||
|
||||
BOOL
|
||||
BnEccGetPrivate(
|
||||
bigNum dOut, // OUT: the qualified random value
|
||||
const ECC_CURVE_DATA *C, // IN: curve for which the private key
|
||||
#if USE_OPENSSL_FUNCTIONS_EC
|
||||
const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
|
||||
BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
|
||||
// result may not have leading zero bytes
|
||||
#endif
|
||||
// needs to be appropriate
|
||||
RAND_STATE *rand // IN: state for DRBG
|
||||
);
|
||||
|
||||
BOOL
|
||||
BnEccGenerateKeyPair(
|
||||
bigNum bnD, // OUT: private scalar
|
||||
bn_point_t *ecQ, // OUT: public point
|
||||
bigCurve E, // IN: curve for the point
|
||||
RAND_STATE *rand // IN: DRBG state to use
|
||||
);
|
||||
//***TpmEcc_GenPrivateScalar()
|
||||
// This function gets random values that are the size of the key plus 64 bits. The
|
||||
// value is reduced (mod ('q' - 1)) and incremented by 1 ('q' is the order of the
|
||||
// curve. This produces a value ('d') such that 1 <= 'd' < 'q'. This is the method
|
||||
// of FIPS 186-4 Section B.4.1 ""Key Pair Generation Using Extra Random Bits"".
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) success
|
||||
// FALSE(0) failure generating private key
|
||||
#if !USE_OPENSSL_FUNCTIONS_EC // libtpms: added
|
||||
BOOL TpmEcc_GenPrivateScalar(
|
||||
Crypt_Int* dOut, // OUT: the qualified random value
|
||||
const Crypt_EccCurve* E, // IN: curve for which the private key
|
||||
// needs to be appropriate
|
||||
RAND_STATE* rand // IN: state for DRBG
|
||||
);
|
||||
#else // libtpms: added begin
|
||||
BOOL TpmEcc_GenPrivateScalar(
|
||||
Crypt_Int* dOut, // OUT: the qualified random value
|
||||
const Crypt_EccCurve* E, // IN: curve for which the private key
|
||||
// needs to be appropriate
|
||||
const EC_GROUP* G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
|
||||
BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
|
||||
// result may not have leading zero bytes
|
||||
RAND_STATE* rand // IN: state for DRBG
|
||||
);
|
||||
#endif // libtpms: added end
|
||||
|
||||
//*** TpmEcc_GenerateKeyPair()
|
||||
// This function gets a private scalar from the source of random bits and does
|
||||
// the point multiply to get the public key.
|
||||
BOOL TpmEcc_GenerateKeyPair(Crypt_Int* bnD, // OUT: private scalar
|
||||
Crypt_Point* ecQ, // OUT: public point
|
||||
const Crypt_EccCurve* E, // IN: curve for the point
|
||||
RAND_STATE* rand // IN: DRBG state to use
|
||||
);
|
||||
|
||||
//***CryptEccNewKeyPair(***)
|
||||
// This function creates an ephemeral ECC. It is ephemeral in that
|
||||
// is expected that the private part of the key will be discarded
|
||||
LIB_EXPORT TPM_RC CryptEccNewKeyPair(
|
||||
TPMS_ECC_POINT* Qout, // OUT: the public point
|
||||
TPM2B_ECC_PARAMETER* dOut, // OUT: the private scalar
|
||||
@ -320,12 +323,12 @@ LIB_EXPORT TPM_RC CryptEccGenerateKey(
|
||||
// RNG state
|
||||
);
|
||||
|
||||
// libtpms added begin
|
||||
// libtpms: added begin
|
||||
LIB_EXPORT BOOL
|
||||
CryptEccIsCurveRuntimeUsable(
|
||||
TPMI_ECC_CURVE curveId
|
||||
);
|
||||
// libtpms added end
|
||||
// libtpms: added end
|
||||
|
||||
#endif // ALG_ECC
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ LIB_EXPORT TPM_RC CryptEccSign(TPMT_SIGNATURE* signature, // OUT: signature
|
||||
const TPM2B_DIGEST* digest, // IN: digest to sign
|
||||
TPMT_ECC_SCHEME* scheme, // IN: signing scheme
|
||||
RAND_STATE* rand);
|
||||
|
||||
//*** CryptEccValidateSignature()
|
||||
// This function validates an EcDsa or EcSchnorr signature.
|
||||
// The point 'Qin' needs to have been validated to be on the curve of 'curveId'.
|
||||
|
||||
@ -80,12 +80,6 @@ LIB_EXPORT bigNum BnFrom2B(bigNum bn, // OUT:
|
||||
const TPM2B* a2B // IN: number to convert
|
||||
);
|
||||
|
||||
LIB_EXPORT bigNum
|
||||
BnFromHex(
|
||||
bigNum bn, // OUT:
|
||||
const char *hex // IN:
|
||||
);
|
||||
|
||||
//*** BnToBytes()
|
||||
// This function converts a BIG_NUM to a byte array. It converts the bigNum to a
|
||||
// big-endian byte string and sets 'size' to the normalized value. If 'size' is an
|
||||
@ -114,19 +108,31 @@ LIB_EXPORT BOOL BnTo2B(bigConst bn, // IN:
|
||||
TPM2B* a2B, // OUT:
|
||||
NUMBYTES size // IN: the desired size
|
||||
);
|
||||
#if ALG_ECC
|
||||
|
||||
//*** BnPointFromBytes()
|
||||
// Function to create a BIG_POINT structure from a byte buffer in big-endian order.
|
||||
// A point is going to be two ECC values in the same buffer. The values are going
|
||||
// to be the size of the modulus. They are in modular form.
|
||||
LIB_EXPORT bn_point_t* BnPointFromBytes(
|
||||
bigPoint ecP, // OUT: the preallocated point structure
|
||||
const BYTE* x,
|
||||
NUMBYTES nBytesX,
|
||||
const BYTE* y,
|
||||
NUMBYTES nBytesY);
|
||||
|
||||
LIB_EXPORT bn_point_t *
|
||||
BnPointFrom2B(
|
||||
bigPoint ecP, // OUT: the preallocated point structure
|
||||
TPMS_ECC_POINT *p // IN: the number to convert
|
||||
);
|
||||
|
||||
LIB_EXPORT BOOL
|
||||
BnPointTo2B(
|
||||
TPMS_ECC_POINT *p, // OUT: the converted 2B structure
|
||||
bigPoint ecP, // IN: the values to be converted
|
||||
bigCurve E // IN: curve descriptor for the point
|
||||
);
|
||||
//*** BnPointToBytes()
|
||||
// This function converts a BIG_POINT into a TPMS_ECC_POINT. A TPMS_ECC_POINT
|
||||
// contains two TPM2B_ECC_PARAMETER values. The maximum size of the parameters
|
||||
// is dependent on the maximum EC key size used in an implementation.
|
||||
// The presumption is that the TPMS_ECC_POINT is large enough to hold 2 TPM2B
|
||||
// values, each as large as a MAX_ECC_PARAMETER_BYTES
|
||||
LIB_EXPORT BOOL BnPointToBytes(
|
||||
pointConst ecP, // OUT: the preallocated point structure
|
||||
BYTE* x,
|
||||
NUMBYTES* pBytesX,
|
||||
BYTE* y,
|
||||
NUMBYTES* pBytesY);
|
||||
#endif // ALG_ECC
|
||||
|
||||
#endif // _BN_CONVERT_FP_H_
|
||||
|
||||
@ -159,4 +159,13 @@ LIB_EXPORT BOOL BnMaskBits(bigNum bn, // IN/OUT: number to mask
|
||||
// This function always returns TRUE.
|
||||
LIB_EXPORT BOOL BnShiftRight(bigNum result, bigConst toShift, uint32_t shiftAmount);
|
||||
|
||||
#endif
|
||||
//*** BnGetCurveData()
|
||||
// This function returns the pointer for the parameter data
|
||||
// associated with a curve.
|
||||
const TPMBN_ECC_CURVE_CONSTANTS* BnGetCurveData(TPM_ECC_CURVE curveId);
|
||||
|
||||
//*** BnIsPointOnCurve()
|
||||
// This function checks if a point is on the curve.
|
||||
BOOL BnIsPointOnCurve(pointConst Q, const TPMBN_ECC_CURVE_CONSTANTS* C);
|
||||
|
||||
#endif // _BN_MATH_FP_H_
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
//#include "BnOssl.h"
|
||||
|
||||
#ifdef MATH_LIB_OSSL
|
||||
# include "TpmToOsslMath_fp.h"
|
||||
# include "BnToOsslMath_fp.h"
|
||||
|
||||
//** Functions
|
||||
|
||||
@ -444,7 +444,7 @@ LIB_EXPORT BOOL BnModInverse(bigNum result, bigConst number, bigConst modulus)
|
||||
// FALSE(0) failure in operation
|
||||
static BOOL PointFromOssl(bigPoint pOut, // OUT: resulting point
|
||||
EC_POINT* pIn, // IN: the point to return
|
||||
const bigCurve E // IN: the curve
|
||||
const bigCurveData* E // IN: the curve
|
||||
)
|
||||
{
|
||||
BIGNUM* x = NULL;
|
||||
@ -478,7 +478,7 @@ static BOOL PointFromOssl(bigPoint pOut, // OUT: resulting point
|
||||
|
||||
//*** EcPointInitialized()
|
||||
// Allocate and initialize a point.
|
||||
LIB_EXPORT EC_POINT* EcPointInitialized(pointConst initializer, bigCurve E) // libtpms: exported function
|
||||
LIB_EXPORT EC_POINT* EcPointInitialized(pointConst initializer, const bigCurveData* E) // libtpms: exported function
|
||||
{
|
||||
EC_POINT* P = NULL;
|
||||
|
||||
@ -510,13 +510,12 @@ LIB_EXPORT EC_POINT* EcPointInitialized(pointConst initializer, bigCurve E) //
|
||||
// NULL the TPM_ECC_CURVE is not valid or there was a problem in
|
||||
// in initializing the curve data
|
||||
// non-NULL points to 'E'
|
||||
LIB_EXPORT bigCurve
|
||||
BnCurveInitialize(
|
||||
bigCurve E, // IN: curve structure to initialize
|
||||
TPM_ECC_CURVE curveId // IN: curve identifier
|
||||
)
|
||||
LIB_EXPORT bigCurveData* BnCurveInitialize(
|
||||
bigCurveData* E, // IN: curve structure to initialize
|
||||
TPM_ECC_CURVE curveId // IN: curve identifier
|
||||
)
|
||||
{
|
||||
const ECC_CURVE_DATA *C = GetCurveData(curveId);
|
||||
const TPMBN_ECC_CURVE_CONSTANTS* C = BnGetCurveData(curveId);
|
||||
if(C == NULL)
|
||||
E = NULL;
|
||||
if(E != NULL)
|
||||
@ -580,7 +579,7 @@ BnCurveInitialize(
|
||||
//*** BnCurveFree()
|
||||
// This function will free the allocated components of the curve and end the
|
||||
// frame in which the curve data exists
|
||||
LIB_EXPORT void BnCurveFree(bigCurve E)
|
||||
LIB_EXPORT void BnCurveFree(bigCurveData* E)
|
||||
{
|
||||
if(E)
|
||||
{
|
||||
@ -597,7 +596,7 @@ LIB_EXPORT void BnCurveFree(bigCurve E)
|
||||
LIB_EXPORT BOOL BnEccModMult(bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: point to multiply by 'd' (optional)
|
||||
bigConst d, // IN: scalar for [d]S
|
||||
const bigCurve E)
|
||||
const bigCurveData* E)
|
||||
{
|
||||
EC_POINT* pR = EC_POINT_new(E->G);
|
||||
EC_POINT* pS = EcPointInitialized(S, E);
|
||||
@ -624,7 +623,7 @@ LIB_EXPORT BOOL BnEccModMult2(bigPoint R, // OUT: computed point
|
||||
bigConst d, // IN: scalar for [d]S or [d]G
|
||||
pointConst Q, // IN: second point
|
||||
bigConst u, // IN: second scalar
|
||||
const bigCurve E // IN: curve
|
||||
const bigCurveData* E // IN: curve
|
||||
)
|
||||
{
|
||||
EC_POINT* pR = EC_POINT_new(E->G);
|
||||
@ -633,7 +632,7 @@ LIB_EXPORT BOOL BnEccModMult2(bigPoint R, // OUT: computed point
|
||||
EC_POINT* pQ = EcPointInitialized(Q, E);
|
||||
BIG_INITIALIZED(bnU, u);
|
||||
|
||||
if(S == NULL || S == (pointConst) & (AccessCurveData(E)->base))
|
||||
if(S == NULL || S == (pointConst) & (AccessCurveConstants(E)->base))
|
||||
EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX);
|
||||
else
|
||||
{
|
||||
@ -678,7 +677,7 @@ LIB_EXPORT BOOL BnEccModMult2(bigPoint R, // OUT: computed point
|
||||
LIB_EXPORT BOOL BnEccAdd(bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: first point to add
|
||||
pointConst Q, // IN: second point
|
||||
const bigCurve E // IN: curve
|
||||
const bigCurveData* E // IN: curve
|
||||
)
|
||||
{
|
||||
EC_POINT* pR = EC_POINT_new(E->G);
|
||||
|
||||
@ -67,6 +67,7 @@
|
||||
|
||||
#define MATH_LIB_OSSL
|
||||
|
||||
#include "BnValues.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
@ -125,15 +126,20 @@ struct bignum_st
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const ECC_CURVE_DATA* C; // the TPM curve values
|
||||
const TPMBN_ECC_CURVE_CONSTANTS* C; // the TPM curve values
|
||||
EC_GROUP* G; // group parameters
|
||||
BN_CTX* CTX; // the context for the math (this might not be
|
||||
// the context in which the curve was created>;
|
||||
} OSSL_CURVE_DATA;
|
||||
|
||||
// Define the curve data type expected by the TpmBigNum library:
|
||||
typedef OSSL_CURVE_DATA *bigCurve;
|
||||
#define AccessCurveData(E) ((E)->C)
|
||||
typedef OSSL_CURVE_DATA bigCurveData;
|
||||
|
||||
TPM_INLINE const TPMBN_ECC_CURVE_CONSTANTS* AccessCurveConstants(
|
||||
const bigCurveData* E)
|
||||
{
|
||||
return E->C;
|
||||
}
|
||||
|
||||
#include "TpmToOsslSupport_fp.h"
|
||||
|
||||
@ -141,12 +147,6 @@ typedef OSSL_CURVE_DATA *bigCurve;
|
||||
#define OSSL_ENTER() BN_CTX* CTX = OsslContextEnter()
|
||||
#define OSSL_LEAVE() OsslContextLeave(CTX)
|
||||
|
||||
#define CURVE_INITIALIZED(name, initializer) \
|
||||
OSSL_CURVE_DATA _##name; \
|
||||
bigCurve name = BnCurveInitialize(&_##name, initializer)
|
||||
|
||||
#define CURVE_FREE(name) BnCurveFree(name)
|
||||
|
||||
#if 0 /* kgold not used */
|
||||
// Start and end a local stack frame within the context of the curve frame
|
||||
#define ECC_ENTER() BN_CTX* CTX = OsslPushContext(E->CTX)
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* TPM to OpenSSL BigNum Shim Layer */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslMath_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -55,98 +54,41 @@
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
|
||||
/* (c) Copyright IBM Corp. and others, 2023 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
#ifndef TPMTOOSSLMATH_FP_H
|
||||
#define TPMTOOSSLMATH_FP_H
|
||||
/*(Auto-generated)
|
||||
* Created by TpmPrototypes; Version 3.0 July 18, 2017
|
||||
* Date: Oct 24, 2019 Time: 11:37:07AM
|
||||
*/
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#ifndef _BN_TO_OSSL_MATH_FP_H_
|
||||
#define _BN_TO_OSSL_MATH_FP_H_
|
||||
|
||||
#ifdef MATH_LIB_OSSL
|
||||
|
||||
//*** OsslToTpmBn()
|
||||
// This function converts an OpenSSL BIGNUM to a TPM bigNum. In this implementation
|
||||
// it is assumed that OpenSSL uses a different control structure but the same data
|
||||
// layout -- an array of native-endian words in little-endian order.
|
||||
// Return Type: BOOL
|
||||
// TRUE(1) success
|
||||
// FALSE(0) failure because value will not fit or OpenSSL variable doesn't
|
||||
// exist
|
||||
BOOL OsslToTpmBn(bigNum bn, const BIGNUM* osslBn);
|
||||
|
||||
//*** BigInitialized()
|
||||
// This function initializes an OSSL BIGNUM from a TPM bigConst. Do not use this for
|
||||
// values that are passed to OpenSLL when they are not declared as const in the
|
||||
// function prototype. Instead, use BnNewVariable().
|
||||
BIGNUM* BigInitialized(BIGNUM* toInit, bigConst initializer);
|
||||
#endif // MATHLIB OSSL
|
||||
|
||||
BOOL
|
||||
OsslToTpmBn(
|
||||
bigNum bn,
|
||||
const BIGNUM *osslBn // libtpms added 'const'
|
||||
);
|
||||
BIGNUM *
|
||||
BigInitialized(
|
||||
BIGNUM *toInit,
|
||||
bigConst initializer
|
||||
);
|
||||
// libtpms added begin
|
||||
EC_POINT *
|
||||
EcPointInitialized(
|
||||
pointConst initializer,
|
||||
bigCurve E
|
||||
);
|
||||
EC_POINT *EcPointInitialized(pointConst initializer,
|
||||
const bigCurveData* E
|
||||
);
|
||||
// libtpms added end
|
||||
LIB_EXPORT BOOL
|
||||
BnModMult(
|
||||
bigNum result,
|
||||
bigConst op1,
|
||||
bigConst op2,
|
||||
bigConst modulus
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnMult(
|
||||
bigNum result,
|
||||
bigConst multiplicand,
|
||||
bigConst multiplier
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnDiv(
|
||||
bigNum quotient,
|
||||
bigNum remainder,
|
||||
bigConst dividend,
|
||||
bigConst divisor
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnGcd(
|
||||
bigNum gcd, // OUT: the common divisor
|
||||
bigConst number1, // IN:
|
||||
bigConst number2 // IN:
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnModExp(
|
||||
bigNum result, // OUT: the result
|
||||
bigConst number, // IN: number to exponentiate
|
||||
bigConst exponent, // IN:
|
||||
bigConst modulus // IN:
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnModInverse(
|
||||
bigNum result,
|
||||
bigConst number,
|
||||
bigConst modulus
|
||||
);
|
||||
bigCurve
|
||||
BnCurveInitialize(
|
||||
bigCurve E, // IN: curve structure to initialize
|
||||
TPM_ECC_CURVE curveId // IN: curve identifier
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnEccModMult(
|
||||
bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: point to multiply by 'd' (optional)
|
||||
bigConst d, // IN: scalar for [d]S
|
||||
bigCurve E
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnEccModMult2(
|
||||
bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: optional point
|
||||
bigConst d, // IN: scalar for [d]S or [d]G
|
||||
pointConst Q, // IN: second point
|
||||
bigConst u, // IN: second scalar
|
||||
bigCurve E // IN: curve
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
BnEccAdd(
|
||||
bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: point to multiply by 'd'
|
||||
pointConst Q, // IN: second point
|
||||
bigCurve E // IN: curve
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif // _TPM_TO_OSSL_MATH_FP_H_
|
||||
@ -217,32 +217,22 @@ typedef struct constant_point_t
|
||||
bigConst y;
|
||||
bigConst z;
|
||||
} constant_point_t;
|
||||
#define ECC_BITS (MAX_ECC_KEY_BYTES * 8)
|
||||
BN_TYPE(ecc, ECC_BITS);
|
||||
#define ECC_NUM(name) BN_VAR(name, ECC_BITS)
|
||||
#define ECC_INITIALIZED(name, initializer) \
|
||||
BN_INITIALIZED(name, ECC_BITS, initializer)
|
||||
#define POINT_INSTANCE(name, bits) \
|
||||
BN_STRUCT (name##_x, bits) name##_x = \
|
||||
{BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
|
||||
BN_STRUCT (name##_y, bits ) name##_y = \
|
||||
{BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
|
||||
BN_STRUCT (name##_z, bits ) name##_z = \
|
||||
{BITS_TO_CRYPT_WORDS ( bits ), 0,{0}}; \
|
||||
bn_point_t name##_
|
||||
#define POINT_INITIALIZER(name) \
|
||||
BnInitializePoint(&name##_, (bigNum)&name##_x, \
|
||||
(bigNum)&name##_y, (bigNum)&name##_z)
|
||||
#define POINT_INITIALIZED(name, initValue) \
|
||||
POINT_INSTANCE(name, MAX_ECC_KEY_BITS); \
|
||||
bigPoint name = BnPointFrom2B( \
|
||||
POINT_INITIALIZER(name), \
|
||||
initValue)
|
||||
#define POINT_VAR(name, bits) \
|
||||
POINT_INSTANCE (name, bits); \
|
||||
bigPoint name = POINT_INITIALIZER(name)
|
||||
#define POINT(name) POINT_VAR(name, MAX_ECC_KEY_BITS)
|
||||
/* Structure for the curve parameters. This is an analog to the TPMS_ALGORITHM_DETAIL_ECC */
|
||||
|
||||
// coords points into x,y,z
|
||||
// a bigPoint is a pointer to one of these structures, and
|
||||
// therefore a pointer to bn_point_t (a coords).
|
||||
// so bigPoint->coords->x->size is the size of x, and
|
||||
// all 3 components are the same size.
|
||||
#define BN_POINT_BUF(typename, bits) \
|
||||
struct bnpt_st_##typename##_t \
|
||||
{ \
|
||||
bn_point_t coords; \
|
||||
BN_STRUCT(typename##_x, MAX_ECC_KEY_BITS) x; \
|
||||
BN_STRUCT(typename##_y, MAX_ECC_KEY_BITS) y; \
|
||||
BN_STRUCT(typename##_z, MAX_ECC_KEY_BITS) z; \
|
||||
}
|
||||
|
||||
typedef BN_POINT_BUF(fullpoint, MAX_ECC_KEY_BITS) bn_fullpoint_t;
|
||||
|
||||
// TPMBN_ECC_CURVE_CONSTANTS
|
||||
// =========================
|
||||
@ -278,13 +268,14 @@ BN_TYPE(ecc, ECC_BITS);
|
||||
// TPMS_ALGORITHM_DETAIL_ECC
|
||||
typedef struct
|
||||
{
|
||||
TPM_ECC_CURVE curveId; // TPM Algorithm ID for this data
|
||||
bigConst prime; // a prime number
|
||||
bigConst order; // the order of the curve
|
||||
bigConst h; // cofactor
|
||||
bigConst a; // linear coefficient
|
||||
bigConst b; // constant term
|
||||
constant_point_t base; // base point
|
||||
} ECC_CURVE_DATA;
|
||||
} TPMBN_ECC_CURVE_CONSTANTS;
|
||||
|
||||
// Access macros for the TPMBN_ECC_CURVE_CONSTANTS structure. The parameter 'C' is a pointer
|
||||
// to an TPMBN_ECC_CURVE_CONSTANTS structure. In some libraries, the curve structure E contains
|
||||
@ -293,14 +284,42 @@ typedef struct
|
||||
// to the TPMBN_ECC_CURVE_CONSTANTS for access. In some cases, the function does nothing.
|
||||
// AccessCurveConstants and these functions are all defined as inline so they can be optimized
|
||||
// away in cases where they are no-ops.
|
||||
#define CurveGetPrime(C) ((C)->prime)
|
||||
#define CurveGetOrder(C) ((C)->order)
|
||||
#define CurveGetCofactor(C) ((C)->h)
|
||||
#define CurveGet_a(C) ((C)->a)
|
||||
#define CurveGet_b(C) ((C)->b)
|
||||
#define CurveGetG(C) ((pointConst)&((C)->base))
|
||||
#define CurveGetGx(C) ((C)->base.x)
|
||||
#define CurveGetGy(C) ((C)->base.y)
|
||||
TPM_INLINE bigConst BnCurveGetPrime(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->prime;
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGetOrder(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->order;
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGetCofactor(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->h;
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGet_a(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->a;
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGet_b(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->b;
|
||||
}
|
||||
TPM_INLINE pointConst BnCurveGetG(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return (pointConst) & (C->base);
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGetGx(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->base.x;
|
||||
}
|
||||
TPM_INLINE bigConst BnCurveGetGy(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->base.y;
|
||||
}
|
||||
TPM_INLINE TPM_ECC_CURVE BnCurveGetCurveId(const TPMBN_ECC_CURVE_CONSTANTS* C)
|
||||
{
|
||||
return C->curveId;
|
||||
}
|
||||
|
||||
// Convert bytes in initializers
|
||||
// This is used for CryptEccData.c.
|
||||
|
||||
@ -60,6 +60,8 @@
|
||||
|
||||
//** Includes and Defines
|
||||
#include "Tpm.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
|
||||
#if CC_ECC_Encrypt || CC_ECC_Encrypt
|
||||
|
||||
@ -108,11 +110,11 @@ LIB_EXPORT TPM_RC CryptEccEncrypt(
|
||||
// and plainText
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
|
||||
POINT_INITIALIZED(PB, &key->publicArea.unique.ecc);
|
||||
POINT_VAR(Px, MAX_ECC_KEY_BITS);
|
||||
TPMS_ECC_POINT p2;
|
||||
ECC_NUM(D);
|
||||
CRYPT_CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
|
||||
CRYPT_POINT_INITIALIZED(PB, &key->publicArea.unique.ecc);
|
||||
CRYPT_POINT_VAR(Px);
|
||||
TPMS_ECC_POINT p2;
|
||||
CRYPT_ECC_NUM(D);
|
||||
TPM2B_TYPE(2ECC, MAX_ECC_KEY_BYTES * 2);
|
||||
TPM2B_2ECC z;
|
||||
int i;
|
||||
@ -137,12 +139,12 @@ LIB_EXPORT TPM_RC CryptEccEncrypt(
|
||||
if(TPM_ALG_KDF2 != scheme->scheme)
|
||||
ERROR_EXIT(TPM_RC_SCHEME);
|
||||
// generate an ephemeral key from a random k
|
||||
if (!BnEccGenerateKeyPair(D, Px, E, RANDOM)
|
||||
// C1 is the public part of the ephemeral key
|
||||
|| !BnPointTo2B(c1, Px, E)
|
||||
// Compute P2
|
||||
|| (BnPointMult(Px, PB, D, NULL, NULL, E) != TPM_RC_SUCCESS)
|
||||
|| !BnPointTo2B(&p2, Px, E))
|
||||
if(!TpmEcc_GenerateKeyPair(D, Px, E, RANDOM)
|
||||
// C1 is the public part of the ephemeral key
|
||||
|| !TpmEcc_PointTo2B(c1, Px, E)
|
||||
// Compute P2
|
||||
|| (TpmEcc_PointMult(Px, PB, D, NULL, NULL, E) != TPM_RC_SUCCESS)
|
||||
|| !TpmEcc_PointTo2B(&p2, Px, E))
|
||||
ERROR_EXIT(TPM_RC_NO_RESULT);
|
||||
|
||||
//Compute the C3 value hash(x2 || M || y2)
|
||||
@ -166,7 +168,7 @@ LIB_EXPORT TPM_RC CryptEccEncrypt(
|
||||
for(i = 0; i < plainText->t.size; i++)
|
||||
c2->t.buffer[i] ^= plainText->t.buffer[i];
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -188,10 +190,10 @@ LIB_EXPORT TPM_RC CryptEccDecrypt(
|
||||
// and plainText
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
|
||||
ECC_INITIALIZED(D, &key->sensitive.sensitive.ecc.b);
|
||||
POINT_INITIALIZED(C1, c1);
|
||||
TPMS_ECC_POINT p2;
|
||||
CRYPT_CURVE_INITIALIZED(E, key->publicArea.parameters.eccDetail.curveID);
|
||||
CRYPT_ECC_INITIALIZED(D, &key->sensitive.sensitive.ecc.b);
|
||||
CRYPT_POINT_INITIALIZED(C1, c1);
|
||||
TPMS_ECC_POINT p2;
|
||||
TPM2B_TYPE(2ECC, MAX_ECC_KEY_BYTES * 2);
|
||||
TPM2B_DIGEST check;
|
||||
TPM2B_2ECC z;
|
||||
@ -204,8 +206,8 @@ LIB_EXPORT TPM_RC CryptEccDecrypt(
|
||||
if(TPM_ALG_KDF2 != scheme->scheme)
|
||||
ERROR_EXIT(TPM_RC_SCHEME);
|
||||
// Generate the Z value
|
||||
BnPointMult(C1, C1, D, NULL, NULL, E);
|
||||
BnPointTo2B(&p2, C1, E);
|
||||
TpmEcc_PointMult(C1, C1, D, NULL, NULL, E);
|
||||
TpmEcc_PointTo2B(&p2, C1, E);
|
||||
|
||||
// Start the hash to check the algorithm
|
||||
if(0 == CryptHashStart(&hashState, scheme->details.mgf1.hashAlg))
|
||||
@ -233,7 +235,7 @@ LIB_EXPORT TPM_RC CryptEccDecrypt(
|
||||
if(!MemoryEqual2B(&check.b, &c3->b))
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@ -63,6 +63,8 @@
|
||||
// key-exchange protocols
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
|
||||
#if CC_ZGen_2Phase == YES
|
||||
|
||||
@ -80,16 +82,19 @@
|
||||
// 3. Calculate the associate value function
|
||||
// avf(Q) = xqm + 2ceil(f / 2)
|
||||
// Always returns TRUE(1).
|
||||
static BOOL avf1(bigNum bnX, // IN/OUT: the reduced value
|
||||
bigNum bnN // IN: the order of the curve
|
||||
static BOOL avf1(Crypt_Int* bnX, // IN/OUT: the reduced value
|
||||
Crypt_Int* bnN // IN: the order of the curve
|
||||
)
|
||||
{
|
||||
// compute f = 2^(ceil(ceil(log2(n)) / 2))
|
||||
int f = (BnSizeInBits(bnN) + 1) / 2;
|
||||
int f = (ExtMath_SizeInBits(bnN) + 1) / 2;
|
||||
// x' = 2^f + (x mod 2^f)
|
||||
BnMaskBits(bnX, f); // This is mod 2*2^f but it doesn't matter because
|
||||
ExtMath_MaskBits(bnX, f); // This is mod 2*2^f but it doesn't matter because
|
||||
// the next operation will SET the extra bit anyway
|
||||
BnSetBit(bnX, f);
|
||||
if(!ExtMath_SetBit(bnX, f))
|
||||
{
|
||||
FAIL(FATAL_ERROR_CRYPTO);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -113,16 +118,15 @@ static TPM_RC C_2_2_MQV(TPMS_ECC_POINT* outZ, // OUT: the computed point
|
||||
TPMS_ECC_POINT* QeB // IN: ephemeral public party B key
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
const ECC_CURVE_DATA *C;
|
||||
POINT(pQeA);
|
||||
POINT_INITIALIZED(pQeB, QeB);
|
||||
POINT_INITIALIZED(pQsB, QsB);
|
||||
ECC_NUM(bnTa);
|
||||
ECC_INITIALIZED(bnDeA, deA);
|
||||
ECC_INITIALIZED(bnDsA, dsA);
|
||||
ECC_NUM(bnN);
|
||||
ECC_NUM(bnXeB);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_POINT_VAR(pQeA);
|
||||
CRYPT_POINT_INITIALIZED(pQeB, QeB);
|
||||
CRYPT_POINT_INITIALIZED(pQsB, QsB);
|
||||
CRYPT_ECC_NUM(bnTa);
|
||||
CRYPT_ECC_INITIALIZED(bnDeA, deA);
|
||||
CRYPT_ECC_INITIALIZED(bnDsA, dsA);
|
||||
CRYPT_ECC_NUM(bnN);
|
||||
CRYPT_ECC_NUM(bnXeB);
|
||||
TPM_RC retVal;
|
||||
//
|
||||
// Parameter checks
|
||||
@ -130,7 +134,6 @@ static TPM_RC C_2_2_MQV(TPMS_ECC_POINT* outZ, // OUT: the computed point
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
pAssert(
|
||||
outZ != NULL && pQeB != NULL && pQsB != NULL && deA != NULL && dsA != NULL);
|
||||
C = AccessCurveData(E);
|
||||
// Process:
|
||||
// 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
|
||||
// 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
|
||||
@ -138,7 +141,8 @@ static TPM_RC C_2_2_MQV(TPMS_ECC_POINT* outZ, // OUT: the computed point
|
||||
// 4. Z=xP, where xP is the x-coordinate of P.
|
||||
|
||||
// Compute the public ephemeral key pQeA = [de,A]G
|
||||
if((retVal = BnPointMult(pQeA, CurveGetG(C), bnDeA, NULL, NULL, E))
|
||||
if((retVal =
|
||||
TpmEcc_PointMult(pQeA, ExtEcc_CurveGetG(curveId), bnDeA, NULL, NULL, E))
|
||||
!= TPM_RC_SUCCESS)
|
||||
goto Exit;
|
||||
|
||||
@ -146,19 +150,24 @@ static TPM_RC C_2_2_MQV(TPMS_ECC_POINT* outZ, // OUT: the computed point
|
||||
// tA := (ds,A + de,A avf(Xe,A)) mod n (3)
|
||||
// Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n
|
||||
// Ta = avf(XeA);
|
||||
BnCopy(bnTa, pQeA->x);
|
||||
ExtMath_Copy(bnTa, ExtEcc_PointX(pQeA));
|
||||
avf1(bnTa, bnN);
|
||||
// do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n
|
||||
BnModMult(bnTa, bnDsA, bnTa, bnN);
|
||||
ExtMath_ModMult(bnTa, bnDsA, bnTa, bnN);
|
||||
// now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n
|
||||
BnAdd(bnTa, bnTa, bnDeA);
|
||||
BnMod(bnTa, bnN);
|
||||
ExtMath_Add(bnTa, bnTa, bnDeA);
|
||||
ExtMath_Mod(bnTa, bnN);
|
||||
|
||||
// 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
|
||||
// Put this in because almost every case of h is == 1 so skip the call when
|
||||
// not necessary.
|
||||
if(!BnEqualWord(CurveGetCofactor(C), 1))
|
||||
if(!ExtMath_IsEqualWord(ExtEcc_CurveGetCofactor(curveId), 1))
|
||||
// Cofactor is not 1 so compute Ta := Ta * h mod n
|
||||
BnModMult(bnTa, bnTa, CurveGetCofactor(C), CurveGetOrder(C));
|
||||
ExtMath_ModMult(bnTa,
|
||||
bnTa,
|
||||
ExtEcc_CurveGetCofactor(curveId),
|
||||
ExtEcc_CurveGetOrder(curveId));
|
||||
|
||||
// Now that 'tA' is (h * 'tA' mod n)
|
||||
// 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B).
|
||||
|
||||
@ -166,17 +175,19 @@ static TPM_RC C_2_2_MQV(TPMS_ECC_POINT* outZ, // OUT: the computed point
|
||||
avf1(bnXeB, bnN);
|
||||
|
||||
// QsB := [XeB]QsB
|
||||
BnPointMult(pQsB, pQsB, bnXeB, NULL, NULL, E);
|
||||
BnEccAdd(pQeB, pQeB, pQsB, E);
|
||||
TpmEcc_PointMult(pQsB, pQsB, bnXeB, NULL, NULL, E);
|
||||
ExtEcc_PointAdd(pQeB, pQeB, pQsB, E);
|
||||
|
||||
// QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
|
||||
// If the result is not the point at infinity, return QeB
|
||||
BnPointMult(pQeB, pQeB, bnTa, NULL, NULL, E);
|
||||
if(BnEqualZero(pQeB->z))
|
||||
TpmEcc_PointMult(pQeB, pQeB, bnTa, NULL, NULL, E);
|
||||
if(ExtEcc_IsInfinityPoint(pQeB))
|
||||
ERROR_EXIT(TPM_RC_NO_RESULT);
|
||||
// Convert BIGNUM E to TPM2B E
|
||||
BnPointTo2B(outZ, pQeB, E);
|
||||
// Convert Crypt_Int* E to TPM2B E
|
||||
TpmEcc_PointTo2B(outZ, pQeB, E);
|
||||
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -195,12 +206,12 @@ static TPM_RC C_2_2_ECDH(TPMS_ECC_POINT* outZs, // OUT: Zs
|
||||
TPMS_ECC_POINT* QeB // IN: ephemeral public party B key
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
ECC_INITIALIZED(bnAs, dsA);
|
||||
ECC_INITIALIZED(bnAe, deA);
|
||||
POINT_INITIALIZED(ecBs, QsB);
|
||||
POINT_INITIALIZED(ecBe, QeB);
|
||||
POINT(ecZ);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_ECC_INITIALIZED(bnAs, dsA);
|
||||
CRYPT_ECC_INITIALIZED(bnAe, deA);
|
||||
CRYPT_POINT_INITIALIZED(ecBs, QsB);
|
||||
CRYPT_POINT_INITIALIZED(ecBe, QeB);
|
||||
CRYPT_POINT_VAR(ecZ);
|
||||
TPM_RC retVal;
|
||||
//
|
||||
// Parameter checks
|
||||
@ -210,18 +221,18 @@ static TPM_RC C_2_2_ECDH(TPMS_ECC_POINT* outZs, // OUT: Zs
|
||||
outZs != NULL && dsA != NULL && deA != NULL && QsB != NULL && QeB != NULL);
|
||||
|
||||
// Do the point multiply for the Zs value ([dsA]QsB)
|
||||
retVal = BnPointMult(ecZ, ecBs, bnAs, NULL, NULL, E);
|
||||
retVal = TpmEcc_PointMult(ecZ, ecBs, bnAs, NULL, NULL, E);
|
||||
if(retVal == TPM_RC_SUCCESS)
|
||||
{
|
||||
// Convert the Zs value.
|
||||
BnPointTo2B(outZs, ecZ, E);
|
||||
TpmEcc_PointTo2B(outZs, ecZ, E);
|
||||
// Do the point multiply for the Ze value ([deA]QeB)
|
||||
retVal = BnPointMult(ecZ, ecBe, bnAe, NULL, NULL, E);
|
||||
retVal = TpmEcc_PointMult(ecZ, ecBe, bnAe, NULL, NULL, E);
|
||||
if(retVal == TPM_RC_SUCCESS)
|
||||
BnPointTo2B(outZe, ecZ, E);
|
||||
TpmEcc_PointTo2B(outZe, ecZ, E);
|
||||
}
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -277,10 +288,10 @@ LIB_EXPORT TPM_RC CryptEcc2PhaseKeyExchange(
|
||||
|
||||
//*** ComputeWForSM2()
|
||||
// Compute the value for w used by SM2
|
||||
static UINT32 ComputeWForSM2(bigCurve E)
|
||||
static UINT32 ComputeWForSM2(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
// w := ceil(ceil(log2(n)) / 2) - 1
|
||||
return (BnMsb(CurveGetOrder(AccessCurveData(E))) / 2 - 1);
|
||||
return (ExtMath_MostSigBitNum(ExtEcc_CurveGetOrder(curveId)) / 2 - 1);
|
||||
}
|
||||
|
||||
//*** avfSm2()
|
||||
@ -290,19 +301,21 @@ static UINT32 ComputeWForSM2(bigCurve E)
|
||||
// standard avf(). For example, if 'n' is 15, 'Ws' ('w' in the standard) is 2 but
|
||||
// the 'W' here is 1. This means that an input value of 14 (1110b) would return a
|
||||
// value of 110b with the standard but 10b with the scheme in SM2.
|
||||
static bigNum
|
||||
avfSm2(
|
||||
bigNum bn, // IN/OUT: the reduced value
|
||||
UINT32 w // IN: the value of w
|
||||
)
|
||||
static Crypt_Int* avfSm2(Crypt_Int* bn, // IN/OUT: the reduced value
|
||||
UINT32 w // IN: the value of w
|
||||
)
|
||||
{
|
||||
// a) set w := ceil(ceil(log2(n)) / 2) - 1
|
||||
// b) set x' := 2^w + ( x & (2^w - 1))
|
||||
// This is just like the avf for MQV where x' = 2^w + (x mod 2^w)
|
||||
BnMaskBits(bn, w); // as with avf1, this is too big by a factor of 2 but
|
||||
|
||||
ExtMath_MaskBits(bn, w); // as with avf1, this is too big by a factor of 2 but
|
||||
// it doesn't matter because we SET the extra bit
|
||||
// anyway
|
||||
BnSetBit(bn, w);
|
||||
if(!ExtMath_SetBit(bn, w))
|
||||
{
|
||||
FAIL(FATAL_ERROR_CRYPTO);
|
||||
}
|
||||
return bn;
|
||||
}
|
||||
|
||||
@ -328,60 +341,62 @@ LIB_EXPORT TPM_RC SM2KeyExchange(
|
||||
TPMS_ECC_POINT* QeBIn // IN: ephemeral public party B key
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
const ECC_CURVE_DATA *C;
|
||||
ECC_INITIALIZED(dsA, dsAIn);
|
||||
ECC_INITIALIZED(deA, deAIn);
|
||||
POINT_INITIALIZED(QsB, QsBIn);
|
||||
POINT_INITIALIZED(QeB, QeBIn);
|
||||
BN_WORD_INITIALIZED(One, 1);
|
||||
POINT(QeA);
|
||||
ECC_NUM(XeB);
|
||||
POINT(Z);
|
||||
ECC_NUM(Ta);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_ECC_INITIALIZED(dsA, dsAIn);
|
||||
CRYPT_ECC_INITIALIZED(deA, deAIn);
|
||||
CRYPT_POINT_INITIALIZED(QsB, QsBIn);
|
||||
CRYPT_POINT_INITIALIZED(QeB, QeBIn);
|
||||
CRYPT_INT_WORD_INITIALIZED(One, 1);
|
||||
CRYPT_POINT_VAR(QeA);
|
||||
CRYPT_ECC_NUM(XeB);
|
||||
CRYPT_POINT_VAR(Z);
|
||||
CRYPT_ECC_NUM(Ta);
|
||||
CRYPT_ECC_NUM(QeA_X);
|
||||
UINT32 w;
|
||||
TPM_RC retVal = TPM_RC_NO_RESULT;
|
||||
//
|
||||
// Parameter checks
|
||||
if(E == NULL)
|
||||
ERROR_EXIT(TPM_RC_CURVE);
|
||||
C = AccessCurveData(E);
|
||||
pAssert(outZ != NULL && dsA != NULL && deA != NULL && QsB != NULL && QeB != NULL);
|
||||
|
||||
// Compute the value for w
|
||||
w = ComputeWForSM2(E);
|
||||
w = ComputeWForSM2(curveId);
|
||||
|
||||
// Compute the public ephemeral key pQeA = [de,A]G
|
||||
if(!BnEccModMult(QeA, CurveGetG(C), deA, E))
|
||||
if(!ExtEcc_PointMultiply(QeA, ExtEcc_CurveGetG(curveId), deA, E))
|
||||
goto Exit;
|
||||
|
||||
// tA := (ds,A + de,A avf(Xe,A)) mod n (3)
|
||||
// Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n
|
||||
// Ta = avf(XeA);
|
||||
// do Ta = de,A * Ta = deA * avf(XeA)
|
||||
BnMult(Ta, deA, avfSm2(QeA->x, w));
|
||||
ExtMath_Copy(QeA_X, ExtEcc_PointX(QeA)); // create mutable copy
|
||||
ExtMath_Multiply(Ta, deA, avfSm2(QeA_X, w));
|
||||
// now Ta = dsA + Ta = dsA + deA * avf(XeA)
|
||||
BnAdd(Ta, dsA, Ta);
|
||||
BnMod(Ta, CurveGetOrder(C));
|
||||
ExtMath_Add(Ta, dsA, Ta);
|
||||
ExtMath_Mod(Ta, ExtEcc_CurveGetOrder(curveId));
|
||||
|
||||
// outZ = [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4)
|
||||
// Put this in because almost every case of h is == 1 so skip the call when
|
||||
// not necessary.
|
||||
if(!BnEqualWord(CurveGetCofactor(C), 1))
|
||||
if(!ExtMath_IsEqualWord(ExtEcc_CurveGetCofactor(curveId), 1))
|
||||
// Cofactor is not 1 so compute Ta := Ta * h mod n
|
||||
BnModMult(Ta, Ta, CurveGetCofactor(C), CurveGetOrder(C));
|
||||
ExtMath_ModMult(
|
||||
Ta, Ta, ExtEcc_CurveGetCofactor(curveId), ExtEcc_CurveGetOrder(curveId));
|
||||
// Now that 'tA' is (h * 'tA' mod n)
|
||||
// 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)).
|
||||
BnCopy(XeB, QeB->x);
|
||||
if(!BnEccModMult2(Z, QsB, One, QeB, avfSm2(XeB, w), E))
|
||||
ExtMath_Copy(XeB, ExtEcc_PointX(QeB));
|
||||
if(!ExtEcc_PointMultiplyAndAdd(Z, QsB, One, QeB, avfSm2(XeB, w), E))
|
||||
goto Exit;
|
||||
// QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
|
||||
if(!BnEccModMult(Z, Z, Ta, E))
|
||||
if(!ExtEcc_PointMultiply(Z, Z, Ta, E))
|
||||
goto Exit;
|
||||
// Convert BIGNUM E to TPM2B E
|
||||
BnPointTo2B(outZ, Z, E);
|
||||
// Convert Crypt_Int* E to TPM2B E
|
||||
TpmEcc_PointTo2B(outZ, Z, E);
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
# endif
|
||||
|
||||
@ -60,8 +60,10 @@
|
||||
|
||||
//** Includes and Defines
|
||||
#include "Tpm.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
#include "TpmEcc_Signature_ECDSA_fp.h" // required for pairwise test in key generation
|
||||
#include "Helpers_fp.h" // libtpms added
|
||||
#include "TpmToOsslMath_fp.h" // libtpms added
|
||||
#if ALG_ECC
|
||||
//** Functions
|
||||
|
||||
@ -108,10 +110,9 @@ void ClearPoint2B(TPMS_ECC_POINT* p // IN: the point
|
||||
// Return Type: const TPM_ECC_CURVE_METADATA
|
||||
// NULL curve with the indicated TPM_ECC_CURVE is not implemented
|
||||
// != NULL pointer to the curve data
|
||||
LIB_EXPORT const ECC_CURVE *
|
||||
CryptEccGetParametersByCurveId(
|
||||
TPM_ECC_CURVE curveId // IN: the curveID
|
||||
)
|
||||
LIB_EXPORT const TPM_ECC_CURVE_METADATA* CryptEccGetParametersByCurveId(
|
||||
TPM_ECC_CURVE curveId // IN: the curveID
|
||||
)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < ECC_CURVE_COUNT; i++)
|
||||
@ -127,27 +128,17 @@ CryptEccGetParametersByCurveId(
|
||||
LIB_EXPORT UINT16 CryptEccGetKeySizeForCurve(TPM_ECC_CURVE curveId // IN: the curve
|
||||
)
|
||||
{
|
||||
const ECC_CURVE* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
UINT16 keySizeInBits;
|
||||
const TPM_ECC_CURVE_METADATA* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
UINT16 keySizeInBits;
|
||||
//
|
||||
keySizeInBits = (curve != NULL) ? curve->keySizeBits : 0;
|
||||
return keySizeInBits;
|
||||
}
|
||||
/* 10.2.11.2.6 GetCurveData() */
|
||||
/* This function returns the a pointer for the parameter data associated with a curve. */
|
||||
const ECC_CURVE_DATA *
|
||||
GetCurveData(
|
||||
TPM_ECC_CURVE curveId // IN: the curveID
|
||||
)
|
||||
{
|
||||
const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
|
||||
return (curve != NULL) ? curve->curveData : NULL;
|
||||
}
|
||||
|
||||
//***CryptEccGetOID()
|
||||
const BYTE* CryptEccGetOID(TPM_ECC_CURVE curveId)
|
||||
{
|
||||
const ECC_CURVE*curve = CryptEccGetParametersByCurveId(curveId);
|
||||
const TPM_ECC_CURVE_METADATA* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
return (curve != NULL) ? curve->OID : NULL;
|
||||
}
|
||||
|
||||
@ -161,55 +152,6 @@ LIB_EXPORT TPM_ECC_CURVE CryptEccGetCurveByIndex(UINT16 i)
|
||||
return TPM_ECC_NONE;
|
||||
return eccCurves[i].curveId;
|
||||
}
|
||||
/* 10.2.11.2.8 CryptEccGetParameter() */
|
||||
/* This function returns an ECC curve parameter. The parameter is selected by a single character
|
||||
designator from the set of {PNABXYH}. */
|
||||
/* Return Values Meaning */
|
||||
/* TRUE curve exists and parameter returned */
|
||||
/* FALSE curve does not exist or parameter selector */
|
||||
LIB_EXPORT BOOL
|
||||
CryptEccGetParameter(
|
||||
TPM2B_ECC_PARAMETER *out, // OUT: place to put parameter
|
||||
char p, // IN: the parameter selector
|
||||
TPM_ECC_CURVE curveId // IN: the curve id
|
||||
)
|
||||
{
|
||||
const ECC_CURVE_DATA *curve = GetCurveData(curveId);
|
||||
bigConst parameter = NULL;
|
||||
if(curve != NULL)
|
||||
{
|
||||
switch(p)
|
||||
{
|
||||
case 'p':
|
||||
parameter = CurveGetPrime(curve);
|
||||
break;
|
||||
case 'n':
|
||||
parameter = CurveGetOrder(curve);
|
||||
break;
|
||||
case 'a':
|
||||
parameter = CurveGet_a(curve);
|
||||
break;
|
||||
case 'b':
|
||||
parameter = CurveGet_b(curve);
|
||||
break;
|
||||
case 'x':
|
||||
parameter = CurveGetGx(curve);
|
||||
break;
|
||||
case 'y':
|
||||
parameter = CurveGetGy(curve);
|
||||
break;
|
||||
case 'h':
|
||||
parameter = CurveGetCofactor(curve);
|
||||
break;
|
||||
default:
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If not debugging and we get here with parameter still NULL, had better
|
||||
// not try to convert so just return FALSE instead.
|
||||
return (parameter != NULL) ? BnTo2B(parameter, &out->b, 0) : 0;
|
||||
}
|
||||
|
||||
//*** CryptCapGetECCCurve()
|
||||
// This function returns the list of implemented ECC curves.
|
||||
@ -267,7 +209,8 @@ const TPMT_ECC_SCHEME* CryptGetCurveSignScheme(
|
||||
TPM_ECC_CURVE curveId // IN: The curve selector
|
||||
)
|
||||
{
|
||||
const ECC_CURVE* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
const TPM_ECC_CURVE_METADATA* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
|
||||
if(curve != NULL)
|
||||
return &(curve->sign);
|
||||
else
|
||||
@ -300,7 +243,7 @@ BOOL CryptGenerateR(TPM2B_ECC_PARAMETER* r, // OUT: the generated random
|
||||
UINT64 currentCount = gr.commitCounter;
|
||||
UINT16 t1;
|
||||
//
|
||||
if(!CryptEccGetParameter(&n, 'n', curveID))
|
||||
if(!TpmMath_IntTo2B(ExtEcc_CurveGetOrder(curveID), (TPM2B*)&n, 0))
|
||||
return FALSE;
|
||||
|
||||
// If this is the commit phase, use the current value of the commit counter
|
||||
@ -401,101 +344,72 @@ BOOL CryptEccGetParameters(
|
||||
TPMS_ALGORITHM_DETAIL_ECC* parameters // OUT: ECC parameters
|
||||
)
|
||||
{
|
||||
const ECC_CURVE *curve = CryptEccGetParametersByCurveId(curveId);
|
||||
const ECC_CURVE_DATA *data;
|
||||
const TPM_ECC_CURVE_METADATA* curve = CryptEccGetParametersByCurveId(curveId);
|
||||
BOOL found = curve != NULL;
|
||||
|
||||
if(found)
|
||||
{
|
||||
data = curve->curveData;
|
||||
parameters->curveID = curve->curveId;
|
||||
parameters->keySize = curve->keySizeBits;
|
||||
parameters->kdf = curve->kdf;
|
||||
parameters->sign = curve->sign;
|
||||
/* BnTo2B(data->prime, ¶meters->p.b, 0); */
|
||||
BnTo2B(data->prime, ¶meters->p.b, parameters->p.t.size);
|
||||
BnTo2B(data->a, ¶meters->a.b, parameters->p.t.size /* libtpms changed for HLK */);
|
||||
BnTo2B(data->b, ¶meters->b.b, parameters->p.t.size /* libtpms changed for HLK */);
|
||||
BnTo2B(data->base.x, ¶meters->gX.b, parameters->p.t.size);
|
||||
BnTo2B(data->base.y, ¶meters->gY.b, parameters->p.t.size);
|
||||
BnTo2B(data->order, ¶meters->n.b, 0);
|
||||
BnTo2B(data->h, ¶meters->h.b, 0);
|
||||
parameters->kdf = curve->kdf;
|
||||
parameters->sign = curve->sign;
|
||||
// BnTo2B(data->prime, ¶meters->p.b, 0);
|
||||
found = found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGetPrime(curveId),
|
||||
¶meters->p.b,
|
||||
parameters->p.t.size);
|
||||
found = found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGet_a(curveId), ¶meters->a.b,
|
||||
parameters->p.t.size /* libtpms changed for HLK */);
|
||||
found = found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGet_b(curveId), ¶meters->b.b,
|
||||
parameters->p.t.size /* libtpms changed for HLK */);
|
||||
found = found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGetGx(curveId),
|
||||
¶meters->gX.b,
|
||||
parameters->p.t.size);
|
||||
found = found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGetGy(curveId),
|
||||
¶meters->gY.b,
|
||||
parameters->p.t.size);
|
||||
// BnTo2B(data->base.x, ¶meters->gX.b, 0);
|
||||
// BnTo2B(data->base.y, ¶meters->gY.b, 0);
|
||||
found =
|
||||
found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGetOrder(curveId), ¶meters->n.b, 0);
|
||||
found =
|
||||
found
|
||||
&& TpmMath_IntTo2B(ExtEcc_CurveGetCofactor(curveId), ¶meters->h.b, 0);
|
||||
// if we got into this IF but failed to get a parameter from the external
|
||||
// library, our crypto systems are broken; enter failure mode.
|
||||
if(!found)
|
||||
{
|
||||
FAIL(FATAL_ERROR_MATHLIBRARY);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
/* 10.2.11.2.15 BnGetCurvePrime() */
|
||||
/* This function is used to get just the prime modulus associated with a curve */
|
||||
const bignum_t *
|
||||
BnGetCurvePrime(
|
||||
TPM_ECC_CURVE curveId
|
||||
)
|
||||
{
|
||||
const ECC_CURVE_DATA *C = GetCurveData(curveId);
|
||||
return (C != NULL) ? CurveGetPrime(C) : NULL;
|
||||
}
|
||||
|
||||
/* 10.2.11.2.16 BnGetCurveOrder() */
|
||||
/* This function is used to get just the curve order */
|
||||
const bignum_t *
|
||||
BnGetCurveOrder(
|
||||
TPM_ECC_CURVE curveId
|
||||
)
|
||||
//*** TpmEcc_IsValidPrivateEcc()
|
||||
// Checks that 0 < 'x' < 'q'
|
||||
BOOL TpmEcc_IsValidPrivateEcc(const Crypt_Int* x, // IN: private key to check
|
||||
const Crypt_EccCurve* E // IN: the curve to check
|
||||
)
|
||||
{
|
||||
const ECC_CURVE_DATA *C = GetCurveData(curveId);
|
||||
return (C != NULL) ? CurveGetOrder(C) : NULL;
|
||||
}
|
||||
|
||||
/* 10.2.11.2.17 BnIsOnCurve() */
|
||||
/* This function checks if a point is on the curve. */
|
||||
BOOL
|
||||
BnIsOnCurve(
|
||||
pointConst Q,
|
||||
const ECC_CURVE_DATA *C
|
||||
)
|
||||
{
|
||||
BN_VAR(right, (MAX_ECC_KEY_BITS * 3));
|
||||
BN_VAR(left, (MAX_ECC_KEY_BITS * 2));
|
||||
bigConst prime = CurveGetPrime(C);
|
||||
//
|
||||
// Show that point is on the curve y^2 = x^3 + ax + b;
|
||||
// Or y^2 = x(x^2 + a) + b
|
||||
// y^2
|
||||
BnMult(left, Q->y, Q->y);
|
||||
BnMod(left, prime);
|
||||
// x^2
|
||||
BnMult(right, Q->x, Q->x);
|
||||
// x^2 + a
|
||||
BnAdd(right, right, CurveGet_a(C));
|
||||
// BnMod(right, CurveGetPrime(C));
|
||||
// x(x^2 + a)
|
||||
BnMult(right, right, Q->x);
|
||||
// x(x^2 + a) + b
|
||||
BnAdd(right, right, CurveGet_b(C));
|
||||
BnMod(right, prime);
|
||||
if(BnUnsignedCmp(left, right) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 10.2.11.2.18 BnIsValidPrivateEcc() */
|
||||
/* Checks that 0 < x < q */
|
||||
BOOL
|
||||
BnIsValidPrivateEcc(
|
||||
bigConst x, // IN: private key to check
|
||||
bigCurve E // IN: the curve to check
|
||||
)
|
||||
{
|
||||
BOOL retVal;
|
||||
retVal = (!BnEqualZero(x)
|
||||
&& (BnUnsignedCmp(x, CurveGetOrder(AccessCurveData(E))) < 0));
|
||||
BOOL retVal;
|
||||
retVal =
|
||||
(!ExtMath_IsZero(x)
|
||||
&& (ExtMath_UnsignedCmp(x, ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E)))
|
||||
< 0));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
LIB_EXPORT BOOL CryptEccIsValidPrivateKey(TPM2B_ECC_PARAMETER* d,
|
||||
TPM_ECC_CURVE curveId)
|
||||
{
|
||||
BN_INITIALIZED(bnD, MAX_ECC_PARAMETER_BYTES * 8, d);
|
||||
return !BnEqualZero(bnD) && (BnUnsignedCmp(bnD, BnGetCurveOrder(curveId)) < 0);
|
||||
CRYPT_INT_INITIALIZED(bnD, MAX_ECC_PARAMETER_BYTES * 8, d);
|
||||
return !ExtMath_IsZero(bnD)
|
||||
&& (ExtMath_UnsignedCmp(bnD, ExtEcc_CurveGetOrder(curveId)) < 0);
|
||||
}
|
||||
|
||||
//*** TpmEcc_PointMult()
|
||||
@ -511,14 +425,13 @@ LIB_EXPORT BOOL CryptEccIsValidPrivateKey(TPM2B_ECC_PARAMETER* d,
|
||||
// TPM_RC_ECC_POINT 'S' or 'Q' is not on the curve
|
||||
// TPM_RC_VALUE 'd' or 'u' is not < n
|
||||
TPM_RC
|
||||
BnPointMult(
|
||||
bigPoint R, // OUT: computed point
|
||||
pointConst S, // IN: optional point to multiply by 'd'
|
||||
bigConst d, // IN: scalar for [d]S or [d]G
|
||||
pointConst Q, // IN: optional second point
|
||||
bigConst u, // IN: optional second scalar
|
||||
bigCurve E // IN: curve parameters
|
||||
)
|
||||
TpmEcc_PointMult(Crypt_Point* R, // OUT: computed point
|
||||
const Crypt_Point* S, // IN: optional point to multiply by 'd'
|
||||
const Crypt_Int* d, // IN: scalar for [d]S or [d]G
|
||||
const Crypt_Point* Q, // IN: optional second point
|
||||
const Crypt_Int* u, // IN: optional second scalar
|
||||
const Crypt_EccCurve* E // IN: curve parameters
|
||||
)
|
||||
{
|
||||
BOOL OK;
|
||||
//
|
||||
@ -538,24 +451,25 @@ BnPointMult(
|
||||
OK = OK && (E != NULL);
|
||||
if(!OK)
|
||||
return TPM_RC_VALUE;
|
||||
OK = (S == NULL) || BnIsOnCurve(S, AccessCurveData(E));
|
||||
OK = OK && ((Q == NULL) || BnIsOnCurve(Q, AccessCurveData(E)));
|
||||
|
||||
OK = (S == NULL) || ExtEcc_IsPointOnCurve(S, E);
|
||||
OK = OK && ((Q == NULL) || ExtEcc_IsPointOnCurve(Q, E));
|
||||
if(!OK)
|
||||
return TPM_RC_ECC_POINT;
|
||||
|
||||
if((d != NULL) && (S == NULL))
|
||||
S = CurveGetG(AccessCurveData(E));
|
||||
S = ExtEcc_CurveGetG(ExtEcc_CurveGetCurveId(E));
|
||||
// If only one scalar, don't need Shamir's trick
|
||||
if((d == NULL) || (u == NULL))
|
||||
{
|
||||
if(d == NULL)
|
||||
OK = BnEccModMult(R, Q, u, E);
|
||||
OK = ExtEcc_PointMultiply(R, Q, u, E);
|
||||
else
|
||||
OK = BnEccModMult(R, S, d, E);
|
||||
OK = ExtEcc_PointMultiply(R, S, d, E);
|
||||
}
|
||||
else
|
||||
{
|
||||
OK = BnEccModMult2(R, S, d, Q, u, E);
|
||||
OK = ExtEcc_PointMultiplyAndAdd(R, S, d, Q, u, E);
|
||||
}
|
||||
return (OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT);
|
||||
}
|
||||
@ -569,59 +483,59 @@ BnPointMult(
|
||||
// TRUE(1) success
|
||||
// FALSE(0) failure generating private key
|
||||
#if !USE_OPENSSL_FUNCTIONS_EC // libtpms added
|
||||
BOOL
|
||||
BnEccGetPrivate(
|
||||
bigNum dOut, // OUT: the qualified random value
|
||||
const ECC_CURVE_DATA *C, // IN: curve for which the private key
|
||||
// needs to be appropriate
|
||||
RAND_STATE *rand // IN: state for DRBG
|
||||
)
|
||||
BOOL TpmEcc_GenPrivateScalar(
|
||||
Crypt_Int* dOut, // OUT: the qualified random value
|
||||
const Crypt_EccCurve* E, // IN: curve for which the private key
|
||||
// needs to be appropriate
|
||||
RAND_STATE* rand // IN: state for DRBG
|
||||
)
|
||||
{
|
||||
bigConst order = CurveGetOrder(C);
|
||||
TPM_ECC_CURVE curveId = ExtEcc_CurveGetCurveId(E);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(curveId);
|
||||
BOOL OK;
|
||||
UINT32 orderBits = BnSizeInBits(order);
|
||||
UINT32 orderBits = ExtMath_SizeInBits(order);
|
||||
UINT32 orderBytes = BITS_TO_BYTES(orderBits);
|
||||
BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
|
||||
BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
|
||||
CRYPT_INT_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
|
||||
CRYPT_INT_VAR(nMinus1, MAX_ECC_KEY_BITS);
|
||||
//
|
||||
OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
|
||||
OK = OK && BnSubWord(nMinus1, order, 1);
|
||||
OK = OK && BnMod(bnExtraBits, nMinus1);
|
||||
OK = OK && BnAddWord(dOut, bnExtraBits, 1);
|
||||
OK = BnGetRandomBits((bigNum)bnExtraBits, (orderBytes * 8) + 64, rand); // libtpms: keep for now
|
||||
OK = OK && ExtMath_SubtractWord(nMinus1, order, 1);
|
||||
OK = OK && ExtMath_Mod(bnExtraBits, nMinus1);
|
||||
OK = OK && ExtMath_AddWord(dOut, bnExtraBits, 1);
|
||||
return OK && !g_inFailureMode;
|
||||
}
|
||||
#else // libtpms added begin
|
||||
BOOL
|
||||
BnEccGetPrivate(
|
||||
bigNum dOut, // OUT: the qualified random value
|
||||
const ECC_CURVE_DATA *C, // IN: curve for which the private key
|
||||
const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
|
||||
BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
|
||||
// result may not have leading zero bytes
|
||||
// needs to be appropriate
|
||||
RAND_STATE *rand // IN: state for DRBG
|
||||
)
|
||||
BOOL TpmEcc_GenPrivateScalar(
|
||||
Crypt_Int* dOut, // OUT: the qualified random value
|
||||
const Crypt_EccCurve* E, // IN: curve for which the private key
|
||||
// needs to be appropriate
|
||||
const EC_GROUP* G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL
|
||||
BOOL noLeadingZeros, // IN: require that all bytes in the private key be set
|
||||
// result may not have leading zero bytes
|
||||
RAND_STATE* rand // IN: state for DRBG
|
||||
)
|
||||
{
|
||||
bigConst order = CurveGetOrder(C);
|
||||
BOOL OK;
|
||||
UINT32 orderBits = BnSizeInBits(order);
|
||||
UINT32 orderBytes = BITS_TO_BYTES(orderBits);
|
||||
UINT32 requestedBits = 0;
|
||||
BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
|
||||
BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
|
||||
TPM_ECC_CURVE curveId = ExtEcc_CurveGetCurveId(E);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(curveId);
|
||||
BOOL OK;
|
||||
UINT32 orderBits = ExtMath_SizeInBits(order);
|
||||
UINT32 orderBytes = BITS_TO_BYTES(orderBits);
|
||||
UINT32 requestedBits = 0;
|
||||
CRYPT_INT_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
|
||||
CRYPT_INT_VAR(nMinus1, MAX_ECC_KEY_BITS);
|
||||
|
||||
if (rand == NULL) {
|
||||
if (noLeadingZeros)
|
||||
requestedBits = orderBits;
|
||||
|
||||
return OpenSSLEccGetPrivate(dOut, G, requestedBits);
|
||||
return OpenSSLEccGetPrivate((bigNum)dOut, G, requestedBits);
|
||||
}
|
||||
|
||||
//
|
||||
OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
|
||||
OK = OK && BnSubWord(nMinus1, order, 1);
|
||||
OK = OK && BnMod(bnExtraBits, nMinus1);
|
||||
OK = OK && BnAddWord(dOut, bnExtraBits, 1);
|
||||
OK = BnGetRandomBits((bigNum)bnExtraBits, (orderBytes * 8) + 64, rand); // libtpms: keep for now
|
||||
OK = OK && ExtMath_SubtractWord(nMinus1, order, 1);
|
||||
OK = OK && ExtMath_Mod(bnExtraBits, nMinus1);
|
||||
OK = OK && ExtMath_AddWord(dOut, bnExtraBits, 1);
|
||||
return OK && !g_inFailureMode;
|
||||
}
|
||||
#endif // USE_OPENSSL_FUNCTIONS_EC libtpms added end
|
||||
@ -630,23 +544,18 @@ BnEccGetPrivate(
|
||||
//*** TpmEcc_GenerateKeyPair()
|
||||
// This function gets a private scalar from the source of random bits and does
|
||||
// the point multiply to get the public key.
|
||||
BOOL
|
||||
BnEccGenerateKeyPair(
|
||||
bigNum bnD, // OUT: private scalar
|
||||
bn_point_t *ecQ, // OUT: public point
|
||||
bigCurve E, // IN: curve for the point
|
||||
RAND_STATE *rand // IN: DRBG state to use
|
||||
)
|
||||
BOOL TpmEcc_GenerateKeyPair(Crypt_Int* bnD, // OUT: private scalar
|
||||
Crypt_Point* ecQ, // OUT: public point
|
||||
const Crypt_EccCurve* E, // IN: curve for the point
|
||||
RAND_STATE* rand // IN: DRBG state to use
|
||||
)
|
||||
{
|
||||
BOOL OK = FALSE;
|
||||
// Get a private scalar
|
||||
OK = BnEccGetPrivate(bnD, AccessCurveData(E), rand);
|
||||
OK = TpmEcc_GenPrivateScalar(bnD, E, rand);
|
||||
|
||||
// Do a point multiply
|
||||
OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
|
||||
if(!OK)
|
||||
BnSetWord(ecQ->z, 0);
|
||||
else
|
||||
BnSetWord(ecQ->z, 1);
|
||||
OK = OK && ExtEcc_PointMultiply(ecQ, NULL, bnD, E);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -660,38 +569,32 @@ BnEccGenerateKeyPair(
|
||||
curves whose order is not at the byte boundary, e.g. NIST P521, we simply
|
||||
always add the order of the curve to bnD and call BnEccModMult() with the
|
||||
result bnD1, which leads to the same result. */
|
||||
BOOL
|
||||
BnEccGenerateKeyPair(
|
||||
bigNum bnD, // OUT: private scalar
|
||||
bn_point_t *ecQ, // OUT: public point
|
||||
bigCurve E, // IN: curve for the point
|
||||
RAND_STATE *rand // IN: DRBG state to use
|
||||
BOOL TpmEcc_GenerateKeyPair(Crypt_Int* bnD, // OUT: private scalar
|
||||
Crypt_Point* ecQ, // OUT: public point
|
||||
const Crypt_EccCurve* E, // IN: curve for the point
|
||||
RAND_STATE* rand // IN: DRBG state to use
|
||||
)
|
||||
{
|
||||
BOOL OK = FALSE;
|
||||
bigConst order = CurveGetOrder(AccessCurveData(E));
|
||||
UINT32 orderBits = BnSizeInBits(order);
|
||||
BOOL atByteBoundary = (orderBits & 7) == 0;
|
||||
BOOL noLeadingZeros = atByteBoundary;
|
||||
ECC_NUM(bnD1);
|
||||
BOOL OK = FALSE;
|
||||
TPM_ECC_CURVE curveId = ExtEcc_CurveGetCurveId(E);
|
||||
const Crypt_Int* order = ExtEcc_CurveGetOrder(curveId);
|
||||
UINT32 orderBits = ExtMath_SizeInBits(order);
|
||||
BOOL atByteBoundary = (orderBits & 7) == 0;
|
||||
BOOL noLeadingZeros = atByteBoundary;
|
||||
CRYPT_ECC_NUM(bnD1);
|
||||
|
||||
// We request that bnD not have leading zeros if it is at byte-boundary,
|
||||
// like for example it is the case for NIST P256.
|
||||
OK = BnEccGetPrivate(bnD, AccessCurveData(E), E->G, noLeadingZeros, rand);
|
||||
OK = TpmEcc_GenPrivateScalar(bnD, E, E->G, noLeadingZeros, rand);
|
||||
if (!atByteBoundary) {
|
||||
// for NIST P521 we can add the order to bnD to ensure we have
|
||||
// a constant amount of bytes; the result is the same as if we
|
||||
// were doing the BnEccModMult() calculation with bnD.
|
||||
OK = OK && BnAdd(bnD1, bnD, order);
|
||||
OK = OK && BnEccModMult(ecQ, NULL, bnD1, E);
|
||||
OK = OK && ExtMath_Add(bnD1, bnD, order);
|
||||
OK = OK && ExtEcc_PointMultiply(ecQ, NULL, bnD1, E);
|
||||
} else {
|
||||
OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
|
||||
OK = OK && ExtEcc_PointMultiply(ecQ, NULL, bnD, E);
|
||||
}
|
||||
|
||||
if(!OK)
|
||||
BnSetWord(ecQ->z, 0);
|
||||
else
|
||||
BnSetWord(ecQ->z, 1);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -706,26 +609,26 @@ LIB_EXPORT TPM_RC CryptEccNewKeyPair(
|
||||
TPM_ECC_CURVE curveId // IN: the curve for the key
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
POINT(ecQ);
|
||||
ECC_NUM(bnD);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_POINT_VAR(ecQ);
|
||||
CRYPT_ECC_NUM(bnD);
|
||||
BOOL OK;
|
||||
|
||||
if(E == NULL)
|
||||
return TPM_RC_CURVE;
|
||||
|
||||
TEST(TPM_ALG_ECDH);
|
||||
OK = BnEccGenerateKeyPair(bnD, ecQ, E, NULL);
|
||||
OK = TpmEcc_GenerateKeyPair(bnD, ecQ, E, NULL);
|
||||
if(OK)
|
||||
{
|
||||
BnPointTo2B(Qout, ecQ, E);
|
||||
BnTo2B(bnD, &dOut->b, Qout->x.t.size);
|
||||
TpmEcc_PointTo2B(Qout, ecQ, E);
|
||||
TpmMath_IntTo2B(bnD, &dOut->b, Qout->x.t.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Qout->x.t.size = Qout->y.t.size = dOut->t.size = 0;
|
||||
}
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return OK ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
|
||||
}
|
||||
|
||||
@ -766,20 +669,21 @@ LIB_EXPORT TPM_RC CryptEccPointMultiply(
|
||||
// of Q
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
POINT_INITIALIZED(ecP, Pin);
|
||||
ECC_INITIALIZED(bnD, dIn); // If dIn is null, then bnD is null
|
||||
ECC_INITIALIZED(bnU, uIn);
|
||||
POINT_INITIALIZED(ecQ, Qin);
|
||||
POINT(ecR);
|
||||
TPM_RC retVal;
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_POINT_INITIALIZED(ecP, Pin);
|
||||
CRYPT_ECC_INITIALIZED(bnD, dIn); // If dIn is null, then bnD is null
|
||||
CRYPT_ECC_INITIALIZED(bnU, uIn);
|
||||
CRYPT_POINT_INITIALIZED(ecQ, Qin);
|
||||
CRYPT_POINT_VAR(ecR);
|
||||
TPM_RC retVal;
|
||||
//
|
||||
retVal = BnPointMult(ecR, ecP, bnD, ecQ, bnU, E);
|
||||
retVal = TpmEcc_PointMult(ecR, ecP, bnD, ecQ, bnU, E);
|
||||
|
||||
if(retVal == TPM_RC_SUCCESS)
|
||||
BnPointTo2B(Rout, ecR, E);
|
||||
TpmEcc_PointTo2B(Rout, ecR, E);
|
||||
else
|
||||
ClearPoint2B(Rout);
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -796,12 +700,12 @@ LIB_EXPORT BOOL CryptEccIsPointOnCurve(
|
||||
TPMS_ECC_POINT* Qin // IN: the point.
|
||||
)
|
||||
{
|
||||
const ECC_CURVE_DATA *C = GetCurveData(curveId);
|
||||
POINT_INITIALIZED(ecQ, Qin);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_POINT_INITIALIZED(ecQ, Qin);
|
||||
BOOL OK;
|
||||
//
|
||||
pAssert(Qin != NULL);
|
||||
OK = (C != NULL && (BnIsOnCurve(ecQ, C)));
|
||||
OK = (E != NULL && (ExtEcc_IsPointOnCurve(ecQ, E)));
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -832,9 +736,9 @@ LIB_EXPORT TPM_RC CryptEccGenerateKey(
|
||||
// RNG state
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, publicArea->parameters.eccDetail.curveID);
|
||||
ECC_NUM(bnD);
|
||||
POINT(ecQ);
|
||||
CRYPT_CURVE_INITIALIZED(E, publicArea->parameters.eccDetail.curveID);
|
||||
CRYPT_ECC_NUM(bnD);
|
||||
CRYPT_POINT_VAR(ecQ);
|
||||
BOOL OK;
|
||||
TPM_RC retVal;
|
||||
//
|
||||
@ -847,18 +751,20 @@ LIB_EXPORT TPM_RC CryptEccGenerateKey(
|
||||
publicArea->unique.ecc.x.t.size = 0;
|
||||
publicArea->unique.ecc.y.t.size = 0;
|
||||
sensitive->sensitive.ecc.t.size = 0;
|
||||
OK = BnEccGenerateKeyPair(bnD, ecQ, E, rand);
|
||||
|
||||
OK = TpmEcc_GenerateKeyPair(bnD, ecQ, E, rand);
|
||||
if(OK)
|
||||
{
|
||||
BnPointTo2B(&publicArea->unique.ecc, ecQ, E);
|
||||
BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
|
||||
TpmEcc_PointTo2B(&publicArea->unique.ecc, ecQ, E);
|
||||
TpmMath_IntTo2B(
|
||||
bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
|
||||
}
|
||||
# if FIPS_COMPLIANT
|
||||
// See if PWCT is required
|
||||
if(OK && (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)))
|
||||
if(OK && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
{
|
||||
ECC_NUM(bnT);
|
||||
ECC_NUM(bnS);
|
||||
CRYPT_ECC_NUM(bnT);
|
||||
CRYPT_ECC_NUM(bnS);
|
||||
TPM2B_DIGEST digest;
|
||||
//
|
||||
TEST(TPM_ALG_ECDSA);
|
||||
@ -867,14 +773,15 @@ LIB_EXPORT TPM_RC CryptEccGenerateKey(
|
||||
DRBG_Generate(NULL, digest.t.buffer, digest.t.size);
|
||||
if(g_inFailureMode)
|
||||
return TPM_RC_FAILURE;
|
||||
BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
|
||||
TpmEcc_SignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
|
||||
// and make sure that we can validate the signature
|
||||
OK = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest) == TPM_RC_SUCCESS;
|
||||
OK = TpmEcc_ValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest)
|
||||
== TPM_RC_SUCCESS;
|
||||
}
|
||||
# endif
|
||||
retVal = (OK) ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -886,10 +793,10 @@ CryptEccIsCurveRuntimeUsable(
|
||||
TPMI_ECC_CURVE curveId
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, curveId);
|
||||
CRYPT_CURVE_INITIALIZED(E, curveId);
|
||||
if (E == NULL)
|
||||
return FALSE;
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return TRUE;
|
||||
}
|
||||
// libtpms added end
|
||||
|
||||
@ -60,92 +60,102 @@
|
||||
|
||||
//** Includes and Defines
|
||||
#include "Tpm.h"
|
||||
#include "CryptEccSignature_fp.h"
|
||||
#include "TpmEcc_Signature_ECDAA_fp.h"
|
||||
#include "TpmEcc_Signature_ECDSA_fp.h"
|
||||
#include "TpmEcc_Signature_ECDAA_fp.h"
|
||||
#include "TpmEcc_Signature_Schnorr_fp.h"
|
||||
#include "TpmEcc_Signature_SM2_fp.h"
|
||||
#include "TpmToOsslMath_fp.h" // libtpms added
|
||||
#if ALG_ECC
|
||||
/* 10.2.12.2 Utility Functions */
|
||||
#include "TpmEcc_Util_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
#include "CryptEccSignature_fp.h"
|
||||
|
||||
/* 10.2.12.3.6 CryptEccSign() */
|
||||
/* This function is the dispatch function for the various ECC-based signing schemes. There is a bit
|
||||
of ugliness to the parameter passing. In order to test this, we sometime would like to use a
|
||||
deterministic RNG so that we can get the same signatures during testing. The easiest way to do
|
||||
this for most schemes is to pass in a deterministic RNG and let it return canned values during
|
||||
testing. There is a competing need for a canned parameter to use in ECDAA. To accommodate both
|
||||
needs with minimal fuss, a special type of RAND_STATE is defined to carry the address of the
|
||||
commit value. The setup and handling of this is not very different for the caller than what was
|
||||
in previous versions of the code. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SCHEME scheme is not supported */
|
||||
LIB_EXPORT TPM_RC
|
||||
CryptEccSign(
|
||||
TPMT_SIGNATURE *signature, // OUT: signature
|
||||
OBJECT *signKey, // IN: ECC key to sign the hash
|
||||
const TPM2B_DIGEST *digest, // IN: digest to sign
|
||||
TPMT_ECC_SCHEME *scheme, // IN: signing scheme
|
||||
RAND_STATE *rand
|
||||
)
|
||||
#if ALG_ECC
|
||||
|
||||
//** Utility Functions
|
||||
|
||||
//** Signing Functions
|
||||
|
||||
//*** CryptEccSign()
|
||||
// This function is the dispatch function for the various ECC-based
|
||||
// signing schemes.
|
||||
// There is a bit of ugliness to the parameter passing. In order to test this,
|
||||
// we sometime would like to use a deterministic RNG so that we can get the same
|
||||
// signatures during testing. The easiest way to do this for most schemes is to
|
||||
// pass in a deterministic RNG and let it return canned values during testing.
|
||||
// There is a competing need for a canned parameter to use in ECDAA. To accommodate
|
||||
// both needs with minimal fuss, a special type of RAND_STATE is defined to carry
|
||||
// the address of the commit value. The setup and handling of this is not very
|
||||
// different for the caller than what was in previous versions of the code.
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_SCHEME 'scheme' is not supported
|
||||
LIB_EXPORT TPM_RC CryptEccSign(TPMT_SIGNATURE* signature, // OUT: signature
|
||||
OBJECT* signKey, // IN: ECC key to sign the hash
|
||||
const TPM2B_DIGEST* digest, // IN: digest to sign
|
||||
TPMT_ECC_SCHEME* scheme, // IN: signing scheme
|
||||
RAND_STATE* rand)
|
||||
{
|
||||
CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
|
||||
ECC_INITIALIZED(bnD, &signKey->sensitive.sensitive.ecc.b);
|
||||
ECC_NUM(bnR);
|
||||
ECC_NUM(bnS);
|
||||
const ECC_CURVE_DATA *C;
|
||||
TPM_RC retVal = TPM_RC_SCHEME;
|
||||
CRYPT_CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
|
||||
CRYPT_ECC_INITIALIZED(bnD, &signKey->sensitive.sensitive.ecc.b);
|
||||
CRYPT_ECC_NUM(bnR);
|
||||
CRYPT_ECC_NUM(bnS);
|
||||
TPM_RC retVal = TPM_RC_SCHEME;
|
||||
//
|
||||
NOT_REFERENCED(scheme);
|
||||
if(E == NULL)
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
C = AccessCurveData(E);
|
||||
signature->signature.ecdaa.signatureR.t.size
|
||||
= sizeof(signature->signature.ecdaa.signatureR.t.buffer);
|
||||
signature->signature.ecdaa.signatureS.t.size
|
||||
= sizeof(signature->signature.ecdaa.signatureS.t.buffer);
|
||||
signature->signature.ecdaa.signatureR.t.size =
|
||||
sizeof(signature->signature.ecdaa.signatureR.t.buffer);
|
||||
signature->signature.ecdaa.signatureS.t.size =
|
||||
sizeof(signature->signature.ecdaa.signatureS.t.buffer);
|
||||
TEST(signature->sigAlg);
|
||||
switch(signature->sigAlg)
|
||||
{
|
||||
case TPM_ALG_ECDSA:
|
||||
retVal = BnSignEcdsa(bnR, bnS, E, bnD, digest, rand);
|
||||
retVal = TpmEcc_SignEcdsa(bnR, bnS, E, bnD, digest, rand);
|
||||
break;
|
||||
#if ALG_ECDAA
|
||||
# if ALG_ECDAA
|
||||
case TPM_ALG_ECDAA:
|
||||
retVal = BnSignEcdaa(&signature->signature.ecdaa.signatureR, bnS, E,
|
||||
bnD, digest, scheme, signKey, rand);
|
||||
bnR = NULL;
|
||||
retVal = TpmEcc_SignEcdaa(&signature->signature.ecdaa.signatureR,
|
||||
bnS,
|
||||
E,
|
||||
bnD,
|
||||
digest,
|
||||
scheme,
|
||||
signKey,
|
||||
rand);
|
||||
bnR = NULL;
|
||||
break;
|
||||
#endif
|
||||
#if ALG_ECSCHNORR
|
||||
# endif
|
||||
# if ALG_ECSCHNORR
|
||||
case TPM_ALG_ECSCHNORR:
|
||||
retVal = BnSignEcSchnorr(bnR, bnS, E, bnD, digest,
|
||||
signature->signature.ecschnorr.hash,
|
||||
rand);
|
||||
retVal = TpmEcc_SignEcSchnorr(
|
||||
bnR, bnS, E, bnD, digest, signature->signature.ecschnorr.hash, rand);
|
||||
break;
|
||||
#endif
|
||||
#if ALG_SM2
|
||||
# endif
|
||||
# if ALG_SM2
|
||||
case TPM_ALG_SM2:
|
||||
retVal = BnSignEcSm2(bnR, bnS, E, bnD, digest, rand);
|
||||
retVal = TpmEcc_SignEcSm2(bnR, bnS, E, bnD, digest, rand);
|
||||
break;
|
||||
#endif
|
||||
# endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// If signature generation worked, convert the results.
|
||||
if(retVal == TPM_RC_SUCCESS)
|
||||
{
|
||||
NUMBYTES orderBytes =
|
||||
(NUMBYTES)BITS_TO_BYTES(BnSizeInBits(CurveGetOrder(C)));
|
||||
NUMBYTES orderBytes = (NUMBYTES)BITS_TO_BYTES(
|
||||
ExtMath_SizeInBits(ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E))));
|
||||
if(bnR != NULL)
|
||||
BnTo2B(bnR, &signature->signature.ecdaa.signatureR.b, orderBytes);
|
||||
TpmMath_IntTo2B(
|
||||
bnR, &signature->signature.ecdaa.signatureR.b, orderBytes);
|
||||
if(bnS != NULL)
|
||||
BnTo2B(bnS, &signature->signature.ecdaa.signatureS.b, orderBytes);
|
||||
TpmMath_IntTo2B(
|
||||
bnS, &signature->signature.ecdaa.signatureS.b, orderBytes);
|
||||
}
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//********************* Signature Validation ********************
|
||||
|
||||
//*** CryptEccValidateSignature()
|
||||
@ -159,16 +169,18 @@ LIB_EXPORT TPM_RC CryptEccValidateSignature(
|
||||
const TPM2B_DIGEST* digest // IN: digest that was signed
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
|
||||
ECC_NUM(bnR);
|
||||
ECC_NUM(bnS);
|
||||
POINT_INITIALIZED(ecQ, &signKey->publicArea.unique.ecc);
|
||||
bigConst order;
|
||||
CRYPT_CURVE_INITIALIZED(E, signKey->publicArea.parameters.eccDetail.curveID);
|
||||
CRYPT_ECC_NUM(bnR);
|
||||
CRYPT_ECC_NUM(bnS);
|
||||
CRYPT_POINT_INITIALIZED(ecQ, &signKey->publicArea.unique.ecc);
|
||||
const Crypt_Int* order;
|
||||
TPM_RC retVal;
|
||||
|
||||
if(E == NULL)
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
order = CurveGetOrder(AccessCurveData(E));
|
||||
|
||||
order = ExtEcc_CurveGetOrder(ExtEcc_CurveGetCurveId(E));
|
||||
|
||||
// // Make sure that the scheme is valid
|
||||
switch(signature->sigAlg)
|
||||
{
|
||||
@ -187,37 +199,38 @@ LIB_EXPORT TPM_RC CryptEccValidateSignature(
|
||||
// Can convert r and s after determining that the scheme is an ECC scheme. If
|
||||
// this conversion doesn't work, it means that the unmarshaling code for
|
||||
// an ECC signature is broken.
|
||||
BnFrom2B(bnR, &signature->signature.ecdsa.signatureR.b);
|
||||
BnFrom2B(bnS, &signature->signature.ecdsa.signatureS.b);
|
||||
TpmMath_IntFrom2B(bnR, &signature->signature.ecdsa.signatureR.b);
|
||||
TpmMath_IntFrom2B(bnS, &signature->signature.ecdsa.signatureS.b);
|
||||
|
||||
// r and s have to be greater than 0 but less than the curve order
|
||||
if(BnEqualZero(bnR) || BnEqualZero(bnS))
|
||||
if(ExtMath_IsZero(bnR) || ExtMath_IsZero(bnS))
|
||||
ERROR_EXIT(TPM_RC_SIGNATURE);
|
||||
if((BnUnsignedCmp(bnS, order) >= 0)
|
||||
|| (BnUnsignedCmp(bnR, order) >= 0))
|
||||
if((ExtMath_UnsignedCmp(bnS, order) >= 0)
|
||||
|| (ExtMath_UnsignedCmp(bnR, order) >= 0))
|
||||
ERROR_EXIT(TPM_RC_SIGNATURE);
|
||||
|
||||
switch(signature->sigAlg)
|
||||
{
|
||||
case TPM_ALG_ECDSA:
|
||||
retVal = BnValidateSignatureEcdsa(bnR, bnS, E, ecQ, digest);
|
||||
retVal = TpmEcc_ValidateSignatureEcdsa(bnR, bnS, E, ecQ, digest);
|
||||
break;
|
||||
#if ALG_ECSCHNORR
|
||||
|
||||
# if ALG_ECSCHNORR
|
||||
case TPM_ALG_ECSCHNORR:
|
||||
retVal = BnValidateSignatureEcSchnorr(bnR, bnS,
|
||||
signature->signature.any.hashAlg,
|
||||
E, ecQ, digest);
|
||||
retVal = TpmEcc_ValidateSignatureEcSchnorr(
|
||||
bnR, bnS, signature->signature.any.hashAlg, E, ecQ, digest);
|
||||
break;
|
||||
#endif
|
||||
#if ALG_SM2
|
||||
# endif
|
||||
# if ALG_SM2
|
||||
case TPM_ALG_SM2:
|
||||
retVal = BnValidateSignatureEcSm2(bnR, bnS, E, ecQ, digest);
|
||||
retVal = TpmEcc_ValidateSignatureEcSm2(bnR, bnS, E, ecQ, digest);
|
||||
break;
|
||||
#endif
|
||||
# endif
|
||||
default:
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
}
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
CRYPT_CURVE_FREE(E);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -248,10 +261,11 @@ LIB_EXPORT TPM_RC CryptEccCommitCompute(
|
||||
TPM2B_ECC_PARAMETER* r // IN: the computed r value (required)
|
||||
)
|
||||
{
|
||||
CURVE_INITIALIZED(curve, curveId); // Normally initialize E as the curve, but E means
|
||||
// something else in this function
|
||||
ECC_INITIALIZED(bnR, r);
|
||||
TPM_RC retVal = TPM_RC_SUCCESS;
|
||||
// Normally initialize E as the curve, but
|
||||
// E means something else in this function
|
||||
CRYPT_CURVE_INITIALIZED(curve, curveId);
|
||||
CRYPT_ECC_INITIALIZED(bnR, r);
|
||||
TPM_RC retVal = TPM_RC_SUCCESS;
|
||||
//
|
||||
// Validate that the required parameters are provided.
|
||||
// Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do
|
||||
@ -269,34 +283,37 @@ LIB_EXPORT TPM_RC CryptEccCommitCompute(
|
||||
// If B is provided, compute K=[d]B and L=[r]B
|
||||
if(B != NULL)
|
||||
{
|
||||
ECC_INITIALIZED(bnD, d);
|
||||
POINT_INITIALIZED(pB, B);
|
||||
POINT(pK);
|
||||
POINT(pL);
|
||||
CRYPT_ECC_INITIALIZED(bnD, d);
|
||||
CRYPT_POINT_INITIALIZED(pB, B);
|
||||
CRYPT_POINT_VAR(pK);
|
||||
CRYPT_POINT_VAR(pL);
|
||||
//
|
||||
pAssert(d != NULL && K != NULL && L != NULL);
|
||||
if(!BnIsOnCurve(pB, AccessCurveData(curve)))
|
||||
|
||||
if(!ExtEcc_IsPointOnCurve(pB, curve))
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
// do the math for K = [d]B
|
||||
if((retVal = BnPointMult(pK, pB, bnD, NULL, NULL, curve)) != TPM_RC_SUCCESS)
|
||||
if((retVal = TpmEcc_PointMult(pK, pB, bnD, NULL, NULL, curve))
|
||||
!= TPM_RC_SUCCESS)
|
||||
goto Exit;
|
||||
// Convert BN K to TPM2B K
|
||||
BnPointTo2B(K, pK, curve);
|
||||
TpmEcc_PointTo2B(K, pK, curve);
|
||||
// compute L= [r]B after checking for cancel
|
||||
if(_plat__IsCanceled())
|
||||
ERROR_EXIT(TPM_RC_CANCELED);
|
||||
// compute L = [r]B
|
||||
if(!BnIsValidPrivateEcc(bnR, curve))
|
||||
if(!TpmEcc_IsValidPrivateEcc(bnR, curve))
|
||||
ERROR_EXIT(TPM_RC_VALUE);
|
||||
if((retVal = BnPointMult(pL, pB, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
|
||||
if((retVal = TpmEcc_PointMult(pL, pB, bnR, NULL, NULL, curve))
|
||||
!= TPM_RC_SUCCESS)
|
||||
goto Exit;
|
||||
// Convert BN L to TPM2B L
|
||||
BnPointTo2B(L, pL, curve);
|
||||
TpmEcc_PointTo2B(L, pL, curve);
|
||||
}
|
||||
if((M != NULL) || (B == NULL))
|
||||
{
|
||||
POINT_INITIALIZED(pM, M);
|
||||
POINT(pE);
|
||||
CRYPT_POINT_INITIALIZED(pM, M);
|
||||
CRYPT_POINT_VAR(pE);
|
||||
//
|
||||
// Make sure that a place was provided for the result
|
||||
pAssert(E != NULL);
|
||||
@ -308,13 +325,14 @@ LIB_EXPORT TPM_RC CryptEccCommitCompute(
|
||||
// If M provided, then pM will not be NULL and will compute E = [r]M.
|
||||
// However, if M was not provided, then pM will be NULL and E = [r]G
|
||||
// will be computed
|
||||
if((retVal = BnPointMult(pE, pM, bnR, NULL, NULL, curve)) != TPM_RC_SUCCESS)
|
||||
if((retVal = TpmEcc_PointMult(pE, pM, bnR, NULL, NULL, curve))
|
||||
!= TPM_RC_SUCCESS)
|
||||
goto Exit;
|
||||
// Convert E to 2B format
|
||||
BnPointTo2B(E, pE, curve);
|
||||
TpmEcc_PointTo2B(E, pE, curve);
|
||||
}
|
||||
Exit:
|
||||
CURVE_FREE(curve);
|
||||
CRYPT_CURVE_FREE(curve);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +61,8 @@
|
||||
#include "Tpm.h"
|
||||
#include "ExpDCache_fp.h"
|
||||
#include "Helpers_fp.h"
|
||||
#include "TpmToOsslMath_fp.h"
|
||||
#include "BnToOsslMath_fp.h"
|
||||
#include "TpmMath_Util_fp.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@ -92,6 +92,14 @@
|
||||
#include "BnMemory_fp.h"
|
||||
#include "BnSupport_Interface.h"
|
||||
|
||||
// Create a data object backing a Crypt_Point big enough for the given number of
|
||||
// data bits, per coordinate
|
||||
#define CRYPT_POINT_BUF(buftypename, bits) BN_POINT_BUF(buftypename, bits)
|
||||
|
||||
// Create an instance of a data object underlying Crypt_EccCurve on the stack
|
||||
// sufficient for given bit size. In our case, all are the same size.
|
||||
#define CRYPT_CURVE_BUF(buftypename, max_size_in_bits) bigCurveData
|
||||
|
||||
// now include the math library functional interface and instantiate the
|
||||
// Crypt_Int & related types
|
||||
// TODO_RENAME_INC_FOLDER: This should have a Tpm_Cryptolib_Common component prefix.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user