blob: 64c3d419c64dbb2e706307344301a8afd7a459e2 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
Scottaad14062016-10-11 10:42:52 -070015// TPM_RC_ATTRIBUTES If the key is restricted or the key is not a decryption key
Vadim Bendebury56797522015-05-20 10:32:25 -070016// TPM_RC_KEY keyHandle does not reference a non-restricted decryption ECC key
17//
18TPM_RC
19TPM2_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)
Vadim Bendebury065e0d72015-10-16 09:35:42 -070034 return TPM_RC_KEY + RC_ECDH_KeyGen_keyHandle;
Vadim Bendebury56797522015-05-20 10:32:25 -070035
36 if( eccKey->publicArea.objectAttributes.restricted == SET
37 || eccKey->publicArea.objectAttributes.decrypt != SET
38 )
Scottaad14062016-10-11 10:42:52 -070039 return TPM_RC_ATTRIBUTES + RC_ECDH_KeyGen_keyHandle;
Vadim Bendebury56797522015-05-20 10:32:25 -070040
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