image-host.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2013, Google Inc.
  4. *
  5. * (C) Copyright 2008 Semihalf
  6. *
  7. * (C) Copyright 2000-2006
  8. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  9. */
  10. #include "mkimage.h"
  11. #include <bootm.h>
  12. #include <image.h>
  13. #include <version.h>
  14. /**
  15. * fit_set_hash_value - set hash value in requested has node
  16. * @fit: pointer to the FIT format image header
  17. * @noffset: hash node offset
  18. * @value: hash value to be set
  19. * @value_len: hash value length
  20. *
  21. * fit_set_hash_value() attempts to set hash value in a node at offset
  22. * given and returns operation status to the caller.
  23. *
  24. * returns
  25. * 0, on success
  26. * -1, on failure
  27. */
  28. static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
  29. int value_len)
  30. {
  31. int ret;
  32. ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
  33. if (ret) {
  34. printf("Can't set hash '%s' property for '%s' node(%s)\n",
  35. FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
  36. fdt_strerror(ret));
  37. return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
  38. }
  39. return 0;
  40. }
  41. /**
  42. * fit_image_process_hash - Process a single subnode of the images/ node
  43. *
  44. * Check each subnode and process accordingly. For hash nodes we generate
  45. * a hash of the supplised data and store it in the node.
  46. *
  47. * @fit: pointer to the FIT format image header
  48. * @image_name: name of image being processes (used to display errors)
  49. * @noffset: subnode offset
  50. * @data: data to process
  51. * @size: size of data in bytes
  52. * @return 0 if ok, -1 on error
  53. */
  54. static int fit_image_process_hash(void *fit, const char *image_name,
  55. int noffset, const void *data, size_t size)
  56. {
  57. uint8_t value[FIT_MAX_HASH_LEN];
  58. const char *node_name;
  59. int value_len;
  60. char *algo;
  61. int ret;
  62. node_name = fit_get_name(fit, noffset, NULL);
  63. if (fit_image_hash_get_algo(fit, noffset, &algo)) {
  64. printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
  65. node_name, image_name);
  66. return -ENOENT;
  67. }
  68. if (calculate_hash(data, size, algo, value, &value_len)) {
  69. printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
  70. algo, node_name, image_name);
  71. return -EPROTONOSUPPORT;
  72. }
  73. ret = fit_set_hash_value(fit, noffset, value, value_len);
  74. if (ret) {
  75. printf("Can't set hash value for '%s' hash node in '%s' image node\n",
  76. node_name, image_name);
  77. return ret;
  78. }
  79. return 0;
  80. }
  81. /**
  82. * fit_image_write_sig() - write the signature to a FIT
  83. *
  84. * This writes the signature and signer data to the FIT.
  85. *
  86. * @fit: pointer to the FIT format image header
  87. * @noffset: hash node offset
  88. * @value: signature value to be set
  89. * @value_len: signature value length
  90. * @comment: Text comment to write (NULL for none)
  91. *
  92. * returns
  93. * 0, on success
  94. * -FDT_ERR_..., on failure
  95. */
  96. static int fit_image_write_sig(void *fit, int noffset, uint8_t *value,
  97. int value_len, const char *comment, const char *region_prop,
  98. int region_proplen, const char *cmdname)
  99. {
  100. int string_size;
  101. int ret;
  102. /*
  103. * Get the current string size, before we update the FIT and add
  104. * more
  105. */
  106. string_size = fdt_size_dt_strings(fit);
  107. ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
  108. if (!ret) {
  109. ret = fdt_setprop_string(fit, noffset, "signer-name",
  110. "mkimage");
  111. }
  112. if (!ret) {
  113. ret = fdt_setprop_string(fit, noffset, "signer-version",
  114. PLAIN_VERSION);
  115. }
  116. if (comment && !ret)
  117. ret = fdt_setprop_string(fit, noffset, "comment", comment);
  118. if (!ret) {
  119. time_t timestamp = imagetool_get_source_date(cmdname,
  120. time(NULL));
  121. ret = fit_set_timestamp(fit, noffset, timestamp);
  122. }
  123. if (region_prop && !ret) {
  124. uint32_t strdata[2];
  125. ret = fdt_setprop(fit, noffset, "hashed-nodes",
  126. region_prop, region_proplen);
  127. /* This is a legacy offset, it is unused, and must remain 0. */
  128. strdata[0] = 0;
  129. strdata[1] = cpu_to_fdt32(string_size);
  130. if (!ret) {
  131. ret = fdt_setprop(fit, noffset, "hashed-strings",
  132. strdata, sizeof(strdata));
  133. }
  134. }
  135. return ret;
  136. }
  137. static int fit_image_setup_sig(struct image_sign_info *info,
  138. const char *keydir, void *fit, const char *image_name,
  139. int noffset, const char *require_keys, const char *engine_id)
  140. {
  141. const char *node_name;
  142. char *algo_name;
  143. const char *padding_name;
  144. node_name = fit_get_name(fit, noffset, NULL);
  145. if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
  146. printf("Can't get algo property for '%s' signature node in '%s' image node\n",
  147. node_name, image_name);
  148. return -1;
  149. }
  150. padding_name = fdt_getprop(fit, noffset, "padding", NULL);
  151. memset(info, '\0', sizeof(*info));
  152. info->keydir = keydir;
  153. info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  154. info->fit = fit;
  155. info->node_offset = noffset;
  156. info->name = strdup(algo_name);
  157. info->checksum = image_get_checksum_algo(algo_name);
  158. info->crypto = image_get_crypto_algo(algo_name);
  159. info->padding = image_get_padding_algo(padding_name);
  160. info->require_keys = require_keys;
  161. info->engine_id = engine_id;
  162. if (!info->checksum || !info->crypto) {
  163. printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
  164. algo_name, node_name, image_name);
  165. return -1;
  166. }
  167. return 0;
  168. }
  169. /**
  170. * fit_image_process_sig- Process a single subnode of the images/ node
  171. *
  172. * Check each subnode and process accordingly. For signature nodes we
  173. * generate a signed hash of the supplised data and store it in the node.
  174. *
  175. * @keydir: Directory containing keys to use for signing
  176. * @keydest: Destination FDT blob to write public keys into
  177. * @fit: pointer to the FIT format image header
  178. * @image_name: name of image being processes (used to display errors)
  179. * @noffset: subnode offset
  180. * @data: data to process
  181. * @size: size of data in bytes
  182. * @comment: Comment to add to signature nodes
  183. * @require_keys: Mark all keys as 'required'
  184. * @engine_id: Engine to use for signing
  185. * @return 0 if ok, -1 on error
  186. */
  187. static int fit_image_process_sig(const char *keydir, void *keydest,
  188. void *fit, const char *image_name,
  189. int noffset, const void *data, size_t size,
  190. const char *comment, int require_keys, const char *engine_id,
  191. const char *cmdname)
  192. {
  193. struct image_sign_info info;
  194. struct image_region region;
  195. const char *node_name;
  196. uint8_t *value;
  197. uint value_len;
  198. int ret;
  199. if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset,
  200. require_keys ? "image" : NULL, engine_id))
  201. return -1;
  202. node_name = fit_get_name(fit, noffset, NULL);
  203. region.data = data;
  204. region.size = size;
  205. ret = info.crypto->sign(&info, &region, 1, &value, &value_len);
  206. if (ret) {
  207. printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
  208. node_name, image_name, ret);
  209. /* We allow keys to be missing */
  210. if (ret == -ENOENT)
  211. return 0;
  212. return -1;
  213. }
  214. ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
  215. NULL, 0, cmdname);
  216. if (ret) {
  217. if (ret == -FDT_ERR_NOSPACE)
  218. return -ENOSPC;
  219. printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
  220. node_name, image_name, fdt_strerror(ret));
  221. return -1;
  222. }
  223. free(value);
  224. /* Get keyname again, as FDT has changed and invalidated our pointer */
  225. info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  226. /*
  227. * Write the public key into the supplied FDT file; this might fail
  228. * several times, since we try signing with successively increasing
  229. * size values
  230. */
  231. if (keydest) {
  232. ret = info.crypto->add_verify_data(&info, keydest);
  233. if (ret) {
  234. printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
  235. node_name, image_name);
  236. return ret;
  237. }
  238. }
  239. return 0;
  240. }
  241. static int fit_image_read_data(char *filename, unsigned char *data,
  242. int expected_size)
  243. {
  244. struct stat sbuf;
  245. int fd, ret = -1;
  246. ssize_t n;
  247. /* Open file */
  248. fd = open(filename, O_RDONLY | O_BINARY);
  249. if (fd < 0) {
  250. printf("Can't open file %s (err=%d => %s)\n",
  251. filename, errno, strerror(errno));
  252. return -1;
  253. }
  254. /* Compute file size */
  255. if (fstat(fd, &sbuf) < 0) {
  256. printf("Can't fstat file %s (err=%d => %s)\n",
  257. filename, errno, strerror(errno));
  258. goto err;
  259. }
  260. /* Check file size */
  261. if (sbuf.st_size != expected_size) {
  262. printf("File %s don't have the expected size (size=%ld, expected=%d)\n",
  263. filename, sbuf.st_size, expected_size);
  264. goto err;
  265. }
  266. /* Read data */
  267. n = read(fd, data, sbuf.st_size);
  268. if (n < 0) {
  269. printf("Can't read file %s (err=%d => %s)\n",
  270. filename, errno, strerror(errno));
  271. goto err;
  272. }
  273. /* Check that we have read all the file */
  274. if (n != sbuf.st_size) {
  275. printf("Can't read all file %s (read %ld bytes, expexted %ld)\n",
  276. filename, n, sbuf.st_size);
  277. goto err;
  278. }
  279. ret = 0;
  280. err:
  281. close(fd);
  282. return ret;
  283. }
  284. static int fit_image_setup_cipher(struct image_cipher_info *info,
  285. const char *keydir, void *fit,
  286. const char *image_name, int image_noffset,
  287. const char *node_name, int noffset)
  288. {
  289. char *algo_name;
  290. char filename[128];
  291. int ret = -1;
  292. if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
  293. printf("Can't get algo name for cipher '%s' in image '%s'\n",
  294. node_name, image_name);
  295. goto out;
  296. }
  297. info->keydir = keydir;
  298. /* Read the key name */
  299. info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  300. if (!info->keyname) {
  301. printf("Can't get key name for cipher '%s' in image '%s'\n",
  302. node_name, image_name);
  303. goto out;
  304. }
  305. /* Read the IV name */
  306. info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
  307. if (!info->ivname) {
  308. printf("Can't get iv name for cipher '%s' in image '%s'\n",
  309. node_name, image_name);
  310. goto out;
  311. }
  312. info->fit = fit;
  313. info->node_noffset = noffset;
  314. info->name = algo_name;
  315. info->cipher = image_get_cipher_algo(algo_name);
  316. if (!info->cipher) {
  317. printf("Can't get algo for cipher '%s'\n", image_name);
  318. goto out;
  319. }
  320. /* Read the key in the file */
  321. snprintf(filename, sizeof(filename), "%s/%s%s",
  322. info->keydir, info->keyname, ".bin");
  323. info->key = malloc(info->cipher->key_len);
  324. if (!info->key) {
  325. printf("Can't allocate memory for key\n");
  326. ret = -1;
  327. goto out;
  328. }
  329. ret = fit_image_read_data(filename, (unsigned char *)info->key,
  330. info->cipher->key_len);
  331. if (ret < 0)
  332. goto out;
  333. /* Read the IV in the file */
  334. snprintf(filename, sizeof(filename), "%s/%s%s",
  335. info->keydir, info->ivname, ".bin");
  336. info->iv = malloc(info->cipher->iv_len);
  337. if (!info->iv) {
  338. printf("Can't allocate memory for iv\n");
  339. ret = -1;
  340. goto out;
  341. }
  342. ret = fit_image_read_data(filename, (unsigned char *)info->iv,
  343. info->cipher->iv_len);
  344. out:
  345. return ret;
  346. }
  347. int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
  348. const void *data, size_t size,
  349. unsigned char *data_ciphered, int data_ciphered_len)
  350. {
  351. int ret = -1;
  352. /* Remove unciphered data */
  353. ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
  354. if (ret) {
  355. printf("Can't remove data (err = %d)\n", ret);
  356. goto out;
  357. }
  358. /* Add ciphered data */
  359. ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
  360. data_ciphered, data_ciphered_len);
  361. if (ret) {
  362. printf("Can't add ciphered data (err = %d)\n", ret);
  363. goto out;
  364. }
  365. /* add non ciphered data size */
  366. ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
  367. if (ret) {
  368. printf("Can't add unciphered data size (err = %d)\n", ret);
  369. goto out;
  370. }
  371. out:
  372. return ret;
  373. }
  374. static int
  375. fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
  376. const char *image_name, int image_noffset,
  377. const char *node_name, int node_noffset,
  378. const void *data, size_t size,
  379. const char *cmdname)
  380. {
  381. struct image_cipher_info info;
  382. unsigned char *data_ciphered = NULL;
  383. int data_ciphered_len;
  384. int ret;
  385. memset(&info, 0, sizeof(info));
  386. ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
  387. image_noffset, node_name, node_noffset);
  388. if (ret)
  389. goto out;
  390. ret = info.cipher->encrypt(&info, data, size,
  391. &data_ciphered, &data_ciphered_len);
  392. if (ret)
  393. goto out;
  394. /*
  395. * Write the public key into the supplied FDT file; this might fail
  396. * several times, since we try signing with successively increasing
  397. * size values
  398. */
  399. if (keydest) {
  400. ret = info.cipher->add_cipher_data(&info, keydest);
  401. if (ret) {
  402. printf("Failed to add verification data for cipher '%s' in image '%s'\n",
  403. info.keyname, image_name);
  404. goto out;
  405. }
  406. }
  407. ret = fit_image_write_cipher(fit, image_noffset, node_noffset,
  408. data, size,
  409. data_ciphered, data_ciphered_len);
  410. out:
  411. free(data_ciphered);
  412. free((void *)info.key);
  413. free((void *)info.iv);
  414. return ret;
  415. }
  416. int fit_image_cipher_data(const char *keydir, void *keydest,
  417. void *fit, int image_noffset, const char *comment,
  418. int require_keys, const char *engine_id,
  419. const char *cmdname)
  420. {
  421. const char *image_name;
  422. const void *data;
  423. size_t size;
  424. int node_noffset;
  425. /* Get image name */
  426. image_name = fit_get_name(fit, image_noffset, NULL);
  427. if (!image_name) {
  428. printf("Can't get image name\n");
  429. return -1;
  430. }
  431. /* Get image data and data length */
  432. if (fit_image_get_data(fit, image_noffset, &data, &size)) {
  433. printf("Can't get image data/size\n");
  434. return -1;
  435. }
  436. /* Process all hash subnodes of the component image node */
  437. for (node_noffset = fdt_first_subnode(fit, image_noffset);
  438. node_noffset >= 0;
  439. node_noffset = fdt_next_subnode(fit, node_noffset)) {
  440. const char *node_name;
  441. int ret = 0;
  442. node_name = fit_get_name(fit, node_noffset, NULL);
  443. if (!node_name) {
  444. printf("Can't get node name\n");
  445. return -1;
  446. }
  447. if (IMAGE_ENABLE_ENCRYPT && keydir &&
  448. !strncmp(node_name, FIT_CIPHER_NODENAME,
  449. strlen(FIT_CIPHER_NODENAME)))
  450. ret = fit_image_process_cipher(keydir, keydest,
  451. fit, image_name,
  452. image_noffset,
  453. node_name, node_noffset,
  454. data, size, cmdname);
  455. if (ret)
  456. return ret;
  457. }
  458. return 0;
  459. }
  460. /**
  461. * fit_image_add_verification_data() - calculate/set verig. data for image node
  462. *
  463. * This adds hash and signature values for an component image node.
  464. *
  465. * All existing hash subnodes are checked, if algorithm property is set to
  466. * one of the supported hash algorithms, hash value is computed and
  467. * corresponding hash node property is set, for example:
  468. *
  469. * Input component image node structure:
  470. *
  471. * o image-1 (at image_noffset)
  472. * | - data = [binary data]
  473. * o hash-1
  474. * |- algo = "sha1"
  475. *
  476. * Output component image node structure:
  477. *
  478. * o image-1 (at image_noffset)
  479. * | - data = [binary data]
  480. * o hash-1
  481. * |- algo = "sha1"
  482. * |- value = sha1(data)
  483. *
  484. * For signature details, please see doc/uImage.FIT/signature.txt
  485. *
  486. * @keydir Directory containing *.key and *.crt files (or NULL)
  487. * @keydest FDT Blob to write public keys into (NULL if none)
  488. * @fit: Pointer to the FIT format image header
  489. * @image_noffset: Requested component image node
  490. * @comment: Comment to add to signature nodes
  491. * @require_keys: Mark all keys as 'required'
  492. * @engine_id: Engine to use for signing
  493. * @return: 0 on success, <0 on failure
  494. */
  495. int fit_image_add_verification_data(const char *keydir, void *keydest,
  496. void *fit, int image_noffset, const char *comment,
  497. int require_keys, const char *engine_id, const char *cmdname)
  498. {
  499. const char *image_name;
  500. const void *data;
  501. size_t size;
  502. int noffset;
  503. /* Get image data and data length */
  504. if (fit_image_get_data(fit, image_noffset, &data, &size)) {
  505. printf("Can't get image data/size\n");
  506. return -1;
  507. }
  508. image_name = fit_get_name(fit, image_noffset, NULL);
  509. /* Process all hash subnodes of the component image node */
  510. for (noffset = fdt_first_subnode(fit, image_noffset);
  511. noffset >= 0;
  512. noffset = fdt_next_subnode(fit, noffset)) {
  513. const char *node_name;
  514. int ret = 0;
  515. /*
  516. * Check subnode name, must be equal to "hash" or "signature".
  517. * Multiple hash nodes require unique unit node
  518. * names, e.g. hash-1, hash-2, signature-1, etc.
  519. */
  520. node_name = fit_get_name(fit, noffset, NULL);
  521. if (!strncmp(node_name, FIT_HASH_NODENAME,
  522. strlen(FIT_HASH_NODENAME))) {
  523. ret = fit_image_process_hash(fit, image_name, noffset,
  524. data, size);
  525. } else if (IMAGE_ENABLE_SIGN && keydir &&
  526. !strncmp(node_name, FIT_SIG_NODENAME,
  527. strlen(FIT_SIG_NODENAME))) {
  528. ret = fit_image_process_sig(keydir, keydest,
  529. fit, image_name, noffset, data, size,
  530. comment, require_keys, engine_id, cmdname);
  531. }
  532. if (ret)
  533. return ret;
  534. }
  535. return 0;
  536. }
  537. struct strlist {
  538. int count;
  539. char **strings;
  540. };
  541. static void strlist_init(struct strlist *list)
  542. {
  543. memset(list, '\0', sizeof(*list));
  544. }
  545. static void strlist_free(struct strlist *list)
  546. {
  547. int i;
  548. for (i = 0; i < list->count; i++)
  549. free(list->strings[i]);
  550. free(list->strings);
  551. }
  552. static int strlist_add(struct strlist *list, const char *str)
  553. {
  554. char *dup;
  555. dup = strdup(str);
  556. list->strings = realloc(list->strings,
  557. (list->count + 1) * sizeof(char *));
  558. if (!list || !str)
  559. return -1;
  560. list->strings[list->count++] = dup;
  561. return 0;
  562. }
  563. static const char *fit_config_get_image_list(void *fit, int noffset,
  564. int *lenp, int *allow_missingp)
  565. {
  566. static const char default_list[] = FIT_KERNEL_PROP "\0"
  567. FIT_FDT_PROP;
  568. const char *prop;
  569. /* If there is an "image" property, use that */
  570. prop = fdt_getprop(fit, noffset, "sign-images", lenp);
  571. if (prop) {
  572. *allow_missingp = 0;
  573. return *lenp ? prop : NULL;
  574. }
  575. /* Default image list */
  576. *allow_missingp = 1;
  577. *lenp = sizeof(default_list);
  578. return default_list;
  579. }
  580. static int fit_config_get_hash_list(void *fit, int conf_noffset,
  581. int sig_offset, struct strlist *node_inc)
  582. {
  583. int allow_missing;
  584. const char *prop, *iname, *end;
  585. const char *conf_name, *sig_name;
  586. char name[200], path[200];
  587. int image_count;
  588. int ret, len;
  589. conf_name = fit_get_name(fit, conf_noffset, NULL);
  590. sig_name = fit_get_name(fit, sig_offset, NULL);
  591. /*
  592. * Build a list of nodes we need to hash. We always need the root
  593. * node and the configuration.
  594. */
  595. strlist_init(node_inc);
  596. snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, conf_name);
  597. if (strlist_add(node_inc, "/") ||
  598. strlist_add(node_inc, name))
  599. goto err_mem;
  600. /* Get a list of images that we intend to sign */
  601. prop = fit_config_get_image_list(fit, sig_offset, &len,
  602. &allow_missing);
  603. if (!prop)
  604. return 0;
  605. /* Locate the images */
  606. end = prop + len;
  607. image_count = 0;
  608. for (iname = prop; iname < end; iname += strlen(iname) + 1) {
  609. int noffset;
  610. int image_noffset;
  611. int hash_count;
  612. image_noffset = fit_conf_get_prop_node(fit, conf_noffset,
  613. iname);
  614. if (image_noffset < 0) {
  615. printf("Failed to find image '%s' in configuration '%s/%s'\n",
  616. iname, conf_name, sig_name);
  617. if (allow_missing)
  618. continue;
  619. return -ENOENT;
  620. }
  621. ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
  622. if (ret < 0)
  623. goto err_path;
  624. if (strlist_add(node_inc, path))
  625. goto err_mem;
  626. snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH,
  627. conf_name);
  628. /* Add all this image's hashes */
  629. hash_count = 0;
  630. for (noffset = fdt_first_subnode(fit, image_noffset);
  631. noffset >= 0;
  632. noffset = fdt_next_subnode(fit, noffset)) {
  633. const char *name = fit_get_name(fit, noffset, NULL);
  634. if (strncmp(name, FIT_HASH_NODENAME,
  635. strlen(FIT_HASH_NODENAME)))
  636. continue;
  637. ret = fdt_get_path(fit, noffset, path, sizeof(path));
  638. if (ret < 0)
  639. goto err_path;
  640. if (strlist_add(node_inc, path))
  641. goto err_mem;
  642. hash_count++;
  643. }
  644. if (!hash_count) {
  645. printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
  646. conf_name, sig_name, iname);
  647. return -ENOMSG;
  648. }
  649. image_count++;
  650. }
  651. if (!image_count) {
  652. printf("Failed to find any images for configuration '%s/%s'\n",
  653. conf_name, sig_name);
  654. return -ENOMSG;
  655. }
  656. return 0;
  657. err_mem:
  658. printf("Out of memory processing configuration '%s/%s'\n", conf_name,
  659. sig_name);
  660. return -ENOMEM;
  661. err_path:
  662. printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
  663. iname, conf_name, sig_name, fdt_strerror(ret));
  664. return -ENOENT;
  665. }
  666. static int fit_config_get_data(void *fit, int conf_noffset, int noffset,
  667. struct image_region **regionp, int *region_countp,
  668. char **region_propp, int *region_proplen)
  669. {
  670. char * const exc_prop[] = {"data"};
  671. struct strlist node_inc;
  672. struct image_region *region;
  673. struct fdt_region fdt_regions[100];
  674. const char *conf_name, *sig_name;
  675. char path[200];
  676. int count, i;
  677. char *region_prop;
  678. int ret, len;
  679. conf_name = fit_get_name(fit, conf_noffset, NULL);
  680. sig_name = fit_get_name(fit, noffset, NULL);
  681. debug("%s: conf='%s', sig='%s'\n", __func__, conf_name, sig_name);
  682. /* Get a list of nodes we want to hash */
  683. ret = fit_config_get_hash_list(fit, conf_noffset, noffset, &node_inc);
  684. if (ret)
  685. return ret;
  686. /* Get a list of regions to hash */
  687. count = fdt_find_regions(fit, node_inc.strings, node_inc.count,
  688. exc_prop, ARRAY_SIZE(exc_prop),
  689. fdt_regions, ARRAY_SIZE(fdt_regions),
  690. path, sizeof(path), 1);
  691. if (count < 0) {
  692. printf("Failed to hash configuration '%s/%s': %s\n", conf_name,
  693. sig_name, fdt_strerror(ret));
  694. return -EIO;
  695. }
  696. if (count == 0) {
  697. printf("No data to hash for configuration '%s/%s': %s\n",
  698. conf_name, sig_name, fdt_strerror(ret));
  699. return -EINVAL;
  700. }
  701. /* Build our list of data blocks */
  702. region = fit_region_make_list(fit, fdt_regions, count, NULL);
  703. if (!region) {
  704. printf("Out of memory hashing configuration '%s/%s'\n",
  705. conf_name, sig_name);
  706. return -ENOMEM;
  707. }
  708. /* Create a list of all hashed properties */
  709. debug("Hash nodes:\n");
  710. for (i = len = 0; i < node_inc.count; i++) {
  711. debug(" %s\n", node_inc.strings[i]);
  712. len += strlen(node_inc.strings[i]) + 1;
  713. }
  714. region_prop = malloc(len);
  715. if (!region_prop) {
  716. printf("Out of memory setting up regions for configuration '%s/%s'\n",
  717. conf_name, sig_name);
  718. return -ENOMEM;
  719. }
  720. for (i = len = 0; i < node_inc.count;
  721. len += strlen(node_inc.strings[i]) + 1, i++)
  722. strcpy(region_prop + len, node_inc.strings[i]);
  723. strlist_free(&node_inc);
  724. *region_countp = count;
  725. *regionp = region;
  726. *region_propp = region_prop;
  727. *region_proplen = len;
  728. return 0;
  729. }
  730. static int fit_config_process_sig(const char *keydir, void *keydest,
  731. void *fit, const char *conf_name, int conf_noffset,
  732. int noffset, const char *comment, int require_keys,
  733. const char *engine_id, const char *cmdname)
  734. {
  735. struct image_sign_info info;
  736. const char *node_name;
  737. struct image_region *region;
  738. char *region_prop;
  739. int region_proplen;
  740. int region_count;
  741. uint8_t *value;
  742. uint value_len;
  743. int ret;
  744. node_name = fit_get_name(fit, noffset, NULL);
  745. if (fit_config_get_data(fit, conf_noffset, noffset, &region,
  746. &region_count, &region_prop, &region_proplen))
  747. return -1;
  748. if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset,
  749. require_keys ? "conf" : NULL, engine_id))
  750. return -1;
  751. ret = info.crypto->sign(&info, region, region_count, &value,
  752. &value_len);
  753. free(region);
  754. if (ret) {
  755. printf("Failed to sign '%s' signature node in '%s' conf node\n",
  756. node_name, conf_name);
  757. /* We allow keys to be missing */
  758. if (ret == -ENOENT)
  759. return 0;
  760. return -1;
  761. }
  762. ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
  763. region_prop, region_proplen, cmdname);
  764. if (ret) {
  765. if (ret == -FDT_ERR_NOSPACE)
  766. return -ENOSPC;
  767. printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
  768. node_name, conf_name, fdt_strerror(ret));
  769. return -1;
  770. }
  771. free(value);
  772. free(region_prop);
  773. /* Get keyname again, as FDT has changed and invalidated our pointer */
  774. info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
  775. /* Write the public key into the supplied FDT file */
  776. if (keydest) {
  777. ret = info.crypto->add_verify_data(&info, keydest);
  778. if (ret) {
  779. printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n",
  780. node_name, conf_name);
  781. }
  782. return ret;
  783. }
  784. return 0;
  785. }
  786. static int fit_config_add_verification_data(const char *keydir, void *keydest,
  787. void *fit, int conf_noffset, const char *comment,
  788. int require_keys, const char *engine_id, const char *cmdname)
  789. {
  790. const char *conf_name;
  791. int noffset;
  792. conf_name = fit_get_name(fit, conf_noffset, NULL);
  793. /* Process all hash subnodes of the configuration node */
  794. for (noffset = fdt_first_subnode(fit, conf_noffset);
  795. noffset >= 0;
  796. noffset = fdt_next_subnode(fit, noffset)) {
  797. const char *node_name;
  798. int ret = 0;
  799. node_name = fit_get_name(fit, noffset, NULL);
  800. if (!strncmp(node_name, FIT_SIG_NODENAME,
  801. strlen(FIT_SIG_NODENAME))) {
  802. ret = fit_config_process_sig(keydir, keydest,
  803. fit, conf_name, conf_noffset, noffset, comment,
  804. require_keys, engine_id, cmdname);
  805. }
  806. if (ret)
  807. return ret;
  808. }
  809. return 0;
  810. }
  811. int fit_cipher_data(const char *keydir, void *keydest, void *fit,
  812. const char *comment, int require_keys,
  813. const char *engine_id, const char *cmdname)
  814. {
  815. int images_noffset;
  816. int noffset;
  817. int ret;
  818. /* Find images parent node offset */
  819. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  820. if (images_noffset < 0) {
  821. printf("Can't find images parent node '%s' (%s)\n",
  822. FIT_IMAGES_PATH, fdt_strerror(images_noffset));
  823. return images_noffset;
  824. }
  825. /* Process its subnodes, print out component images details */
  826. for (noffset = fdt_first_subnode(fit, images_noffset);
  827. noffset >= 0;
  828. noffset = fdt_next_subnode(fit, noffset)) {
  829. /*
  830. * Direct child node of the images parent node,
  831. * i.e. component image node.
  832. */
  833. ret = fit_image_cipher_data(keydir, keydest,
  834. fit, noffset, comment,
  835. require_keys, engine_id,
  836. cmdname);
  837. if (ret)
  838. return ret;
  839. }
  840. return 0;
  841. }
  842. int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
  843. const char *comment, int require_keys,
  844. const char *engine_id, const char *cmdname)
  845. {
  846. int images_noffset, confs_noffset;
  847. int noffset;
  848. int ret;
  849. /* Find images parent node offset */
  850. images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
  851. if (images_noffset < 0) {
  852. printf("Can't find images parent node '%s' (%s)\n",
  853. FIT_IMAGES_PATH, fdt_strerror(images_noffset));
  854. return images_noffset;
  855. }
  856. /* Process its subnodes, print out component images details */
  857. for (noffset = fdt_first_subnode(fit, images_noffset);
  858. noffset >= 0;
  859. noffset = fdt_next_subnode(fit, noffset)) {
  860. /*
  861. * Direct child node of the images parent node,
  862. * i.e. component image node.
  863. */
  864. ret = fit_image_add_verification_data(keydir, keydest,
  865. fit, noffset, comment, require_keys, engine_id,
  866. cmdname);
  867. if (ret)
  868. return ret;
  869. }
  870. /* If there are no keys, we can't sign configurations */
  871. if (!IMAGE_ENABLE_SIGN || !keydir)
  872. return 0;
  873. /* Find configurations parent node offset */
  874. confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
  875. if (confs_noffset < 0) {
  876. printf("Can't find images parent node '%s' (%s)\n",
  877. FIT_CONFS_PATH, fdt_strerror(confs_noffset));
  878. return -ENOENT;
  879. }
  880. /* Process its subnodes, print out component images details */
  881. for (noffset = fdt_first_subnode(fit, confs_noffset);
  882. noffset >= 0;
  883. noffset = fdt_next_subnode(fit, noffset)) {
  884. ret = fit_config_add_verification_data(keydir, keydest,
  885. fit, noffset, comment,
  886. require_keys,
  887. engine_id, cmdname);
  888. if (ret)
  889. return ret;
  890. }
  891. return 0;
  892. }
  893. #ifdef CONFIG_FIT_SIGNATURE
  894. int fit_check_sign(const void *fit, const void *key,
  895. const char *fit_uname_config)
  896. {
  897. int cfg_noffset;
  898. int ret;
  899. cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
  900. if (!cfg_noffset)
  901. return -1;
  902. printf("Verifying Hash Integrity for node '%s'... ",
  903. fdt_get_name(fit, cfg_noffset, NULL));
  904. ret = fit_config_verify(fit, cfg_noffset);
  905. if (ret)
  906. return ret;
  907. printf("Verified OK, loading images\n");
  908. ret = bootm_host_load_images(fit, cfg_noffset);
  909. return ret;
  910. }
  911. #endif