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