diff options
Diffstat (limited to 'drivers/char/tpm/tpm2-cmd.c')
-rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index c12130485fc1..45a634016f95 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -16,6 +16,7 @@ */ #include "tpm.h" +#include <crypto/hash_info.h> #include <keys/trusted-type.h> enum tpm2_object_attributes { @@ -104,6 +105,19 @@ struct tpm2_cmd { union tpm2_cmd_params params; } __packed; +struct tpm2_hash { + unsigned int crypto_id; + unsigned int tpm_id; +}; + +static struct tpm2_hash tpm2_hash_map[] = { + {HASH_ALGO_SHA1, TPM2_ALG_SHA1}, + {HASH_ALGO_SHA256, TPM2_ALG_SHA256}, + {HASH_ALGO_SHA384, TPM2_ALG_SHA384}, + {HASH_ALGO_SHA512, TPM2_ALG_SHA512}, + {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256}, +}; + /* * Array with one entry per ordinal defining the maximum amount * of time the chip could take to return the result. The values @@ -429,8 +443,20 @@ int tpm2_seal_trusted(struct tpm_chip *chip, { unsigned int blob_len; struct tpm_buf buf; + u32 hash; + int i; int rc; + for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { + if (options->hash == tpm2_hash_map[i].crypto_id) { + hash = tpm2_hash_map[i].tpm_id; + break; + } + } + + if (i == ARRAY_SIZE(tpm2_hash_map)) + return -EINVAL; + rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); if (rc) return rc; @@ -452,12 +478,26 @@ int tpm2_seal_trusted(struct tpm_chip *chip, tpm_buf_append_u8(&buf, payload->migratable); /* public */ - tpm_buf_append_u16(&buf, 14); + if (options->policydigest) + tpm_buf_append_u16(&buf, 14 + options->digest_len); + else + tpm_buf_append_u16(&buf, 14); tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); - tpm_buf_append_u16(&buf, TPM2_ALG_SHA256); - tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); - tpm_buf_append_u16(&buf, 0); /* policy digest size */ + tpm_buf_append_u16(&buf, hash); + + /* policy */ + if (options->policydigest) { + tpm_buf_append_u32(&buf, 0); + tpm_buf_append_u16(&buf, options->digest_len); + tpm_buf_append(&buf, options->policydigest, + options->digest_len); + } else { + tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); + tpm_buf_append_u16(&buf, 0); + } + + /* public parameters */ tpm_buf_append_u16(&buf, TPM2_ALG_NULL); tpm_buf_append_u16(&buf, 0); @@ -488,8 +528,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, out: tpm_buf_destroy(&buf); - if (rc > 0) - rc = -EPERM; + if (rc > 0) { + if ((rc & TPM2_RC_HASH) == TPM2_RC_HASH) + rc = -EINVAL; + else + rc = -EPERM; + } return rc; } @@ -583,7 +627,9 @@ static int tpm2_unseal(struct tpm_chip *chip, return rc; tpm_buf_append_u32(&buf, blob_handle); - tpm2_buf_append_auth(&buf, TPM2_RS_PW, + tpm2_buf_append_auth(&buf, + options->policyhandle ? + options->policyhandle : TPM2_RS_PW, NULL /* nonce */, 0, 0 /* session_attributes */, options->blobauth /* hmac */, |