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 "Attest_spt_fp.h"
10 #include "CertifyCreation_fp.h"
11 //
12 //
13 //     Error Returns               Meaning
14 //
15 //     TPM_RC_KEY                  key referenced by signHandle is not a signing key
16 //     TPM_RC_SCHEME               inScheme is not compatible with signHandle
17 //     TPM_RC_TICKET               creationTicket does not match objectHandle
18 //     TPM_RC_VALUE                digest generated for inScheme is greater or has larger size than the
19 //                                 modulus of signHandle, or the buffer for the result in signature is too
20 //                                 small (for an RSA key); invalid commit status (for an ECC key with a
21 //                                 split scheme).
22 //
23 TPM_RC
TPM2_CertifyCreation(CertifyCreation_In * in,CertifyCreation_Out * out)24 TPM2_CertifyCreation(
25    CertifyCreation_In     *in,                // IN: input parameter list
26    CertifyCreation_Out    *out                // OUT: output parameter list
27    )
28 {
29    TPM_RC                 result;
30    TPM2B_NAME             name;
31    TPMT_TK_CREATION       ticket;
32    TPMS_ATTEST            certifyInfo;
33 
34 // Input Validation
35 
36    // CertifyCreation specific input validation
37    // Get certified object name
38    name.t.size = ObjectGetName(in->objectHandle, &name.t.name);
39    // Re-compute ticket
40    TicketComputeCreation(in->creationTicket.hierarchy, &name,
41                          &in->creationHash, &ticket);
42    // Compare ticket
43    if(!Memory2BEqual(&ticket.digest.b, &in->creationTicket.digest.b))
44        return TPM_RC_TICKET + RC_CertifyCreation_creationTicket;
45 
46 // Command Output
47    // Common fields
48    result = FillInAttestInfo(in->signHandle, &in->inScheme, &in->qualifyingData,
49                              &certifyInfo);
50    if(result != TPM_RC_SUCCESS)
51    {
52        if(result == TPM_RC_KEY)
53            return TPM_RC_KEY + RC_CertifyCreation_signHandle;
54        else
55            return RcSafeAddToResult(result, RC_CertifyCreation_inScheme);
56    }
57 
58    // CertifyCreation specific fields
59    // Attestation type
60    certifyInfo.type = TPM_ST_ATTEST_CREATION;
61    certifyInfo.attested.creation.objectName = name;
62 
63    // Copy the creationHash
64    certifyInfo.attested.creation.creationHash = in->creationHash;
65 
66    // Sign attestation structure.   A NULL signature will be returned if
67    // signHandle is TPM_RH_NULL. A TPM_RC_NV_UNAVAILABLE, TPM_RC_NV_RATE,
68    // TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES error may be returned at
69    // this point
70    result = SignAttestInfo(in->signHandle,
71                            &in->inScheme,
72                            &certifyInfo,
73                            &in->qualifyingData,
74                            &out->certifyInfo,
75                            &out->signature);
76 
77    // TPM_RC_ATTRIBUTES cannot be returned here as FillInAttestInfo would already
78    // have returned TPM_RC_KEY
79    pAssert(result != TPM_RC_ATTRIBUTES);
80 
81    if(result != TPM_RC_SUCCESS)
82        return result;
83 
84    // orderly state should be cleared because of the reporting of clock info
85    // if signing happens
86    if(in->signHandle != TPM_RH_NULL)
87        g_clearOrderly = TRUE;
88 
89    return TPM_RC_SUCCESS;
90 }
91