Coverage Report

Created: 2025-07-11 06:15

/src/tpm2/PolicySigned.c
Line
Count
Source (jump to first uncovered line)
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 "Policy_spt_fp.h"
10
#include "PolicySigned_fp.h"
11
//
12
//
13
//     Error Returns                     Meaning
14
//
15
//     TPM_RC_CPHASH                     cpHash was previously set to a different value
16
//     TPM_RC_EXPIRED                    expiration indicates a time in the past or expiration is non-zero but no
17
//                                       nonceTPM is present
18
//     TPM_RC_HANDLE                     authObject need to have sensitive portion loaded
19
//     TPM_RC_KEY                        authObject is not a signing scheme
20
//     TPM_RC_NONCE                      nonceTPM is not the nonce associated with the policySession
21
//     TPM_RC_SCHEME                     the signing scheme of auth is not supported by the TPM
22
//     TPM_RC_SIGNATURE                  the signature is not genuine
23
//     TPM_RC_SIZE                       input cpHash has wrong size
24
//     TPM_RC_VALUE                      input policyID or expiration does not match the internal data in policy
25
//                                       session
26
//
27
TPM_RC
28
TPM2_PolicySigned(
29
   PolicySigned_In       *in,                  // IN: input parameter list
30
   PolicySigned_Out      *out                  // OUT: output parameter list
31
   )
32
0
{
33
0
   TPM_RC                     result = TPM_RC_SUCCESS;
34
0
   SESSION                   *session;
35
0
   TPM2B_NAME                 entityName;
36
0
   TPM2B_DIGEST               authHash;
37
0
   HASH_STATE                 hashState;
38
0
   UINT32                     expiration = (in->expiration < 0)
39
0
                                           ? -(in->expiration) : in->expiration;
40
0
   UINT64                     authTimeout = 0;
41
42
// Input Validation
43
44
   // Set up local pointers
45
0
   session = SessionGet(in->policySession);               // the session structure
46
47
   // Only do input validation if this is not a trial policy session
48
0
   if(session->attributes.isTrialPolicy == CLEAR)
49
0
   {
50
0
       if(expiration != 0)
51
0
           authTimeout = expiration * 1000 + session->startTime;
52
53
0
       result = PolicyParameterChecks(session, authTimeout,
54
0
                                       &in->cpHashA, &in->nonceTPM,
55
0
                                       RC_PolicySigned_nonceTPM,
56
0
                                       RC_PolicySigned_cpHashA,
57
0
                                       RC_PolicySigned_expiration);
58
0
       if(result != TPM_RC_SUCCESS)
59
0
           return result;
60
61
       // Re-compute the digest being signed
62
       /*(See part 3 specification)
63
       // The digest is computed as:
64
       //     aHash := hash ( nonceTPM | expiration | cpHashA | policyRef)
65
       // where:
66
       //      hash()      the hash associated with the signed auth
67
       //      nonceTPM    the nonceTPM value from the TPM2_StartAuthSession .
68
       //                  response If the authorization is not limited to this
69
       //                  session, the size of this value is zero.
70
       //      expiration time limit on authorization set by authorizing object.
71
       //                  This 32-bit value is set to zero if the expiration
72
       //                  time is not being set.
73
       //      cpHashA     hash of the command parameters for the command being
74
       //                  approved using the hash algorithm of the PSAP session.
75
       //                  Set to NULLauth if the authorization is not limited
76
       //                  to a specific command.
77
       //      policyRef   hash of an opaque value determined by the authorizing
78
       //                  object. Set to the NULLdigest if no hash is present.
79
       */
80
       // Start hash
81
0
       authHash.t.size = CryptStartHash(CryptGetSignHashAlg(&in->auth),
82
0
                                        &hashState);
83
84
       // add nonceTPM
85
0
       CryptUpdateDigest2B(&hashState, &in->nonceTPM.b);
86
87
       // add expiration
88
0
       CryptUpdateDigestInt(&hashState, sizeof(UINT32), (BYTE*) &in->expiration);
89
90
       // add cpHashA
91
0
       CryptUpdateDigest2B(&hashState, &in->cpHashA.b);
92
93
       // add policyRef
94
0
       CryptUpdateDigest2B(&hashState, &in->policyRef.b);
95
96
       // Complete digest
97
0
       CryptCompleteHash2B(&hashState, &authHash.b);
98
99
       // Validate Signature. A TPM_RC_SCHEME, TPM_RC_HANDLE or TPM_RC_SIGNATURE
100
       // error may be returned at this point
101
0
       result = CryptVerifySignature(in->authObject, &authHash, &in->auth);
102
0
       if(result != TPM_RC_SUCCESS)
103
0
           return RcSafeAddToResult(result, RC_PolicySigned_auth);
104
0
   }
105
// Internal Data Update
106
   // Need the Name of the signing entity
107
0
   entityName.t.size = EntityGetName(in->authObject, &entityName.t.name);
108
109
   // Update policy with input policyRef and name of auth key
110
   // These values are updated even if the session is a trial session
111
0
   PolicyContextUpdate(TPM_CC_PolicySigned, &entityName, &in->policyRef,
112
0
                       &in->cpHashA, authTimeout, session);
113
114
// Command Output
115
116
   // Create ticket and timeout buffer if in->expiration < 0 and this is not
117
   // a trial session.
118
   // NOTE: PolicyParameterChecks() makes sure that nonceTPM is present
119
   // when expiration is non-zero.
120
0
   if(   in->expiration < 0
121
0
      && session->attributes.isTrialPolicy == CLEAR
122
0
     )
123
0
   {
124
       // Generate timeout buffer. The format of output timeout buffer is
125
       // TPM-specific.
126
       // Note: can't do a direct copy because the output buffer is a byte
127
       // array and it may not be aligned to accept a 64-bit value. The method
128
       // used has the side-effect of making the returned value a big-endian,
129
       // 64-bit value that is byte aligned.
130
0
       out->timeout.t.size = sizeof(UINT64);
131
0
       UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
132
133
       // Compute policy ticket
134
0
       TicketComputeAuth(TPM_ST_AUTH_SIGNED, EntityGetHierarchy(in->authObject),
135
0
                         authTimeout, &in->cpHashA, &in->policyRef, &entityName,
136
0
                         &out->policyTicket);
137
0
   }
138
0
   else
139
0
   {
140
       // Generate a null ticket.
141
       // timeout buffer is null
142
0
       out->timeout.t.size = 0;
143
144
       // auth ticket is null
145
0
       out->policyTicket.tag = TPM_ST_AUTH_SIGNED;
146
0
       out->policyTicket.hierarchy = TPM_RH_NULL;
147
0
       out->policyTicket.digest.t.size = 0;
148
0
   }
149
150
0
   return TPM_RC_SUCCESS;
151
0
}