[PATCH v5 16/21] tpm: tpm1: rewrite tpm1_get_random() using tpm_buf structure

2018-09-28 Thread Tomas Winkler
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 
Reviewed-by: Jarkko Sakkinen 
Tested-by: Jarkko Sakkinen 
---
V3: New in the series.
V4: Resend.
V5: A small adjustment in the kdoc.

 drivers/char/tpm/tpm-interface.c |  2 +-
 drivers/char/tpm/tpm.h   | 11 --
 drivers/char/tpm/tpm1-cmd.c  | 84 +++-
 3 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 98f9a0bbeed9..0af71d53d129 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -586,7 +586,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 8a84db315676..b5c4fa158c30 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -505,58 +505,70 @@ 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  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(, 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, _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(, 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 *)[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, 

[PATCH v5 16/21] tpm: tpm1: rewrite tpm1_get_random() using tpm_buf structure

2018-09-28 Thread Tomas Winkler
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 
Reviewed-by: Jarkko Sakkinen 
Tested-by: Jarkko Sakkinen 
---
V3: New in the series.
V4: Resend.
V5: A small adjustment in the kdoc.

 drivers/char/tpm/tpm-interface.c |  2 +-
 drivers/char/tpm/tpm.h   | 11 --
 drivers/char/tpm/tpm1-cmd.c  | 84 +++-
 3 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 98f9a0bbeed9..0af71d53d129 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -586,7 +586,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 8a84db315676..b5c4fa158c30 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -505,58 +505,70 @@ 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  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(, 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, _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(, 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 *)[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,