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
TPM2_ECDH_KeyGen(ECDH_KeyGen_In * in,ECDH_KeyGen_Out * out)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