diff options
-rw-r--r-- | drivers/char/tpm/tpm-chip.c | 1 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 18 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm1-cmd.c | 10 | ||||
-rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 31 |
5 files changed, 44 insertions, 19 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 4eb48cf6a03a..8804c9e916fd 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
@@ -266,6 +266,7 @@ static void tpm_dev_release(struct device *dev) | |||
266 | kfree(chip->log.bios_event_log); | 266 | kfree(chip->log.bios_event_log); |
267 | kfree(chip->work_space.context_buf); | 267 | kfree(chip->work_space.context_buf); |
268 | kfree(chip->work_space.session_buf); | 268 | kfree(chip->work_space.session_buf); |
269 | kfree(chip->allocated_banks); | ||
269 | kfree(chip); | 270 | kfree(chip); |
270 | } | 271 | } |
271 | 272 | ||
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 498809bf1bf0..2b31eff06b0e 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -318,8 +318,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); | |||
318 | int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) | 318 | int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) |
319 | { | 319 | { |
320 | int rc; | 320 | int rc; |
321 | struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)]; | 321 | struct tpm2_digest *digest_list; |
322 | u32 count = 0; | ||
323 | int i; | 322 | int i; |
324 | 323 | ||
325 | chip = tpm_find_get_ops(chip); | 324 | chip = tpm_find_get_ops(chip); |
@@ -327,16 +326,19 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) | |||
327 | return -ENODEV; | 326 | return -ENODEV; |
328 | 327 | ||
329 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | 328 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
330 | memset(digest_list, 0, sizeof(digest_list)); | 329 | digest_list = kcalloc(chip->nr_allocated_banks, |
330 | sizeof(*digest_list), GFP_KERNEL); | ||
331 | if (!digest_list) | ||
332 | return -ENOMEM; | ||
331 | 333 | ||
332 | for (i = 0; i < ARRAY_SIZE(chip->active_banks) && | 334 | for (i = 0; i < chip->nr_allocated_banks; i++) { |
333 | chip->active_banks[i] != TPM2_ALG_ERROR; i++) { | 335 | digest_list[i].alg_id = chip->allocated_banks[i]; |
334 | digest_list[i].alg_id = chip->active_banks[i]; | ||
335 | memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); | 336 | memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); |
336 | count++; | ||
337 | } | 337 | } |
338 | 338 | ||
339 | rc = tpm2_pcr_extend(chip, pcr_idx, count, digest_list); | 339 | rc = tpm2_pcr_extend(chip, pcr_idx, chip->nr_allocated_banks, |
340 | digest_list); | ||
341 | kfree(digest_list); | ||
340 | tpm_put_ops(chip); | 342 | tpm_put_ops(chip); |
341 | return rc; | 343 | return rc; |
342 | } | 344 | } |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 183e2b93e0fe..cd330ace6248 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -257,7 +257,8 @@ struct tpm_chip { | |||
257 | const struct attribute_group *groups[3]; | 257 | const struct attribute_group *groups[3]; |
258 | unsigned int groups_cnt; | 258 | unsigned int groups_cnt; |
259 | 259 | ||
260 | u16 active_banks[7]; | 260 | u32 nr_allocated_banks; |
261 | u16 *allocated_banks; | ||
261 | #ifdef CONFIG_ACPI | 262 | #ifdef CONFIG_ACPI |
262 | acpi_handle acpi_dev_handle; | 263 | acpi_handle acpi_dev_handle; |
263 | char ppi_version[TPM_PPI_VERSION_LEN + 1]; | 264 | char ppi_version[TPM_PPI_VERSION_LEN + 1]; |
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index ec5f3693c096..e7d3228a0f37 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c | |||
@@ -696,6 +696,16 @@ int tpm1_auto_startup(struct tpm_chip *chip) | |||
696 | goto out; | 696 | goto out; |
697 | } | 697 | } |
698 | 698 | ||
699 | chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks), | ||
700 | GFP_KERNEL); | ||
701 | if (!chip->allocated_banks) { | ||
702 | rc = -ENOMEM; | ||
703 | goto out; | ||
704 | } | ||
705 | |||
706 | chip->allocated_banks[0] = TPM2_ALG_SHA1; | ||
707 | chip->nr_allocated_banks = 1; | ||
708 | |||
699 | return rc; | 709 | return rc; |
700 | out: | 710 | out: |
701 | if (rc > 0) | 711 | if (rc > 0) |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 971d46efaca5..bd20b9a61fc0 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -234,7 +234,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, | |||
234 | int i; | 234 | int i; |
235 | int j; | 235 | int j; |
236 | 236 | ||
237 | if (count > ARRAY_SIZE(chip->active_banks)) | 237 | if (count > chip->nr_allocated_banks) |
238 | return -EINVAL; | 238 | return -EINVAL; |
239 | 239 | ||
240 | rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); | 240 | rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); |
@@ -808,8 +808,10 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | |||
808 | void *marker; | 808 | void *marker; |
809 | void *end; | 809 | void *end; |
810 | void *pcr_select_offset; | 810 | void *pcr_select_offset; |
811 | unsigned int count; | ||
812 | u32 sizeof_pcr_selection; | 811 | u32 sizeof_pcr_selection; |
812 | u32 nr_possible_banks; | ||
813 | u32 nr_alloc_banks = 0; | ||
814 | u16 hash_alg; | ||
813 | u32 rsp_len; | 815 | u32 rsp_len; |
814 | int rc; | 816 | int rc; |
815 | int i = 0; | 817 | int i = 0; |
@@ -826,11 +828,14 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | |||
826 | if (rc) | 828 | if (rc) |
827 | goto out; | 829 | goto out; |
828 | 830 | ||
829 | count = be32_to_cpup( | 831 | nr_possible_banks = be32_to_cpup( |
830 | (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); | 832 | (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); |
831 | 833 | ||
832 | if (count > ARRAY_SIZE(chip->active_banks)) { | 834 | chip->allocated_banks = kcalloc(nr_possible_banks, |
833 | rc = -ENODEV; | 835 | sizeof(*chip->allocated_banks), |
836 | GFP_KERNEL); | ||
837 | if (!chip->allocated_banks) { | ||
838 | rc = -ENOMEM; | ||
834 | goto out; | 839 | goto out; |
835 | } | 840 | } |
836 | 841 | ||
@@ -839,7 +844,7 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | |||
839 | rsp_len = be32_to_cpup((__be32 *)&buf.data[2]); | 844 | rsp_len = be32_to_cpup((__be32 *)&buf.data[2]); |
840 | end = &buf.data[rsp_len]; | 845 | end = &buf.data[rsp_len]; |
841 | 846 | ||
842 | for (i = 0; i < count; i++) { | 847 | for (i = 0; i < nr_possible_banks; i++) { |
843 | pcr_select_offset = marker + | 848 | pcr_select_offset = marker + |
844 | offsetof(struct tpm2_pcr_selection, size_of_select); | 849 | offsetof(struct tpm2_pcr_selection, size_of_select); |
845 | if (pcr_select_offset >= end) { | 850 | if (pcr_select_offset >= end) { |
@@ -848,17 +853,23 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) | |||
848 | } | 853 | } |
849 | 854 | ||
850 | memcpy(&pcr_selection, marker, sizeof(pcr_selection)); | 855 | memcpy(&pcr_selection, marker, sizeof(pcr_selection)); |
851 | chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg); | 856 | hash_alg = be16_to_cpu(pcr_selection.hash_alg); |
857 | |||
858 | pcr_select_offset = memchr_inv(pcr_selection.pcr_select, 0, | ||
859 | pcr_selection.size_of_select); | ||
860 | if (pcr_select_offset) { | ||
861 | chip->allocated_banks[nr_alloc_banks] = hash_alg; | ||
862 | nr_alloc_banks++; | ||
863 | } | ||
864 | |||
852 | sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) + | 865 | sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) + |
853 | sizeof(pcr_selection.size_of_select) + | 866 | sizeof(pcr_selection.size_of_select) + |
854 | pcr_selection.size_of_select; | 867 | pcr_selection.size_of_select; |
855 | marker = marker + sizeof_pcr_selection; | 868 | marker = marker + sizeof_pcr_selection; |
856 | } | 869 | } |
857 | 870 | ||
871 | chip->nr_allocated_banks = nr_alloc_banks; | ||
858 | out: | 872 | out: |
859 | if (i < ARRAY_SIZE(chip->active_banks)) | ||
860 | chip->active_banks[i] = TPM2_ALG_ERROR; | ||
861 | |||
862 | tpm_buf_destroy(&buf); | 873 | tpm_buf_destroy(&buf); |
863 | 874 | ||
864 | return rc; | 875 | return rc; |