Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 1 | /* |
| 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. */ |
| 22 | typedef uint16_t TPM_SU; |
| 23 | typedef uint16_t TPM_ALG_ID; |
| 24 | typedef uint32_t TPM_CC; |
| 25 | typedef uint32_t TPM_HANDLE; |
| 26 | typedef uint32_t TPM_RC; |
| 27 | typedef uint8_t TPMI_YES_NO; |
Vadim Bendebury | f5ef699 | 2016-07-03 22:20:17 -0700 | [diff] [blame] | 28 | typedef TPM_ALG_ID TPMI_ALG_HASH; |
| 29 | typedef TPM_HANDLE TPMI_DH_PCR; |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 30 | typedef TPM_HANDLE TPMI_RH_NV_INDEX; |
Aaron Durbin | f56c778 | 2017-01-10 17:44:42 -0600 | [diff] [blame] | 31 | typedef TPM_HANDLE TPMI_RH_ENABLES; |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 32 | typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; |
| 33 | typedef TPM_HANDLE TPM_RH; |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 34 | |
| 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 Bendebury | f5ef699 | 2016-07-03 22:20:17 -0700 | [diff] [blame] | 41 | #define SHA256_DIGEST_SIZE 32 |
| 42 | |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 43 | /* Some hardcoded hierarchies. */ |
| 44 | #define TPM_RH_NULL 0x40000007 |
| 45 | #define TPM_RS_PW 0x40000009 |
| 46 | #define TPM_RH_PLATFORM 0x4000000C |
| 47 | |
| 48 | typedef struct { |
| 49 | uint16_t size; |
| 50 | uint8_t *buffer; |
| 51 | } TPM2B; |
| 52 | |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 53 | /* Relevant TPM Command's structures. */ |
| 54 | /* Common command/response header. */ |
| 55 | struct 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 Durbin | f56c778 | 2017-01-10 17:44:42 -0600 | [diff] [blame] | 62 | #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 Durbin | eeb7737 | 2017-03-08 11:23:11 -0600 | [diff] [blame] | 72 | /* 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 Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 81 | |
| 82 | /* Startup values. */ |
| 83 | #define TPM_SU_CLEAR 0 |
| 84 | #define TPM_SU_STATE 1 |
| 85 | |
Vadim Bendebury | f5ef699 | 2016-07-03 22:20:17 -0700 | [diff] [blame] | 86 | #define TPM_HT_PCR 0x00 |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 87 | #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 | |
| 128 | struct tpm2_startup { |
| 129 | TPM_SU startup_type; |
| 130 | }; |
| 131 | |
| 132 | /* Various TPM capability types to use when querying the device. */ |
| 133 | typedef uint32_t TPM_CAP; |
| 134 | #define TPM_CAP_TPM_PROPERTIES ((TPM_CAP)0x00000006) |
| 135 | |
| 136 | typedef TPM_HANDLE TPMI_RH_NV_AUTH; |
| 137 | typedef TPM_HANDLE TPMI_RH_NV_INDEX; |
| 138 | |
| 139 | /* TPM Property capability constants. */ |
| 140 | typedef 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. */ |
| 146 | struct 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. */ |
| 153 | typedef 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 | |
| 164 | typedef 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 | |
| 193 | typedef union { |
| 194 | struct { |
| 195 | uint16_t size; |
Vadim Bendebury | 1a98050 | 2016-07-07 11:15:47 -0700 | [diff] [blame] | 196 | const uint8_t *buffer; |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 197 | } t; |
| 198 | TPM2B b; |
| 199 | } TPM2B_DIGEST; |
| 200 | |
| 201 | typedef TPM2B_DIGEST TPM2B_AUTH; |
| 202 | typedef TPM2B_DIGEST TPM2B_NONCE; |
| 203 | |
| 204 | typedef 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 | |
| 216 | typedef struct { |
| 217 | uint32_t count; |
| 218 | TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES]; |
| 219 | } TPML_TAGGED_TPM_PROPERTY; |
| 220 | |
| 221 | typedef union { |
| 222 | TPML_TAGGED_TPM_PROPERTY tpmProperties; |
| 223 | } TPMU_CAPABILITIES; |
| 224 | |
| 225 | typedef struct { |
| 226 | TPM_CAP capability; |
| 227 | TPMU_CAPABILITIES data; |
| 228 | } TPMS_CAPABILITY_DATA; |
| 229 | |
| 230 | struct get_cap_response { |
| 231 | TPMI_YES_NO more_data; |
| 232 | TPMS_CAPABILITY_DATA cd; |
| 233 | }; |
| 234 | |
| 235 | typedef 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 | |
| 243 | typedef union { |
| 244 | struct { |
| 245 | uint16_t size; |
| 246 | TPMS_NV_PUBLIC nvPublic; |
| 247 | } t; |
| 248 | TPM2B b; |
| 249 | } TPM2B_NV_PUBLIC; |
| 250 | |
| 251 | typedef union { |
| 252 | struct { |
| 253 | uint16_t size; |
| 254 | const uint8_t *buffer; |
| 255 | } t; |
| 256 | TPM2B b; |
| 257 | } TPM2B_MAX_NV_BUFFER; |
| 258 | |
Vadim Bendebury | f5ef699 | 2016-07-03 22:20:17 -0700 | [diff] [blame] | 259 | /* |
| 260 | * This is a union, but as of now we support just one digest - sha256, so |
| 261 | * there is just one element. |
| 262 | */ |
| 263 | typedef union { |
| 264 | uint8_t sha256[SHA256_DIGEST_SIZE]; |
| 265 | } TPMU_HA; |
| 266 | |
| 267 | typedef struct { |
| 268 | TPMI_ALG_HASH hashAlg; |
| 269 | TPMU_HA digest; |
| 270 | } TPMT_HA; |
| 271 | |
| 272 | typedef struct { |
| 273 | uint32_t count; |
| 274 | TPMT_HA digests[1]; /* Limit max number of hashes to 1. */ |
| 275 | } TPML_DIGEST_VALUES; |
| 276 | |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 277 | struct nv_read_response { |
| 278 | uint32_t params_size; |
| 279 | TPM2B_MAX_NV_BUFFER buffer; |
| 280 | }; |
| 281 | |
| 282 | struct 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 | */ |
| 296 | struct 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 | |
| 308 | struct 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 | |
| 317 | struct tpm2_nv_define_space_cmd { |
| 318 | TPM2B_AUTH auth; |
| 319 | TPMS_NV_PUBLIC publicInfo; |
| 320 | }; |
| 321 | |
| 322 | struct tpm2_nv_write_cmd { |
| 323 | TPMI_RH_NV_INDEX nvIndex; |
| 324 | TPM2B_MAX_NV_BUFFER data; |
| 325 | uint16_t offset; |
| 326 | }; |
| 327 | |
| 328 | struct tpm2_self_test { |
| 329 | TPMI_YES_NO yes_no; |
| 330 | }; |
| 331 | |
| 332 | struct tpm2_nv_read_cmd { |
| 333 | TPMI_RH_NV_INDEX nvIndex; |
| 334 | uint16_t size; |
| 335 | uint16_t offset; |
| 336 | }; |
| 337 | |
Vadim Bendebury | 4c0851c | 2016-07-03 17:08:10 -0700 | [diff] [blame] | 338 | struct tpm2_nv_write_lock_cmd { |
| 339 | TPMI_RH_NV_INDEX nvIndex; |
| 340 | }; |
| 341 | |
Vadim Bendebury | f5ef699 | 2016-07-03 22:20:17 -0700 | [diff] [blame] | 342 | struct tpm2_pcr_extend_cmd { |
| 343 | TPMI_DH_PCR pcrHandle; |
| 344 | TPML_DIGEST_VALUES digests; |
| 345 | }; |
| 346 | |
Aaron Durbin | f56c778 | 2017-01-10 17:44:42 -0600 | [diff] [blame] | 347 | struct tpm2_hierarchy_control_cmd { |
| 348 | TPMI_RH_ENABLES enable; |
| 349 | TPMI_YES_NO state; |
| 350 | }; |
| 351 | |
Vadim Bendebury | 245d457 | 2016-04-05 16:01:57 -0700 | [diff] [blame] | 352 | #endif // __SRC_LIB_TPM2_TLCL_STRUCTURES_H |