1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2022, Linaro Limited
4 */
5
6 #ifndef __TPM2_H__
7 #define __TPM2_H__
8
9 #include <stdint.h>
10 #include <types_ext.h>
11 #include <util.h>
12
13 /* Algorithm Registry */
14 #define EFI_TCG2_BOOT_HASH_ALG_SHA1 BIT(0)
15 #define EFI_TCG2_BOOT_HASH_ALG_SHA256 BIT(1)
16 #define EFI_TCG2_BOOT_HASH_ALG_SHA384 BIT(2)
17 #define EFI_TCG2_BOOT_HASH_ALG_SHA512 BIT(3)
18 #define EFI_TCG2_BOOT_HASH_ALG_SM3_256 BIT(4)
19
20 /* TPM2_ST Structure Tags */
21 #define TPM2_ST_RSP_COMMAND U(0x00C4)
22 #define TPM2_ST_NULL U(0X8000)
23 #define TPM2_ST_NO_SESSIONS U(0x8001)
24 #define TPM2_ST_SESSIONS U(0x8002)
25
26 /* TPM2_SU Constants Shutdown and startup modes */
27 #define TPM2_SU_CLEAR U(0x0000)
28 #define TPM2_SU_STATE U(0x0001)
29
30 /* Command Codes */
31 #define TPM2_CC_NV_WRITE U(0x00000137)
32 #define TPM2_CC_SELFTEST U(0x00000143)
33 #define TPM2_CC_STARTUP U(0x00000144)
34 #define TPM2_CC_NV_READ U(0x0000014E)
35 #define TPM2_CC_GET_CAPABILITY U(0x0000017A)
36 #define TPM2_CC_PCR_READ U(0x0000017E)
37 #define TPM2_CC_PCR_EXTEND U(0x00000182)
38
39 /* Table 22 TPM2_CAP constants */
40 #define TPM2_CAP_PCRS U(0x00000005)
41 #define TPM2_CAP_TPM_PROPERTIES U(0x00000006)
42
43 /* Table 23 TPM2_PT constants */
44 #define TPM2_PT_NONE U(0x00000000)
45 #define TPM2_PT_GROUP U(0x00000100)
46 #define TPM2_PT_FIXED (TPM2_PT_GROUP * 1)
47 #define TPM2_PT_PCR_COUNT (TPM2_PT_FIXED + 18)
48 #define TPM2_PT_PCR_SELECT_MIN (TPM2_PT_FIXED + 19)
49
50 /* Table 28 TPM_RH constants */
51 #define TPM_RS_PW U(0x40000009)
52
53 /* TPM_ALG_ID table 19 Part2 Structures */
54 #define TPM2_ALG_SHA1 U(0x0004)
55 #define TPM2_ALG_SHA256 U(0x000B)
56 #define TPM2_ALG_SHA384 U(0x000C)
57 #define TPM2_ALG_SHA512 U(0x000D)
58
59 /* Section 4.2 - TSS_Overview_Common_v1_r10_pub09232021.pdf */
60
61 /* ABI Constants */
62 #define TPM2_SHA_DIGEST_SIZE 20
63 #define TPM2_SHA1_DIGEST_SIZE 20
64 #define TPM2_SHA256_DIGEST_SIZE 32
65 #define TPM2_SHA384_DIGEST_SIZE 48
66 #define TPM2_SHA512_DIGEST_SIZE 64
67 #define TPM2_SM3_256_DIGEST_SIZE 32
68
69 /* The following set of ABI constants were chosen by the TSS Working Group.
70 * They represent reasonable, future-proof values.
71 */
72 #define TPM2_NUM_PCR_BANKS 16
73 #define TPM2_MAX_PCRS 32
74 #define TPM2_PCR_SELECT_MAX ((TPM2_MAX_PCRS + 7) / 8)
75
76 /* Table 78 - Definition of TPMU_HA Union */
77 union tpmu_ha {
78 uint8_t sha[TPM2_SHA_DIGEST_SIZE];
79 uint8_t sha1[TPM2_SHA1_DIGEST_SIZE];
80 uint8_t sha256[TPM2_SHA256_DIGEST_SIZE];
81 uint8_t sha384[TPM2_SHA384_DIGEST_SIZE];
82 uint8_t sha512[TPM2_SHA512_DIGEST_SIZE];
83 uint8_t sm3_256[TPM2_SM3_256_DIGEST_SIZE];
84 };
85
86 /* Table 79 - Definition of TPMT_HA Structure */
87 struct tpmt_ha {
88 uint16_t hash_alg;
89 union tpmu_ha digest;
90 } __packed;
91
92 /* Table 110 TPML_DIGEST_VALUES */
93 struct tpml_digest_values {
94 uint32_t count;
95 struct tpmt_ha digests[TPM2_NUM_PCR_BANKS];
96 } __packed;
97
98 /* Table 80 - Definition of TPM2B_DIGEST Structure */
99 struct tpm2b_digest {
100 uint16_t size;
101 uint8_t buffer[sizeof(union tpmu_ha)];
102 } __packed;
103
104 /* Table 109 - Definition of TPML_DIGEST Structure */
105 struct tpml_digest {
106 uint32_t count;
107 struct tpm2b_digest digest[8];
108 } __packed;
109
110 /* Table 93 - Definition of TPMS_PCR_SELECTION Structure */
111 struct tpms_pcr_selection {
112 uint16_t hash;
113 uint8_t size_of_select;
114 uint8_t pcr_select[TPM2_PCR_SELECT_MAX];
115 } __packed;
116
117 /* Table 111 - Definition of TPML_PCR_SELECTION Structure */
118 struct tpml_pcr_selection {
119 uint32_t count;
120 struct tpms_pcr_selection pcr_selections[TPM2_NUM_PCR_BANKS];
121 } __packed;
122
123 /* Table 101 TPMS_TAGGED_PROPERTY */
124 struct tpms_tagged_property {
125 uint32_t property;
126 uint32_t value;
127 } __packed;
128
129 /* Table 113 TPML_TAGGED_TPM_PROPERTY */
130 struct tpml_tagged_tpm_property {
131 uint32_t count;
132 struct tpms_tagged_property tpm_property[];
133 } __packed;
134
135 /* Table 109 TPMU_CAPABILITIES Union */
136 union tpmu_capabilities {
137 /*
138 * Non exhaustive. Only added the structs needed for our
139 * current code
140 */
141 struct tpml_pcr_selection assigned_pcr;
142 struct tpml_tagged_tpm_property tpm_properties;
143 } __packed;
144
145 /* Table 119 TPMS_CAPABILITY_DATA Structure */
146 struct tpms_capability_data {
147 uint32_t capability;
148 union tpmu_capabilities data;
149 } __packed;
150
151 struct tpms_auth_command {
152 uint32_t handle;
153 struct tpm2b_digest nonce;
154 uint8_t session_attributes;
155 struct tpm2b_digest hmac;
156 } __packed;
157
158 /*
159 * Send a TPM2_Startup command
160 *
161 * @mode - TPM startup mode
162 * It is one of TPM2_SU_CLEAR or TPM2_SU_STATE
163 *
164 * @return - tpm2_result
165 */
166 enum tpm2_result tpm2_startup(uint16_t mode);
167
168 /*
169 * Send a TPM2_SelfTest command
170 *
171 * @full - 1 if full test needs to be performed
172 * 0 if only test of untested functions required
173 *
174 * @return - tpm2_result
175 */
176 enum tpm2_result tpm2_selftest(uint8_t full);
177
178 /*
179 * Get TPM capabilities by sending a TPM2_GetCapability command
180 *
181 * @capability - Capability group selection of type TPM_CAP
182 * @property - Property associated with the capability
183 * @prop_cnt - Number of properties in indicated type
184 * @buf - Returns the content of TPMU_CAPABILITIES from response buffer
185 * (Part of TPMS_CAPABILITY_DATA Structure retrned in response)
186 * @buf_len - Size of the content returned
187 *
188 * @return - tpm2_result
189 */
190 enum tpm2_result tpm2_get_capability(uint32_t capability, uint32_t property,
191 uint32_t prop_cnt, void *buf,
192 uint32_t *buf_len);
193
194 /*
195 * Read the PCR by sending a TPM2_PCR_Read command
196 *
197 * @pcr_idx - Index of the PCR to read
198 * @alg - Hash algorithm (Bank) associated with PCR
199 * @digest - Output buffer to return content of PCR
200 * @digest_len - Size of the content read
201 *
202 * @return - tpm2_result
203 */
204 enum tpm2_result tpm2_pcr_read(uint8_t pcr_idx, uint16_t alg, void *digest,
205 uint32_t *digest_len);
206
207 /*
208 * Extend the PCR by sending a TPM2_PCR_Extend command
209 *
210 * @pcr_idx - index of the PCR to be extended
211 * @alg - Hash algorithm (Bank) associated with PCR
212 * @digest - Input buffer with content to be extended
213 * @digest_len - Size of the content
214 *
215 * @return - tpm2_result
216 */
217 enum tpm2_result tpm2_pcr_extend(uint8_t pcr_idx, uint16_t alg, void *digest,
218 uint32_t digest_len);
219
220 /*
221 * Get hash length corresponding to TPM algorithm
222 *
223 * @alg - TPM2 hash algorithm ID, on of TPM2_ALG_*
224 *
225 * @return - hash length or 0 if algorithm not supported
226 */
tpm2_get_alg_len(uint16_t alg)227 static inline uint32_t tpm2_get_alg_len(uint16_t alg)
228 {
229 switch (alg) {
230 case TPM2_ALG_SHA1:
231 return TPM2_SHA1_DIGEST_SIZE;
232 case TPM2_ALG_SHA256:
233 return TPM2_SHA256_DIGEST_SIZE;
234 case TPM2_ALG_SHA384:
235 return TPM2_SHA384_DIGEST_SIZE;
236 case TPM2_ALG_SHA512:
237 return TPM2_SHA512_DIGEST_SIZE;
238 default:
239 return 0;
240 }
241 }
242
243 /*
244 * Get TCG hash mask for TPM algorithm
245 *
246 * @alg - TPM2 hash algorithm ID, on of TPM2_ALG_*
247 *
248 * @return - TCG hashing algorithm bitmaps or 0 if algorithm not supported
249 */
tpm2_alg_to_tcg_mask(uint16_t alg)250 static inline uint32_t tpm2_alg_to_tcg_mask(uint16_t alg)
251 {
252 switch (alg) {
253 case TPM2_ALG_SHA1:
254 return EFI_TCG2_BOOT_HASH_ALG_SHA1;
255 case TPM2_ALG_SHA256:
256 return EFI_TCG2_BOOT_HASH_ALG_SHA256;
257 case TPM2_ALG_SHA384:
258 return EFI_TCG2_BOOT_HASH_ALG_SHA384;
259 case TPM2_ALG_SHA512:
260 return EFI_TCG2_BOOT_HASH_ALG_SHA512;
261 default:
262 return 0;
263 }
264 }
265
266 #endif /* __TPM2_H__ */
267