15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published 25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library 35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines 45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0" 55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16 65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014 75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury 80a05071eda743000b3936bae53374bbe07893848Vadim Bendebury#include <string.h> 90a05071eda743000b3936bae53374bbe07893848Vadim Bendebury 105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "OsslCryptoEngine.h" 110a05071eda743000b3936bae53374bbe07893848Vadim Bendebury 125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECC 135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "CpriDataEcc.h" 145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "CpriDataEcc.c" 155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Functions 185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__EccStartup() 205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is called at TPM Startup to initialize the crypto units. 225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// In this implementation, no initialization is performed at startup but a future version may initialize the self- 235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// test functions here. 245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT BOOL 265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccStartup( 275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury void 285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__GetCurveIdByIndex() 355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function returns the number of the i-th implemented curve. The normal use would be to call this 375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// function with i starting at 0. When the i is greater than or equal to the number of implemented curves, 385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPM_ECC_NONE is returned. 395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 405679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT TPM_ECC_CURVE 415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__GetCurveIdByIndex( 425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 i 435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(i >= ECC_CURVE_COUNT) 465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TPM_ECC_NONE; 475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return eccCurves[i].curveId; 485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT UINT32 505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccGetCurveCount( 515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury void 525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return ECC_CURVE_COUNT; 555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__EccGetParametersByCurveId() 595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function returns a pointer to the curve data that is associated with the indicated curveId. If there is no 615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// curve with the indicated ID, the function returns NULL. 625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// NULL curve with the indicated TPM_ECC_CURVE value is not 695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// implemented 705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// non-NULL pointer to the curve data 715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT const ECC_CURVE * 735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccGetParametersByCurveId( 745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId // IN: the curveID 755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int i; 785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury for(i = 0; i < ECC_CURVE_COUNT; i++) 795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(eccCurves[i].curveId == curveId) 815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return &eccCurves[i]; 825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 840a05071eda743000b3936bae53374bbe07893848Vadim Bendebury 850a05071eda743000b3936bae53374bbe07893848Vadim Bendebury return NULL; // Never reached. 865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 875679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic const ECC_CURVE_DATA * 885679752bf24c21135884e987c4077e2f7184897Vadim BendeburyGetCurveData( 895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId // IN: the curveID 905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE *curve = _cpri__EccGetParametersByCurveId(curveId); 935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return curve->curveData; 945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Point2B() 985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function makes a TPMS_ECC_POINT from a BIGNUM EC_POINT. 1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1015679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL 1025679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPoint2B( 1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group, // IN: group for the point 1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *p, // OUT: receives the converted point 1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *ecP, // IN: the point to convert 1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT16 size, // IN: size of the coordinates 1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context // IN: working context 1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX; 1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnY; 1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnX = BN_CTX_get(context); 1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY = BN_CTX_get(context); 1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnY == NULL 1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the coordinate values 1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || EC_POINT_get_affine_coordinates_GFp(group, ecP, bnX, bnY, context) != 1 1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert x 1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (!BnTo2B(&p->x.b, bnX, size)) 1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert y 1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (!BnTo2B(&p->y.b, bnY, size)) 1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// EccCurveInit() 1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function initializes the OpenSSL() group definition structure 1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is only used within this file. 1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if groupContext is not provided. 1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// NULL the TPM_ECC_CURVE is not valid 1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// non-NULL points to a structure in groupContext static EC_GROUP * 1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1405679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic EC_GROUP * 1415679752bf24c21135884e987c4077e2f7184897Vadim BendeburyEccCurveInit( 1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the ID of the curve 1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *groupContext // IN: the context in which the group is to be 1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // created 1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *P = NULL; 1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnP; 1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnA; 1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnB; 1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX; 1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnY; 1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnH; 1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int ok = FALSE; 1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Context must be provided and curve selector must be valid 1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(groupContext != NULL && curveData != NULL); 1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnP = BN_CTX_get(context); 1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnA = BN_CTX_get(context); 1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnB = BN_CTX_get(context); 1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnX = BN_CTX_get(context); 1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY = BN_CTX_get(context); 1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnH = BN_CTX_get(context); 1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if (bnH == NULL) 1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert the number formats 1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnP, curveData->p); 1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnA, curveData->a); 1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnB, curveData->b); 1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnX, curveData->x); 1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnY, curveData->y); 1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnN, curveData->n); 1815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnH, curveData->h); 1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // initialize EC group, associate a generator point and initialize the point 1835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // from the parameter data 1845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ok = ( (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, groupContext)) != NULL 1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && (P = EC_POINT_new(group)) != NULL 1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, groupContext) 1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && EC_GROUP_set_generator(group, P, bnN, bnH) 1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ); 1895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup: 1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if (!ok && group != NULL) 1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP_free(group); 1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury group = NULL; 1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 1955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(P != NULL) 1965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT_free(P); 1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return group; 2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// PointFrom2B() 2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function sets the coordinates of an existing BN Point from a TPMS_ECC_POINT. 2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2075679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic EC_POINT * 2085679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPointFrom2B( 2095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group, // IN: the group for the point 2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *ecP, // IN: an existing BN point in the group 2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *p, // IN: the 2B coordinates of the point 2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context // IN: the BIGNUM context 2135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX; 2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnY; 2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the point is not allocated then just return a NULL 2185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(ecP == NULL) 2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return NULL; 2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnX = BN_CTX_get(context); 2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY = BN_CTX_get(context); 2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( // Set the coordinates of the point 2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY == NULL 2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(p->x.t.buffer, p->x.t.size, bnX) == NULL 2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(p->y.t.buffer, p->y.t.size, bnY) == NULL 2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !EC_POINT_set_affine_coordinates_GFp(group, ecP, bnX, bnY, context) 2285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return ecP; 2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// EccInitPoint2B() 2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function allocates a point in the provided group and initializes it with the values in a 2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TPMS_ECC_POINT. 2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2405679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic EC_POINT * 2415679752bf24c21135884e987c4077e2f7184897Vadim BendeburyEccInitPoint2B( 2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group, // IN: group for the point 2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *p, // IN: the coordinates for the point 2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context // IN: the BIGNUM context 2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *ecP; 2485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ecP = EC_POINT_new(group); 2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointFrom2B(group, ecP, p, context) == NULL) 2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return ecP; 2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// PointMul() 2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function does a point multiply and checks for the result being the point at infinity. Q = ([A]G + [B]P) 2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_NO_RESULT point is at infinity 2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS point not at infinity 2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2665679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 2675679752bf24c21135884e987c4077e2f7184897Vadim BendeburyPointMul( 2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group, // IN: group curve 2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *ecpQ, // OUT: result 2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnA, // IN: scalar for [A]G 2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *ecpP, // IN: point for [B]P 2725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnB, // IN: scalar for [B]P 2735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context // IN: working context 2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(EC_POINT_mul(group, ecpQ, bnA, ecpP, bnB, context) != 1) 2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(EC_POINT_is_at_infinity(group, ecpQ)) 2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_NO_RESULT; 2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// GetRandomPrivate() 2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function gets a random value (d) to use as a private ECC key and then qualifies the key so that it is 2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// between 0 < d < n. 2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if dOut or pIn is not provided or if the size of pIn is larger than MAX_ECC_KEY_BYTES 2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// (the largest buffer size of a TPM2B_ECC_PARAMETER) 2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2915679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 2925679752bf24c21135884e987c4077e2f7184897Vadim BendeburyGetRandomPrivate( 2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dOut, // OUT: the qualified random value 2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPM2B *pIn // IN: the maximum value for the key 2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int i; 2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE *pb; 2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(pIn != NULL && dOut != NULL && pIn->size <= MAX_ECC_KEY_BYTES); 3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Set the size of the output 3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury dOut->t.size = pIn->size; 3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get some random bits 3035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(TRUE) 3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__GenerateRandom(dOut->t.size, dOut->t.buffer); 3065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // See if the d < n 3075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(memcmp(dOut->t.buffer, pIn->buffer, pIn->size) < 0) 3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // dOut < n so make sure that 0 < dOut 3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury for(pb = dOut->t.buffer, i = dOut->t.size; i > 0; i--) 3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(*pb++ != 0) 3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return; 3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__EccPointMultiply 3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are points on 3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the specified curve and G is the default generator of the curve. 3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// The xOut and yOut parameters are optional and may be set to NULL if not used. 3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be provided. If dIn and 3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// QIn are specified but uIn is not provided, then R = [dIn]QIn. 3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// If the multiply produces the point at infinity, the CRYPT_NO_RESULT is returned. 3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// The sizes of xOut and yOut' will be set to be the size of the degree of the curve 3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is unspecified. 3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS point multiplication succeeded 3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_POINT the point Qin is not on the curve 3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_NO_RESULT the product point is at infinity 3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3405679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccPointMultiply( 3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Rout, // OUT: the product point R 3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve to use 3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: value to multiply against the 3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // curve generator 3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qin, // IN: point Q 3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *uIn // IN: scalar value for the multiplier 3485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of Q 3495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 3505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnD; 3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnU; 3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group; 3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *R = NULL; 3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *Q = NULL; 3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal = CRYPT_SUCCESS; 3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Validate that the required parameters are provided. 3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert((dIn != NULL || uIn != NULL) && (Qin != NULL || dIn != NULL)); 3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If a point is provided for the multiply, make sure that it is on the curve 3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(Qin != NULL && !_cpri__EccIsPointOnCurve(curveId, Qin)) 3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_POINT; 3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnU = BN_CTX_get(context); 3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 3695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury group = EccCurveInit(curveId, context); 3705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // There should be no path for getting a bad curve ID into this function. 3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(group != NULL); 3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // check allocations should have worked and allocate R 3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnD == NULL 3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (R = EC_POINT_new(group)) == NULL) 3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If Qin is present, create the point 3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(Qin != NULL) 3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow. This should not happen in 3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts in which this function will be called. 3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(Qin->x.t); 3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(Qin->x.t); 3835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Q = EccInitPoint2B(group, Qin, context); 3845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(dIn != NULL) 3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 3885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(dIn->t); 3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnD, &dIn->b); 3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = NULL; 3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If uIn is specified, initialize its BIGNUM 3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(uIn != NULL) 3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 3975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 3985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 3995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(uIn->t); 4005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnU, &uIn->b); 4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If uIn is not specified but Q is, then we are going to 4035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // do R = [d]Q 4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else if(Qin != NULL) 4055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnU = bnD; 4075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = NULL; 4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If neither Q nor u is specified, then null this pointer 4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnU = NULL; 4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Use the generator of the curve 4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((retVal = PointMul(group, R, bnD, Q, bnU, context)) == CRYPT_SUCCESS) 414ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr Point2B(group, Rout, R, (INT16) ((EC_GROUP_get_degree(group)+7)/8), context); 4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if (Q) 4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT_free(Q); 4175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(R) 4185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT_free(R); 4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group) 4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP_free(group); 4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 4245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 42516e65be1bdf7ee570373449d8cff729c55fc8776nagendra modadugu#if defined TPM_ALG_ECDAA || defined TPM_ALG_SM2 //% 4265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ClearPoint2B() 4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Initialize the size values of a point 4315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4325679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 4335679752bf24c21135884e987c4077e2f7184897Vadim BendeburyClearPoint2B( 4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *p // IN: the point 4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(p != NULL) { 4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury p->x.t.size = 0; 4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury p->y.t.size = 0; 4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__EccCommitCompute() 4455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function performs the point multiply operations required by TPM2_Commit(). 4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// If B or M is provided, they must be on the curve defined by curveId. This routine does not check that they 4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// are on the curve and results are unpredictable if they are not. 4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if r or d is NULL. If B is not NULL, then it is a fatal error if K and L are both NULL. If M is 4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// not NULL, then it is a fatal error if E is NULL. 4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 4565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS computations completed normally 4585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_NO_RESULT if K, L or E was computed to be the point at infinity 4595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_CANCEL a cancel indication was asserted during this function 4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4615679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccCommitCompute( 4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *K, // OUT: [d]B or [r]Q 4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *L, // OUT: [r]B 4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *E, // OUT: [r]M 4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve for the computations 4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *M, // IN: M (optional) 4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *B, // IN: B (optional) 4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *d, // IN: d (required) 4705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *r // IN: the computed r value (required) 4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 4725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 4740a05071eda743000b3936bae53374bbe07893848Vadim Bendebury BIGNUM *bnY, *bnR, *bnD; 4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group; 4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pK = NULL, *pL = NULL, *pE = NULL, *pM = NULL, *pB = NULL; 4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 keySizeInBytes; 4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal = CRYPT_SUCCESS; 4795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Validate that the required parameters are provided. 4805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do 4815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // E := [r]Q if both M and B are NULL. 4820a05071eda743000b3936bae53374bbe07893848Vadim Bendebury 4830a05071eda743000b3936bae53374bbe07893848Vadim Bendebury pAssert((r && (K || !B) && (L || !B)) || (E || (!M && B))); 4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY = BN_CTX_get(context); 4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnY == NULL) 4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 4935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize the output points in case they are not computed 4945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ClearPoint2B(K); 4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ClearPoint2B(L); 4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ClearPoint2B(E); 4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((group = EccCurveInit(curveId, context)) == NULL) 4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = CRYPT_PARAMETER; 5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup2; 5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 502ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr keySizeInBytes = (UINT16) ((EC_GROUP_get_degree(group)+7)/8); 503d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu // Size of the r parameter may not be zero 504d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu pAssert((int) r->t.size > 0); 5055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert scalars to BIGNUM 5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnR, &r->b); 5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If B is provided, compute K=[d]B and L=[r]B 5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(B != NULL) 5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 510d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu // Size of the d parameter may not be zero 511d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu pAssert((int) d->t.size > 0); 512d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu BnFrom2B(bnD, &d->b); 513d0a96517e517e9a2f3012910ffa1300973616070nagendra modadugu 5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Allocate the points to receive the value 5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( (pK = EC_POINT_new(group)) == NULL 5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (pL = EC_POINT_new(group)) == NULL) 5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // need to compute K = [d]B 5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Allocate and initialize BIGNUM version of B 5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pB = EccInitPoint2B(group, B, context); 5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // do the math for K = [d]B 5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((retVal = PointMul(group, pK, NULL, pB, bnD, context)) != CRYPT_SUCCESS) 5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert BN K to TPM2B K 5255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, K, pK, (INT16)keySizeInBytes, context); 5265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute L= [r]B after checking for cancel 5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_plat__IsCanceled()) 5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = CRYPT_CANCEL; 5305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 5315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute L = [r]B 5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((retVal = PointMul(group, pL, NULL, pB, bnR, context)) != CRYPT_SUCCESS) 5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert BN L to TPM2B L 5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, L, pL, (INT16)keySizeInBytes, context); 5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(M != NULL || B == NULL) 5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if this is the third point multiply, check for cancel first 5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(B != NULL && _plat__IsCanceled()) 5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = CRYPT_CANCEL; 5445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 5455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Allocate E 5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((pE = EC_POINT_new(group)) == NULL) 5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 5495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Create BIGNUM version of M unless M is NULL 5505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(M != NULL) 5515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 5525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // M provided so initialize a BIGNUM M and compute E = [r]M 5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pM = EccInitPoint2B(group, M, context); 5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = PointMul(group, pE, NULL, pM, bnR, context); 5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute E = [r]G (this is only done if M and B are both NULL 5585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = PointMul(group, pE, bnR, NULL, NULL, context); 5595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(retVal == CRYPT_SUCCESS) 5605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert E to 2B format 5615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, E, pE, (INT16)keySizeInBytes, context); 5625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 5635679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup: 5645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP_free(group); 5655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pK != NULL) EC_POINT_free(pK); 5665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pL != NULL) EC_POINT_free(pL); 5675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pE != NULL) EC_POINT_free(pE); 5685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pM != NULL) EC_POINT_free(pM); 5695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pB != NULL) EC_POINT_free(pB); 5705679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup2: 5715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 5725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 5735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 5745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 5755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% 5765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__EccIsPointOnCurve() 5795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is used to test if a point is on a defined curve. It does this by checking that y^2 mod p = x^3 5815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// + a*x + b mod p 5825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if Q is not specified (is NULL). 5835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 5855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TRUE point is on curve 5875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// FALSE point is not on curve or curve is not supported 5885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5895679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT BOOL 5905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__EccIsPointOnCurve( 5915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve selector 5925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Q // IN: the point. 5935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 5945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 5955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 5965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX; 5975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnY; 5985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnA; 5995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnB; 6005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnP; 6015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bn3; 6025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 6035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL retVal; 6045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(Q != NULL && curveData != NULL); 6055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((context = BN_CTX_new()) == NULL) 6065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 6075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 6085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnX = BN_CTX_get(context); 6095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnY = BN_CTX_get(context); 6105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnA = BN_CTX_get(context); 6115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnB = BN_CTX_get(context); 6125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bn3 = BN_CTX_get(context); 6135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnP = BN_CTX_get(context); 6145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnP == NULL) 6155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 6165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert values 6175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if ( !BN_bin2bn(Q->x.t.buffer, Q->x.t.size, bnX) 6185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_bin2bn(Q->y.t.buffer, Q->y.t.size, bnY) 6195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_bin2bn(curveData->p->buffer, curveData->p->size, bnP) 6205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_bin2bn(curveData->a->buffer, curveData->a->size, bnA) 6215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_set_word(bn3, 3) 6225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_bin2bn(curveData->b->buffer, curveData->b->size, bnB) 6235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 6245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 6255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The following sequence is probably not optimal but it seems to be correct. 6265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute x^3 + a*x + b mod p 6275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // first, compute a*x mod p 6285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !BN_mod_mul(bnA, bnA, bnX, bnP, context) 6295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // next, compute a*x + b mod p 6315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_add(bnA, bnA, bnB, bnP, context) 6325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // next, compute X^3 mod p 6335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_exp(bnX, bnX, bn3, bnP, context) 6345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // finally, compute x^3 + a*x + b mod p 6355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_add(bnX, bnX, bnA, bnP, context) 6365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // then compute y^2 6375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_mul(bnY, bnY, bnY, bnP, context) 6385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 6395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 6405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = BN_cmp(bnX, bnY) == 0; 6415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 6425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 6435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 6445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 6455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__GenerateKeyEcc() 6485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function generates an ECC key pair based on the input parameters. This routine uses KDFa() to 6505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// produce candidate numbers. The method is according to FIPS 186-3, section B.4.1 "GKey() Pair 6515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Generation Using Extra Random Bits." According to the method in FIPS 186-3, the resulting private value 6525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// d should be 1 <= d < n where n is the order of the base point. In this implementation, the range of the 6535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// private value is further restricted to be 2^(nLen/2) <= d < n where nLen is the order of n. 6545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// EXAMPLE: If the curve is NIST-P256, then nLen is 256 bits and d will need to be between 2^128 <= d < n 6565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if Qout, dOut, or seed is not provided (is NULL). 6585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 6605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_PARAMETER the hash algorithm is not supported 6625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6635679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 6645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__GenerateKeyEcc( 6655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qout, // OUT: the public point 6665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar 6675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve identifier 6685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm to use in the key 6695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // generation process 6705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *seed, // IN: the seed to use 6715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const char *label, // IN: A label for the generation 6725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process. 6735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *extra, // IN: Party 1 data for the KDF 6745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 *counter // IN/OUT: Counter value to allow KDF 6755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // iteration to be propagated across 6765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // multiple functions 6775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 6785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 6795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 6805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT16 keySizeInBytes; 6815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 count = 0; 6825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal; 6835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 hLen = _cpri__GetDigestSize(hashAlg); 6845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnNm1; // Order of the curve minus one 6855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnD; // the private scalar 6865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; // the context for the BIGNUM values 6875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BYTE withExtra[MAX_ECC_KEY_BYTES + 8]; // trial key with 6885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury //extra bits 6890a05071eda743000b3936bae53374bbe07893848Vadim Bendebury TPM2B_4_BYTE_VALUE marshaledCounter = {.t = {4}}; 6905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32 totalBits; 6915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Validate parameters (these are fatal) 6925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( seed != NULL && dOut != NULL && Qout != NULL && curveData != NULL); 6935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Non-fatal parameter checks. 6945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(hLen <= 0) 6955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_PARAMETER; 6965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // allocate the local BN values 6975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 6985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 6995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 7005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 7015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnNm1 = BN_CTX_get(context); 7025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 7035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The size of the input scalars is limited by the size of the size of a 7045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // TPM2B_ECC_PARAMETER. Make sure that it is not irrational. 7055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert((int) curveData->n->size <= MAX_ECC_KEY_BYTES); 7065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnD == NULL 7075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnNm1) == NULL 7085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (keySizeInBytes = (INT16) BN_num_bytes(bnNm1)) > MAX_ECC_KEY_BYTES) 7095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 7105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // get the total number of bits 7115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury totalBits = BN_num_bits(bnNm1) + 64; 7125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Reduce bnNm1 from 'n' to 'n' - 1 7135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_sub_word(bnNm1, 1); 7145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize the count value 7155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(counter != NULL) 7165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury count = *counter; 7175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(count == 0) 7185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury count = 1; 7195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Start search for key (should be quick) 7205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury for(; count != 0; count++) 7215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 7225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT32_TO_BYTE_ARRAY(count, marshaledCounter.t.buffer); 7235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__KDFa(hashAlg, seed, label, extra, &marshaledCounter.b, 7245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury totalBits, withExtra, NULL, FALSE); 7255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert the result and modular reduce 7265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 7275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 7285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(keySizeInBytes <= MAX_ECC_KEY_BYTES); 7295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if ( BN_bin2bn(withExtra, keySizeInBytes+8, bnD) == NULL 7305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_mod(bnD, bnD, bnNm1, context) != 1) 7315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 7325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Add one to get 0 < d < n 7335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_add_word(bnD, 1); 7345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BnTo2B(&dOut->b, bnD, keySizeInBytes) != 1) 7355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 7365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Do the point multiply to create the public portion of the key. If 7375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the multiply generates the point at infinity (unlikely), do another 7385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // iteration. 7395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( (retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL)) 7405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != CRYPT_NO_RESULT) 7415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 7425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 7435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(count == 0) // if counter wrapped, then the TPM should go into failure mode 7445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 7455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Free up allocated BN values 7465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 7475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 7485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(counter != NULL) 7495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury *counter = count; 7505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 7515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 7525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__GetEphemeralEcc() 7555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part of the 7575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// key will be discarded 7585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7595679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 7605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__GetEphemeralEcc( 7615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qout, // OUT: the public point 7625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dOut, // OUT: the private scalar 7635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId // IN: the curve for the key 7645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 7655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 7665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal; 7675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 7685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveData != NULL); 7695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Keep getting random values until one is found that doesn't create a point 7705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // at infinity. This will never, ever, ever, ever, ever, happen but if it does 7715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // we have to get a next random value. 7725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(TRUE) 7735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 7745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury GetRandomPrivate(dOut, curveData->p); 7755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // _cpri__EccPointMultiply does not return CRYPT_ECC_POINT if no point is 7765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // provided. CRYPT_PARAMTER should not be returned because the curve ID 7775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // has to be supported. Thus the only possible error is CRYPT_NO_RESULT. 7785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL); 7795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(retVal != CRYPT_NO_RESULT) 7805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; // Will return CRYPT_SUCCESS 7815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 7825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 7835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECDSA //% 7845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SignEcdsa() 7875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function implements the ECDSA signing algorithm. The method is described in the comments below. 7895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// It is a fatal error if rOut, sOut, dIn, or digest are not provided. 7905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7915679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 7925679752bf24c21135884e987c4077e2f7184897Vadim BendeburySignEcdsa( 7935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 7945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 7955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 7965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 7975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: the private key 7985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the value to sign 7995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 8005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 8015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnK; 8025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnIk; 8035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 8045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnR; 8055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 8065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnD; 8075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnZ; 8085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER k; 8095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT R; 8105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 8115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal = CRYPT_SUCCESS; 8125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 8135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(rOut != NULL && sOut != NULL && dIn != NULL && digest != NULL); 8145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 8155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 8165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 8175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 8185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 8195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnZ = BN_CTX_get(context); 8205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 8215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 8225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnIk = BN_CTX_get(context); 8235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnK = BN_CTX_get(context); 8245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 8255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 8265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveData->n->size <= MAX_ECC_PARAMETER_BYTES); 8275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnK == NULL 8285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 8295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 8305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// The algorithm as described in "Suite B Implementer's Guide to FIPS 186-3(ECDSA)" 8315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a per-message 8325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// secret number and its inverse modulo n. Since n is prime, the 8335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// output will be invalid only if there is a failure in the RBG. 8345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar 8355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// multiplication (see [Routines]), where G is the base point included in 8365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the set of domain parameters. 8375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3. Compute r = xR mod n. If r = 0, then return to Step 1. 1. 8385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4. Use the selected hash function to compute H = Hash(M). 8395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5. Convert the bit string H to an integer e as described in Appendix B.2. 8405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6. Compute s = (k^-1 * (e + d * r)) mod n. If s = 0, return to Step 1.2. 8415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 7. Return (r, s). 8425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Generate a random value k in the range 1 <= k < n 8435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Want a K value that is the same size as the curve order 8445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury k.t.size = curveData->n->size; 8455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(TRUE) // This implements the loop at step 6. If s is zero, start over. 8465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(TRUE) 8485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Step 1 and 2 -- generate an ephemeral key and the modular inverse 8505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of the private key. 8515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(TRUE) 8525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury GetRandomPrivate(&k, curveData->n); 8545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Do the point multiply to generate a point and check to see if 8555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the point it at infinity 8565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( _cpri__EccPointMultiply(&R, curveId, &k, NULL, NULL) 8575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != CRYPT_NO_RESULT) 8585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; // can only be CRYPT_SUCCESS 8595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // x coordinate is mod p. Make it mod n 8615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen 8625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // in the contexts that this function will be called. 8635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(R.x.t); 8645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_bin2bn(R.x.t.buffer, R.x.t.size, bnR); 8655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_mod(bnR, bnR, bnN, context); 8665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure that it is not zero; 8675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_is_zero(bnR)) 8685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury continue; 8695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure that a modular inverse exists 8705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen 8715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // in the contexts that this function will be called. 8725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(k.t); 8735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_bin2bn(k.t.buffer, k.t.size, bnK); 8745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( BN_mod_inverse(bnIk, bnK, bnN, context) != NULL) 8755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 8765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Set z = leftmost bits of the digest 8785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // NOTE: This is implemented such that the key size needs to be 8795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // an even number of bytes in length. 8805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(digest->size > curveData->n->size) 8815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen 8835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // in the contexts that this function will be called. 8845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveData->n->size <= MAX_ECC_KEY_BYTES); 8855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // digest is larger than n so truncate 8865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_bin2bn(digest->buffer, curveData->n->size, bnZ); 8875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 8895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 8905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen 8915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // in the contexts that this function will be called. 8925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(digest->size <= MAX_DIGEST_SIZE); 8935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // digest is same or smaller than n so use it all 8945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_bin2bn(digest->buffer, digest->size, bnZ); 8955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 8965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 8975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 8985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(dIn->t); 8995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnZ == NULL 9005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // need the private scalar of the signing key 9015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL) 9025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 9035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // NOTE: When the result of an operation is going to be reduced mod x 9045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // any modular multiplication is done so that the intermediate values 9055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // don't get too large. 9065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // 9075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // now have inverse of K (bnIk), z (bnZ), r (bnR), d (bnD) and n (bnN) 9085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute s = k^-1 (z + r*d)(mod n) 9095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // first do d = r*d mod n 9105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !BN_mod_mul(bnD, bnR, bnD, bnN, context) 9115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // d = z + r * d 9125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_add(bnD, bnZ, bnD) 9135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // d = k^(-1)(z + r * d)(mod n) 9145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_mul(bnD, bnIk, bnD, bnN, context) 9155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // convert to TPM2B format 9165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BnTo2B(&sOut->b, bnD, curveData->n->size) 9175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // and write the modular reduced version of r 9185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // NOTE: this was deferred to reduce the number of 9195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // error checks. 9205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BnTo2B(&rOut->b, bnR, curveData->n->size)) 9215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 9225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_is_zero(bnD)) 9235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; // signature not zero so done 9245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if the signature value was zero, start over 9255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 9265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Free up allocated BN values 9275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 9285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 9295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 9305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 9315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% 9325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if defined TPM_ALG_ECDAA || defined TPM_ALG_ECSCHNORR //% 9335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// EcDaa() 9365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is used to perform a modified Schnorr signature for ECDAA. 9385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function performs s = k + T * d mod n where 9395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) 'k is a random, or pseudo-random value used in the commit phase 9405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) T is the digest to be signed, and 9415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) d is a private key. 9425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// If tIn is NULL then use tOut as T 9435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 9455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature created 9475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 9495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyEcDaa( 9505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *tOut, // OUT: T component of the signature 9515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 9525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in signing 9535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: the private key 9545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *tIn, // IN: the value to sign 9555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *kIn // IN: a random value from commit 9565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 9575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 9585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN, *bnK, *bnT, *bnD; 9595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 9605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPM2B *n; 9615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 9625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL OK = TRUE; 9635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Parameter checks 9645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( sOut != NULL && dIn != NULL && tOut != NULL 9655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && kIn != NULL && curveData != NULL); 9665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // this just saves key strokes 9675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury n = curveData->n; 9685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(tIn != NULL) 9695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Copy2B(&tOut->b, tIn); 9705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The size of dIn and kIn input scalars is limited by the size of the size 9715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // of a TPM2B_ECC_PARAMETER and tIn can be no larger than a digest. 9725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Make sure they are within range. 9735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( (int) dIn->t.size <= MAX_ECC_KEY_BYTES 9745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && (int) kIn->t.size <= MAX_ECC_KEY_BYTES 9755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 9765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && (int) tOut->t.size <= MAX_DIGEST_SIZE 9775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ); 9785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 9795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 9805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 9815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 9825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 9835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnK = BN_CTX_get(context); 9845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnT = BN_CTX_get(context); 9855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 9865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Check for allocation problems 9875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnD == NULL) 9885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 9895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert values 9905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( BN_bin2bn(n->buffer, n->size, bnN) == NULL 9915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(kIn->t.buffer, kIn->t.size, bnK) == NULL 9925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL 9935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(tOut->t.buffer, tOut->t.size, bnT) == NULL) 9945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 9955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute T = T mod n 9965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = OK && BN_mod(bnT, bnT, bnN, context); 9975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute (s = k + T * d mod n) 9985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // d = T * d mod n 9995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = OK && BN_mod_mul(bnD, bnT, bnD, bnN, context) == 1; 10005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // d = k + T * d mod n 10015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = OK && BN_mod_add(bnD, bnK, bnD, bnN, context) == 1; 10025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // s = d 10035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = OK && BnTo2B(&sOut->b, bnD, n->size); 10045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // r = T 10055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = OK && BnTo2B(&tOut->b, bnT, n->size); 10065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!OK) 10075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 10085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Cleanup 10095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 10105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 10115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 10125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 10135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% 10145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECSCHNORR //% 10155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10170343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// Mod2B() 10180343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// 10190343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// Function does modular reduction of TPM2B values. 10200343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// 10210343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendeburystatic CRYPT_RESULT 10220343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim BendeburyMod2B( 10230343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury TPM2B *x, // IN/OUT: value to reduce 10240343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury const TPM2B *n // IN: mod 10250343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury ) 10260343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury{ 10270343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury int compare; 10280343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury compare = _math__uComp(x->size, x->buffer, n->size, n->buffer); 10290343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury if(compare < 0) 10300343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury // if x < n, then mod is x 10310343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury return CRYPT_SUCCESS; 10320343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury if(compare == 0) 10330343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury { 10340343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury // if x == n then mod is 0 10350343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury x->size = 0; 10360343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury x->buffer[0] = 0; 10370343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury return CRYPT_SUCCESS; 10380343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury } 10390343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury return _math__Div(x, n, NULL, x); 10400343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury} 10410343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury 10420343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// 10430343d5bfce6fbea1cad2d626e14382f6ebe28667Vadim Bendebury// 10445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SchnorrEcc() 10455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is used to perform a modified Schnorr signature. 10475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function will generate a random value k and compute 10485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) (xR, yR) = [k]G 10495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) r = hash(P || xR)(mod n) 10505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) s= k + r * ds 10515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// d) return the tuple T, s 10525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 10575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature created 10595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SCHEME hashAlg can't produce zero-length digest 10605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 10615679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 10625679752bf24c21135884e987c4077e2f7184897Vadim BendeburySchnorrEcc( 10635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 10645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 10655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm used 10665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in signing 10675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: the private key 10685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest, // IN: the digest to sign 10695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *kIn // IN: for testing 10705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 10715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 10725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER k; 10735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnR, *bnN, *bnK, *bnT, *bnD; 10745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 10755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPM2B *n; 10765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pR = NULL; 10775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 10785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CPRI_HASH_STATE hashState; 10795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 10805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 10815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_PARAMETER_BYTES)); 10825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_T T2b; 10835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL OK = TRUE; 10845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Parameter checks 10855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Must have a place for the 'r' and 's' parts of the signature, a private 10865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // key ('d') 10875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( rOut != NULL && sOut != NULL && dIn != NULL 10885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && digest != NULL && curveData != NULL); 10895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // to save key strokes 10905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury n = curveData->n; 10915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If the digest does not produce a hash, then null the signature and return 10925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // a failure. 10935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(digestSize == 0) 10945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 10955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury rOut->t.size = 0; 10965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury sOut->t.size = 0; 10975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SCHEME; 10985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 10995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Allocate big number values 11005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 11015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 11025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 11035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 11045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 11055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 11065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnK = BN_CTX_get(context); 11075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnT = BN_CTX_get(context); 11085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 11095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnD == NULL 11105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // initialize the group parameters 11115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (group = EccCurveInit(curveId, context)) == NULL 11125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // allocate a local point 11135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (pR = EC_POINT_new(group)) == NULL 11145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 11155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 11165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 11175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 11185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury while(OK) 11195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) set k to a random value such that 1 k n-1 11215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(kIn != NULL) 11225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 11235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Copy2B(&k.b, &kIn->b); // copy input k if testing 11245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = FALSE; // not OK to loop 11255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 11275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If get a random value in the correct range 11285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury GetRandomPrivate(&k, n); 11295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert 'k' and generate pR = ['k']G 11305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnK, &k.b); 11315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) compute E (xE, yE) [k]G 11325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointMul(group, pR, bnK, NULL, NULL, context) == CRYPT_NO_RESULT) 11335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) if E is the point at infinity, go to a) 11345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury continue; 11355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// d) compute e xE (mod n) 11365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the x coordinate of the point 11375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT_get_affine_coordinates_GFp(group, pR, bnR, NULL, context); 11385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // make (mod n) 11395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_mod(bnR, bnR, bnN, context); 11405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// e) if e is zero, go to a) 11415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_is_zero(bnR)) 11425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury continue; 11435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert xR to a string (use T as a temp) 11445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&T2b.b, bnR, (UINT16)(BN_num_bits(bnR)+7)/8); 11455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// f) compute r HschemeHash(P || e) (mod n) 11465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__StartHash(hashAlg, FALSE, &hashState); 11475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__UpdateHash(&hashState, digest->size, digest->buffer); 11485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__UpdateHash(&hashState, T2b.t.size, T2b.t.buffer); 11495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_cpri__CompleteHash(&hashState, digestSize, T2b.b.buffer) != digestSize) 11505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 11515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury T2b.t.size = digestSize; 11525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnT, &T2b.b); 11535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_div(NULL, bnT, bnT, bnN, context); 11545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&rOut->b, bnT, (UINT16)BN_num_bytes(bnT)); 11555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // We have a value and we are going to exit the loop successfully 11565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury OK = TRUE; 11575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 11585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 11595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Cleanup 11605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT_free(pR); 11615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP_free(group); 11625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 11635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 11645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // If we have a value, finish the signature 11655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(OK) 11665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return EcDaa(rOut, sOut, curveId, dIn, NULL, &k); 11675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 11685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_NO_RESULT; 11695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 11705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% 11715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 //% 11725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG //% 11735679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic int 11745679752bf24c21135884e987c4077e2f7184897Vadim Bendeburycmp_bn2hex( 11755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bn, // IN: big number value 11765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const char *c // IN: character string number 11775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 11785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 11795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int result; 11805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnC = BN_new(); 11815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(bnC != NULL); 11825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_hex2bn(&bnC, c); 11835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = BN_ucmp(bn, bnC); 11845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_free(bnC); 11855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 11865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 11875679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic int 11885679752bf24c21135884e987c4077e2f7184897Vadim Bendeburycmp_2B2hex( 11895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *a, // IN: TPM2B number to compare 11905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const char *c // IN: character string 11915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 11925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 11935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int result; 11945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int sl = strlen(c); 11955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnA; 11965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = (a->size * 2) - sl; 11975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(result != 0) 11985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 11995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert((bnA = BN_bin2bn(a->buffer, a->size, NULL)) != NULL); 12005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury result = cmp_bn2hex(bnA, c); 12015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_free(bnA); 12025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return result; 12035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 12045679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void 12055679752bf24c21135884e987c4077e2f7184897Vadim Bendeburycpy_hexTo2B( 12065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *b, // OUT: receives value 12075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const char *c // IN: source string 12085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 12095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 12105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnB = BN_new(); 12115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert((strlen(c) & 1) == 0); // must have an even number of digits 12125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury b->size = strlen(c) / 2; 12135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_hex2bn(&bnB, c); 12145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(bnB != NULL); 12155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(b, bnB, b->size); 12165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_free(bnB); 12175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 12185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% _SM2_SIGN_DEBUG 12195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SignSM2() 12225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function signs a digest using the method defined in SM2 Part 2. The method in the standard will add 12245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a header to the message to be signed that is a hash of the values that define the key. This then hashed 12255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// with the message to produce a digest (e) that is signed. This function signs e. 12265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 12315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS sign worked 12335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 12345679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 12355679752bf24c21135884e987c4077e2f7184897Vadim BendeburySignSM2( 12365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 12375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 12385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in signing 12395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: the private key 12405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the digest to sign 12415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 12425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 12435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnR; 12445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnS; 12455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 12465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnK; 12475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX1; 12485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnD; 12495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnT; // temp 12505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnE; 12515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 12525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER k; 12535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT p2Br; 12545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 12555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveData != NULL); 12565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 12575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 12585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnK = BN_CTX_get(context); 12595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 12605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnS = BN_CTX_get(context); 12615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnX1 = BN_CTX_get(context); 12625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 12635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnD = BN_CTX_get(context); 12645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnT = BN_CTX_get(context); 12655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnE = BN_CTX_get(context); 12665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnE == NULL) 12675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 12685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnE, digest); 12695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnN, curveData->n); 12705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnD, &dIn->b); 12715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 12725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBN_hex2bn(&bnE, "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76"); 12735679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBN_hex2bn(&bnD, "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263"); 12745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 12755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// A3: Use random number generator to generate random number 1 <= k <= n-1; 12765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// NOTE: Ax: numbers are from the SM2 standard 12775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury k.t.size = curveData->n->size; 12785679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyloop: 12795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 12805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get a random number 12815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__GenerateRandom(k.t.size, k.t.buffer); 12825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 12835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBN_hex2bn(&bnK, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F"); 12845679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBnTo2B(&k.b,bnK, 32); 12855679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyk.t.size = 32; 12865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 12875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury //make sure that the number is 0 < k < n 12885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnK, &k.b); 12895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( BN_ucmp(bnK, bnN) >= 0 12905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_is_zero(bnK)) 12915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto loop; 12925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according 12935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// to details specified in 4.2.7 in Part 1 of this document, transform the 12945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// data type of x1 into an integer; 12955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( _cpri__EccPointMultiply(&p2Br, curveId, &k, NULL, NULL) 12965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == CRYPT_NO_RESULT) 12975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto loop; 12985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnX1, &p2Br.x.b); 12995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// A5: Figure out r = (e + x1) mod n, 13005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_mod_add(bnR, bnE, bnX1, bnN, context)) 13015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 13025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 13035679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_bn2hex(bnR, 13045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") 13055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 13065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if r=0 or r+k=n, return to A3; 13085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_add(bnT, bnK, bnR)) 13095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 13105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_is_zero(bnR) || BN_ucmp(bnT, bnN) == 0) 13115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto loop; 13125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n, if s=0, return to A3; 13135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute t = (1+d)-1 13145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_copy(bnT, bnD); 13155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !BN_add_word(bnT, 1) 13165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_inverse(bnT, bnT, bnN, context) // (1 + dA)^-1 mod n 13175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 13185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 13195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 13205679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_bn2hex(bnT, 13215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "79BFCF3052C80DA7B939E0C6914A18CBB2D96D8555256E83122743A7D4F5F956") 13225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 13235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // compute s = t * (k - r * dA) mod n 13255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !BN_mod_mul(bnS, bnD, bnR, bnN, context) // (r * dA) mod n 13265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_sub(bnS, bnK, bnS, bnN, context) // (k - (r * dA) mod n 13275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_mul(bnS, bnT, bnS, bnN, context))// t * (k - (r * dA) mod n 13285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 13295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 13305679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_bn2hex(bnS, 13315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") 13325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 13335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_is_zero(bnS)) 13355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto loop; 13365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 13375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// A7: According to details specified in 4.2.1 in Part 1 of this document, transform 13385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the data type of r, s into bit strings, signature of message M is (r, s). 13395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&rOut->b, bnR, curveData->n->size); 13405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&sOut->b, bnS, curveData->n->size); 13415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 13425679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_2B2hex(&rOut->b, 13435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") 13445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 13455679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_2B2hex(&sOut->b, 13465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") 13475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 13485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 13505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 13515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 13525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 13535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% TPM_ALG_SM2 13545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__SignEcc() 13575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is the dispatch function for the various ECC-based signing schemes. 13595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 13615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SCHEME scheme is not supported 13635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 13645679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 13655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__SignEcc( 13665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rOut, // OUT: r component of the signature 13675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sOut, // OUT: s component of the signature 13685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID scheme, // IN: the scheme selector 13695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: the hash algorithm if need 13705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 13715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 13725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dIn, // IN: the private key 13735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest, // IN: the digest to sign 13745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *kIn // IN: k for input 13755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 13765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 13775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury switch (scheme) 13785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 13795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECDSA: 13805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // SignEcdsa always works 13815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return SignEcdsa(rOut, sOut, curveId, dIn, digest); 13825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 13835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECDAA 13845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECDAA: 13855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(rOut != NULL) 13865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury rOut->b.size = 0; 13875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return EcDaa(rOut, sOut, curveId, dIn, digest, kIn); 13885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 13895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECSCHNORR 13915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECSCHNORR: 13925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return SchnorrEcc(rOut, sOut, hashAlg, curveId, dIn, digest, kIn); 13935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 13945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 13955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 13965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_SM2: 13975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return SignSM2(rOut, sOut, curveId, dIn, digest); 13985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 13995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 14005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury default: 14015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SCHEME; 14025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 14035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 14045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECDSA //% 14055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ValidateSignatureEcdsa() 14085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function validates an ECDSA signature. rIn and sIn shoudl have been checked to make sure that 14105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// they are not zero. 14115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 14135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature valid 14155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_FAIL signature not valid 14165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 14175679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 14185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyValidateSignatureEcdsa( 14195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 14205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 14215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 14225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 14235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qin, // IN: the public point of the key 14245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the digest that was signed 14255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 14265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 14275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER U1; 14285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER U2; 14295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT R; 14305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPM2B *n; 14315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 14325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQ = NULL; 14335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 14345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnU1; 14355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnU2; 14365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnR; 14375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnS; 14385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnW; 14395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnV; 14405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 14415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnE; 14425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnQx; 14435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnQy; 14445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal = CRYPT_FAIL; 14455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int t; 14465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 14475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The curve selector should have been filtered by the unmarshaling process 14485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert (curveData != NULL); 14495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury n = curveData->n; 14505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1. If r and s are not both integers in the interval [1, n - 1], output 14515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// INVALID. 14525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// rIn and sIn are known to be greater than zero (was checked by the caller). 14535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( _math__uComp(rIn->t.size, rIn->t.buffer, n->size, n->buffer) >= 0 14545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || _math__uComp(sIn->t.size, sIn->t.buffer, n->size, n->buffer) >= 0 14555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 14565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 14575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 14585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL) 14595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 14605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 14615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 14625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnS = BN_CTX_get(context); 14635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 14645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnE = BN_CTX_get(context); 14655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnV = BN_CTX_get(context); 14665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnW = BN_CTX_get(context); 14675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnQx = BN_CTX_get(context); 14685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnQy = BN_CTX_get(context); 14695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnU1 = BN_CTX_get(context); 14705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnU2 = BN_CTX_get(context); 14715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Assume the size variables do not overflow, which should not happen in 14725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the contexts that this function will be called. 14735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(Qin->x.t); 14745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(rIn->t); 14755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury assert2Bsize(sIn->t); 14765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // BN_CTX_get() is sticky so only need to check the last value to know that 14775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // all worked. 14785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( bnU2 == NULL 14795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // initialize the group parameters 14805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (group = EccCurveInit(curveId, context)) == NULL 14815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // allocate a local point 14825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (pQ = EC_POINT_new(group)) == NULL 14835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // use the public key values (QxIn and QyIn) to initialize Q 14845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQx) == NULL 14855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQy) == NULL 14865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !EC_POINT_set_affine_coordinates_GFp(group, pQ, bnQx, bnQy, context) 14875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // convert the signature values 14885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(rIn->t.buffer, rIn->t.size, bnR) == NULL 14895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(sIn->t.buffer, sIn->t.size, bnS) == NULL 14905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // convert the curve order 14915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL) 14925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 14935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2. Use the selected hash function to compute H0 = Hash(M0). 14945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // This is an input parameter 14955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3. Convert the bit string H0 to an integer e as described in Appendix B.2. 14965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury t = (digest->size > rIn->t.size) ? rIn->t.size : digest->size; 14975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_bin2bn(digest->buffer, t, bnE) == NULL) 14985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 14995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1. 15005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if (BN_mod_inverse(bnW, bnS, bnN, context) == NULL) 15015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 5. Compute u1 = (e' * w) mod n, and compute u2 = (r' * w) mod n. 15035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !BN_mod_mul(bnU1, bnE, bnW, bnN, context) 15045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_mul(bnU2, bnR, bnW, bnN, context)) 15055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&U1.b, bnU1, (INT16) BN_num_bytes(bnU1)); 15075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnTo2B(&U2.b, bnU2, (INT16) BN_num_bytes(bnU2)); 15085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC 15095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// scalar multiplication and EC addition (see [Routines]). If R is equal to 15105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the point at infinity O, output INVALID. 15115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_cpri__EccPointMultiply(&R, curveId, &U1, Qin, &U2) == CRYPT_SUCCESS) 15125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 15135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // 7. Compute v = Rx mod n. 15145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( BN_bin2bn(R.x.t.buffer, R.x.t.size, bnV) == NULL 15155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod(bnV, bnV, bnN, context)) 15165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID 15185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_cmp(bnV, bnR) == 0) 15195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = CRYPT_SUCCESS; 15205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 15215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQ != NULL) EC_POINT_free(pQ); 15225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group != NULL) EC_GROUP_free(group); 15235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 15245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 15255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 15265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 15275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% TPM_ALG_ECDSA 15285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECSCHNORR //% 15295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ValidateSignatureEcSchnorr() 15325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is used to validate an EC Schnorr signature. rIn and sIn are required to be greater than 15345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// zero. This is checked in _cpri__ValidateSignatureEcc(). 15355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 15375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature valid 15395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_FAIL signature not valid 15405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SCHEME hashAlg is not supported 15415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 15425679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 15435679752bf24c21135884e987c4077e2f7184897Vadim BendeburyValidateSignatureEcSchnorr( 15445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 15455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 15465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: hash algorithm of the signature 15475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 15485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 15495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qin, // IN: the public point of the key 15505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the digest that was signed 15515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 15525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 15535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT pE; 15545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const TPM2B *n; 15555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CPRI_HASH_STATE hashState; 15565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_DIGEST rPrime; 15575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER minusR; 15585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury UINT16 digestSize = _cpri__GetDigestSize(hashAlg); 15595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 15605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // The curve parameter should have been filtered by unmarshaling code 15615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(curveData != NULL); 15625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(digestSize == 0) 15635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SCHEME; 15645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Input parameter validation 15655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(rIn != NULL && sIn != NULL && Qin != NULL && digest != NULL); 15665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury n = curveData->n; 15675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if sIn or rIn are not between 1 and N-1, signature check fails 15685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // sIn and rIn were verified to be non-zero by the caller 15695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( _math__uComp(sIn->b.size, sIn->b.buffer, n->size, n->buffer) >= 0 15705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || _math__uComp(rIn->b.size, rIn->b.buffer, n->size, n->buffer) >= 0 15715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 15725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 15735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury //E = [s]InG - [r]InQ 15745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _math__sub(n->size, n->buffer, 15755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury rIn->t.size, rIn->t.buffer, 15765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury &minusR.t.size, minusR.t.buffer); 15775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_cpri__EccPointMultiply(&pE, curveId, sIn, Qin, &minusR) != CRYPT_SUCCESS) 15785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 15795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Ex = Ex mod N 15805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(Mod2B(&pE.x.b, n) != CRYPT_SUCCESS) 15815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _math__Normalize2B(&pE.x.b); 15835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // rPrime = h(digest || pE.x) mod n; 15845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__StartHash(hashAlg, FALSE, &hashState); 15855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__UpdateHash(&hashState, digest->size, digest->buffer); 15865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury _cpri__UpdateHash(&hashState, pE.x.t.size, pE.x.t.buffer); 15875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_cpri__CompleteHash(&hashState, digestSize, rPrime.t.buffer) != digestSize) 15885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury rPrime.t.size = digestSize; 15905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // rPrime = rPrime (mod n) 15915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(Mod2B(&rPrime.b, n) != CRYPT_SUCCESS) 15925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 15935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // if the values don't match, then the signature is bad 15945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_math__uComp(rIn->t.size, rIn->t.buffer, 15955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury rPrime.t.size, rPrime.t.buffer) != 0) 15965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 15975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 15985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 15995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 16005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% TPM_ALG_ECSCHNORR 16015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 //% 16025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// ValidateSignatueSM2Dsa() 16055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is used to validate an SM2 signature. 16075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 16095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature valid 16115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_FAIL signature not valid 16125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16135679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 16145679752bf24c21135884e987c4077e2f7184897Vadim BendeburyValidateSignatureSM2Dsa( 16155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 16165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 16175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 16185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 16195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qin, // IN: the public point of the key 16205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the digest that was signed 16215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 16225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 16235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnR; 16245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnRp; 16255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnT; 16265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnS; 16275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnE; 1628ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr BIGNUM *order; 16295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQ; 16305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 16315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 16325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 16335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BOOL fail = FALSE; 16345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 16355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((context = BN_CTX_new()) == NULL || curveData == NULL) 16365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 16375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnR = BN_CTX_get(context); 16385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnRp= BN_CTX_get(context); 16395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnE = BN_CTX_get(context); 16405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnT = BN_CTX_get(context); 16415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnS = BN_CTX_get(context); 1642ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr order = BN_CTX_get(context); 1643ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr if( order == NULL 16445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || (group = EccCurveInit(curveId, context)) == NULL) 16455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 16465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 16475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury cpy_hexTo2B(&Qin->x.b, 16485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A"); 16495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury cpy_hexTo2B(&Qin->y.b, 16505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857"); 16515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury cpy_hexTo2B(digest, 16525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76"); 16535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 16545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQ = EccInitPoint2B(group, Qin, context); 16555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 16565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, bnS, context)); 16575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(cmp_bn2hex(bnT, 16585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A") 16595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 16605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(cmp_bn2hex(bnS, 16615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857") 16625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 16635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 16645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnR, &rIn->b); 16655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnS, &sIn->b); 16665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnE, digest); 16675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 16685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Make sure that the input signature is the test signature 16695679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_2B2hex(&rIn->b, 16705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") == 0); 16715679752bf24c21135884e987c4077e2f7184897Vadim BendeburypAssert(cmp_2B2hex(&sIn->b, 16725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") == 0); 16735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 16745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) verify that r and s are in the inclusive interval 1 to (n 1) 1675ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr if (!EC_GROUP_get_order(group, order, context)) goto Cleanup; 1676ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr fail = (BN_ucmp(bnR, order) >= 0); 1677ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr fail = (BN_ucmp(bnS, order) >= 0) || fail; 16785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(fail) 16795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // There is no reason to continue. Since r and s are inputs from the caller, 16805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // they can know that the values are not in the proper range. So, exiting here 16815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // does not disclose any information. 16825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 16835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) compute t := (r + s) mod n 1684ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr if(!BN_mod_add(bnT, bnR, bnS, order, context)) 16855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 16865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 16875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(cmp_bn2hex(bnT, 16885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "2B75F07ED7ECE7CCC1C8986B991F441AD324D6D619FE06DD63ED32E0C997C801") 16895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 16905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 16915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) verify that t > 0 16925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(BN_is_zero(bnT)) { 16935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury fail = TRUE; 16945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // set to a value that should allow rest of the computations to run without 16955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // trouble 16965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_copy(bnT, bnS); 16975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 16985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// d) compute (x, y) := [s]G + [t]Q 16995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!EC_POINT_mul(group, pQ, bnS, pQ, bnT, context)) 17005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 17015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the x coordinate of the point 17025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, NULL, context)) 17035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 17045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef _SM2_SIGN_DEBUG 17055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert(cmp_bn2hex(bnT, 17065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury "110FCDA57615705D5E7B9324AC4B856D23E6D9188B2AE47759514657CE25D112") 17075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury == 0); 17085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 17095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// e) compute r' := (e + x) mod n (the x coordinate is in bnT) 1710ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr if(!BN_mod_add(bnRp, bnE, bnT, order, context)) 17115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 17125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// f) verify that r' = r 17135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury fail = BN_ucmp(bnR, bnRp) != 0 || fail; 17145679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup: 17155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQ) EC_POINT_free(pQ); 17165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group) EC_GROUP_free(group); 17175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 17185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 17195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(fail) 17205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 17215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury else 17225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 17235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 17245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% TPM_ALG_SM2 17255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__ValidateSignatureEcc() 17285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function validates 17305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 17325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS signature is valid 17345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_FAIL not a valid signature 17355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SCHEME unsupported scheme 17365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17375679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 17385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__ValidateSignatureEcc( 17395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *rIn, // IN: r component of the signature 17405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *sIn, // IN: s component of the signature 17415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID scheme, // IN: the scheme selector 17425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID hashAlg, // IN: the hash algorithm used (not used 17435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // in all schemes) 17445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve used in the signature 17455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // process 17465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *Qin, // IN: the public point of the key 17475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B *digest // IN: the digest that was signed 17485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 17495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 17505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal; 17515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // return failure if either part of the signature is zero 17525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(_math__Normalize2B(&rIn->b) == 0 || _math__Normalize2B(&sIn->b) == 0) 17535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 17545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury switch (scheme) 17555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 17565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECDSA: 17575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = ValidateSignatureEcdsa(rIn, sIn, curveId, Qin, digest); 17585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 17595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECSCHNORR 17605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECSCHNORR: 17615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = ValidateSignatureEcSchnorr(rIn, sIn, hashAlg, curveId, Qin, 17625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury digest); 17635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 17645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 17655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 17665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_SM2: 17675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = ValidateSignatureSM2Dsa(rIn, sIn, curveId, Qin, digest); 17685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 17695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury default: 17705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury retVal = CRYPT_SCHEME; 17715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 17725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 17735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 17745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 17755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#if CC_ZGen_2Phase == YES //% 17765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECMQV 17775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// avf1() 17805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function does the associated value computation required by MQV key exchange. Process: 17825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) Convert xQ to an integer xqi using the convention specified in Appendix C.3. 17835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)). 17845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2) 17855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 17865679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL 17875679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyavf1( 17885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX, // IN/OUT: the reduced value 17895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN // IN: the order of the curve 17905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 17915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 17925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// compute f = 2^(ceil(ceil(log2(n)) / 2)) 17935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int f = (BN_num_bits(bnN) + 1) / 2; 17945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// x' = 2^f + (x mod 2^f) 17955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_mask_bits(bnX, f); // This is mod 2*2^f but it doesn't matter because 17965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // the next operation will SET the extra bit anyway 17975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_set_bit(bnX, f); 17985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 17995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 18005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// C_2_2_MQV() 18035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC MQV). 18055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CAUTION: Implementation of this function may require use of essential claims in patents not owned by 18065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// TCG members. 18075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly 18085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// catastrophically, if this is not the case. 18095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 18135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS results is valid 18155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve 18165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 18175679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 18185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyC_2_2_MQV( 18195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ, // OUT: the computed point 18205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve for the computations 18215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 18225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 18235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QsB, // IN: static public party B key 18245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 18255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 18265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 18275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 18285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQeA = NULL; 18295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQeB = NULL; 18305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQsB = NULL; 18315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 18325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnTa; 18335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnDeA; 18345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnDsA; 18355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnXeA; // x coordinate of ephemeral party A key 18365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnH; 18375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 18385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnXeB; 18395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 18405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal; 18415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( curveData != NULL && outZ != NULL && dsA != NULL 18425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && deA != NULL && QsB != NULL && QeB != NULL); 18435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 18445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL || curveData == NULL) 18455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 18465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 18475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnTa = BN_CTX_get(context); 18485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnDeA = BN_CTX_get(context); 18495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnDsA = BN_CTX_get(context); 18505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnXeA = BN_CTX_get(context); 18515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnH = BN_CTX_get(context); 18525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 18535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnXeB = BN_CTX_get(context); 18545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnXeB == NULL) 18555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 18565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Process: 18575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n. 18585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B). 18595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 3. If P = O, output an error indicator. 18605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 4. Z=xP, where xP is the x-coordinate of P. 18615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize group parameters and local values of input 18625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((group = EccCurveInit(curveId, context)) == NULL) 18635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 18645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((pQeA = EC_POINT_new(group)) == NULL) 18655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 18665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnDeA, &deA->b); 18675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnDsA, &dsA->b); 18685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnH, curveData->h); 18695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnN, curveData->n); 18705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnXeB, &QeB->x.b); 18715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQeB = EccInitPoint2B(group, QeB, context); 18725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQsB = EccInitPoint2B(group, QsB, context); 18735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the public ephemeral key pQeA = [de,A]G 18745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context)) 18755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != CRYPT_SUCCESS) 18765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 18775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1) 18785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 18795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n. 18805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// tA := (ds,A + de,A avf(Xe,A)) mod n (3) 18815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n 18825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Ta = avf(XeA); 18835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_copy(bnTa, bnXeA); 18845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury avf1(bnTa, bnN); 18855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(// do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n 18865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury !BN_mod_mul(bnTa, bnDsA, bnTa, bnN, context) 18875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n 18885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_add(bnTa, bnDeA, bnTa, bnN, context) 18895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 18905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 18915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B). 18925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Put this in because almost every case of h is == 1 so skip the call when 18935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // not necessary. 18945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_is_one(bnH)) 18955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 18965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Cofactor is not 1 so compute Ta := Ta * h mod n 18975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_mul(bnTa, bnTa, bnH, context)) 18985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 18995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 19005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Now that 'tA' is (h * 'tA' mod n) 19015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B). 19025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // first, compute XeB = avf(XeB) 19035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury avf1(bnXeB, bnN); 19045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QsB := [XeB]QsB 19055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !EC_POINT_mul(group, pQsB, NULL, pQsB, bnXeB, context) 19065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QeB := QsB + QeB 19075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !EC_POINT_add(group, pQeB, pQeB, pQsB, context) 19085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 19095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 19105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity 19115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS) 19125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert BIGNUM E to TPM2B E 19135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context); 19145679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup: 19155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQeA != NULL) EC_POINT_free(pQeA); 19165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQeB != NULL) EC_POINT_free(pQeB); 19175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQsB != NULL) EC_POINT_free(pQsB); 19185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group != NULL) EC_GROUP_free(group); 19195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 19205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 19215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 19225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 19235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_ECMQV 19245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 //% 19255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// avfSm2() 19285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function does the associated value computation required by SM2 key exchange. This is different 19305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// form the avf() in the international standards because it returns a value that is half the size of the value 19315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// returned by the standard avf. For example, if n is 15, Ws (w in the standard) is 2 but the W here is 1. This 19325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// means that an input value of 14 (1110b) would return a value of 110b with the standard but 10b with the 19335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// scheme in SM2. 19345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19355679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL 19365679752bf24c21135884e987c4077e2f7184897Vadim BendeburyavfSm2( 19375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnX, // IN/OUT: the reduced value 19385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN // IN: the order of the curve 19395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 19405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 19415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// a) set w := ceil(ceil(log2(n)) / 2) - 1 19425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury int w = ((BN_num_bits(bnN) + 1) / 2) - 1; 19435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// b) set x' := 2^w + ( x & (2^w - 1)) 19445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This is just like the avf for MQV where x' = 2^w + (x mod 2^w) 19455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_mask_bits(bnX, w); // as wiht avf1, this is too big by a factor of 2 but 19465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // it doesn't matter becasue we SET the extra bit anyway 19475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_set_bit(bnX, w); 19485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return TRUE; 19495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 19505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to compute 19525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA + 19535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral private 19545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// key. All points are required to be on the curve of inQsA. The function will fail catastrophically if this is not 19555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// the case 19565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 19585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SUCCESS results is valid 19605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_NO_RESULT the value for dsA does not give a valid point on the curve 19615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19625679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 19635679752bf24c21135884e987c4077e2f7184897Vadim BendeburySM2KeyExchange( 19645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ, // OUT: the computed point 19655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve for the computations 19665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 19675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 19685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QsB, // IN: static public party B key 19695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 19705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 19715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 19725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 19735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQeA = NULL; 19745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQeB = NULL; 19755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQsB = NULL; 19765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 19775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnTa; 19785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnDeA; 19795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnDsA; 19805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnXeA; // x coordinate of ephemeral party A key 19815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnH; 19825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnN; 19835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnXeB; 19845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 19855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 19865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury CRYPT_RESULT retVal; 19875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( curveData != NULL && outZ != NULL && dsA != NULL 19885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && deA != NULL && QsB != NULL && QeB != NULL); 19895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 19905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL || curveData == NULL) 19915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 19925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 19935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnTa = BN_CTX_get(context); 19945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnDeA = BN_CTX_get(context); 19955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnDsA = BN_CTX_get(context); 19965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnXeA = BN_CTX_get(context); 19975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnH = BN_CTX_get(context); 19985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnN = BN_CTX_get(context); 19995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury bnXeB = BN_CTX_get(context); 20005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(bnXeB == NULL) 20015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 20025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize group parameters and local values of input 20035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((group = EccCurveInit(curveId, context)) == NULL) 20045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((pQeA = EC_POINT_new(group)) == NULL) 20065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 20075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnDeA, &deA->b); 20085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnDsA, &dsA->b); 20095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnH, curveData->h); 20105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnN, curveData->n); 20115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnXeB, &QeB->x.b); 20125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQeB = EccInitPoint2B(group, QeB, context); 20135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQsB = EccInitPoint2B(group, QsB, context); 20145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Compute the public ephemeral key pQeA = [de,A]G 20155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context)) 20165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury != CRYPT_SUCCESS) 20175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury goto Cleanup; 20185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1) 20195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// tA := (ds,A + de,A avf(Xe,A)) mod n (3) 20215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n 20225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Ta = avf(XeA); 20235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_copy(bnTa, bnXeA); 20245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury avfSm2(bnTa, bnN); 20255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(// do Ta = de,A * Ta mod n = deA * avf(XeA) mod n 20265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury !BN_mod_mul(bnTa, bnDeA, bnTa, bnN, context) 20275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // now Ta = dsA + Ta mod n = dsA + deA * avf(XeA) mod n 20285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !BN_mod_add(bnTa, bnDsA, bnTa, bnN, context) 20295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 20305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// outZ ? [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4) 20325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Put this in because almost every case of h is == 1 so skip the call when 20335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // not necessary. 20345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_is_one(bnH)) 20355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 20365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Cofactor is not 1 so compute Ta := Ta * h mod n 20375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(!BN_mul(bnTa, bnTa, bnH, context)) 20385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 20405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Now that 'tA' is (h * 'tA' mod n) 20415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)). 20425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // first, compute XeB = avf(XeB) 20435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury avfSm2(bnXeB, bnN); 20445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QeB := [XeB]QeB 20455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if( !EC_POINT_mul(group, pQeB, NULL, pQeB, bnXeB, context) 20465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QeB := QsB + QeB 20475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury || !EC_POINT_add(group, pQeB, pQeB, pQsB, context) 20485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 20495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity 20515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS) 20525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert BIGNUM E to TPM2B E 20535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context); 20545679752bf24c21135884e987c4077e2f7184897Vadim BendeburyCleanup: 20555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQeA != NULL) EC_POINT_free(pQeA); 20565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQeB != NULL) EC_POINT_free(pQeB); 20575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQsB != NULL) EC_POINT_free(pQsB); 20585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group != NULL) EC_GROUP_free(group); 20595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 20605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 20615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return retVal; 20625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 20635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% TPM_ALG_SM2 20645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 20655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 20665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// C_2_2_ECDH() 20675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 20685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified Model, 20695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// C(2, 2, ECC CDH). 20705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 20715679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic CRYPT_RESULT 20725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyC_2_2_ECDH( 20735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ1, // OUT: Zs 20745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ2, // OUT: Ze 20755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve for the computations 20765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 20775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 20785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QsB, // IN: static public party B key 20795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 20805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 20815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 2082ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr BIGNUM *order; 20835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX *context; 20845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_POINT *pQ = NULL; 20855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury EC_GROUP *group = NULL; 20865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BIGNUM *bnD; 20875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury INT16 size; 20885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury const ECC_CURVE_DATA *curveData = GetCurveData(curveId); 20895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury context = BN_CTX_new(); 20905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(context == NULL || curveData == NULL) 20915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_ALLOCATION); 20925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_start(context); 2093ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr order = BN_CTX_get(context); 20945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((bnD = BN_CTX_get(context)) == NULL) 20955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 20965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize group parameters and local values of input 20975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if((group = EccCurveInit(curveId, context)) == NULL) 20985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury FAIL(FATAL_ERROR_INTERNAL); 2099ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr if (!EC_GROUP_get_order(group, order, context)) 2100ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr FAIL(FATAL_ERROR_INTERNAL); 2101ddcb1ce5cc06ae4fc84132aed3e7ec1b611075e8Jocelyn Bohr size = (INT16)BN_num_bytes(order); 21025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the static private key of A 21035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnD, &dsA->b); 21045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initialize the static public point from B 21055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pQ = EccInitPoint2B(group, QsB, context); 21065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Do the point multiply for the Zs value 21075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT) 21085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert the Zs value 21095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, outZ1, pQ, size, context); 21105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Get the ephemeral private key of A 21115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BnFrom2B(bnD, &deA->b); 21125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initalize the ephemeral public point from B 21135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury PointFrom2B(group, pQ, QeB, context); 21145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Do the point multiply for the Ze value 21155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT) 21165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Convert the Ze value. 21175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury Point2B(group, outZ2, pQ, size, context); 21185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(pQ != NULL) EC_POINT_free(pQ); 21195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(group != NULL) EC_GROUP_free(group); 21205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_end(context); 21215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury BN_CTX_free(context); 21225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SUCCESS; 21235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 21245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// _cpri__C_2_2_KeyExchange() 21275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This function is the dispatch routine for the EC key exchange function that use two ephemeral and two 21295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// static keys. 21305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Return Value Meaning 21325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// CRYPT_SCHEME scheme is not defined 21345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21355679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 21365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__C_2_2_KeyExchange( 21375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ1, // OUT: a computed point 21385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *outZ2, // OUT: and optional second point 21395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ECC_CURVE curveId, // IN: the curve for the computations 21405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM_ALG_ID scheme, // IN: the key exchange scheme 21415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *dsA, // IN: static private TPM key 21425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPM2B_ECC_PARAMETER *deA, // IN: ephemeral private TPM key 21435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QsB, // IN: static public party B key 21445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury TPMS_ECC_POINT *QeB // IN: ephemeral public party B key 21455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 21465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 21475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury pAssert( outZ1 != NULL 21485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && dsA != NULL && deA != NULL 21495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury && QsB != NULL && QeB != NULL); 21505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // Initalize the output points so that they are empty until one of the 21515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury // functions decides otherwise 21525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outZ1->x.b.size = 0; 21535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outZ1->y.b.size = 0; 21545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury if(outZ2 != NULL) 21555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 21565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outZ2->x.b.size = 0; 21575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury outZ2->y.b.size = 0; 21585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 21595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury switch (scheme) 21605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury { 21615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECDH: 21625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB); 21635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 21645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_ECMQV 21655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_ECMQV: 21665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB); 21675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 21685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 21695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#ifdef TPM_ALG_SM2 21705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury case TPM_ALG_SM2: 21715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB); 21725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury break; 21735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif 21745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury default: 21755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_SCHEME; 21765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury } 21775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 21785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#else //% 21795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Stub used when the 2-phase key exchange is not defined so that the linker has something to associate 21815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// with the value in the .def file. 21825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// 21835679752bf24c21135884e987c4077e2f7184897Vadim BendeburyLIB_EXPORT CRYPT_RESULT 21845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury_cpri__C_2_2_KeyExchange( 21855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury void 21865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury ) 21875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{ 21885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury return CRYPT_FAIL; 21895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury} 21905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif //% CC_ZGen_2Phase 21915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#endif // TPM_ALG_ECC 2192