blob: ec5b6747013925897e06992241da724cdc6dcce9 [file] [log] [blame]
Vadim Bendebury245d4572016-04-05 16:01:57 -07001/*
2 * Copyright 2016 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#ifndef __SRC_LIB_TPM2_TLCL_STRUCTURES_H
8#define __SRC_LIB_TPM2_TLCL_STRUCTURES_H
9
10/*
11 * This file includes a subset of definitions of TPM protocol version 2.x
12 * constants and structures needed for functions used in coreboot.
13 */
14#include <stdint.h>
15#include <tpm_lite/tlcl.h>
16#include <types.h>
17
18/* This should be plenty for what firmware needs. */
19#define TPM_BUFFER_SIZE 256
20
21/* Basic TPM2 types. */
22typedef uint16_t TPM_SU;
23typedef uint16_t TPM_ALG_ID;
24typedef uint32_t TPM_CC;
25typedef uint32_t TPM_HANDLE;
26typedef uint32_t TPM_RC;
27typedef uint8_t TPMI_YES_NO;
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -070028typedef TPM_ALG_ID TPMI_ALG_HASH;
29typedef TPM_HANDLE TPMI_DH_PCR;
Vadim Bendebury245d4572016-04-05 16:01:57 -070030typedef TPM_HANDLE TPMI_RH_NV_INDEX;
Aaron Durbinf56c7782017-01-10 17:44:42 -060031typedef TPM_HANDLE TPMI_RH_ENABLES;
Vadim Bendebury245d4572016-04-05 16:01:57 -070032typedef TPM_HANDLE TPMI_SH_AUTH_SESSION;
33typedef TPM_HANDLE TPM_RH;
Vadim Bendebury245d4572016-04-05 16:01:57 -070034
35/* Some hardcoded algorithm values. */
36#define TPM_ALG_HMAC ((TPM_ALG_ID)0x0005)
37#define TPM_ALG_NULL ((TPM_ALG_ID)0x0010)
38#define TPM_ALG_SHA1 ((TPM_ALG_ID)0x0004)
39#define TPM_ALG_SHA256 ((TPM_ALG_ID)0x000b)
40
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -070041#define SHA256_DIGEST_SIZE 32
42
Vadim Bendebury245d4572016-04-05 16:01:57 -070043/* Some hardcoded hierarchies. */
44#define TPM_RH_NULL 0x40000007
45#define TPM_RS_PW 0x40000009
46#define TPM_RH_PLATFORM 0x4000000C
47
48typedef struct {
49 uint16_t size;
50 uint8_t *buffer;
51} TPM2B;
52
Vadim Bendebury245d4572016-04-05 16:01:57 -070053/* Relevant TPM Command's structures. */
54/* Common command/response header. */
55struct tpm_header {
56 uint16_t tpm_tag;
57 uint32_t tpm_size;
58 TPM_CC tpm_code;
59} __attribute__((packed));
60
61/* TPM command codes. */
Aaron Durbinf56c7782017-01-10 17:44:42 -060062#define TPM2_Hierarchy_Control ((TPM_CC)0x00000121)
63#define TPM2_Clear ((TPM_CC)0x00000126)
64#define TPM2_NV_DefineSpace ((TPM_CC)0x0000012A)
65#define TPM2_NV_Write ((TPM_CC)0x00000137)
66#define TPM2_NV_WriteLock ((TPM_CC)0x00000138)
67#define TPM2_SelfTest ((TPM_CC)0x00000143)
68#define TPM2_Startup ((TPM_CC)0x00000144)
69#define TPM2_NV_Read ((TPM_CC)0x0000014E)
70#define TPM2_GetCapability ((TPM_CC)0x0000017A)
71#define TPM2_PCR_Extend ((TPM_CC)0x00000182)
Aaron Durbineeb77372017-03-08 11:23:11 -060072/* TPM2 specifies vendor commands need to have this bit set. Vendor command
73 space is defined by the lower 16 bits. */
74#define TPM_CC_VENDOR_BIT_MASK 0x20000000
75/* FIXME: below is not enough to differentiate between vendors commands
76 of numerous devices. However, the current tpm2 APIs aren't very amenable
77 to extending generically because the marshaling code is assuming all
78 knowledge of all commands. */
79#define TPM2_CR50_VENDOR_COMMAND ((TPM_CC)(TPM_CC_VENDOR_BIT_MASK | 0))
80#define TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS (21)
Vadim Bendebury245d4572016-04-05 16:01:57 -070081
82/* Startup values. */
83#define TPM_SU_CLEAR 0
84#define TPM_SU_STATE 1
85
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -070086#define TPM_HT_PCR 0x00
Vadim Bendebury245d4572016-04-05 16:01:57 -070087#define TPM_HT_NV_INDEX 0x01
88#define TPM_HT_HMAC_SESSION 0x02
89#define TPM_HT_POLICY_SESSION 0x03
90
91#define HR_SHIFT 24
92#define HR_PCR (TPM_HT_PCR << HR_SHIFT)
93#define HR_HMAC_SESSION (TPM_HT_HMAC_SESSION << HR_SHIFT)
94#define HR_POLICY_SESSION (TPM_HT_POLICY_SESSION << HR_SHIFT)
95#define HR_TRANSIENT (TPM_HT_TRANSIENT << HR_SHIFT)
96#define HR_PERSISTENT (TPM_HT_PERSISTENT << HR_SHIFT)
97#define HR_NV_INDEX (TPM_HT_NV_INDEX << HR_SHIFT)
98#define HR_PERMANENT (TPM_HT_PERMANENT << HR_SHIFT)
99#define PCR_FIRST (HR_PCR + 0)
100#define PCR_LAST (PCR_FIRST + IMPLEMENTATION_PCR-1)
101#define HMAC_SESSION_FIRST (HR_HMAC_SESSION + 0)
102#define HMAC_SESSION_LAST (HMAC_SESSION_FIRST+MAX_ACTIVE_SESSIONS-1)
103#define LOADED_SESSION_FIRST HMAC_SESSION_FIRST
104#define LOADED_SESSION_LAST HMAC_SESSION_LAST
105#define POLICY_SESSION_FIRST (HR_POLICY_SESSION + 0)
106#define POLICY_SESSION_LAST (POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS-1)
107#define TRANSIENT_FIRST (HR_TRANSIENT + 0)
108#define ACTIVE_SESSION_FIRST POLICY_SESSION_FIRST
109#define ACTIVE_SESSION_LAST POLICY_SESSION_LAST
110#define TRANSIENT_LAST (TRANSIENT_FIRST+MAX_LOADED_OBJECTS-1)
111#define PERSISTENT_FIRST (HR_PERSISTENT + 0)
112#define PERSISTENT_LAST (PERSISTENT_FIRST + 0x00FFFFFF)
113#define PLATFORM_PERSISTENT (PERSISTENT_FIRST + 0x00800000)
114#define NV_INDEX_FIRST (HR_NV_INDEX + 0)
115#define NV_INDEX_LAST (NV_INDEX_FIRST + 0x00FFFFFF)
116#define PERMANENT_FIRST TPM_RH_FIRST
117#define PERMANENT_LAST TPM_RH_LAST
118
119/* Tpm2 command tags. */
120#define TPM_ST_NO_SESSIONS 0x8001
121#define TPM_ST_SESSIONS 0x8002
122
123#define RC_VER1 0x100
124#define TPM_RC_INITIALIZE ((TPM_RC)(RC_VER1 + 0x000))
125
126/* TPM command structures. */
127
128struct tpm2_startup {
129 TPM_SU startup_type;
130};
131
132/* Various TPM capability types to use when querying the device. */
133typedef uint32_t TPM_CAP;
134#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP)0x00000006)
135
136typedef TPM_HANDLE TPMI_RH_NV_AUTH;
137typedef TPM_HANDLE TPMI_RH_NV_INDEX;
138
139/* TPM Property capability constants. */
140typedef uint32_t TPM_PT;
141#define PT_GROUP 0x00000100
142#define PT_VAR (PT_GROUP * 2)
143#define TPM_PT_PERMANENT ((TPM_PT)(PT_VAR + 0))
144
145/* Structures of payloads of various TPM2 commands. */
146struct tpm2_get_capability {
147 TPM_CAP capability;
148 uint32_t property;
149 uint32_t propertyCount;
150};
151
152/* get_capability response when PT_PERMANENT is requested. */
153typedef struct {
154 uint32_t ownerAuthSet : 1;
155 uint32_t endorsementAuthSet : 1;
156 uint32_t lockoutAuthSet : 1;
157 uint32_t reserved3_7 : 5;
158 uint32_t disableClear : 1;
159 uint32_t inLockout : 1;
160 uint32_t tpmGeneratedEPS : 1;
161 uint32_t reserved11_31 : 21;
162} TPMA_PERMANENT;
163
164typedef struct {
165 uint32_t TPMA_NV_PPWRITE : 1;
166 uint32_t TPMA_NV_OWNERWRITE : 1;
167 uint32_t TPMA_NV_AUTHWRITE : 1;
168 uint32_t TPMA_NV_POLICYWRITE : 1;
169 uint32_t TPMA_NV_COUNTER : 1;
170 uint32_t TPMA_NV_BITS : 1;
171 uint32_t TPMA_NV_EXTEND : 1;
172 uint32_t reserved7_9 : 3;
173 uint32_t TPMA_NV_POLICY_DELETE : 1;
174 uint32_t TPMA_NV_WRITELOCKED : 1;
175 uint32_t TPMA_NV_WRITEALL : 1;
176 uint32_t TPMA_NV_WRITEDEFINE : 1;
177 uint32_t TPMA_NV_WRITE_STCLEAR : 1;
178 uint32_t TPMA_NV_GLOBALLOCK : 1;
179 uint32_t TPMA_NV_PPREAD : 1;
180 uint32_t TPMA_NV_OWNERREAD : 1;
181 uint32_t TPMA_NV_AUTHREAD : 1;
182 uint32_t TPMA_NV_POLICYREAD : 1;
183 uint32_t reserved20_24 : 5;
184 uint32_t TPMA_NV_NO_DA : 1;
185 uint32_t TPMA_NV_ORDERLY : 1;
186 uint32_t TPMA_NV_CLEAR_STCLEAR : 1;
187 uint32_t TPMA_NV_READLOCKED : 1;
188 uint32_t TPMA_NV_WRITTEN : 1;
189 uint32_t TPMA_NV_PLATFORMCREATE : 1;
190 uint32_t TPMA_NV_READ_STCLEAR : 1;
191} TPMA_NV;
192
193typedef union {
194 struct {
195 uint16_t size;
Vadim Bendebury1a980502016-07-07 11:15:47 -0700196 const uint8_t *buffer;
Vadim Bendebury245d4572016-04-05 16:01:57 -0700197 } t;
198 TPM2B b;
199} TPM2B_DIGEST;
200
201typedef TPM2B_DIGEST TPM2B_AUTH;
202typedef TPM2B_DIGEST TPM2B_NONCE;
203
204typedef struct {
205 TPM_PT property;
206 uint32_t value;
207} TPMS_TAGGED_PROPERTY;
208
209#define MAX_CAP_DATA (TPM_BUFFER_SIZE - sizeof(struct tpm_header) - \
210 sizeof(TPMI_YES_NO) - sizeof(TPM_CAP) - sizeof(uint32_t))
211#define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY))
212
213/* Somewhat arbitrary, leave enough room for command wrappers. */
214#define MAX_NV_BUFFER_SIZE (TPM_BUFFER_SIZE - sizeof(struct tpm_header) - 50)
215
216typedef struct {
217 uint32_t count;
218 TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
219} TPML_TAGGED_TPM_PROPERTY;
220
221typedef union {
222 TPML_TAGGED_TPM_PROPERTY tpmProperties;
223} TPMU_CAPABILITIES;
224
225typedef struct {
226 TPM_CAP capability;
227 TPMU_CAPABILITIES data;
228} TPMS_CAPABILITY_DATA;
229
230struct get_cap_response {
231 TPMI_YES_NO more_data;
232 TPMS_CAPABILITY_DATA cd;
233};
234
235typedef struct {
236 TPMI_RH_NV_INDEX nvIndex;
237 TPMI_ALG_HASH nameAlg;
238 TPMA_NV attributes;
239 TPM2B_DIGEST authPolicy;
240 uint16_t dataSize;
241} TPMS_NV_PUBLIC;
242
243typedef union {
244 struct {
245 uint16_t size;
246 TPMS_NV_PUBLIC nvPublic;
247 } t;
248 TPM2B b;
249} TPM2B_NV_PUBLIC;
250
251typedef union {
252 struct {
253 uint16_t size;
254 const uint8_t *buffer;
255 } t;
256 TPM2B b;
257} TPM2B_MAX_NV_BUFFER;
258
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700259/*
260 * This is a union, but as of now we support just one digest - sha256, so
261 * there is just one element.
262 */
263typedef union {
264 uint8_t sha256[SHA256_DIGEST_SIZE];
265} TPMU_HA;
266
267typedef struct {
268 TPMI_ALG_HASH hashAlg;
269 TPMU_HA digest;
270} TPMT_HA;
271
272typedef struct {
273 uint32_t count;
274 TPMT_HA digests[1]; /* Limit max number of hashes to 1. */
275} TPML_DIGEST_VALUES;
276
Vadim Bendebury245d4572016-04-05 16:01:57 -0700277struct nv_read_response {
278 uint32_t params_size;
279 TPM2B_MAX_NV_BUFFER buffer;
280};
281
282struct tpm2_session_attrs {
283 uint8_t continueSession : 1;
284 uint8_t auditExclusive : 1;
285 uint8_t auditReset : 1;
286 uint8_t reserved3_4 : 2;
287 uint8_t decrypt : 1;
288 uint8_t encrypt : 1;
289 uint8_t audit : 1;
290};
291
292/*
293 * TPM session header for commands requiring session information. Also
294 * included in the responses to those commands.
295 */
296struct tpm2_session_header {
297 uint32_t session_handle;
298 uint16_t nonce_size;
299 uint8_t *nonce;
300 union {
301 struct tpm2_session_attrs session_attr_bits;
302 uint8_t session_attrs;
303 } __attribute__((packed));
304 uint16_t auth_size;
305 uint8_t *auth;
306};
307
308struct tpm2_response {
309 struct tpm_header hdr;
310 union {
311 struct get_cap_response gc;
312 struct nv_read_response nvr;
313 struct tpm2_session_header def_space;
314 };
315};
316
317struct tpm2_nv_define_space_cmd {
318 TPM2B_AUTH auth;
319 TPMS_NV_PUBLIC publicInfo;
320};
321
322struct tpm2_nv_write_cmd {
323 TPMI_RH_NV_INDEX nvIndex;
324 TPM2B_MAX_NV_BUFFER data;
325 uint16_t offset;
326};
327
328struct tpm2_self_test {
329 TPMI_YES_NO yes_no;
330};
331
332struct tpm2_nv_read_cmd {
333 TPMI_RH_NV_INDEX nvIndex;
334 uint16_t size;
335 uint16_t offset;
336};
337
Vadim Bendebury4c0851c2016-07-03 17:08:10 -0700338struct tpm2_nv_write_lock_cmd {
339 TPMI_RH_NV_INDEX nvIndex;
340};
341
Vadim Bendeburyf5ef6992016-07-03 22:20:17 -0700342struct tpm2_pcr_extend_cmd {
343 TPMI_DH_PCR pcrHandle;
344 TPML_DIGEST_VALUES digests;
345};
346
Aaron Durbinf56c7782017-01-10 17:44:42 -0600347struct tpm2_hierarchy_control_cmd {
348 TPMI_RH_ENABLES enable;
349 TPMI_YES_NO state;
350};
351
Vadim Bendebury245d4572016-04-05 16:01:57 -0700352#endif // __SRC_LIB_TPM2_TLCL_STRUCTURES_H