|
From: Roberto S. <rob...@hu...> - 2017-03-29 17:40:53
|
Check if the algorithms provided by the user are supported by the TPM.
If an algorithm is not supported, the template digest is calculated using
remaining algorithms.
Signed-off-by: Roberto Sassu <rob...@hu...>
---
security/integrity/ima/ima_crypto.c | 78 +++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index afb4d75..b5095ac 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -66,12 +66,90 @@ MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size");
static struct crypto_shash *ima_shash_tfm;
static struct crypto_ahash *ima_ahash_tfm;
+int ima_digest_algo_tpm_check(void)
+{
+ struct ima_digest_desc *desc = ima_get_digest_desc_fmt(cur_fmt);
+ enum tpm2_algorithms tpm_algo[ARRAY_SIZE(desc->tpm_algorithms)];
+ bool all_algorithms = (desc->algo_num == 1 &&
+ desc->algorithms[0] == HASH_ALGO__LAST);
+ int is_tpm2 = tpm_is_tpm2(TPM_ANY_NUM);
+ enum hash_algo crypto_id;
+ int tpm_num, checked_num = 0;
+ int i, j, k;
+
+ if (!ima_used_chip || !is_tpm2) {
+ if (!is_tpm2 || all_algorithms)
+ desc->algorithms[0] = HASH_ALGO_SHA1;
+ if (!is_tpm2)
+ desc->tpm_algo_num = desc->algo_num = 1;
+
+ return 0;
+ }
+
+ tpm_num = tpm_pcr_algorithms(TPM_ANY_NUM,
+ ARRAY_SIZE(tpm_algo), tpm_algo);
+ if (tpm_num < 0) {
+ pr_err("unable to retrieve TPM algorithms\n");
+ return tpm_num;
+ }
+
+ if (all_algorithms) {
+ desc->algo_num = tpm_num;
+ goto out_copy;
+ }
+
+ for (i = 0; i < desc->algo_num; i++) {
+ for (j = 0; j < tpm_num; j++) {
+ crypto_id = tpm2_pcr_algo_to_crypto(tpm_algo[j]);
+ if (crypto_id == desc->algorithms[checked_num])
+ break;
+ }
+
+ if (j < tpm_num) {
+ desc->tpm_algorithms[checked_num++] = tpm_algo[j];
+ tpm_algo[j] = TPM2_ALG_ERROR;
+ continue;
+ }
+
+ pr_err("algorithm %s not supported by the TPM\n",
+ hash_algo_name[desc->algorithms[checked_num]]);
+
+ for (k = checked_num;
+ k < checked_num + desc->algo_num - i - 1; k++)
+ desc->algorithms[k] = desc->algorithms[k + 1];
+ }
+
+ if (checked_num == 0) {
+ pr_err("no usable algorithms found\n");
+ return -EINVAL;
+ }
+
+ desc->algo_num = checked_num;
+out_copy:
+ for (i = 0; i < tpm_num; i++) {
+ if (tpm_algo[i] == TPM2_ALG_ERROR)
+ continue;
+
+ crypto_id = tpm2_pcr_algo_to_crypto(tpm_algo[i]);
+ desc->algorithms[checked_num] = crypto_id;
+ desc->tpm_algorithms[checked_num] = tpm_algo[i];
+ checked_num++;
+ }
+
+ desc->tpm_algo_num = checked_num;
+ return 0;
+}
+
int __init ima_init_crypto(void)
{
struct ima_digest_desc *digest_desc = ima_get_digest_desc_fmt(cur_fmt);
long rc;
int i;
+ rc = ima_digest_algo_tpm_check();
+ if (rc < 0)
+ return rc;
+
for (i = 0; i < digest_desc->algo_num + 1; i++) {
enum hash_algo algo = (i < digest_desc->algo_num) ?
digest_desc->algorithms[i] : ima_hash_algo;
--
2.9.3
|