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//
20TPM_RC
21TPM2_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