aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2015-10-11 05:26:58 -0400
committerPeter Huewe <peterhuewe@gmx.de>2015-10-18 19:01:20 -0400
commita74f8b36352e79b13d48fa92759c9ea6b78d5817 (patch)
tree672ff847e04b461d4926e982506605b846426603 /drivers/char
parentb8e98dcdc5ad24bbecc763cd0ac87bbde602e5ea (diff)
tpm: introduce tpm_buf
This patch introduces struct tpm_buf that provides a string buffer for constructing TPM commands. This allows to construct variable sized TPM commands. For the buffer a page is allocated and mapped, which limits maximum size to PAGE_SIZE. Variable sized TPM commands are needed in order to add algorithmic agility. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Peter Huewe <peterhuewe@gmx.de> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 36ceb710f0eb..cb46f6267af2 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2004 IBM Corporation 2 * Copyright (C) 2004 IBM Corporation
3 * Copyright (C) 2015 Intel Corporation
3 * 4 *
4 * Authors: 5 * Authors:
5 * Leendert van Doorn <leendert@watson.ibm.com> 6 * Leendert van Doorn <leendert@watson.ibm.com>
@@ -28,6 +29,7 @@
28#include <linux/tpm.h> 29#include <linux/tpm.h>
29#include <linux/acpi.h> 30#include <linux/acpi.h>
30#include <linux/cdev.h> 31#include <linux/cdev.h>
32#include <linux/highmem.h>
31 33
32enum tpm_const { 34enum tpm_const {
33 TPM_MINOR = 224, /* officially assigned */ 35 TPM_MINOR = 224, /* officially assigned */
@@ -390,6 +392,101 @@ struct tpm_cmd_t {
390 tpm_cmd_params params; 392 tpm_cmd_params params;
391} __packed; 393} __packed;
392 394
395/* A string buffer type for constructing TPM commands. This is based on the
396 * ideas of string buffer code in security/keys/trusted.h but is heap based
397 * in order to keep the stack usage minimal.
398 */
399
400enum tpm_buf_flags {
401 TPM_BUF_OVERFLOW = BIT(0),
402};
403
404struct tpm_buf {
405 struct page *data_page;
406 unsigned int flags;
407 u8 *data;
408};
409
410static inline void tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
411{
412 struct tpm_input_header *head;
413
414 buf->data_page = alloc_page(GFP_HIGHUSER);
415 if (!buf->data_page)
416 return -ENOMEM;
417
418 buf->flags = 0;
419 buf->data = kmap(buf->data_page);
420
421 head = (struct tpm_input_header *) buf->data;
422
423 head->tag = cpu_to_be16(tag);
424 head->length = cpu_to_be32(sizeof(*head));
425 head->ordinal = cpu_to_be32(ordinal);
426
427 return 0;
428}
429
430static inline void tpm_buf_destroy(struct tpm_buf *buf)
431{
432 kunmap(buf->data_page);
433 __free_page(buf->data_page);
434}
435
436static inline u32 tpm_buf_length(struct tpm_buf *buf)
437{
438 struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
439
440 return be32_to_cpu(head->length);
441}
442
443static inline u16 tpm_buf_tag(struct tpm_buf *buf)
444{
445 struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
446
447 return be16_to_cpu(head->tag);
448}
449
450static inline void tpm_buf_append(struct tpm_buf *buf,
451 const unsigned char *new_data,
452 unsigned int new_len)
453{
454 struct tpm_input_header *head = (struct tpm_input_header *) buf->data;
455 u32 len = tpm_buf_length(buf);
456
457 /* Return silently if overflow has already happened. */
458 if (buf->flags & TPM_BUF_OVERFLOW)
459 return;
460
461 if ((len + new_len) > PAGE_SIZE) {
462 WARN(1, "tpm_buf: overflow\n");
463 buf->flags |= TPM_BUF_OVERFLOW;
464 return;
465 }
466
467 memcpy(&buf->data[len], new_data, new_len);
468 head->length = cpu_to_be32(len + new_len);
469}
470
471static inline void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value)
472{
473 tpm_buf_append(buf, &value, 1);
474}
475
476static inline void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value)
477{
478 __be16 value2 = cpu_to_be16(value);
479
480 tpm_buf_append(buf, (u8 *) &value2, 2);
481}
482
483static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
484{
485 __be32 value2 = cpu_to_be32(value);
486
487 tpm_buf_append(buf, (u8 *) &value2, 4);
488}
489
393extern struct class *tpm_class; 490extern struct class *tpm_class;
394extern dev_t tpm_devt; 491extern dev_t tpm_devt;
395extern const struct file_operations tpm_fops; 492extern const struct file_operations tpm_fops;