host.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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. * Host functions for signing
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include "bdb.h"
  11. #include "host.h"
  12. char *strzcpy(char *dest, const char *src, size_t size)
  13. {
  14. strncpy(dest, src, size);
  15. dest[size - 1] = 0;
  16. return dest;
  17. }
  18. uint8_t *read_file(const char *filename, uint32_t *size_ptr)
  19. {
  20. FILE *f;
  21. uint8_t *buf;
  22. long size;
  23. *size_ptr = 0;
  24. f = fopen(filename, "rb");
  25. if (!f) {
  26. fprintf(stderr, "Unable to open file %s\n", filename);
  27. return NULL;
  28. }
  29. fseek(f, 0, SEEK_END);
  30. size = ftell(f);
  31. rewind(f);
  32. if (size < 0 || size > UINT32_MAX) {
  33. fclose(f);
  34. return NULL;
  35. }
  36. buf = malloc(size);
  37. if (!buf) {
  38. fclose(f);
  39. return NULL;
  40. }
  41. if (1 != fread(buf, size, 1, f)) {
  42. fprintf(stderr, "Unable to read file %s\n", filename);
  43. fclose(f);
  44. free(buf);
  45. return NULL;
  46. }
  47. fclose(f);
  48. *size_ptr = size;
  49. return buf;
  50. }
  51. int write_file(const char *filename, const void *buf, uint32_t size)
  52. {
  53. FILE *f = fopen(filename, "wb");
  54. if (!f) {
  55. fprintf(stderr, "Unable to open file %s\n", filename);
  56. return 1;
  57. }
  58. if (1 != fwrite(buf, size, 1, f)) {
  59. fprintf(stderr, "Unable to write to file %s\n", filename);
  60. fclose(f);
  61. unlink(filename); /* Delete any partial file */
  62. return 1;
  63. }
  64. fclose(f);
  65. return 0;
  66. }
  67. struct rsa_st *read_pem(const char *filename)
  68. {
  69. struct rsa_st *pem;
  70. FILE *f;
  71. /* Read private key */
  72. f = fopen(filename, "rb");
  73. if (!f) {
  74. fprintf(stderr, "%s: unable to read key from %s\n",
  75. __func__, filename);
  76. return NULL;
  77. }
  78. pem = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
  79. fclose(f);
  80. return pem;
  81. }
  82. struct bdb_key *bdb_create_key(const char *filename,
  83. uint32_t key_version,
  84. const char *desc)
  85. {
  86. uint32_t sig_alg;
  87. size_t key_size = sizeof(struct bdb_key);
  88. struct bdb_key *k;
  89. uint8_t *kdata;
  90. uint32_t kdata_size = 0;
  91. /*
  92. * Read key data. Somewhat lame assumption that we can determine the
  93. * signature algorithm from the key size, but it's true right now.
  94. */
  95. kdata = read_file(filename, &kdata_size);
  96. if (kdata_size == BDB_RSA4096_KEY_DATA_SIZE) {
  97. sig_alg = BDB_SIG_ALG_RSA4096;
  98. } else if (kdata_size == BDB_RSA3072B_KEY_DATA_SIZE) {
  99. sig_alg = BDB_SIG_ALG_RSA3072B;
  100. } else {
  101. fprintf(stderr, "%s: bad key size from %s\n",
  102. __func__, filename);
  103. return NULL;
  104. }
  105. key_size += kdata_size;
  106. /* Allocate buffer */
  107. k = (struct bdb_key *)calloc(key_size, 1);
  108. if (!k) {
  109. free(kdata);
  110. return NULL;
  111. }
  112. k->struct_magic = BDB_KEY_MAGIC;
  113. k->struct_major_version = BDB_KEY_VERSION_MAJOR;
  114. k->struct_minor_version = BDB_KEY_VERSION_MINOR;
  115. k->struct_size = key_size;
  116. k->hash_alg = BDB_HASH_ALG_SHA256;
  117. k->sig_alg = sig_alg;
  118. k->key_version = key_version;
  119. /* Copy description, if any */
  120. if (desc)
  121. strzcpy(k->description, desc, sizeof(k->description));
  122. /* Copy key data */
  123. memcpy(k->key_data, kdata, kdata_size);
  124. free(kdata);
  125. return k;
  126. }
  127. struct bdb_sig *bdb_create_sig(const void *data,
  128. size_t size,
  129. struct rsa_st *key,
  130. uint32_t sig_alg,
  131. const char *desc)
  132. {
  133. static const uint8_t info[] = {
  134. 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
  135. 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
  136. 0x00, 0x04, 0x20
  137. };
  138. size_t sig_size = sizeof(struct bdb_sig);
  139. uint8_t digest[sizeof(info) + BDB_SHA256_DIGEST_SIZE];
  140. struct bdb_sig *sig;
  141. if (size >= UINT32_MAX)
  142. return NULL;
  143. switch(sig_alg) {
  144. case BDB_SIG_ALG_RSA4096:
  145. sig_size += BDB_RSA4096_SIG_SIZE;
  146. break;
  147. case BDB_SIG_ALG_RSA3072B:
  148. sig_size += BDB_RSA3072B_SIG_SIZE;
  149. break;
  150. default:
  151. fprintf(stderr, "%s: bad signature algorithm %d\n",
  152. __func__, sig_alg);
  153. return NULL;
  154. }
  155. /* Allocate buffer */
  156. sig = (struct bdb_sig *)calloc(sig_size, 1);
  157. if (!sig)
  158. return NULL;
  159. sig->struct_magic = BDB_SIG_MAGIC;
  160. sig->struct_major_version = BDB_SIG_VERSION_MAJOR;
  161. sig->struct_minor_version = BDB_SIG_VERSION_MINOR;
  162. sig->struct_size = sig_size;
  163. sig->hash_alg = BDB_HASH_ALG_SHA256;
  164. sig->sig_alg = sig_alg;
  165. sig->signed_size = size;
  166. /* Copy description, if any */
  167. if (desc)
  168. strzcpy(sig->description, desc, sizeof(sig->description));
  169. /* Calculate info-padded digest */
  170. memcpy(digest, info, sizeof(info));
  171. if (bdb_sha256(digest + sizeof(info), data, size)) {
  172. free(sig);
  173. return NULL;
  174. }
  175. /* RSA-encrypt the signature */
  176. if (RSA_private_encrypt(sizeof(digest),
  177. digest,
  178. sig->sig_data,
  179. key,
  180. RSA_PKCS1_PADDING) == -1) {
  181. free(sig);
  182. return NULL;
  183. }
  184. return sig;
  185. }
  186. struct bdb_header *bdb_create(struct bdb_create_params *p)
  187. {
  188. size_t bdb_size = 0;
  189. size_t sig_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE;
  190. size_t hashes_size = sizeof(struct bdb_hash) * p->num_hashes;
  191. uint8_t *buf, *bnext;
  192. struct bdb_header *h;
  193. struct bdb_sig *sig;
  194. struct bdb_data *data;
  195. const void *oem;
  196. /* We can do some checks before we even allocate the buffer */
  197. /* Make sure OEM sizes are aligned */
  198. if ((p->oem_area_0_size & 3) || (p->oem_area_1_size & 3)) {
  199. fprintf(stderr, "%s: OEM areas not 32-bit aligned\n",
  200. __func__);
  201. return NULL;
  202. }
  203. /* Hash count must fit in uint8_t */
  204. if (p->num_hashes > 255) {
  205. fprintf(stderr, "%s: too many hashes\n", __func__);
  206. return NULL;
  207. }
  208. /* Calculate BDB size */
  209. bdb_size = sizeof(struct bdb_header);
  210. bdb_size += p->bdbkey->struct_size;
  211. bdb_size += p->oem_area_0_size;
  212. bdb_size += p->subkey->struct_size;
  213. bdb_size += sig_size;
  214. bdb_size += sizeof(struct bdb_data);
  215. bdb_size += p->oem_area_1_size;
  216. bdb_size += sizeof(struct bdb_hash) * p->num_hashes;
  217. bdb_size += sig_size;
  218. /* Make sure it fits */
  219. if (bdb_size > UINT32_MAX) {
  220. fprintf(stderr, "%s: BDB size > UINT32_MAX\n", __func__);
  221. return NULL;
  222. }
  223. /* Allocate a buffer */
  224. bnext = buf = calloc(bdb_size, 1);
  225. if (!buf) {
  226. fprintf(stderr, "%s: can't allocate buffer\n", __func__);
  227. return NULL;
  228. }
  229. /* Fill in the header */
  230. h = (struct bdb_header *)bnext;
  231. h->struct_magic = BDB_HEADER_MAGIC;
  232. h->struct_major_version = BDB_HEADER_VERSION_MAJOR;
  233. h->struct_minor_version = BDB_HEADER_VERSION_MINOR;
  234. h->struct_size = sizeof(*h);
  235. h->bdb_load_address = p->bdb_load_address;
  236. h->bdb_size = bdb_size;
  237. h->signed_size = p->oem_area_0_size + p->subkey->struct_size;
  238. h->oem_area_0_size = p->oem_area_0_size;
  239. bnext += h->struct_size;
  240. /* Copy BDB key */
  241. memcpy(bnext, p->bdbkey, p->bdbkey->struct_size);
  242. bnext += p->bdbkey->struct_size;
  243. /* Copy OEM area 0 */
  244. oem = bnext;
  245. if (p->oem_area_0_size) {
  246. memcpy(bnext, p->oem_area_0, p->oem_area_0_size);
  247. bnext += p->oem_area_0_size;
  248. }
  249. /* Copy subkey */
  250. memcpy(bnext, p->subkey, p->subkey->struct_size);
  251. bnext += p->subkey->struct_size;
  252. /*
  253. * Create header signature using private BDB key.
  254. *
  255. * TODO: create the header signature in a totally separate step. That
  256. * way, the private BDB key is not required each time a BDB is created.
  257. */
  258. sig = bdb_create_sig(oem, h->signed_size, p->private_bdbkey,
  259. p->bdbkey->sig_alg, p->header_sig_description);
  260. memcpy(bnext, sig, sig->struct_size);
  261. bnext += sig->struct_size;
  262. /* Fill in the data */
  263. data = (struct bdb_data *)bnext;
  264. data->struct_magic = BDB_DATA_MAGIC;
  265. data->struct_major_version = BDB_DATA_VERSION_MAJOR;
  266. data->struct_minor_version = BDB_DATA_VERSION_MINOR;
  267. data->struct_size = sizeof(struct bdb_data);
  268. data->data_version = p->data_version;
  269. data->oem_area_1_size = p->oem_area_1_size;
  270. data->num_hashes = p->num_hashes;
  271. data->hash_entry_size = sizeof(struct bdb_hash);
  272. data->signed_size = data->struct_size + data->oem_area_1_size +
  273. hashes_size;
  274. if (p->data_description) {
  275. strzcpy(data->description, p->data_description,
  276. sizeof(data->description));
  277. }
  278. bnext += data->struct_size;
  279. /* Copy OEM area 1 */
  280. oem = bnext;
  281. if (p->oem_area_1_size) {
  282. memcpy(bnext, p->oem_area_1, p->oem_area_1_size);
  283. bnext += p->oem_area_1_size;
  284. }
  285. /* Copy hashes */
  286. memcpy(bnext, p->hash, hashes_size);
  287. bnext += hashes_size;
  288. /* Create data signature using private subkey */
  289. sig = bdb_create_sig(data, data->signed_size, p->private_subkey,
  290. p->subkey->sig_alg, p->data_sig_description);
  291. memcpy(bnext, sig, sig->struct_size);
  292. /* Return the BDB */
  293. return h;
  294. }