Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: scripts/image_signing/sign_official_build.sh

Issue 4262004: Fix signing script to work with new recovery image format. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: 80 Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/bash 1 #!/bin/bash
2 2
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 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 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 # Sign the final build image using the "official" keys. 7 # Sign the final build image using the "official" keys.
8 # 8 #
9 # Prerequisite tools needed in the system path: 9 # Prerequisite tools needed in the system path:
10 # 10 #
11 # gbb_utility (from src/platform/vboot_reference) 11 # gbb_utility (from src/platform/vboot_reference)
12 # vbutil_kernel (from src/platform/vboot_reference) 12 # vbutil_kernel (from src/platform/vboot_reference)
13 # cgpt (from src/platform/vboot_reference) 13 # cgpt (from src/platform/vboot_reference)
14 # dump_kernel_config (from src/platform/vboot_reference) 14 # dump_kernel_config (from src/platform/vboot_reference)
15 # verity (from src/platform/verity) 15 # verity (from src/platform/verity)
16 # load_kernel_test (from src/platform/vboot_reference) 16 # load_kernel_test (from src/platform/vboot_reference)
17 # dumpe2fs 17 # dumpe2fs
18 # sha1sum
18 19
19 # Load common constants and variables. 20 # Load common constants and variables.
20 . "$(dirname "$0")/common.sh" 21 . "$(dirname "$0")/common.sh"
21 22
22 # Print usage string 23 # Print usage string
23 usage() { 24 usage() {
24 cat <<EOF 25 cat <<EOF
25 Usage: $PROG <type> input_image /path/to/keys/dir [output_image] 26 Usage: $PROG <type> input_image /path/to/keys/dir [output_image]
26 where <type> is one of: 27 where <type> is one of:
27 ssd (sign an SSD image) 28 ssd (sign an SSD image)
28 recovery (sign a USB recovery image) 29 recovery (sign a USB recovery image)
29 install (sign a factory install image) 30 install (sign a factory install image)
30 verify (verify an image including rootfs hashes) 31 verify (verify an image including rootfs hashes)
31 32
32 If you are signing an image, you must specify an [output_image]. 33 If you are signing an image, you must specify an [output_image].
33 EOF 34 EOF
34 } 35 }
35 36
36 if [ $# -ne 3 ] && [ $# -ne 4 ]; then 37 if [ $# -ne 3 ] && [ $# -ne 4 ]; then
37 usage 38 usage
38 exit 1 39 exit 1
39 fi 40 fi
40 41
41 # Abort on errors. 42 # Abort on errors.
42 set -e 43 set -e
43 44
44 # Make sure the tools we need are available. 45 # Make sure the tools we need are available.
45 for prereqs in gbb_utility vbutil_kernel cgpt dump_kernel_config verity \ 46 for prereqs in gbb_utility vbutil_kernel cgpt dump_kernel_config verity \
46 load_kernel_test dumpe2fs; 47 load_kernel_test dumpe2fs sha1sum;
47 do 48 do
48 type -P "${prereqs}" &>/dev/null || \ 49 type -P "${prereqs}" &>/dev/null || \
49 { echo "${prereqs} tool not found."; exit 1; } 50 { echo "${prereqs} tool not found."; exit 1; }
50 done 51 done
51 52
52 TYPE=$1 53 TYPE=$1
53 INPUT_IMAGE=$2 54 INPUT_IMAGE=$2
54 KEY_DIR=$3 55 KEY_DIR=$3
55 OUTPUT_IMAGE=$4 56 OUTPUT_IMAGE=$4
56 57
57 # Get current rootfs hash and kernel command line 58 # Get current rootfs hash and kernel command line
58 # ARGS: IMAGE 59 # ARGS: IMAGE KERNELPART
59 grab_kernel_config() { 60 grab_kernel_config() {
60 local image=$1 61 local image=$1
62 local kernelpart=$2 # Kernel partition number to grab.
61 # Grab the existing kernel partition and get the kernel config. 63 # Grab the existing kernel partition and get the kernel config.
62 temp_kimage=$(make_temp_file) 64 temp_kimage=$(make_temp_file)
63 extract_image_partition ${image} 2 ${temp_kimage} 65 extract_image_partition ${image} ${kernelpart} ${temp_kimage}
64 dump_kernel_config ${temp_kimage} 66 dump_kernel_config ${temp_kimage}
65 } 67 }
66 68
67 # Get the hash from a kernel config command line 69 # Get the hash from a kernel config command line
68 get_hash_from_config() { 70 get_hash_from_config() {
69 local kernel_config=$1 71 local kernel_config=$1
70 echo ${kernel_config} | sed -e 's/.*dm="\([^"]*\)".*/\1/g' | \ 72 echo ${kernel_config} | sed -e 's/.*dm="\([^"]*\)".*/\1/g' | \
71 cut -f2- -d, | cut -f9 -d ' ' 73 cut -f2- -d, | cut -f9 -d ' '
72 } 74 }
73 75
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 ${rootfs_image} \ 110 ${rootfs_image} \
109 $((rootfs_sectors / 8)) \ 111 $((rootfs_sectors / 8)) \
110 ${hash_image}) 112 ${hash_image})
111 # Reconstruct new kernel config command line and replace placeholders. 113 # Reconstruct new kernel config command line and replace placeholders.
112 table="$(echo "$table" | 114 table="$(echo "$table" |
113 sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")" 115 sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")"
114 echo ${kernel_config} | sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${table}\3#g" 116 echo ${kernel_config} | sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${table}\3#g"
115 } 117 }
116 118
117 # Re-calculate rootfs hash, update rootfs and kernel command line. 119 # Re-calculate rootfs hash, update rootfs and kernel command line.
118 # Args: IMAGE KEYBLOCK PRIVATEKEY 120 # Args: IMAGE KEYBLOCK PRIVATEKEY KERNELPART
119 update_rootfs_hash() { 121 update_rootfs_hash() {
120 echo "Recalculating rootfs"
121 local image=$1 # Input image. 122 local image=$1 # Input image.
122 local keyblock=$2 # Keyblock for re-generating signed kernel partition 123 local keyblock=$2 # Keyblock for re-generating signed kernel partition
123 local signprivate=$3 # Private key to use for signing. 124 local signprivate=$3 # Private key to use for signing.
125 local kernelpart=$4 # Kernel partition number to update (usually 2 or 4)
126
127 echo "Updating rootfs hash and updating config for Kernel partition " \
128 "$kernelpart"
124 129
125 # check and clear need_to_resign tag 130 # check and clear need_to_resign tag
126 local rootfs_dir=$(make_temp_dir) 131 local rootfs_dir=$(make_temp_dir)
127 mount_image_partition_ro "${image}" 3 "${rootfs_dir}" 132 mount_image_partition_ro "${image}" 3 "${rootfs_dir}"
128 if has_needs_to_be_resigned_tag "${rootfs_dir}"; then 133 if has_needs_to_be_resigned_tag "${rootfs_dir}"; then
129 # remount as RW 134 # remount as RW
130 sudo umount -d "${rootfs_dir}" 135 sudo umount -d "${rootfs_dir}"
131 mount_image_partition "${image}" 3 "${rootfs_dir}" 136 mount_image_partition "${image}" 3 "${rootfs_dir}"
132 sudo rm -f "${rootfs_dir}/${TAG_NEEDS_TO_BE_SIGNED}" 137 sudo rm -f "${rootfs_dir}/${TAG_NEEDS_TO_BE_SIGNED}"
133 fi 138 fi
134 sudo umount -d "${rootfs_dir}" 139 sudo umount -d "${rootfs_dir}"
135 140
136 local rootfs_image=$(make_temp_file) 141 local rootfs_image=$(make_temp_file)
137 extract_image_partition ${image} 3 ${rootfs_image} 142 extract_image_partition ${image} 3 ${rootfs_image}
138 local kernel_config=$(grab_kernel_config "${image}") 143 local kernel_config=$(grab_kernel_config "${image}" ${kernelpart})
139 local hash_image=$(make_temp_file) 144 local hash_image=$(make_temp_file)
140 145
141 # Disable rw mount support prior to hashing. 146 # Disable rw mount support prior to hashing.
142 disable_rw_mount "${rootfs_image}" 147 disable_rw_mount "${rootfs_image}"
143 148
144 local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \ 149 local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \
145 "${kernel_config}" "${hash_image}") 150 "${kernel_config}" "${hash_image}")
151 echo "New config for kernel partition $kernelpart is:"
152 echo $new_kernel_config
146 153
147 local rootfs_blocks=$(sudo dumpe2fs "${rootfs_image}" 2> /dev/null | 154 local rootfs_blocks=$(sudo dumpe2fs "${rootfs_image}" 2> /dev/null |
148 grep "Block count" | 155 grep "Block count" |
149 tr -d ' ' | 156 tr -d ' ' |
150 cut -f2 -d:) 157 cut -f2 -d:)
151 local rootfs_sectors=$((rootfs_blocks * 8)) 158 local rootfs_sectors=$((rootfs_blocks * 8))
152 159
153 # Overwrite the appended hashes in the rootfs 160 # Overwrite the appended hashes in the rootfs
154 local temp_config=$(make_temp_file) 161 local temp_config=$(make_temp_file)
155 echo ${new_kernel_config} >${temp_config} 162 echo ${new_kernel_config} >${temp_config}
156 dd if=${hash_image} of=${rootfs_image} bs=512 \ 163 dd if=${hash_image} of=${rootfs_image} bs=512 \
157 seek=${rootfs_sectors} conv=notrunc 164 seek=${rootfs_sectors} conv=notrunc
158 165
159 local temp_kimage=$(make_temp_file) 166 local temp_kimage=$(make_temp_file)
160 extract_image_partition ${image} 2 ${temp_kimage} 167 extract_image_partition ${image} ${kernelpart} ${temp_kimage}
161 # Re-calculate kernel partition signature and command line. 168 # Re-calculate kernel partition signature and command line.
162 local updated_kimage=$(make_temp_file) 169 local updated_kimage=$(make_temp_file)
163 vbutil_kernel --repack ${updated_kimage} \ 170 vbutil_kernel --repack ${updated_kimage} \
164 --keyblock ${keyblock} \ 171 --keyblock ${keyblock} \
165 --signprivate ${signprivate} \ 172 --signprivate ${signprivate} \
166 --oldblob ${temp_kimage} \ 173 --oldblob ${temp_kimage} \
167 --config ${temp_config} 174 --config ${temp_config}
168 175
169 replace_image_partition ${image} 2 ${updated_kimage} 176 replace_image_partition ${image} ${kernelpart} ${updated_kimage}
170 replace_image_partition ${image} 3 ${rootfs_image} 177 replace_image_partition ${image} 3 ${rootfs_image}
171 } 178 }
172 179
173 # Extracts the firmware update binaries from the a firmware update 180 # Extracts the firmware update binaries from the a firmware update
174 # shell ball (generated by src/platform/firmware/pack_firmware.sh) 181 # shell ball (generated by src/platform/firmware/pack_firmware.sh)
175 # Args: INPUT_SCRIPT OUTPUT_DIR 182 # Args: INPUT_SCRIPT OUTPUT_DIR
176 get_firmwarebin_from_shellball() { 183 get_firmwarebin_from_shellball() {
177 local input=$1 184 local input=$1
178 local output_dir=$2 185 local output_dir=$2
179 if [ -s "${input}" ]; then 186 if [ -s "${input}" ]; then
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 new_shellball=$(make_temp_file) 253 new_shellball=$(make_temp_file)
247 cat ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate | \ 254 cat ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate | \
248 sed -e '/^begin .*firmware_package/,/end/D' | \ 255 sed -e '/^begin .*firmware_package/,/end/D' | \
249 cat - ${new_fwblob} >${new_shellball} 256 cat - ${new_fwblob} >${new_shellball}
250 sudo cp ${new_shellball} ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate 257 sudo cp ${new_shellball} ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate
251 echo "Re-signed firmware AU payload in $image" 258 echo "Re-signed firmware AU payload in $image"
252 } 259 }
253 260
254 # Verify an image including rootfs hash using the specified keys. 261 # Verify an image including rootfs hash using the specified keys.
255 verify_image() { 262 verify_image() {
256 local kernel_config=$(grab_kernel_config ${INPUT_IMAGE}) 263 local kernel_config=$(grab_kernel_config ${INPUT_IMAGE} 2)
257 local rootfs_image=$(make_temp_file) 264 local rootfs_image=$(make_temp_file)
258 extract_image_partition ${INPUT_IMAGE} 3 ${rootfs_image} 265 extract_image_partition ${INPUT_IMAGE} 3 ${rootfs_image}
259 local hash_image=$(make_temp_file) 266 local hash_image=$(make_temp_file)
260 local type="" 267 local type=""
261 268
262
263 # First, perform RootFS verification 269 # First, perform RootFS verification
264 echo "Verifying RootFS hash..." 270 echo "Verifying RootFS hash..."
265 local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \ 271 local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \
266 "${kernel_config}" "${hash_image}") 272 "${kernel_config}" "${hash_image}")
267 local expected_hash=$(get_hash_from_config "${new_kernel_config}") 273 local expected_hash=$(get_hash_from_config "${new_kernel_config}")
268 local got_hash=$(get_hash_from_config "${kernel_config}") 274 local got_hash=$(get_hash_from_config "${kernel_config}")
269 275
270 if [ ! "${got_hash}" = "${expected_hash}" ]; then 276 if [ ! "${got_hash}" = "${expected_hash}" ]; then
271 cat <<EOF 277 cat <<EOF
272 FAILED: RootFS hash is incorrect. 278 FAILED: RootFS hash is incorrect.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 # Generate the SSD image 311 # Generate the SSD image
306 sign_for_ssd() { 312 sign_for_ssd() {
307 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 313 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
308 ${KEY_DIR}/kernel_data_key.vbprivk \ 314 ${KEY_DIR}/kernel_data_key.vbprivk \
309 ${KEY_DIR}/kernel.keyblock 315 ${KEY_DIR}/kernel.keyblock
310 echo "Signed SSD image output to ${OUTPUT_IMAGE}" 316 echo "Signed SSD image output to ${OUTPUT_IMAGE}"
311 } 317 }
312 318
313 # Generate the USB (recovery + install) image 319 # Generate the USB (recovery + install) image
314 sign_for_recovery() { 320 sign_for_recovery() {
315 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 321 # Update the Kernel B hash in Kernel A command line
316 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 322 temp_kimageb=$(make_temp_file)
317 ${KEY_DIR}/recovery_kernel.keyblock 323 extract_image_partition ${INPUT_IMAGE} 4 ${temp_kimageb}
324 local kern_a_config=$(grab_kernel_config "${INPUT_IMAGE}" 2)
325 local kern_b_hash=$(sha1sum ${temp_kimageb} | cut -f1 -d' ')
326
327 temp_configa=$(make_temp_file)
328 echo "$kern_a_config" |
329 sed -e "s#\(kern_b_hash=\)[a-z0-9]*#\1${kern_b_hash}#" > ${temp_configa}
330 echo "New config for kernel partition 2 is"
331 cat $temp_configa
332
333 # Make a copy of the input image
334 cp "${INPUT_IMAGE}" "${OUTPUT_IMAGE}"
335 local temp_kimagea=$(make_temp_file)
336 extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimagea}
337 # Re-calculate kernel partition signature and command line.
338 local updated_kimagea=$(make_temp_file)
339 vbutil_kernel --repack ${updated_kimagea} \
340 --keyblock ${KEY_DIR}/recovery_kernel.keyblock \
341 --signprivate ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
342 --oldblob ${temp_kimagea} \
343 --config ${temp_configa}
344
345 replace_image_partition ${OUTPUT_IMAGE} 2 ${updated_kimagea}
318 346
319 # Now generate the installer vblock with the SSD keys. 347 # Now generate the installer vblock with the SSD keys.
320 temp_kimage=$(make_temp_file) 348 # The installer vblock is for KERN-B on recovery images.
321 temp_out_vb=$(make_temp_file) 349 temp_out_vb=$(make_temp_file)
322 extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimage} 350 extract_image_partition ${OUTPUT_IMAGE} 4 ${temp_kimageb}
323 ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimage} ${temp_out_vb} \ 351 ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimageb} ${temp_out_vb} \
324 ${KEY_DIR}/kernel_data_key.vbprivk \ 352 ${KEY_DIR}/kernel_data_key.vbprivk \
325 ${KEY_DIR}/kernel.keyblock 353 ${KEY_DIR}/kernel.keyblock
326 354
327 # Copy the installer vblock to the stateful partition. 355 # Copy the installer vblock to the stateful partition.
356 # TODO(gauravsh): Remove this after we get rid of the need to overwrite
357 # the vblock during installs. Kenrn B could directly be signed by the
358 # SSD keys.
328 local stateful_dir=$(make_temp_dir) 359 local stateful_dir=$(make_temp_dir)
329 mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir} 360 mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
330 sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock 361 sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
331 362
332 echo "Signed recovery image output to ${OUTPUT_IMAGE}" 363 echo "Signed recovery image output to ${OUTPUT_IMAGE}"
333 } 364 }
334 365
335 # Generate the factory install image. 366 # Generate the factory install image.
336 sign_for_factory_install() { 367 sign_for_factory_install() {
337 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 368 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
(...skipping 12 matching lines...) Expand all
350 if [ -z "${OUTPUT_IMAGE}" ]; then 381 if [ -z "${OUTPUT_IMAGE}" ]; then
351 usage 382 usage
352 exit 1 383 exit 1
353 fi 384 fi
354 385
355 386
356 if [ "${TYPE}" == "ssd" ]; then 387 if [ "${TYPE}" == "ssd" ]; then
357 resign_firmware_payload ${INPUT_IMAGE} 388 resign_firmware_payload ${INPUT_IMAGE}
358 update_rootfs_hash ${INPUT_IMAGE} \ 389 update_rootfs_hash ${INPUT_IMAGE} \
359 ${KEY_DIR}/kernel.keyblock \ 390 ${KEY_DIR}/kernel.keyblock \
360 ${KEY_DIR}/kernel_data_key.vbprivk 391 ${KEY_DIR}/kernel_data_key.vbprivk \
392 2
361 sign_for_ssd 393 sign_for_ssd
362 elif [ "${TYPE}" == "recovery" ]; then 394 elif [ "${TYPE}" == "recovery" ]; then
363 resign_firmware_payload ${INPUT_IMAGE} 395 resign_firmware_payload ${INPUT_IMAGE}
396 # Both kernel command lines must have the correct rootfs hash
364 update_rootfs_hash ${INPUT_IMAGE} \ 397 update_rootfs_hash ${INPUT_IMAGE} \
365 ${KEY_DIR}/recovery_kernel.keyblock \ 398 ${KEY_DIR}/recovery_kernel.keyblock \
366 ${KEY_DIR}/recovery_kernel_data_key.vbprivk 399 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
400 4
401 update_rootfs_hash ${INPUT_IMAGE} \
402 ${KEY_DIR}/recovery_kernel.keyblock \
403 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
404 2
367 sign_for_recovery 405 sign_for_recovery
368 elif [ "${TYPE}" == "install" ]; then 406 elif [ "${TYPE}" == "install" ]; then
369 resign_firmware_payload ${INPUT_IMAGE} 407 resign_firmware_payload ${INPUT_IMAGE}
370 update_rootfs_hash ${INPUT_IMAGE} \ 408 update_rootfs_hash ${INPUT_IMAGE} \
371 ${KEY_DIR}/installer_kernel.keyblock \ 409 ${KEY_DIR}/installer_kernel.keyblock \
372 ${KEY_DIR}/recovery_kernel_data_key.vbprivk 410 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
411 2
373 sign_for_factory_install 412 sign_for_factory_install
374 else 413 else
375 echo "Invalid type ${TYPE}" 414 echo "Invalid type ${TYPE}"
376 exit 1 415 exit 1
377 fi 416 fi
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698