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 "PolicySecret_fp.h"
10 #include "Policy_spt_fp.h"
11 //
12 //
13 //     Error Returns                 Meaning
14 //
15 //     TPM_RC_CPHASH                 cpHash for policy was previously set to a value that is not the same
16 //                                   as cpHashA
17 //     TPM_RC_EXPIRED                expiration indicates a time in the past
18 //     TPM_RC_NONCE                  nonceTPM does not match the nonce associated with policySession
19 //     TPM_RC_SIZE                   cpHashA is not the size of a digest for the hash associated with
20 //                                   policySession
21 //     TPM_RC_VALUE                  input policyID or expiration does not match the internal data in policy
22 //                                   session
23 //
24 TPM_RC
TPM2_PolicySecret(PolicySecret_In * in,PolicySecret_Out * out)25 TPM2_PolicySecret(
26    PolicySecret_In    *in,                 // IN: input parameter list
27    PolicySecret_Out   *out                 // OUT: output parameter list
28    )
29 {
30    TPM_RC                  result;
31    SESSION                *session;
32    TPM2B_NAME              entityName;
33    UINT32                  expiration = (in->expiration < 0)
34                                         ? -(in->expiration) : in->expiration;
35    UINT64                  authTimeout = 0;
36 
37 // Input Validation
38 
39    // Get pointer to the session structure
40    session = SessionGet(in->policySession);
41 
42    //Only do input validation if this is not a trial policy session
43    if(session->attributes.isTrialPolicy == CLEAR)
44    {
45 
46        if(expiration != 0)
47            authTimeout = expiration * 1000 + session->startTime;
48 
49        result = PolicyParameterChecks(session, authTimeout,
50                                        &in->cpHashA, &in->nonceTPM,
51                                        RC_PolicySecret_nonceTPM,
52                                        RC_PolicySecret_cpHashA,
53                                        RC_PolicySecret_expiration);
54        if(result != TPM_RC_SUCCESS)
55            return result;
56    }
57 
58 // Internal Data Update
59    // Need the name of the authorizing entity
60    entityName.t.size = EntityGetName(in->authHandle, &entityName.t.name);
61 
62    // Update policy context with input policyRef and name of auth key
63    // This value is computed even for trial sessions. Possibly update the cpHash
64    PolicyContextUpdate(TPM_CC_PolicySecret, &entityName, &in->policyRef,
65                        &in->cpHashA, authTimeout, session);
66 
67 // Command Output
68 
69    // Create ticket and timeout buffer if in->expiration < 0 and this is not
70    // a trial session.
71    // NOTE: PolicyParameterChecks() makes sure that nonceTPM is present
72    // when expiration is non-zero.
73    if(   in->expiration < 0
74       && session->attributes.isTrialPolicy == CLEAR
75      )
76    {
77        // Generate timeout buffer. The format of output timeout buffer is
78        // TPM-specific.
79        // Note: can't do a direct copy because the output buffer is a byte
80        // array and it may not be aligned to accept a 64-bit value. The method
81        // used has the side-effect of making the returned value a big-endian,
82        // 64-bit value that is byte aligned.
83        out->timeout.t.size = sizeof(UINT64);
84        UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
85 
86        // Compute policy ticket
87        TicketComputeAuth(TPM_ST_AUTH_SECRET, EntityGetHierarchy(in->authHandle),
88                          authTimeout, &in->cpHashA, &in->policyRef,
89                          &entityName, &out->policyTicket);
90    }
91    else
92    {
93        // timeout buffer is null
94        out->timeout.t.size = 0;
95 
96        // auth ticket is null
97        out->policyTicket.tag = TPM_ST_AUTH_SECRET;
98        out->policyTicket.hierarchy = TPM_RH_NULL;
99        out->policyTicket.digest.t.size = 0;
100    }
101 
102    return TPM_RC_SUCCESS;
103 }
104