0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "tpm.h"
0015 #include <crypto/hash_info.h>
0016
0017 static struct tpm2_hash tpm2_hash_map[] = {
0018 {HASH_ALGO_SHA1, TPM_ALG_SHA1},
0019 {HASH_ALGO_SHA256, TPM_ALG_SHA256},
0020 {HASH_ALGO_SHA384, TPM_ALG_SHA384},
0021 {HASH_ALGO_SHA512, TPM_ALG_SHA512},
0022 {HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
0023 };
0024
0025 int tpm2_get_timeouts(struct tpm_chip *chip)
0026 {
0027
0028 chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
0029 chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
0030 chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
0031 chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
0032
0033
0034 chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
0035 chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
0036 chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
0037
0038
0039 chip->duration[TPM_LONG_LONG] =
0040 msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
0041
0042 chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
0043
0044 return 0;
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 static u8 tpm2_ordinal_duration_index(u32 ordinal)
0068 {
0069 switch (ordinal) {
0070
0071 case TPM2_CC_STARTUP:
0072 return TPM_MEDIUM;
0073
0074 case TPM2_CC_SELF_TEST:
0075 return TPM_LONG;
0076
0077 case TPM2_CC_GET_RANDOM:
0078 return TPM_LONG;
0079
0080 case TPM2_CC_SEQUENCE_UPDATE:
0081 return TPM_MEDIUM;
0082 case TPM2_CC_SEQUENCE_COMPLETE:
0083 return TPM_MEDIUM;
0084 case TPM2_CC_EVENT_SEQUENCE_COMPLETE:
0085 return TPM_MEDIUM;
0086 case TPM2_CC_HASH_SEQUENCE_START:
0087 return TPM_MEDIUM;
0088
0089 case TPM2_CC_VERIFY_SIGNATURE:
0090 return TPM_LONG_LONG;
0091
0092 case TPM2_CC_PCR_EXTEND:
0093 return TPM_MEDIUM;
0094
0095 case TPM2_CC_HIERARCHY_CONTROL:
0096 return TPM_LONG;
0097 case TPM2_CC_HIERARCHY_CHANGE_AUTH:
0098 return TPM_LONG;
0099
0100 case TPM2_CC_GET_CAPABILITY:
0101 return TPM_MEDIUM;
0102
0103 case TPM2_CC_NV_READ:
0104 return TPM_LONG;
0105
0106 case TPM2_CC_CREATE_PRIMARY:
0107 return TPM_LONG_LONG;
0108 case TPM2_CC_CREATE:
0109 return TPM_LONG_LONG;
0110 case TPM2_CC_CREATE_LOADED:
0111 return TPM_LONG_LONG;
0112
0113 default:
0114 return TPM_UNDEFINED;
0115 }
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
0129 {
0130 unsigned int index;
0131
0132 index = tpm2_ordinal_duration_index(ordinal);
0133
0134 if (index != TPM_UNDEFINED)
0135 return chip->duration[index];
0136 else
0137 return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
0138 }
0139
0140
0141 struct tpm2_pcr_read_out {
0142 __be32 update_cnt;
0143 __be32 pcr_selects_cnt;
0144 __be16 hash_alg;
0145 u8 pcr_select_size;
0146 u8 pcr_select[TPM2_PCR_SELECT_MIN];
0147 __be32 digests_cnt;
0148 __be16 digest_size;
0149 u8 digest[];
0150 } __packed;
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
0162 struct tpm_digest *digest, u16 *digest_size_ptr)
0163 {
0164 int i;
0165 int rc;
0166 struct tpm_buf buf;
0167 struct tpm2_pcr_read_out *out;
0168 u8 pcr_select[TPM2_PCR_SELECT_MIN] = {0};
0169 u16 digest_size;
0170 u16 expected_digest_size = 0;
0171
0172 if (pcr_idx >= TPM2_PLATFORM_PCR)
0173 return -EINVAL;
0174
0175 if (!digest_size_ptr) {
0176 for (i = 0; i < chip->nr_allocated_banks &&
0177 chip->allocated_banks[i].alg_id != digest->alg_id; i++)
0178 ;
0179
0180 if (i == chip->nr_allocated_banks)
0181 return -EINVAL;
0182
0183 expected_digest_size = chip->allocated_banks[i].digest_size;
0184 }
0185
0186 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ);
0187 if (rc)
0188 return rc;
0189
0190 pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
0191
0192 tpm_buf_append_u32(&buf, 1);
0193 tpm_buf_append_u16(&buf, digest->alg_id);
0194 tpm_buf_append_u8(&buf, TPM2_PCR_SELECT_MIN);
0195 tpm_buf_append(&buf, (const unsigned char *)pcr_select,
0196 sizeof(pcr_select));
0197
0198 rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to read a pcr value");
0199 if (rc)
0200 goto out;
0201
0202 out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE];
0203 digest_size = be16_to_cpu(out->digest_size);
0204 if (digest_size > sizeof(digest->digest) ||
0205 (!digest_size_ptr && digest_size != expected_digest_size)) {
0206 rc = -EINVAL;
0207 goto out;
0208 }
0209
0210 if (digest_size_ptr)
0211 *digest_size_ptr = digest_size;
0212
0213 memcpy(digest->digest, out->digest, digest_size);
0214 out:
0215 tpm_buf_destroy(&buf);
0216 return rc;
0217 }
0218
0219 struct tpm2_null_auth_area {
0220 __be32 handle;
0221 __be16 nonce_size;
0222 u8 attributes;
0223 __be16 auth_size;
0224 } __packed;
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
0236 struct tpm_digest *digests)
0237 {
0238 struct tpm_buf buf;
0239 struct tpm2_null_auth_area auth_area;
0240 int rc;
0241 int i;
0242
0243 rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
0244 if (rc)
0245 return rc;
0246
0247 tpm_buf_append_u32(&buf, pcr_idx);
0248
0249 auth_area.handle = cpu_to_be32(TPM2_RS_PW);
0250 auth_area.nonce_size = 0;
0251 auth_area.attributes = 0;
0252 auth_area.auth_size = 0;
0253
0254 tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area));
0255 tpm_buf_append(&buf, (const unsigned char *)&auth_area,
0256 sizeof(auth_area));
0257 tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
0258
0259 for (i = 0; i < chip->nr_allocated_banks; i++) {
0260 tpm_buf_append_u16(&buf, digests[i].alg_id);
0261 tpm_buf_append(&buf, (const unsigned char *)&digests[i].digest,
0262 chip->allocated_banks[i].digest_size);
0263 }
0264
0265 rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value");
0266
0267 tpm_buf_destroy(&buf);
0268
0269 return rc;
0270 }
0271
0272 struct tpm2_get_random_out {
0273 __be16 size;
0274 u8 buffer[TPM_MAX_RNG_DATA];
0275 } __packed;
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
0289 {
0290 struct tpm2_get_random_out *out;
0291 struct tpm_buf buf;
0292 u32 recd;
0293 u32 num_bytes = max;
0294 int err;
0295 int total = 0;
0296 int retries = 5;
0297 u8 *dest_ptr = dest;
0298
0299 if (!num_bytes || max > TPM_MAX_RNG_DATA)
0300 return -EINVAL;
0301
0302 err = tpm_buf_init(&buf, 0, 0);
0303 if (err)
0304 return err;
0305
0306 do {
0307 tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM);
0308 tpm_buf_append_u16(&buf, num_bytes);
0309 err = tpm_transmit_cmd(chip, &buf,
0310 offsetof(struct tpm2_get_random_out,
0311 buffer),
0312 "attempting get random");
0313 if (err) {
0314 if (err > 0)
0315 err = -EIO;
0316 goto out;
0317 }
0318
0319 out = (struct tpm2_get_random_out *)
0320 &buf.data[TPM_HEADER_SIZE];
0321 recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
0322 if (tpm_buf_length(&buf) <
0323 TPM_HEADER_SIZE +
0324 offsetof(struct tpm2_get_random_out, buffer) +
0325 recd) {
0326 err = -EFAULT;
0327 goto out;
0328 }
0329 memcpy(dest_ptr, out->buffer, recd);
0330
0331 dest_ptr += recd;
0332 total += recd;
0333 num_bytes -= recd;
0334 } while (retries-- && total < max);
0335
0336 tpm_buf_destroy(&buf);
0337 return total ? total : -EIO;
0338 out:
0339 tpm_buf_destroy(&buf);
0340 return err;
0341 }
0342
0343
0344
0345
0346
0347
0348 void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
0349 {
0350 struct tpm_buf buf;
0351 int rc;
0352
0353 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
0354 if (rc) {
0355 dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
0356 handle);
0357 return;
0358 }
0359
0360 tpm_buf_append_u32(&buf, handle);
0361
0362 tpm_transmit_cmd(chip, &buf, 0, "flushing context");
0363 tpm_buf_destroy(&buf);
0364 }
0365 EXPORT_SYMBOL_GPL(tpm2_flush_context);
0366
0367 struct tpm2_get_cap_out {
0368 u8 more_data;
0369 __be32 subcap_id;
0370 __be32 property_cnt;
0371 __be32 property_id;
0372 __be32 value;
0373 } __packed;
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value,
0387 const char *desc)
0388 {
0389 struct tpm2_get_cap_out *out;
0390 struct tpm_buf buf;
0391 int rc;
0392
0393 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
0394 if (rc)
0395 return rc;
0396 tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
0397 tpm_buf_append_u32(&buf, property_id);
0398 tpm_buf_append_u32(&buf, 1);
0399 rc = tpm_transmit_cmd(chip, &buf, 0, NULL);
0400 if (!rc) {
0401 out = (struct tpm2_get_cap_out *)
0402 &buf.data[TPM_HEADER_SIZE];
0403
0404
0405
0406
0407
0408
0409 if (be32_to_cpu(out->property_cnt) > 0)
0410 *value = be32_to_cpu(out->value);
0411 else
0412 rc = -ENODATA;
0413 }
0414 tpm_buf_destroy(&buf);
0415 return rc;
0416 }
0417 EXPORT_SYMBOL_GPL(tpm2_get_tpm_pt);
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
0430 {
0431 struct tpm_buf buf;
0432 int rc;
0433
0434 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SHUTDOWN);
0435 if (rc)
0436 return;
0437 tpm_buf_append_u16(&buf, shutdown_type);
0438 tpm_transmit_cmd(chip, &buf, 0, "stopping the TPM");
0439 tpm_buf_destroy(&buf);
0440 }
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 static int tpm2_do_selftest(struct tpm_chip *chip)
0456 {
0457 struct tpm_buf buf;
0458 int full;
0459 int rc;
0460
0461 for (full = 0; full < 2; full++) {
0462 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST);
0463 if (rc)
0464 return rc;
0465
0466 tpm_buf_append_u8(&buf, full);
0467 rc = tpm_transmit_cmd(chip, &buf, 0,
0468 "attempting the self test");
0469 tpm_buf_destroy(&buf);
0470
0471 if (rc == TPM2_RC_TESTING)
0472 rc = TPM2_RC_SUCCESS;
0473 if (rc == TPM2_RC_INITIALIZE || rc == TPM2_RC_SUCCESS)
0474 return rc;
0475 }
0476
0477 return rc;
0478 }
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492 int tpm2_probe(struct tpm_chip *chip)
0493 {
0494 struct tpm_header *out;
0495 struct tpm_buf buf;
0496 int rc;
0497
0498 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
0499 if (rc)
0500 return rc;
0501 tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
0502 tpm_buf_append_u32(&buf, TPM_PT_TOTAL_COMMANDS);
0503 tpm_buf_append_u32(&buf, 1);
0504 rc = tpm_transmit_cmd(chip, &buf, 0, NULL);
0505
0506 if (rc >= 0) {
0507 out = (struct tpm_header *)buf.data;
0508 if (be16_to_cpu(out->tag) == TPM2_ST_NO_SESSIONS)
0509 chip->flags |= TPM_CHIP_FLAG_TPM2;
0510 }
0511 tpm_buf_destroy(&buf);
0512 return 0;
0513 }
0514 EXPORT_SYMBOL_GPL(tpm2_probe);
0515
0516 static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index)
0517 {
0518 struct tpm_bank_info *bank = chip->allocated_banks + bank_index;
0519 struct tpm_digest digest = { .alg_id = bank->alg_id };
0520 int i;
0521
0522
0523
0524
0525
0526 for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
0527 enum hash_algo crypto_algo = tpm2_hash_map[i].crypto_id;
0528
0529 if (bank->alg_id != tpm2_hash_map[i].tpm_id)
0530 continue;
0531
0532 bank->digest_size = hash_digest_size[crypto_algo];
0533 bank->crypto_id = crypto_algo;
0534 return 0;
0535 }
0536
0537 bank->crypto_id = HASH_ALGO__LAST;
0538
0539 return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size);
0540 }
0541
0542 struct tpm2_pcr_selection {
0543 __be16 hash_alg;
0544 u8 size_of_select;
0545 u8 pcr_select[3];
0546 } __packed;
0547
0548 ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
0549 {
0550 struct tpm2_pcr_selection pcr_selection;
0551 struct tpm_buf buf;
0552 void *marker;
0553 void *end;
0554 void *pcr_select_offset;
0555 u32 sizeof_pcr_selection;
0556 u32 nr_possible_banks;
0557 u32 nr_alloc_banks = 0;
0558 u16 hash_alg;
0559 u32 rsp_len;
0560 int rc;
0561 int i = 0;
0562
0563 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
0564 if (rc)
0565 return rc;
0566
0567 tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
0568 tpm_buf_append_u32(&buf, 0);
0569 tpm_buf_append_u32(&buf, 1);
0570
0571 rc = tpm_transmit_cmd(chip, &buf, 9, "get tpm pcr allocation");
0572 if (rc)
0573 goto out;
0574
0575 nr_possible_banks = be32_to_cpup(
0576 (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]);
0577
0578 chip->allocated_banks = kcalloc(nr_possible_banks,
0579 sizeof(*chip->allocated_banks),
0580 GFP_KERNEL);
0581 if (!chip->allocated_banks) {
0582 rc = -ENOMEM;
0583 goto out;
0584 }
0585
0586 marker = &buf.data[TPM_HEADER_SIZE + 9];
0587
0588 rsp_len = be32_to_cpup((__be32 *)&buf.data[2]);
0589 end = &buf.data[rsp_len];
0590
0591 for (i = 0; i < nr_possible_banks; i++) {
0592 pcr_select_offset = marker +
0593 offsetof(struct tpm2_pcr_selection, size_of_select);
0594 if (pcr_select_offset >= end) {
0595 rc = -EFAULT;
0596 break;
0597 }
0598
0599 memcpy(&pcr_selection, marker, sizeof(pcr_selection));
0600 hash_alg = be16_to_cpu(pcr_selection.hash_alg);
0601
0602 pcr_select_offset = memchr_inv(pcr_selection.pcr_select, 0,
0603 pcr_selection.size_of_select);
0604 if (pcr_select_offset) {
0605 chip->allocated_banks[nr_alloc_banks].alg_id = hash_alg;
0606
0607 rc = tpm2_init_bank_info(chip, nr_alloc_banks);
0608 if (rc < 0)
0609 break;
0610
0611 nr_alloc_banks++;
0612 }
0613
0614 sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) +
0615 sizeof(pcr_selection.size_of_select) +
0616 pcr_selection.size_of_select;
0617 marker = marker + sizeof_pcr_selection;
0618 }
0619
0620 chip->nr_allocated_banks = nr_alloc_banks;
0621 out:
0622 tpm_buf_destroy(&buf);
0623
0624 return rc;
0625 }
0626
0627 int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
0628 {
0629 struct tpm_buf buf;
0630 u32 nr_commands;
0631 __be32 *attrs;
0632 u32 cc;
0633 int i;
0634 int rc;
0635
0636 rc = tpm2_get_tpm_pt(chip, TPM_PT_TOTAL_COMMANDS, &nr_commands, NULL);
0637 if (rc)
0638 goto out;
0639
0640 if (nr_commands > 0xFFFFF) {
0641 rc = -EFAULT;
0642 goto out;
0643 }
0644
0645 chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands,
0646 GFP_KERNEL);
0647 if (!chip->cc_attrs_tbl) {
0648 rc = -ENOMEM;
0649 goto out;
0650 }
0651
0652 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
0653 if (rc)
0654 goto out;
0655
0656 tpm_buf_append_u32(&buf, TPM2_CAP_COMMANDS);
0657 tpm_buf_append_u32(&buf, TPM2_CC_FIRST);
0658 tpm_buf_append_u32(&buf, nr_commands);
0659
0660 rc = tpm_transmit_cmd(chip, &buf, 9 + 4 * nr_commands, NULL);
0661 if (rc) {
0662 tpm_buf_destroy(&buf);
0663 goto out;
0664 }
0665
0666 if (nr_commands !=
0667 be32_to_cpup((__be32 *)&buf.data[TPM_HEADER_SIZE + 5])) {
0668 rc = -EFAULT;
0669 tpm_buf_destroy(&buf);
0670 goto out;
0671 }
0672
0673 chip->nr_commands = nr_commands;
0674
0675 attrs = (__be32 *)&buf.data[TPM_HEADER_SIZE + 9];
0676 for (i = 0; i < nr_commands; i++, attrs++) {
0677 chip->cc_attrs_tbl[i] = be32_to_cpup(attrs);
0678 cc = chip->cc_attrs_tbl[i] & 0xFFFF;
0679
0680 if (cc == TPM2_CC_CONTEXT_SAVE || cc == TPM2_CC_FLUSH_CONTEXT) {
0681 chip->cc_attrs_tbl[i] &=
0682 ~(GENMASK(2, 0) << TPM2_CC_ATTR_CHANDLES);
0683 chip->cc_attrs_tbl[i] |= 1 << TPM2_CC_ATTR_CHANDLES;
0684 }
0685 }
0686
0687 tpm_buf_destroy(&buf);
0688
0689 out:
0690 if (rc > 0)
0691 rc = -ENODEV;
0692 return rc;
0693 }
0694 EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl);
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707 static int tpm2_startup(struct tpm_chip *chip)
0708 {
0709 struct tpm_buf buf;
0710 int rc;
0711
0712 dev_info(&chip->dev, "starting up the TPM manually\n");
0713
0714 rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
0715 if (rc < 0)
0716 return rc;
0717
0718 tpm_buf_append_u16(&buf, TPM2_SU_CLEAR);
0719 rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to start the TPM");
0720 tpm_buf_destroy(&buf);
0721
0722 return rc;
0723 }
0724
0725
0726
0727
0728
0729
0730
0731
0732 int tpm2_auto_startup(struct tpm_chip *chip)
0733 {
0734 int rc;
0735
0736 rc = tpm2_get_timeouts(chip);
0737 if (rc)
0738 goto out;
0739
0740 rc = tpm2_do_selftest(chip);
0741 if (rc && rc != TPM2_RC_INITIALIZE)
0742 goto out;
0743
0744 if (rc == TPM2_RC_INITIALIZE) {
0745 rc = tpm2_startup(chip);
0746 if (rc)
0747 goto out;
0748
0749 rc = tpm2_do_selftest(chip);
0750 if (rc)
0751 goto out;
0752 }
0753
0754 rc = tpm2_get_cc_attrs_tbl(chip);
0755 if (rc == TPM2_RC_FAILURE || (rc < 0 && rc != -ENOMEM)) {
0756 dev_info(&chip->dev,
0757 "TPM in field failure mode, requires firmware upgrade\n");
0758 chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE;
0759 rc = 0;
0760 }
0761
0762 out:
0763
0764
0765
0766
0767 if (rc == TPM2_RC_UPGRADE || rc == -ENODATA) {
0768 dev_info(&chip->dev, "TPM in field upgrade mode, requires firmware upgrade\n");
0769 chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE;
0770 rc = 0;
0771 }
0772
0773 if (rc > 0)
0774 rc = -ENODEV;
0775 return rc;
0776 }
0777
0778 int tpm2_find_cc(struct tpm_chip *chip, u32 cc)
0779 {
0780 int i;
0781
0782 for (i = 0; i < chip->nr_commands; i++)
0783 if (cc == (chip->cc_attrs_tbl[i] & GENMASK(15, 0)))
0784 return i;
0785
0786 return -1;
0787 }