Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 3: Commands
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "ZGen_2Phase_fp.h"
     10 #ifdef TPM_CC_ZGen_2Phase // Conditional expansion of this file
     11 //
     12 //     This command uses the TPM to recover one or two Z values in a two phase key exchange protocol
     13 //
     14 //     Error Returns                    Meaning
     15 //
     16 //     TPM_RC_ATTRIBUTES                key referenced by keyA is restricted or not a decrypt key
     17 //     TPM_RC_ECC_POINT                 inQsB or inQeB is not on the curve of the key reference by keyA
     18 //     TPM_RC_KEY                       key referenced by keyA is not an ECC key
     19 //     TPM_RC_SCHEME                    the scheme of the key referenced by keyA is not TPM_ALG_NULL,
     20 //                                      TPM_ALG_ECDH, TPM_ALG_ECMQV or TPM_ALG_SM2
     21 //
     22 TPM_RC
     23 TPM2_ZGen_2Phase(
     24    ZGen_2Phase_In        *in,                 // IN: input parameter list
     25    ZGen_2Phase_Out       *out                 // OUT: output parameter list
     26    )
     27 {
     28    TPM_RC                    result;
     29    OBJECT                   *eccKey;
     30    TPM2B_ECC_PARAMETER       r;
     31    TPM_ALG_ID                scheme;
     32 
     33 // Input Validation
     34 
     35    eccKey = ObjectGet(in->keyA);
     36 
     37    // keyA must be an ECC key
     38    if(eccKey->publicArea.type != TPM_ALG_ECC)
     39        return TPM_RC_KEY + RC_ZGen_2Phase_keyA;
     40 
     41    // keyA must not be restricted and must be a decrypt key
     42    if(   eccKey->publicArea.objectAttributes.restricted == SET
     43       || eccKey->publicArea.objectAttributes.decrypt != SET
     44      )
     45        return TPM_RC_ATTRIBUTES + RC_ZGen_2Phase_keyA;
     46 
     47    // if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise
     48    // the input scheme must be the same as the scheme of keyA
     49    scheme = eccKey->publicArea.parameters.asymDetail.scheme.scheme;
     50    if(scheme != TPM_ALG_NULL)
     51    {
     52        if(scheme != in->inScheme)
     53            return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme;
     54    }
     55    else
     56        scheme = in->inScheme;
     57    if(scheme == TPM_ALG_NULL)
     58        return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme;
     59 
     60    // Input points must be on the curve of keyA
     61    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
     62                               &in->inQsB.t.point))
     63        return TPM_RC_ECC_POINT + RC_ZGen_2Phase_inQsB;
     64 
     65    if(!CryptEccIsPointOnCurve(eccKey->publicArea.parameters.eccDetail.curveID,
     66                               &in->inQeB.t.point))
     67 //
     68        return TPM_RC_ECC_POINT + RC_ZGen_2Phase_inQeB;
     69 
     70    if(!CryptGenerateR(&r, &in->counter,
     71                       eccKey->publicArea.parameters.eccDetail.curveID,
     72                       NULL))
     73            return TPM_RC_VALUE + RC_ZGen_2Phase_counter;
     74 
     75 // Command Output
     76 
     77    result = CryptEcc2PhaseKeyExchange(&out->outZ1.t.point,
     78                                    &out->outZ2.t.point,
     79                                    eccKey->publicArea.parameters.eccDetail.curveID,
     80                                    scheme,
     81                                    &eccKey->sensitive.sensitive.ecc,
     82                                    &r,
     83                                    &in->inQsB.t.point,
     84                                    &in->inQeB.t.point);
     85    if(result == TPM_RC_SCHEME)
     86        return TPM_RC_SCHEME + RC_ZGen_2Phase_inScheme;
     87 
     88    if(result == TPM_RC_SUCCESS)
     89        CryptEndCommit(in->counter);
     90 
     91    return result;
     92 }
     93 #endif
     94