tpm2_eventlog.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (C) 2016 IBM Corporation
  3. *
  4. * Authors:
  5. * Nayna Jain <nayna@linux.vnet.ibm.com>
  6. *
  7. * Access to TPM 2.0 event log as written by Firmware.
  8. * It assumes that writer of event log has followed TCG Specification
  9. * for Family "2.0" and written the event data in little endian.
  10. * With that, it doesn't need any endian conversion for structure
  11. * content.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version
  16. * 2 of the License, or (at your option) any later version.
  17. */
  18. #include <linux/seq_file.h>
  19. #include <linux/fs.h>
  20. #include <linux/security.h>
  21. #include <linux/module.h>
  22. #include <linux/slab.h>
  23. #include "tpm.h"
  24. #include "tpm_eventlog.h"
  25. /*
  26. * calc_tpm2_event_size() - calculate the event size, where event
  27. * is an entry in the TPM 2.0 event log. The event is of type Crypto
  28. * Agile Log Entry Format as defined in TCG EFI Protocol Specification
  29. * Family "2.0".
  30. * @event: event whose size is to be calculated.
  31. * @event_header: the first event in the event log.
  32. *
  33. * Returns size of the event. If it is an invalid event, returns 0.
  34. */
  35. static int calc_tpm2_event_size(struct tcg_pcr_event2 *event,
  36. struct tcg_pcr_event *event_header)
  37. {
  38. struct tcg_efi_specid_event *efispecid;
  39. struct tcg_event_field *event_field;
  40. void *marker;
  41. void *marker_start;
  42. u32 halg_size;
  43. size_t size;
  44. u16 halg;
  45. int i;
  46. int j;
  47. marker = event;
  48. marker_start = marker;
  49. marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type)
  50. + sizeof(event->count);
  51. efispecid = (struct tcg_efi_specid_event *)event_header->event;
  52. for (i = 0; (i < event->count) && (i < TPM2_ACTIVE_PCR_BANKS);
  53. i++) {
  54. halg_size = sizeof(event->digests[i].alg_id);
  55. memcpy(&halg, marker, halg_size);
  56. marker = marker + halg_size;
  57. for (j = 0; (j < efispecid->num_algs); j++) {
  58. if (halg == efispecid->digest_sizes[j].alg_id) {
  59. marker = marker +
  60. efispecid->digest_sizes[j].digest_size;
  61. break;
  62. }
  63. }
  64. }
  65. event_field = (struct tcg_event_field *)marker;
  66. marker = marker + sizeof(event_field->event_size)
  67. + event_field->event_size;
  68. size = marker - marker_start;
  69. if ((event->event_type == 0) && (event_field->event_size == 0))
  70. return 0;
  71. return size;
  72. }
  73. static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)
  74. {
  75. struct tpm_chip *chip = m->private;
  76. struct tpm_bios_log *log = &chip->log;
  77. void *addr = log->bios_event_log;
  78. void *limit = log->bios_event_log_end;
  79. struct tcg_pcr_event *event_header;
  80. struct tcg_pcr_event2 *event;
  81. size_t size;
  82. int i;
  83. event_header = addr;
  84. size = sizeof(struct tcg_pcr_event) - sizeof(event_header->event)
  85. + event_header->event_size;
  86. if (*pos == 0) {
  87. if (addr + size < limit) {
  88. if ((event_header->event_type == 0) &&
  89. (event_header->event_size == 0))
  90. return NULL;
  91. return SEQ_START_TOKEN;
  92. }
  93. }
  94. if (*pos > 0) {
  95. addr += size;
  96. event = addr;
  97. size = calc_tpm2_event_size(event, event_header);
  98. if ((addr + size >= limit) || (size == 0))
  99. return NULL;
  100. }
  101. for (i = 0; i < (*pos - 1); i++) {
  102. event = addr;
  103. size = calc_tpm2_event_size(event, event_header);
  104. if ((addr + size >= limit) || (size == 0))
  105. return NULL;
  106. addr += size;
  107. }
  108. return addr;
  109. }
  110. static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,
  111. loff_t *pos)
  112. {
  113. struct tcg_pcr_event *event_header;
  114. struct tcg_pcr_event2 *event;
  115. struct tpm_chip *chip = m->private;
  116. struct tpm_bios_log *log = &chip->log;
  117. void *limit = log->bios_event_log_end;
  118. size_t event_size;
  119. void *marker;
  120. event_header = log->bios_event_log;
  121. if (v == SEQ_START_TOKEN) {
  122. event_size = sizeof(struct tcg_pcr_event) -
  123. sizeof(event_header->event) + event_header->event_size;
  124. marker = event_header;
  125. } else {
  126. event = v;
  127. event_size = calc_tpm2_event_size(event, event_header);
  128. if (event_size == 0)
  129. return NULL;
  130. marker = event;
  131. }
  132. marker = marker + event_size;
  133. if (marker >= limit)
  134. return NULL;
  135. v = marker;
  136. event = v;
  137. event_size = calc_tpm2_event_size(event, event_header);
  138. if (((v + event_size) >= limit) || (event_size == 0))
  139. return NULL;
  140. (*pos)++;
  141. return v;
  142. }
  143. static void tpm2_bios_measurements_stop(struct seq_file *m, void *v)
  144. {
  145. }
  146. static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)
  147. {
  148. struct tpm_chip *chip = m->private;
  149. struct tpm_bios_log *log = &chip->log;
  150. struct tcg_pcr_event *event_header = log->bios_event_log;
  151. struct tcg_pcr_event2 *event = v;
  152. void *temp_ptr;
  153. size_t size;
  154. if (v == SEQ_START_TOKEN) {
  155. size = sizeof(struct tcg_pcr_event) -
  156. sizeof(event_header->event) + event_header->event_size;
  157. temp_ptr = event_header;
  158. if (size > 0)
  159. seq_write(m, temp_ptr, size);
  160. } else {
  161. size = calc_tpm2_event_size(event, event_header);
  162. temp_ptr = event;
  163. if (size > 0)
  164. seq_write(m, temp_ptr, size);
  165. }
  166. return 0;
  167. }
  168. const struct seq_operations tpm2_binary_b_measurements_seqops = {
  169. .start = tpm2_bios_measurements_start,
  170. .next = tpm2_bios_measurements_next,
  171. .stop = tpm2_bios_measurements_stop,
  172. .show = tpm2_binary_bios_measurements_show,
  173. };