mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 11:56:58 +00:00
Merge tag 'tpmdd-sessions-next-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull more tpm updates from Jarkko Sakkinen: "This is targeted for tpm2-sessions updates. There's two bug fixes and two more cosmetic tweaks for HMAC protected sessions. They provide a baseine for further improvements to be implemented during the the course of the release cycle" * tag 'tpmdd-sessions-next-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm2-sessions: Open code tpm_buf_append_hmac_session() tpm2-sessions: Remove 'attributes' parameter from tpm_buf_append_auth tpm2-sessions: Fix tpm2_read_public range checks tpm2-sessions: Fix out of range indexing in name_size
This commit is contained in:
@@ -11,8 +11,11 @@
|
||||
* used by the kernel internally.
|
||||
*/
|
||||
|
||||
#include "linux/dev_printk.h"
|
||||
#include "linux/tpm.h"
|
||||
#include "tpm.h"
|
||||
#include <crypto/hash_info.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
static bool disable_pcr_integrity;
|
||||
module_param(disable_pcr_integrity, bool, 0444);
|
||||
@@ -199,11 +202,15 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
|
||||
}
|
||||
|
||||
if (!disable_pcr_integrity) {
|
||||
tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
|
||||
rc = tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
|
||||
if (rc) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return rc;
|
||||
}
|
||||
tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
|
||||
} else {
|
||||
tpm_buf_append_handle(chip, &buf, pcr_idx);
|
||||
tpm_buf_append_auth(chip, &buf, 0, NULL, 0);
|
||||
tpm_buf_append_auth(chip, &buf, NULL, 0);
|
||||
}
|
||||
|
||||
tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
|
||||
@@ -214,8 +221,14 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
|
||||
chip->allocated_banks[i].digest_size);
|
||||
}
|
||||
|
||||
if (!disable_pcr_integrity)
|
||||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (!disable_pcr_integrity) {
|
||||
rc = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (rc) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value");
|
||||
if (!disable_pcr_integrity)
|
||||
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
|
||||
@@ -269,11 +282,24 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
|
||||
|
||||
do {
|
||||
tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
|
||||
tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT
|
||||
| TPM2_SA_CONTINUE_SESSION,
|
||||
NULL, 0);
|
||||
if (tpm2_chip_auth(chip)) {
|
||||
tpm_buf_append_hmac_session(chip, &buf,
|
||||
TPM2_SA_ENCRYPT |
|
||||
TPM2_SA_CONTINUE_SESSION,
|
||||
NULL, 0);
|
||||
} else {
|
||||
offset = buf.handles * 4 + TPM_HEADER_SIZE;
|
||||
head = (struct tpm_header *)buf.data;
|
||||
if (tpm_buf_length(&buf) == offset)
|
||||
head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
|
||||
}
|
||||
tpm_buf_append_u16(&buf, num_bytes);
|
||||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
err = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (err) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = tpm_transmit_cmd(chip, &buf,
|
||||
offsetof(struct tpm2_get_random_out,
|
||||
buffer),
|
||||
|
||||
@@ -144,59 +144,80 @@ struct tpm2_auth {
|
||||
/*
|
||||
* Name Size based on TPM algorithm (assumes no hash bigger than 255)
|
||||
*/
|
||||
static u8 name_size(const u8 *name)
|
||||
static int name_size(const u8 *name)
|
||||
{
|
||||
static u8 size_map[] = {
|
||||
[TPM_ALG_SHA1] = SHA1_DIGEST_SIZE,
|
||||
[TPM_ALG_SHA256] = SHA256_DIGEST_SIZE,
|
||||
[TPM_ALG_SHA384] = SHA384_DIGEST_SIZE,
|
||||
[TPM_ALG_SHA512] = SHA512_DIGEST_SIZE,
|
||||
};
|
||||
u16 alg = get_unaligned_be16(name);
|
||||
return size_map[alg] + 2;
|
||||
u16 hash_alg = get_unaligned_be16(name);
|
||||
|
||||
switch (hash_alg) {
|
||||
case TPM_ALG_SHA1:
|
||||
return SHA1_DIGEST_SIZE + 2;
|
||||
case TPM_ALG_SHA256:
|
||||
return SHA256_DIGEST_SIZE + 2;
|
||||
case TPM_ALG_SHA384:
|
||||
return SHA384_DIGEST_SIZE + 2;
|
||||
case TPM_ALG_SHA512:
|
||||
return SHA512_DIGEST_SIZE + 2;
|
||||
default:
|
||||
pr_warn("tpm: unsupported name algorithm: 0x%04x\n", hash_alg);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
|
||||
static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
|
||||
{
|
||||
struct tpm_header *head = (struct tpm_header *)buf->data;
|
||||
u32 mso = tpm2_handle_mso(handle);
|
||||
off_t offset = TPM_HEADER_SIZE;
|
||||
u32 tot_len = be32_to_cpu(head->length);
|
||||
u32 val;
|
||||
|
||||
/* we're starting after the header so adjust the length */
|
||||
tot_len -= TPM_HEADER_SIZE;
|
||||
|
||||
/* skip public */
|
||||
val = tpm_buf_read_u16(buf, &offset);
|
||||
if (val > tot_len)
|
||||
return -EINVAL;
|
||||
offset += val;
|
||||
/* name */
|
||||
val = tpm_buf_read_u16(buf, &offset);
|
||||
if (val != name_size(&buf->data[offset]))
|
||||
return -EINVAL;
|
||||
memcpy(name, &buf->data[offset], val);
|
||||
/* forget the rest */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
|
||||
{
|
||||
int rc, name_size_alg;
|
||||
struct tpm_buf buf;
|
||||
int rc;
|
||||
|
||||
if (mso != TPM2_MSO_PERSISTENT && mso != TPM2_MSO_VOLATILE &&
|
||||
mso != TPM2_MSO_NVRAM) {
|
||||
memcpy(name, &handle, sizeof(u32));
|
||||
return sizeof(u32);
|
||||
}
|
||||
|
||||
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
tpm_buf_append_u32(&buf, handle);
|
||||
rc = tpm_transmit_cmd(chip, &buf, 0, "read public");
|
||||
if (rc == TPM2_RC_SUCCESS)
|
||||
rc = tpm2_parse_read_public(name, &buf);
|
||||
|
||||
tpm_buf_destroy(&buf);
|
||||
rc = tpm_transmit_cmd(chip, &buf, 0, "TPM2_ReadPublic");
|
||||
if (rc) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return tpm_ret_to_err(rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
/* Skip TPMT_PUBLIC: */
|
||||
offset += tpm_buf_read_u16(&buf, &offset);
|
||||
|
||||
/*
|
||||
* Ensure space for the length field of TPM2B_NAME and hashAlg field of
|
||||
* TPMT_HA (the extra four bytes).
|
||||
*/
|
||||
if (offset + 4 > tpm_buf_length(&buf)) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = tpm_buf_read_u16(&buf, &offset);
|
||||
name_size_alg = name_size(&buf.data[offset]);
|
||||
|
||||
if (name_size_alg < 0)
|
||||
return name_size_alg;
|
||||
|
||||
if (rc != name_size_alg) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (offset + rc > tpm_buf_length(&buf)) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(name, &buf.data[offset], rc);
|
||||
return name_size_alg;
|
||||
}
|
||||
#endif /* CONFIG_TCG_TPM2_HMAC */
|
||||
|
||||
@@ -221,52 +242,76 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
|
||||
* As with most tpm_buf operations, success is assumed because failure
|
||||
* will be caused by an incorrect programming model and indicated by a
|
||||
* kernel message.
|
||||
*
|
||||
* Ends the authorization session on failure.
|
||||
*/
|
||||
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u32 handle, u8 *name)
|
||||
int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u32 handle, u8 *name)
|
||||
{
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
enum tpm2_mso_type mso = tpm2_handle_mso(handle);
|
||||
struct tpm2_auth *auth;
|
||||
u16 name_size_alg;
|
||||
int slot;
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
if (!tpm2_chip_auth(chip)) {
|
||||
tpm_buf_append_handle(chip, buf, handle);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE) / 4;
|
||||
if (slot >= AUTH_MAX_NAMES) {
|
||||
dev_err(&chip->dev, "TPM: too many handles\n");
|
||||
return;
|
||||
dev_err(&chip->dev, "too many handles\n");
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
auth = chip->auth;
|
||||
WARN(auth->session != tpm_buf_length(buf),
|
||||
"name added in wrong place\n");
|
||||
if (auth->session != tpm_buf_length(buf)) {
|
||||
dev_err(&chip->dev, "session state malformed");
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
tpm_buf_append_u32(buf, handle);
|
||||
auth->session += 4;
|
||||
|
||||
if (mso == TPM2_MSO_PERSISTENT ||
|
||||
mso == TPM2_MSO_VOLATILE ||
|
||||
mso == TPM2_MSO_NVRAM) {
|
||||
if (!name)
|
||||
tpm2_read_public(chip, handle, auth->name[slot]);
|
||||
if (!name) {
|
||||
ret = tpm2_read_public(chip, handle, auth->name[slot]);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
name_size_alg = ret;
|
||||
}
|
||||
} else {
|
||||
if (name)
|
||||
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
|
||||
if (name) {
|
||||
dev_err(&chip->dev, "handle 0x%08x does not use a name\n",
|
||||
handle);
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
auth->name_h[slot] = handle;
|
||||
if (name)
|
||||
memcpy(auth->name[slot], name, name_size(name));
|
||||
memcpy(auth->name[slot], name, name_size_alg);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
err:
|
||||
tpm2_end_auth_session(chip);
|
||||
return tpm_ret_to_err(ret);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_buf_append_name);
|
||||
|
||||
void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u8 attributes, u8 *passphrase, int passphrase_len)
|
||||
u8 *passphrase, int passphrase_len)
|
||||
{
|
||||
/* offset tells us where the sessions area begins */
|
||||
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
|
||||
@@ -327,8 +372,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
#endif
|
||||
|
||||
if (!tpm2_chip_auth(chip)) {
|
||||
tpm_buf_append_auth(chip, buf, attributes, passphrase,
|
||||
passphrase_len);
|
||||
tpm_buf_append_auth(chip, buf, passphrase, passphrase_len);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -533,11 +577,9 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
* encryption key and encrypts the first parameter of the command
|
||||
* buffer with it.
|
||||
*
|
||||
* As with most tpm_buf operations, success is assumed because failure
|
||||
* will be caused by an incorrect programming model and indicated by a
|
||||
* kernel message.
|
||||
* Ends the authorization session on failure.
|
||||
*/
|
||||
void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
{
|
||||
u32 cc, handles, val;
|
||||
struct tpm2_auth *auth = chip->auth;
|
||||
@@ -549,9 +591,12 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
u8 cphash[SHA256_DIGEST_SIZE];
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
int ret;
|
||||
|
||||
if (!auth)
|
||||
return;
|
||||
if (!auth) {
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* save the command code in BE format */
|
||||
auth->ordinal = head->ordinal;
|
||||
@@ -560,9 +605,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
|
||||
i = tpm2_find_cc(chip, cc);
|
||||
if (i < 0) {
|
||||
dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc);
|
||||
return;
|
||||
dev_err(&chip->dev, "command 0x%08x not found\n", cc);
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
attrs = chip->cc_attrs_tbl[i];
|
||||
|
||||
handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0);
|
||||
@@ -576,9 +623,9 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
u32 handle = tpm_buf_read_u32(buf, &offset_s);
|
||||
|
||||
if (auth->name_h[i] != handle) {
|
||||
dev_err(&chip->dev, "TPM: handle %d wrong for name\n",
|
||||
i);
|
||||
return;
|
||||
dev_err(&chip->dev, "invalid handle 0x%08x\n", handle);
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* point offset_s to the start of the sessions */
|
||||
@@ -609,12 +656,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
offset_s += len;
|
||||
}
|
||||
if (offset_s != offset_p) {
|
||||
dev_err(&chip->dev, "TPM session length is incorrect\n");
|
||||
return;
|
||||
dev_err(&chip->dev, "session length is incorrect\n");
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
if (!hmac) {
|
||||
dev_err(&chip->dev, "TPM could not find HMAC session\n");
|
||||
return;
|
||||
dev_err(&chip->dev, "could not find HMAC session\n");
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* encrypt before HMAC */
|
||||
@@ -646,8 +695,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
if (mso == TPM2_MSO_PERSISTENT ||
|
||||
mso == TPM2_MSO_VOLATILE ||
|
||||
mso == TPM2_MSO_NVRAM) {
|
||||
sha256_update(&sctx, auth->name[i],
|
||||
name_size(auth->name[i]));
|
||||
ret = name_size(auth->name[i]);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
sha256_update(&sctx, auth->name[i], ret);
|
||||
} else {
|
||||
__be32 h = cpu_to_be32(auth->name_h[i]);
|
||||
|
||||
@@ -668,6 +720,11 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
hmac_sha256_update(&hctx, &auth->attrs, 1);
|
||||
hmac_sha256_final(&hctx, hmac);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
tpm2_end_auth_session(chip);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
|
||||
|
||||
|
||||
@@ -529,41 +529,18 @@ static inline struct tpm2_auth *tpm2_chip_auth(struct tpm_chip *chip)
|
||||
#endif
|
||||
}
|
||||
|
||||
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u32 handle, u8 *name);
|
||||
int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u32 handle, u8 *name);
|
||||
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u8 attributes, u8 *passphrase,
|
||||
int passphraselen);
|
||||
void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u8 attributes, u8 *passphrase, int passphraselen);
|
||||
static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
|
||||
struct tpm_buf *buf,
|
||||
u8 attributes,
|
||||
u8 *passphrase,
|
||||
int passphraselen)
|
||||
{
|
||||
struct tpm_header *head;
|
||||
int offset;
|
||||
|
||||
if (tpm2_chip_auth(chip)) {
|
||||
tpm_buf_append_hmac_session(chip, buf, attributes, passphrase, passphraselen);
|
||||
} else {
|
||||
offset = buf->handles * 4 + TPM_HEADER_SIZE;
|
||||
head = (struct tpm_header *)buf->data;
|
||||
|
||||
/*
|
||||
* If the only sessions are optional, the command tag must change to
|
||||
* TPM2_ST_NO_SESSIONS.
|
||||
*/
|
||||
if (tpm_buf_length(buf) == offset)
|
||||
head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
|
||||
}
|
||||
}
|
||||
u8 *passphrase, int passphraselen);
|
||||
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
|
||||
int tpm2_start_auth_session(struct tpm_chip *chip);
|
||||
void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf);
|
||||
int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf);
|
||||
int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
int rc);
|
||||
void tpm2_end_auth_session(struct tpm_chip *chip);
|
||||
@@ -577,10 +554,13 @@ static inline int tpm2_start_auth_session(struct tpm_chip *chip)
|
||||
static inline void tpm2_end_auth_session(struct tpm_chip *chip)
|
||||
{
|
||||
}
|
||||
static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip,
|
||||
struct tpm_buf *buf)
|
||||
|
||||
static inline int tpm_buf_fill_hmac_session(struct tpm_chip *chip,
|
||||
struct tpm_buf *buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int tpm_buf_check_hmac_response(struct tpm_chip *chip,
|
||||
struct tpm_buf *buf,
|
||||
int rc)
|
||||
|
||||
@@ -268,7 +268,10 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
|
||||
rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_DECRYPT,
|
||||
options->keyauth, TPM_DIGEST_SIZE);
|
||||
|
||||
@@ -316,7 +319,10 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
||||
goto out;
|
||||
}
|
||||
|
||||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
rc = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
|
||||
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
|
||||
if (rc)
|
||||
@@ -427,7 +433,10 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
|
||||
return rc;
|
||||
}
|
||||
|
||||
tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
|
||||
rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
tpm_buf_append_hmac_session(chip, &buf, 0, options->keyauth,
|
||||
TPM_DIGEST_SIZE);
|
||||
|
||||
@@ -439,7 +448,10 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
|
||||
goto out;
|
||||
}
|
||||
|
||||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
rc = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
|
||||
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
|
||||
if (!rc)
|
||||
@@ -469,8 +481,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
||||
struct trusted_key_options *options,
|
||||
u32 blob_handle)
|
||||
{
|
||||
struct tpm_header *head;
|
||||
struct tpm_buf buf;
|
||||
u16 data_len;
|
||||
int offset;
|
||||
u8 *data;
|
||||
int rc;
|
||||
|
||||
@@ -484,7 +498,9 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
||||
return rc;
|
||||
}
|
||||
|
||||
tpm_buf_append_name(chip, &buf, blob_handle, NULL);
|
||||
rc = tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
if (!options->policyhandle) {
|
||||
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT,
|
||||
@@ -505,11 +521,20 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
||||
tpm2_buf_append_auth(&buf, options->policyhandle,
|
||||
NULL /* nonce */, 0, 0,
|
||||
options->blobauth, options->blobauth_len);
|
||||
tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT,
|
||||
NULL, 0);
|
||||
if (tpm2_chip_auth(chip)) {
|
||||
tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT, NULL, 0);
|
||||
} else {
|
||||
offset = buf.handles * 4 + TPM_HEADER_SIZE;
|
||||
head = (struct tpm_header *)buf.data;
|
||||
if (tpm_buf_length(&buf) == offset)
|
||||
head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
|
||||
}
|
||||
}
|
||||
|
||||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
rc = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
|
||||
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user