The projects I'm working on are based on Yocto so I've been using the u-boot signing support that is built in there. I believe the magic you are looking for is in http://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/classes/uboot-sign.bbclass. Specifically, when you run 'mkimage -F -k <key-name> -K <control-dtb> -r <fit>', the public keys will be inserted into the control dtb. You can then rebuild u-boot with 'make EXT_DTB=<control-dtb>' which will use the dtb that includes the keys.
On Mon, Feb 27, 2017 at 7:34 AM, Ron Brash <ron.br...@gmail.com> wrote: > Okay - it seems, after working my way through a bunch of the documentation > and examples in /doc/uImage.FIT - I noticed a discrepancy > > /dts-v1/; > /{ > description = "Configuration to load a Basic Kernel"; > #address-cells = <1>; > images { > linux_kernel@1 { > description = "Linux zImage"; > data = /incbin/("zImage"); > type = "kernel"; > arch = "arm"; > os = "linux"; > compression = "none"; > load = <0x20000000>; > entry = <0x20008000>; > kernel-version = <1>; > hash@1 { > algo = "sha256"; > }; > }; > fdt@1 { > description = "FDT blob"; > data = /incbin/("myboard.dtn"); > type = "flat_dt"; > arch = "arm"; > compression = "none"; > fdt-version = <1>; > hash@1{ > algo = "sha256"; > }; > }; > }; > configurations { > default = "config@1"; > config@1{ > description = "Plain Linux"; > kernel = "linux_kernel@1"; > fdt = "fdt@1"; > signature@1{ > algo = "sha256,rsa2048"; > key-name-hint = "dev_key"; > sign-images = "fdt", "kernel"; > }; > }; > }; > }; > > Does NOT equal (for brevity - I just used the node) > > fdt@1 { > description = "FDT blob"; > data = /incbin/("myboard.dtn"); > type = "flat_dt"; > arch = "arm"; > compression = "none"; > fdt-version = <1>; > hash@1{ > algo = "sha256"; > }; > signature@1{ > algo = "sha256,rsa2048"; > key-name-hint = "dev_key"; > }; > }; > > Apparently, this causes the mkimage tooling in my particular instance to > explain invalid blob messages. The large example above indeed does work > once this nuance was noticed. > > Next, once the final CTRL FDT is created, how does one get it back into > the actual u-boot binary. Does/can mkimage insert it into the binary image > at a particular offset? What is the command to do so? > > > > > > On 23 February 2017 at 12:27, Rick Altherr <ralth...@google.com> wrote: > >> >> >> On Thu, Feb 23, 2017 at 7:48 AM, Ron Brash <ron.br...@gmail.com> wrote: >> >>> Hello all (and thanks Mr. Altherr for this insight), >>> >>> Excellent feedback and I agree that all of this needs to find a home >>> either on the global docs on the website and/or the text-only >>> documentation. Regardless, this leads me to a few questions. >>> >>> NOTE: the use of a uboot control DTS, control DTB and control FTD even >>> in Mr. Altherr's email is confusion provoking. One term to rule them all >>> is needed ;) >>> >> >> Agreed. Technically a flattened device tree (FDT) can be described in an >> ASCII form (dts) or binary form (dtb). >> >> >>> >>> 1.) What if a board doesn't have OR has ever been configured to use >>> u-boot DTS (could we call this a UDTS or something friendly to >>> differentiate that fact?); this was a point of misunderstanding until I >>> started scampering around into arch/arm/dts/? >>> >>> * For example, my board is a derivative of an Atmel at91sam9g20. It had >>> a very generic implementation of a DTS that covered reference boards in the >>> Linux kernel, but required a fair bit of modification to make it work. As >>> the at91sam(legacy platform) isn't in u-boot's source tree for a DTS - what >>> would someone like me need to do - do we have a barebones tutorial (again I >>> don't mind publishing such with proofing)? Is it even required if we have >>> a platform/board already working in the traditional u-boot way? >>> >>> I believe (but have no verified) that if your board is supported by >> U-Boot without a control FDT today, you can just create one that contains >> only the public keys. I've gathered from the mailing list that using a >> control FDT and the driver model is how all new boards should be >> implemented. >> >> >>> 2.) Just to summarise - everything winds up in two binaries: u-boot and >>> the FIT image. So the partition scheme would more or less would look like: >>> >>> /----------------- >>> * Bootstrap/ROM (optional) >>> /---------------- >>> * U-boot >>> * Control DTB >>> * Has keys >>> >> >> Only the public keys. The private keys are never stored on the target >> device. >> >> >>> * Driver loadout/init >>> >> The control FDT only describes the hardware (see >> https://www.devicetree.org/ and http://git.kernel.org/cgit/lin >> ux/kernel/git/torvalds/linux.git/tree/Documentation/devicet >> ree/usage-model.txt). U-Boot's driver model matches device drivers >> against nodes in the FDT and starts them. >> >> >>> /---------------- >>> * U-boot env >>> *---------------- >>> * FIT image >>> >> The FIT shouldn't be in the U-Boot env section. That's used by U-Boot to >> store its persistent environment. The FIT is a replacement for the kernel >> image. Keep a separate place allocated in the flash for kernel but store >> the FIT there. >> >> >>> * ITS >>> >> I never really thought of it this way, but yes, that's true. The ITS is >> itself written in device tree syntax and gets compiled to binary form. dtb >> tends to get used only to describe device trees in binary form that >> describe hardware. Maybe we need to introduce ITB to clarify this is the >> device tree in binary form describing the image. >> >> >>> * Kernel >>> * DTS >>> >> >> Prefer the terms FDT or DTB. Only the compiled form is stored in the FIT. >> >> >>> * .... >>> /--------------- >>> * Rootfs etc... >>> * ... >>> /--------------- >>> >>> >>> 3.) What people used to use to load X address into Z location in memory >>> is now removed by the usage of a DTB in u-boot correct? I assume that the >>> u-boot DTB now does this and bootarg/bootcmd is partially done away with - >>> as its arguments are augmented by said file. >>> >> >> Not quite. bootarg/bootcmd is still used. What is different is that >> booting linux with a FDT with legacy images required multiple arguments to >> bootm. In that case, bootarg would be 'bootm <zimage_addr> - <fdt_addr>'. >> With a FIT, you only provide the address of the FIT itself to bootm so >> bootarg is set to 'bootm <fit_addr>'. >> >> >>> >>> Anybody have the spare cycles to organise a >>> web-tutorial/presentation/recording with me on a play-by-play to make >>> all of this make sense? I'm aiming to be in Prague for the 2017 conference >>> in October, might be a good place to showcase this fine-tuning. >>> >>> >> I'm not clear on what you are asking. I probably have time to review >> docs and presentations and maybe a few phone or video conference meetings. >> >> >>> Ron >>> >>> On 22 February 2017 at 13:51, Rick Altherr <ralth...@google.com> wrote: >>> >>>> >>>> On Tue, Feb 21, 2017 at 10:08 AM, Ron Brash <ron.br...@gmail.com> >>>> wrote: >>>> >>>>> Hello all, >>>>> >>>>> I am adding verified kernel support on a board we are using and I am >>>>> struggling to fully understand all of the concepts and steps required >>>>> to >>>>> pull everything together (on ARM, using ZImages and booting with a >>>>> working >>>>> DTB on 4.4.3x). I also looked at the test script inside of examples, >>>>> but >>>>> it left me with more questions than understanding. >>>>> >>>>> Please correct me where appropriate in my understanding, but if I am >>>>> confused, likely others are too and I hope this helps everyone involved >>>>> overall. >>>>> >>>> >>>> You've asked some really good questions. Hopefully this discussion >>>> will end up with patches to clarify the docs. >>>> >>>> >>>>> >>>>> Steps: >>>>> --------------------------------------------------------------- >>>>> >>>>> First, u-boot needs to have the appropriate features enabled and to be >>>>> built using them. At a minimum, I suspect: >>>>> >>>>> CONFIG_RSA=y >>>>> CONFIG_FIT=y >>>>> CONFIG_FIT_SIGNATURE=y >>>>> CONFIG_OF_CONTROL=y >>>>> >>>>> >>>> Yup. That looks right. >>>> >>>> >>>>> Next, we need to derive the appropriate cryptographic primitives/keys. >>>>> >>>>> #Generate a private signing key (RSA2048): >>>>> openssl genrsa -F4 -out \ >>>>> "${key_dir}"/"${key_name}".key 2048 >>>>> >>>>> # Generate a public key: >>>>> openssl req -batch -new -x509 \ >>>>> -key "${key_dir}"/"${key_name}".key \ >>>>> -out "${key_dir}"/"${key_name}".crt >>>>> >>>>> >>>> So far so good. In general, I suggest having multiple signing keys. >>>> You can put all the public keys in your u-boot so an image signed with any >>>> of those keys will be accepted. If you happen to have a signing key >>>> compromised, you can switch to one of the other ones. With that other key, >>>> you can sign an update the removes the compromised public key from future >>>> images. >>>> >>>> >>>>> Then we derive the ITS or image source file - a file that >>>>> hints/describes >>>>> the elements that will be verified and/or inside of the FIT image? >>>>> Lets >>>>> call this $FIT_ITS >>>>> >>>>> FIT is a container format. Generally, you'll create a FIT that >>>> contains the zImage, dtb, initramfs, etc. With FIT support enabled in >>>> u-boot, you only need to provide the single FIT image address to 'bootm'. >>>> u-boot will use the config section to find the individual elements, load >>>> them into RAM as needed, and boot. >>>> >>>> >>>>> / dts - v1 /; >>>>> / { >>>>> description = "Configuration to load a Xen Kernel"; >>>>> #address-cells = <1>; >>>>> images { >>>>> linux_kernel @ 1 { >>>>> description = "Linux zImage"; >>>>> data = /incbin / ("pathToImage/zImage"); >>>>> type = "kernel"; >>>>> arch = "arm"; >>>>> os = "linux"; >>>>> compression = "none"; >>>>> load = <0xaf600000 >; >>>>> entry = <0xaf600000 >; >>>>> hash @ 1 { >>>>> algo = "sha1"; >>>>> }; >>>>> }; >>>>> fdt @ 1 { >>>>> description = "FDT blob"; >>>>> data = /incbin / ("PathToDTBUsedByBootingKernel/ex.dtb"); >>>>> type = "flat_dt"; >>>>> arch = "arm"; >>>>> compression = "none"; >>>>> load = <0xaec00000 >; >>>>> >>>> >>>> You generally don't need a 'load' property for the FDT or an >>>> initramfs. Without one, U-Boot will allocate RAM dynamically, if needed, >>>> and pass the relocated address to the kernel. >>>> >>>> hash @ 1 { >>>>> algo = "sha1"; >>>>> }; >>>>> }; >>>>> }; >>>>> configurations { >>>>> default = "config@1"; >>>>> config @ 1 { >>>>> description = "Plain Linux"; >>>>> kernel = "linux_kernel@1"; >>>>> fdt = "fdt@1"; >>>>> loadables = "linux_kernel@1"; >>>>> >>>> >>>> 'loadables' is for other types of firmware. You only need the 'kernel' >>>> property for loading and booting the kernel. >>>> >>>> >>>>> }; >>>>> }; >>>>> }; >>>>> >>>>> Question: Does a signature section go into this as well? underneath the >>>>> hash node for each value? >>>> >>>> >>>>> signature@1 { >>>>> algo = "sha1,rsa2048"; >>>>> value = <...kernel signature 1...> >>>>> }; >>>>> >>>> >>>> You add a signature section to each image you want signed within the >>>> FIT. In your case, add one for both the kernel and FDT images. Signatures >>>> go _next_ to the hash section, not in it. Omit the 'value' property as it >>>> will be generated for you later. >>>> >>>> >>>>> >>>>> Then using the device-tree-compiler (dtc), I create a DTB for u-boot. >>>>> This >>>>> is the control FDT and this defines what keys are used etc.. >>>>> >>>> >>>> The control FDT is used for U-Boot's driver model _as well as_ >>>> providing public keys for verifying images. Your board may not currently >>>> use a control FDT in which case you create one from scratch. >>>> >>>> >>>>> >>>>> #Assemble control FDT for U-Boot with space for public key: >>>>> $DTC -p 0x1000 u-boot.dts -O dtb -o u-boot.dtb >>>>> >>>>> Question: What is required inside of the u-boot.dts for u-boot? Is it >>>>> simply the same .dts used by the booting kernel, but with a section >>>>> proclaiming the keys? >>>>> >>>> >>>> This depends on the board you are using. For example, an AST2500 >>>> requires a DTB for U-Boot to load the right drivers. The DTB used by >>>> U-Boot is slightly different from that used by Linux as the Linux DTB often >>>> includes addition configuration information. When using verified boot, the >>>> U-Boot DTB includes the public keys whereas the FDT/DTB stored in the FIT >>>> does not as Linux doesn't need them. >>>> >>>> >>>>> >>>>> Question: Where will the compiled u-boot.dtb eventually go? Is this >>>>> put >>>>> into a FIT image, or flashed onto the board alongside the u-boot >>>>> bootloader >>>>> itself? >>>>> >>>> >>>> The U-Boot control FDT is compiled into the U-Boot binary. The FDT in >>>> the FIT is the FDT that is provided to Linux. >>>> >>>> >>>>> >>>>> Next, given that the above steps are completed, I need to create a FIT >>>>> image with space for the signature. >>>>> >>>>> # Generate fitImage with space for signature: >>>>> $MKIMG -D "-I dts -O dtb -p 2000" \ >>>>> -f f$FIT_ITS $FIT_IMG >>>>> >>>>> Question: Is the FIT_IMAGE the actual zimage or is it an output image >>>>> that >>>>> contains all of the values contained within the ITS? >>>>> >>>> >>>> The latter. It will have a compiled version of the ITS as well as the >>>> actual images specified in the ITS (kernel, fdt). >>>> >>>> >>>>> >>>>> Next this FIT_IMAGE (assuming that this is the final FIT image that >>>>> contains the FDT and zImage) needs to be signed and the public key >>>>> added to >>>>> it; given that that the key information is in the uboot. >>>>> >>>> >>>> You sign the FIT_IMAGE and put the public keys in the control DTB. >>>> >>>> >>>>> >>>>> # Sign fitImage and add public key into u-boot.dtb: >>>>> $MKIMG -D "-I dts -O dtb -p 2000" -F \ >>>>> -k "${key dir}" -K u-boot.dtb -r $FIT_IMG >>>>> >>>> >>>> This is putting the public keys used by the FIT image into the control >>>> DTB >>>> >>>> >>>>> >>>>> Then, we sign the subsequent fitImage again - correct? >>>>> >>>>> # Signing subsequent fitImage: >>>>> $MKIMG -D "-I dts -O dtb -p 2000" \ >>>>> -k "${key dir}" -f $FIT_ITS -r $FIT_IMG >>>>> >>>> >>>> This is generating signatures for the images in the FIT and storing >>>> those signatures in the FIT. >>>> >>>> >>>>> >>>>> Now that all of the above is done - we need to: >>>>> 1. Write our uboot to the flash >>>>> 2. Write our FIT_IMAGE to flash >>>>> >>>>> Question: Do we write anything else to persistent storage? The ITS? >>>>> etc.. >>>>> >>>> >>>> No. Everything is contained in the U-Boot binary (control FDT >>>> including public keys) and the FIT (images, signatures) >>>> >>>>> >>>>> Question: Do we just boot using anything else or just bootm >>>>> 0xLocationOfTheFitImageInRAM >>>>> >>>> >>>> The latter. bootm will check the config section in the FIT and use the >>>> kernel, fdt, etc specified there. >>>> >>>> >>>>> >>>>> Greatly appreciate any assistance to all of these questions and I'm >>>>> sure >>>>> this threat will be of interest to anyone else too. >>>>> >>>>> Thanks! >>>> >>>> _______________________________________________ >>>>> U-Boot mailing list >>>>> U-Boot@lists.denx.de >>>>> http://lists.denx.de/mailman/listinfo/u-boot >>>>> >>>> >>>> >>> >> > > > -- > > > Ron Brash > CTO & Co-founder of Atlants Embedded Inc. > www.atlantsembedded.com > ------------------------------------------------------------------ > > Cell +1 438 880 6441 <(438)%20880-6441> > Email ron.br...@gmail.com > Blog www.pacificsimplicity.ca > LinkedIn ca.linkedin.com/in/ronbrash/ > > > > This communication is intended for the use of the recipient to which it is > addressed, and may contain confidential, personal, and or privileged > information. Please contact the sender immediately if you are not the > intended recipient of this communication, and do not copy, distribute, or > take action relying on it. Any communication received in error, or > subsequent reply, should be deleted or destroyed. > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/listinfo/u-boot