aboutsummaryrefslogtreecommitdiff
path: root/security/integrity/ima
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-10 17:37:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-10 17:37:29 -0700
commit5af7f115886f7ec193171e2e49b8000ddd1e7147 (patch)
tree117b9e99650b0772f683e6b8f734e2c94f6a6c3b /security/integrity/ima
parentc3665a6be5de16cf6670a00003642114c44d8a70 (diff)
parent5da10728037afea6743b76afddfdc9950cd711b3 (diff)
Merge branch 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull tpm updates from James Morris: - Clean up the transmission flow Cleaned up the whole transmission flow. Locking of the chip is now done in the level of tpm_try_get_ops() and tpm_put_ops() instead taking the chip lock inside tpm_transmit(). The nested calls inside tpm_transmit(), used with the resource manager, have been refactored out. Should make easier to perform more complex transactions with the TPM without making the subsystem a bigger mess (e.g. encrypted channel patches by James Bottomley). - PPI 1.3 support TPM PPI 1.3 introduces an additional optional command parameter that may be needed for some commands. Display the parameter if the command requires such a parameter. Only command 23 (SetPCRBanks) needs one. The PPI request file will show output like this then: # echo "23 16" > request # cat request 23 16 # echo "5" > request # cat request 5 - Extend all PCR banks in IMA Instead of static PCR banks array, the array of available PCR banks is now allocated dynamically. The digests sizes are determined dynamically using a probe PCR read without relying crypto's static list of hash algorithms. This should finally make sealing of measurements in IMA safe and secure. - TPM 2.0 selftests Added a test suite to tools/testing/selftests/tpm2 previously outside of the kernel tree: https://github.com/jsakkine-intel/tpm2-scripts * 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (37 commits) tpm/ppi: Enable submission of optional command parameter for PPI 1.3 tpm/ppi: Possibly show command parameter if TPM PPI 1.3 is used tpm/ppi: Display up to 101 operations as define for version 1.3 tpm/ppi: rename TPM_PPI_REVISION_ID to TPM_PPI_REVISION_ID_1 tpm/ppi: pass function revision ID to tpm_eval_dsm() tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend() KEYS: trusted: explicitly use tpm_chip structure from tpm_default_chip() tpm: move tpm_chip definition to include/linux/tpm.h tpm: retrieve digest size of unknown algorithms with PCR read tpm: rename and export tpm2_digest and tpm2_algorithms tpm: dynamically allocate the allocated_banks array tpm: remove @flags from tpm_transmit() tpm: take TPM chip power gating out of tpm_transmit() tpm: introduce tpm_chip_start() and tpm_chip_stop() tpm: remove TPM_TRANSMIT_UNLOCKED flag tpm: use tpm_try_get_ops() in tpm-sysfs.c. tpm: remove @space from tpm_transmit() tpm: move TPM space code out of tpm_transmit() tpm: move tpm_validate_commmand() to tpm2-space.c tpm: clean up tpm_try_transmit() error handling flow ...
Diffstat (limited to 'security/integrity/ima')
-rw-r--r--security/integrity/ima/ima.h1
-rw-r--r--security/integrity/ima/ima_crypto.c10
-rw-r--r--security/integrity/ima/ima_init.c4
-rw-r--r--security/integrity/ima/ima_queue.c27
4 files changed, 36 insertions, 6 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 026163f37ba1..d213e835c498 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -153,6 +153,7 @@ int ima_measurements_show(struct seq_file *m, void *v);
unsigned long ima_get_binary_runtime_size(void);
int ima_init_template(void);
void ima_init_template_list(void);
+int __init ima_init_digests(void);
/*
* used to protect h_table and sha_table
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index acf2c7df7145..16a4f45863b1 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -643,12 +643,12 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
return calc_buffer_shash(buf, len, hash);
}
-static void __init ima_pcrread(u32 idx, u8 *pcr)
+static void __init ima_pcrread(u32 idx, struct tpm_digest *d)
{
if (!ima_tpm_chip)
return;
- if (tpm_pcr_read(ima_tpm_chip, idx, pcr) != 0)
+ if (tpm_pcr_read(ima_tpm_chip, idx, d) != 0)
pr_err("Error Communicating to TPM chip\n");
}
@@ -658,7 +658,7 @@ static void __init ima_pcrread(u32 idx, u8 *pcr)
static int __init ima_calc_boot_aggregate_tfm(char *digest,
struct crypto_shash *tfm)
{
- u8 pcr_i[TPM_DIGEST_SIZE];
+ struct tpm_digest d = { .alg_id = TPM_ALG_SHA1, .digest = {0} };
int rc;
u32 i;
SHASH_DESC_ON_STACK(shash, tfm);
@@ -672,9 +672,9 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest,
/* cumulative sha1 over tpm registers 0-7 */
for (i = TPM_PCR0; i < TPM_PCR8; i++) {
- ima_pcrread(i, pcr_i);
+ ima_pcrread(i, &d);
/* now accumulate with current aggregate */
- rc = crypto_shash_update(shash, pcr_i, TPM_DIGEST_SIZE);
+ rc = crypto_shash_update(shash, d.digest, TPM_DIGEST_SIZE);
}
if (!rc)
crypto_shash_final(shash, digest);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 6bb42a9c5e47..6c9295449751 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -123,8 +123,12 @@ int __init ima_init(void)
if (rc != 0)
return rc;
+ /* It can be called before ima_init_digests(), it does not use TPM. */
ima_load_kexec_buffer();
+ rc = ima_init_digests();
+ if (rc != 0)
+ return rc;
rc = ima_add_boot_aggregate(); /* boot aggregate must be first entry */
if (rc != 0)
return rc;
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 0e41dc1df1d4..6b6d044e0440 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -27,6 +27,9 @@
#define AUDIT_CAUSE_LEN_MAX 32
+/* pre-allocated array of tpm_digest structures to extend a PCR */
+static struct tpm_digest *digests;
+
LIST_HEAD(ima_measurements); /* list of all measurements */
#ifdef CONFIG_IMA_KEXEC
static unsigned long binary_runtime_size;
@@ -140,11 +143,15 @@ unsigned long ima_get_binary_runtime_size(void)
static int ima_pcr_extend(const u8 *hash, int pcr)
{
int result = 0;
+ int i;
if (!ima_tpm_chip)
return result;
- result = tpm_pcr_extend(ima_tpm_chip, pcr, hash);
+ for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++)
+ memcpy(digests[i].digest, hash, TPM_DIGEST_SIZE);
+
+ result = tpm_pcr_extend(ima_tpm_chip, pcr, digests);
if (result != 0)
pr_err("Error Communicating to TPM chip, result: %d\n", result);
return result;
@@ -211,3 +218,21 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry)
mutex_unlock(&ima_extend_list_mutex);
return result;
}
+
+int __init ima_init_digests(void)
+{
+ int i;
+
+ if (!ima_tpm_chip)
+ return 0;
+
+ digests = kcalloc(ima_tpm_chip->nr_allocated_banks, sizeof(*digests),
+ GFP_NOFS);
+ if (!digests)
+ return -ENOMEM;
+
+ for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++)
+ digests[i].alg_id = ima_tpm_chip->allocated_banks[i].alg_id;
+
+ return 0;
+}