]>
Commit | Line | Data |
---|---|---|
bfe8fa26 SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright 2019 Google LLC | |
4 | */ | |
5 | ||
6 | #include <common.h> | |
7 | #include <dm.h> | |
8 | #include <log.h> | |
9 | #include <tpm_api.h> | |
10 | #include <tpm-v1.h> | |
11 | #include <tpm-v2.h> | |
12 | #include <tpm_api.h> | |
13 | ||
bfe8fa26 SG |
14 | u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) |
15 | { | |
5e593782 | 16 | if (tpm_is_v1(dev)) { |
bfe8fa26 | 17 | return tpm1_startup(dev, mode); |
5e593782 | 18 | } else if (tpm_is_v2(dev)) { |
b8eb9210 SG |
19 | enum tpm2_startup_types type; |
20 | ||
21 | switch (mode) { | |
22 | case TPM_ST_CLEAR: | |
23 | type = TPM2_SU_CLEAR; | |
24 | break; | |
25 | case TPM_ST_STATE: | |
26 | type = TPM2_SU_STATE; | |
27 | break; | |
28 | default: | |
29 | case TPM_ST_DEACTIVATED: | |
30 | return -EINVAL; | |
31 | } | |
32 | return tpm2_startup(dev, type); | |
33 | } else { | |
bfe8fa26 | 34 | return -ENOSYS; |
b8eb9210 | 35 | } |
bfe8fa26 SG |
36 | } |
37 | ||
38 | u32 tpm_resume(struct udevice *dev) | |
39 | { | |
5e593782 | 40 | if (tpm_is_v1(dev)) |
bfe8fa26 | 41 | return tpm1_startup(dev, TPM_ST_STATE); |
5e593782 | 42 | else if (tpm_is_v2(dev)) |
b8eb9210 | 43 | return tpm2_startup(dev, TPM2_SU_STATE); |
bfe8fa26 SG |
44 | else |
45 | return -ENOSYS; | |
46 | } | |
47 | ||
48 | u32 tpm_self_test_full(struct udevice *dev) | |
49 | { | |
5e593782 | 50 | if (tpm_is_v1(dev)) |
bfe8fa26 | 51 | return tpm1_self_test_full(dev); |
5e593782 | 52 | else if (tpm_is_v2(dev)) |
b8eb9210 | 53 | return tpm2_self_test(dev, TPMI_YES); |
bfe8fa26 SG |
54 | else |
55 | return -ENOSYS; | |
56 | } | |
57 | ||
58 | u32 tpm_continue_self_test(struct udevice *dev) | |
59 | { | |
5e593782 | 60 | if (tpm_is_v1(dev)) |
bfe8fa26 | 61 | return tpm1_continue_self_test(dev); |
5e593782 | 62 | else if (tpm_is_v2(dev)) |
b8eb9210 | 63 | return tpm2_self_test(dev, TPMI_NO); |
bfe8fa26 SG |
64 | else |
65 | return -ENOSYS; | |
66 | } | |
67 | ||
68 | u32 tpm_clear_and_reenable(struct udevice *dev) | |
69 | { | |
70 | u32 ret; | |
71 | ||
72 | log_info("TPM: Clear and re-enable\n"); | |
73 | ret = tpm_force_clear(dev); | |
74 | if (ret != TPM_SUCCESS) { | |
75 | log_err("Can't initiate a force clear\n"); | |
76 | return ret; | |
77 | } | |
78 | ||
5e593782 | 79 | if (tpm_is_v1(dev)) { |
bfe8fa26 SG |
80 | ret = tpm1_physical_enable(dev); |
81 | if (ret != TPM_SUCCESS) { | |
82 | log_err("TPM: Can't set enabled state\n"); | |
83 | return ret; | |
84 | } | |
85 | ||
86 | ret = tpm1_physical_set_deactivated(dev, 0); | |
87 | if (ret != TPM_SUCCESS) { | |
88 | log_err("TPM: Can't set deactivated state\n"); | |
89 | return ret; | |
90 | } | |
bfe8fa26 SG |
91 | } |
92 | ||
93 | return TPM_SUCCESS; | |
94 | } | |
95 | ||
96 | u32 tpm_nv_enable_locking(struct udevice *dev) | |
97 | { | |
5e593782 | 98 | if (tpm_is_v1(dev)) |
bfe8fa26 | 99 | return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0); |
5e593782 | 100 | else if (tpm_is_v2(dev)) |
b8eb9210 | 101 | return -ENOSYS; |
bfe8fa26 SG |
102 | else |
103 | return -ENOSYS; | |
104 | } | |
105 | ||
106 | u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) | |
107 | { | |
5e593782 | 108 | if (tpm_is_v1(dev)) |
bfe8fa26 | 109 | return tpm1_nv_read_value(dev, index, data, count); |
5e593782 | 110 | else if (tpm_is_v2(dev)) |
6719cbe3 | 111 | return tpm2_nv_read_value(dev, index, data, count); |
bfe8fa26 SG |
112 | else |
113 | return -ENOSYS; | |
114 | } | |
115 | ||
116 | u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, | |
117 | u32 count) | |
118 | { | |
5e593782 | 119 | if (tpm_is_v1(dev)) |
bfe8fa26 | 120 | return tpm1_nv_write_value(dev, index, data, count); |
5e593782 | 121 | else if (tpm_is_v2(dev)) |
6719cbe3 | 122 | return tpm2_nv_write_value(dev, index, data, count); |
bfe8fa26 SG |
123 | else |
124 | return -ENOSYS; | |
125 | } | |
126 | ||
127 | u32 tpm_set_global_lock(struct udevice *dev) | |
128 | { | |
129 | return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0); | |
130 | } | |
131 | ||
132 | u32 tpm_write_lock(struct udevice *dev, u32 index) | |
133 | { | |
5e593782 | 134 | if (tpm_is_v1(dev)) |
bfe8fa26 | 135 | return -ENOSYS; |
5e593782 | 136 | else if (tpm_is_v2(dev)) |
7785bc1d | 137 | return tpm2_write_lock(dev, index); |
bfe8fa26 SG |
138 | else |
139 | return -ENOSYS; | |
140 | } | |
141 | ||
142 | u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest, | |
143 | void *out_digest) | |
144 | { | |
5e593782 | 145 | if (tpm_is_v1(dev)) |
bfe8fa26 | 146 | return tpm1_extend(dev, index, in_digest, out_digest); |
5e593782 | 147 | else if (tpm_is_v2(dev)) |
b8eb9210 SG |
148 | return tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, in_digest, |
149 | TPM2_DIGEST_LEN); | |
bfe8fa26 SG |
150 | else |
151 | return -ENOSYS; | |
152 | } | |
153 | ||
154 | u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) | |
155 | { | |
5e593782 | 156 | if (tpm_is_v1(dev)) |
bfe8fa26 | 157 | return tpm1_pcr_read(dev, index, data, count); |
5e593782 | 158 | else if (tpm_is_v2(dev)) |
b8eb9210 | 159 | return -ENOSYS; |
bfe8fa26 SG |
160 | else |
161 | return -ENOSYS; | |
162 | } | |
163 | ||
164 | u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence) | |
165 | { | |
5e593782 | 166 | if (tpm_is_v1(dev)) |
bfe8fa26 | 167 | return tpm1_tsc_physical_presence(dev, presence); |
b8eb9210 SG |
168 | |
169 | /* | |
170 | * Nothing to do on TPM2 for this; use platform hierarchy availability | |
171 | * instead. | |
172 | */ | |
5e593782 | 173 | else if (tpm_is_v2(dev)) |
b8eb9210 | 174 | return 0; |
bfe8fa26 SG |
175 | else |
176 | return -ENOSYS; | |
177 | } | |
178 | ||
179 | u32 tpm_finalise_physical_presence(struct udevice *dev) | |
180 | { | |
5e593782 | 181 | if (tpm_is_v1(dev)) |
bfe8fa26 | 182 | return tpm1_finalise_physical_presence(dev); |
b8eb9210 SG |
183 | |
184 | /* Nothing needs to be done with tpm2 */ | |
5e593782 | 185 | else if (tpm_is_v2(dev)) |
b8eb9210 | 186 | return 0; |
bfe8fa26 SG |
187 | else |
188 | return -ENOSYS; | |
189 | } | |
190 | ||
191 | u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count) | |
192 | { | |
5e593782 | 193 | if (tpm_is_v1(dev)) |
bfe8fa26 | 194 | return tpm1_read_pubek(dev, data, count); |
5e593782 | 195 | else if (tpm_is_v2(dev)) |
bfe8fa26 | 196 | return -ENOSYS; /* not implemented yet */ |
b8eb9210 SG |
197 | else |
198 | return -ENOSYS; | |
bfe8fa26 SG |
199 | } |
200 | ||
201 | u32 tpm_force_clear(struct udevice *dev) | |
202 | { | |
5e593782 | 203 | if (tpm_is_v1(dev)) |
bfe8fa26 | 204 | return tpm1_force_clear(dev); |
5e593782 | 205 | else if (tpm_is_v2(dev)) |
b8eb9210 | 206 | return tpm2_clear(dev, TPM2_RH_PLATFORM, NULL, 0); |
bfe8fa26 SG |
207 | else |
208 | return -ENOSYS; | |
209 | } | |
210 | ||
211 | u32 tpm_physical_enable(struct udevice *dev) | |
212 | { | |
5e593782 | 213 | if (tpm_is_v1(dev)) |
bfe8fa26 | 214 | return tpm1_physical_enable(dev); |
b8eb9210 SG |
215 | |
216 | /* Nothing needs to be done with tpm2 */ | |
5e593782 | 217 | else if (tpm_is_v2(dev)) |
b8eb9210 | 218 | return 0; |
bfe8fa26 SG |
219 | else |
220 | return -ENOSYS; | |
221 | } | |
222 | ||
223 | u32 tpm_physical_disable(struct udevice *dev) | |
224 | { | |
5e593782 | 225 | if (tpm_is_v1(dev)) |
bfe8fa26 | 226 | return tpm1_physical_disable(dev); |
b8eb9210 SG |
227 | |
228 | /* Nothing needs to be done with tpm2 */ | |
5e593782 | 229 | else if (tpm_is_v2(dev)) |
b8eb9210 | 230 | return 0; |
bfe8fa26 SG |
231 | else |
232 | return -ENOSYS; | |
233 | } | |
234 | ||
235 | u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state) | |
236 | { | |
5e593782 | 237 | if (tpm_is_v1(dev)) |
bfe8fa26 | 238 | return tpm1_physical_set_deactivated(dev, state); |
b8eb9210 | 239 | /* Nothing needs to be done with tpm2 */ |
5e593782 | 240 | else if (tpm_is_v2(dev)) |
b8eb9210 | 241 | return 0; |
bfe8fa26 SG |
242 | else |
243 | return -ENOSYS; | |
244 | } | |
245 | ||
246 | u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap, | |
247 | void *cap, size_t count) | |
248 | { | |
5e593782 | 249 | if (tpm_is_v1(dev)) |
bfe8fa26 | 250 | return tpm1_get_capability(dev, cap_area, sub_cap, cap, count); |
5e593782 | 251 | else if (tpm_is_v2(dev)) |
b8eb9210 | 252 | return tpm2_get_capability(dev, cap_area, sub_cap, cap, count); |
bfe8fa26 SG |
253 | else |
254 | return -ENOSYS; | |
255 | } | |
256 | ||
257 | u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm) | |
258 | { | |
5e593782 | 259 | if (tpm_is_v1(dev)) |
bfe8fa26 | 260 | return tpm1_get_permissions(dev, index, perm); |
5e593782 | 261 | else if (tpm_is_v2(dev)) |
bfe8fa26 | 262 | return -ENOSYS; /* not implemented yet */ |
b8eb9210 SG |
263 | else |
264 | return -ENOSYS; | |
bfe8fa26 SG |
265 | } |
266 | ||
267 | u32 tpm_get_random(struct udevice *dev, void *data, u32 count) | |
268 | { | |
5e593782 | 269 | if (tpm_is_v1(dev)) |
bfe8fa26 | 270 | return tpm1_get_random(dev, data, count); |
5e593782 | 271 | else if (tpm_is_v2(dev)) |
bfe8fa26 | 272 | return -ENOSYS; /* not implemented yet */ |
b8eb9210 SG |
273 | else |
274 | return -ENOSYS; | |
bfe8fa26 | 275 | } |