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 "PolicyTicket_fp.h"
10 #include "Policy_spt_fp.h"
11 //
12 //
13 //     Error Returns                Meaning
14 //
15 //     TPM_RC_CPHASH                policy's cpHash was previously set to a different value
16 //     TPM_RC_EXPIRED               timeout value in the ticket is in the past and the ticket has expired
17 //     TPM_RC_SIZE                  timeout or cpHash has invalid size for the
18 //     TPM_RC_TICKET                ticket is not valid
19 //
20 TPM_RC
TPM2_PolicyTicket(PolicyTicket_In * in)21 TPM2_PolicyTicket(
22    PolicyTicket_In    *in                   // IN: input parameter list
23    )
24 {
25    TPM_RC                    result;
26    SESSION                  *session;
27    UINT64                    timeout;
28    TPMT_TK_AUTH              ticketToCompare;
29    TPM_CC                    commandCode = TPM_CC_PolicySecret;
30 
31 // Input Validation
32 
33    // Get pointer to the session structure
34    session = SessionGet(in->policySession);
35 
36    // NOTE: A trial policy session is not allowed to use this command.
37    // A ticket is used in place of a previously given authorization. Since
38    // a trial policy doesn't actually authenticate, the validated
39    // ticket is not necessary and, in place of using a ticket, one
40    // should use the intended authorization for which the ticket
41    // would be a substitute.
42    if(session->attributes.isTrialPolicy)
43        return TPM_RC_ATTRIBUTES + RC_PolicyTicket_policySession;
44 
45    // Restore timeout data. The format of timeout buffer is TPM-specific.
46    // In this implementation, we simply copy the value of timeout to the
47    // buffer.
48    if(in->timeout.t.size != sizeof(UINT64))
49        return TPM_RC_SIZE + RC_PolicyTicket_timeout;
50    timeout = BYTE_ARRAY_TO_UINT64(in->timeout.t.buffer);
51 
52    // Do the normal checks on the cpHashA and timeout values
53    result = PolicyParameterChecks(session, timeout,
54                                   &in->cpHashA, NULL,
55                                   0,                       // no bad nonce return
56                                   RC_PolicyTicket_cpHashA,
57                                   RC_PolicyTicket_timeout);
58    if(result != TPM_RC_SUCCESS)
59        return result;
60 
61    // Validate Ticket
62    // Re-generate policy ticket by input parameters
63    TicketComputeAuth(in->ticket.tag, in->ticket.hierarchy, timeout, &in->cpHashA,
64                      &in->policyRef, &in->authName, &ticketToCompare);
65 
66    // Compare generated digest with input ticket digest
67    if(!Memory2BEqual(&in->ticket.digest.b, &ticketToCompare.digest.b))
68        return TPM_RC_TICKET + RC_PolicyTicket_ticket;
69 
70 // Internal Data Update
71 
72    // Is this ticket to take the place of a TPM2_PolicySigned() or
73    // a TPM2_PolicySecret()?
74    if(in->ticket.tag == TPM_ST_AUTH_SIGNED)
75        commandCode = TPM_CC_PolicySigned;
76    else if(in->ticket.tag == TPM_ST_AUTH_SECRET)
77        commandCode = TPM_CC_PolicySecret;
78    else
79        // There could only be two possible tag values. Any other value should
80        // be caught by the ticket validation process.
81        pAssert(FALSE);
82 
83    // Update policy context
84    PolicyContextUpdate(commandCode, &in->authName, &in->policyRef,
85                        &in->cpHashA, timeout, session);
86 
87    return TPM_RC_SUCCESS;
88 }
89