keyprogram.c 2.7 KB

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