1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2014, 2015 Intel Corporation |
4 | * |
5 | * Authors: |
6 | * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> |
7 | * |
8 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
9 | * |
10 | * This file contains TPM2 protocol implementations of the commands |
11 | * used by the kernel internally. |
12 | */ |
13 | |
14 | #include "tpm.h" |
15 | #include <crypto/hash_info.h> |
16 | |
17 | static struct tpm2_hash tpm2_hash_map[] = { |
18 | {HASH_ALGO_SHA1, TPM_ALG_SHA1}, |
19 | {HASH_ALGO_SHA256, TPM_ALG_SHA256}, |
20 | {HASH_ALGO_SHA384, TPM_ALG_SHA384}, |
21 | {HASH_ALGO_SHA512, TPM_ALG_SHA512}, |
22 | {HASH_ALGO_SM3_256, TPM_ALG_SM3_256}, |
23 | }; |
24 | |
25 | int tpm2_get_timeouts(struct tpm_chip *chip) |
26 | { |
27 | /* Fixed timeouts for TPM2 */ |
28 | chip->timeout_a = msecs_to_jiffies(m: TPM2_TIMEOUT_A); |
29 | chip->timeout_b = msecs_to_jiffies(m: TPM2_TIMEOUT_B); |
30 | chip->timeout_c = msecs_to_jiffies(m: TPM2_TIMEOUT_C); |
31 | chip->timeout_d = msecs_to_jiffies(m: TPM2_TIMEOUT_D); |
32 | |
33 | /* PTP spec timeouts */ |
34 | chip->duration[TPM_SHORT] = msecs_to_jiffies(m: TPM2_DURATION_SHORT); |
35 | chip->duration[TPM_MEDIUM] = msecs_to_jiffies(m: TPM2_DURATION_MEDIUM); |
36 | chip->duration[TPM_LONG] = msecs_to_jiffies(m: TPM2_DURATION_LONG); |
37 | |
38 | /* Key creation commands long timeouts */ |
39 | chip->duration[TPM_LONG_LONG] = |
40 | msecs_to_jiffies(m: TPM2_DURATION_LONG_LONG); |
41 | |
42 | chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; |
43 | |
44 | return 0; |
45 | } |
46 | |
47 | /** |
48 | * tpm2_ordinal_duration_index() - returns an index to the chip duration table |
49 | * @ordinal: TPM command ordinal. |
50 | * |
51 | * The function returns an index to the chip duration table |
52 | * (enum tpm_duration), that describes the maximum amount of |
53 | * time the chip could take to return the result for a particular ordinal. |
54 | * |
55 | * The values of the MEDIUM, and LONG durations are taken |
56 | * from the PC Client Profile (PTP) specification (750, 2000 msec) |
57 | * |
58 | * LONG_LONG is for commands that generates keys which empirically takes |
59 | * a longer time on some systems. |
60 | * |
61 | * Return: |
62 | * * TPM_MEDIUM |
63 | * * TPM_LONG |
64 | * * TPM_LONG_LONG |
65 | * * TPM_UNDEFINED |
66 | */ |
67 | static u8 tpm2_ordinal_duration_index(u32 ordinal) |
68 | { |
69 | switch (ordinal) { |
70 | /* Startup */ |
71 | case TPM2_CC_STARTUP: /* 144 */ |
72 | return TPM_MEDIUM; |
73 | |
74 | case TPM2_CC_SELF_TEST: /* 143 */ |
75 | return TPM_LONG; |
76 | |
77 | case TPM2_CC_GET_RANDOM: /* 17B */ |
78 | return TPM_LONG; |
79 | |
80 | case TPM2_CC_SEQUENCE_UPDATE: /* 15C */ |
81 | return TPM_MEDIUM; |
82 | case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */ |
83 | return TPM_MEDIUM; |
84 | case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */ |
85 | return TPM_MEDIUM; |
86 | case TPM2_CC_HASH_SEQUENCE_START: /* 186 */ |
87 | return TPM_MEDIUM; |
88 | |
89 | case TPM2_CC_VERIFY_SIGNATURE: /* 177 */ |
90 | return TPM_LONG_LONG; |
91 | |
92 | case TPM2_CC_PCR_EXTEND: /* 182 */ |
93 | return TPM_MEDIUM; |
94 | |
95 | case TPM2_CC_HIERARCHY_CONTROL: /* 121 */ |
96 | return TPM_LONG; |
97 | case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */ |
98 | return TPM_LONG; |
99 | |
100 | case TPM2_CC_GET_CAPABILITY: /* 17A */ |
101 | return TPM_MEDIUM; |
102 | |
103 | case TPM2_CC_NV_READ: /* 14E */ |
104 | return TPM_LONG; |
105 | |
106 | case TPM2_CC_CREATE_PRIMARY: /* 131 */ |
107 | return TPM_LONG_LONG; |
108 | case TPM2_CC_CREATE: /* 153 */ |
109 | return TPM_LONG_LONG; |
110 | case TPM2_CC_CREATE_LOADED: /* 191 */ |
111 | return TPM_LONG_LONG; |
112 | |
113 | default: |
114 | return TPM_UNDEFINED; |
115 | } |
116 | } |
117 | |
118 | /** |
119 | * tpm2_calc_ordinal_duration() - calculate the maximum command duration |
120 | * @chip: TPM chip to use. |
121 | * @ordinal: TPM command ordinal. |
122 | * |
123 | * The function returns the maximum amount of time the chip could take |
124 | * to return the result for a particular ordinal in jiffies. |
125 | * |
126 | * Return: A maximal duration time for an ordinal in jiffies. |
127 | */ |
128 | unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) |
129 | { |
130 | unsigned int index; |
131 | |
132 | index = tpm2_ordinal_duration_index(ordinal); |
133 | |
134 | if (index != TPM_UNDEFINED) |
135 | return chip->duration[index]; |
136 | else |
137 | return msecs_to_jiffies(m: TPM2_DURATION_DEFAULT); |
138 | } |
139 | |
140 | |
141 | struct tpm2_pcr_read_out { |
142 | __be32 update_cnt; |
143 | __be32 pcr_selects_cnt; |
144 | __be16 hash_alg; |
145 | u8 pcr_select_size; |
146 | u8 pcr_select[TPM2_PCR_SELECT_MIN]; |
147 | __be32 digests_cnt; |
148 | __be16 digest_size; |
149 | u8 digest[]; |
150 | } __packed; |
151 | |
152 | /** |
153 | * tpm2_pcr_read() - read a PCR value |
154 | * @chip: TPM chip to use. |
155 | * @pcr_idx: index of the PCR to read. |
156 | * @digest: PCR bank and buffer current PCR value is written to. |
157 | * @digest_size_ptr: pointer to variable that stores the digest size. |
158 | * |
159 | * Return: Same as with tpm_transmit_cmd. |
160 | */ |
161 | int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, |
162 | struct tpm_digest *digest, u16 *digest_size_ptr) |
163 | { |
164 | int i; |
165 | int rc; |
166 | struct tpm_buf buf; |
167 | struct tpm2_pcr_read_out *out; |
168 | u8 pcr_select[TPM2_PCR_SELECT_MIN] = {0}; |
169 | u16 digest_size; |
170 | u16 expected_digest_size = 0; |
171 | |
172 | if (pcr_idx >= TPM2_PLATFORM_PCR) |
173 | return -EINVAL; |
174 | |
175 | if (!digest_size_ptr) { |
176 | for (i = 0; i < chip->nr_allocated_banks && |
177 | chip->allocated_banks[i].alg_id != digest->alg_id; i++) |
178 | ; |
179 | |
180 | if (i == chip->nr_allocated_banks) |
181 | return -EINVAL; |
182 | |
183 | expected_digest_size = chip->allocated_banks[i].digest_size; |
184 | } |
185 | |
186 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_PCR_READ); |
187 | if (rc) |
188 | return rc; |
189 | |
190 | pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); |
191 | |
192 | tpm_buf_append_u32(buf: &buf, value: 1); |
193 | tpm_buf_append_u16(buf: &buf, value: digest->alg_id); |
194 | tpm_buf_append_u8(buf: &buf, value: TPM2_PCR_SELECT_MIN); |
195 | tpm_buf_append(buf: &buf, new_data: (const unsigned char *)pcr_select, |
196 | new_len: sizeof(pcr_select)); |
197 | |
198 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, desc: "attempting to read a pcr value" ); |
199 | if (rc) |
200 | goto out; |
201 | |
202 | out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; |
203 | digest_size = be16_to_cpu(out->digest_size); |
204 | if (digest_size > sizeof(digest->digest) || |
205 | (!digest_size_ptr && digest_size != expected_digest_size)) { |
206 | rc = -EINVAL; |
207 | goto out; |
208 | } |
209 | |
210 | if (digest_size_ptr) |
211 | *digest_size_ptr = digest_size; |
212 | |
213 | memcpy(digest->digest, out->digest, digest_size); |
214 | out: |
215 | tpm_buf_destroy(buf: &buf); |
216 | return rc; |
217 | } |
218 | |
219 | struct tpm2_null_auth_area { |
220 | __be32 handle; |
221 | __be16 nonce_size; |
222 | u8 attributes; |
223 | __be16 auth_size; |
224 | } __packed; |
225 | |
226 | /** |
227 | * tpm2_pcr_extend() - extend a PCR value |
228 | * |
229 | * @chip: TPM chip to use. |
230 | * @pcr_idx: index of the PCR. |
231 | * @digests: list of pcr banks and corresponding digest values to extend. |
232 | * |
233 | * Return: Same as with tpm_transmit_cmd. |
234 | */ |
235 | int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, |
236 | struct tpm_digest *digests) |
237 | { |
238 | struct tpm_buf buf; |
239 | struct tpm2_null_auth_area auth_area; |
240 | int rc; |
241 | int i; |
242 | |
243 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_SESSIONS, ordinal: TPM2_CC_PCR_EXTEND); |
244 | if (rc) |
245 | return rc; |
246 | |
247 | tpm_buf_append_u32(buf: &buf, value: pcr_idx); |
248 | |
249 | auth_area.handle = cpu_to_be32(TPM2_RS_PW); |
250 | auth_area.nonce_size = 0; |
251 | auth_area.attributes = 0; |
252 | auth_area.auth_size = 0; |
253 | |
254 | tpm_buf_append_u32(buf: &buf, value: sizeof(struct tpm2_null_auth_area)); |
255 | tpm_buf_append(buf: &buf, new_data: (const unsigned char *)&auth_area, |
256 | new_len: sizeof(auth_area)); |
257 | tpm_buf_append_u32(buf: &buf, value: chip->nr_allocated_banks); |
258 | |
259 | for (i = 0; i < chip->nr_allocated_banks; i++) { |
260 | tpm_buf_append_u16(buf: &buf, value: digests[i].alg_id); |
261 | tpm_buf_append(buf: &buf, new_data: (const unsigned char *)&digests[i].digest, |
262 | new_len: chip->allocated_banks[i].digest_size); |
263 | } |
264 | |
265 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, desc: "attempting extend a PCR value" ); |
266 | |
267 | tpm_buf_destroy(buf: &buf); |
268 | |
269 | return rc; |
270 | } |
271 | |
272 | struct tpm2_get_random_out { |
273 | __be16 size; |
274 | u8 buffer[TPM_MAX_RNG_DATA]; |
275 | } __packed; |
276 | |
277 | /** |
278 | * tpm2_get_random() - get random bytes from the TPM RNG |
279 | * |
280 | * @chip: a &tpm_chip instance |
281 | * @dest: destination buffer |
282 | * @max: the max number of random bytes to pull |
283 | * |
284 | * Return: |
285 | * size of the buffer on success, |
286 | * -errno otherwise (positive TPM return codes are masked to -EIO) |
287 | */ |
288 | int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) |
289 | { |
290 | struct tpm2_get_random_out *out; |
291 | struct tpm_buf buf; |
292 | u32 recd; |
293 | u32 num_bytes = max; |
294 | int err; |
295 | int total = 0; |
296 | int retries = 5; |
297 | u8 *dest_ptr = dest; |
298 | |
299 | if (!num_bytes || max > TPM_MAX_RNG_DATA) |
300 | return -EINVAL; |
301 | |
302 | err = tpm_buf_init(buf: &buf, tag: 0, ordinal: 0); |
303 | if (err) |
304 | return err; |
305 | |
306 | do { |
307 | tpm_buf_reset(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_GET_RANDOM); |
308 | tpm_buf_append_u16(buf: &buf, value: num_bytes); |
309 | err = tpm_transmit_cmd(chip, buf: &buf, |
310 | offsetof(struct tpm2_get_random_out, |
311 | buffer), |
312 | desc: "attempting get random" ); |
313 | if (err) { |
314 | if (err > 0) |
315 | err = -EIO; |
316 | goto out; |
317 | } |
318 | |
319 | out = (struct tpm2_get_random_out *) |
320 | &buf.data[TPM_HEADER_SIZE]; |
321 | recd = min_t(u32, be16_to_cpu(out->size), num_bytes); |
322 | if (tpm_buf_length(buf: &buf) < |
323 | TPM_HEADER_SIZE + |
324 | offsetof(struct tpm2_get_random_out, buffer) + |
325 | recd) { |
326 | err = -EFAULT; |
327 | goto out; |
328 | } |
329 | memcpy(dest_ptr, out->buffer, recd); |
330 | |
331 | dest_ptr += recd; |
332 | total += recd; |
333 | num_bytes -= recd; |
334 | } while (retries-- && total < max); |
335 | |
336 | tpm_buf_destroy(buf: &buf); |
337 | return total ? total : -EIO; |
338 | out: |
339 | tpm_buf_destroy(buf: &buf); |
340 | return err; |
341 | } |
342 | |
343 | /** |
344 | * tpm2_flush_context() - execute a TPM2_FlushContext command |
345 | * @chip: TPM chip to use |
346 | * @handle: context handle |
347 | */ |
348 | void tpm2_flush_context(struct tpm_chip *chip, u32 handle) |
349 | { |
350 | struct tpm_buf buf; |
351 | int rc; |
352 | |
353 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_FLUSH_CONTEXT); |
354 | if (rc) { |
355 | dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n" , |
356 | handle); |
357 | return; |
358 | } |
359 | |
360 | tpm_buf_append_u32(buf: &buf, value: handle); |
361 | |
362 | tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, desc: "flushing context" ); |
363 | tpm_buf_destroy(buf: &buf); |
364 | } |
365 | EXPORT_SYMBOL_GPL(tpm2_flush_context); |
366 | |
367 | struct tpm2_get_cap_out { |
368 | u8 more_data; |
369 | __be32 subcap_id; |
370 | __be32 property_cnt; |
371 | __be32 property_id; |
372 | __be32 value; |
373 | } __packed; |
374 | |
375 | /** |
376 | * tpm2_get_tpm_pt() - get value of a TPM_CAP_TPM_PROPERTIES type property |
377 | * @chip: a &tpm_chip instance |
378 | * @property_id: property ID. |
379 | * @value: output variable. |
380 | * @desc: passed to tpm_transmit_cmd() |
381 | * |
382 | * Return: |
383 | * 0 on success, |
384 | * -errno or a TPM return code otherwise |
385 | */ |
386 | ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value, |
387 | const char *desc) |
388 | { |
389 | struct tpm2_get_cap_out *out; |
390 | struct tpm_buf buf; |
391 | int rc; |
392 | |
393 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_GET_CAPABILITY); |
394 | if (rc) |
395 | return rc; |
396 | tpm_buf_append_u32(buf: &buf, value: TPM2_CAP_TPM_PROPERTIES); |
397 | tpm_buf_append_u32(buf: &buf, value: property_id); |
398 | tpm_buf_append_u32(buf: &buf, value: 1); |
399 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, NULL); |
400 | if (!rc) { |
401 | out = (struct tpm2_get_cap_out *) |
402 | &buf.data[TPM_HEADER_SIZE]; |
403 | /* |
404 | * To prevent failing boot up of some systems, Infineon TPM2.0 |
405 | * returns SUCCESS on TPM2_Startup in field upgrade mode. Also |
406 | * the TPM2_Getcapability command returns a zero length list |
407 | * in field upgrade mode. |
408 | */ |
409 | if (be32_to_cpu(out->property_cnt) > 0) |
410 | *value = be32_to_cpu(out->value); |
411 | else |
412 | rc = -ENODATA; |
413 | } |
414 | tpm_buf_destroy(buf: &buf); |
415 | return rc; |
416 | } |
417 | EXPORT_SYMBOL_GPL(tpm2_get_tpm_pt); |
418 | |
419 | /** |
420 | * tpm2_shutdown() - send a TPM shutdown command |
421 | * |
422 | * Sends a TPM shutdown command. The shutdown command is used in call |
423 | * sites where the system is going down. If it fails, there is not much |
424 | * that can be done except print an error message. |
425 | * |
426 | * @chip: a &tpm_chip instance |
427 | * @shutdown_type: TPM_SU_CLEAR or TPM_SU_STATE. |
428 | */ |
429 | void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type) |
430 | { |
431 | struct tpm_buf buf; |
432 | int rc; |
433 | |
434 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_SHUTDOWN); |
435 | if (rc) |
436 | return; |
437 | tpm_buf_append_u16(buf: &buf, value: shutdown_type); |
438 | tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, desc: "stopping the TPM" ); |
439 | tpm_buf_destroy(buf: &buf); |
440 | } |
441 | |
442 | /** |
443 | * tpm2_do_selftest() - ensure that all self tests have passed |
444 | * |
445 | * @chip: TPM chip to use |
446 | * |
447 | * Return: Same as with tpm_transmit_cmd. |
448 | * |
449 | * The TPM can either run all self tests synchronously and then return |
450 | * RC_SUCCESS once all tests were successful. Or it can choose to run the tests |
451 | * asynchronously and return RC_TESTING immediately while the self tests still |
452 | * execute in the background. This function handles both cases and waits until |
453 | * all tests have completed. |
454 | */ |
455 | static int tpm2_do_selftest(struct tpm_chip *chip) |
456 | { |
457 | struct tpm_buf buf; |
458 | int full; |
459 | int rc; |
460 | |
461 | for (full = 0; full < 2; full++) { |
462 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_SELF_TEST); |
463 | if (rc) |
464 | return rc; |
465 | |
466 | tpm_buf_append_u8(buf: &buf, value: full); |
467 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, |
468 | desc: "attempting the self test" ); |
469 | tpm_buf_destroy(buf: &buf); |
470 | |
471 | if (rc == TPM2_RC_TESTING) |
472 | rc = TPM2_RC_SUCCESS; |
473 | if (rc == TPM2_RC_INITIALIZE || rc == TPM2_RC_SUCCESS) |
474 | return rc; |
475 | } |
476 | |
477 | return rc; |
478 | } |
479 | |
480 | /** |
481 | * tpm2_probe() - probe for the TPM 2.0 protocol |
482 | * @chip: a &tpm_chip instance |
483 | * |
484 | * Send an idempotent TPM 2.0 command and see whether there is TPM2 chip in the |
485 | * other end based on the response tag. The flag TPM_CHIP_FLAG_TPM2 is set by |
486 | * this function if this is the case. |
487 | * |
488 | * Return: |
489 | * 0 on success, |
490 | * -errno otherwise |
491 | */ |
492 | int tpm2_probe(struct tpm_chip *chip) |
493 | { |
494 | struct tpm_header *out; |
495 | struct tpm_buf buf; |
496 | int rc; |
497 | |
498 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_GET_CAPABILITY); |
499 | if (rc) |
500 | return rc; |
501 | tpm_buf_append_u32(buf: &buf, value: TPM2_CAP_TPM_PROPERTIES); |
502 | tpm_buf_append_u32(buf: &buf, value: TPM_PT_TOTAL_COMMANDS); |
503 | tpm_buf_append_u32(buf: &buf, value: 1); |
504 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, NULL); |
505 | /* We ignore TPM return codes on purpose. */ |
506 | if (rc >= 0) { |
507 | out = (struct tpm_header *)buf.data; |
508 | if (be16_to_cpu(out->tag) == TPM2_ST_NO_SESSIONS) |
509 | chip->flags |= TPM_CHIP_FLAG_TPM2; |
510 | } |
511 | tpm_buf_destroy(buf: &buf); |
512 | return 0; |
513 | } |
514 | EXPORT_SYMBOL_GPL(tpm2_probe); |
515 | |
516 | static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index) |
517 | { |
518 | struct tpm_bank_info *bank = chip->allocated_banks + bank_index; |
519 | struct tpm_digest digest = { .alg_id = bank->alg_id }; |
520 | int i; |
521 | |
522 | /* |
523 | * Avoid unnecessary PCR read operations to reduce overhead |
524 | * and obtain identifiers of the crypto subsystem. |
525 | */ |
526 | for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { |
527 | enum hash_algo crypto_algo = tpm2_hash_map[i].crypto_id; |
528 | |
529 | if (bank->alg_id != tpm2_hash_map[i].tpm_id) |
530 | continue; |
531 | |
532 | bank->digest_size = hash_digest_size[crypto_algo]; |
533 | bank->crypto_id = crypto_algo; |
534 | return 0; |
535 | } |
536 | |
537 | bank->crypto_id = HASH_ALGO__LAST; |
538 | |
539 | return tpm2_pcr_read(chip, pcr_idx: 0, digest: &digest, digest_size_ptr: &bank->digest_size); |
540 | } |
541 | |
542 | struct tpm2_pcr_selection { |
543 | __be16 hash_alg; |
544 | u8 size_of_select; |
545 | u8 pcr_select[3]; |
546 | } __packed; |
547 | |
548 | ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) |
549 | { |
550 | struct tpm2_pcr_selection pcr_selection; |
551 | struct tpm_buf buf; |
552 | void *marker; |
553 | void *end; |
554 | void *pcr_select_offset; |
555 | u32 sizeof_pcr_selection; |
556 | u32 nr_possible_banks; |
557 | u32 nr_alloc_banks = 0; |
558 | u16 hash_alg; |
559 | u32 rsp_len; |
560 | int rc; |
561 | int i = 0; |
562 | |
563 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_GET_CAPABILITY); |
564 | if (rc) |
565 | return rc; |
566 | |
567 | tpm_buf_append_u32(buf: &buf, value: TPM2_CAP_PCRS); |
568 | tpm_buf_append_u32(buf: &buf, value: 0); |
569 | tpm_buf_append_u32(buf: &buf, value: 1); |
570 | |
571 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 9, desc: "get tpm pcr allocation" ); |
572 | if (rc) |
573 | goto out; |
574 | |
575 | nr_possible_banks = be32_to_cpup( |
576 | p: (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); |
577 | |
578 | chip->allocated_banks = kcalloc(n: nr_possible_banks, |
579 | size: sizeof(*chip->allocated_banks), |
580 | GFP_KERNEL); |
581 | if (!chip->allocated_banks) { |
582 | rc = -ENOMEM; |
583 | goto out; |
584 | } |
585 | |
586 | marker = &buf.data[TPM_HEADER_SIZE + 9]; |
587 | |
588 | rsp_len = be32_to_cpup(p: (__be32 *)&buf.data[2]); |
589 | end = &buf.data[rsp_len]; |
590 | |
591 | for (i = 0; i < nr_possible_banks; i++) { |
592 | pcr_select_offset = marker + |
593 | offsetof(struct tpm2_pcr_selection, size_of_select); |
594 | if (pcr_select_offset >= end) { |
595 | rc = -EFAULT; |
596 | break; |
597 | } |
598 | |
599 | memcpy(&pcr_selection, marker, sizeof(pcr_selection)); |
600 | hash_alg = be16_to_cpu(pcr_selection.hash_alg); |
601 | |
602 | pcr_select_offset = memchr_inv(p: pcr_selection.pcr_select, c: 0, |
603 | size: pcr_selection.size_of_select); |
604 | if (pcr_select_offset) { |
605 | chip->allocated_banks[nr_alloc_banks].alg_id = hash_alg; |
606 | |
607 | rc = tpm2_init_bank_info(chip, bank_index: nr_alloc_banks); |
608 | if (rc < 0) |
609 | break; |
610 | |
611 | nr_alloc_banks++; |
612 | } |
613 | |
614 | sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) + |
615 | sizeof(pcr_selection.size_of_select) + |
616 | pcr_selection.size_of_select; |
617 | marker = marker + sizeof_pcr_selection; |
618 | } |
619 | |
620 | chip->nr_allocated_banks = nr_alloc_banks; |
621 | out: |
622 | tpm_buf_destroy(buf: &buf); |
623 | |
624 | return rc; |
625 | } |
626 | |
627 | int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip) |
628 | { |
629 | struct tpm_buf buf; |
630 | u32 nr_commands; |
631 | __be32 *attrs; |
632 | u32 cc; |
633 | int i; |
634 | int rc; |
635 | |
636 | rc = tpm2_get_tpm_pt(chip, TPM_PT_TOTAL_COMMANDS, &nr_commands, NULL); |
637 | if (rc) |
638 | goto out; |
639 | |
640 | if (nr_commands > 0xFFFFF) { |
641 | rc = -EFAULT; |
642 | goto out; |
643 | } |
644 | |
645 | chip->cc_attrs_tbl = devm_kcalloc(dev: &chip->dev, n: 4, size: nr_commands, |
646 | GFP_KERNEL); |
647 | if (!chip->cc_attrs_tbl) { |
648 | rc = -ENOMEM; |
649 | goto out; |
650 | } |
651 | |
652 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_GET_CAPABILITY); |
653 | if (rc) |
654 | goto out; |
655 | |
656 | tpm_buf_append_u32(buf: &buf, value: TPM2_CAP_COMMANDS); |
657 | tpm_buf_append_u32(buf: &buf, value: TPM2_CC_FIRST); |
658 | tpm_buf_append_u32(buf: &buf, value: nr_commands); |
659 | |
660 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 9 + 4 * nr_commands, NULL); |
661 | if (rc) { |
662 | tpm_buf_destroy(buf: &buf); |
663 | goto out; |
664 | } |
665 | |
666 | if (nr_commands != |
667 | be32_to_cpup(p: (__be32 *)&buf.data[TPM_HEADER_SIZE + 5])) { |
668 | rc = -EFAULT; |
669 | tpm_buf_destroy(buf: &buf); |
670 | goto out; |
671 | } |
672 | |
673 | chip->nr_commands = nr_commands; |
674 | |
675 | attrs = (__be32 *)&buf.data[TPM_HEADER_SIZE + 9]; |
676 | for (i = 0; i < nr_commands; i++, attrs++) { |
677 | chip->cc_attrs_tbl[i] = be32_to_cpup(p: attrs); |
678 | cc = chip->cc_attrs_tbl[i] & 0xFFFF; |
679 | |
680 | if (cc == TPM2_CC_CONTEXT_SAVE || cc == TPM2_CC_FLUSH_CONTEXT) { |
681 | chip->cc_attrs_tbl[i] &= |
682 | ~(GENMASK(2, 0) << TPM2_CC_ATTR_CHANDLES); |
683 | chip->cc_attrs_tbl[i] |= 1 << TPM2_CC_ATTR_CHANDLES; |
684 | } |
685 | } |
686 | |
687 | tpm_buf_destroy(buf: &buf); |
688 | |
689 | out: |
690 | if (rc > 0) |
691 | rc = -ENODEV; |
692 | return rc; |
693 | } |
694 | EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl); |
695 | |
696 | /** |
697 | * tpm2_startup - turn on the TPM |
698 | * @chip: TPM chip to use |
699 | * |
700 | * Normally the firmware should start the TPM. This function is provided as a |
701 | * workaround if this does not happen. A legal case for this could be for |
702 | * example when a TPM emulator is used. |
703 | * |
704 | * Return: same as tpm_transmit_cmd() |
705 | */ |
706 | |
707 | static int tpm2_startup(struct tpm_chip *chip) |
708 | { |
709 | struct tpm_buf buf; |
710 | int rc; |
711 | |
712 | dev_info(&chip->dev, "starting up the TPM manually\n" ); |
713 | |
714 | rc = tpm_buf_init(buf: &buf, tag: TPM2_ST_NO_SESSIONS, ordinal: TPM2_CC_STARTUP); |
715 | if (rc < 0) |
716 | return rc; |
717 | |
718 | tpm_buf_append_u16(buf: &buf, value: TPM2_SU_CLEAR); |
719 | rc = tpm_transmit_cmd(chip, buf: &buf, min_rsp_body_length: 0, desc: "attempting to start the TPM" ); |
720 | tpm_buf_destroy(buf: &buf); |
721 | |
722 | return rc; |
723 | } |
724 | |
725 | /** |
726 | * tpm2_auto_startup - Perform the standard automatic TPM initialization |
727 | * sequence |
728 | * @chip: TPM chip to use |
729 | * |
730 | * Returns 0 on success, < 0 in case of fatal error. |
731 | */ |
732 | int tpm2_auto_startup(struct tpm_chip *chip) |
733 | { |
734 | int rc; |
735 | |
736 | rc = tpm2_get_timeouts(chip); |
737 | if (rc) |
738 | goto out; |
739 | |
740 | rc = tpm2_do_selftest(chip); |
741 | if (rc && rc != TPM2_RC_INITIALIZE) |
742 | goto out; |
743 | |
744 | if (rc == TPM2_RC_INITIALIZE) { |
745 | rc = tpm2_startup(chip); |
746 | if (rc) |
747 | goto out; |
748 | |
749 | rc = tpm2_do_selftest(chip); |
750 | if (rc) |
751 | goto out; |
752 | } |
753 | |
754 | rc = tpm2_get_cc_attrs_tbl(chip); |
755 | if (rc == TPM2_RC_FAILURE || (rc < 0 && rc != -ENOMEM)) { |
756 | dev_info(&chip->dev, |
757 | "TPM in field failure mode, requires firmware upgrade\n" ); |
758 | chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE; |
759 | rc = 0; |
760 | } |
761 | |
762 | out: |
763 | /* |
764 | * Infineon TPM in field upgrade mode will return no data for the number |
765 | * of supported commands. |
766 | */ |
767 | if (rc == TPM2_RC_UPGRADE || rc == -ENODATA) { |
768 | dev_info(&chip->dev, "TPM in field upgrade mode, requires firmware upgrade\n" ); |
769 | chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE; |
770 | rc = 0; |
771 | } |
772 | |
773 | if (rc > 0) |
774 | rc = -ENODEV; |
775 | return rc; |
776 | } |
777 | |
778 | int tpm2_find_cc(struct tpm_chip *chip, u32 cc) |
779 | { |
780 | u32 cc_mask; |
781 | int i; |
782 | |
783 | cc_mask = 1 << TPM2_CC_ATTR_VENDOR | GENMASK(15, 0); |
784 | for (i = 0; i < chip->nr_commands; i++) |
785 | if (cc == (chip->cc_attrs_tbl[i] & cc_mask)) |
786 | return i; |
787 | |
788 | return -1; |
789 | } |
790 | |