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 "ECDH_KeyGen_fp.h"
     10 #ifdef TPM_ALG_ECC
     11 //
     12 //
     13 //     Error Returns                     Meaning
     14 //
     15 //     TPM_RC_KEY                        keyHandle does not reference a non-restricted decryption ECC key
     16 //
     17 TPM_RC
     18 TPM2_ECDH_KeyGen(
     19    ECDH_KeyGen_In        *in,                 // IN: input parameter list
     20    ECDH_KeyGen_Out       *out                 // OUT: output parameter list
     21    )
     22 {
     23    OBJECT                    *eccKey;
     24    TPM2B_ECC_PARAMETER        sensitive;
     25    TPM_RC                     result;
     26 
     27 // Input Validation
     28 
     29    eccKey = ObjectGet(in->keyHandle);
     30 
     31    // Input key must be a non-restricted, decrypt ECC key
     32    if(   eccKey->publicArea.type != TPM_ALG_ECC)
     33        return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle;
     34 
     35    if(     eccKey->publicArea.objectAttributes.restricted == SET
     36       ||   eccKey->publicArea.objectAttributes.decrypt != SET
     37      )
     38        return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle;
     39 
     40 // Command Output
     41    do
     42    {
     43        // Create ephemeral ECC key
     44        CryptNewEccKey(eccKey->publicArea.parameters.eccDetail.curveID,
     45                       &out->pubPoint.t.point, &sensitive);
     46 
     47        out->pubPoint.t.size = TPMS_ECC_POINT_Marshal(&out->pubPoint.t.point,
     48                               NULL, NULL);
     49 
     50        // Compute Z
     51        result = CryptEccPointMultiply(&out->zPoint.t.point,
     52                                   eccKey->publicArea.parameters.eccDetail.curveID,
     53                                   &sensitive, &eccKey->publicArea.unique.ecc);
     54        // The point in the key is not on the curve. Indicate that the key is bad.
     55        if(result == TPM_RC_ECC_POINT)
     56            return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle;
     57        // The other possible error is TPM_RC_NO_RESULT indicating that the
     58        // multiplication resulted in the point at infinity, so get a new
     59        // random key and start over (hardly ever happens).
     60    }
     61    while(result == TPM_RC_NO_RESULT);
     62 
     63    if(result == TPM_RC_SUCCESS)
     64        // Marshal the values to generate the point.
     65        out->zPoint.t.size = TPMS_ECC_POINT_Marshal(&out->zPoint.t.point,
     66                                                    NULL, NULL);
     67 
     68    return result;
     69 }
     70 #endif
     71