bdb_create.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* Copyright (c) 2015 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. * Create a BDB
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "bdb.h"
  11. #include "host.h"
  12. /* Parameters for creating a BDB hash entry */
  13. struct create_hash {
  14. /* File containing data */
  15. const char *filename;
  16. /* Type of data; enum bdb_data_type */
  17. uint8_t type;
  18. /* Address in RAM to load data. -1 means use default. */
  19. uint64_t load_address;
  20. /* Partition number containing data, or -1 to use the same partition as
  21. * the BDB. */
  22. uint8_t partition;
  23. /*
  24. * Offset of data from start of partition.
  25. *
  26. * TODO: if -1, append after BDB. But need to know how big the BDB
  27. * is, and need to round up offset to 32-bit boundary.
  28. */
  29. uint64_t offset;
  30. };
  31. /* Parameters for a key */
  32. struct create_key {
  33. /* Description */
  34. const char *description;
  35. /* Key version (not meaningful for BDB key) */
  36. uint32_t key_version;
  37. /* Public key filename (.keyb) */
  38. const char *public_filename;
  39. /* Private key filename (.pem) */
  40. const char *private_filename;
  41. };
  42. struct create_params_2 {
  43. /* Destination filename */
  44. const char *filename;
  45. /* Partition to contain the BDB */
  46. uint8_t partition;
  47. /* OEM area files. NULL means there is no data for that area. */
  48. const char *oem_area_0_filename;
  49. const char *oem_area_1_filename;
  50. /* BDB key and subkey */
  51. struct create_key bdbkey;
  52. struct create_key subkey;
  53. };
  54. /*****************************************************************************/
  55. /* FILL THIS IN WITH YOUR SOURCE DATA */
  56. /*
  57. * Creation parameters. Hash and num_hashes will be filled in automatically
  58. * by create().
  59. */
  60. struct bdb_create_params p = {
  61. .bdb_load_address = 0x11223344,
  62. .header_sig_description = "The header sig",
  63. .data_sig_description = "The data sig",
  64. .data_description = "Test BDB data",
  65. .data_version = 3,
  66. };
  67. /* Additional parameters */
  68. struct create_params_2 p2 = {
  69. .filename = "build/bdb.bin",
  70. .partition = 1,
  71. .oem_area_0_filename = "testdata/oem0.bin",
  72. .oem_area_1_filename = "testdata/oem1.bin",
  73. .bdbkey = {
  74. .description = "Test BDB key",
  75. .key_version = 3,
  76. .public_filename = "testkeys/bdbkey.keyb",
  77. .private_filename = "testkeys/bdbkey.pem",
  78. },
  79. .subkey = {
  80. .description = "Test Subkey",
  81. .key_version = 4,
  82. .public_filename = "testkeys/subkey.keyb",
  83. .private_filename = "testkeys/subkey.pem",
  84. },
  85. };
  86. /* List of hash entries, terminated by one with a NULL filename */
  87. struct create_hash hash_entries[] = {
  88. {
  89. .filename = "testdata/sp-rw.bin",
  90. .type = BDB_DATA_SP_RW,
  91. .load_address = -1,
  92. .partition = -1,
  93. .offset = 0x10000,
  94. },
  95. {
  96. .filename = "testdata/ap-rw.bin",
  97. .type = BDB_DATA_AP_RW,
  98. .load_address = 0x200000,
  99. .partition = -1,
  100. .offset = 0x28000,
  101. },
  102. {
  103. .filename = NULL
  104. },
  105. };
  106. /*****************************************************************************/
  107. int create(void)
  108. {
  109. struct bdb_hash *hash;
  110. struct bdb_header *h;
  111. int i;
  112. /* Count the number of hash entries */
  113. for (p.num_hashes = 0; hash_entries[p.num_hashes].filename;
  114. p.num_hashes++)
  115. ;
  116. printf("Found %d hash entries\n", p.num_hashes);
  117. /* Calculate hashes */
  118. p.hash = hash = calloc(sizeof(struct bdb_hash), p.num_hashes);
  119. for (i = 0; i < p.num_hashes; i++, hash++) {
  120. const struct create_hash *he = hash_entries + i;
  121. /* Read file and calculate size and hash */
  122. uint8_t *buf = read_file(he->filename, &hash->size);
  123. if (!buf)
  124. return 1;
  125. if (bdb_sha256(hash->digest, buf, hash->size)) {
  126. fprintf(stderr, "Unable to calculate hash\n");
  127. return 1;
  128. }
  129. free(buf);
  130. hash->type = he->type;
  131. hash->load_address = he->load_address;
  132. hash->partition = he->partition == -1 ? p2.partition :
  133. he->partition;
  134. hash->offset = he->offset;
  135. }
  136. /* Read OEM data */
  137. if (p2.oem_area_0_filename) {
  138. p.oem_area_0 = read_file(p2.oem_area_0_filename,
  139. &p.oem_area_0_size);
  140. if (!p.oem_area_0)
  141. return 1;
  142. if (p.oem_area_0_size & 3) {
  143. fprintf(stderr,
  144. "OEM area 0 size isn't 32-bit aligned\n");
  145. return 1;
  146. }
  147. }
  148. if (p2.oem_area_1_filename) {
  149. p.oem_area_1 = read_file(p2.oem_area_1_filename,
  150. &p.oem_area_1_size);
  151. if (!p.oem_area_1)
  152. return 1;
  153. if (p.oem_area_1_size & 3) {
  154. fprintf(stderr,
  155. "OEM area 1 size isn't 32-bit aligned\n");
  156. return 1;
  157. }
  158. }
  159. /* Load keys */
  160. p.bdbkey = bdb_create_key(p2.bdbkey.public_filename,
  161. p2.bdbkey.key_version,
  162. p2.bdbkey.description);
  163. p.subkey = bdb_create_key(p2.subkey.public_filename,
  164. p2.subkey.key_version,
  165. p2.subkey.description);
  166. p.private_bdbkey = read_pem(p2.bdbkey.private_filename);
  167. p.private_subkey = read_pem(p2.subkey.private_filename);
  168. if (!p.bdbkey || !p.subkey || !p.private_bdbkey || !p.private_subkey) {
  169. fprintf(stderr, "Unable to load keys\n");
  170. return 1;
  171. }
  172. /* Create the BDB */
  173. h = bdb_create(&p);
  174. if (!h) {
  175. fprintf(stderr, "Unable to create BDB\n");
  176. return 1;
  177. }
  178. /* Write it */
  179. if (write_file(p2.filename, h, h->bdb_size))
  180. return 1;
  181. /* Free keys and buffers */
  182. free(p.bdbkey);
  183. free(p.subkey);
  184. RSA_free(p.private_bdbkey);
  185. RSA_free(p.private_subkey);
  186. free(h);
  187. free(p.hash);
  188. return 0;
  189. }
  190. /*****************************************************************************/
  191. int main(void)
  192. {
  193. return create();
  194. }