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