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 "MakeCredential_fp.h"
10 #include "Object_spt_fp.h"
11 //
12 //
13 //     Error Returns                   Meaning
14 //
15 //     TPM_RC_KEY                      handle referenced an ECC key that has a unique field that is not a
16 //                                     point on the curve of the key
17 //     TPM_RC_SIZE                     credential is larger than the digest size of Name algorithm of handle
18 //     TPM_RC_TYPE                     handle does not reference an asymmetric decryption key
19 //
20 TPM_RC
TPM2_MakeCredential(MakeCredential_In * in,MakeCredential_Out * out)21 TPM2_MakeCredential(
22    MakeCredential_In    *in,                 // IN: input parameter list
23    MakeCredential_Out   *out                 // OUT: output parameter list
24    )
25 {
26    TPM_RC                    result = TPM_RC_SUCCESS;
27 
28    OBJECT                    *object;
29    TPM2B_DATA                data;
30 
31 // Input Validation
32 
33    // Get object pointer
34    object = ObjectGet(in->handle);
35 
36    // input key must be an asymmetric, restricted decryption key
37    // NOTE: Needs to be restricted to have a symmetric value.
38    if(   !CryptIsAsymAlgorithm(object->publicArea.type)
39       || object->publicArea.objectAttributes.decrypt == CLEAR
40       || object->publicArea.objectAttributes.restricted == CLEAR
41      )
42        return TPM_RC_TYPE + RC_MakeCredential_handle;
43 
44    // The credential information may not be larger than the digest size used for
45    // the Name of the key associated with handle.
46    if(in->credential.t.size > CryptGetHashDigestSize(object->publicArea.nameAlg))
47        return TPM_RC_SIZE + RC_MakeCredential_credential;
48 
49 // Command Output
50 
51    // Make encrypt key and its associated secret structure.
52    // Even though CrypeSecretEncrypt() may return
53    out->secret.t.size = sizeof(out->secret.t.secret);
54    result = CryptSecretEncrypt(in->handle, "IDENTITY", &data, &out->secret);
55    if(result != TPM_RC_SUCCESS)
56        return result;
57 
58    // Prepare output credential data from secret
59    SecretToCredential(&in->credential, &in->objectName, (TPM2B_SEED *) &data,
60                       in->handle, &out->credentialBlob);
61 
62    return TPM_RC_SUCCESS;
63 }
64