* [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it
@ 2012-06-07 18:42 Kent Yoder
2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Kent Yoder @ 2012-06-07 18:42 UTC (permalink / raw)
To: linux-kernel; +Cc: tpmdd-devel, m.selhorst, safford, key
These patches move the tpm_get_random API out of the trusted keys code
and into the tpm device driver itself. Then a hwrng driver is added that
makes use of the API to provide a H/W RNG source.
These are based off the latest upstream kernel.
Thanks,
Kent
Kent Yoder (2):
tpm: Move tpm_get_random api into the TPM device driver
hw_random: add support for the TPM chip as a hardware RNG source
drivers/char/hw_random/Kconfig | 13 +++++++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/tpm-rng.c | 55 ++++++++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm.c | 53 ++++++++++++++++++++++++++++++++----
drivers/char/tpm/tpm.h | 23 ++++++++++++++++
include/linux/tpm.h | 4 +++
security/keys/trusted.c | 47 +++++++-------------------------
7 files changed, 153 insertions(+), 43 deletions(-)
create mode 100644 drivers/char/hw_random/tpm-rng.c
--
1.7.5.4
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-06-07 18:42 [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it Kent Yoder @ 2012-06-07 18:47 ` Kent Yoder 2012-06-08 19:13 ` David Safford ` (2 more replies) 2012-06-07 18:47 ` [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source Kent Yoder 2012-06-08 19:13 ` [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it David Safford 2 siblings, 3 replies; 13+ messages in thread From: Kent Yoder @ 2012-06-07 18:47 UTC (permalink / raw) To: linux-kernel; +Cc: tpmdd-devel, m.selhorst, safford, key Move the tpm_get_random api from the trusted keys code into the TPM device driver itself so that other callers can make use of it. Also, change the api slightly so that the number of bytes read is returned in the call, since the TPM command can potentially return fewer bytes than requested. Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> --- drivers/char/tpm/tpm.c | 53 +++++++++++++++++++++++++++++++++++++++++----- drivers/char/tpm/tpm.h | 23 ++++++++++++++++++++ include/linux/tpm.h | 4 +++ security/keys/trusted.c | 47 ++++++++-------------------------------- 4 files changed, 84 insertions(+), 43 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ad7c732..8c74b24 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -31,12 +31,6 @@ #include "tpm.h" -enum tpm_const { - TPM_MINOR = 224, /* officially assigned */ - TPM_BUFSIZE = 4096, - TPM_NUM_DEVICES = 256, -}; - enum tpm_duration { TPM_SHORT = 0, TPM_MEDIUM = 1, @@ -482,6 +476,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, #define TPM_INTERNAL_RESULT_SIZE 200 #define TPM_TAG_RQU_COMMAND cpu_to_be16(193) #define TPM_ORD_GET_CAP cpu_to_be32(101) +#define TPM_ORD_GET_RANDOM cpu_to_be32(70) static const struct tpm_input_header tpm_getcap_header = { .tag = TPM_TAG_RQU_COMMAND, @@ -1318,6 +1313,52 @@ int tpm_pm_resume(struct device *dev) } EXPORT_SYMBOL_GPL(tpm_pm_resume); +#define TPM_GETRANDOM_RESULT_SIZE 18 +static struct tpm_input_header tpm_getrandom_header = { + .tag = TPM_TAG_RQU_COMMAND, + .length = cpu_to_be32(14), + .ordinal = TPM_ORD_GET_RANDOM +}; + +/** + * tpm_get_random() - Get random bytes from the tpm's RNG + * @chip_num: A specific chip number for the request or TPM_ANY_NUM + * @out: destination buffer for the random bytes + * @max: on input, the max number of bytes to write to @out, on output + * this is set to the actual number of bytes written to @out + * + * Note that @max will be capped at TPM_MAX_RNG_DATA bytes. + */ +int tpm_get_random(u32 chip_num, u8 *out, size_t *max) +{ + struct tpm_chip *chip; + struct tpm_cmd_t tpm_cmd; + u32 num_bytes = min_t(u32, *max, TPM_MAX_RNG_DATA); + int err; + + chip = tpm_chip_find_get(chip_num); + if (chip == NULL) + return -ENODEV; + + if (!num_bytes) + return -EINVAL; + + tpm_cmd.header.in = tpm_getrandom_header; + tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); + + err = transmit_cmd(chip, &tpm_cmd, + TPM_GETRANDOM_RESULT_SIZE + num_bytes, + "attempting get random"); + if (err) + goto out; + + *max = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); + memcpy(out, tpm_cmd.params.getrandom_out.rng_data, *max); +out: + return err; +} +EXPORT_SYMBOL_GPL(tpm_get_random); + /* In case vendor provided release function, call it too.*/ void tpm_dev_vendor_release(struct tpm_chip *chip) diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b1c5280..610fe42 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -28,6 +28,12 @@ #include <linux/io.h> #include <linux/tpm.h> +enum tpm_const { + TPM_MINOR = 224, /* officially assigned */ + TPM_BUFSIZE = 4096, + TPM_NUM_DEVICES = 256, +}; + enum tpm_timeout { TPM_TIMEOUT = 5, /* msecs */ }; @@ -269,6 +275,21 @@ struct tpm_pcrextend_in { u8 hash[TPM_DIGEST_SIZE]; }__attribute__((packed)); +/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18 + * bytes, but 128 is still a relatively large number of random bytes and + * anything much bigger causes users of struct tpm_cmd_t to start getting + * 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]; +}__attribute__((packed)); + +struct tpm_getrandom_in { + __be32 num_bytes; +}__attribute__((packed)); + typedef union { struct tpm_getcap_params_out getcap_out; struct tpm_readpubek_params_out readpubek_out; @@ -277,6 +298,8 @@ typedef union { struct tpm_pcrread_in pcrread_in; struct tpm_pcrread_out pcrread_out; struct tpm_pcrextend_in pcrextend_in; + struct tpm_getrandom_in getrandom_in; + struct tpm_getrandom_out getrandom_out; } tpm_cmd_params; struct tpm_cmd_t { diff --git a/include/linux/tpm.h b/include/linux/tpm.h index fdc718a..d5b2f2d 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -32,6 +32,7 @@ extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); extern int tpm_send(u32 chip_num, void *cmd, size_t buflen); +extern int tpm_get_random(u32 chip_num, u8 *data, size_t *max); #else static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { return -ENODEV; @@ -42,5 +43,8 @@ static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) { return -ENODEV; } +static inline int tpm_get_random(u32 chip_num, u8 *data, size_t *max) { + return -ENODEV; +} #endif #endif diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 2d5d041..48a9eabc 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -369,38 +369,6 @@ static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd, } /* - * get a random value from TPM - */ -static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len) -{ - int ret; - - INIT_BUF(tb); - store16(tb, TPM_TAG_RQU_COMMAND); - store32(tb, TPM_GETRANDOM_SIZE); - store32(tb, TPM_ORD_GETRANDOM); - store32(tb, len); - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data); - if (!ret) - memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len); - return ret; -} - -static int my_get_random(unsigned char *buf, int len) -{ - struct tpm_buf *tb; - int ret; - - tb = kmalloc(sizeof *tb, GFP_KERNEL); - if (!tb) - return -ENOMEM; - ret = tpm_get_random(tb, buf, len); - - kfree(tb); - return ret; -} - -/* * Lock a trusted key, by extending a selected PCR. * * Prevents a trusted key that is sealed to PCRs from being accessed. @@ -409,11 +377,12 @@ static int my_get_random(unsigned char *buf, int len) static int pcrlock(const int pcrnum) { unsigned char hash[SHA1_DIGEST_SIZE]; + size_t digest_size = SHA1_DIGEST_SIZE; int ret; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - ret = my_get_random(hash, SHA1_DIGEST_SIZE); + ret = tpm_get_random(TPM_ANY_NUM, hash, &digest_size); if (ret < 0) return ret; return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; @@ -427,9 +396,10 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, { unsigned char enonce[TPM_NONCE_SIZE]; unsigned char ononce[TPM_NONCE_SIZE]; + size_t nonce_size = TPM_NONCE_SIZE; int ret; - ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE); + ret = tpm_get_random(TPM_ANY_NUM, ononce, &nonce_size); if (ret < 0) return ret; @@ -500,6 +470,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, uint32_t ordinal; uint32_t pcrsize; uint32_t datsize; + size_t nonce_size = TPM_NONCE_SIZE; int sealinfosize; int encdatasize; int storedsize; @@ -524,7 +495,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, if (ret < 0) goto out; - ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE); + ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, &nonce_size); if (ret < 0) goto out; ordinal = htonl(TPM_ORD_SEAL); @@ -618,6 +589,7 @@ static int tpm_unseal(struct tpm_buf *tb, unsigned char cont = 0; uint32_t ordinal; uint32_t keyhndl; + size_t nonce_size = TPM_NONCE_SIZE; int ret; /* sessions for unsealing key and data */ @@ -634,7 +606,7 @@ static int tpm_unseal(struct tpm_buf *tb, ordinal = htonl(TPM_ORD_UNSEAL); keyhndl = htonl(SRKHANDLE); - ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE); + ret = tpm_get_random(TPM_ANY_NUM, nonceodd, &nonce_size); if (ret < 0) { pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); return ret; @@ -974,7 +946,8 @@ static int trusted_instantiate(struct key *key, const void *data, pr_info("trusted_key: key_unseal failed (%d)\n", ret); break; case Opt_new: - ret = my_get_random(payload->key, payload->key_len); + ret = tpm_get_random(TPM_ANY_NUM, payload->key, + &payload->key_len); if (ret < 0) { pr_info("trusted_key: key_create failed (%d)\n", ret); goto out; -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder @ 2012-06-08 19:13 ` David Safford 2012-07-26 22:12 ` H. Peter Anvin 2012-07-27 0:10 ` H. Peter Anvin 2 siblings, 0 replies; 13+ messages in thread From: David Safford @ 2012-06-08 19:13 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, David Safford On Thu, 2012-06-07 at 13:47 -0500, Kent Yoder wrote: > Move the tpm_get_random api from the trusted keys code into the TPM > device driver itself so that other callers can make use of it. Also, > change the api slightly so that the number of bytes read is returned in > the call, since the TPM command can potentially return fewer bytes than > requested. > > Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> checkpatch had minor complaints, but otherwise, Acked-by: David Safford <safford@linux.vnet.ibm.com> > --- > drivers/char/tpm/tpm.c | 53 +++++++++++++++++++++++++++++++++++++++++----- > drivers/char/tpm/tpm.h | 23 ++++++++++++++++++++ > include/linux/tpm.h | 4 +++ > security/keys/trusted.c | 47 ++++++++-------------------------------- > 4 files changed, 84 insertions(+), 43 deletions(-) > > diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c > index ad7c732..8c74b24 100644 > --- a/drivers/char/tpm/tpm.c > +++ b/drivers/char/tpm/tpm.c > @@ -31,12 +31,6 @@ > > #include "tpm.h" > > -enum tpm_const { > - TPM_MINOR = 224, /* officially assigned */ > - TPM_BUFSIZE = 4096, > - TPM_NUM_DEVICES = 256, > -}; > - > enum tpm_duration { > TPM_SHORT = 0, > TPM_MEDIUM = 1, > @@ -482,6 +476,7 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, > #define TPM_INTERNAL_RESULT_SIZE 200 > #define TPM_TAG_RQU_COMMAND cpu_to_be16(193) > #define TPM_ORD_GET_CAP cpu_to_be32(101) > +#define TPM_ORD_GET_RANDOM cpu_to_be32(70) > > static const struct tpm_input_header tpm_getcap_header = { > .tag = TPM_TAG_RQU_COMMAND, > @@ -1318,6 +1313,52 @@ int tpm_pm_resume(struct device *dev) > } > EXPORT_SYMBOL_GPL(tpm_pm_resume); > > +#define TPM_GETRANDOM_RESULT_SIZE 18 > +static struct tpm_input_header tpm_getrandom_header = { > + .tag = TPM_TAG_RQU_COMMAND, > + .length = cpu_to_be32(14), > + .ordinal = TPM_ORD_GET_RANDOM > +}; > + > +/** > + * tpm_get_random() - Get random bytes from the tpm's RNG > + * @chip_num: A specific chip number for the request or TPM_ANY_NUM > + * @out: destination buffer for the random bytes > + * @max: on input, the max number of bytes to write to @out, on output > + * this is set to the actual number of bytes written to @out > + * > + * Note that @max will be capped at TPM_MAX_RNG_DATA bytes. > + */ > +int tpm_get_random(u32 chip_num, u8 *out, size_t *max) > +{ > + struct tpm_chip *chip; > + struct tpm_cmd_t tpm_cmd; > + u32 num_bytes = min_t(u32, *max, TPM_MAX_RNG_DATA); > + int err; > + > + chip = tpm_chip_find_get(chip_num); > + if (chip == NULL) > + return -ENODEV; > + > + if (!num_bytes) > + return -EINVAL; > + > + tpm_cmd.header.in = tpm_getrandom_header; > + tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); > + > + err = transmit_cmd(chip, &tpm_cmd, > + TPM_GETRANDOM_RESULT_SIZE + num_bytes, > + "attempting get random"); > + if (err) > + goto out; > + > + *max = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); > + memcpy(out, tpm_cmd.params.getrandom_out.rng_data, *max); > +out: > + return err; > +} > +EXPORT_SYMBOL_GPL(tpm_get_random); > + > /* In case vendor provided release function, call it too.*/ > > void tpm_dev_vendor_release(struct tpm_chip *chip) > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h > index b1c5280..610fe42 100644 > --- a/drivers/char/tpm/tpm.h > +++ b/drivers/char/tpm/tpm.h > @@ -28,6 +28,12 @@ > #include <linux/io.h> > #include <linux/tpm.h> > > +enum tpm_const { > + TPM_MINOR = 224, /* officially assigned */ > + TPM_BUFSIZE = 4096, > + TPM_NUM_DEVICES = 256, > +}; > + > enum tpm_timeout { > TPM_TIMEOUT = 5, /* msecs */ > }; > @@ -269,6 +275,21 @@ struct tpm_pcrextend_in { > u8 hash[TPM_DIGEST_SIZE]; > }__attribute__((packed)); > > +/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18 > + * bytes, but 128 is still a relatively large number of random bytes and > + * anything much bigger causes users of struct tpm_cmd_t to start getting > + * 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]; > +}__attribute__((packed)); > + > +struct tpm_getrandom_in { > + __be32 num_bytes; > +}__attribute__((packed)); > + > typedef union { > struct tpm_getcap_params_out getcap_out; > struct tpm_readpubek_params_out readpubek_out; > @@ -277,6 +298,8 @@ typedef union { > struct tpm_pcrread_in pcrread_in; > struct tpm_pcrread_out pcrread_out; > struct tpm_pcrextend_in pcrextend_in; > + struct tpm_getrandom_in getrandom_in; > + struct tpm_getrandom_out getrandom_out; > } tpm_cmd_params; > > struct tpm_cmd_t { > diff --git a/include/linux/tpm.h b/include/linux/tpm.h > index fdc718a..d5b2f2d 100644 > --- a/include/linux/tpm.h > +++ b/include/linux/tpm.h > @@ -32,6 +32,7 @@ > extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); > extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); > extern int tpm_send(u32 chip_num, void *cmd, size_t buflen); > +extern int tpm_get_random(u32 chip_num, u8 *data, size_t *max); > #else > static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { > return -ENODEV; > @@ -42,5 +43,8 @@ static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { > static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) { > return -ENODEV; > } > +static inline int tpm_get_random(u32 chip_num, u8 *data, size_t *max) { > + return -ENODEV; > +} > #endif > #endif > diff --git a/security/keys/trusted.c b/security/keys/trusted.c > index 2d5d041..48a9eabc 100644 > --- a/security/keys/trusted.c > +++ b/security/keys/trusted.c > @@ -369,38 +369,6 @@ static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd, > } > > /* > - * get a random value from TPM > - */ > -static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len) > -{ > - int ret; > - > - INIT_BUF(tb); > - store16(tb, TPM_TAG_RQU_COMMAND); > - store32(tb, TPM_GETRANDOM_SIZE); > - store32(tb, TPM_ORD_GETRANDOM); > - store32(tb, len); > - ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data); > - if (!ret) > - memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len); > - return ret; > -} > - > -static int my_get_random(unsigned char *buf, int len) > -{ > - struct tpm_buf *tb; > - int ret; > - > - tb = kmalloc(sizeof *tb, GFP_KERNEL); > - if (!tb) > - return -ENOMEM; > - ret = tpm_get_random(tb, buf, len); > - > - kfree(tb); > - return ret; > -} > - > -/* > * Lock a trusted key, by extending a selected PCR. > * > * Prevents a trusted key that is sealed to PCRs from being accessed. > @@ -409,11 +377,12 @@ static int my_get_random(unsigned char *buf, int len) > static int pcrlock(const int pcrnum) > { > unsigned char hash[SHA1_DIGEST_SIZE]; > + size_t digest_size = SHA1_DIGEST_SIZE; > int ret; > > if (!capable(CAP_SYS_ADMIN)) > return -EPERM; > - ret = my_get_random(hash, SHA1_DIGEST_SIZE); > + ret = tpm_get_random(TPM_ANY_NUM, hash, &digest_size); > if (ret < 0) > return ret; > return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; > @@ -427,9 +396,10 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, > { > unsigned char enonce[TPM_NONCE_SIZE]; > unsigned char ononce[TPM_NONCE_SIZE]; > + size_t nonce_size = TPM_NONCE_SIZE; > int ret; > > - ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE); > + ret = tpm_get_random(TPM_ANY_NUM, ononce, &nonce_size); > if (ret < 0) > return ret; > > @@ -500,6 +470,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, > uint32_t ordinal; > uint32_t pcrsize; > uint32_t datsize; > + size_t nonce_size = TPM_NONCE_SIZE; > int sealinfosize; > int encdatasize; > int storedsize; > @@ -524,7 +495,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, > if (ret < 0) > goto out; > > - ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE); > + ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, &nonce_size); > if (ret < 0) > goto out; > ordinal = htonl(TPM_ORD_SEAL); > @@ -618,6 +589,7 @@ static int tpm_unseal(struct tpm_buf *tb, > unsigned char cont = 0; > uint32_t ordinal; > uint32_t keyhndl; > + size_t nonce_size = TPM_NONCE_SIZE; > int ret; > > /* sessions for unsealing key and data */ > @@ -634,7 +606,7 @@ static int tpm_unseal(struct tpm_buf *tb, > > ordinal = htonl(TPM_ORD_UNSEAL); > keyhndl = htonl(SRKHANDLE); > - ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE); > + ret = tpm_get_random(TPM_ANY_NUM, nonceodd, &nonce_size); > if (ret < 0) { > pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); > return ret; > @@ -974,7 +946,8 @@ static int trusted_instantiate(struct key *key, const void *data, > pr_info("trusted_key: key_unseal failed (%d)\n", ret); > break; > case Opt_new: > - ret = my_get_random(payload->key, payload->key_len); > + ret = tpm_get_random(TPM_ANY_NUM, payload->key, > + &payload->key_len); > if (ret < 0) { > pr_info("trusted_key: key_create failed (%d)\n", ret); > goto out; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder 2012-06-08 19:13 ` David Safford @ 2012-07-26 22:12 ` H. Peter Anvin 2012-07-27 14:49 ` Kent Yoder 2012-07-27 0:10 ` H. Peter Anvin 2 siblings, 1 reply; 13+ messages in thread From: H. Peter Anvin @ 2012-07-26 22:12 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford On 06/07/2012 11:47 AM, Kent Yoder wrote: > Move the tpm_get_random api from the trusted keys code into the TPM > device driver itself so that other callers can make use of it. Also, > change the api slightly so that the number of bytes read is returned in > the call, since the TPM command can potentially return fewer bytes than > requested. > > Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> > +int tpm_get_random(u32 chip_num, u8 *out, size_t *max) /* ... */ > case Opt_new: > - ret = my_get_random(payload->key, payload->key_len); > + ret = tpm_get_random(TPM_ANY_NUM, payload->key, > + &payload->key_len); payload->key_len is unsigned int, not size_t; this causes an overwrite of blob_len on 64-bit platforms. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-07-26 22:12 ` H. Peter Anvin @ 2012-07-27 14:49 ` Kent Yoder 2012-07-27 15:07 ` H. Peter Anvin 0 siblings, 1 reply; 13+ messages in thread From: Kent Yoder @ 2012-07-27 14:49 UTC (permalink / raw) To: H. Peter Anvin; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford On Thu, Jul 26, 2012 at 03:12:19PM -0700, H. Peter Anvin wrote: > On 06/07/2012 11:47 AM, Kent Yoder wrote: > >Move the tpm_get_random api from the trusted keys code into the TPM > >device driver itself so that other callers can make use of it. Also, > >change the api slightly so that the number of bytes read is returned in > >the call, since the TPM command can potentially return fewer bytes than > >requested. > > > >Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> > > >+int tpm_get_random(u32 chip_num, u8 *out, size_t *max) > > /* ... */ > > > case Opt_new: > >- ret = my_get_random(payload->key, payload->key_len); > >+ ret = tpm_get_random(TPM_ANY_NUM, payload->key, > >+ &payload->key_len); > > payload->key_len is unsigned int, not size_t; this causes an > overwrite of blob_len on 64-bit platforms. Good catch. Thanks, Kent > > -hpa > > > -- > H. Peter Anvin, Intel Open Source Technology Center > I work for Intel. I don't speak on their behalf. > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-07-27 14:49 ` Kent Yoder @ 2012-07-27 15:07 ` H. Peter Anvin 0 siblings, 0 replies; 13+ messages in thread From: H. Peter Anvin @ 2012-07-27 15:07 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford On 07/27/2012 07:49 AM, Kent Yoder wrote: >> >>> case Opt_new: >>> - ret = my_get_random(payload->key, payload->key_len); >>> + ret = tpm_get_random(TPM_ANY_NUM, payload->key, >>> + &payload->key_len); >> >> payload->key_len is unsigned int, not size_t; this causes an >> overwrite of blob_len on 64-bit platforms. > > Good catch. > It generated a compiler warning, so that one was trivial to spot. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder 2012-06-08 19:13 ` David Safford 2012-07-26 22:12 ` H. Peter Anvin @ 2012-07-27 0:10 ` H. Peter Anvin 2012-07-27 14:51 ` Kent Yoder 2 siblings, 1 reply; 13+ messages in thread From: H. Peter Anvin @ 2012-07-27 0:10 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford On 06/07/2012 11:47 AM, Kent Yoder wrote: > Move the tpm_get_random api from the trusted keys code into the TPM > device driver itself so that other callers can make use of it. Also, > change the api slightly so that the number of bytes read is returned in > the call, since the TPM command can potentially return fewer bytes than > requested. > > Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> I see a second problem with this patch: you don't seem to handle the case where you get a short return anywhere in your code. Presumably this should either be considered an error condition, or you need to create a private wrapper which can loop and make additional requests. As it is if you get a short return you simply proceed as if you had gotten what you requested, since this was not an error mode supported by the old code. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver 2012-07-27 0:10 ` H. Peter Anvin @ 2012-07-27 14:51 ` Kent Yoder 0 siblings, 0 replies; 13+ messages in thread From: Kent Yoder @ 2012-07-27 14:51 UTC (permalink / raw) To: H. Peter Anvin; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford On Thu, Jul 26, 2012 at 05:10:44PM -0700, H. Peter Anvin wrote: > On 06/07/2012 11:47 AM, Kent Yoder wrote: > >Move the tpm_get_random api from the trusted keys code into the TPM > >device driver itself so that other callers can make use of it. Also, > >change the api slightly so that the number of bytes read is returned in > >the call, since the TPM command can potentially return fewer bytes than > >requested. > > > >Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> > > I see a second problem with this patch: you don't seem to handle the > case where you get a short return anywhere in your code. Presumably > this should either be considered an error condition, or you need to > create a private wrapper which can loop and make additional > requests. > > As it is if you get a short return you simply proceed as if you had > gotten what you requested, since this was not an error mode > supported by the old code. Right, I did notice this but didn't think I was creating a regression so I left it. I'll add both a loop and then error out if that fails. Thanks, Kent > > -hpa > > -- > H. Peter Anvin, Intel Open Source Technology Center > I work for Intel. I don't speak on their behalf. > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source 2012-06-07 18:42 [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it Kent Yoder 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder @ 2012-06-07 18:47 ` Kent Yoder 2012-06-08 19:13 ` David Safford 2012-07-26 21:58 ` H. Peter Anvin 2012-06-08 19:13 ` [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it David Safford 2 siblings, 2 replies; 13+ messages in thread From: Kent Yoder @ 2012-06-07 18:47 UTC (permalink / raw) To: linux-kernel; +Cc: tpmdd-devel, m.selhorst, safford, key This driver will make use of any available TPM chip on the system as a hwrng source. Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> --- drivers/char/hw_random/Kconfig | 13 +++++++++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/tpm-rng.c | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 0 deletions(-) create mode 100644 drivers/char/hw_random/tpm-rng.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index f45dad3..4e8c01a 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -263,3 +263,16 @@ config HW_RANDOM_PSERIES module will be called pseries-rng. If unsure, say Y. + +config HW_RANDOM_TPM + tristate "TPM HW Random Number Generator support" + depends on HW_RANDOM && TCG_TPM + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number + Generator in the Trusted Platform Module + + To compile this driver as a module, choose M here: the + module will be called tpm-rng. + + If unsure, say Y. diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index d901dfa..5dc10da 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o +obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c new file mode 100644 index 0000000..a869b42c --- /dev/null +++ b/drivers/char/hw_random/tpm-rng.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Kent Yoder IBM Corporation + * + * HWRNG interfaces to pull RNG data from a TPM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/hw_random.h> +#include <linux/tpm.h> + +#define MODULE_NAME "tpm-rng" + +static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) +{ + int err; + size_t tpm_max = max; + + err = tpm_get_random(TPM_ANY_NUM, data, &tpm_max); + + return err ? 0 : tpm_max; +} + +static struct hwrng tpm_rng = { + .name = MODULE_NAME, + .read = tpm_rng_read, +}; + +static int __init rng_init(void) +{ + return hwrng_register(&tpm_rng); +} +module_init(rng_init); + +static void __exit rng_exit(void) +{ + hwrng_unregister(&tpm_rng); +} +module_exit(rng_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>"); +MODULE_DESCRIPTION("RNG driver for TPM devices"); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source 2012-06-07 18:47 ` [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source Kent Yoder @ 2012-06-08 19:13 ` David Safford 2012-07-26 21:58 ` H. Peter Anvin 1 sibling, 0 replies; 13+ messages in thread From: David Safford @ 2012-06-08 19:13 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, David Safford On Thu, 2012-06-07 at 13:47 -0500, Kent Yoder wrote: > This driver will make use of any available TPM chip on the system as a > hwrng source. > > Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> Acked-by: David Safford <safford@linux.vnet.ibm.com> > --- > drivers/char/hw_random/Kconfig | 13 +++++++++ > drivers/char/hw_random/Makefile | 1 + > drivers/char/hw_random/tpm-rng.c | 55 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 69 insertions(+), 0 deletions(-) > create mode 100644 drivers/char/hw_random/tpm-rng.c > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > index f45dad3..4e8c01a 100644 > --- a/drivers/char/hw_random/Kconfig > +++ b/drivers/char/hw_random/Kconfig > @@ -263,3 +263,16 @@ config HW_RANDOM_PSERIES > module will be called pseries-rng. > > If unsure, say Y. > + > +config HW_RANDOM_TPM > + tristate "TPM HW Random Number Generator support" > + depends on HW_RANDOM && TCG_TPM > + default HW_RANDOM > + ---help--- > + This driver provides kernel-side support for the Random Number > + Generator in the Trusted Platform Module > + > + To compile this driver as a module, choose M here: the > + module will be called tpm-rng. > + > + If unsure, say Y. > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > index d901dfa..5dc10da 100644 > --- a/drivers/char/hw_random/Makefile > +++ b/drivers/char/hw_random/Makefile > @@ -23,3 +23,4 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o > obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o > obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o > obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o > +obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o > diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c > new file mode 100644 > index 0000000..a869b42c > --- /dev/null > +++ b/drivers/char/hw_random/tpm-rng.c > @@ -0,0 +1,55 @@ > +/* > + * Copyright (C) 2012 Kent Yoder IBM Corporation > + * > + * HWRNG interfaces to pull RNG data from a TPM > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include <linux/module.h> > +#include <linux/hw_random.h> > +#include <linux/tpm.h> > + > +#define MODULE_NAME "tpm-rng" > + > +static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) > +{ > + int err; > + size_t tpm_max = max; > + > + err = tpm_get_random(TPM_ANY_NUM, data, &tpm_max); > + > + return err ? 0 : tpm_max; > +} > + > +static struct hwrng tpm_rng = { > + .name = MODULE_NAME, > + .read = tpm_rng_read, > +}; > + > +static int __init rng_init(void) > +{ > + return hwrng_register(&tpm_rng); > +} > +module_init(rng_init); > + > +static void __exit rng_exit(void) > +{ > + hwrng_unregister(&tpm_rng); > +} > +module_exit(rng_exit); > + > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>"); > +MODULE_DESCRIPTION("RNG driver for TPM devices"); ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source 2012-06-07 18:47 ` [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source Kent Yoder 2012-06-08 19:13 ` David Safford @ 2012-07-26 21:58 ` H. Peter Anvin 2012-07-26 22:28 ` H. Peter Anvin 1 sibling, 1 reply; 13+ messages in thread From: H. Peter Anvin @ 2012-07-26 21:58 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford, Jeff Garzik On 06/07/2012 11:47 AM, Kent Yoder wrote: > This driver will make use of any available TPM chip on the system as a > hwrng source. > > Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> > --- > drivers/char/hw_random/Kconfig | 13 +++++++++ > drivers/char/hw_random/Makefile | 1 + > drivers/char/hw_random/tpm-rng.c | 55 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 69 insertions(+), 0 deletions(-) > create mode 100644 drivers/char/hw_random/tpm-rng.c > So I just noticed this patch being pushed. /dev/hw_random is used by rngd, which already has support for the TPM directly. However, the TPM support in rngd conflict with tcsd (from TrouSerS). Does this driver solve the coexistence problem? If so, this is a Very Good Thing and should be accepted (and the TPM support in rngd deprecated/removed.) If it does *not* solve the coexistence problem, then it just prevents a user space solution and the patch really should be rejected. It would be great to get that clarified as soon as possible. Thanks, -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source 2012-07-26 21:58 ` H. Peter Anvin @ 2012-07-26 22:28 ` H. Peter Anvin 0 siblings, 0 replies; 13+ messages in thread From: H. Peter Anvin @ 2012-07-26 22:28 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, safford, Jeff Garzik On 07/26/2012 02:58 PM, H. Peter Anvin wrote: > On 06/07/2012 11:47 AM, Kent Yoder wrote: >> This driver will make use of any available TPM chip on the system as a >> hwrng source. >> >> Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com> >> --- >> drivers/char/hw_random/Kconfig | 13 +++++++++ >> drivers/char/hw_random/Makefile | 1 + >> drivers/char/hw_random/tpm-rng.c | 55 >> ++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 69 insertions(+), 0 deletions(-) >> create mode 100644 drivers/char/hw_random/tpm-rng.c >> > > So I just noticed this patch being pushed. > > /dev/hw_random is used by rngd, which already has support for the TPM > directly. However, the TPM support in rngd conflict with tcsd (from > TrouSerS). > > Does this driver solve the coexistence problem? If so, this is a Very > Good Thing and should be accepted (and the TPM support in rngd > deprecated/removed.) > > If it does *not* solve the coexistence problem, then it just prevents a > user space solution and the patch really should be rejected. > > It would be great to get that clarified as soon as possible. > To answer my own question: this *does* seem to resolve the coexistence problem. However, please see the type violation/memory overwrite bug I posted about in my other mail. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it 2012-06-07 18:42 [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it Kent Yoder 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder 2012-06-07 18:47 ` [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source Kent Yoder @ 2012-06-08 19:13 ` David Safford 2 siblings, 0 replies; 13+ messages in thread From: David Safford @ 2012-06-08 19:13 UTC (permalink / raw) To: Kent Yoder; +Cc: linux-kernel, tpmdd-devel, m.selhorst, David Safford On Thu, 2012-06-07 at 13:42 -0500, Kent Yoder wrote: > These patches move the tpm_get_random API out of the trusted keys code > and into the tpm device driver itself. Then a hwrng driver is added that > makes use of the API to provide a H/W RNG source. Very nice! checkpatch complained a bit on patch 1, but otherwise, Acked-by: David Safford <safford@linux.vnet.ibm.com> > These are based off the latest upstream kernel. > > Thanks, > Kent > > Kent Yoder (2): > tpm: Move tpm_get_random api into the TPM device driver > hw_random: add support for the TPM chip as a hardware RNG source > > drivers/char/hw_random/Kconfig | 13 +++++++++ > drivers/char/hw_random/Makefile | 1 + > drivers/char/hw_random/tpm-rng.c | 55 ++++++++++++++++++++++++++++++++++++++ > drivers/char/tpm/tpm.c | 53 ++++++++++++++++++++++++++++++++---- > drivers/char/tpm/tpm.h | 23 ++++++++++++++++ > include/linux/tpm.h | 4 +++ > security/keys/trusted.c | 47 +++++++------------------------- > 7 files changed, 153 insertions(+), 43 deletions(-) > create mode 100644 drivers/char/hw_random/tpm-rng.c > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-07-27 15:08 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-06-07 18:42 [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it Kent Yoder 2012-06-07 18:47 ` [PATCH 1/2] tpm: Move tpm_get_random api into the TPM device driver Kent Yoder 2012-06-08 19:13 ` David Safford 2012-07-26 22:12 ` H. Peter Anvin 2012-07-27 14:49 ` Kent Yoder 2012-07-27 15:07 ` H. Peter Anvin 2012-07-27 0:10 ` H. Peter Anvin 2012-07-27 14:51 ` Kent Yoder 2012-06-07 18:47 ` [PATCH 2/2] hw_random: add support for the TPM chip as a hardware RNG source Kent Yoder 2012-06-08 19:13 ` David Safford 2012-07-26 21:58 ` H. Peter Anvin 2012-07-26 22:28 ` H. Peter Anvin 2012-06-08 19:13 ` [PATCH 0/2] Move the tpm_get_random api and add an hwrng driver for it David Safford
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox