Skip to content

Commit e1b72e1

Browse files
committed
tpm: Store the length of the tpm_buf data separately.
TPM2B buffers, or sized buffers, have a two byte header, which contains the length of the payload as a 16-bit big-endian number, without counting in the space taken by the header. This differs from encoding in the TPM header where the length includes also the bytes taken by the header. Unbound the length of a tpm_buf from the value stored to the TPM command header. A separate encoding and decoding step so that different buffer types can be supported, with variant header format and length encoding. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Tested-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
1 parent 37e2ee1 commit e1b72e1

5 files changed

Lines changed: 47 additions & 20 deletions

File tree

drivers/char/tpm/tpm-buf.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,44 @@
33
* Handling of TPM command and other buffers.
44
*/
55

6+
#include <linux/tpm_command.h>
67
#include <linux/module.h>
78
#include <linux/tpm.h>
89

10+
/**
11+
* tpm_buf_init() - Allocate and initialize a TPM command
12+
* @buf: A &tpm_buf
13+
* @tag: TPM_TAG_RQU_COMMAND, TPM2_ST_NO_SESSIONS or TPM2_ST_SESSIONS
14+
* @ordinal: A command ordinal
15+
*
16+
* Return: 0 or -ENOMEM
17+
*/
918
int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
1019
{
1120
buf->data = (u8 *)__get_free_page(GFP_KERNEL);
1221
if (!buf->data)
1322
return -ENOMEM;
1423

15-
buf->flags = 0;
1624
tpm_buf_reset(buf, tag, ordinal);
1725
return 0;
1826
}
1927
EXPORT_SYMBOL_GPL(tpm_buf_init);
2028

29+
/**
30+
* tpm_buf_reset() - Initialize a TPM command
31+
* @buf: A &tpm_buf
32+
* @tag: TPM_TAG_RQU_COMMAND, TPM2_ST_NO_SESSIONS or TPM2_ST_SESSIONS
33+
* @ordinal: A command ordinal
34+
*/
2135
void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal)
2236
{
2337
struct tpm_header *head = (struct tpm_header *)buf->data;
2438

39+
WARN_ON(tag != TPM_TAG_RQU_COMMAND && tag != TPM2_ST_NO_SESSIONS &&
40+
tag != TPM2_ST_SESSIONS && tag != 0);
41+
42+
buf->flags = 0;
43+
buf->length = sizeof(*head);
2544
head->tag = cpu_to_be16(tag);
2645
head->length = cpu_to_be32(sizeof(*head));
2746
head->ordinal = cpu_to_be32(ordinal);
@@ -34,33 +53,41 @@ void tpm_buf_destroy(struct tpm_buf *buf)
3453
}
3554
EXPORT_SYMBOL_GPL(tpm_buf_destroy);
3655

56+
/**
57+
* tpm_buf_length() - Return the number of bytes consumed by the data
58+
* @buf: A &tpm_buf
59+
*
60+
* Return: The number of bytes consumed by the buffer
61+
*/
3762
u32 tpm_buf_length(struct tpm_buf *buf)
3863
{
39-
struct tpm_header *head = (struct tpm_header *)buf->data;
40-
41-
return be32_to_cpu(head->length);
64+
return buf->length;
4265
}
4366
EXPORT_SYMBOL_GPL(tpm_buf_length);
4467

