beaglebone_vboot.txt 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. Verified Boot on the Beaglebone Black
  2. =====================================
  3. Introduction
  4. ------------
  5. Before reading this, please read verified-boot.txt and signature.txt. These
  6. instructions are for mainline U-Boot from v2014.07 onwards.
  7. There is quite a bit of documentation in this directory describing how
  8. verified boot works in U-Boot. There is also a test which runs through the
  9. entire process of signing an image and running U-Boot (sandbox) to check it.
  10. However, it might be useful to also have an example on a real board.
  11. Beaglebone Black is a fairly common board so seems to be a reasonable choice
  12. for an example of how to enable verified boot using U-Boot.
  13. First a note that may to help avoid confusion. U-Boot and Linux both use
  14. device tree. They may use the same device tree source, but it is seldom useful
  15. for them to use the exact same binary from the same place. More typically,
  16. U-Boot has its device tree packaged wtih it, and the kernel's device tree is
  17. packaged with the kernel. In particular this is important with verified boot,
  18. since U-Boot's device tree must be immutable. If it can be changed then the
  19. public keys can be changed and verified boot is useless. An attacker can
  20. simply generate a new key and put his public key into U-Boot so that
  21. everything verifies. On the other hand the kernel's device tree typically
  22. changes when the kernel changes, so it is useful to package an updated device
  23. tree with the kernel binary. U-Boot supports the latter with its flexible FIT
  24. format (Flat Image Tree).
  25. Overview
  26. --------
  27. The steps are roughly as follows:
  28. 1. Build U-Boot for the board, with the verified boot options enabled.
  29. 2. Obtain a suitable Linux kernel
  30. 3. Create a Image Tree Source file (ITS) file describing how you want the
  31. kernel to be packaged, compressed and signed.
  32. 4. Create a key pair
  33. 5. Sign the kernel
  34. 6. Put the public key into U-Boot's image
  35. 7. Put U-Boot and the kernel onto the board
  36. 8. Try it
  37. Step 1: Build U-Boot
  38. --------------------
  39. a. Set up the environment variable to point to your toolchain. You will need
  40. this for U-Boot and also for the kernel if you build it. For example if you
  41. installed a Linaro version manually it might be something like:
  42. export CROSS_COMPILE=/opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux/bin/arm-linux-gnueabihf-
  43. or if you just installed gcc-arm-linux-gnueabi then it might be
  44. export CROSS_COMPILE=arm-linux-gnueabi-
  45. b. Configure and build U-Boot with verified boot enabled:
  46. export UBOOT=/path/to/u-boot
  47. cd $UBOOT
  48. # You can add -j10 if you have 10 CPUs to make it faster
  49. make O=b/am335x_boneblack_vboot am335x_boneblack_vboot_config all
  50. export UOUT=$UBOOT/b/am335x_boneblack_vboot
  51. c. You will now have a U-Boot image:
  52. file b/am335x_boneblack_vboot/u-boot-dtb.img
  53. b/am335x_boneblack_vboot/u-boot-dtb.img: u-boot legacy uImage, U-Boot 2014.07-rc2-00065-g2f69f8, Firmware/ARM, Firmware Image (Not compressed), 395375 bytes, Sat May 31 16:19:04 2014, Load Address: 0x80800000, Entry Point: 0x00000000, Header CRC: 0x0ABD6ACA, Data CRC: 0x36DEF7E4
  54. Step 2: Build Linux
  55. --------------------
  56. a. Find the kernel image ('Image') and device tree (.dtb) file you plan to
  57. use. In our case it is am335x-boneblack.dtb and it is built with the kernel.
  58. At the time of writing an SD Boot image can be obtained from here:
  59. http://www.elinux.org/Beagleboard:Updating_The_Software#Image_For_Booting_From_microSD
  60. You can write this to an SD card and then mount it to extract the kernel and
  61. device tree files.
  62. You can also build a kernel. Instructions for this are are here:
  63. http://elinux.org/Building_BBB_Kernel
  64. or you can use your favourite search engine. Following these instructions
  65. produces a kernel Image and device tree files. For the record the steps were:
  66. export KERNEL=/path/to/kernel
  67. cd $KERNEL
  68. git clone git://github.com/beagleboard/kernel.git .
  69. git checkout v3.14
  70. ./patch.sh
  71. cp configs/beaglebone kernel/arch/arm/configs/beaglebone_defconfig
  72. cd kernel
  73. make beaglebone_defconfig
  74. make uImage dtbs # -j10 if you have 10 CPUs
  75. export OKERNEL=$KERNEL/kernel/arch/arm/boot
  76. c. You now have the 'Image' and 'am335x-boneblack.dtb' files needed to boot.
  77. Step 3: Create the ITS
  78. ----------------------
  79. Set up a directory for your work.
  80. export WORK=/path/to/dir
  81. cd $WORK
  82. Put this into a file in that directory called sign.its:
  83. /dts-v1/;
  84. / {
  85. description = "Beaglebone black";
  86. #address-cells = <1>;
  87. images {
  88. kernel {
  89. data = /incbin/("Image.lzo");
  90. type = "kernel";
  91. arch = "arm";
  92. os = "linux";
  93. compression = "lzo";
  94. load = <0x80008000>;
  95. entry = <0x80008000>;
  96. hash-1 {
  97. algo = "sha1";
  98. };
  99. };
  100. fdt-1 {
  101. description = "beaglebone-black";
  102. data = /incbin/("am335x-boneblack.dtb");
  103. type = "flat_dt";
  104. arch = "arm";
  105. compression = "none";
  106. hash-1 {
  107. algo = "sha1";
  108. };
  109. };
  110. };
  111. configurations {
  112. default = "conf-1";
  113. conf-1 {
  114. kernel = "kernel";
  115. fdt = "fdt-1";
  116. signature-1 {
  117. algo = "sha1,rsa2048";
  118. key-name-hint = "dev";
  119. sign-images = "fdt", "kernel";
  120. };
  121. };
  122. };
  123. };
  124. The explanation for this is all in the documentation you have already read.
  125. But briefly it packages a kernel and device tree, and provides a single
  126. configuration to be signed with a key named 'dev'. The kernel is compressed
  127. with LZO to make it smaller.
  128. Step 4: Create a key pair
  129. -------------------------
  130. See signature.txt for details on this step.
  131. cd $WORK
  132. mkdir keys
  133. openssl genrsa -F4 -out keys/dev.key 2048
  134. openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt
  135. Note: keys/dev.key contains your private key and is very secret. If anyone
  136. gets access to that file they can sign kernels with it. Keep it secure.
  137. Step 5: Sign the kernel
  138. -----------------------
  139. We need to use mkimage (which was built when you built U-Boot) to package the
  140. Linux kernel into a FIT (Flat Image Tree, a flexible file format that U-Boot
  141. can load) using the ITS file you just created.
  142. At the same time we must put the public key into U-Boot device tree, with the
  143. 'required' property, which tells U-Boot that this key must be verified for the
  144. image to be valid. You will make this key available to U-Boot for booting in
  145. step 6.
  146. ln -s $OKERNEL/dts/am335x-boneblack.dtb
  147. ln -s $OKERNEL/Image
  148. ln -s $UOUT/u-boot-dtb.img
  149. cp $UOUT/arch/arm/dts/am335x-boneblack.dtb am335x-boneblack-pubkey.dtb
  150. lzop Image
  151. $UOUT/tools/mkimage -f sign.its -K am335x-boneblack-pubkey.dtb -k keys -r image.fit
  152. You should see something like this:
  153. FIT description: Beaglebone black
  154. Created: Sun Jun 1 12:50:30 2014
  155. Image 0 (kernel)
  156. Description: unavailable
  157. Created: Sun Jun 1 12:50:30 2014
  158. Type: Kernel Image
  159. Compression: lzo compressed
  160. Data Size: 7790938 Bytes = 7608.34 kB = 7.43 MB
  161. Architecture: ARM
  162. OS: Linux
  163. Load Address: 0x80008000
  164. Entry Point: 0x80008000
  165. Hash algo: sha1
  166. Hash value: c94364646427e10f423837e559898ef02c97b988
  167. Image 1 (fdt-1)
  168. Description: beaglebone-black
  169. Created: Sun Jun 1 12:50:30 2014
  170. Type: Flat Device Tree
  171. Compression: uncompressed
  172. Data Size: 31547 Bytes = 30.81 kB = 0.03 MB
  173. Architecture: ARM
  174. Hash algo: sha1
  175. Hash value: cb09202f889d824f23b8e4404b781be5ad38a68d
  176. Default Configuration: 'conf-1'
  177. Configuration 0 (conf-1)
  178. Description: unavailable
  179. Kernel: kernel
  180. FDT: fdt-1
  181. Now am335x-boneblack-pubkey.dtb contains the public key and image.fit contains
  182. the signed kernel. Jump to step 6 if you like, or continue reading to increase
  183. your understanding.
  184. You can also run fit_check_sign to check it:
  185. $UOUT/tools/fit_check_sign -f image.fit -k am335x-boneblack-pubkey.dtb
  186. which results in:
  187. Verifying Hash Integrity ... sha1,rsa2048:dev+
  188. ## Loading kernel from FIT Image at 7fc6ee469000 ...
  189. Using 'conf-1' configuration
  190. Verifying Hash Integrity ...
  191. sha1,rsa2048:dev+
  192. OK
  193. Trying 'kernel' kernel subimage
  194. Description: unavailable
  195. Created: Sun Jun 1 12:50:30 2014
  196. Type: Kernel Image
  197. Compression: lzo compressed
  198. Data Size: 7790938 Bytes = 7608.34 kB = 7.43 MB
  199. Architecture: ARM
  200. OS: Linux
  201. Load Address: 0x80008000
  202. Entry Point: 0x80008000
  203. Hash algo: sha1
  204. Hash value: c94364646427e10f423837e559898ef02c97b988
  205. Verifying Hash Integrity ...
  206. sha1+
  207. OK
  208. Unimplemented compression type 4
  209. ## Loading fdt from FIT Image at 7fc6ee469000 ...
  210. Using 'conf-1' configuration
  211. Trying 'fdt-1' fdt subimage
  212. Description: beaglebone-black
  213. Created: Sun Jun 1 12:50:30 2014
  214. Type: Flat Device Tree
  215. Compression: uncompressed
  216. Data Size: 31547 Bytes = 30.81 kB = 0.03 MB
  217. Architecture: ARM
  218. Hash algo: sha1
  219. Hash value: cb09202f889d824f23b8e4404b781be5ad38a68d
  220. Verifying Hash Integrity ...
  221. sha1+
  222. OK
  223. Loading Flat Device Tree ... OK
  224. ## Loading ramdisk from FIT Image at 7fc6ee469000 ...
  225. Using 'conf-1' configuration
  226. Could not find subimage node
  227. Signature check OK
  228. At the top, you see "sha1,rsa2048:dev+". This means that it checked an RSA key
  229. of size 2048 bits using SHA1 as the hash algorithm. The key name checked was
  230. 'dev' and the '+' means that it verified. If it showed '-' that would be bad.
  231. Once the configuration is verified it is then possible to rely on the hashes
  232. in each image referenced by that configuration. So fit_check_sign goes on to
  233. load each of the images. We have a kernel and an FDT but no ramkdisk. In each
  234. case fit_check_sign checks the hash and prints sha1+ meaning that the SHA1
  235. hash verified. This means that none of the images has been tampered with.
  236. There is a test in test/vboot which uses U-Boot's sandbox build to verify that
  237. the above flow works.
  238. But it is fun to do this by hand, so you can load image.fit into a hex editor
  239. like ghex, and change a byte in the kernel:
  240. $UOUT/tools/fit_info -f image.fit -n /images/kernel -p data
  241. NAME: kernel
  242. LEN: 7790938
  243. OFF: 168
  244. This tells us that the kernel starts at byte offset 168 (decimal) in image.fit
  245. and extends for about 7MB. Try changing a byte at 0x2000 (say) and run
  246. fit_check_sign again. You should see something like:
  247. Verifying Hash Integrity ... sha1,rsa2048:dev+
  248. ## Loading kernel from FIT Image at 7f5a39571000 ...
  249. Using 'conf-1' configuration
  250. Verifying Hash Integrity ...
  251. sha1,rsa2048:dev+
  252. OK
  253. Trying 'kernel' kernel subimage
  254. Description: unavailable
  255. Created: Sun Jun 1 13:09:21 2014
  256. Type: Kernel Image
  257. Compression: lzo compressed
  258. Data Size: 7790938 Bytes = 7608.34 kB = 7.43 MB
  259. Architecture: ARM
  260. OS: Linux
  261. Load Address: 0x80008000
  262. Entry Point: 0x80008000
  263. Hash algo: sha1
  264. Hash value: c94364646427e10f423837e559898ef02c97b988
  265. Verifying Hash Integrity ...
  266. sha1 error
  267. Bad hash value for 'hash-1' hash node in 'kernel' image node
  268. Bad Data Hash
  269. ## Loading fdt from FIT Image at 7f5a39571000 ...
  270. Using 'conf-1' configuration
  271. Trying 'fdt-1' fdt subimage
  272. Description: beaglebone-black
  273. Created: Sun Jun 1 13:09:21 2014
  274. Type: Flat Device Tree
  275. Compression: uncompressed
  276. Data Size: 31547 Bytes = 30.81 kB = 0.03 MB
  277. Architecture: ARM
  278. Hash algo: sha1
  279. Hash value: cb09202f889d824f23b8e4404b781be5ad38a68d
  280. Verifying Hash Integrity ...
  281. sha1+
  282. OK
  283. Loading Flat Device Tree ... OK
  284. ## Loading ramdisk from FIT Image at 7f5a39571000 ...
  285. Using 'conf-1' configuration
  286. Could not find subimage node
  287. Signature check Bad (error 1)
  288. It has detected the change in the kernel.
  289. You can also be sneaky and try to switch images, using the libfdt utilities
  290. that come with dtc (package name is device-tree-compiler but you will need a
  291. recent version like 1.4:
  292. dtc -v
  293. Version: DTC 1.4.0
  294. First we can check which nodes are actually hashed by the configuration:
  295. fdtget -l image.fit /
  296. images
  297. configurations
  298. fdtget -l image.fit /configurations
  299. conf-1
  300. fdtget -l image.fit /configurations/conf-1
  301. signature-1
  302. fdtget -p image.fit /configurations/conf-1/signature-1
  303. hashed-strings
  304. hashed-nodes
  305. timestamp
  306. signer-version
  307. signer-name
  308. value
  309. algo
  310. key-name-hint
  311. sign-images
  312. fdtget image.fit /configurations/conf-1/signature-1 hashed-nodes
  313. / /configurations/conf-1 /images/fdt-1 /images/fdt-1/hash /images/kernel /images/kernel/hash-1
  314. This gives us a bit of a look into the signature that mkimage added. Note you
  315. can also use fdtdump to list the entire device tree.
  316. Say we want to change the kernel that this configuration uses
  317. (/images/kernel). We could just put a new kernel in the image, but we will
  318. need to change the hash to match. Let's simulate that by changing a byte of
  319. the hash:
  320. fdtget -tx image.fit /images/kernel/hash-1 value
  321. c9436464 6427e10f 423837e5 59898ef0 2c97b988
  322. fdtput -tx image.fit /images/kernel/hash-1 value c9436464 6427e10f 423837e5 59898ef0 2c97b981
  323. Now check it again:
  324. $UOUT/tools/fit_check_sign -f image.fit -k am335x-boneblack-pubkey.dtb
  325. Verifying Hash Integrity ... sha1,rsa2048:devrsa_verify_with_keynode: RSA failed to verify: -13
  326. rsa_verify_with_keynode: RSA failed to verify: -13
  327. -
  328. Failed to verify required signature 'key-dev'
  329. Signature check Bad (error 1)
  330. This time we don't even get as far as checking the images, since the
  331. configuration signature doesn't match. We can't change any hashes without the
  332. signature check noticing. The configuration is essentially locked. U-Boot has
  333. a public key for which it requires a match, and will not permit the use of any
  334. configuration that does not match that public key. The only way the
  335. configuration will match is if it was signed by the matching private key.
  336. It would also be possible to add a new signature node that does match your new
  337. configuration. But that won't work since you are not allowed to change the
  338. configuration in any way. Try it with a fresh (valid) image if you like by
  339. running the mkimage link again. Then:
  340. fdtput -p image.fit /configurations/conf-1/signature-1 value fred
  341. $UOUT/tools/fit_check_sign -f image.fit -k am335x-boneblack-pubkey.dtb
  342. Verifying Hash Integrity ... -
  343. sha1,rsa2048:devrsa_verify_with_keynode: RSA failed to verify: -13
  344. rsa_verify_with_keynode: RSA failed to verify: -13
  345. -
  346. Failed to verify required signature 'key-dev'
  347. Signature check Bad (error 1)
  348. Of course it would be possible to add an entirely new configuration and boot
  349. with that, but it still needs to be signed, so it won't help.
  350. 6. Put the public key into U-Boot's image
  351. -----------------------------------------
  352. Having confirmed that the signature is doing its job, let's try it out in
  353. U-Boot on the board. U-Boot needs access to the public key corresponding to
  354. the private key that you signed with so that it can verify any kernels that
  355. you sign.
  356. cd $UBOOT
  357. make O=b/am335x_boneblack_vboot EXT_DTB=${WORK}/am335x-boneblack-pubkey.dtb
  358. Here we are overriding the normal device tree file with our one, which
  359. contains the public key.
  360. Now you have a special U-Boot image with the public key. It can verify can
  361. kernel that you sign with the private key as in step 5.
  362. If you like you can take a look at the public key information that mkimage
  363. added to U-Boot's device tree:
  364. fdtget -p am335x-boneblack-pubkey.dtb /signature/key-dev
  365. required
  366. algo
  367. rsa,r-squared
  368. rsa,modulus
  369. rsa,n0-inverse
  370. rsa,num-bits
  371. key-name-hint
  372. This has information about the key and some pre-processed values which U-Boot
  373. can use to verify against it. These values are obtained from the public key
  374. certificate by mkimage, but require quite a bit of code to generate. To save
  375. code space in U-Boot, the information is extracted and written in raw form for
  376. U-Boot to easily use. The same mechanism is used in Google's Chrome OS.
  377. Notice the 'required' property. This marks the key as required - U-Boot will
  378. not boot any image that does not verify against this key.
  379. 7. Put U-Boot and the kernel onto the board
  380. -------------------------------------------
  381. The method here varies depending on how you are booting. For this example we
  382. are booting from an micro-SD card with two partitions, one for U-Boot and one
  383. for Linux. Put it into your machine and write U-Boot and the kernel to it.
  384. Here the card is /dev/sde:
  385. cd $WORK
  386. export UDEV=/dev/sde1 # Change thes two lines to the correct device
  387. export KDEV=/dev/sde2
  388. sudo mount $UDEV /mnt/tmp && sudo cp $UOUT/u-boot-dtb.img /mnt/tmp/u-boot.img && sleep 1 && sudo umount $UDEV
  389. sudo mount $KDEV /mnt/tmp && sudo cp $WORK/image.fit /mnt/tmp/boot/image.fit && sleep 1 && sudo umount $KDEV
  390. 8. Try it
  391. ---------
  392. Boot the board using the commands below:
  393. setenv bootargs console=ttyO0,115200n8 quiet root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
  394. ext2load mmc 0:2 82000000 /boot/image.fit
  395. bootm 82000000
  396. You should then see something like this:
  397. U-Boot# setenv bootargs console=ttyO0,115200n8 quiet root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
  398. U-Boot# ext2load mmc 0:2 82000000 /boot/image.fit
  399. 7824930 bytes read in 589 ms (12.7 MiB/s)
  400. U-Boot# bootm 82000000
  401. ## Loading kernel from FIT Image at 82000000 ...
  402. Using 'conf-1' configuration
  403. Verifying Hash Integrity ... sha1,rsa2048:dev+ OK
  404. Trying 'kernel' kernel subimage
  405. Description: unavailable
  406. Created: 2014-06-01 19:32:54 UTC
  407. Type: Kernel Image
  408. Compression: lzo compressed
  409. Data Start: 0x820000a8
  410. Data Size: 7790938 Bytes = 7.4 MiB
  411. Architecture: ARM
  412. OS: Linux
  413. Load Address: 0x80008000
  414. Entry Point: 0x80008000
  415. Hash algo: sha1
  416. Hash value: c94364646427e10f423837e559898ef02c97b988
  417. Verifying Hash Integrity ... sha1+ OK
  418. ## Loading fdt from FIT Image at 82000000 ...
  419. Using 'conf-1' configuration
  420. Trying 'fdt-1' fdt subimage
  421. Description: beaglebone-black
  422. Created: 2014-06-01 19:32:54 UTC
  423. Type: Flat Device Tree
  424. Compression: uncompressed
  425. Data Start: 0x8276e2ec
  426. Data Size: 31547 Bytes = 30.8 KiB
  427. Architecture: ARM
  428. Hash algo: sha1
  429. Hash value: cb09202f889d824f23b8e4404b781be5ad38a68d
  430. Verifying Hash Integrity ... sha1+ OK
  431. Booting using the fdt blob at 0x8276e2ec
  432. Uncompressing Kernel Image ... OK
  433. Loading Device Tree to 8fff5000, end 8ffffb3a ... OK
  434. Starting kernel ...
  435. [ 0.582377] omap_init_mbox: hwmod doesn't have valid attrs
  436. [ 2.589651] musb-hdrc musb-hdrc.0.auto: Failed to request rx1.
  437. [ 2.595830] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed with status -517
  438. [ 2.606470] musb-hdrc musb-hdrc.1.auto: Failed to request rx1.
  439. [ 2.612723] musb-hdrc musb-hdrc.1.auto: musb_init_controller failed with status -517
  440. [ 2.940808] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
  441. [ 7.248889] libphy: PHY 4a101000.mdio:01 not found
  442. [ 7.253995] net eth0: phy 4a101000.mdio:01 not found on slave 1
  443. systemd-fsck[83]: Angstrom: clean, 50607/218160 files, 306348/872448 blocks
  444. .---O---.
  445. | | .-. o o
  446. | | |-----.-----.-----.| | .----..-----.-----.
  447. | | | __ | ---'| '--.| .-'| | |
  448. | | | | | |--- || --'| | | ' | | | |
  449. '---'---'--'--'--. |-----''----''--' '-----'-'-'-'
  450. -' |
  451. '---'
  452. The Angstrom Distribution beaglebone ttyO0
  453. Angstrom v2012.12 - Kernel 3.14.1+
  454. beaglebone login:
  455. At this point your kernel has been verified and you can be sure that it is one
  456. that you signed. As an exercise, try changing image.fit as in step 5 and see
  457. what happens.
  458. Further Improvements
  459. --------------------
  460. Several of the steps here can be easily automated. In particular it would be
  461. capital if signing and packaging a kernel were easy, perhaps a simple make
  462. target in the kernel.
  463. Some mention of how to use multiple .dtb files in a FIT might be useful.
  464. U-Boot's verified boot mechanism has not had a robust and independent security
  465. review. Such a review should look at the implementation and its resistance to
  466. attacks.
  467. Perhaps the verified boot feature could could be integrated into the Amstrom
  468. distribution.
  469. Simon Glass
  470. sjg@chromium.org
  471. 2-June-14