Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include <string.h>
      9 
     10 #include   "OsslCryptoEngine.h"
     11 
     12 #ifdef TPM_ALG_ECC
     13 #include   "CpriDataEcc.h"
     14 #include   "CpriDataEcc.c"
     15 //
     16 //
     17 //      Functions
     18 //
     19 //      _cpri__EccStartup()
     20 //
     21 //     This function is called at TPM Startup to initialize the crypto units.
     22 //     In this implementation, no initialization is performed at startup but a future version may initialize the self-
     23 //     test functions here.
     24 //
     25 LIB_EXPORT BOOL
     26 _cpri__EccStartup(
     27     void
     28     )
     29 {
     30     return TRUE;
     31 }
     32 //
     33 //
     34 //      _cpri__GetCurveIdByIndex()
     35 //
     36 //     This function returns the number of the i-th implemented curve. The normal use would be to call this
     37 //     function with i starting at 0. When the i is greater than or equal to the number of implemented curves,
     38 //     TPM_ECC_NONE is returned.
     39 //
     40 LIB_EXPORT TPM_ECC_CURVE
     41 _cpri__GetCurveIdByIndex(
     42     UINT16                i
     43     )
     44 {
     45     if(i >= ECC_CURVE_COUNT)
     46         return TPM_ECC_NONE;
     47     return eccCurves[i].curveId;
     48 }
     49 LIB_EXPORT UINT32
     50 _cpri__EccGetCurveCount(
     51     void
     52     )
     53 {
     54     return ECC_CURVE_COUNT;
     55 }
     56 //
     57 //
     58 //      _cpri__EccGetParametersByCurveId()
     59 //
     60 //     This function returns a pointer to the curve data that is associated with the indicated curveId. If there is no
     61 //     curve with the indicated ID, the function returns NULL.
     62 //
     63 //
     64 //
     65 //
     66 //     Return Value                      Meaning
     67 //
     68 //     NULL                              curve with the      indicated   TPM_ECC_CURVE    value   is   not
     69 //                                       implemented
     70 //     non-NULL                          pointer to the curve data
     71 //
     72 LIB_EXPORT const ECC_CURVE *
     73 _cpri__EccGetParametersByCurveId(
     74    TPM_ECC_CURVE       curveId               // IN: the curveID
     75    )
     76 {
     77    int          i;
     78    for(i = 0; i < ECC_CURVE_COUNT; i++)
     79    {
     80        if(eccCurves[i].curveId == curveId)
     81            return &eccCurves[i];
     82    }
     83    FAIL(FATAL_ERROR_INTERNAL);
     84 
     85    return NULL; // Never reached.
     86 }
     87 static const ECC_CURVE_DATA *
     88 GetCurveData(
     89    TPM_ECC_CURVE       curveId               // IN: the curveID
     90    )
     91 {
     92    const ECC_CURVE     *curve = _cpri__EccGetParametersByCurveId(curveId);
     93    return curve->curveData;
     94 }
     95 //
     96 //
     97 //      Point2B()
     98 //
     99 //     This function makes a TPMS_ECC_POINT from a BIGNUM EC_POINT.
    100 //
    101 static BOOL
    102 Point2B(
    103    EC_GROUP           *group,                //   IN: group for the point
    104    TPMS_ECC_POINT     *p,                    //   OUT: receives the converted point
    105    EC_POINT           *ecP,                  //   IN: the point to convert
    106    INT16               size,                 //   IN: size of the coordinates
    107    BN_CTX             *context               //   IN: working context
    108    )
    109 {
    110    BIGNUM             *bnX;
    111    BIGNUM             *bnY;
    112    BN_CTX_start(context);
    113    bnX = BN_CTX_get(context);
    114    bnY = BN_CTX_get(context);
    115    if(        bnY == NULL
    116         // Get the coordinate values
    117        || EC_POINT_get_affine_coordinates_GFp(group, ecP, bnX, bnY, context) != 1
    118        // Convert x
    119        || (!BnTo2B(&p->x.b, bnX, size))
    120        // Convert y
    121        || (!BnTo2B(&p->y.b, bnY, size))
    122       )
    123             FAIL(FATAL_ERROR_INTERNAL);
    124    BN_CTX_end(context);
    125    return TRUE;
    126 }
    127 //
    128 //
    129 //       EccCurveInit()
    130 //
    131 //      This function initializes the OpenSSL() group definition structure
    132 //      This function is only used within this file.
    133 //      It is a fatal error if groupContext is not provided.
    134 //
    135 //      Return Value                       Meaning
    136 //
    137 //      NULL                               the TPM_ECC_CURVE is not valid
    138 //      non-NULL                           points to a structure in groupContext static EC_GROUP *
    139 //
    140 static EC_GROUP *
    141 EccCurveInit(
    142     TPM_ECC_CURVE         curveId,             // IN: the ID of the curve
    143     BN_CTX               *groupContext         // IN: the context in which the group is to be
    144                                                //     created
    145     )
    146 {
    147     const ECC_CURVE_DATA            *curveData = GetCurveData(curveId);
    148     EC_GROUP                        *group = NULL;
    149     EC_POINT                        *P = NULL;
    150     BN_CTX                          *context;
    151     BIGNUM                          *bnP;
    152     BIGNUM                          *bnA;
    153     BIGNUM                          *bnB;
    154     BIGNUM                          *bnX;
    155     BIGNUM                          *bnY;
    156     BIGNUM                          *bnN;
    157     BIGNUM                          *bnH;
    158     int                              ok = FALSE;
    159     // Context must be provided and curve selector must be valid
    160     pAssert(groupContext != NULL && curveData != NULL);
    161     context = BN_CTX_new();
    162     if(context == NULL)
    163         FAIL(FATAL_ERROR_ALLOCATION);
    164     BN_CTX_start(context);
    165     bnP = BN_CTX_get(context);
    166     bnA = BN_CTX_get(context);
    167     bnB = BN_CTX_get(context);
    168     bnX = BN_CTX_get(context);
    169     bnY = BN_CTX_get(context);
    170     bnN = BN_CTX_get(context);
    171     bnH = BN_CTX_get(context);
    172     if (bnH == NULL)
    173         goto Cleanup;
    174     // Convert the number formats
    175     BnFrom2B(bnP,      curveData->p);
    176     BnFrom2B(bnA,      curveData->a);
    177     BnFrom2B(bnB,      curveData->b);
    178     BnFrom2B(bnX,      curveData->x);
    179     BnFrom2B(bnY,      curveData->y);
    180     BnFrom2B(bnN,      curveData->n);
    181     BnFrom2B(bnH,      curveData->h);
    182    // initialize EC group, associate a generator point and initialize the point
    183    // from the parameter data
    184    ok = (   (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, groupContext)) != NULL
    185          && (P = EC_POINT_new(group)) != NULL
    186          && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, groupContext)
    187          && EC_GROUP_set_generator(group, P, bnN, bnH)
    188         );
    189 Cleanup:
    190    if (!ok && group != NULL)
    191    {
    192        EC_GROUP_free(group);
    193        group = NULL;
    194    }
    195    if(P != NULL)
    196        EC_POINT_free(P);
    197    BN_CTX_end(context);
    198    BN_CTX_free(context);
    199    return group;
    200 }
    201 //
    202 //
    203 //       PointFrom2B()
    204 //
    205 //      This function sets the coordinates of an existing BN Point from a TPMS_ECC_POINT.
    206 //
    207 static EC_POINT *
    208 PointFrom2B(
    209    EC_GROUP           *group,           //   IN:   the group for the point
    210    EC_POINT           *ecP,             //   IN:   an existing BN point in the group
    211    TPMS_ECC_POINT     *p,               //   IN:   the 2B coordinates of the point
    212    BN_CTX             *context          //   IN:   the BIGNUM context
    213    )
    214 {
    215    BIGNUM             *bnX;
    216    BIGNUM             *bnY;
    217    // If the point is not allocated then just return a NULL
    218    if(ecP == NULL)
    219        return NULL;
    220    BN_CTX_start(context);
    221    bnX = BN_CTX_get(context);
    222    bnY = BN_CTX_get(context);
    223    if( // Set the coordinates of the point
    224          bnY == NULL
    225       || BN_bin2bn(p->x.t.buffer, p->x.t.size, bnX) == NULL
    226       || BN_bin2bn(p->y.t.buffer, p->y.t.size, bnY) == NULL
    227       || !EC_POINT_set_affine_coordinates_GFp(group, ecP, bnX, bnY, context)
    228       )
    229       FAIL(FATAL_ERROR_INTERNAL);
    230    BN_CTX_end(context);
    231    return ecP;
    232 }
    233 //
    234 //
    235 //       EccInitPoint2B()
    236 //
    237 //      This function allocates a point in the provided group and initializes it with the values in a
    238 //      TPMS_ECC_POINT.
    239 //
    240 static EC_POINT *
    241 EccInitPoint2B(
    242    EC_GROUP           *group,           // IN: group for the point
    243    TPMS_ECC_POINT     *p,               // IN: the coordinates for the point
    244     BN_CTX              *context                // IN: the BIGNUM context
    245     )
    246 {
    247     EC_POINT            *ecP;
    248     BN_CTX_start(context);
    249     ecP = EC_POINT_new(group);
    250     if(PointFrom2B(group, ecP, p, context) == NULL)
    251         FAIL(FATAL_ERROR_INTERNAL);
    252     BN_CTX_end(context);
    253     return ecP;
    254 }
    255 //
    256 //
    257 //       PointMul()
    258 //
    259 //      This function does a point multiply and checks for the result being the point at infinity. Q = ([A]G + [B]P)
    260 //
    261 //      Return Value                      Meaning
    262 //
    263 //      CRYPT_NO_RESULT                   point is at infinity
    264 //      CRYPT_SUCCESS                     point not at infinity
    265 //
    266 static CRYPT_RESULT
    267 PointMul(
    268     EC_GROUP            *group,                 //      IN: group curve
    269     EC_POINT            *ecpQ,                  //      OUT: result
    270     BIGNUM              *bnA,                   //      IN: scalar for [A]G
    271     EC_POINT            *ecpP,                  //      IN: point for [B]P
    272     BIGNUM              *bnB,                   //      IN: scalar for [B]P
    273     BN_CTX              *context                //      IN: working context
    274     )
    275 {
    276        if(EC_POINT_mul(group, ecpQ, bnA, ecpP, bnB, context) != 1)
    277             FAIL(FATAL_ERROR_INTERNAL);
    278         if(EC_POINT_is_at_infinity(group, ecpQ))
    279             return CRYPT_NO_RESULT;
    280         return CRYPT_SUCCESS;
    281 }
    282 //
    283 //
    284 //       GetRandomPrivate()
    285 //
    286 //      This function gets a random value (d) to use as a private ECC key and then qualifies the key so that it is
    287 //      between 0 < d < n.
    288 //      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
    289 //      (the largest buffer size of a TPM2B_ECC_PARAMETER)
    290 //
    291 static void
    292 GetRandomPrivate(
    293     TPM2B_ECC_PARAMETER            *dOut,                    // OUT: the qualified random value
    294     const TPM2B                    *pIn                      // IN: the maximum value for the key
    295     )
    296 {
    297     int             i;
    298     BYTE           *pb;
    299     pAssert(pIn != NULL && dOut != NULL && pIn->size <= MAX_ECC_KEY_BYTES);
    300     // Set the size of the output
    301     dOut->t.size = pIn->size;
    302     // Get some random bits
    303     while(TRUE)
    304     {
    305         _cpri__GenerateRandom(dOut->t.size, dOut->t.buffer);
    306         // See if the d < n
    307         if(memcmp(dOut->t.buffer, pIn->buffer, pIn->size) < 0)
    308         {
    309             // dOut < n so make sure that 0 < dOut
    310             for(pb = dOut->t.buffer, i = dOut->t.size; i > 0; i--)
    311             {
    312                 if(*pb++ != 0)
    313                     return;
    314             }
    315         }
    316     }
    317 }
    318 //
    319 //
    320 //       _cpri__EccPointMultiply
    321 //
    322 //      This function computes 'R := [dIn]G + [uIn]QIn. Where dIn and uIn are scalars, G and QIn are points on
    323 //      the specified curve and G is the default generator of the curve.
    324 //      The xOut and yOut parameters are optional and may be set to NULL if not used.
    325 //      It is not necessary to provide uIn if QIn is specified but one of uIn and dIn must be provided. If dIn and
    326 //      QIn are specified but uIn is not provided, then R = [dIn]QIn.
    327 //      If the multiply produces the point at infinity, the CRYPT_NO_RESULT is returned.
    328 //      The sizes of xOut and yOut' will be set to be the size of the degree of the curve
    329 //      It is a fatal error if dIn and uIn are both unspecified (NULL) or if Qin or Rout is unspecified.
    330 //
    331 //
    332 //
    333 //
    334 //      Return Value                    Meaning
    335 //
    336 //      CRYPT_SUCCESS                   point multiplication succeeded
    337 //      CRYPT_POINT                     the point Qin is not on the curve
    338 //      CRYPT_NO_RESULT                 the product point is at infinity
    339 //
    340 LIB_EXPORT CRYPT_RESULT
    341 _cpri__EccPointMultiply(
    342    TPMS_ECC_POINT                *Rout,                  //   OUT: the product point R
    343    TPM_ECC_CURVE                  curveId,               //   IN: the curve to use
    344    TPM2B_ECC_PARAMETER           *dIn,                   //   IN: value to multiply against the
    345                                                          //       curve generator
    346    TPMS_ECC_POINT                *Qin,                   //   IN: point Q
    347    TPM2B_ECC_PARAMETER           *uIn                    //   IN: scalar value for the multiplier
    348                                                          //       of Q
    349    )
    350 {
    351    BN_CTX                    *context;
    352    BIGNUM                    *bnD;
    353    BIGNUM                    *bnU;
    354    EC_GROUP                  *group;
    355    EC_POINT                  *R = NULL;
    356    EC_POINT                  *Q = NULL;
    357    CRYPT_RESULT               retVal = CRYPT_SUCCESS;
    358    // Validate that the required parameters are provided.
    359    pAssert((dIn != NULL || uIn != NULL) && (Qin != NULL || dIn != NULL));
    360    // If a point is provided for the multiply, make sure that it is on the curve
    361    if(Qin != NULL && !_cpri__EccIsPointOnCurve(curveId, Qin))
    362        return CRYPT_POINT;
    363    context = BN_CTX_new();
    364    if(context == NULL)
    365        FAIL(FATAL_ERROR_ALLOCATION);
    366    BN_CTX_start(context);
    367    bnU = BN_CTX_get(context);
    368    bnD = BN_CTX_get(context);
    369    group = EccCurveInit(curveId, context);
    370    // There should be no path for getting a bad curve ID into this function.
    371    pAssert(group != NULL);
    372    // check allocations should have worked and allocate R
    373    if(   bnD == NULL
    374       || (R = EC_POINT_new(group)) == NULL)
    375        FAIL(FATAL_ERROR_ALLOCATION);
    376    // If Qin is present, create the point
    377    if(Qin != NULL)
    378    {
    379        // Assume the size variables do not overflow. This should not happen in
    380        // the contexts in which this function will be called.
    381        assert2Bsize(Qin->x.t);
    382        assert2Bsize(Qin->x.t);
    383        Q = EccInitPoint2B(group, Qin, context);
    384    }
    385    if(dIn != NULL)
    386    {
    387        // Assume the size variables do not overflow, which should not happen in
    388        // the contexts that this function will be called.
    389        assert2Bsize(dIn->t);
    390         BnFrom2B(bnD, &dIn->b);
    391     }
    392     else
    393         bnD = NULL;
    394     // If uIn is specified, initialize its BIGNUM
    395     if(uIn != NULL)
    396     {
    397         // Assume the size variables do not overflow, which should not happen in
    398         // the contexts that this function will be called.
    399         assert2Bsize(uIn->t);
    400         BnFrom2B(bnU, &uIn->b);
    401     }
    402     // If uIn is not specified but Q is, then we are going to
    403     // do R = [d]Q
    404     else if(Qin != NULL)
    405     {
    406         bnU = bnD;
    407         bnD = NULL;
    408     }
    409     // If neither Q nor u is specified, then null this pointer
    410     else
    411         bnU = NULL;
    412     // Use the generator of the curve
    413     if((retVal = PointMul(group, R, bnD, Q, bnU, context)) == CRYPT_SUCCESS)
    414         Point2B(group, Rout, R, (INT16) ((EC_GROUP_get_degree(group)+7)/8), context);
    415     if (Q)
    416         EC_POINT_free(Q);
    417     if(R)
    418         EC_POINT_free(R);
    419     if(group)
    420         EC_GROUP_free(group);
    421     BN_CTX_end(context);
    422     BN_CTX_free(context);
    423     return retVal;
    424 }
    425 //
    426 //
    427 //       ClearPoint2B()
    428 //
    429 //      Initialize the size values of a point
    430 //
    431 static void
    432 ClearPoint2B(
    433     TPMS_ECC_POINT       *p                 // IN: the point
    434     )
    435 {
    436     if(p != NULL) {
    437         p->x.t.size = 0;
    438         p->y.t.size = 0;
    439     }
    440 }
    441 #if defined TPM_ALG_ECDAA || defined TPM_ALG_SM2 //%
    442 //
    443 //
    444 //       _cpri__EccCommitCompute()
    445 //
    446 //      This function performs the point multiply operations required by TPM2_Commit().
    447 //      If B or M is provided, they must be on the curve defined by curveId. This routine does not check that they
    448 //      are on the curve and results are unpredictable if they are not.
    449 //
    450 //
    451 //
    452 //      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
    453 //      not NULL, then it is a fatal error if E is NULL.
    454 //
    455 //      Return Value                       Meaning
    456 //
    457 //      CRYPT_SUCCESS                      computations completed normally
    458 //      CRYPT_NO_RESULT                    if K, L or E was computed to be the point at infinity
    459 //      CRYPT_CANCEL                       a cancel indication was asserted during this function
    460 //
    461 LIB_EXPORT CRYPT_RESULT
    462 _cpri__EccCommitCompute(
    463     TPMS_ECC_POINT                  *K,                   //   OUT: [d]B or [r]Q
    464     TPMS_ECC_POINT                  *L,                   //   OUT: [r]B
    465     TPMS_ECC_POINT                  *E,                   //   OUT: [r]M
    466     TPM_ECC_CURVE                    curveId,             //   IN: the curve for the computations
    467     TPMS_ECC_POINT                  *M,                   //   IN: M (optional)
    468     TPMS_ECC_POINT                  *B,                   //   IN: B (optional)
    469     TPM2B_ECC_PARAMETER             *d,                   //   IN: d (required)
    470     TPM2B_ECC_PARAMETER             *r                    //   IN: the computed r value (required)
    471     )
    472 {
    473     BN_CTX                    *context;
    474     BIGNUM                    *bnY, *bnR, *bnD;
    475     EC_GROUP                  *group;
    476     EC_POINT                  *pK = NULL, *pL = NULL, *pE = NULL, *pM = NULL, *pB = NULL;
    477     UINT16                     keySizeInBytes;
    478     CRYPT_RESULT               retVal = CRYPT_SUCCESS;
    479     // Validate that the required parameters are provided.
    480     // Note: E has to be provided if computing E := [r]Q or E := [r]M. Will do
    481     // E := [r]Q if both M and B are NULL.
    482 
    483     pAssert((r && (K || !B) && (L || !B)) || (E || (!M && B)));
    484     context = BN_CTX_new();
    485     if(context == NULL)
    486         FAIL(FATAL_ERROR_ALLOCATION);
    487     BN_CTX_start(context);
    488     bnR = BN_CTX_get(context);
    489     bnD = BN_CTX_get(context);
    490     bnY = BN_CTX_get(context);
    491     if(bnY == NULL)
    492         FAIL(FATAL_ERROR_ALLOCATION);
    493     // Initialize the output points in case they are not computed
    494     ClearPoint2B(K);
    495     ClearPoint2B(L);
    496     ClearPoint2B(E);
    497     if((group = EccCurveInit(curveId, context)) == NULL)
    498     {
    499         retVal = CRYPT_PARAMETER;
    500         goto Cleanup2;
    501     }
    502     keySizeInBytes = (UINT16) ((EC_GROUP_get_degree(group)+7)/8);
    503     // Sizes of the r and d parameters may not be zero
    504     pAssert(((int) r->t.size > 0) && ((int) d->t.size > 0));
    505     // Convert scalars to BIGNUM
    506     BnFrom2B(bnR, &r->b);
    507     BnFrom2B(bnD, &d->b);
    508    // If B is provided, compute K=[d]B and L=[r]B
    509    if(B != NULL)
    510    {
    511        // Allocate the points to receive the value
    512        if(    (pK = EC_POINT_new(group)) == NULL
    513            || (pL = EC_POINT_new(group)) == NULL)
    514        FAIL(FATAL_ERROR_ALLOCATION);
    515        // need to compute K = [d]B
    516        // Allocate and initialize BIGNUM version of B
    517        pB = EccInitPoint2B(group, B, context);
    518         // do the math for K = [d]B
    519         if((retVal = PointMul(group, pK, NULL, pB, bnD, context)) != CRYPT_SUCCESS)
    520             goto Cleanup;
    521         // Convert BN K to TPM2B K
    522         Point2B(group, K, pK, (INT16)keySizeInBytes, context);
    523         // compute L= [r]B after checking for cancel
    524         if(_plat__IsCanceled())
    525         {
    526             retVal = CRYPT_CANCEL;
    527             goto Cleanup;
    528         }
    529         // compute L = [r]B
    530         if((retVal = PointMul(group, pL, NULL, pB, bnR, context)) != CRYPT_SUCCESS)
    531             goto Cleanup;
    532         // Convert BN L to TPM2B L
    533         Point2B(group, L, pL, (INT16)keySizeInBytes, context);
    534    }
    535    if(M != NULL || B == NULL)
    536    {
    537        // if this is the third point multiply, check for cancel first
    538        if(B != NULL && _plat__IsCanceled())
    539        {
    540            retVal = CRYPT_CANCEL;
    541            goto Cleanup;
    542        }
    543         // Allocate E
    544         if((pE = EC_POINT_new(group)) == NULL)
    545             FAIL(FATAL_ERROR_ALLOCATION);
    546         // Create BIGNUM version of M unless M is NULL
    547         if(M != NULL)
    548         {
    549              // M provided so initialize a BIGNUM M and compute E = [r]M
    550              pM = EccInitPoint2B(group, M, context);
    551              retVal = PointMul(group, pE, NULL, pM, bnR, context);
    552         }
    553         else
    554              // compute E = [r]G (this is only done if M and B are both NULL
    555              retVal = PointMul(group, pE, bnR, NULL, NULL, context);
    556         if(retVal == CRYPT_SUCCESS)
    557             // Convert E to 2B format
    558             Point2B(group, E, pE, (INT16)keySizeInBytes, context);
    559    }
    560 Cleanup:
    561    EC_GROUP_free(group);
    562    if(pK != NULL) EC_POINT_free(pK);
    563    if(pL != NULL) EC_POINT_free(pL);
    564    if(pE != NULL) EC_POINT_free(pE);
    565    if(pM != NULL) EC_POINT_free(pM);
    566    if(pB != NULL) EC_POINT_free(pB);
    567 Cleanup2:
    568    BN_CTX_end(context);
    569    BN_CTX_free(context);
    570    return retVal;
    571 }
    572 #endif //%
    573 //
    574 //
    575 //       _cpri__EccIsPointOnCurve()
    576 //
    577 //      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
    578 //      + a*x + b mod p
    579 //      It is a fatal error if Q is not specified (is NULL).
    580 //
    581 //      Return Value                        Meaning
    582 //
    583 //      TRUE                                point is on curve
    584 //      FALSE                               point is not on curve or curve is not supported
    585 //
    586 LIB_EXPORT BOOL
    587 _cpri__EccIsPointOnCurve(
    588     TPM_ECC_CURVE          curveId,             // IN: the curve selector
    589     TPMS_ECC_POINT        *Q                    // IN: the point.
    590     )
    591 {
    592     BN_CTX                           *context;
    593     BIGNUM                           *bnX;
    594     BIGNUM                           *bnY;
    595     BIGNUM                           *bnA;
    596     BIGNUM                           *bnB;
    597     BIGNUM                           *bnP;
    598     BIGNUM                           *bn3;
    599     const ECC_CURVE_DATA             *curveData = GetCurveData(curveId);
    600     BOOL                              retVal;
    601     pAssert(Q != NULL && curveData != NULL);
    602     if((context = BN_CTX_new()) == NULL)
    603         FAIL(FATAL_ERROR_ALLOCATION);
    604     BN_CTX_start(context);
    605     bnX = BN_CTX_get(context);
    606     bnY = BN_CTX_get(context);
    607     bnA = BN_CTX_get(context);
    608     bnB = BN_CTX_get(context);
    609     bn3 = BN_CTX_get(context);
    610     bnP = BN_CTX_get(context);
    611     if(bnP == NULL)
    612         FAIL(FATAL_ERROR_ALLOCATION);
    613     // Convert values
    614     if (    !BN_bin2bn(Q->x.t.buffer, Q->x.t.size, bnX)
    615          || !BN_bin2bn(Q->y.t.buffer, Q->y.t.size, bnY)
    616          || !BN_bin2bn(curveData->p->buffer, curveData->p->size, bnP)
    617          || !BN_bin2bn(curveData->a->buffer, curveData->a->size, bnA)
    618          || !BN_set_word(bn3, 3)
    619          || !BN_bin2bn(curveData->b->buffer, curveData->b->size, bnB)
    620        )
    621          FAIL(FATAL_ERROR_INTERNAL);
    622     // The following sequence is probably not optimal but it seems to be correct.
    623     // compute x^3 + a*x + b mod p
    624             // first, compute a*x mod p
    625     if(   !BN_mod_mul(bnA, bnA, bnX, bnP, context)
    626 //
    627               // next, compute a*x + b mod p
    628          || !BN_mod_add(bnA, bnA, bnB, bnP, context)
    629               // next, compute X^3 mod p
    630          || !BN_mod_exp(bnX, bnX, bn3, bnP, context)
    631               // finally, compute x^3 + a*x + b mod p
    632          || !BN_mod_add(bnX, bnX, bnA, bnP, context)
    633               // then compute y^2
    634          || !BN_mod_mul(bnY, bnY, bnY, bnP, context)
    635         )
    636           FAIL(FATAL_ERROR_INTERNAL);
    637     retVal = BN_cmp(bnX, bnY) == 0;
    638     BN_CTX_end(context);
    639     BN_CTX_free(context);
    640     return retVal;
    641 }
    642 //
    643 //
    644 //       _cpri__GenerateKeyEcc()
    645 //
    646 //      This function generates an ECC key pair based on the input parameters. This routine uses KDFa() to
    647 //      produce candidate numbers. The method is according to FIPS 186-3, section B.4.1 "GKey() Pair
    648 //      Generation Using Extra Random Bits." According to the method in FIPS 186-3, the resulting private value
    649 //      d should be 1 <= d < n where n is the order of the base point. In this implementation, the range of the
    650 //      private value is further restricted to be 2^(nLen/2) <= d < n where nLen is the order of n.
    651 //
    652 //      EXAMPLE:         If the curve is NIST-P256, then nLen is 256 bits and d will need to be between 2^128 <= d < n
    653 //
    654 //      It is a fatal error if Qout, dOut, or seed is not provided (is NULL).
    655 //
    656 //      Return Value                         Meaning
    657 //
    658 //      CRYPT_PARAMETER                      the hash algorithm is not supported
    659 //
    660 LIB_EXPORT CRYPT_RESULT
    661 _cpri__GenerateKeyEcc(
    662     TPMS_ECC_POINT                    *Qout,                  //   OUT: the public point
    663     TPM2B_ECC_PARAMETER               *dOut,                  //   OUT: the private scalar
    664     TPM_ECC_CURVE                      curveId,               //   IN: the curve identifier
    665     TPM_ALG_ID                         hashAlg,               //   IN: hash algorithm to use in the key
    666                                                               //       generation process
    667     TPM2B                             *seed,                  //   IN: the seed to use
    668     const char                        *label,                 //   IN: A label for the generation
    669                                                               //       process.
    670     TPM2B                             *extra,                 //   IN: Party 1 data for the KDF
    671     UINT32                            *counter                //   IN/OUT: Counter value to allow KDF
    672                                                               //       iteration to be propagated across
    673                                                               //       multiple functions
    674     )
    675 {
    676     const ECC_CURVE_DATA              *curveData = GetCurveData(curveId);
    677     INT16                              keySizeInBytes;
    678     UINT32                             count = 0;
    679     CRYPT_RESULT                       retVal;
    680     UINT16                             hLen = _cpri__GetDigestSize(hashAlg);
    681     BIGNUM                            *bnNm1;          // Order of the curve minus one
    682     BIGNUM                            *bnD;            // the private scalar
    683     BN_CTX                            *context;        // the context for the BIGNUM values
    684     BYTE                               withExtra[MAX_ECC_KEY_BYTES + 8]; // trial key with
    685                                                                            //extra bits
    686     TPM2B_4_BYTE_VALUE                 marshaledCounter = {.t = {4}};
    687     UINT32                             totalBits;
    688     // Validate parameters (these are fatal)
    689    pAssert(     seed != NULL && dOut != NULL && Qout != NULL && curveData != NULL);
    690    // Non-fatal parameter checks.
    691    if(hLen <= 0)
    692        return CRYPT_PARAMETER;
    693    // allocate the local BN values
    694    context = BN_CTX_new();
    695    if(context == NULL)
    696        FAIL(FATAL_ERROR_ALLOCATION);
    697    BN_CTX_start(context);
    698    bnNm1 = BN_CTX_get(context);
    699    bnD = BN_CTX_get(context);
    700    // The size of the input scalars is limited by the size of the size of a
    701    // TPM2B_ECC_PARAMETER. Make sure that it is not irrational.
    702    pAssert((int) curveData->n->size <= MAX_ECC_KEY_BYTES);
    703    if(   bnD == NULL
    704       || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnNm1) == NULL
    705       || (keySizeInBytes = (INT16) BN_num_bytes(bnNm1)) > MAX_ECC_KEY_BYTES)
    706        FAIL(FATAL_ERROR_INTERNAL);
    707    // get the total number of bits
    708    totalBits = BN_num_bits(bnNm1) + 64;
    709    // Reduce bnNm1 from 'n' to 'n' - 1
    710    BN_sub_word(bnNm1, 1);
    711    // Initialize the count value
    712    if(counter != NULL)
    713        count = *counter;
    714    if(count == 0)
    715        count = 1;
    716    // Start search for key (should be quick)
    717    for(; count != 0; count++)
    718    {
    719         UINT32_TO_BYTE_ARRAY(count, marshaledCounter.t.buffer);
    720         _cpri__KDFa(hashAlg, seed, label, extra, &marshaledCounter.b,
    721                     totalBits, withExtra, NULL, FALSE);
    722         // Convert the result and modular reduce
    723         // Assume the size variables do not overflow, which should not happen in
    724         // the contexts that this function will be called.
    725         pAssert(keySizeInBytes <= MAX_ECC_KEY_BYTES);
    726         if (    BN_bin2bn(withExtra, keySizeInBytes+8, bnD) == NULL
    727              || BN_mod(bnD, bnD, bnNm1, context) != 1)
    728              FAIL(FATAL_ERROR_INTERNAL);
    729         // Add one to get 0 < d < n
    730         BN_add_word(bnD, 1);
    731         if(BnTo2B(&dOut->b, bnD, keySizeInBytes) != 1)
    732                 FAIL(FATAL_ERROR_INTERNAL);
    733         // Do the point multiply to create the public portion of the key. If
    734         // the multiply generates the point at infinity (unlikely), do another
    735         // iteration.
    736         if(    (retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL))
    737             != CRYPT_NO_RESULT)
    738             break;
    739    }
    740    if(count == 0) // if counter wrapped, then the TPM should go into failure mode
    741        FAIL(FATAL_ERROR_INTERNAL);
    742    // Free up allocated BN values
    743    BN_CTX_end(context);
    744    BN_CTX_free(context);
    745    if(counter != NULL)
    746        *counter = count;
    747    return retVal;
    748 }
    749 //
    750 //
    751 //       _cpri__GetEphemeralEcc()
    752 //
    753 //      This function creates an ephemeral ECC. It is ephemeral in that is expected that the private part of the
    754 //      key will be discarded
    755 //
    756 LIB_EXPORT CRYPT_RESULT
    757 _cpri__GetEphemeralEcc(
    758    TPMS_ECC_POINT                *Qout,            // OUT: the public point
    759    TPM2B_ECC_PARAMETER           *dOut,            // OUT: the private scalar
    760    TPM_ECC_CURVE                  curveId          // IN: the curve for the key
    761    )
    762 {
    763    CRYPT_RESULT                   retVal;
    764    const ECC_CURVE_DATA          *curveData = GetCurveData(curveId);
    765    pAssert(curveData != NULL);
    766    // Keep getting random values until one is found that doesn't create a point
    767    // at infinity. This will never, ever, ever, ever, ever, happen but if it does
    768    // we have to get a next random value.
    769    while(TRUE)
    770    {
    771        GetRandomPrivate(dOut, curveData->p);
    772         // _cpri__EccPointMultiply does not return CRYPT_ECC_POINT if no point is
    773         // provided. CRYPT_PARAMTER should not be returned because the curve ID
    774         // has to be supported. Thus the only possible error is CRYPT_NO_RESULT.
    775         retVal = _cpri__EccPointMultiply(Qout, curveId, dOut, NULL, NULL);
    776         if(retVal != CRYPT_NO_RESULT)
    777             return retVal; // Will return CRYPT_SUCCESS
    778    }
    779 }
    780 #ifdef TPM_ALG_ECDSA      //%
    781 //
    782 //
    783 //       SignEcdsa()
    784 //
    785 //      This function implements the ECDSA signing algorithm. The method is described in the comments below.
    786 //      It is a fatal error if rOut, sOut, dIn, or digest are not provided.
    787 //
    788 LIB_EXPORT CRYPT_RESULT
    789 SignEcdsa(
    790    TPM2B_ECC_PARAMETER           *rOut,            //   OUT: r component of the signature
    791    TPM2B_ECC_PARAMETER           *sOut,            //   OUT: s component of the signature
    792    TPM_ECC_CURVE                  curveId,         //   IN: the curve used in the signature
    793                                                    //       process
    794    TPM2B_ECC_PARAMETER           *dIn,             //   IN: the private key
    795    TPM2B                         *digest           //   IN: the value to sign
    796    )
    797 {
    798    BIGNUM                        *bnK;
    799    BIGNUM                        *bnIk;
    800    BIGNUM                        *bnN;
    801    BIGNUM                        *bnR;
    802 //
    803     BIGNUM                    *bnD;
    804     BIGNUM                    *bnZ;
    805     TPM2B_ECC_PARAMETER        k;
    806     TPMS_ECC_POINT             R;
    807     BN_CTX                    *context;
    808     CRYPT_RESULT               retVal = CRYPT_SUCCESS;
    809     const ECC_CURVE_DATA      *curveData = GetCurveData(curveId);
    810     pAssert(rOut != NULL && sOut != NULL && dIn != NULL && digest != NULL);
    811     context = BN_CTX_new();
    812     if(context == NULL)
    813         FAIL(FATAL_ERROR_ALLOCATION);
    814     BN_CTX_start(context);
    815     bnN = BN_CTX_get(context);
    816     bnZ = BN_CTX_get(context);
    817     bnR = BN_CTX_get(context);
    818     bnD = BN_CTX_get(context);
    819     bnIk = BN_CTX_get(context);
    820     bnK = BN_CTX_get(context);
    821     // Assume the size variables do not overflow, which should not happen in
    822     // the contexts that this function will be called.
    823     pAssert(curveData->n->size <= MAX_ECC_PARAMETER_BYTES);
    824     if(   bnK == NULL
    825        || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
    826         FAIL(FATAL_ERROR_INTERNAL);
    827 //   The algorithm as described in "Suite B Implementer's Guide to FIPS 186-3(ECDSA)"
    828 //   1. Use one of the routines in Appendix A.2 to generate (k, k^-1), a per-message
    829 //      secret number and its inverse modulo n. Since n is prime, the
    830 //      output will be invalid only if there is a failure in the RBG.
    831 //   2. Compute the elliptic curve point R = [k]G = (xR, yR) using EC scalar
    832 //      multiplication (see [Routines]), where G is the base point included in
    833 //      the set of domain parameters.
    834 //   3. Compute r = xR mod n. If r = 0, then return to Step 1. 1.
    835 //   4. Use the selected hash function to compute H = Hash(M).
    836 //   5. Convert the bit string H to an integer e as described in Appendix B.2.
    837 //   6. Compute s = (k^-1 * (e + d * r)) mod n. If s = 0, return to Step 1.2.
    838 //   7. Return (r, s).
    839     // Generate a random value k in the range 1 <= k < n
    840     // Want a K value that is the same size as the curve order
    841     k.t.size = curveData->n->size;
    842     while(TRUE) // This implements the loop at step 6. If s is zero, start over.
    843     {
    844         while(TRUE)
    845         {
    846             // Step 1 and 2 -- generate an ephemeral key and the modular inverse
    847             // of the private key.
    848             while(TRUE)
    849             {
    850                 GetRandomPrivate(&k, curveData->n);
    851                   // Do the point multiply to generate a point and check to see if
    852                   // the point it at infinity
    853                   if(    _cpri__EccPointMultiply(&R, curveId, &k, NULL, NULL)
    854                       != CRYPT_NO_RESULT)
    855                       break; // can only be CRYPT_SUCCESS
    856               }
    857               // x coordinate is mod p. Make it mod n
    858               // Assume the size variables do not overflow, which should not happen
    859               // in the contexts that this function will be called.
    860               assert2Bsize(R.x.t);
    861               BN_bin2bn(R.x.t.buffer, R.x.t.size, bnR);
    862               BN_mod(bnR, bnR, bnN, context);
    863               // Make sure that it is not zero;
    864               if(BN_is_zero(bnR))
    865                   continue;
    866               // Make sure that a modular inverse exists
    867               // Assume the size variables do not overflow, which should not happen
    868               // in the contexts that this function will be called.
    869               assert2Bsize(k.t);
    870               BN_bin2bn(k.t.buffer, k.t.size, bnK);
    871               if( BN_mod_inverse(bnIk, bnK, bnN, context) != NULL)
    872                   break;
    873         }
    874         // Set z = leftmost bits of the digest
    875         // NOTE: This is implemented such that the key size needs to be
    876         //        an even number of bytes in length.
    877         if(digest->size > curveData->n->size)
    878         {
    879              // Assume the size variables do not overflow, which should not happen
    880              // in the contexts that this function will be called.
    881              pAssert(curveData->n->size <= MAX_ECC_KEY_BYTES);
    882              // digest is larger than n so truncate
    883              BN_bin2bn(digest->buffer, curveData->n->size, bnZ);
    884         }
    885         else
    886         {
    887              // Assume the size variables do not overflow, which should not happen
    888              // in the contexts that this function will be called.
    889              pAssert(digest->size <= MAX_DIGEST_SIZE);
    890              // digest is same or smaller than n so use it all
    891              BN_bin2bn(digest->buffer, digest->size, bnZ);
    892         }
    893         // Assume the size variables do not overflow, which should not happen in
    894         // the contexts that this function will be called.
    895         assert2Bsize(dIn->t);
    896         if(   bnZ == NULL
    897              // need the private scalar of the signing key
    898              || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL)
    899               FAIL(FATAL_ERROR_INTERNAL);
    900         //   NOTE: When the result of an operation is going to be reduced mod x
    901         //   any modular multiplication is done so that the intermediate values
    902         //   don't get too large.
    903         //
    904         // now have inverse of K (bnIk), z (bnZ), r (bnR),      d (bnD) and n (bnN)
    905         // Compute s = k^-1 (z + r*d)(mod n)
    906             // first do d = r*d mod n
    907         if( !BN_mod_mul(bnD, bnR, bnD, bnN, context)
    908              // d = z + r * d
    909              || !BN_add(bnD, bnZ, bnD)
    910              // d = k^(-1)(z + r * d)(mod n)
    911              || !BN_mod_mul(bnD, bnIk, bnD, bnN, context)
    912              // convert to TPM2B format
    913              || !BnTo2B(&sOut->b, bnD, curveData->n->size)
    914              //   and write the modular reduced version of r
    915              //   NOTE: this was deferred to reduce the number of
    916              //   error checks.
    917              ||   !BnTo2B(&rOut->b, bnR, curveData->n->size))
    918               FAIL(FATAL_ERROR_INTERNAL);
    919         if(!BN_is_zero(bnD))
    920             break; // signature not zero so done
    921         // if the signature value was zero, start over
    922    }
    923    // Free up allocated BN values
    924    BN_CTX_end(context);
    925    BN_CTX_free(context);
    926    return retVal;
    927 }
    928 #endif //%
    929 #if defined TPM_ALG_ECDAA || defined TPM_ALG_ECSCHNORR                //%
    930 //
    931 //
    932 //       EcDaa()
    933 //
    934 //      This function is used to perform a modified Schnorr signature for ECDAA.
    935 //      This function performs s = k + T * d mod n where
    936 //      a) 'k is a random, or pseudo-random value used in the commit phase
    937 //      b) T is the digest to be signed, and
    938 //      c) d is a private key.
    939 //      If tIn is NULL then use tOut as T
    940 //
    941 //      Return Value                        Meaning
    942 //
    943 //      CRYPT_SUCCESS                       signature created
    944 //
    945 static CRYPT_RESULT
    946 EcDaa(
    947    TPM2B_ECC_PARAMETER              *tOut,             //   OUT: T component of the signature
    948    TPM2B_ECC_PARAMETER              *sOut,             //   OUT: s component of the signature
    949    TPM_ECC_CURVE                     curveId,          //   IN: the curve used in signing
    950    TPM2B_ECC_PARAMETER              *dIn,              //   IN: the private key
    951    TPM2B                            *tIn,              //   IN: the value to sign
    952    TPM2B_ECC_PARAMETER              *kIn               //   IN: a random value from commit
    953    )
    954 {
    955    BIGNUM                           *bnN, *bnK, *bnT, *bnD;
    956    BN_CTX                           *context;
    957    const TPM2B                      *n;
    958    const ECC_CURVE_DATA             *curveData = GetCurveData(curveId);
    959    BOOL                              OK = TRUE;
    960    // Parameter checks
    961     pAssert(   sOut != NULL && dIn != NULL && tOut != NULL
    962             && kIn != NULL && curveData != NULL);
    963    // this just saves key strokes
    964    n = curveData->n;
    965    if(tIn != NULL)
    966        Copy2B(&tOut->b, tIn);
    967    // The size of dIn and kIn input scalars is limited by the size of the size
    968    // of a TPM2B_ECC_PARAMETER and tIn can be no larger than a digest.
    969    // Make sure they are within range.
    970    pAssert(   (int) dIn->t.size <= MAX_ECC_KEY_BYTES
    971            && (int) kIn->t.size <= MAX_ECC_KEY_BYTES
    972 //
    973              && (int) tOut->t.size <= MAX_DIGEST_SIZE
    974             );
    975    context = BN_CTX_new();
    976    if(context == NULL)
    977        FAIL(FATAL_ERROR_ALLOCATION);
    978    BN_CTX_start(context);
    979    bnN = BN_CTX_get(context);
    980    bnK = BN_CTX_get(context);
    981    bnT = BN_CTX_get(context);
    982    bnD = BN_CTX_get(context);
    983    // Check for allocation problems
    984    if(bnD == NULL)
    985        FAIL(FATAL_ERROR_ALLOCATION);
    986    // Convert values
    987    if(   BN_bin2bn(n->buffer, n->size, bnN) == NULL
    988       || BN_bin2bn(kIn->t.buffer, kIn->t.size, bnK) == NULL
    989       || BN_bin2bn(dIn->t.buffer, dIn->t.size, bnD) == NULL
    990       || BN_bin2bn(tOut->t.buffer, tOut->t.size, bnT) == NULL)
    991        FAIL(FATAL_ERROR_INTERNAL);
    992    // Compute T = T mod n
    993    OK = OK && BN_mod(bnT, bnT, bnN, context);
    994    // compute (s = k + T * d mod n)
    995            //   d = T * d mod n
    996    OK = OK && BN_mod_mul(bnD, bnT, bnD, bnN, context) == 1;
    997            //   d = k + T * d mod n
    998    OK = OK && BN_mod_add(bnD, bnK, bnD, bnN, context) == 1;
    999            //   s = d
   1000    OK = OK && BnTo2B(&sOut->b, bnD, n->size);
   1001            //   r = T
   1002    OK = OK && BnTo2B(&tOut->b, bnT, n->size);
   1003    if(!OK)
   1004        FAIL(FATAL_ERROR_INTERNAL);
   1005    // Cleanup
   1006    BN_CTX_end(context);
   1007    BN_CTX_free(context);
   1008    return CRYPT_SUCCESS;
   1009 }
   1010 #endif //%
   1011 #ifdef TPM_ALG_ECSCHNORR //%
   1012 //
   1013 //
   1014 //       Mod2B()
   1015 //
   1016 //      Function does modular reduction of TPM2B values.
   1017 //
   1018 static CRYPT_RESULT
   1019 Mod2B(
   1020     TPM2B                *x,                 // IN/OUT: value to reduce
   1021     const TPM2B          *n                  // IN: mod
   1022     )
   1023 {
   1024     int         compare;
   1025     compare = _math__uComp(x->size, x->buffer, n->size, n->buffer);
   1026     if(compare < 0)
   1027         // if x < n, then mod is x
   1028         return CRYPT_SUCCESS;
   1029     if(compare == 0)
   1030     {
   1031         // if x == n then mod is 0
   1032         x->size = 0;
   1033         x->buffer[0] = 0;
   1034         return CRYPT_SUCCESS;
   1035     }
   1036    return _math__Div(x, n, NULL, x);
   1037 }
   1038 
   1039 //
   1040 //
   1041 //       SchnorrEcc()
   1042 //
   1043 //      This function is used to perform a modified Schnorr signature.
   1044 //      This function will generate a random value k and compute
   1045 //      a) (xR, yR) = [k]G
   1046 //      b) r = hash(P || xR)(mod n)
   1047 //      c) s= k + r * ds
   1048 //      d) return the tuple T, s
   1049 //
   1050 //
   1051 //
   1052 //
   1053 //      Return Value                  Meaning
   1054 //
   1055 //      CRYPT_SUCCESS                 signature created
   1056 //      CRYPT_SCHEME                  hashAlg can't produce zero-length digest
   1057 //
   1058 static CRYPT_RESULT
   1059 SchnorrEcc(
   1060    TPM2B_ECC_PARAMETER        *rOut,               //   OUT: r component of the signature
   1061    TPM2B_ECC_PARAMETER        *sOut,               //   OUT: s component of the signature
   1062    TPM_ALG_ID                  hashAlg,            //   IN: hash algorithm used
   1063    TPM_ECC_CURVE               curveId,            //   IN: the curve used in signing
   1064    TPM2B_ECC_PARAMETER        *dIn,                //   IN: the private key
   1065    TPM2B                      *digest,             //   IN: the digest to sign
   1066    TPM2B_ECC_PARAMETER        *kIn                 //   IN: for testing
   1067    )
   1068 {
   1069    TPM2B_ECC_PARAMETER      k;
   1070    BIGNUM                  *bnR, *bnN, *bnK, *bnT, *bnD;
   1071    BN_CTX                  *context;
   1072    const TPM2B             *n;
   1073    EC_POINT                *pR = NULL;
   1074    EC_GROUP                *group = NULL;
   1075    CPRI_HASH_STATE          hashState;
   1076    UINT16                   digestSize = _cpri__GetDigestSize(hashAlg);
   1077    const ECC_CURVE_DATA    *curveData = GetCurveData(curveId);
   1078    TPM2B_TYPE(T, MAX(MAX_DIGEST_SIZE, MAX_ECC_PARAMETER_BYTES));
   1079    TPM2B_T                  T2b;
   1080    BOOL                     OK = TRUE;
   1081    // Parameter checks
   1082    // Must have a place for the 'r' and 's' parts of the signature, a private
   1083    // key ('d')
   1084    pAssert(   rOut != NULL && sOut != NULL && dIn != NULL
   1085            && digest != NULL && curveData != NULL);
   1086    // to save key strokes
   1087    n = curveData->n;
   1088    // If the digest does not produce a hash, then null the signature and return
   1089    // a failure.
   1090    if(digestSize == 0)
   1091    {
   1092        rOut->t.size = 0;
   1093        sOut->t.size = 0;
   1094        return CRYPT_SCHEME;
   1095    }
   1096    // Allocate big number values
   1097    context = BN_CTX_new();
   1098    if(context == NULL)
   1099        FAIL(FATAL_ERROR_ALLOCATION);
   1100    BN_CTX_start(context);
   1101    bnR = BN_CTX_get(context);
   1102    bnN = BN_CTX_get(context);
   1103    bnK = BN_CTX_get(context);
   1104    bnT = BN_CTX_get(context);
   1105    bnD = BN_CTX_get(context);
   1106    if(   bnD == NULL
   1107            // initialize the group parameters
   1108       || (group = EccCurveInit(curveId, context)) == NULL
   1109           // allocate a local point
   1110       || (pR = EC_POINT_new(group)) == NULL
   1111      )
   1112         FAIL(FATAL_ERROR_ALLOCATION);
   1113    if(BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
   1114        FAIL(FATAL_ERROR_INTERNAL);
   1115    while(OK)
   1116    {
   1117 // a) set k to a random value such that 1 k n-1
   1118        if(kIn != NULL)
   1119        {
   1120             Copy2B(&k.b, &kIn->b); // copy input k if testing
   1121             OK = FALSE;              // not OK to loop
   1122        }
   1123        else
   1124        // If get a random value in the correct range
   1125             GetRandomPrivate(&k, n);
   1126         // Convert 'k' and generate pR = ['k']G
   1127         BnFrom2B(bnK, &k.b);
   1128 // b) compute E (xE, yE) [k]G
   1129        if(PointMul(group, pR, bnK, NULL, NULL, context) == CRYPT_NO_RESULT)
   1130 // c) if E is the point at infinity, go to a)
   1131            continue;
   1132 // d) compute e xE (mod n)
   1133        // Get the x coordinate of the point
   1134        EC_POINT_get_affine_coordinates_GFp(group, pR, bnR, NULL, context);
   1135         // make (mod n)
   1136         BN_mod(bnR, bnR, bnN, context);
   1137 // e) if e is zero, go to a)
   1138        if(BN_is_zero(bnR))
   1139            continue;
   1140         // Convert xR to a string (use T as a temp)
   1141         BnTo2B(&T2b.b, bnR, (UINT16)(BN_num_bits(bnR)+7)/8);
   1142 // f) compute r HschemeHash(P || e) (mod n)
   1143        _cpri__StartHash(hashAlg, FALSE, &hashState);
   1144        _cpri__UpdateHash(&hashState, digest->size, digest->buffer);
   1145        _cpri__UpdateHash(&hashState, T2b.t.size, T2b.t.buffer);
   1146        if(_cpri__CompleteHash(&hashState, digestSize, T2b.b.buffer) != digestSize)
   1147            FAIL(FATAL_ERROR_INTERNAL);
   1148        T2b.t.size = digestSize;
   1149        BnFrom2B(bnT, &T2b.b);
   1150        BN_div(NULL, bnT, bnT, bnN, context);
   1151        BnTo2B(&rOut->b, bnT, (UINT16)BN_num_bytes(bnT));
   1152         // We have a value and we are going to exit the loop successfully
   1153         OK = TRUE;
   1154         break;
   1155    }
   1156    // Cleanup
   1157    EC_POINT_free(pR);
   1158    EC_GROUP_free(group);
   1159    BN_CTX_end(context);
   1160    BN_CTX_free(context);
   1161    // If we have a value, finish the signature
   1162    if(OK)
   1163        return EcDaa(rOut, sOut, curveId, dIn, NULL, &k);
   1164    else
   1165        return CRYPT_NO_RESULT;
   1166 }
   1167 #endif //%
   1168 #ifdef TPM_ALG_SM2 //%
   1169 #ifdef _SM2_SIGN_DEBUG //%
   1170 static int
   1171 cmp_bn2hex(
   1172    BIGNUM              *bn,               // IN: big number value
   1173    const char          *c                 // IN: character string number
   1174    )
   1175 {
   1176    int         result;
   1177    BIGNUM      *bnC = BN_new();
   1178    pAssert(bnC != NULL);
   1179    BN_hex2bn(&bnC, c);
   1180    result = BN_ucmp(bn, bnC);
   1181    BN_free(bnC);
   1182    return result;
   1183 }
   1184 static int
   1185 cmp_2B2hex(
   1186    TPM2B               *a,                // IN: TPM2B number to compare
   1187    const char          *c                 // IN: character string
   1188    )
   1189 {
   1190    int            result;
   1191    int            sl = strlen(c);
   1192    BIGNUM         *bnA;
   1193    result = (a->size * 2) - sl;
   1194    if(result != 0)
   1195        return result;
   1196    pAssert((bnA = BN_bin2bn(a->buffer, a->size, NULL)) != NULL);
   1197    result = cmp_bn2hex(bnA, c);
   1198    BN_free(bnA);
   1199    return result;
   1200 }
   1201 static void
   1202 cpy_hexTo2B(
   1203    TPM2B               *b,                // OUT: receives value
   1204    const char          *c                 // IN: source string
   1205    )
   1206 {
   1207    BIGNUM      *bnB = BN_new();
   1208    pAssert((strlen(c) & 1) == 0);         // must have an even number of digits
   1209    b->size = strlen(c) / 2;
   1210    BN_hex2bn(&bnB, c);
   1211    pAssert(bnB != NULL);
   1212    BnTo2B(b, bnB, b->size);
   1213    BN_free(bnB);
   1214 }
   1215 #endif //% _SM2_SIGN_DEBUG
   1216 //
   1217 //
   1218 //        SignSM2()
   1219 //
   1220 //       This function signs a digest using the method defined in SM2 Part 2. The method in the standard will add
   1221 //       a header to the message to be signed that is a hash of the values that define the key. This then hashed
   1222 //       with the message to produce a digest (e) that is signed. This function signs e.
   1223 //
   1224 //
   1225 //
   1226 //
   1227 //       Return Value                      Meaning
   1228 //
   1229 //       CRYPT_SUCCESS                     sign worked
   1230 //
   1231 static CRYPT_RESULT
   1232 SignSM2(
   1233    TPM2B_ECC_PARAMETER            *rOut,                 //   OUT: r component of the signature
   1234    TPM2B_ECC_PARAMETER            *sOut,                 //   OUT: s component of the signature
   1235    TPM_ECC_CURVE                   curveId,              //   IN: the curve used in signing
   1236    TPM2B_ECC_PARAMETER            *dIn,                  //   IN: the private key
   1237    TPM2B                          *digest                //   IN: the digest to sign
   1238    )
   1239 {
   1240    BIGNUM                         *bnR;
   1241    BIGNUM                         *bnS;
   1242    BIGNUM                         *bnN;
   1243    BIGNUM                         *bnK;
   1244    BIGNUM                         *bnX1;
   1245    BIGNUM                         *bnD;
   1246    BIGNUM                         *bnT;        // temp
   1247    BIGNUM                         *bnE;
   1248    BN_CTX                  *context;
   1249    TPM2B_ECC_PARAMETER      k;
   1250    TPMS_ECC_POINT           p2Br;
   1251    const ECC_CURVE_DATA    *curveData = GetCurveData(curveId);
   1252    pAssert(curveData != NULL);
   1253    context = BN_CTX_new();
   1254    BN_CTX_start(context);
   1255    bnK = BN_CTX_get(context);
   1256    bnR = BN_CTX_get(context);
   1257    bnS = BN_CTX_get(context);
   1258    bnX1 = BN_CTX_get(context);
   1259    bnN = BN_CTX_get(context);
   1260    bnD = BN_CTX_get(context);
   1261    bnT = BN_CTX_get(context);
   1262    bnE = BN_CTX_get(context);
   1263    if(bnE == NULL)
   1264        FAIL(FATAL_ERROR_ALLOCATION);
   1265    BnFrom2B(bnE, digest);
   1266    BnFrom2B(bnN, curveData->n);
   1267    BnFrom2B(bnD, &dIn->b);
   1268 #ifdef _SM2_SIGN_DEBUG
   1269 BN_hex2bn(&bnE, "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76");
   1270 BN_hex2bn(&bnD, "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263");
   1271 #endif
   1272 // A3: Use random number generator to generate random number 1 <= k <= n-1;
   1273 // NOTE: Ax: numbers are from the SM2 standard
   1274    k.t.size = curveData->n->size;
   1275 loop:
   1276    {
   1277        // Get a random number
   1278        _cpri__GenerateRandom(k.t.size, k.t.buffer);
   1279 #ifdef _SM2_SIGN_DEBUG
   1280 BN_hex2bn(&bnK, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F");
   1281 BnTo2B(&k.b,bnK, 32);
   1282 k.t.size = 32;
   1283 #endif
   1284        //make sure that the number is 0 < k < n
   1285        BnFrom2B(bnK, &k.b);
   1286         if(      BN_ucmp(bnK, bnN) >= 0
   1287               || BN_is_zero(bnK))
   1288               goto loop;
   1289 // A4: Figure out the point of elliptic curve (x1, y1)=[k]G, and according
   1290 // to details specified in 4.2.7 in Part 1 of this document, transform the
   1291 // data type of x1 into an integer;
   1292        if(    _cpri__EccPointMultiply(&p2Br, curveId, &k, NULL, NULL)
   1293            == CRYPT_NO_RESULT)
   1294             goto loop;
   1295         BnFrom2B(bnX1, &p2Br.x.b);
   1296 // A5: Figure out r = (e + x1) mod n,
   1297        if(!BN_mod_add(bnR, bnE, bnX1, bnN, context))
   1298            FAIL(FATAL_ERROR_INTERNAL);
   1299 #ifdef _SM2_SIGN_DEBUG
   1300 pAssert(cmp_bn2hex(bnR,
   1301                "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")
   1302        == 0);
   1303 #endif
   1304            // if r=0 or r+k=n, return to A3;
   1305          if(!BN_add(bnT, bnK, bnR))
   1306             FAIL(FATAL_ERROR_INTERNAL);
   1307         if(BN_is_zero(bnR) || BN_ucmp(bnT, bnN) == 0)
   1308             goto loop;
   1309 // A6: Figure out s = ((1 + dA)^-1 (k - r dA)) mod n, if s=0, return to A3;
   1310        // compute t = (1+d)-1
   1311        BN_copy(bnT, bnD);
   1312        if(     !BN_add_word(bnT, 1)
   1313            || !BN_mod_inverse(bnT, bnT, bnN, context) // (1 + dA)^-1 mod n
   1314            )
   1315              FAIL(FATAL_ERROR_INTERNAL);
   1316 #ifdef _SM2_SIGN_DEBUG
   1317 pAssert(cmp_bn2hex(bnT,
   1318                  "79BFCF3052C80DA7B939E0C6914A18CBB2D96D8555256E83122743A7D4F5F956")
   1319        == 0);
   1320 #endif
   1321        // compute s = t * (k - r * dA) mod n
   1322        if(     !BN_mod_mul(bnS, bnD, bnR, bnN, context) // (r * dA) mod n
   1323            || !BN_mod_sub(bnS, bnK, bnS, bnN, context) // (k - (r * dA) mod n
   1324            || !BN_mod_mul(bnS, bnT, bnS, bnN, context))// t * (k - (r * dA) mod n
   1325            FAIL(FATAL_ERROR_INTERNAL);
   1326 #ifdef _SM2_SIGN_DEBUG
   1327 pAssert(cmp_bn2hex(bnS,
   1328                  "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")
   1329        == 0);
   1330 #endif
   1331         if(BN_is_zero(bnS))
   1332             goto loop;
   1333    }
   1334 // A7: According to details specified in 4.2.1 in Part 1 of this document, transform
   1335 // the data type of r, s into bit strings, signature of message M is (r, s).
   1336    BnTo2B(&rOut->b, bnR, curveData->n->size);
   1337    BnTo2B(&sOut->b, bnS, curveData->n->size);
   1338 #ifdef _SM2_SIGN_DEBUG
   1339 pAssert(cmp_2B2hex(&rOut->b,
   1340                "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1")
   1341        == 0);
   1342 pAssert(cmp_2B2hex(&sOut->b,
   1343                   "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")
   1344         == 0);
   1345 #endif
   1346    BN_CTX_end(context);
   1347    BN_CTX_free(context);
   1348    return CRYPT_SUCCESS;
   1349 }
   1350 #endif //% TPM_ALG_SM2
   1351 //
   1352 //
   1353 //        _cpri__SignEcc()
   1354 //
   1355 //       This function is the dispatch function for the various ECC-based signing schemes.
   1356 //
   1357 //       Return Value                      Meaning
   1358 //
   1359 //       CRYPT_SCHEME                      scheme is not supported
   1360 //
   1361 LIB_EXPORT CRYPT_RESULT
   1362 _cpri__SignEcc(
   1363    TPM2B_ECC_PARAMETER            *rOut,              //   OUT: r component of the signature
   1364    TPM2B_ECC_PARAMETER            *sOut,              //   OUT: s component of the signature
   1365    TPM_ALG_ID                      scheme,            //   IN: the scheme selector
   1366    TPM_ALG_ID                      hashAlg,           //   IN: the hash algorithm if need
   1367    TPM_ECC_CURVE                   curveId,           //   IN: the curve used in the signature
   1368                                                       //       process
   1369    TPM2B_ECC_PARAMETER            *dIn,               //   IN: the private key
   1370    TPM2B                          *digest,            //   IN: the digest to sign
   1371    TPM2B_ECC_PARAMETER            *kIn                //   IN: k for input
   1372    )
   1373 {
   1374    switch (scheme)
   1375    {
   1376        case TPM_ALG_ECDSA:
   1377            // SignEcdsa always works
   1378            return SignEcdsa(rOut, sOut, curveId, dIn, digest);
   1379            break;
   1380 #ifdef TPM_ALG_ECDAA
   1381        case TPM_ALG_ECDAA:
   1382            if(rOut != NULL)
   1383                 rOut->b.size = 0;
   1384            return EcDaa(rOut, sOut, curveId, dIn, digest, kIn);
   1385            break;
   1386 #endif
   1387 #ifdef TPM_ALG_ECSCHNORR
   1388        case TPM_ALG_ECSCHNORR:
   1389            return SchnorrEcc(rOut, sOut, hashAlg, curveId, dIn, digest, kIn);
   1390            break;
   1391 #endif
   1392 #ifdef TPM_ALG_SM2
   1393        case TPM_ALG_SM2:
   1394            return SignSM2(rOut, sOut, curveId, dIn, digest);
   1395            break;
   1396 #endif
   1397        default:
   1398            return CRYPT_SCHEME;
   1399    }
   1400 }
   1401 #ifdef TPM_ALG_ECDSA //%
   1402 //
   1403 //
   1404 //        ValidateSignatureEcdsa()
   1405 //
   1406 //       This function validates an ECDSA signature. rIn and sIn shoudl have been checked to make sure that
   1407 //       they are not zero.
   1408 //
   1409 //       Return Value                  Meaning
   1410 //
   1411 //       CRYPT_SUCCESS                 signature valid
   1412 //       CRYPT_FAIL                    signature not valid
   1413 //
   1414 static CRYPT_RESULT
   1415 ValidateSignatureEcdsa(
   1416    TPM2B_ECC_PARAMETER        *rIn,                //   IN: r component of the signature
   1417    TPM2B_ECC_PARAMETER        *sIn,                //   IN: s component of the signature
   1418    TPM_ECC_CURVE               curveId,            //   IN: the curve used in the signature
   1419                                                    //       process
   1420    TPMS_ECC_POINT             *Qin,                //   IN: the public point of the key
   1421    TPM2B                      *digest              //   IN: the digest that was signed
   1422    )
   1423 {
   1424    TPM2B_ECC_PARAMETER         U1;
   1425    TPM2B_ECC_PARAMETER         U2;
   1426    TPMS_ECC_POINT              R;
   1427    const TPM2B                *n;
   1428    BN_CTX                     *context;
   1429    EC_POINT                   *pQ = NULL;
   1430    EC_GROUP                   *group = NULL;
   1431    BIGNUM                     *bnU1;
   1432    BIGNUM                     *bnU2;
   1433    BIGNUM                     *bnR;
   1434    BIGNUM                     *bnS;
   1435    BIGNUM                     *bnW;
   1436    BIGNUM                     *bnV;
   1437    BIGNUM                     *bnN;
   1438    BIGNUM                     *bnE;
   1439    BIGNUM                     *bnQx;
   1440    BIGNUM                     *bnQy;
   1441    CRYPT_RESULT                retVal = CRYPT_FAIL;
   1442    int                         t;
   1443    const ECC_CURVE_DATA       *curveData = GetCurveData(curveId);
   1444    // The curve selector should have been filtered by the unmarshaling process
   1445    pAssert (curveData != NULL);
   1446    n = curveData->n;
   1447 // 1. If r and s are not both integers in the interval [1, n - 1], output
   1448 //    INVALID.
   1449 // rIn and sIn are known to be greater than zero (was checked by the caller).
   1450    if(     _math__uComp(rIn->t.size, rIn->t.buffer, n->size, n->buffer) >= 0
   1451        || _math__uComp(sIn->t.size, sIn->t.buffer, n->size, n->buffer) >= 0
   1452      )
   1453       return CRYPT_FAIL;
   1454    context = BN_CTX_new();
   1455    if(context == NULL)
   1456        FAIL(FATAL_ERROR_ALLOCATION);
   1457    BN_CTX_start(context);
   1458    bnR = BN_CTX_get(context);
   1459    bnS = BN_CTX_get(context);
   1460    bnN = BN_CTX_get(context);
   1461    bnE = BN_CTX_get(context);
   1462    bnV = BN_CTX_get(context);
   1463    bnW = BN_CTX_get(context);
   1464    bnQx = BN_CTX_get(context);
   1465    bnQy = BN_CTX_get(context);
   1466    bnU1 = BN_CTX_get(context);
   1467    bnU2 = BN_CTX_get(context);
   1468    // Assume the size variables do not overflow, which should not happen in
   1469    // the contexts that this function will be called.
   1470    assert2Bsize(Qin->x.t);
   1471    assert2Bsize(rIn->t);
   1472    assert2Bsize(sIn->t);
   1473    // BN_CTX_get() is sticky so only need to check the last value to know that
   1474    // all worked.
   1475    if(   bnU2 == NULL
   1476         // initialize the group parameters
   1477        || (group = EccCurveInit(curveId, context)) == NULL
   1478        // allocate a local point
   1479        || (pQ = EC_POINT_new(group)) == NULL
   1480        //   use the public key values (QxIn and QyIn) to initialize Q
   1481        ||   BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQx) == NULL
   1482        ||   BN_bin2bn(Qin->x.t.buffer, Qin->x.t.size, bnQy) == NULL
   1483        ||   !EC_POINT_set_affine_coordinates_GFp(group, pQ, bnQx, bnQy, context)
   1484        // convert the signature values
   1485        || BN_bin2bn(rIn->t.buffer, rIn->t.size, bnR) == NULL
   1486        || BN_bin2bn(sIn->t.buffer, sIn->t.size, bnS) == NULL
   1487        // convert the curve order
   1488        || BN_bin2bn(curveData->n->buffer, curveData->n->size, bnN) == NULL)
   1489         FAIL(FATAL_ERROR_INTERNAL);
   1490 // 2. Use the selected hash function to compute H0 = Hash(M0).
   1491    // This is an input parameter
   1492 // 3. Convert the bit string H0 to an integer e as described in Appendix B.2.
   1493    t = (digest->size > rIn->t.size) ? rIn->t.size : digest->size;
   1494    if(BN_bin2bn(digest->buffer, t, bnE) == NULL)
   1495        FAIL(FATAL_ERROR_INTERNAL);
   1496 // 4. Compute w = (s')^-1 mod n, using the routine in Appendix B.1.
   1497    if (BN_mod_inverse(bnW, bnS, bnN, context) == NULL)
   1498        FAIL(FATAL_ERROR_INTERNAL);
   1499 // 5. Compute u1 = (e' *   w) mod n, and compute u2 = (r' *     w) mod n.
   1500    if(   !BN_mod_mul(bnU1, bnE, bnW, bnN, context)
   1501       || !BN_mod_mul(bnU2, bnR, bnW, bnN, context))
   1502        FAIL(FATAL_ERROR_INTERNAL);
   1503    BnTo2B(&U1.b, bnU1, (INT16) BN_num_bytes(bnU1));
   1504    BnTo2B(&U2.b, bnU2, (INT16) BN_num_bytes(bnU2));
   1505 // 6. Compute the elliptic curve point R = (xR, yR) = u1G+u2Q, using EC
   1506 //    scalar multiplication and EC addition (see [Routines]). If R is equal to
   1507 //    the point at infinity O, output INVALID.
   1508    if(_cpri__EccPointMultiply(&R, curveId, &U1, Qin, &U2) == CRYPT_SUCCESS)
   1509    {
   1510        // 7. Compute v = Rx mod n.
   1511        if(    BN_bin2bn(R.x.t.buffer, R.x.t.size, bnV) == NULL
   1512            || !BN_mod(bnV, bnV, bnN, context))
   1513             FAIL(FATAL_ERROR_INTERNAL);
   1514    // 8. Compare v and r0. If v = r0, output VALID; otherwise, output INVALID
   1515        if(BN_cmp(bnV, bnR) == 0)
   1516            retVal = CRYPT_SUCCESS;
   1517    }
   1518    if(pQ != NULL) EC_POINT_free(pQ);
   1519    if(group != NULL) EC_GROUP_free(group);
   1520    BN_CTX_end(context);
   1521    BN_CTX_free(context);
   1522    return retVal;
   1523 }
   1524 #endif      //% TPM_ALG_ECDSA
   1525 #ifdef TPM_ALG_ECSCHNORR //%
   1526 //
   1527 //
   1528 //        ValidateSignatureEcSchnorr()
   1529 //
   1530 //       This function is used to validate an EC Schnorr signature. rIn and sIn are required to be greater than
   1531 //       zero. This is checked in _cpri__ValidateSignatureEcc().
   1532 //
   1533 //       Return Value                   Meaning
   1534 //
   1535 //       CRYPT_SUCCESS                  signature valid
   1536 //       CRYPT_FAIL                     signature not valid
   1537 //       CRYPT_SCHEME                   hashAlg is not supported
   1538 //
   1539 static CRYPT_RESULT
   1540 ValidateSignatureEcSchnorr(
   1541    TPM2B_ECC_PARAMETER         *rIn,                //   IN: r component of the signature
   1542    TPM2B_ECC_PARAMETER         *sIn,                //   IN: s component of the signature
   1543    TPM_ALG_ID                   hashAlg,            //   IN: hash algorithm of the signature
   1544    TPM_ECC_CURVE                curveId,            //   IN: the curve used in the signature
   1545                                                     //       process
   1546    TPMS_ECC_POINT              *Qin,                //   IN: the public point of the key
   1547    TPM2B                       *digest              //   IN: the digest that was signed
   1548    )
   1549 {
   1550    TPMS_ECC_POINT               pE;
   1551    const TPM2B                 *n;
   1552    CPRI_HASH_STATE              hashState;
   1553    TPM2B_DIGEST                 rPrime;
   1554    TPM2B_ECC_PARAMETER          minusR;
   1555    UINT16                       digestSize = _cpri__GetDigestSize(hashAlg);
   1556    const ECC_CURVE_DATA        *curveData = GetCurveData(curveId);
   1557    // The curve parameter should have been filtered by unmarshaling code
   1558    pAssert(curveData != NULL);
   1559    if(digestSize == 0)
   1560        return CRYPT_SCHEME;
   1561    // Input parameter validation
   1562    pAssert(rIn != NULL && sIn != NULL && Qin != NULL && digest != NULL);
   1563    n = curveData->n;
   1564    // if sIn or rIn are not between 1 and N-1, signature check fails
   1565    // sIn and rIn were verified to be non-zero by the caller
   1566    if(   _math__uComp(sIn->b.size, sIn->b.buffer, n->size, n->buffer) >= 0
   1567       || _math__uComp(rIn->b.size, rIn->b.buffer, n->size, n->buffer) >= 0
   1568      )
   1569        return CRYPT_FAIL;
   1570    //E = [s]InG - [r]InQ
   1571    _math__sub(n->size, n->buffer,
   1572               rIn->t.size, rIn->t.buffer,
   1573               &minusR.t.size, minusR.t.buffer);
   1574    if(_cpri__EccPointMultiply(&pE, curveId, sIn, Qin, &minusR) != CRYPT_SUCCESS)
   1575        return CRYPT_FAIL;
   1576    // Ex = Ex mod N
   1577    if(Mod2B(&pE.x.b, n) != CRYPT_SUCCESS)
   1578        FAIL(FATAL_ERROR_INTERNAL);
   1579    _math__Normalize2B(&pE.x.b);
   1580    // rPrime = h(digest || pE.x) mod n;
   1581    _cpri__StartHash(hashAlg, FALSE, &hashState);
   1582    _cpri__UpdateHash(&hashState, digest->size, digest->buffer);
   1583    _cpri__UpdateHash(&hashState, pE.x.t.size, pE.x.t.buffer);
   1584    if(_cpri__CompleteHash(&hashState, digestSize, rPrime.t.buffer) != digestSize)
   1585        FAIL(FATAL_ERROR_INTERNAL);
   1586    rPrime.t.size = digestSize;
   1587    // rPrime = rPrime (mod n)
   1588    if(Mod2B(&rPrime.b, n) != CRYPT_SUCCESS)
   1589        FAIL(FATAL_ERROR_INTERNAL);
   1590    // if the values don't match, then the signature is bad
   1591    if(_math__uComp(rIn->t.size, rIn->t.buffer,
   1592                    rPrime.t.size, rPrime.t.buffer) != 0)
   1593        return CRYPT_FAIL;
   1594    else
   1595        return CRYPT_SUCCESS;
   1596 }
   1597 #endif //% TPM_ALG_ECSCHNORR
   1598 #ifdef TPM_ALG_SM2 //%
   1599 //
   1600 //
   1601 //        ValidateSignatueSM2Dsa()
   1602 //
   1603 //       This function is used to validate an SM2 signature.
   1604 //
   1605 //       Return Value                      Meaning
   1606 //
   1607 //       CRYPT_SUCCESS                     signature valid
   1608 //       CRYPT_FAIL                        signature not valid
   1609 //
   1610 static CRYPT_RESULT
   1611 ValidateSignatureSM2Dsa(
   1612    TPM2B_ECC_PARAMETER            *rIn,                //   IN: r component of the signature
   1613    TPM2B_ECC_PARAMETER            *sIn,                //   IN: s component of the signature
   1614    TPM_ECC_CURVE                   curveId,            //   IN: the curve used in the signature
   1615                                                        //       process
   1616    TPMS_ECC_POINT                 *Qin,                //   IN: the public point of the key
   1617    TPM2B                          *digest              //   IN: the digest that was signed
   1618    )
   1619 {
   1620    BIGNUM                         *bnR;
   1621    BIGNUM                         *bnRp;
   1622    BIGNUM                         *bnT;
   1623    BIGNUM                         *bnS;
   1624    BIGNUM                         *bnE;
   1625    BIGNUM                         *order;
   1626    EC_POINT                       *pQ;
   1627    BN_CTX                         *context;
   1628    EC_GROUP                       *group = NULL;
   1629    const ECC_CURVE_DATA           *curveData = GetCurveData(curveId);
   1630    BOOL                            fail = FALSE;
   1631 //
   1632    if((context = BN_CTX_new()) == NULL || curveData == NULL)
   1633        FAIL(FATAL_ERROR_INTERNAL);
   1634    bnR = BN_CTX_get(context);
   1635    bnRp= BN_CTX_get(context);
   1636    bnE = BN_CTX_get(context);
   1637    bnT = BN_CTX_get(context);
   1638    bnS = BN_CTX_get(context);
   1639    order = BN_CTX_get(context);
   1640    if(   order == NULL
   1641       || (group = EccCurveInit(curveId, context)) == NULL)
   1642        FAIL(FATAL_ERROR_INTERNAL);
   1643 #ifdef _SM2_SIGN_DEBUG
   1644    cpy_hexTo2B(&Qin->x.b,
   1645           "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A");
   1646    cpy_hexTo2B(&Qin->y.b,
   1647           "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857");
   1648    cpy_hexTo2B(digest,
   1649           "B524F552CD82B8B028476E005C377FB19A87E6FC682D48BB5D42E3D9B9EFFE76");
   1650 #endif
   1651    pQ = EccInitPoint2B(group, Qin, context);
   1652 #ifdef _SM2_SIGN_DEBUG
   1653    pAssert(EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, bnS, context));
   1654    pAssert(cmp_bn2hex(bnT,
   1655                "0AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A")
   1656            == 0);
   1657    pAssert(cmp_bn2hex(bnS,
   1658                "7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857")
   1659            == 0);
   1660 #endif
   1661    BnFrom2B(bnR, &rIn->b);
   1662    BnFrom2B(bnS, &sIn->b);
   1663    BnFrom2B(bnE, digest);
   1664 #ifdef _SM2_SIGN_DEBUG
   1665 // Make sure that the input signature is the test signature
   1666 pAssert(cmp_2B2hex(&rIn->b,
   1667        "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1") == 0);
   1668 pAssert(cmp_2B2hex(&sIn->b,
   1669        "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7") == 0);
   1670 #endif
   1671 // a) verify that r and s are in the inclusive interval 1 to (n   1)
   1672    if (!EC_GROUP_get_order(group, order, context)) goto Cleanup;
   1673    fail = (BN_ucmp(bnR, order) >= 0);
   1674    fail = (BN_ucmp(bnS, order) >= 0) || fail;
   1675    if(fail)
   1676    // There is no reason to continue. Since r and s are inputs from the caller,
   1677    // they can know that the values are not in the proper range. So, exiting here
   1678    // does not disclose any information.
   1679        goto Cleanup;
   1680 // b) compute t := (r + s) mod n
   1681    if(!BN_mod_add(bnT, bnR, bnS, order, context))
   1682        FAIL(FATAL_ERROR_INTERNAL);
   1683 #ifdef _SM2_SIGN_DEBUG
   1684    pAssert(cmp_bn2hex(bnT,
   1685                "2B75F07ED7ECE7CCC1C8986B991F441AD324D6D619FE06DD63ED32E0C997C801")
   1686            == 0);
   1687 #endif
   1688 // c) verify that t > 0
   1689    if(BN_is_zero(bnT)) {
   1690        fail = TRUE;
   1691        // set to a value that should allow rest of the computations to run without
   1692          // trouble
   1693          BN_copy(bnT, bnS);
   1694    }
   1695 // d) compute (x, y) := [s]G + [t]Q
   1696    if(!EC_POINT_mul(group, pQ, bnS, pQ, bnT, context))
   1697        FAIL(FATAL_ERROR_INTERNAL);
   1698    // Get the x coordinate of the point
   1699    if(!EC_POINT_get_affine_coordinates_GFp(group, pQ, bnT, NULL, context))
   1700        FAIL(FATAL_ERROR_INTERNAL);
   1701 #ifdef _SM2_SIGN_DEBUG
   1702    pAssert(cmp_bn2hex(bnT,
   1703                "110FCDA57615705D5E7B9324AC4B856D23E6D9188B2AE47759514657CE25D112")
   1704                == 0);
   1705 #endif
   1706 // e) compute r' := (e + x) mod n (the x coordinate is in bnT)
   1707    if(!BN_mod_add(bnRp, bnE, bnT, order, context))
   1708        FAIL(FATAL_ERROR_INTERNAL);
   1709 // f) verify that r' = r
   1710    fail = BN_ucmp(bnR, bnRp) != 0 || fail;
   1711 Cleanup:
   1712    if(pQ) EC_POINT_free(pQ);
   1713    if(group) EC_GROUP_free(group);
   1714    BN_CTX_end(context);
   1715    BN_CTX_free(context);
   1716     if(fail)
   1717         return CRYPT_FAIL;
   1718     else
   1719         return CRYPT_SUCCESS;
   1720 }
   1721 #endif //% TPM_ALG_SM2
   1722 //
   1723 //
   1724 //        _cpri__ValidateSignatureEcc()
   1725 //
   1726 //       This function validates
   1727 //
   1728 //       Return Value                      Meaning
   1729 //
   1730 //       CRYPT_SUCCESS                     signature is valid
   1731 //       CRYPT_FAIL                        not a valid signature
   1732 //       CRYPT_SCHEME                      unsupported scheme
   1733 //
   1734 LIB_EXPORT CRYPT_RESULT
   1735 _cpri__ValidateSignatureEcc(
   1736     TPM2B_ECC_PARAMETER           *rIn,                  //   IN: r component of the signature
   1737     TPM2B_ECC_PARAMETER           *sIn,                  //   IN: s component of the signature
   1738     TPM_ALG_ID                     scheme,               //   IN: the scheme selector
   1739     TPM_ALG_ID                     hashAlg,              //   IN: the hash algorithm used (not used
   1740                                                          //       in all schemes)
   1741     TPM_ECC_CURVE                   curveId,             //   IN: the curve used in the signature
   1742                                                          //       process
   1743     TPMS_ECC_POINT                *Qin,                  //   IN: the public point of the key
   1744     TPM2B                         *digest                //   IN: the digest that was signed
   1745     )
   1746 {
   1747     CRYPT_RESULT                  retVal;
   1748     // return failure if either part of the signature is zero
   1749     if(_math__Normalize2B(&rIn->b) == 0 || _math__Normalize2B(&sIn->b) == 0)
   1750         return CRYPT_FAIL;
   1751    switch (scheme)
   1752    {
   1753        case TPM_ALG_ECDSA:
   1754            retVal = ValidateSignatureEcdsa(rIn, sIn, curveId, Qin, digest);
   1755            break;
   1756 #ifdef   TPM_ALG_ECSCHNORR
   1757         case TPM_ALG_ECSCHNORR:
   1758             retVal = ValidateSignatureEcSchnorr(rIn, sIn, hashAlg, curveId, Qin,
   1759                                               digest);
   1760             break;
   1761 #endif
   1762 #ifdef TPM_ALG_SM2
   1763        case TPM_ALG_SM2:
   1764            retVal = ValidateSignatureSM2Dsa(rIn, sIn, curveId, Qin, digest);
   1765 #endif
   1766        default:
   1767            retVal = CRYPT_SCHEME;
   1768            break;
   1769    }
   1770    return retVal;
   1771 }
   1772 #if CC_ZGen_2Phase == YES //%
   1773 #ifdef TPM_ALG_ECMQV
   1774 //
   1775 //
   1776 //        avf1()
   1777 //
   1778 //       This function does the associated value computation required by MQV key exchange. Process:
   1779 //       a) Convert xQ to an integer xqi using the convention specified in Appendix C.3.
   1780 //       b) Calculate xqm = xqi mod 2^ceil(f/2) (where f = ceil(log2(n)).
   1781 //       c) Calculate the associate value function avf(Q) = xqm + 2ceil(f / 2)
   1782 //
   1783 static BOOL
   1784 avf1(
   1785    BIGNUM              *bnX,               // IN/OUT: the reduced value
   1786    BIGNUM              *bnN                // IN: the order of the curve
   1787    )
   1788 {
   1789 // compute f = 2^(ceil(ceil(log2(n)) / 2))
   1790    int                      f = (BN_num_bits(bnN) + 1) / 2;
   1791 // x' = 2^f + (x mod 2^f)
   1792    BN_mask_bits(bnX, f);   // This is mod 2*2^f but it doesn't matter because
   1793                            // the next operation will SET the extra bit anyway
   1794    BN_set_bit(bnX, f);
   1795    return TRUE;
   1796 }
   1797 //
   1798 //
   1799 //        C_2_2_MQV()
   1800 //
   1801 //       This function performs the key exchange defined in SP800-56A 6.1.1.4 Full MQV, C(2, 2, ECC MQV).
   1802 //       CAUTION: Implementation of this function may require use of essential claims in patents not owned by
   1803 //       TCG members.
   1804 //       Points QsB() and QeB() are required to be on the curve of inQsA. The function will fail, possibly
   1805 //       catastrophically, if this is not the case.
   1806 //
   1807 //
   1808 //
   1809 //       Return Value                      Meaning
   1810 //
   1811 //       CRYPT_SUCCESS                     results is valid
   1812 //       CRYPT_NO_RESULT                   the value for dsA does not give a valid point on the curve
   1813 //
   1814 static CRYPT_RESULT
   1815 C_2_2_MQV(
   1816    TPMS_ECC_POINT                  *outZ,                //   OUT: the computed point
   1817    TPM_ECC_CURVE                    curveId,             //   IN: the curve for the computations
   1818    TPM2B_ECC_PARAMETER             *dsA,                 //   IN: static private TPM key
   1819    TPM2B_ECC_PARAMETER             *deA,                 //   IN: ephemeral private TPM key
   1820    TPMS_ECC_POINT                  *QsB,                 //   IN: static public party B key
   1821    TPMS_ECC_POINT                  *QeB                  //   IN: ephemeral public party B key
   1822    )
   1823 {
   1824    BN_CTX                          *context;
   1825    EC_POINT                        *pQeA = NULL;
   1826    EC_POINT                        *pQeB = NULL;
   1827    EC_POINT                        *pQsB = NULL;
   1828    EC_GROUP                        *group = NULL;
   1829    BIGNUM                          *bnTa;
   1830    BIGNUM                          *bnDeA;
   1831    BIGNUM                          *bnDsA;
   1832    BIGNUM                          *bnXeA;         // x coordinate of ephemeral party A key
   1833    BIGNUM                          *bnH;
   1834    BIGNUM                          *bnN;
   1835    BIGNUM                          *bnXeB;
   1836    const ECC_CURVE_DATA            *curveData = GetCurveData(curveId);
   1837    CRYPT_RESULT                    retVal;
   1838    pAssert(       curveData != NULL && outZ != NULL && dsA != NULL
   1839            &&           deA != NULL && QsB != NULL && QeB != NULL);
   1840    context = BN_CTX_new();
   1841    if(context == NULL || curveData == NULL)
   1842        FAIL(FATAL_ERROR_ALLOCATION);
   1843    BN_CTX_start(context);
   1844    bnTa = BN_CTX_get(context);
   1845    bnDeA = BN_CTX_get(context);
   1846    bnDsA = BN_CTX_get(context);
   1847    bnXeA = BN_CTX_get(context);
   1848    bnH = BN_CTX_get(context);
   1849    bnN = BN_CTX_get(context);
   1850    bnXeB = BN_CTX_get(context);
   1851    if(bnXeB == NULL)
   1852        FAIL(FATAL_ERROR_ALLOCATION);
   1853 // Process:
   1854 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
   1855 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
   1856 // 3. If P = O, output an error indicator.
   1857 // 4. Z=xP, where xP is the x-coordinate of P.
   1858    // Initialize group parameters and local values of input
   1859    if((group = EccCurveInit(curveId, context)) == NULL)
   1860        FAIL(FATAL_ERROR_INTERNAL);
   1861    if((pQeA = EC_POINT_new(group)) == NULL)
   1862        FAIL(FATAL_ERROR_ALLOCATION);
   1863    BnFrom2B(bnDeA, &deA->b);
   1864    BnFrom2B(bnDsA, &dsA->b);
   1865    BnFrom2B(bnH, curveData->h);
   1866    BnFrom2B(bnN, curveData->n);
   1867    BnFrom2B(bnXeB, &QeB->x.b);
   1868    pQeB = EccInitPoint2B(group, QeB, context);
   1869    pQsB = EccInitPoint2B(group, QsB, context);
   1870    // Compute the public ephemeral key pQeA = [de,A]G
   1871    if(    (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context))
   1872       != CRYPT_SUCCESS)
   1873        goto Cleanup;
   1874    if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1)
   1875            FAIL(FATAL_ERROR_INTERNAL);
   1876 // 1. implicitsigA = (de,A + avf(Qe,A)ds,A ) mod n.
   1877 // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
   1878 // Compute 'tA' = ('deA' + 'dsA' avf('XeA')) mod n
   1879    // Ta = avf(XeA);
   1880    BN_copy(bnTa, bnXeA);
   1881    avf1(bnTa, bnN);
   1882    if(// do Ta = ds,A * Ta mod n = dsA * avf(XeA) mod n
   1883          !BN_mod_mul(bnTa, bnDsA, bnTa, bnN, context)
   1884        // now Ta = deA + Ta mod n = deA + dsA * avf(XeA) mod n
   1885        || !BN_mod_add(bnTa, bnDeA, bnTa, bnN, context)
   1886       )
   1887             FAIL(FATAL_ERROR_INTERNAL);
   1888 // 2. P = h(implicitsigA)(Qe,B + avf(Qe,B)Qs,B).
   1889 // Put this in because almost every case of h is == 1 so skip the call when
   1890    // not necessary.
   1891    if(!BN_is_one(bnH))
   1892    {
   1893        // Cofactor is not 1 so compute Ta := Ta * h mod n
   1894        if(!BN_mul(bnTa, bnTa, bnH, context))
   1895            FAIL(FATAL_ERROR_INTERNAL);
   1896    }
   1897    // Now that 'tA' is (h * 'tA' mod n)
   1898    // 'outZ' = (tA)(Qe,B + avf(Qe,B)Qs,B).
   1899    // first, compute XeB = avf(XeB)
   1900    avf1(bnXeB, bnN);
   1901    // QsB := [XeB]QsB
   1902    if(     !EC_POINT_mul(group, pQsB, NULL, pQsB, bnXeB, context)
   1903         // QeB := QsB + QeB
   1904         || !EC_POINT_add(group, pQeB, pQeB, pQsB, context)
   1905        )
   1906         FAIL(FATAL_ERROR_INTERNAL);
   1907    // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
   1908    if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS)
   1909        // Convert BIGNUM E to TPM2B E
   1910        Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context);
   1911 Cleanup:
   1912    if(pQeA != NULL) EC_POINT_free(pQeA);
   1913    if(pQeB != NULL) EC_POINT_free(pQeB);
   1914    if(pQsB != NULL) EC_POINT_free(pQsB);
   1915    if(group != NULL) EC_GROUP_free(group);
   1916    BN_CTX_end(context);
   1917    BN_CTX_free(context);
   1918    return retVal;
   1919 }
   1920 #endif // TPM_ALG_ECMQV
   1921 #ifdef TPM_ALG_SM2 //%
   1922 //
   1923 //
   1924 //        avfSm2()
   1925 //
   1926 //       This function does the associated value computation required by SM2 key exchange. This is different
   1927 //       form the avf() in the international standards because it returns a value that is half the size of the value
   1928 //       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
   1929 //       means that an input value of 14 (1110b) would return a value of 110b with the standard but 10b with the
   1930 //       scheme in SM2.
   1931 //
   1932 static BOOL
   1933 avfSm2(
   1934     BIGNUM              *bnX,                  // IN/OUT: the reduced value
   1935     BIGNUM              *bnN                   // IN: the order of the curve
   1936     )
   1937 {
   1938 // a) set w := ceil(ceil(log2(n)) / 2) - 1
   1939    int                      w = ((BN_num_bits(bnN) + 1) / 2) - 1;
   1940 // b) set x' := 2^w + ( x & (2^w - 1))
   1941 // This is just like the avf for MQV where x' = 2^w + (x mod 2^w)
   1942    BN_mask_bits(bnX, w);   // as wiht avf1, this is too big by a factor of 2 but
   1943                            // it doesn't matter becasue we SET the extra bit anyway
   1944    BN_set_bit(bnX, w);
   1945    return TRUE;
   1946 }
   1947 //
   1948 //       SM2KeyExchange() This function performs the key exchange defined in SM2. The first step is to compute
   1949 //       tA = (dsA + deA avf(Xe,A)) mod n Then, compute the Z value from outZ = (h tA mod n) (QsA +
   1950 //       [avf(QeB().x)](QeB())). The function will compute the ephemeral public key from the ephemeral private
   1951 //       key. All points are required to be on the curve of inQsA. The function will fail catastrophically if this is not
   1952 //       the case
   1953 //
   1954 //       Return Value                      Meaning
   1955 //
   1956 //       CRYPT_SUCCESS                     results is valid
   1957 //       CRYPT_NO_RESULT                   the value for dsA does not give a valid point on the curve
   1958 //
   1959 static CRYPT_RESULT
   1960 SM2KeyExchange(
   1961     TPMS_ECC_POINT                 *outZ,                //   OUT: the computed point
   1962     TPM_ECC_CURVE                   curveId,             //   IN: the curve for the computations
   1963     TPM2B_ECC_PARAMETER            *dsA,                 //   IN: static private TPM key
   1964     TPM2B_ECC_PARAMETER            *deA,                 //   IN: ephemeral private TPM key
   1965     TPMS_ECC_POINT                 *QsB,                 //   IN: static public party B key
   1966     TPMS_ECC_POINT                 *QeB                  //   IN: ephemeral public party B key
   1967     )
   1968 {
   1969     BN_CTX                         *context;
   1970     EC_POINT                       *pQeA = NULL;
   1971     EC_POINT                       *pQeB = NULL;
   1972     EC_POINT                       *pQsB = NULL;
   1973     EC_GROUP                       *group = NULL;
   1974     BIGNUM                         *bnTa;
   1975     BIGNUM                         *bnDeA;
   1976     BIGNUM                         *bnDsA;
   1977     BIGNUM                         *bnXeA;               // x coordinate of ephemeral party A key
   1978     BIGNUM                         *bnH;
   1979     BIGNUM                         *bnN;
   1980     BIGNUM                         *bnXeB;
   1981 //
   1982    const ECC_CURVE_DATA      *curveData = GetCurveData(curveId);
   1983    CRYPT_RESULT              retVal;
   1984    pAssert(       curveData != NULL && outZ != NULL && dsA != NULL
   1985            &&           deA != NULL && QsB != NULL && QeB != NULL);
   1986    context = BN_CTX_new();
   1987    if(context == NULL || curveData == NULL)
   1988        FAIL(FATAL_ERROR_ALLOCATION);
   1989    BN_CTX_start(context);
   1990    bnTa = BN_CTX_get(context);
   1991    bnDeA = BN_CTX_get(context);
   1992    bnDsA = BN_CTX_get(context);
   1993    bnXeA = BN_CTX_get(context);
   1994    bnH = BN_CTX_get(context);
   1995    bnN = BN_CTX_get(context);
   1996    bnXeB = BN_CTX_get(context);
   1997    if(bnXeB == NULL)
   1998        FAIL(FATAL_ERROR_ALLOCATION);
   1999    // Initialize group parameters and local values of input
   2000    if((group = EccCurveInit(curveId, context)) == NULL)
   2001        FAIL(FATAL_ERROR_INTERNAL);
   2002    if((pQeA = EC_POINT_new(group)) == NULL)
   2003        FAIL(FATAL_ERROR_ALLOCATION);
   2004    BnFrom2B(bnDeA, &deA->b);
   2005    BnFrom2B(bnDsA, &dsA->b);
   2006    BnFrom2B(bnH, curveData->h);
   2007    BnFrom2B(bnN, curveData->n);
   2008    BnFrom2B(bnXeB, &QeB->x.b);
   2009    pQeB = EccInitPoint2B(group, QeB, context);
   2010    pQsB = EccInitPoint2B(group, QsB, context);
   2011    // Compute the public ephemeral key pQeA = [de,A]G
   2012    if(    (retVal = PointMul(group, pQeA, bnDeA, NULL, NULL, context))
   2013       != CRYPT_SUCCESS)
   2014        goto Cleanup;
   2015    if(EC_POINT_get_affine_coordinates_GFp(group, pQeA, bnXeA, NULL, context) != 1)
   2016            FAIL(FATAL_ERROR_INTERNAL);
   2017 // tA := (ds,A + de,A avf(Xe,A)) mod n (3)
   2018 // Compute 'tA' = ('dsA' + 'deA' avf('XeA')) mod n
   2019    // Ta = avf(XeA);
   2020    BN_copy(bnTa, bnXeA);
   2021    avfSm2(bnTa, bnN);
   2022    if(// do Ta = de,A * Ta mod n = deA * avf(XeA) mod n
   2023          !BN_mod_mul(bnTa, bnDeA, bnTa, bnN, context)
   2024        // now Ta = dsA + Ta mod n = dsA + deA * avf(XeA) mod n
   2025        || !BN_mod_add(bnTa, bnDsA, bnTa, bnN, context)
   2026       )
   2027             FAIL(FATAL_ERROR_INTERNAL);
   2028 // outZ ? [h tA mod n] (Qs,B + [avf(Xe,B)](Qe,B)) (4)
   2029    // Put this in because almost every case of h is == 1 so skip the call when
   2030    // not necessary.
   2031    if(!BN_is_one(bnH))
   2032    {
   2033        // Cofactor is not 1 so compute Ta := Ta * h mod n
   2034        if(!BN_mul(bnTa, bnTa, bnH, context))
   2035            FAIL(FATAL_ERROR_INTERNAL);
   2036    }
   2037    // Now that 'tA' is (h * 'tA' mod n)
   2038    // 'outZ' = ['tA'](QsB + [avf(QeB.x)](QeB)).
   2039    // first, compute XeB = avf(XeB)
   2040    avfSm2(bnXeB, bnN);
   2041    // QeB := [XeB]QeB
   2042    if(     !EC_POINT_mul(group, pQeB, NULL, pQeB, bnXeB, context)
   2043          // QeB := QsB + QeB
   2044          || !EC_POINT_add(group, pQeB, pQeB, pQsB, context)
   2045         )
   2046          FAIL(FATAL_ERROR_INTERNAL);
   2047    // QeB := [tA]QeB = [tA](QsB + [Xe,B]QeB) and check for at infinity
   2048    if(PointMul(group, pQeB, NULL, pQeB, bnTa, context) == CRYPT_SUCCESS)
   2049        // Convert BIGNUM E to TPM2B E
   2050        Point2B(group, outZ, pQeB, (INT16)BN_num_bytes(bnN), context);
   2051 Cleanup:
   2052    if(pQeA != NULL) EC_POINT_free(pQeA);
   2053    if(pQeB != NULL) EC_POINT_free(pQeB);
   2054    if(pQsB != NULL) EC_POINT_free(pQsB);
   2055    if(group != NULL) EC_GROUP_free(group);
   2056    BN_CTX_end(context);
   2057    BN_CTX_free(context);
   2058    return retVal;
   2059 }
   2060 #endif       //% TPM_ALG_SM2
   2061 //
   2062 //
   2063 //        C_2_2_ECDH()
   2064 //
   2065 //       This function performs the two phase key exchange defined in SP800-56A, 6.1.1.2 Full Unified Model,
   2066 //       C(2, 2, ECC CDH).
   2067 //
   2068 static CRYPT_RESULT
   2069 C_2_2_ECDH(
   2070    TPMS_ECC_POINT                *outZ1,         //   OUT: Zs
   2071    TPMS_ECC_POINT                *outZ2,         //   OUT: Ze
   2072    TPM_ECC_CURVE                  curveId,       //   IN: the curve for the computations
   2073    TPM2B_ECC_PARAMETER           *dsA,           //   IN: static private TPM key
   2074    TPM2B_ECC_PARAMETER           *deA,           //   IN: ephemeral private TPM key
   2075    TPMS_ECC_POINT                *QsB,           //   IN: static public party B key
   2076    TPMS_ECC_POINT                *QeB            //   IN: ephemeral public party B key
   2077    )
   2078 {
   2079    BIGNUM                        *order;
   2080    BN_CTX                        *context;
   2081    EC_POINT                      *pQ = NULL;
   2082    EC_GROUP                      *group = NULL;
   2083    BIGNUM                        *bnD;
   2084    INT16                          size;
   2085    const ECC_CURVE_DATA          *curveData = GetCurveData(curveId);
   2086    context = BN_CTX_new();
   2087    if(context == NULL || curveData == NULL)
   2088        FAIL(FATAL_ERROR_ALLOCATION);
   2089    BN_CTX_start(context);
   2090    order = BN_CTX_get(context);
   2091    if((bnD = BN_CTX_get(context)) == NULL)
   2092        FAIL(FATAL_ERROR_INTERNAL);
   2093    // Initialize group parameters and local values of input
   2094    if((group = EccCurveInit(curveId, context)) == NULL)
   2095        FAIL(FATAL_ERROR_INTERNAL);
   2096    if (!EC_GROUP_get_order(group, order, context))
   2097        FAIL(FATAL_ERROR_INTERNAL);
   2098    size = (INT16)BN_num_bytes(order);
   2099    // Get the static private key of A
   2100    BnFrom2B(bnD, &dsA->b);
   2101    // Initialize the static public point from B
   2102    pQ = EccInitPoint2B(group, QsB, context);
   2103    // Do the point multiply for the Zs value
   2104    if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT)
   2105        // Convert the Zs value
   2106        Point2B(group, outZ1, pQ, size, context);
   2107    // Get the ephemeral private key of A
   2108    BnFrom2B(bnD, &deA->b);
   2109    // Initalize the ephemeral public point from B
   2110    PointFrom2B(group, pQ, QeB, context);
   2111    // Do the point multiply for the Ze value
   2112    if(PointMul(group, pQ, NULL, pQ, bnD, context) != CRYPT_NO_RESULT)
   2113        // Convert the Ze value.
   2114        Point2B(group, outZ2, pQ, size, context);
   2115    if(pQ != NULL) EC_POINT_free(pQ);
   2116    if(group != NULL) EC_GROUP_free(group);
   2117    BN_CTX_end(context);
   2118    BN_CTX_free(context);
   2119    return CRYPT_SUCCESS;
   2120 }
   2121 //
   2122 //
   2123 //        _cpri__C_2_2_KeyExchange()
   2124 //
   2125 //       This function is the dispatch routine for the EC key exchange function that use two ephemeral and two
   2126 //       static keys.
   2127 //
   2128 //       Return Value                   Meaning
   2129 //
   2130 //       CRYPT_SCHEME                   scheme is not defined
   2131 //
   2132 LIB_EXPORT CRYPT_RESULT
   2133 _cpri__C_2_2_KeyExchange(
   2134    TPMS_ECC_POINT              *outZ1,                //   OUT: a computed point
   2135    TPMS_ECC_POINT              *outZ2,                //   OUT: and optional second point
   2136    TPM_ECC_CURVE                curveId,              //   IN: the curve for the computations
   2137    TPM_ALG_ID                   scheme,               //   IN: the key exchange scheme
   2138    TPM2B_ECC_PARAMETER         *dsA,                  //   IN: static private TPM key
   2139    TPM2B_ECC_PARAMETER         *deA,                  //   IN: ephemeral private TPM key
   2140    TPMS_ECC_POINT              *QsB,                  //   IN: static public party B key
   2141    TPMS_ECC_POINT              *QeB                   //   IN: ephemeral public party B key
   2142    )
   2143 {
   2144    pAssert(   outZ1 != NULL
   2145            && dsA != NULL && deA != NULL
   2146            && QsB != NULL && QeB != NULL);
   2147    // Initalize the output points so that they are empty until one of the
   2148    // functions decides otherwise
   2149    outZ1->x.b.size = 0;
   2150    outZ1->y.b.size = 0;
   2151    if(outZ2 != NULL)
   2152    {
   2153        outZ2->x.b.size = 0;
   2154         outZ2->y.b.size = 0;
   2155    }
   2156    switch (scheme)
   2157    {
   2158        case TPM_ALG_ECDH:
   2159            return C_2_2_ECDH(outZ1, outZ2, curveId, dsA, deA, QsB, QeB);
   2160            break;
   2161 #ifdef TPM_ALG_ECMQV
   2162        case TPM_ALG_ECMQV:
   2163            return C_2_2_MQV(outZ1, curveId, dsA, deA, QsB, QeB);
   2164            break;
   2165 #endif
   2166 #ifdef TPM_ALG_SM2
   2167        case TPM_ALG_SM2:
   2168            return SM2KeyExchange(outZ1, curveId, dsA, deA, QsB, QeB);
   2169            break;
   2170 #endif
   2171        default:
   2172            return CRYPT_SCHEME;
   2173    }
   2174 }
   2175 #else       //%
   2176 //
   2177 //       Stub used when the 2-phase key exchange is not defined so that the linker has something to associate
   2178 //       with the value in the .def file.
   2179 //
   2180 LIB_EXPORT CRYPT_RESULT
   2181 _cpri__C_2_2_KeyExchange(
   2182    void
   2183    )
   2184 {
   2185    return CRYPT_FAIL;
   2186 }
   2187 #endif //% CC_ZGen_2Phase
   2188 #endif // TPM_ALG_ECC
   2189