1 // This file was extracted from the TCG Published
2 // Trusted Platform Module Library
3 // Part 4: Supporting Routines
4 // Family "2.0"
5 // Level 00 Revision 01.16
6 // October 30, 2014
7 
8 #include    "Tpm.h"
9 #include    "InternalRoutines.h"
10 typedef UINT16          ATTRIBUTE_TYPE;
11 //
12 //     The following file is produced from the command tables in part 3 of the specification. It defines the
13 //     attributes for each of the commands.
14 //
15 //     NOTE:           This file is currently produced by an automated process. Files produced from Part 2 or Part 3 tables through
16 //                     automated processes are not included in the specification so that their is no ambiguity about the table
17 //                     containing the information being the normative definition.
18 //
19 #include       "CommandAttributeData.c"
20 //
21 //
22 //          Command Attribute Functions
23 //
24 //          CommandAuthRole()
25 //
26 //     This function returns the authorization role required of a handle.
27 //
28 //     Return Value                       Meaning
29 //
30 //     AUTH_NONE                          no authorization is required
31 //     AUTH_USER                          user role authorization is required
32 //     AUTH_ADMIN                         admin role authorization is required
33 //     AUTH_DUP                           duplication role authorization is required
34 //
35 AUTH_ROLE
CommandAuthRole(TPM_CC commandCode,UINT32 handleIndex)36 CommandAuthRole(
37      TPM_CC        commandCode,                 // IN: command code
38      UINT32        handleIndex                  // IN: handle index (zero based)
39      )
40 {
41    if(handleIndex > 1)
42        return AUTH_NONE;
43    if(handleIndex == 0) {
44        ATTRIBUTE_TYPE properties = s_commandAttributes[commandCode - TPM_CC_FIRST];
45        if(properties & HANDLE_1_USER) return AUTH_USER;
46        if(properties & HANDLE_1_ADMIN) return AUTH_ADMIN;
47        if(properties & HANDLE_1_DUP) return AUTH_DUP;
48        return AUTH_NONE;
49    }
50    if(s_commandAttributes[commandCode - TPM_CC_FIRST] & HANDLE_2_USER)
51            return AUTH_USER;
52    return AUTH_NONE;
53 }
54 //
55 //
56 //          CommandIsImplemented()
57 //
58 //     This function indicates if a command is implemented.
59 //
60 //     Return Value                      Meaning
61 //
62 //     TRUE                              if the command is implemented
63 //     FALSE                             if the command is not implemented
64 //
65 BOOL
CommandIsImplemented(TPM_CC commandCode)66 CommandIsImplemented(
67     TPM_CC                commandCode          // IN: command code
68     )
69 {
70     if(commandCode < TPM_CC_FIRST || commandCode > TPM_CC_LAST)
71         return FALSE;
72     if((s_commandAttributes[commandCode - TPM_CC_FIRST] & IS_IMPLEMENTED))
73         return TRUE;
74     else
75         return FALSE;
76 }
77 //
78 //
79 //          CommandGetAttribute()
80 //
81 //     return a TPMA_CC structure for the given command code
82 //
83 TPMA_CC
CommandGetAttribute(TPM_CC commandCode)84 CommandGetAttribute(
85     TPM_CC                commandCode          // IN: command code
86     )
87 {
88     UINT32      size = sizeof(s_ccAttr) / sizeof(s_ccAttr[0]);
89     UINT32      i;
90     for(i = 0; i < size; i++) {
91         if(s_ccAttr[i].commandIndex == (UINT16) commandCode)
92             return s_ccAttr[i];
93     }
94     // This function should be called in the way that the command code
95     // attribute is available.
96     FAIL(FATAL_ERROR_INTERNAL);
97 
98     return s_ccAttr[0]; // Just to appease the compiler, never reached.
99 }
100 //
101 //
102 //          EncryptSize()
103 //
104 //     This function returns the size of the decrypt size field. This function returns 0 if encryption is not allowed
105 //
106 //     Return Value                      Meaning
107 //
108 //     0                                 encryption not allowed
109 //     2                                 size field is two bytes
110 //     4                                 size field is four bytes
111 //
112 int
EncryptSize(TPM_CC commandCode)113 EncryptSize(
114     TPM_CC                commandCode          // IN: commandCode
115     )
116 {
117     COMMAND_ATTRIBUTES        ca = s_commandAttributes[commandCode - TPM_CC_FIRST];
118     if(ca & ENCRYPT_2)
119         return 2;
120     if(ca & ENCRYPT_4)
121         return 4;
122     return 0;
123 }
124 //
125 //
126 //          DecryptSize()
127 //
128 //     This function returns the size of the decrypt size field. This function returns 0 if decryption is not allowed
129 //
130 //     Return Value                      Meaning
131 //
132 //     0                                 encryption not allowed
133 //     2                                 size field is two bytes
134 //     4                                 size field is four bytes
135 //
136 int
DecryptSize(TPM_CC commandCode)137 DecryptSize(
138     TPM_CC                commandCode          // IN: commandCode
139     )
140 {
141     COMMAND_ATTRIBUTES        ca = s_commandAttributes[commandCode - TPM_CC_FIRST];
142     if(ca & DECRYPT_2)
143         return 2;
144     if(ca & DECRYPT_4)
145         return 4;
146     return 0;
147 }
148 //
149 //
150 //          IsSessionAllowed()
151 //
152 //     This function indicates if the command is allowed to have sessions.
153 //     This function must not be called if the command is not known to be implemented.
154 //
155 //     Return Value                      Meaning
156 //
157 //     TRUE                              session is allowed with this command
158 //     FALSE                             session is not allowed with this command
159 //
160 BOOL
IsSessionAllowed(TPM_CC commandCode)161 IsSessionAllowed(
162     TPM_CC                commandCode          // IN: the command to be checked
163     )
164 {
165     if(s_commandAttributes[commandCode - TPM_CC_FIRST] & NO_SESSIONS)
166         return FALSE;
167     else
168         return TRUE;
169 }
170 //
171 //
172 //          IsHandleInResponse()
173 //
174 BOOL
IsHandleInResponse(TPM_CC commandCode)175 IsHandleInResponse(
176     TPM_CC                commandCode
177     )
178 {
179     if(s_commandAttributes[commandCode - TPM_CC_FIRST] & R_HANDLE)
180         return TRUE;
181     else
182         return FALSE;
183 //
184 }
185 //
186 //
187 //           IsWriteOperation()
188 //
189 //      Checks to see if an operation will write to NV memory
190 //
191 BOOL
IsWriteOperation(TPM_CC command)192 IsWriteOperation(
193    TPM_CC               command           // IN: Command to check
194    )
195 {
196    switch (command)
197    {
198        case TPM_CC_NV_Write:
199        case TPM_CC_NV_Increment:
200        case TPM_CC_NV_SetBits:
201        case TPM_CC_NV_Extend:
202        // Nv write lock counts as a write operation for authorization purposes.
203        // We check to see if the NV is write locked before we do the authorization
204        // If it is locked, we fail the command early.
205        case TPM_CC_NV_WriteLock:
206            return TRUE;
207        default:
208            break;
209    }
210    return FALSE;
211 }
212 //
213 //
214 //           IsReadOperation()
215 //
216 //      Checks to see if an operation will write to NV memory
217 //
218 BOOL
IsReadOperation(TPM_CC command)219 IsReadOperation(
220    TPM_CC               command           // IN: Command to check
221    )
222 {
223    switch (command)
224    {
225        case TPM_CC_NV_Read:
226        case TPM_CC_PolicyNV:
227        case TPM_CC_NV_Certify:
228        // Nv read lock counts as a read operation for authorization purposes.
229        // We check to see if the NV is read locked before we do the authorization
230        // If it is locked, we fail the command early.
231        case TPM_CC_NV_ReadLock:
232            return TRUE;
233        default:
234            break;
235    }
236    return FALSE;
237 }
238 //
239 //
240 //          CommandCapGetCCList()
241 //
242 //      This function returns a list of implemented commands and command attributes starting from the
243 //      command in commandCode.
244 //
245 //
246 //
247 //
248 //      Return Value                      Meaning
249 //
250 //      YES                               more command attributes are available
251 //      NO                                no more command attributes are available
252 //
253 TPMI_YES_NO
CommandCapGetCCList(TPM_CC commandCode,UINT32 count,TPML_CCA * commandList)254 CommandCapGetCCList(
255      TPM_CC            commandCode,         // IN: start command code
256      UINT32            count,               // IN: maximum count for number of entries in
257                                             //     'commandList'
258      TPML_CCA         *commandList          // OUT: list of TPMA_CC
259      )
260 {
261      TPMI_YES_NO       more = NO;
262      UINT32            i;
263      // initialize output handle list count
264      commandList->count = 0;
265      // The maximum count of commands that may be return is MAX_CAP_CC.
266      if(count > MAX_CAP_CC) count = MAX_CAP_CC;
267      // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
268      if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
269      // Collect command attributes
270      for(i = commandCode; i <= TPM_CC_LAST; i++)
271      {
272          if(CommandIsImplemented(i))
273          {
274              if(commandList->count < count)
275              {
276                  // If the list is not full, add the attributes for this command.
277                  commandList->commandAttributes[commandList->count]
278                      = CommandGetAttribute(i);
279                  commandList->count++;
280              }
281              else
282              {
283                  // If the list is full but there are more commands to report,
284                  // indicate this and return.
285                  more = YES;
286                  break;
287              }
288          }
289      }
290      return more;
291 }
292