1. Use tpm_buf in tpm1_get_random()
2. Fix comment in tpm_get_random() so it is clear that
the function is expected to return number of random bytes.

Signed-off-by: Tomas Winkler <tomas.wink...@intel.com>
---
V3: new in the series
 drivers/char/tpm/tpm-interface.c |  2 +-
 drivers/char/tpm/tpm.h           | 11 ------
 drivers/char/tpm/tpm1-cmd.c      | 85 +++++++++++++++++++++++-----------------
 3 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 358ef5bd601e..e3206874be22 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -576,7 +576,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  * @out:       destination buffer for the random bytes
  * @max:       the max number of bytes to write to @out
  *
- * Return: same as with tpm_transmit_cmd()
+ * Return: number of random bytes read or a negative error value.
  */
 int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
 {
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 4ccffbb56864..d6eca81a011a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -396,20 +396,9 @@ struct tpm_pcrread_in {
  * compiler warnings about stack frame size. */
 #define TPM_MAX_RNG_DATA       128
 
-struct tpm_getrandom_out {
-       __be32 rng_data_len;
-       u8     rng_data[TPM_MAX_RNG_DATA];
-} __packed;
-
-struct tpm_getrandom_in {
-       __be32 num_bytes;
-} __packed;
-
 typedef union {
        struct  tpm_pcrread_in  pcrread_in;
        struct  tpm_pcrread_out pcrread_out;
-       struct  tpm_getrandom_in getrandom_in;
-       struct  tpm_getrandom_out getrandom_out;
 } tpm_cmd_params;
 
 struct tpm_cmd_t {
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 90e5bc1720ad..5708d4bf908f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -507,58 +507,71 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, 
cap_t *cap,
 EXPORT_SYMBOL_GPL(tpm1_getcap);
 
 #define TPM_ORD_GET_RANDOM 70
-#define TPM_GETRANDOM_RESULT_SIZE      18
-static const struct tpm_input_header tpm_getrandom_header = {
-       .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
-       .length = cpu_to_be32(14),
-       .ordinal = cpu_to_be32(TPM_ORD_GET_RANDOM)
-};
+struct tpm1_get_random_out {
+       __be32 rng_data_len;
+       u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;
 
-int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+/**
+ * tpm1_get_random() - get random bytes from the TPM's RNG
+ *
+ * @chip:      a &struct tpm_chip instance
+ * @dest:      destination buffer for the random bytes
+ * @max:       the maximum number of bytes to write to @dest
+ *
+ * Return:
+ *   number of bytes read
+ *   -errno or a TPM return code otherwise
+ */
+int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 {
-       struct tpm_cmd_t tpm_cmd;
+       struct tpm1_get_random_out *out;
+       u32 num_bytes =  min_t(u32, max, TPM_MAX_RNG_DATA);
+       struct tpm_buf buf;
+       u32 total = 0;
+       int retries = 5;
        u32 recd;
-       u32 num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
-       u32 rlength;
-       int err, total = 0, retries = 5;
-       u8 *dest = out;
+       int rc;
 
-       if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
-               return -EINVAL;
+       rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+       if (rc)
+               return rc;
 
        do {
-               tpm_cmd.header.in = tpm_getrandom_header;
-               tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
-
-               err = tpm_transmit_cmd(chip, NULL, &tpm_cmd,
-                                      TPM_GETRANDOM_RESULT_SIZE + num_bytes,
-                                      offsetof(struct tpm_getrandom_out,
-                                               rng_data),
-                                      0, "attempting get random");
-               if (err)
-                       break;
+               tpm_buf_append_u32(&buf, num_bytes);
+
+               rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+                                     sizeof(out->rng_data_len), 0,
+                                     "attempting get random");
+               if (rc)
+                       goto out;
 
-               recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+               out = (struct tpm1_get_random_out *)&buf.data[TPM_HEADER_SIZE];
+
+               recd = be32_to_cpu(out->rng_data_len);
                if (recd > num_bytes) {
-                       total = -EFAULT;
-                       break;
+                       rc = -EFAULT;
+                       goto out;
                }
 
-               rlength = be32_to_cpu(tpm_cmd.header.out.length);
-               if (rlength < TPM_HEADER_SIZE +
-                             offsetof(struct tpm_getrandom_out, rng_data) +
-                             recd) {
-                       total = -EFAULT;
-                       break;
+               if (tpm_buf_length(&buf) < TPM_HEADER_SIZE +
+                                          sizeof(out->rng_data_len) + recd) {
+                       rc = -EFAULT;
+                       goto out;
                }
-               memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
+               memcpy(dest, out->rng_data, recd);
 
                dest += recd;
                total += recd;
                num_bytes -= recd;
-       } while (retries-- && (size_t)total < max);
 
-       return total ? total : -EIO;
+               tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+       } while (retries-- && total < max);
+
+       rc = total ? total : -EIO;
+out:
+       tpm_buf_destroy(&buf);
+       return rc;
 }
 
 #define TPM_ORDINAL_PCRREAD 21
-- 
2.14.4

Reply via email to