readonly.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
  2. * Use of this source code is governed by a BSD-style license that can be
  3. * found in the LICENSE file.
  4. */
  5. /* This program mimicks the TPM usage from read-only firmware. It exercises
  6. * the TPM functionality needed in the read-only firmware. It is meant to be
  7. * integrated with the rest of the read-only firmware. It is also provided as
  8. * a test.
  9. */
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include "tlcl.h"
  14. #include "utility.h"
  15. /* These index values are used to create NVRAM spaces. They only need to be
  16. * unique.
  17. */
  18. #define INDEX0 0xda70
  19. #define INDEX1 0xda71
  20. #define INDEX2 0xda72
  21. #define INDEX3 0xda73
  22. #define INDEX_INITIALIZED 0xda80
  23. /* This is called once at initialization time. It may be called again from
  24. * recovery mode to rebuild the spaces if something incomprehensible happened
  25. * and the spaces are gone or messed up. This is called after TPM_Startup and
  26. * before the spaces are write-locked, so there is a chance that they can be
  27. * recreated (but who knows---if anything can happen, there are plenty of ways
  28. * of making this FUBAR).
  29. */
  30. void InitializeSpaces(void) {
  31. uint32_t zero = 0;
  32. uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
  33. printf("Initializing spaces\n");
  34. TlclSetNvLocked(); /* useful only the first time */
  35. TlclDefineSpace(INDEX0, perm, 4);
  36. TlclWrite(INDEX0, (uint8_t *) &zero, 4);
  37. TlclDefineSpace(INDEX1, perm, 4);
  38. TlclWrite(INDEX1, (uint8_t *) &zero, 4);
  39. TlclDefineSpace(INDEX2, perm, 4);
  40. TlclWrite(INDEX2, (uint8_t *) &zero, 4);
  41. TlclDefineSpace(INDEX3, perm, 4);
  42. TlclWrite(INDEX3, (uint8_t *) &zero, 4);
  43. perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
  44. TPM_NV_PER_PPWRITE;
  45. TlclDefineSpace(INDEX_INITIALIZED, perm, 1);
  46. }
  47. void EnterRecoveryMode(void) {
  48. printf("entering recovery mode");
  49. exit(0);
  50. }
  51. int main(int argc, char** argv) {
  52. uint8_t c;
  53. uint32_t index_0, index_1, index_2, index_3;
  54. TlclLibInit();
  55. TlclStartup();
  56. TlclSelfTestFull();
  57. TlclAssertPhysicalPresence();
  58. /* Checks if initialization has completed by trying to read-lock a space
  59. * that's created at the end of initialization.
  60. */
  61. if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) {
  62. /* The initialization did not complete.
  63. */
  64. InitializeSpaces();
  65. }
  66. /* Checks if spaces are OK or messed up.
  67. */
  68. if (TlclRead(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) != TPM_SUCCESS ||
  69. TlclRead(INDEX1, (uint8_t*) &index_1, sizeof(index_1)) != TPM_SUCCESS ||
  70. TlclRead(INDEX2, (uint8_t*) &index_2, sizeof(index_2)) != TPM_SUCCESS ||
  71. TlclRead(INDEX3, (uint8_t*) &index_3, sizeof(index_3)) != TPM_SUCCESS) {
  72. EnterRecoveryMode();
  73. }
  74. /* Writes space, and locks it. Then attempts to write again. I really wish
  75. * I could use the imperative.
  76. */
  77. index_0 += 1;
  78. if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0) != TPM_SUCCESS)) {
  79. error("could not write index 0\n");
  80. }
  81. TlclWriteLock(INDEX0);
  82. if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) == TPM_SUCCESS) {
  83. error("index 0 is not locked\n");
  84. }
  85. /* Done for now.
  86. */
  87. printf("TEST SUCCEEDED\n");
  88. exit(0);
  89. }