image-host.c 33 KB

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