blob: 5b2c11a277cc9c4610d1f546f34d56b10dbd2128 [file] [log] [blame]
Simon Glassbfe8fa22021-02-06 14:23:35 -07001// 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
Simon Glassbfe8fa22021-02-06 14:23:35 -070014u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
15{
Simon Glass5e593782022-07-22 21:32:02 +053016 if (tpm_is_v1(dev)) {
Simon Glassbfe8fa22021-02-06 14:23:35 -070017 return tpm1_startup(dev, mode);
Simon Glass5e593782022-07-22 21:32:02 +053018 } else if (tpm_is_v2(dev)) {
Simon Glassb8eb9212021-02-06 14:23:37 -070019 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 {
Simon Glassbfe8fa22021-02-06 14:23:35 -070034 return -ENOSYS;
Simon Glassb8eb9212021-02-06 14:23:37 -070035 }
Simon Glassbfe8fa22021-02-06 14:23:35 -070036}
37
Ilias Apalodimasa595be32023-01-25 12:18:36 +020038u32 tpm_auto_start(struct udevice *dev)
39{
40 if (tpm_is_v2(dev))
41 return tpm2_auto_start(dev);
42
43 return -ENOSYS;
44}
45
Simon Glassbfe8fa22021-02-06 14:23:35 -070046u32 tpm_resume(struct udevice *dev)
47{
Simon Glass5e593782022-07-22 21:32:02 +053048 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -070049 return tpm1_startup(dev, TPM_ST_STATE);
Simon Glass5e593782022-07-22 21:32:02 +053050 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -070051 return tpm2_startup(dev, TPM2_SU_STATE);
Simon Glassbfe8fa22021-02-06 14:23:35 -070052 else
53 return -ENOSYS;
54}
55
56u32 tpm_self_test_full(struct udevice *dev)
57{
Simon Glass5e593782022-07-22 21:32:02 +053058 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -070059 return tpm1_self_test_full(dev);
Simon Glass5e593782022-07-22 21:32:02 +053060 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -070061 return tpm2_self_test(dev, TPMI_YES);
Simon Glassbfe8fa22021-02-06 14:23:35 -070062 else
63 return -ENOSYS;
64}
65
66u32 tpm_continue_self_test(struct udevice *dev)
67{
Simon Glass5e593782022-07-22 21:32:02 +053068 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -070069 return tpm1_continue_self_test(dev);
Simon Glass5e593782022-07-22 21:32:02 +053070 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -070071 return tpm2_self_test(dev, TPMI_NO);
Simon Glassbfe8fa22021-02-06 14:23:35 -070072 else
73 return -ENOSYS;
74}
75
76u32 tpm_clear_and_reenable(struct udevice *dev)
77{
78 u32 ret;
79
80 log_info("TPM: Clear and re-enable\n");
81 ret = tpm_force_clear(dev);
82 if (ret != TPM_SUCCESS) {
83 log_err("Can't initiate a force clear\n");
84 return ret;
85 }
86
Simon Glass5e593782022-07-22 21:32:02 +053087 if (tpm_is_v1(dev)) {
Simon Glassbfe8fa22021-02-06 14:23:35 -070088 ret = tpm1_physical_enable(dev);
89 if (ret != TPM_SUCCESS) {
90 log_err("TPM: Can't set enabled state\n");
91 return ret;
92 }
93
94 ret = tpm1_physical_set_deactivated(dev, 0);
95 if (ret != TPM_SUCCESS) {
96 log_err("TPM: Can't set deactivated state\n");
97 return ret;
98 }
Simon Glassbfe8fa22021-02-06 14:23:35 -070099 }
100
101 return TPM_SUCCESS;
102}
103
104u32 tpm_nv_enable_locking(struct udevice *dev)
105{
Simon Glass5e593782022-07-22 21:32:02 +0530106 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700107 return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
Simon Glass5e593782022-07-22 21:32:02 +0530108 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700109 return -ENOSYS;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700110 else
111 return -ENOSYS;
112}
113
114u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
115{
Simon Glass5e593782022-07-22 21:32:02 +0530116 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700117 return tpm1_nv_read_value(dev, index, data, count);
Simon Glass5e593782022-07-22 21:32:02 +0530118 else if (tpm_is_v2(dev))
Simon Glass6719cbe2021-02-06 14:23:40 -0700119 return tpm2_nv_read_value(dev, index, data, count);
Simon Glassbfe8fa22021-02-06 14:23:35 -0700120 else
121 return -ENOSYS;
122}
123
124u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
125 u32 count)
126{
Simon Glass5e593782022-07-22 21:32:02 +0530127 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700128 return tpm1_nv_write_value(dev, index, data, count);
Simon Glass5e593782022-07-22 21:32:02 +0530129 else if (tpm_is_v2(dev))
Simon Glass6719cbe2021-02-06 14:23:40 -0700130 return tpm2_nv_write_value(dev, index, data, count);
Simon Glassbfe8fa22021-02-06 14:23:35 -0700131 else
132 return -ENOSYS;
133}
134
135u32 tpm_set_global_lock(struct udevice *dev)
136{
137 return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0);
138}
139
140u32 tpm_write_lock(struct udevice *dev, u32 index)
141{
Simon Glass5e593782022-07-22 21:32:02 +0530142 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700143 return -ENOSYS;
Simon Glass5e593782022-07-22 21:32:02 +0530144 else if (tpm_is_v2(dev))
Simon Glass7785bc12021-02-06 14:23:41 -0700145 return tpm2_write_lock(dev, index);
Simon Glassbfe8fa22021-02-06 14:23:35 -0700146 else
147 return -ENOSYS;
148}
149
150u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest,
Simon Glassa557d252022-08-30 21:05:32 -0600151 uint size, void *out_digest, const char *name)
Simon Glassbfe8fa22021-02-06 14:23:35 -0700152{
Simon Glassa557d252022-08-30 21:05:32 -0600153 if (tpm_is_v1(dev)) {
Simon Glassbfe8fa22021-02-06 14:23:35 -0700154 return tpm1_extend(dev, index, in_digest, out_digest);
Simon Glassa557d252022-08-30 21:05:32 -0600155 } else if (tpm_is_v2(dev)) {
Simon Glassb8eb9212021-02-06 14:23:37 -0700156 return tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, in_digest,
157 TPM2_DIGEST_LEN);
Simon Glassa557d252022-08-30 21:05:32 -0600158 /* @name is ignored as we do not support the TPM log here */
159 } else {
Simon Glassbfe8fa22021-02-06 14:23:35 -0700160 return -ENOSYS;
Simon Glassa557d252022-08-30 21:05:32 -0600161 }
Simon Glassbfe8fa22021-02-06 14:23:35 -0700162}
163
164u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
165{
Simon Glass5e593782022-07-22 21:32:02 +0530166 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700167 return tpm1_pcr_read(dev, index, data, count);
Simon Glass5e593782022-07-22 21:32:02 +0530168 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700169 return -ENOSYS;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700170 else
171 return -ENOSYS;
172}
173
174u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence)
175{
Simon Glass5e593782022-07-22 21:32:02 +0530176 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700177 return tpm1_tsc_physical_presence(dev, presence);
Simon Glassb8eb9212021-02-06 14:23:37 -0700178
179 /*
180 * Nothing to do on TPM2 for this; use platform hierarchy availability
181 * instead.
182 */
Simon Glass5e593782022-07-22 21:32:02 +0530183 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700184 return 0;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700185 else
186 return -ENOSYS;
187}
188
189u32 tpm_finalise_physical_presence(struct udevice *dev)
190{
Simon Glass5e593782022-07-22 21:32:02 +0530191 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700192 return tpm1_finalise_physical_presence(dev);
Simon Glassb8eb9212021-02-06 14:23:37 -0700193
194 /* Nothing needs to be done with tpm2 */
Simon Glass5e593782022-07-22 21:32:02 +0530195 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700196 return 0;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700197 else
198 return -ENOSYS;
199}
200
201u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count)
202{
Simon Glass5e593782022-07-22 21:32:02 +0530203 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700204 return tpm1_read_pubek(dev, data, count);
Simon Glass5e593782022-07-22 21:32:02 +0530205 else if (tpm_is_v2(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700206 return -ENOSYS; /* not implemented yet */
Simon Glassb8eb9212021-02-06 14:23:37 -0700207 else
208 return -ENOSYS;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700209}
210
211u32 tpm_force_clear(struct udevice *dev)
212{
Simon Glass5e593782022-07-22 21:32:02 +0530213 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700214 return tpm1_force_clear(dev);
Simon Glass5e593782022-07-22 21:32:02 +0530215 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700216 return tpm2_clear(dev, TPM2_RH_PLATFORM, NULL, 0);
Simon Glassbfe8fa22021-02-06 14:23:35 -0700217 else
218 return -ENOSYS;
219}
220
221u32 tpm_physical_enable(struct udevice *dev)
222{
Simon Glass5e593782022-07-22 21:32:02 +0530223 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700224 return tpm1_physical_enable(dev);
Simon Glassb8eb9212021-02-06 14:23:37 -0700225
226 /* Nothing needs to be done with tpm2 */
Simon Glass5e593782022-07-22 21:32:02 +0530227 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700228 return 0;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700229 else
230 return -ENOSYS;
231}
232
233u32 tpm_physical_disable(struct udevice *dev)
234{
Simon Glass5e593782022-07-22 21:32:02 +0530235 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700236 return tpm1_physical_disable(dev);
Simon Glassb8eb9212021-02-06 14:23:37 -0700237
238 /* Nothing needs to be done with tpm2 */
Simon Glass5e593782022-07-22 21:32:02 +0530239 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700240 return 0;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700241 else
242 return -ENOSYS;
243}
244
245u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state)
246{
Simon Glass5e593782022-07-22 21:32:02 +0530247 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700248 return tpm1_physical_set_deactivated(dev, state);
Simon Glassb8eb9212021-02-06 14:23:37 -0700249 /* Nothing needs to be done with tpm2 */
Simon Glass5e593782022-07-22 21:32:02 +0530250 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700251 return 0;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700252 else
253 return -ENOSYS;
254}
255
256u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
257 void *cap, size_t count)
258{
Simon Glass5e593782022-07-22 21:32:02 +0530259 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700260 return tpm1_get_capability(dev, cap_area, sub_cap, cap, count);
Simon Glass5e593782022-07-22 21:32:02 +0530261 else if (tpm_is_v2(dev))
Simon Glassb8eb9212021-02-06 14:23:37 -0700262 return tpm2_get_capability(dev, cap_area, sub_cap, cap, count);
Simon Glassbfe8fa22021-02-06 14:23:35 -0700263 else
264 return -ENOSYS;
265}
266
267u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm)
268{
Simon Glass5e593782022-07-22 21:32:02 +0530269 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700270 return tpm1_get_permissions(dev, index, perm);
Simon Glass5e593782022-07-22 21:32:02 +0530271 else if (tpm_is_v2(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700272 return -ENOSYS; /* not implemented yet */
Simon Glassb8eb9212021-02-06 14:23:37 -0700273 else
274 return -ENOSYS;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700275}
276
277u32 tpm_get_random(struct udevice *dev, void *data, u32 count)
278{
Simon Glass5e593782022-07-22 21:32:02 +0530279 if (tpm_is_v1(dev))
Simon Glassbfe8fa22021-02-06 14:23:35 -0700280 return tpm1_get_random(dev, data, count);
Simon Glass5e593782022-07-22 21:32:02 +0530281 else if (tpm_is_v2(dev))
Sughosh Ganue67ffb52022-07-22 21:32:04 +0530282 return tpm2_get_random(dev, data, count);
283
284 return -ENOSYS;
Simon Glassbfe8fa22021-02-06 14:23:35 -0700285}