Commit ce63c05b authored by Jarkko Sakkinen's avatar Jarkko Sakkinen

tpm: migrate tpm2_get_random() to use struct tpm_buf

In order to make struct tpm_buf the first class object for constructing
TPM commands, migrate tpm2_get_random() to use it. In addition, removed
remaining references to struct tpm2_cmd. All of them use it to acquire
the length of the response, which can be achieved by using
tpm_buf_length().
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Nayna Jain<nayna@linux.vnet.ibm.com>
parent 2ab32411
...@@ -424,23 +424,24 @@ struct tpm_buf { ...@@ -424,23 +424,24 @@ struct tpm_buf {
u8 *data; u8 *data;
}; };
static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal) static inline void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal)
{ {
struct tpm_input_header *head; struct tpm_input_header *head;
head = (struct tpm_input_header *)buf->data;
head->tag = cpu_to_be16(tag);
head->length = cpu_to_be32(sizeof(*head));
head->ordinal = cpu_to_be32(ordinal);
}
static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
{
buf->data_page = alloc_page(GFP_HIGHUSER); buf->data_page = alloc_page(GFP_HIGHUSER);
if (!buf->data_page) if (!buf->data_page)
return -ENOMEM; return -ENOMEM;
buf->flags = 0; buf->flags = 0;
buf->data = kmap(buf->data_page); buf->data = kmap(buf->data_page);
tpm_buf_reset(buf, tag, ordinal);
head = (struct tpm_input_header *) buf->data;
head->tag = cpu_to_be16(tag);
head->length = cpu_to_be32(sizeof(*head));
head->ordinal = cpu_to_be32(ordinal);
return 0; return 0;
} }
...@@ -569,7 +570,7 @@ static inline u32 tpm2_rc_value(u32 rc) ...@@ -569,7 +570,7 @@ static inline u32 tpm2_rc_value(u32 rc)
int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count, int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
struct tpm2_digest *digests); struct tpm2_digest *digests);
int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max); int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max);
void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
unsigned int flags); unsigned int flags);
int tpm2_seal_trusted(struct tpm_chip *chip, int tpm2_seal_trusted(struct tpm_chip *chip,
......
...@@ -27,25 +27,6 @@ enum tpm2_session_attributes { ...@@ -27,25 +27,6 @@ enum tpm2_session_attributes {
TPM2_SA_CONTINUE_SESSION = BIT(0), TPM2_SA_CONTINUE_SESSION = BIT(0),
}; };
struct tpm2_get_random_in {
__be16 size;
} __packed;
struct tpm2_get_random_out {
__be16 size;
u8 buffer[TPM_MAX_RNG_DATA];
} __packed;
union tpm2_cmd_params {
struct tpm2_get_random_in getrandom_in;
struct tpm2_get_random_out getrandom_out;
};
struct tpm2_cmd {
tpm_cmd_header header;
union tpm2_cmd_params params;
} __packed;
struct tpm2_hash { struct tpm2_hash {
unsigned int crypto_id; unsigned int crypto_id;
unsigned int tpm_id; unsigned int tpm_id;
...@@ -300,67 +281,70 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count, ...@@ -300,67 +281,70 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
} }
#define TPM2_GETRANDOM_IN_SIZE \ struct tpm2_get_random_out {
(sizeof(struct tpm_input_header) + \ __be16 size;
sizeof(struct tpm2_get_random_in)) u8 buffer[TPM_MAX_RNG_DATA];
} __packed;
static const struct tpm_input_header tpm2_getrandom_header = {
.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
.length = cpu_to_be32(TPM2_GETRANDOM_IN_SIZE),
.ordinal = cpu_to_be32(TPM2_CC_GET_RANDOM)
};
/** /**
* tpm2_get_random() - get random bytes from the TPM RNG * tpm2_get_random() - get random bytes from the TPM RNG
* *
* @chip: TPM chip to use * @chip: a &tpm_chip instance
* @out: destination buffer for the random bytes * @dest: destination buffer
* @max: the max number of bytes to write to @out * @max: the max number of random bytes to pull
* *
* Return: * Return:
* Size of the output buffer, or -EIO on error. * size of the buffer on success,
* -errno otherwise
*/ */
int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max) int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
{ {
struct tpm2_cmd cmd; struct tpm2_get_random_out *out;
u32 recd, rlength; struct tpm_buf buf;
u32 num_bytes; u32 recd;
u32 num_bytes = max;
int err; int err;
int total = 0; int total = 0;
int retries = 5; int retries = 5;
u8 *dest = out; u8 *dest_ptr = dest;
num_bytes = min_t(u32, max, sizeof(cmd.params.getrandom_out.buffer)); if (!num_bytes || max > TPM_MAX_RNG_DATA)
if (!out || !num_bytes ||
max > sizeof(cmd.params.getrandom_out.buffer))
return -EINVAL; return -EINVAL;
do { err = tpm_buf_init(&buf, 0, 0);
cmd.header.in = tpm2_getrandom_header; if (err)
cmd.params.getrandom_in.size = cpu_to_be16(num_bytes); return err;
err = tpm_transmit_cmd(chip, NULL, &cmd, sizeof(cmd), do {
tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM);
tpm_buf_append_u16(&buf, num_bytes);
err = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
offsetof(struct tpm2_get_random_out, offsetof(struct tpm2_get_random_out,
buffer), buffer),
0, "attempting get random"); 0, "attempting get random");
if (err) if (err)
break; goto out;
recd = min_t(u32, be16_to_cpu(cmd.params.getrandom_out.size), out = (struct tpm2_get_random_out *)
num_bytes); &buf.data[TPM_HEADER_SIZE];
rlength = be32_to_cpu(cmd.header.out.length); recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
if (rlength < offsetof(struct tpm2_get_random_out, buffer) + if (tpm_buf_length(&buf) <
recd) offsetof(struct tpm2_get_random_out, buffer) + recd) {
return -EFAULT; err = -EFAULT;
memcpy(dest, cmd.params.getrandom_out.buffer, recd); goto out;
}
memcpy(dest_ptr, out->buffer, recd);
dest += recd; dest_ptr += recd;
total += recd; total += recd;
num_bytes -= recd; num_bytes -= recd;
} while (retries-- && total < max); } while (retries-- && total < max);
tpm_buf_destroy(&buf);
return total ? total : -EIO; return total ? total : -EIO;
out:
tpm_buf_destroy(&buf);
return err;
} }
/** /**
...@@ -437,7 +421,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, ...@@ -437,7 +421,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
{ {
unsigned int blob_len; unsigned int blob_len;
struct tpm_buf buf; struct tpm_buf buf;
u32 hash, rlength; u32 hash;
int i; int i;
int rc; int rc;
...@@ -512,8 +496,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, ...@@ -512,8 +496,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
rc = -E2BIG; rc = -E2BIG;
goto out; goto out;
} }
rlength = be32_to_cpu(((struct tpm2_cmd *)&buf)->header.out.length); if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) {
if (rlength < TPM_HEADER_SIZE + 4 + blob_len) {
rc = -EFAULT; rc = -EFAULT;
goto out; goto out;
} }
...@@ -623,7 +606,6 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, ...@@ -623,7 +606,6 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
u16 data_len; u16 data_len;
u8 *data; u8 *data;
int rc; int rc;
u32 rlength;
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL); rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
if (rc) if (rc)
...@@ -651,9 +633,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, ...@@ -651,9 +633,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
goto out; goto out;
} }
rlength = be32_to_cpu(((struct tpm2_cmd *)&buf) if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) {
->header.out.length);
if (rlength < TPM_HEADER_SIZE + 6 + data_len) {
rc = -EFAULT; rc = -EFAULT;
goto out; goto out;
} }
......
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