Commit 5cc46711 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'tpmdd-next-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull TPM fixes from Jarkko Sakkinen:
 "This contains the fixes for !chip->auth condition, preventing the
  breakage of:
   - tpm_ftpm_tee.c
   - tpm_i2c_nuvoton.c
   - tpm_ibmvtpm.c
   - tpm_tis_i2c_cr50.c
   - tpm_vtpm_proxy.c

  All drivers will continue to work as they did in 6.9, except a single
  warning (dev_warn() not WARN()) is printed to klog only to inform that
  authenticated sessions are not enabled"

* tag 'tpmdd-next-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  tpm: Address !chip->auth in tpm_buf_append_hmac_session*()
  tpm: Address !chip->auth in tpm_buf_append_name()
  tpm: Address !chip->auth in tpm2_*_auth_session()
parents 75aa87ca 7ca110f2
...@@ -16,8 +16,8 @@ tpm-y += eventlog/common.o ...@@ -16,8 +16,8 @@ tpm-y += eventlog/common.o
tpm-y += eventlog/tpm1.o tpm-y += eventlog/tpm1.o
tpm-y += eventlog/tpm2.o tpm-y += eventlog/tpm2.o
tpm-y += tpm-buf.o tpm-y += tpm-buf.o
tpm-y += tpm2-sessions.o
tpm-$(CONFIG_TCG_TPM2_HMAC) += tpm2-sessions.o
tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
tpm-$(CONFIG_EFI) += eventlog/efi.o tpm-$(CONFIG_EFI) += eventlog/efi.o
tpm-$(CONFIG_OF) += eventlog/of.o tpm-$(CONFIG_OF) += eventlog/of.o
......
...@@ -83,9 +83,6 @@ ...@@ -83,9 +83,6 @@
#define AES_KEY_BYTES AES_KEYSIZE_128 #define AES_KEY_BYTES AES_KEYSIZE_128
#define AES_KEY_BITS (AES_KEY_BYTES*8) #define AES_KEY_BITS (AES_KEY_BYTES*8)
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
u32 *handle, u8 *name);
/* /*
* This is the structure that carries all the auth information (like * This is the structure that carries all the auth information (like
* session handle, nonces, session key and auth) from use to use it is * session handle, nonces, session key and auth) from use to use it is
...@@ -148,6 +145,7 @@ struct tpm2_auth { ...@@ -148,6 +145,7 @@ struct tpm2_auth {
u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE]; u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
}; };
#ifdef CONFIG_TCG_TPM2_HMAC
/* /*
* Name Size based on TPM algorithm (assumes no hash bigger than 255) * Name Size based on TPM algorithm (assumes no hash bigger than 255)
*/ */
...@@ -163,6 +161,226 @@ static u8 name_size(const u8 *name) ...@@ -163,6 +161,226 @@ static u8 name_size(const u8 *name)
return size_map[alg] + 2; return size_map[alg] + 2;
} }
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
{
struct tpm_header *head = (struct tpm_header *)buf->data;
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)
{
struct tpm_buf buf;
int rc;
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);
return rc;
}
#endif /* CONFIG_TCG_TPM2_HMAC */
/**
* tpm_buf_append_name() - add a handle area to the buffer
* @chip: the TPM chip structure
* @buf: The buffer to be appended
* @handle: The handle to be appended
* @name: The name of the handle (may be NULL)
*
* In order to compute session HMACs, we need to know the names of the
* objects pointed to by the handles. For most objects, this is simply
* the actual 4 byte handle or an empty buf (in these cases @name
* should be NULL) but for volatile objects, permanent objects and NV
* areas, the name is defined as the hash (according to the name
* algorithm which should be set to sha256) of the public area to
* which the two byte algorithm id has been appended. For these
* objects, the @name pointer should point to this. If a name is
* required but @name is NULL, then TPM2_ReadPublic() will be called
* on the handle to obtain the 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.
*/
void 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;
int slot;
#endif
if (!tpm2_chip_auth(chip)) {
tpm_buf_append_u32(buf, handle);
/* count the number of handles in the upper bits of flags */
buf->handles++;
return;
}
#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;
}
auth = chip->auth;
WARN(auth->session != tpm_buf_length(buf),
"name added in wrong place\n");
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]);
} else {
if (name)
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
}
auth->name_h[slot] = handle;
if (name)
memcpy(auth->name[slot], name, name_size(name));
#endif
}
EXPORT_SYMBOL_GPL(tpm_buf_append_name);
/**
* tpm_buf_append_hmac_session() - Append a TPM session element
* @chip: the TPM chip structure
* @buf: The buffer to be appended
* @attributes: The session attributes
* @passphrase: The session authority (NULL if none)
* @passphrase_len: The length of the session authority (0 if none)
*
* This fills in a session structure in the TPM command buffer, except
* for the HMAC which cannot be computed until the command buffer is
* complete. The type of session is controlled by the @attributes,
* the main ones of which are TPM2_SA_CONTINUE_SESSION which means the
* session won't terminate after tpm_buf_check_hmac_response(),
* TPM2_SA_DECRYPT which means this buffers first parameter should be
* encrypted with a session key and TPM2_SA_ENCRYPT, which means the
* response buffer's first parameter needs to be decrypted (confusing,
* but the defines are written from the point of view of the TPM).
*
* Any session appended by this command must be finalized by calling
* tpm_buf_fill_hmac_session() otherwise the HMAC will be incorrect
* and the TPM will reject the command.
*
* 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.
*/
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
u8 attributes, u8 *passphrase,
int passphrase_len)
{
#ifdef CONFIG_TCG_TPM2_HMAC
u8 nonce[SHA256_DIGEST_SIZE];
struct tpm2_auth *auth;
u32 len;
#endif
if (!tpm2_chip_auth(chip)) {
/* offset tells us where the sessions area begins */
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
u32 len = 9 + passphrase_len;
if (tpm_buf_length(buf) != offset) {
/* not the first session so update the existing length */
len += get_unaligned_be32(&buf->data[offset]);
put_unaligned_be32(len, &buf->data[offset]);
} else {
tpm_buf_append_u32(buf, len);
}
/* auth handle */
tpm_buf_append_u32(buf, TPM2_RS_PW);
/* nonce */
tpm_buf_append_u16(buf, 0);
/* attributes */
tpm_buf_append_u8(buf, 0);
/* passphrase */
tpm_buf_append_u16(buf, passphrase_len);
tpm_buf_append(buf, passphrase, passphrase_len);
return;
}
#ifdef CONFIG_TCG_TPM2_HMAC
/*
* The Architecture Guide requires us to strip trailing zeros
* before computing the HMAC
*/
while (passphrase && passphrase_len > 0 && passphrase[passphrase_len - 1] == '\0')
passphrase_len--;
auth = chip->auth;
auth->attrs = attributes;
auth->passphrase_len = passphrase_len;
if (passphrase_len)
memcpy(auth->passphrase, passphrase, passphrase_len);
if (auth->session != tpm_buf_length(buf)) {
/* we're not the first session */
len = get_unaligned_be32(&buf->data[auth->session]);
if (4 + len + auth->session != tpm_buf_length(buf)) {
WARN(1, "session length mismatch, cannot append");
return;
}
/* add our new session */
len += 9 + 2 * SHA256_DIGEST_SIZE;
put_unaligned_be32(len, &buf->data[auth->session]);
} else {
tpm_buf_append_u32(buf, 9 + 2 * SHA256_DIGEST_SIZE);
}
/* random number for our nonce */
get_random_bytes(nonce, sizeof(nonce));
memcpy(auth->our_nonce, nonce, sizeof(nonce));
tpm_buf_append_u32(buf, auth->handle);
/* our new nonce */
tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
tpm_buf_append_u8(buf, auth->attrs);
/* and put a placeholder for the hmac */
tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
#endif
}
EXPORT_SYMBOL_GPL(tpm_buf_append_hmac_session);
#ifdef CONFIG_TCG_TPM2_HMAC
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
u32 *handle, u8 *name);
/* /*
* It turns out the crypto hmac(sha256) is hard for us to consume * It turns out the crypto hmac(sha256) is hard for us to consume
* because it assumes a fixed key and the TPM seems to change the key * because it assumes a fixed key and the TPM seems to change the key
...@@ -343,82 +561,6 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) ...@@ -343,82 +561,6 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
crypto_free_kpp(kpp); crypto_free_kpp(kpp);
} }
/**
* tpm_buf_append_hmac_session() - Append a TPM session element
* @chip: the TPM chip structure
* @buf: The buffer to be appended
* @attributes: The session attributes
* @passphrase: The session authority (NULL if none)
* @passphrase_len: The length of the session authority (0 if none)
*
* This fills in a session structure in the TPM command buffer, except
* for the HMAC which cannot be computed until the command buffer is
* complete. The type of session is controlled by the @attributes,
* the main ones of which are TPM2_SA_CONTINUE_SESSION which means the
* session won't terminate after tpm_buf_check_hmac_response(),
* TPM2_SA_DECRYPT which means this buffers first parameter should be
* encrypted with a session key and TPM2_SA_ENCRYPT, which means the
* response buffer's first parameter needs to be decrypted (confusing,
* but the defines are written from the point of view of the TPM).
*
* Any session appended by this command must be finalized by calling
* tpm_buf_fill_hmac_session() otherwise the HMAC will be incorrect
* and the TPM will reject the command.
*
* 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.
*/
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
u8 attributes, u8 *passphrase,
int passphrase_len)
{
u8 nonce[SHA256_DIGEST_SIZE];
u32 len;
struct tpm2_auth *auth = chip->auth;
/*
* The Architecture Guide requires us to strip trailing zeros
* before computing the HMAC
*/
while (passphrase && passphrase_len > 0
&& passphrase[passphrase_len - 1] == '\0')
passphrase_len--;
auth->attrs = attributes;
auth->passphrase_len = passphrase_len;
if (passphrase_len)
memcpy(auth->passphrase, passphrase, passphrase_len);
if (auth->session != tpm_buf_length(buf)) {
/* we're not the first session */
len = get_unaligned_be32(&buf->data[auth->session]);
if (4 + len + auth->session != tpm_buf_length(buf)) {
WARN(1, "session length mismatch, cannot append");
return;
}
/* add our new session */
len += 9 + 2 * SHA256_DIGEST_SIZE;
put_unaligned_be32(len, &buf->data[auth->session]);
} else {
tpm_buf_append_u32(buf, 9 + 2 * SHA256_DIGEST_SIZE);
}
/* random number for our nonce */
get_random_bytes(nonce, sizeof(nonce));
memcpy(auth->our_nonce, nonce, sizeof(nonce));
tpm_buf_append_u32(buf, auth->handle);
/* our new nonce */
tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
tpm_buf_append_u8(buf, auth->attrs);
/* and put a placeholder for the hmac */
tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
}
EXPORT_SYMBOL(tpm_buf_append_hmac_session);
/** /**
* tpm_buf_fill_hmac_session() - finalize the session HMAC * tpm_buf_fill_hmac_session() - finalize the session HMAC
* @chip: the TPM chip structure * @chip: the TPM chip structure
...@@ -449,6 +591,9 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) ...@@ -449,6 +591,9 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
u8 cphash[SHA256_DIGEST_SIZE]; u8 cphash[SHA256_DIGEST_SIZE];
struct sha256_state sctx; struct sha256_state sctx;
if (!auth)
return;
/* save the command code in BE format */ /* save the command code in BE format */
auth->ordinal = head->ordinal; auth->ordinal = head->ordinal;
...@@ -567,104 +712,6 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) ...@@ -567,104 +712,6 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
} }
EXPORT_SYMBOL(tpm_buf_fill_hmac_session); EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
{
struct tpm_header *head = (struct tpm_header *)buf->data;
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)
{
struct tpm_buf buf;
int rc;
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);
return rc;
}
/**
* tpm_buf_append_name() - add a handle area to the buffer
* @chip: the TPM chip structure
* @buf: The buffer to be appended
* @handle: The handle to be appended
* @name: The name of the handle (may be NULL)
*
* In order to compute session HMACs, we need to know the names of the
* objects pointed to by the handles. For most objects, this is simply
* the actual 4 byte handle or an empty buf (in these cases @name
* should be NULL) but for volatile objects, permanent objects and NV
* areas, the name is defined as the hash (according to the name
* algorithm which should be set to sha256) of the public area to
* which the two byte algorithm id has been appended. For these
* objects, the @name pointer should point to this. If a name is
* required but @name is NULL, then TPM2_ReadPublic() will be called
* on the handle to obtain the 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.
*/
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
u32 handle, u8 *name)
{
enum tpm2_mso_type mso = tpm2_handle_mso(handle);
struct tpm2_auth *auth = chip->auth;
int slot;
slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE)/4;
if (slot >= AUTH_MAX_NAMES) {
dev_err(&chip->dev, "TPM: too many handles\n");
return;
}
WARN(auth->session != tpm_buf_length(buf),
"name added in wrong place\n");
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]);
} else {
if (name)
dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
}
auth->name_h[slot] = handle;
if (name)
memcpy(auth->name[slot], name, name_size(name));
}
EXPORT_SYMBOL(tpm_buf_append_name);
/** /**
* tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness * tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness
* @chip: the TPM chip structure * @chip: the TPM chip structure
...@@ -705,6 +752,9 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, ...@@ -705,6 +752,9 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
u32 cc = be32_to_cpu(auth->ordinal); u32 cc = be32_to_cpu(auth->ordinal);
int parm_len, len, i, handles; int parm_len, len, i, handles;
if (!auth)
return rc;
if (auth->session >= TPM_HEADER_SIZE) { if (auth->session >= TPM_HEADER_SIZE) {
WARN(1, "tpm session not filled correctly\n"); WARN(1, "tpm session not filled correctly\n");
goto out; goto out;
...@@ -824,8 +874,13 @@ EXPORT_SYMBOL(tpm_buf_check_hmac_response); ...@@ -824,8 +874,13 @@ EXPORT_SYMBOL(tpm_buf_check_hmac_response);
*/ */
void tpm2_end_auth_session(struct tpm_chip *chip) void tpm2_end_auth_session(struct tpm_chip *chip)
{ {
tpm2_flush_context(chip, chip->auth->handle); struct tpm2_auth *auth = chip->auth;
memzero_explicit(chip->auth, sizeof(*chip->auth));
if (!auth)
return;
tpm2_flush_context(chip, auth->handle);
memzero_explicit(auth, sizeof(*auth));
} }
EXPORT_SYMBOL(tpm2_end_auth_session); EXPORT_SYMBOL(tpm2_end_auth_session);
...@@ -907,6 +962,11 @@ int tpm2_start_auth_session(struct tpm_chip *chip) ...@@ -907,6 +962,11 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
int rc; int rc;
u32 null_key; u32 null_key;
if (!auth) {
dev_warn_once(&chip->dev, "auth session is not active\n");
return 0;
}
rc = tpm2_load_null(chip, &null_key); rc = tpm2_load_null(chip, &null_key);
if (rc) if (rc)
goto out; goto out;
...@@ -1301,3 +1361,4 @@ int tpm2_sessions_init(struct tpm_chip *chip) ...@@ -1301,3 +1361,4 @@ int tpm2_sessions_init(struct tpm_chip *chip)
return rc; return rc;
} }
#endif /* CONFIG_TCG_TPM2_HMAC */
...@@ -490,9 +490,16 @@ static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle) ...@@ -490,9 +490,16 @@ static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
{ {
} }
#endif #endif
static inline struct tpm2_auth *tpm2_chip_auth(struct tpm_chip *chip)
{
#ifdef CONFIG_TCG_TPM2_HMAC #ifdef CONFIG_TCG_TPM2_HMAC
return chip->auth;
#else
return NULL;
#endif
}
int tpm2_start_auth_session(struct tpm_chip *chip);
void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
u32 handle, u8 *name); u32 handle, u8 *name);
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
...@@ -504,9 +511,27 @@ static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip, ...@@ -504,9 +511,27 @@ static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
u8 *passphrase, u8 *passphrase,
int passphraselen) int passphraselen)
{ {
tpm_buf_append_hmac_session(chip, buf, attributes, passphrase, struct tpm_header *head;
passphraselen); 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);
}
} }
#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); void 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 tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
int rc); int rc);
...@@ -521,56 +546,6 @@ static inline int tpm2_start_auth_session(struct tpm_chip *chip) ...@@ -521,56 +546,6 @@ 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 tpm2_end_auth_session(struct tpm_chip *chip)
{ {
} }
static inline void tpm_buf_append_name(struct tpm_chip *chip,
struct tpm_buf *buf,
u32 handle, u8 *name)
{
tpm_buf_append_u32(buf, handle);
/* count the number of handles in the upper bits of flags */
buf->handles++;
}
static inline void tpm_buf_append_hmac_session(struct tpm_chip *chip,
struct tpm_buf *buf,
u8 attributes, u8 *passphrase,
int passphraselen)
{
/* offset tells us where the sessions area begins */
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
u32 len = 9 + passphraselen;
if (tpm_buf_length(buf) != offset) {
/* not the first session so update the existing length */
len += get_unaligned_be32(&buf->data[offset]);
put_unaligned_be32(len, &buf->data[offset]);
} else {
tpm_buf_append_u32(buf, len);
}
/* auth handle */
tpm_buf_append_u32(buf, TPM2_RS_PW);
/* nonce */
tpm_buf_append_u16(buf, 0);
/* attributes */
tpm_buf_append_u8(buf, 0);
/* passphrase */
tpm_buf_append_u16(buf, passphraselen);
tpm_buf_append(buf, passphrase, passphraselen);
}
static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
struct tpm_buf *buf,
u8 attributes,
u8 *passphrase,
int passphraselen)
{
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
struct tpm_header *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);
}
static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip, static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip,
struct tpm_buf *buf) struct tpm_buf *buf)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment