Blame view
lib/tpm-v2.c
11.9 KB
ff32245bb tpm: prepare supp... |
1 2 3 4 5 6 7 8 9 10 11 |
// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2018 Bootlin * Author: Miquel Raynal <miquel.raynal@bootlin.com> */ #include <common.h> #include <dm.h> #include <tpm-common.h> #include <tpm-v2.h> #include "tpm-utils.h" |
1922df201 tpm: add TPM2_Sta... |
12 |
|
abdc7b8a2 tpm: Convert to u... |
13 |
u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) |
1922df201 tpm: add TPM2_Sta... |
14 15 16 17 18 19 20 21 22 23 24 25 26 |
{ const u8 command_v2[12] = { tpm_u16(TPM2_ST_NO_SESSIONS), tpm_u32(12), tpm_u32(TPM2_CC_STARTUP), tpm_u16(mode), }; int ret; /* * Note TPM2_Startup command will return RC_SUCCESS the first time, * but will return RC_INITIALIZE otherwise. */ |
abdc7b8a2 tpm: Convert to u... |
27 |
ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
1922df201 tpm: add TPM2_Sta... |
28 29 30 31 32 |
if (ret && ret != TPM2_RC_INITIALIZE) return ret; return 0; } |
2dc6d97e1 tpm: add TPM2_Sel... |
33 |
|
abdc7b8a2 tpm: Convert to u... |
34 |
u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test) |
2dc6d97e1 tpm: add TPM2_Sel... |
35 36 37 38 39 40 41 |
{ const u8 command_v2[12] = { tpm_u16(TPM2_ST_NO_SESSIONS), tpm_u32(11), tpm_u32(TPM2_CC_SELF_TEST), full_test, }; |
abdc7b8a2 tpm: Convert to u... |
42 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
2dc6d97e1 tpm: add TPM2_Sel... |
43 |
} |
bad8ff569 tpm: add TPM2_Cle... |
44 |
|
abdc7b8a2 tpm: Convert to u... |
45 46 |
u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw, const ssize_t pw_sz) |
bad8ff569 tpm: add TPM2_Cle... |
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(27 + pw_sz), /* Length */ tpm_u32(TPM2_CC_CLEAR), /* Command code */ /* HANDLE */ tpm_u32(handle), /* TPM resource handle */ /* AUTH_SESSION */ tpm_u32(9 + pw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* Session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(pw_sz), /* Size of <hmac/password> */ /* STRING(pw) <hmac/password> (if any) */ }; unsigned int offset = 27; int ret; /* * Fill the command structure starting from the first buffer: * - the password (if any) */ ret = pack_byte_string(command_v2, sizeof(command_v2), "s", offset, pw, pw_sz); offset += pw_sz; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
77 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
bad8ff569 tpm: add TPM2_Cle... |
78 |
} |
6284be5a9 tpm: add TPM2_PCR... |
79 |
|
abdc7b8a2 tpm: Convert to u... |
80 |
u32 tpm2_pcr_extend(struct udevice *dev, u32 index, const uint8_t *digest) |
6284be5a9 tpm: add TPM2_PCR... |
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(33 + TPM2_DIGEST_LEN), /* Length */ tpm_u32(TPM2_CC_PCR_EXTEND), /* Command code */ /* HANDLE */ tpm_u32(index), /* Handle (PCR Index) */ /* AUTH_SESSION */ tpm_u32(9), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* Session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(0), /* Size of <hmac/password> */ /* <hmac/password> (if any) */ tpm_u32(1), /* Count (number of hashes) */ tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ /* STRING(digest) Digest */ }; unsigned int offset = 33; int ret; /* * Fill the command structure starting from the first buffer: * - the digest */ ret = pack_byte_string(command_v2, sizeof(command_v2), "s", offset, digest, TPM2_DIGEST_LEN); offset += TPM2_DIGEST_LEN; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
114 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
6284be5a9 tpm: add TPM2_PCR... |
115 |
} |
1c4ea8f49 tpm: add TPM2_PCR... |
116 |
|
abdc7b8a2 tpm: Convert to u... |
117 118 |
u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, void *data, unsigned int *updates) |
1c4ea8f49 tpm: add TPM2_PCR... |
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
{ u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ tpm_u32(17 + idx_array_sz), /* Length */ tpm_u32(TPM2_CC_PCR_READ), /* Command code */ /* TPML_PCR_SELECTION */ tpm_u32(1), /* Number of selections */ tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ idx_array_sz, /* Array size for selection */ /* bitmap(idx) Selected PCR bitmap */ }; size_t response_len = COMMAND_BUFFER_SIZE; u8 response[COMMAND_BUFFER_SIZE]; unsigned int pcr_sel_idx = idx / 8; u8 pcr_sel_bit = BIT(idx % 8); unsigned int counter = 0; int ret; if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "b", 17 + pcr_sel_idx, pcr_sel_bit)) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
142 |
ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); |
1c4ea8f49 tpm: add TPM2_PCR... |
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
if (ret) return ret; if (unpack_byte_string(response, response_len, "ds", 10, &counter, response_len - TPM2_DIGEST_LEN, data, TPM2_DIGEST_LEN)) return TPM_LIB_ERROR; if (updates) *updates = counter; return 0; } |
69cd8f068 tpm: add TPM2_Get... |
157 |
|
abdc7b8a2 tpm: Convert to u... |
158 159 |
u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property, void *buf, size_t prop_count) |
69cd8f068 tpm: add TPM2_Get... |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ tpm_u32(22), /* Length */ tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ tpm_u32(capability), /* Capability */ tpm_u32(property), /* Property */ tpm_u32(prop_count), /* Property count */ }; u8 response[COMMAND_BUFFER_SIZE]; size_t response_len = COMMAND_BUFFER_SIZE; unsigned int properties_off; int ret; |
abdc7b8a2 tpm: Convert to u... |
174 |
ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); |
69cd8f068 tpm: add TPM2_Get... |
175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
if (ret) return ret; /* * In the response buffer, the properties are located after the: * tag (u16), response size (u32), response code (u32), * YES/NO flag (u8), TPM_CAP (u32) and TPMU_CAPABILITIES (u32). */ properties_off = sizeof(u16) + sizeof(u32) + sizeof(u32) + sizeof(u8) + sizeof(u32) + sizeof(u32); memcpy(buf, &response[properties_off], response_len - properties_off); return 0; } |
da9c3392e tpm: add dictiona... |
189 |
|
abdc7b8a2 tpm: Convert to u... |
190 |
u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz) |
da9c3392e tpm: add dictiona... |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(27 + pw_sz), /* Length */ tpm_u32(TPM2_CC_DAM_RESET), /* Command code */ /* HANDLE */ tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ /* AUTH_SESSION */ tpm_u32(9 + pw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* Session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(pw_sz), /* Size of <hmac/password> */ /* STRING(pw) <hmac/password> (if any) */ }; unsigned int offset = 27; int ret; /* * Fill the command structure starting from the first buffer: * - the password (if any) */ ret = pack_byte_string(command_v2, sizeof(command_v2), "s", offset, pw, pw_sz); offset += pw_sz; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
221 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
da9c3392e tpm: add dictiona... |
222 |
} |
abdc7b8a2 tpm: Convert to u... |
223 224 225 |
u32 tpm2_dam_parameters(struct udevice *dev, const char *pw, const ssize_t pw_sz, unsigned int max_tries, unsigned int recovery_time, |
da9c3392e tpm: add dictiona... |
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
unsigned int lockout_recovery) { u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(27 + pw_sz + 12), /* Length */ tpm_u32(TPM2_CC_DAM_PARAMETERS), /* Command code */ /* HANDLE */ tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ /* AUTH_SESSION */ tpm_u32(9 + pw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* Session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(pw_sz), /* Size of <hmac/password> */ /* STRING(pw) <hmac/password> (if any) */ /* LOCKOUT PARAMETERS */ /* tpm_u32(max_tries) Max tries (0, always lock) */ /* tpm_u32(recovery_time) Recovery time (0, no lock) */ /* tpm_u32(lockout_recovery) Lockout recovery */ }; unsigned int offset = 27; int ret; /* * Fill the command structure starting from the first buffer: * - the password (if any) * - max tries * - recovery time * - lockout recovery */ ret = pack_byte_string(command_v2, sizeof(command_v2), "sddd", offset, pw, pw_sz, offset + pw_sz, max_tries, offset + pw_sz + 4, recovery_time, offset + pw_sz + 8, lockout_recovery); offset += pw_sz + 12; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
268 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
da9c3392e tpm: add dictiona... |
269 |
} |
dc26e913a tpm: add TPM2_Hie... |
270 |
|
abdc7b8a2 tpm: Convert to u... |
271 272 273 |
int tpm2_change_auth(struct udevice *dev, u32 handle, const char *newpw, const ssize_t newpw_sz, const char *oldpw, const ssize_t oldpw_sz) |
dc26e913a tpm: add TPM2_Hie... |
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
{ unsigned int offset = 27; u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ /* HANDLE */ tpm_u32(handle), /* TPM resource handle */ /* AUTH_SESSION */ tpm_u32(9 + oldpw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* Session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(oldpw_sz) /* Size of <hmac/password> */ /* STRING(oldpw) <hmac/password> (if any) */ /* TPM2B_AUTH (TPM2B_DIGEST) */ /* tpm_u16(newpw_sz) Digest size, new pw length */ /* STRING(newpw) Digest buffer, new pw */ }; int ret; /* * Fill the command structure starting from the first buffer: * - the old password (if any) * - size of the new password * - new password */ ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", offset, oldpw, oldpw_sz, offset + oldpw_sz, newpw_sz, offset + oldpw_sz + 2, newpw, newpw_sz); offset += oldpw_sz + 2 + newpw_sz; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
312 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
dc26e913a tpm: add TPM2_Hie... |
313 |
} |
b9dd4fabb tpm: add PCR auth... |
314 |
|
abdc7b8a2 tpm: Convert to u... |
315 316 |
u32 tpm2_pcr_setauthpolicy(struct udevice *dev, const char *pw, const ssize_t pw_sz, u32 index, const char *key) |
b9dd4fabb tpm: add PCR auth... |
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */ tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */ /* HANDLE */ tpm_u32(TPM2_RH_PLATFORM), /* TPM resource handle */ /* AUTH_SESSION */ tpm_u32(9 + pw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(pw_sz) /* Size of <hmac/password> */ /* STRING(pw) <hmac/password> (if any) */ /* TPM2B_AUTH (TPM2B_DIGEST) */ /* tpm_u16(TPM2_DIGEST_LEN) Digest size length */ /* STRING(key) Digest buffer (PCR key) */ /* TPMI_ALG_HASH */ /* tpm_u16(TPM2_ALG_SHA256) Algorithm of the hash */ /* TPMI_DH_PCR */ /* tpm_u32(index), PCR Index */ }; unsigned int offset = 27; int ret; /* * Fill the command structure starting from the first buffer: * - the password (if any) * - the PCR key length * - the PCR key * - the hash algorithm * - the PCR index */ ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd", offset, pw, pw_sz, offset + pw_sz, TPM2_DIGEST_LEN, offset + pw_sz + 2, key, TPM2_DIGEST_LEN, offset + pw_sz + 2 + TPM2_DIGEST_LEN, TPM2_ALG_SHA256, offset + pw_sz + 4 + TPM2_DIGEST_LEN, index); offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
366 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
b9dd4fabb tpm: add PCR auth... |
367 |
} |
abdc7b8a2 tpm: Convert to u... |
368 369 370 |
u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw, const ssize_t pw_sz, u32 index, const char *key, const ssize_t key_sz) |
b9dd4fabb tpm: add PCR auth... |
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
{ u8 command_v2[COMMAND_BUFFER_SIZE] = { tpm_u16(TPM2_ST_SESSIONS), /* TAG */ tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */ tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */ /* HANDLE */ tpm_u32(index), /* Handle (PCR Index) */ /* AUTH_SESSION */ tpm_u32(9 + pw_sz), /* Authorization size */ tpm_u32(TPM2_RS_PW), /* session handle */ tpm_u16(0), /* Size of <nonce> */ /* <nonce> (if any) */ 0, /* Attributes: Cont/Excl/Rst */ tpm_u16(pw_sz), /* Size of <hmac/password> */ /* STRING(pw) <hmac/password> (if any) */ /* TPM2B_DIGEST */ /* tpm_u16(key_sz) Key length */ /* STRING(key) Key */ }; unsigned int offset = 27; int ret; /* * Fill the command structure starting from the first buffer: * - the password (if any) * - the number of digests, 1 in our case * - the algorithm, sha256 in our case * - the digest (64 bytes) */ ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", offset, pw, pw_sz, offset + pw_sz, key_sz, offset + pw_sz + 2, key, key_sz); offset += pw_sz + 2 + key_sz; if (ret) return TPM_LIB_ERROR; |
abdc7b8a2 tpm: Convert to u... |
410 |
return tpm_sendrecv_command(dev, command_v2, NULL, NULL); |
b9dd4fabb tpm: add PCR auth... |
411 |
} |