blob: 533598d322309326dba050318d2443e9d8d5b86d [file] [log] [blame]
Will Drewry69563b72010-06-24 16:12:58 -05001#!/bin/bash
2
3# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# Helper script that generates the signed kernel image
8
9. "$(dirname "$0")/common.sh"
10
11get_default_board
12
13# Flags.
14DEFINE_string arch "x86" \
15 "The boot architecture: arm or x86. (Default: x86)"
16DEFINE_string to "/tmp/vmlinuz.image" \
17 "The path to the kernel image to be created. (Default: /tmp/vmlinuz.image)"
18DEFINE_string vmlinuz "vmlinuz" \
19 "The path to the kernel (Default: vmlinuz)"
20DEFINE_string working_dir "/tmp/vmlinuz.working" \
21 "Working directory for in-progress files. (Default: /tmp/vmlinuz.working)"
22DEFINE_boolean keep_work ${FLAGS_FALSE} \
23 "Keep temporary files (*.keyblock, *.vbpubk). (Default: false)"
24DEFINE_string keys_dir "${SRC_ROOT}/platform/vboot_reference/tests/testkeys" \
Bill Richardson2ace49e2010-07-01 10:23:27 -070025 "Directory with the RSA signing keys. (Defaults to test keys)"
Will Drewrybcbf1c42010-07-03 10:23:30 -050026# Note, to enable verified boot, the caller would manually pass:
Will Drewry69563b72010-06-24 16:12:58 -050027# --boot_args='dm="... /dev/sd%D%P /dev/sd%D%P ..." \
28# --root=/dev/dm-0
29DEFINE_string boot_args "noinitrd" \
30 "Additional boot arguments to pass to the commandline (Default: noinitrd)"
31DEFINE_string root "/dev/sd%D%P" \
32 "Expected device root (Default: root=/dev/sd%D%P)"
33
Will Drewrybcbf1c42010-07-03 10:23:30 -050034# If provided, will automatically add verified boot arguments.
35DEFINE_string rootfs_image "" \
36 "Optional path to the rootfs device or image.(Default: \"\")"
37DEFINE_string rootfs_hash "" \
38 "Optional path to output the rootfs hash to. (Default: \"\")"
39DEFINE_integer vboot_error_behavior 2 \
40 "Verified boot error behavior [0: I/O errors, 1: reboot, 2: nothing] \
41(Default: 2)"
42DEFINE_integer vboot_tree_depth 1 \
43 "Optional Verified boot hash tree depth. (Default: 1)"
44DEFINE_integer vboot_max_ios 1024 \
45 "Optional number of outstanding I/O operations. (Default: 1024)"
46DEFINE_string vboot_hash_alg "sha1" \
47 "Cryptographic hash algorithm used for vboot. (Default: sha1)"
48
Will Drewry69563b72010-06-24 16:12:58 -050049# Parse flags
50FLAGS "$@" || exit 1
51eval set -- "${FLAGS_ARGV}"
52
53# Die on error
54set -e
55
Will Drewrybcbf1c42010-07-03 10:23:30 -050056vboot_args=
57# Even with a rootfs_image, root= is not changed unless specified.
58if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then
59 info "Determining root fs block count."
60 # Gets the number of blocks. 4096 byte blocks _are_ expected.
61 root_fs_blocks=$(sudo dumpe2fs "${FLAGS_rootfs_image}" 2> /dev/null |
62 grep "Block count" |
63 tr -d ' ' |
64 cut -f2 -d:)
65 info "Checking root fs block size."
66 root_fs_block_sz=$(sudo dumpe2fs "${FLAGS_rootfs_image}" 2> /dev/null |
67 grep "Block size" |
68 tr -d ' ' |
69 cut -f2 -d:)
70 if [[ ${root_fs_block_sz} -ne 4096 ]]; then
71 error "Root file system blocks are not 4k!"
72 fi
73
74 info "Generating root fs hash tree."
75 # Runs as sudo in case the image is a block device.
76 table=$(sudo verity create ${FLAGS_vboot_tree_depth} \
77 ${FLAGS_vboot_hash_alg} \
78 ${FLAGS_rootfs_image} \
79 ${root_fs_blocks} \
80 ${FLAGS_rootfs_hash})
81 # Don't claim the root device unless the root= flag is pointed to
82 # the verified boot device. Doing so will claim /dev/sdDP out from
83 # under the system.
84 if [[ ${FLAGS_root} = "/dev/dm-0" ]]; then
85 table=${table//HASH_DEV/\/dev\/sd%D%P}
86 table=${table//ROOT_DEV/\/dev\/sd%D%P}
87 fi
88 vboot_args="dm=\"${table}\""
89 info "dm-verity configuration: ${vboot_args}"
90fi
91
92mkdir -p "${FLAGS_working_dir}"
93cat <<EOF > "${FLAGS_working_dir}/boot.config"
94root=${FLAGS_root}
95dm_verity.error_behavior=${FLAGS_vboot_error_behavior}
96dm_verity.max_bios=${FLAGS_vboot_max_ios}
97${vboot_args}
98${FLAGS_boot_args}
99EOF
100
101WORK="${WORK} ${FLAGS_working_dir}/boot.config"
102info "Emitted cross-platform boot params to ${FLAGS_working_dir}/boot.config"
103
Will Drewry69563b72010-06-24 16:12:58 -0500104# FIXME: At the moment, we're working on signed images for x86 only. ARM will
105# support this before shipping, but at the moment they don't.
106if [[ "${FLAGS_arch}" = "x86" ]]; then
107
Will Drewrybcbf1c42010-07-03 10:23:30 -0500108 # Legacy BIOS will use the kernel in the rootfs (via syslinux), as will
109 # standard EFI BIOS (via grub, from the EFI System Partition). Chrome OS
110 # BIOS will use a separate signed kernel partition, which we'll create now.
111 # FIXME: remove serial output, debugging messages.
112 mkdir -p ${FLAGS_working_dir}
113 cat <<EOF | cat - "${FLAGS_working_dir}/boot.config" \
114 > "${FLAGS_working_dir}/config.txt"
Will Drewry69563b72010-06-24 16:12:58 -0500115earlyprintk=serial,ttyS0,115200
116console=ttyS0,115200
117init=/sbin/init
118add_efi_memmap
119boot=local
120rootwait
Will Drewry69563b72010-06-24 16:12:58 -0500121ro
122noresume
123noswap
124i915.modeset=1
125loglevel=7
126cros_secure
Will Drewry69563b72010-06-24 16:12:58 -0500127EOF
Will Drewrybcbf1c42010-07-03 10:23:30 -0500128 WORK="${WORK} ${FLAGS_working_dir}/config.txt"
Will Drewry69563b72010-06-24 16:12:58 -0500129
Bill Richardson2ace49e2010-07-01 10:23:27 -0700130
Will Drewrybcbf1c42010-07-03 10:23:30 -0500131 # FIX: The .vbprivk files are not encrypted, so we shouldn't just leave them
132 # lying around as a general thing.
Bill Richardson2ace49e2010-07-01 10:23:27 -0700133
Will Drewrybcbf1c42010-07-03 10:23:30 -0500134 # Wrap the kernel data keypair, used for the kernel body
135 vbutil_key \
136 --pack "${FLAGS_working_dir}/kernel_data_key.vbpubk" \
137 --key "${FLAGS_keys_dir}/key_rsa2048.keyb" \
138 --version 1 \
139 --algorithm 4
140 WORK="${WORK} ${FLAGS_working_dir}/kernel_data_key.vbpubk"
Will Drewry69563b72010-06-24 16:12:58 -0500141
Will Drewrybcbf1c42010-07-03 10:23:30 -0500142 vbutil_key \
143 --pack "${FLAGS_working_dir}/kernel_data_key.vbprivk" \
144 --key "${FLAGS_keys_dir}/key_rsa2048.pem" \
145 --algorithm 4
146 WORK="${WORK} ${FLAGS_working_dir}/kernel_data_key.vbprivk"
Will Drewry69563b72010-06-24 16:12:58 -0500147
Bill Richardson2ace49e2010-07-01 10:23:27 -0700148
Will Drewrybcbf1c42010-07-03 10:23:30 -0500149 # Wrap the kernel subkey pair, used for the kernel's keyblock
150 vbutil_key \
151 --pack "${FLAGS_working_dir}/kernel_subkey.vbpubk" \
152 --key "${FLAGS_keys_dir}/key_rsa4096.keyb" \
153 --version 1 \
154 --algorithm 8
155 WORK="${WORK} ${FLAGS_working_dir}/kernel_subkey.vbpubk"
Bill Richardson2ace49e2010-07-01 10:23:27 -0700156
Will Drewrybcbf1c42010-07-03 10:23:30 -0500157 vbutil_key \
158 --pack "${FLAGS_working_dir}/kernel_subkey.vbprivk" \
159 --key "${FLAGS_keys_dir}/key_rsa4096.pem" \
160 --algorithm 8
161 WORK="${WORK} ${FLAGS_working_dir}/kernel_subkey.vbprivk"
Bill Richardson2ace49e2010-07-01 10:23:27 -0700162
163
Will Drewrybcbf1c42010-07-03 10:23:30 -0500164 # Create the kernel keyblock, containing the kernel data key
165 vbutil_keyblock \
166 --pack "${FLAGS_working_dir}/kernel.keyblock" \
167 --datapubkey "${FLAGS_working_dir}/kernel_data_key.vbpubk" \
168 --signprivate "${FLAGS_working_dir}/kernel_subkey.vbprivk" \
169 --flags 15
170 WORK="${WORK} ${FLAGS_working_dir}/kernel.keyblock"
Will Drewry69563b72010-06-24 16:12:58 -0500171
Will Drewrybcbf1c42010-07-03 10:23:30 -0500172 # Verify the keyblock.
173 vbutil_keyblock \
174 --unpack "${FLAGS_working_dir}/kernel.keyblock" \
175 --signpubkey "${FLAGS_working_dir}/kernel_subkey.vbpubk"
Will Drewry69563b72010-06-24 16:12:58 -0500176
Will Drewrybcbf1c42010-07-03 10:23:30 -0500177 # TODO: We should sign the kernel blob using the recovery root key and
178 # recovery kernel data key instead (to create the recovery image), and then
179 # re-sign it this way for the install image. But we'll want to keep the
180 # install vblock separate, so we can just copy that part over separately when
181 # we install it instead of the whole kernel blob.
Bill Richardson2ace49e2010-07-01 10:23:27 -0700182
Will Drewrybcbf1c42010-07-03 10:23:30 -0500183 # Create and sign the kernel blob
184 vbutil_kernel \
185 --pack "${FLAGS_to}" \
186 --keyblock "${FLAGS_working_dir}/kernel.keyblock" \
187 --signprivate "${FLAGS_working_dir}/kernel_data_key.vbprivk" \
188 --version 1 \
189 --config "${FLAGS_working_dir}/config.txt" \
190 --bootloader /lib64/bootstub/bootstub.efi \
191 --vmlinuz "${FLAGS_vmlinuz}"
Will Drewry69563b72010-06-24 16:12:58 -0500192
Will Drewrybcbf1c42010-07-03 10:23:30 -0500193 # And verify it.
194 vbutil_kernel \
195 --verify "${FLAGS_to}" \
196 --signpubkey "${FLAGS_working_dir}/kernel_subkey.vbpubk"
Will Drewry69563b72010-06-24 16:12:58 -0500197
Will Drewrybcbf1c42010-07-03 10:23:30 -0500198elif [[ "${FLAGS_arch}" = "arm" ]]; then
Will Drewry69563b72010-06-24 16:12:58 -0500199 # FIXME: For now, ARM just uses the unsigned kernel by itself.
200 cp -f "${FLAGS_vmlinuz}" "${FLAGS_to}"
Will Drewrybcbf1c42010-07-03 10:23:30 -0500201else
202 error "Unknown arch: ${FLAGS_arch}"
Will Drewry69563b72010-06-24 16:12:58 -0500203fi
204
205set +e # cleanup failure is a-ok
206
207if [[ ${FLAGS_keep_work} -eq ${FLAGS_FALSE} ]]; then
Will Drewrybcbf1c42010-07-03 10:23:30 -0500208 info "Cleaning up temporary files: ${WORK}"
Will Drewry69563b72010-06-24 16:12:58 -0500209 rm ${WORK}
210 rmdir ${FLAGS_working_dir}
211fi
212
Will Drewrybcbf1c42010-07-03 10:23:30 -0500213info "Kernel partition image emitted: ${FLAGS_to}"
214
215if [[ -f ${FLAGS_rootfs_hash} ]]; then
216 info "Root filesystem hash emitted: ${FLAGS_rootfs_hash}"
217fi