keyprogram.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2016
  4. * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
  5. */
  6. #include <common.h>
  7. #include <command.h>
  8. #include <env.h>
  9. #include <tpm-v1.h>
  10. #include <malloc.h>
  11. #include <linux/ctype.h>
  12. #include <asm/unaligned.h>
  13. #include "hre.h"
  14. int flush_keys(struct udevice *tpm)
  15. {
  16. u16 key_count;
  17. u8 buf[288];
  18. u8 *ptr;
  19. u32 err;
  20. uint i;
  21. /* fetch list of already loaded keys in the TPM */
  22. err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
  23. sizeof(buf));
  24. if (err)
  25. return -1;
  26. key_count = get_unaligned_be16(buf);
  27. ptr = buf + 2;
  28. for (i = 0; i < key_count; ++i, ptr += 4) {
  29. err = tpm1_flush_specific(tpm, get_unaligned_be32(ptr),
  30. TPM_RT_KEY);
  31. if (err && err != TPM_KEY_OWNER_CONTROL)
  32. return err;
  33. }
  34. return 0;
  35. }
  36. int decode_hexstr(char *hexstr, u8 **result)
  37. {
  38. int len = strlen(hexstr);
  39. int bytes = len / 2;
  40. int i;
  41. u8 acc = 0;
  42. if (len % 2 == 1)
  43. return 1;
  44. *result = (u8 *)malloc(bytes);
  45. for (i = 0; i < len; i++) {
  46. char cur = tolower(hexstr[i]);
  47. u8 val;
  48. if ((cur >= 'a' && cur <= 'f') || (cur >= '0' && cur <= '9')) {
  49. val = cur - (cur > '9' ? 87 : 48);
  50. if (i % 2 == 0)
  51. acc = 16 * val;
  52. else
  53. (*result)[i / 2] = acc + val;
  54. } else {
  55. free(*result);
  56. return 1;
  57. }
  58. }
  59. return 0;
  60. }
  61. int extract_subprogram(u8 **progdata, u32 expected_magic,
  62. struct key_program **result)
  63. {
  64. struct key_program *prog = *result;
  65. u32 magic, code_crc, code_size;
  66. magic = get_unaligned_be32(*progdata);
  67. code_crc = get_unaligned_be32(*progdata + 4);
  68. code_size = get_unaligned_be32(*progdata + 8);
  69. *progdata += 12;
  70. if (magic != expected_magic)
  71. return -1;
  72. *result = malloc(sizeof(struct key_program) + code_size);
  73. if (!*result)
  74. return -1;
  75. prog->magic = magic;
  76. prog->code_crc = code_crc;
  77. prog->code_size = code_size;
  78. memcpy(prog->code, *progdata, code_size);
  79. *progdata += code_size;
  80. if (hre_verify_program(prog)) {
  81. free(prog);
  82. return -1;
  83. }
  84. return 0;
  85. }
  86. struct key_program *parse_and_check_keyprog(u8 *progdata)
  87. {
  88. struct key_program *result = NULL, *hmac = NULL;
  89. /* Part 1: Load key program */
  90. if (extract_subprogram(&progdata, MAGIC_KEY_PROGRAM, &result))
  91. return NULL;
  92. /* Part 2: Load hmac program */
  93. if (extract_subprogram(&progdata, MAGIC_HMAC, &hmac))
  94. return NULL;
  95. free(hmac);
  96. return result;
  97. }
  98. int load_and_run_keyprog(struct udevice *tpm)
  99. {
  100. char *cmd = NULL;
  101. u8 *binprog = NULL;
  102. char *hexprog;
  103. struct key_program *prog;
  104. cmd = env_get("loadkeyprogram");
  105. if (!cmd || run_command(cmd, 0))
  106. return 1;
  107. hexprog = env_get("keyprogram");
  108. if (decode_hexstr(hexprog, &binprog))
  109. return 1;
  110. prog = parse_and_check_keyprog(binprog);
  111. free(binprog);
  112. if (!prog)
  113. return 1;
  114. if (hre_run_program(tpm, prog->code, prog->code_size)) {
  115. free(prog);
  116. return 1;
  117. }
  118. printf("\nSD code ran successfully\n");
  119. free(prog);
  120. return 0;
  121. }