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

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

Issue 3083025: Make signing script re-sign Firmware AU payload, and update rootfs hash. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git
Patch Set: review fixes Created 10 years, 4 months 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 | « scripts/image_signing/resign_image.sh ('k') | 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:
10 #
11 # gbb_utility (from src/platform/vboot_reference)
12 # vbutil_kernel (from src/platform/vboot_reference)
13 # cgpt (from src/platform/vboot_reference)
14 # dump_kernel_config (from src/platform/vboot_reference)
15 # verity (from src/platform/verity)
16 #
9 # Usage: sign_for_ssd.sh <type> input_image /path/to/keys/dir output_image 17 # Usage: sign_for_ssd.sh <type> input_image /path/to/keys/dir output_image
10 # 18 #
11 # where <type> is one of: 19 # where <type> is one of:
12 # ssd (sign an SSD image) 20 # ssd (sign an SSD image)
13 # recovery (sign a USB recovery image) 21 # recovery (sign a USB recovery image)
14 # install (sign a factory install image) 22 # install (sign a factory install image)
15 23
16 # Load common constants and variables. 24 # Load common constants and variables.
17 . "$(dirname "$0")/common.sh" 25 . "$(dirname "$0")/common.sh"
18 26
19 if [ $# -ne 4 ]; then 27 if [ $# -ne 4 ]; then
20 cat <<EOF 28 cat <<EOF
21 Usage: $0 <type> input_image /path/to/keys/dir output_image" 29 Usage: $0 <type> input_image /path/to/keys/dir output_image"
22 where <type> is one of: 30 where <type> is one of:
23 ssd (sign an SSD image) 31 ssd (sign an SSD image)
24 recovery (sign a USB recovery image) 32 recovery (sign a USB recovery image)
25 install (sign a factory install image) 33 install (sign a factory install image)
26 EOF 34 EOF
27 exit 1 35 exit 1
28 fi 36 fi
29 37
30 # Abort on errors. 38 # Abort on errors.
31 set -e 39 set -e
32 40
33 TYPE=$1 41 TYPE=$1
34 INPUT_IMAGE=$2 42 INPUT_IMAGE=$2
35 KEY_DIR=$3 43 KEY_DIR=$3
36 OUTPUT_IMAGE=$4 44 OUTPUT_IMAGE=$4
37 45
46 # Re-calculate rootfs hash, update rootfs and kernel command line.
47 # Args: IMAGE KEYBLOCK PRIVATEKEY
48 recalculate_rootfs_hash() {
49 local image=$1 # Input image.
50 local keyblock=$2 # Keyblock for re-generating signed kernel partition
51 local signprivate=$3 # Private key to use for signing.
52
53 # First, grab the existing kernel partition and get the kernel config.
54 temp_kimage=$(make_temp_file)
55 extract_image_partition ${image} 2 ${temp_kimage}
56 local kernel_config=$(sudo dump_kernel_config ${temp_kimage})
57 local dm_config=$(echo $kernel_config |
58 sed -e 's/.*dm="\([^"]*\)".*/\1/g' |
59 cut -f2- -d,)
60 # We extract dm=... portion of the config command line. Here's an example:
61 #
62 # dm="0 2097152 verity ROOT_DEV HASH_DEV 2097152 1 \
63 # sha1 63b7ad16cb9db4b70b28593f825aa6b7825fdcf2"
64 #
65
66 if [ -z ${dm_config} ]; then
67 echo "WARNING: Couldn't grab dm_config. Aborting rootfs hash calculation"
68 return
69 fi
70 local rootfs_sectors=$(echo ${dm_config} | cut -f2 -d' ')
71 local root_dev=$(echo ${dm_config} | cut -f4 -d ' ')
72 local hash_dev=$(echo ${dm_config} | cut -f5 -d ' ')
73 local verity_depth=$(echo ${dm_config} | cut -f7 -d' ')
74 local verity_algorithm=$(echo ${dm_config} | cut -f8 -d' ')
75
76 # Mount the rootfs and run the verity tool on it.
77 local hash_image=$(make_temp_file)
78 local rootfs_img=$(make_temp_file)
79 extract_image_partition ${image} 3 ${rootfs_img}
80 local table="vroot none ro,"$(sudo verity create \
81 ${verity_depth} \
82 ${verity_algorithm} \
83 ${rootfs_img} \
84 $((rootfs_sectors / 8)) \
85 ${hash_image})
86 # Reconstruct new kernel config command line and replace placeholders.
87 table="$(echo "$table" |
88 sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")"
89 kernel_config=$(echo ${kernel_config} |
90 sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${table}\3#g")
91
92 # Overwrite the appended hashes in the rootfs
93 local temp_config=$(make_temp_file)
94 echo ${kernel_config} >${temp_config}
95 dd if=${hash_image} of=${rootfs_img} bs=512 \
96 seek=${rootfs_sectors} conv=notrunc
97
98 # Re-calculate kernel partition signature and command line.
99 local updated_kimage=$(make_temp_file)
100 vbutil_kernel --repack ${updated_kimage} \
101 --keyblock ${keyblock} \
102 --signprivate ${signprivate} \
103 --oldblob ${temp_kimage} \
104 --config ${temp_config}
105
106 replace_image_partition ${image} 2 ${updated_kimage}
107 replace_image_partition ${image} 3 ${rootfs_img}
108 }
109
110 # Extracts the firmware update binaries from the a firmware update
111 # shell ball (generated by src/platform/firmware/pack_firmware.sh)
112 # Args: INPUT_SCRIPT OUTPUT_DIR
113 get_firmwarebin_from_shellball() {
114 local input=$1
115 local output_dir=$2
116 uudecode -o - ${input} | tar -C ${output_dir} -zxf - 2>/dev/null || \
117 echo "Extracting firmware autoupdate failed.
118 Try re-running with FW_NOUPDATE=1." && exit 1
119 }
120
121 # Re-sign the firmware AU payload inside the image rootfs with a new keys.
122 # Args: IMAGE
123 resign_firmware_payload() {
124 local image=$1
125
126 # Grab firmware image from the autoupdate shellball.
127 local rootfs_dir=$(make_temp_dir)
128 mount_image_partition ${image} 3 ${rootfs_dir}
129
130 local shellball_dir=$(make_temp_dir)
131 get_firmwarebin_from_shellball \
132 ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate ${shellball_dir}
133
134 temp_outfd=$(make_temp_file)
135 # Replace the root key in the GBB
136 # TODO(gauravsh): Remove when we lock down the R/O portion of firmware.
137 gbb_utility -s \
138 --rootkey=${KEY_DIR}/root_key.vbpubk \
139 --recoverykey=${KEY_DIR}/recovery_key.vbpubk \
140 ${shellball_dir}/bios.bin ${temp_outfd}
141
142 # Resign the firmware with new keys
143 ${SCRIPT_DIR}/resign_firmwarefd.sh ${temp_outfd} ${temp_dir}/bios.bin \
144 ${KEY_DIR}/firmware_data_key.vbprivk \
145 ${KEY_DIR}/firmware.keyblock \
146 ${KEY_DIR}/kernel_subkey.vbpubk
147
148 # Replace MD5 checksum in the firmware update payload
149 newfd_checksum=$(md5sum ${shellball_dir}/bios.bin | cut -f 1 -d ' ')
150 temp_version=$(make_temp_file)
151 cat ${shellball_dir}/VERSION |
152 sed -e "s#\(.*\)\ \(.*bios.bin.*\)#${newfd_checksum}\ \2#" > ${temp_version}
153 sudo cp ${temp_version} ${shellball_dir}/VERSION
154
155 # Re-generate firmware_update.tgz and copy over encoded archive in
156 # the original shell ball.
157 new_fwblob=$(make_temp_file)
158 tar zcf - -C ${shellball_dir} . | \
159 uuencode firmware_package.tgz > ${new_fwblob}
160 new_shellball=$(make_temp_file)
161 cat ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate | \
162 sed -e '/^begin .*firmware_package/,/end/D' | \
163 cat - ${new_fwblob} >${new_shellball}
164 sudo cp ${new_shellball} ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate
165 # Force unmount of the image as it is needed later.
166 sudo umount -d ${rootfs_dir}
167 echo "Re-signed firmware AU payload in $image"
168 }
38 169
39 # Generate the SSD image 170 # Generate the SSD image
40 sign_for_ssd() { 171 sign_for_ssd() {
41 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 172 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
42 ${KEY_DIR}/kernel_data_key.vbprivk \ 173 ${KEY_DIR}/kernel_data_key.vbprivk \
43 ${KEY_DIR}/kernel.keyblock 174 ${KEY_DIR}/kernel.keyblock
44 echo "Output signed SSD image to ${OUTPUT_IMAGE}" 175 echo "Output signed SSD image to ${OUTPUT_IMAGE}"
45 } 176 }
46 177
47 # Generate the USB (recovery + install) image 178 # Generate the USB (recovery + install) image
48 sign_for_recovery() { 179 sign_for_recovery() {
49 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 180 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
50 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 181 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
51 ${KEY_DIR}/recovery_kernel.keyblock 182 ${KEY_DIR}/recovery_kernel.keyblock
52 183
53 # Now generate the installer vblock with the SSD keys. 184 # Now generate the installer vblock with the SSD keys.
54 temp_kimage=$(mktemp) 185 temp_kimage=$(make_temp_file)
55 trap "rm -f ${temp_kimage}" EXIT 186 temp_out_vb=$(make_temp_file)
56 temp_out_vb=$(mktemp)
57 trap "rm -f ${temp_out_vb}" EXIT
58 extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimage} 187 extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimage}
59 ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimage} ${temp_out_vb} \ 188 ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimage} ${temp_out_vb} \
60 ${KEY_DIR}/kernel_data_key.vbprivk \ 189 ${KEY_DIR}/kernel_data_key.vbprivk \
61 ${KEY_DIR}/kernel.keyblock 190 ${KEY_DIR}/kernel.keyblock
62 191
63 # Copy the installer vblock to the stateful partition. 192 # Copy the installer vblock to the stateful partition.
64 local stateful_dir=$(mktemp -d) 193 local stateful_dir=$(make_temp_dir)
65 trap "sudo umount -d $stateful_dir; rm -rf $stateful_dir" EXIT
66 mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir} 194 mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
67 sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock 195 sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
68 196
69 echo "Output signed recovery image to ${OUTPUT_IMAGE}" 197 echo "Output signed recovery image to ${OUTPUT_IMAGE}"
70 } 198 }
71 199
72 # Generate the factory install image. 200 # Generate the factory install image.
73 sign_for_factory_install() { 201 sign_for_factory_install() {
74 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ 202 ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
75 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 203 ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
76 ${KEY_DIR}/installer_kernel.keyblock 204 ${KEY_DIR}/installer_kernel.keyblock
77 echo "Output signed factory install image to ${OUTPUT_IMAGE}" 205 echo "Output signed factory install image to ${OUTPUT_IMAGE}"
78 } 206 }
79 207
208 if [ ! "${FW_NOUPDATE}" == "1" ]; then
209 resign_firmware_payload ${INPUT_IMAGE}
210 fi
211
80 if [ "${TYPE}" == "ssd" ]; then 212 if [ "${TYPE}" == "ssd" ]; then
213 recalculate_rootfs_hash ${INPUT_IMAGE} \
214 ${KEY_DIR}/kernel.keyblock \
215 ${KEY_DIR}/kernel_data_key.vbprivk
81 sign_for_ssd 216 sign_for_ssd
82 elif [ "${TYPE}" == "recovery" ]; then 217 elif [ "${TYPE}" == "recovery" ]; then
218 recalculate_rootfs_hash ${INPUT_IMAGE} \
219 ${KEY_DIR}/recovery_kernel.keyblock \
220 ${KEY_DIR}/recovery_kernel_data_key.vbprivk
83 sign_for_recovery 221 sign_for_recovery
84 elif [ "${TYPE}" == "install" ]; then 222 elif [ "${TYPE}" == "install" ]; then
223 recalculate_rootfs_hash ${INPUT_IMAGE} \
224 ${KEY_DIR}/installer_kernel.keyblock \
225 ${KEY_DIR}/recovery_kernel_data_key.vbprivk
85 sign_for_factory_install 226 sign_for_factory_install
86 else 227 else
87 echo "Invalid type ${TYPE}" 228 echo "Invalid type ${TYPE}"
88 exit 1 229 exit 1
89 fi 230 fi
90
91
OLDNEW
« no previous file with comments | « scripts/image_signing/resign_image.sh ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698