45-
void tpm_buf_append(struct tpm_buf *buf,
46-
const unsigned char *new_data,
47-
unsigned int new_len)
68+
/**
69+
* tpm_buf_append() - Append data to an initialized buffer
70+
* @buf: A &tpm_buf
71+
* @new_data: A data blob
72+
* @new_length: Size of the appended data
73+
*/
74+
void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length)
4875
{
4976
struct tpm_header *head = (struct tpm_header *)buf->data;
50-
u32 len = tpm_buf_length(buf);
5177

5278
/* Return silently if overflow has already happened. */
5379
if (buf->flags & TPM_BUF_OVERFLOW)
5480
return;
5581

56-
if ((len + new_len) > PAGE_SIZE) {
82+
if ((buf->length + new_length) > PAGE_SIZE) {
5783
WARN(1, "tpm_buf: overflow\n");
5884
buf->flags |= TPM_BUF_OVERFLOW;
5985
return;
6086
}
6187

62-
memcpy(&buf->data[len], new_data, new_len);
63-
head->length = cpu_to_be32(len + new_len);
88+
memcpy(&buf->data[buf->length], new_data, new_length);
89+
buf->length += new_length;
90+
head->length = cpu_to_be32(buf->length);
6491
}
6592
EXPORT_SYMBOL_GPL(tpm_buf_append);
6693

drivers/char/tpm/tpm-interface.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
232232
if (len < min_rsp_body_length + TPM_HEADER_SIZE)
233233
return -EFAULT;
234234

235+
buf->length = len;
235236
return 0;
236237
}
237238
EXPORT_SYMBOL_GPL(tpm_transmit_cmd);

include/keys/trusted_tpm.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include <linux/tpm_command.h>
77

88
/* implementation specific TPM constants */
9-
#define MAX_BUF_SIZE 1024
10-
#define TPM_GETRANDOM_SIZE 14
119
#define TPM_SIZE_OFFSET 2
1210
#define TPM_RETURN_OFFSET 6
1311
#define TPM_DATA_OFFSET 10

include/linux/tpm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ enum tpm_buf_flags {
306306
* A string buffer type for constructing TPM commands.
307307
*/
308308
struct tpm_buf {
309-
unsigned int flags;
309+
u32 flags;
310+
u32 length;
310311
u8 *data;
311312
};
312313

@@ -329,8 +330,7 @@ int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal);
329330
void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
330331
void tpm_buf_destroy(struct tpm_buf *buf);
331332
u32 tpm_buf_length(struct tpm_buf *buf);
332-
void tpm_buf_append(struct tpm_buf *buf, const unsigned char *new_data,
333-
unsigned int new_len);
333+
void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length);
334334
void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value);
335335
void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value);
336336
void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value);

security/keys/trusted-keys/trusted_tpm1.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ int trusted_tpm_send(unsigned char *cmd, size_t buflen)
367367
return rc;
368368

369369
buf.flags = 0;
370+
buf.length = buflen;
370371
buf.data = cmd;
371372
dump_tpm_buf(cmd);
372373
rc = tpm_transmit_cmd(chip, &buf, 4, "sending data");
@@ -417,7 +418,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
417418
tpm_buf_append_u32(tb, handle);
418419
tpm_buf_append(tb, ononce, TPM_NONCE_SIZE);
419420

420-
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
421+
ret = trusted_tpm_send(tb->data, tb->length);
421422
if (ret < 0)
422423
return ret;
423424

@@ -441,7 +442,7 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
441442
return -ENODEV;
442443

443444
tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
444-
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
445+
ret = trusted_tpm_send(tb->data, tb->length);
445446
if (ret < 0)
446447
return ret;
447448

@@ -553,7 +554,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
553554
tpm_buf_append_u8(tb, cont);
554555
tpm_buf_append(tb, td->pubauth, SHA1_DIGEST_SIZE);
555556

556-
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
557+
ret = trusted_tpm_send(tb->data, tb->length);
557558
if (ret < 0)
558559
goto out;
559560

@@ -644,7 +645,7 @@ static int tpm_unseal(struct tpm_buf *tb,
644645
tpm_buf_append_u8(tb, cont);
645646
tpm_buf_append(tb, authdata2, SHA1_DIGEST_SIZE);
646647

647-
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
648+
ret = trusted_tpm_send(tb->data, tb->length);
648649
if (ret < 0) {
649650
pr_info("authhmac failed (%d)\n", ret);
650651
return ret;

0 commit comments

Comments
 (0)