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