diff options
author | Daniel Drake <dsd@laptop.org> | 2010-01-04 18:11:04 (GMT) |
---|---|---|
committer | Daniel Drake <dsd@laptop.org> | 2010-01-04 18:11:04 (GMT) |
commit | 6cc90b63ffe245e49adbad6725fed0746db5d96d (patch) | |
tree | f7b10ccf0792de7aebc6394fe46cf7299815b3b1 | |
parent | c9fb11d7ca37b853641b9427d3d4981f9d139fdc (diff) |
Finish signing module
Supports both external signing workflows and build-time signing.
-rw-r--r-- | TODO | 6 | ||||
-rw-r--r-- | modules/signing/README | 187 | ||||
-rw-r--r-- | modules/signing/defaults.ini | 3 | ||||
-rw-r--r-- | modules/signing/finalize.50.makefszip.sh | 17 | ||||
-rw-r--r-- | modules/signing/finalize.50.makefszip_img.sh | 51 | ||||
-rw-r--r-- | modules/signing/finalize.50.makefszip_zsp.sh | 45 | ||||
-rw-r--r-- | modules/signing/postimage.50.extract.sh | 26 | ||||
-rw-r--r-- | modules/signing/preimage.10.extract.sh | 45 | ||||
-rw-r--r-- | modules/signing/preimage.40.sign-firmware.sh | 26 | ||||
-rw-r--r-- | modules/signing/preimage.40.sign-os.sh | 26 |
10 files changed, 364 insertions, 68 deletions
@@ -1,10 +1,4 @@ -signing testing FIXMEs - - -signing via olpc-bios-crypto - - custom scripts lang pack integration diff --git a/modules/signing/README b/modules/signing/README index 2d175c2..89e2caf 100644 --- a/modules/signing/README +++ b/modules/signing/README @@ -1,24 +1,175 @@ -This module helps with signing of builds. +OLPC XO laptops can optionally include a security system, parts of which +aim to ensure the following: + 1. Only trusted kernels and initramfs image (early boot code) can be booted + 2. Only trusted OS images can be installed on the laptop -It has 3 configuration options. +Trust is established through the verification of signatures of the above +components. The XO laptop flash includes a set of public keys which are used +to perform this verification. -[signing] -extract=0 -make_fs_zip=1 -add_signed_content=/path/to/zip/file +These security systems are typically disabled for small deployments, but are +enabled for large deployments who have sufficient technical resources to +meet the technical challenges presented by this system. It's complex. -"extract" causes an output file named osXX.for-signing.zip to be generated, -including all content needed for OS and FW signing (firmware, kernel, -initramfs). Default 0. +Other security systems are available too (e.g. developer keys, +activation leases) but these fall out of the scope of the tasks that +olpc-os-builder is concerned with. -"make_fs_zip" results in an unsigned fs.zip files being created for every -.zsp file output from the build. A file named os31.2gb.zsp will result in -os31.2gb.fs.zip being created. Default 1. +See http://wiki.laptop.org/go/Firmware_security for more information. The +following instructions assume you understand the basics and know what you are +doing. -"add_signed_content" is an optional setting which lets you provide a zip -file containing some combination of the following files: - bootfw.zip runos.zip runrd.zip actos.zip actrd.zip -These will be copied to /boot in the resultant image. -The idea is that you sign these files externally, then use this module to -insert them into the next build. +Some of the options below require you to have a local and ready-built checkout +of OLPC's bios-crypto git repository. You probably have one of these already, +because you've used this to create the keypairs that you'll be using for +signing, right? If not, instructions for this step can be found at +http://wiki.laptop.org/go/OSBuilder + +Once you have done this, you should tell olpc-os-builder about this, as follows: + + [signing] + bios_crypto_path=/home/myuser/bios-crypto + +The above bios_crypto_path should point to the root directory of the git +checkout. + + +When following the instructions below, it is possible to combine a few steps. +For example, it is perfectly OK to configure olpc-os-builder to sign the +firmware, kernel, initramfs and resultant OS image all in the same build. + + +=== SIGNING KERNEL, INITRAMFS, AND FIRMWARE === + +These components must be signed and included in the OS build. There are +2 approaches that you can take here. + + +1. External signing + +You can ask olpc-os-builder to extract various components from the build which +need signing, by enabling the "extract" option (default 0, disabled): + + [signing] + extract=1 + +This causes an output file named osXX.for-signing.zip to be generated, +including all content needed for signing: + - an unsigned /boot/bootfw.zip is expected to be included in the build, + if found then this will be extracted + - if found, the kernel at /boot/vmlinuz will be extracted as an unsigned + runos.zip + - if found, the initramfs at /boot/initrd.img (or /boot/olpcrd.img) will be + extracted as an unsigned runrd.zip + +You would then sign these components by your own means, perhaps on another +computer system, kept in a safe and never connected to any networks for +security purposes. + +The output from this process should be some subset of the following files: + + bootfw.zip - signed kernel + actos.zip - signed kernel for activation + runos.zip - signed kernel for regular boot + actrd.zip - signed initramfs for activation + runrd.zip - signed initramfs for regular boot + +At this point, put all these zip files (without renaming them) into another +zip file, and run another build, this time with the following configuration: + + [signing] + add_signed_content=/path/to/zip/file + +The files from this zip file will be included in /boot in the final image. +It's OK to skip some files. act* and run* files will be created as symlinks +if they don't exist. For example, if you don't provide a actos.zip, a symlink +named "actos.zip" will be created, pointing at runos.zip. This is useful +when there is no difference between the signed content used for booting the +activation environment vs the regular system (as is true for all OLPC builds, +at the time of writing). + + +2. Signing at build time + +If the keypairs are available at build time, you can sign these components +as part of the regular build process. bios-crypto is required here. + +If you supply a 'w' key, the firmware found at /boot/bootfw.zip in your build +will be (re-)signed with that key. + +If you supply an 'o' key, the kernel found at /boot/vmlinuz and the initramfs +found at /boot/initrd.img will be signed into runos.zip and runrd.zip +respectively, and actos/actrd symlinks will be set up. + +If you supply both keys, the firmware, kernel and initramfs will all be signed. +This is usually what you want. + + [signing] + bios_crypto_path=/home/myuser/bios-crypto + okey=/home/myuser/keys/o1 + wkey=/home/myuser/keys/w1 + +In the above example, the root of the bios-crypto git checkout is at +/home/myuser/bios-crypto, and the public/private keys in question are found at: + + /home/myuser/keys/o1.public + /home/myuser/keys/o1.private + /home/myuser/keys/w1.public + /home/myuser/keys/w1.private + + + +=== SIGNING OS IMAGE === + +The 2nd step in the signing process is to sign the resultant OS image file, +allowing it to be used for NANDblaster and secure reflash. A similar pair +of options apply. + +1. External signing + +For XO-1.5, you need to sign the .zsp file that is produced as part of the +SD card image generation process. The following option will produce a fs.zip +file for every outputted .zsp file: + + [signing] + make_zsp_fs_zip=1 + +A file named os31.2gb.zsp will result in os31.2gb.fs.zip being generated. + + +For XO-1, bios-crypto is required. + [signing] + bios_crypto_path=/home/myuser/bios-crypto + make_img_fs_zip=1 + +All output .img files will be signed into (e.g.) os52.fs.zip. + + +In both cases, these fs.zip output files are unsigned and must be externally +resigned using your private 's' key before it becomes useful. + + +2. Signing at build time + +If the 's' keypair is available at build time, you can sign the resultant +build simply by specifying it's path in addition to following the instructions +above. bios-crypto is required in both cases. + +e.g. for XO-1.5: + [signing] + bios_crypto_path=/home/myuser/bios-crypto + skey=/home/myuser/keys/s1 + make_zsp_fs_zip=1 + +e.g. for XO-1: + [signing] + bios_crypto_path=/home/myuser/bios-crypto + skey=/home/myuser/keys/s1 + make_img_fs_zip=1 + +In both cases, the resultant fs.zip files will be signed with the 's' keypair, +whose files are expected to be found at: + + /home/myuser/keys/s1.public + /home/myuser/keys/s1.private diff --git a/modules/signing/defaults.ini b/modules/signing/defaults.ini index 88f632c..7e24121 100644 --- a/modules/signing/defaults.ini +++ b/modules/signing/defaults.ini @@ -1,4 +1,5 @@ [signing] extract=0 -make_fs_zip=1 +make_zsp_fs_zip=1 +make_img_fs_zip=1 diff --git a/modules/signing/finalize.50.makefszip.sh b/modules/signing/finalize.50.makefszip.sh deleted file mode 100644 index ec5c193..0000000 --- a/modules/signing/finalize.50.makefszip.sh +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2009 One Laptop Per Child -# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. - -. $OOB__shlib -enabled=$(read_config signing make_fs_zip) -[[ "$enabled" == "1" ]] || exit 0 - -for i in $outputdir/*.zsp; do -#FIXME XO-1 support - bname=$(basename $i) - echo "$bname" > $intermediatesdir/version.txt - cp $outputdir/$i $intermediatesdir/data.img - - zip -n .img:.txt $bname.fs.zip \ - $intermediatesdir/data.img $intermediatesdir/version.txt -done - diff --git a/modules/signing/finalize.50.makefszip_img.sh b/modules/signing/finalize.50.makefszip_img.sh new file mode 100644 index 0000000..ce3481c --- /dev/null +++ b/modules/signing/finalize.50.makefszip_img.sh @@ -0,0 +1,51 @@ +# Copyright (C) 2009 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +# sign XO-1 jffs2 images + +. $OOB__shlib +enabled=$(read_config signing make_img_fs_zip) +[[ "$enabled" == "1" ]] || exit 0 + +bios_crypto=$(read_config signing bios_crypto_path) +[ -n "$bios_crypto" -a -d "$bios_crypto" ] || exit 0 + +skey=$(read_config signing skey) + +make_unsigned_img() +{ + local bname=$(basename $1) + local bname_noext=$(basename $1 .img) + + echo "Generating unsigned fs.zip for $bname..." + + echo "$bname" > $intermediatesdir/data.img + $bios_crypto/build/hashfs sha256 "$i" >> $intermediatesdir/data.img + echo $bname_noext > $intermediatesdir/version.txt + + zip -j -n .img:.txt $outputdir/$bname.fs.zip \ + $intermediatesdir/data.img $intermediatesdir/version.txt + rm -f $intermediatesdir/{data.img,version.txt} +} + +make_signed_img() +{ + echo "Generating signed fs.zip for $(basename $1)..." + local outfile=$outputdir/$(basename $1).fs.zip + pushd /tmp + $bios_crypto/build/make-fs.sh --signingkey $skey $1 $outfile + popd +} + +shopt -s nullglob +for i in $outputdir/*.img; do + # skip SD card disk images + [[ "${i:(-9)}" == ".disk.img" ]] && continue + + if [ -n "$skey" ]; then + make_signed_img $i + else + make_unsigned_img $i + fi +done + diff --git a/modules/signing/finalize.50.makefszip_zsp.sh b/modules/signing/finalize.50.makefszip_zsp.sh new file mode 100644 index 0000000..2e73533 --- /dev/null +++ b/modules/signing/finalize.50.makefszip_zsp.sh @@ -0,0 +1,45 @@ +# Copyright (C) 2009 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +# make a fs.zip, optionally signed, from a .zsp file + +. $OOB__shlib +enabled=$(read_config signing make_zsp_fs_zip) +[[ "$enabled" == "1" ]] || exit 0 + +bios_crypto=$(read_config signing bios_crypto_path) +skey=$(read_config signing skey) + +make_unsigned_zsp() +{ + local bname=$(basename $1) + local bname_noext=$(basename $1 .zsp) + + echo "Generating unsigned fs.zip for $bname..." + + echo "$bname_noext" > $intermediatesdir/version.txt + cp $i $intermediatesdir/data.img + + zip -j -n .img:.txt $outputdir/$bname.fs.zip \ + $intermediatesdir/data.img $intermediatesdir/version.txt + rm -f $intermediatesdir/{data.img,version.txt} +} + +make_signed_zsp() +{ + echo "Generating signed fs.zip for $(basename $1)..." + local outfile=$outputdir/$(basename $1).fs.zip + pushd /tmp + $bios_crypto/build/sign-zsp.sh $skey $1 $outfile + popd +} + +shopt -s nullglob +for i in $outputdir/*.zsp; do + if [ -n "$skey" -a -n "$bios_crypto" -a -d "$bios_crypto" ]; then + make_signed_zsp $i + else + make_unsigned_zsp $i + fi +done + diff --git a/modules/signing/postimage.50.extract.sh b/modules/signing/postimage.50.extract.sh deleted file mode 100644 index 0a8f10b..0000000 --- a/modules/signing/postimage.50.extract.sh +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2009 One Laptop Per Child -# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. - -. $OOB__shlib -enabled=$(read_config signing extract) -[[ "$enabled" == "1" ]] || exit 0 - -buildnr=$(read_buildnr) -tgt=$intermediatesdir/for-signing -outzip=$outputdir/os$buildnr.for-signing.zip -rm -rf $tgt -mkdir -p $tgt - -found=0 -echo "Extracting content for signing..." -for i in bootfw.zip vmlinuz initrd.img olpcrd.img; do - path="$fsmount/boot/$i" - [ -e "$path" ] || continue - found=1 - cp "$path" $tgt -done - -[ "$found" == "1" ] || exit 0 - -zip $outzip $tgt/* - diff --git a/modules/signing/preimage.10.extract.sh b/modules/signing/preimage.10.extract.sh new file mode 100644 index 0000000..eee927c --- /dev/null +++ b/modules/signing/preimage.10.extract.sh @@ -0,0 +1,45 @@ +# Copyright (C) 2009 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +# this must be run before the base module creates versioned fs layout + +. $OOB__shlib +enabled=$(read_config signing extract) +[[ "$enabled" == "1" ]] || exit 0 + +buildnr=$(read_buildnr) +tgt=$intermediatesdir/for-signing +outzip=$outputdir/os$buildnr.for-signing.zip +rm -rf $tgt +mkdir -p $tgt + +found=0 +echo "Extracting content for signing..." +if [ -e "$fsmount/boot/bootfw.zip" ]; then + cp $fsmount/boot/bootfw.zip $tgt + found=1 +fi + +if [ -e "$fsmount/boot/vmlinuz" ]; then + cp $fsmount/boot/vmlinuz $tgt/data.img + zip -j -n .img $tgt/runos.zip $tgt/data.img + rm -f $tgt/data.img + found=1 +fi + +if [ -e "$fsmount/boot/initrd.img" ]; then + cp $fsmount/boot/initrd.img $tgt/data.img + zip -j -n .img $tgt/runrd.zip $tgt/data.img + rm -f $tgt/data.img + found=1 +elif [ -e "$fsmount/boot/olpcrd.img" ]; then + cp $fsmount/boot/olpcrd.img $tgt/data.img + zip -j -n .img $tgt/runrd.zip $tgt/data.img + rm -f $tgt/data.img + found=1 +fi + +[ "$found" == "1" ] || exit 0 + +zip -j $outzip $tgt/* + diff --git a/modules/signing/preimage.40.sign-firmware.sh b/modules/signing/preimage.40.sign-firmware.sh new file mode 100644 index 0000000..10eeb67 --- /dev/null +++ b/modules/signing/preimage.40.sign-firmware.sh @@ -0,0 +1,26 @@ +# Copyright (C) 2010 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +wkey=$(read_config signing wkey) +[[ -n "$wkey" ]] || exit 0 + +bios_crypto=$(read_config signing bios_crypto_path) +[ -n "$bios_crypto" -a -d "$bios_crypto" ] || exit 0 + +[ -e $fsmount/boot/bootfw.zip ] || exit 0 + +echo "Signing firmware..." + +fwtmp=$intermediatesdir/fw-for-signing +mkdir -p $fwtmp +unzip -d $fwtmp $fsmount/boot/bootfw.zip +mv $fwtmp/data.img $intermediatesdir/fw.rom + +outzip=$intermediatesdir/bootfw.zip +rm -f $outzip +pushd /tmp +$bios_crypto/build/sign-fw.sh $wkey $intermediatesdir/fw.rom $outzip +popd +mv $outzip $fsmount/boot/ + diff --git a/modules/signing/preimage.40.sign-os.sh b/modules/signing/preimage.40.sign-os.sh new file mode 100644 index 0000000..673927b --- /dev/null +++ b/modules/signing/preimage.40.sign-os.sh @@ -0,0 +1,26 @@ +# Copyright (C) 2010 One Laptop Per Child +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +. $OOB__shlib +okey=$(read_config signing okey) +[[ -n "$okey" ]] || exit 0 + +bios_crypto=$(read_config signing bios_crypto_path) +[ -n "$bios_crypto" -a -d "$bios_crypto" ] || exit 0 + +if [ -e "$fsmount/boot/vmlinuz" ]; then + echo "Signing kernel..." + pushd /tmp + $bios_crypto/build/sign-os.sh $okey $fsmount/boot/vmlinuz $fsmount/boot/runos.zip + popd + [ -e $fsmount/boot/actos.zip ] || ln -s runos.zip $fsmount/boot/actos.zip +fi + +if [ -e "$fsmount/boot/initrd.img" ]; then + echo "Signing initramfs..." + pushd /tmp + $bios_crypto/build/sign-os.sh $okey $fsmount/boot/initrd.img $fsmount/boot/runrd.zip + popd + [ -e $fsmount/boot/actrd.zip ] || ln -s runrd.zip $fsmount/boot/actrd.zip +fi + |