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