tpm2_eventlog.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. /* Check if event is malformed. */
  53. if (event->count > efispecid->num_algs)
  54. return 0;
  55. for (i = 0; i < event->count; i++) {
  56. halg_size = sizeof(event->digests[i].alg_id);
  57. memcpy(&halg, marker, halg_size);
  58. marker = marker + halg_size;
  59. for (j = 0; j < efispecid->num_algs; j++) {
  60. if (halg == efispecid->digest_sizes[j].alg_id) {
  61. marker +=
  62. efispecid->digest_sizes[j].digest_size;
  63. break;
  64. }
  65. }
  66. /* Algorithm without known length. Such event is unparseable. */
  67. if (j == efispecid->num_algs)
  68. return 0;
  69. }
  70. event_field = (struct tcg_event_field *)marker;
  71. marker = marker + sizeof(event_field->event_size)
  72. + event_field->event_size;
  73. size = marker - marker_start;
  74. if ((event->event_type == 0) && (event_field->event_size == 0))
  75. return 0;
  76. return size;
  77. }
  78. static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)
  79. {
  80. struct tpm_chip *chip = m->private;
  81. struct tpm_bios_log *log = &chip->log;
  82. void *addr = log->bios_event_log;
  83. void *limit = log->bios_event_log_end;
  84. struct tcg_pcr_event *event_header;
  85. struct tcg_pcr_event2 *event;
  86. size_t size;
  87. int i;
  88. event_header = addr;
  89. size = sizeof(struct tcg_pcr_event) - sizeof(event_header->event)
  90. + event_header->event_size;
  91. if (*pos == 0) {
  92. if (addr + size < limit) {
  93. if ((event_header->event_type == 0) &&
  94. (event_header->event_size == 0))
  95. return NULL;
  96. return SEQ_START_TOKEN;
  97. }
  98. }
  99. if (*pos > 0) {
  100. addr += size;
  101. event = addr;
  102. size = calc_tpm2_event_size(event, event_header);
  103. if ((addr + size >= limit) || (size == 0))
  104. return NULL;
  105. }
  106. for (i = 0; i < (*pos - 1); i++) {
  107. event = addr;
  108. size = calc_tpm2_event_size(event, event_header);
  109. if ((addr + size >= limit) || (size == 0))
  110. return NULL;
  111. addr += size;
  112. }
  113. return addr;
  114. }
  115. static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,
  116. loff_t *pos)
  117. {
  118. struct tcg_pcr_event *event_header;
  119. struct tcg_pcr_event2 *event;
  120. struct tpm_chip *chip = m->private;
  121. struct tpm_bios_log *log = &chip->log;
  122. void *limit = log->bios_event_log_end;
  123. size_t event_size;
  124. void *marker;
  125. event_header = log->bios_event_log;
  126. if (v == SEQ_START_TOKEN) {
  127. event_size = sizeof(struct tcg_pcr_event) -
  128. sizeof(event_header->event) + event_header->event_size;
  129. marker = event_header;
  130. } else {
  131. event = v;
  132. event_size = calc_tpm2_event_size(event, event_header);
  133. if (event_size == 0)
  134. return NULL;
  135. marker = event;
  136. }
  137. marker = marker + event_size;
  138. if (marker >= limit)
  139. return NULL;
  140. v = marker;
  141. event = v;
  142. event_size = calc_tpm2_event_size(event, event_header);
  143. if (((v + event_size) >= limit) || (event_size == 0))
  144. return NULL;
  145. (*pos)++;
  146. return v;
  147. }
  148. static void tpm2_bios_measurements_stop(struct seq_file *m, void *v)
  149. {
  150. }
  151. static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)
  152. {
  153. struct tpm_chip *chip = m->private;
  154. struct tpm_bios_log *log = &chip->log;
  155. struct tcg_pcr_event *event_header = log->bios_event_log;
  156. struct tcg_pcr_event2 *event = v;
  157. void *temp_ptr;
  158. size_t size;
  159. if (v == SEQ_START_TOKEN) {
  160. size = sizeof(struct tcg_pcr_event) -
  161. sizeof(event_header->event) + event_header->event_size;
  162. temp_ptr = event_header;
  163. if (size > 0)
  164. seq_write(m, temp_ptr, size);
  165. } else {
  166. size = calc_tpm2_event_size(event, event_header);
  167. temp_ptr = event;
  168. if (size > 0)
  169. seq_write(m, temp_ptr, size);
  170. }
  171. return 0;
  172. }
  173. const struct seq_operations tpm2_binary_b_measurements_seqops = {
  174. .start = tpm2_bios_measurements_start,
  175. .next = tpm2_bios_measurements_next,
  176. .stop = tpm2_bios_measurements_stop,
  177. .show = tpm2_binary_bios_measurements_show,
  178. };