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

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

Issue 3026018: Add script for re-signing final firmware images with the correct keys. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git
Patch Set: . Created 10 years, 5 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
OLDNEW
(Empty)
1 #!/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 # Script to resign a firmware image using a different set of keys
8 # for use on signing servers.
9 #
10 # arguments: src_fd, dst_fd, firmware_datakey, and firmware_keyblock
11 #
12 # src_fd: Input firmware image (in .fd format)
13 # dst_fd: output firmware image name
14 # firmware_datakey: Key used to sign firmware data (in .vbprivk format)
15 # firmware_keyblock: Key block for firmware data key (in .keyblock format)
16 #
17 # Both the fmap_decode tool and vbutil_firmware should be in the system path.
18 #
19 # This script parses the output of fmap_decode tool from the Flashmap project
20 # http://code.google.com/p/flashmap
21 #
22 # to determine the regions in the image containing "Firmware [A|B] Data" and
23 # "Firmware [A|B] Key", which contain firmware data and firmware vblocks
24 # respectively. It will then generate new vblocks using the set of keys
25 # passed as arguments and output a new firmware image, with this new firmware
26 # vblocks the old ones.
27 #
28 # Here is an example output of fmap_decode:
29 #
30 # area_offset="0x001c0000" area_size="0x00040000" area_name="Boot Stub" \
31 # area_flags_raw="0x01" area_flags="static"
32 # area_offset="0x001a0000" area_size="0x00020000" area_name="GBB Area" \
33 # area_flags_raw="0x01" area_flags="static"
34 # area_offset="0x00008000" area_size="0x00002000" area_name="Firmware A Key" \
35 # area_flags_raw="0x01" area_flags="static"
36 # area_offset="0x0000a000" area_size="0x0009e000" area_name="Firmware A Data" \
37 # area_flags_raw="0x03" area_flags="static,compressed"
38 # area_offset="0x000a8000" area_size="0x00002000" area_name="Firmware B Key" \
39 # area_flags_raw="0x01" area_flags="static"
40 # area_offset="0x000aa000" area_size="0x0002e000" area_name="Firmware B Data" \
41 # area_flags_raw="0x03" area_flags="static,compressed"
42 # area_offset="0x00005200" area_size="0x00001000" area_name="RW VPD" \
43 # area_flags_raw="0x00" area_flags=""
44 #
45 # This shows that Firmware A Data is at offset 0x0000a0000 in the .fd image
46 # and is of size 0x0009e000 bytes. This can be extracted to generate new vblocks
47 # which can then replace old vblock for Firmware A ("Firmware A Key" region at
48 # offset 0x00008000 and size 0x00002000).
49
50 # Abort on error
51 set -e
52
53 # Check arguments
54 if [ $# -ne 5 ] ; then
55 echo \
56 "Usage: $0 src_fd dst_fd firmware_datakey firmware_keyblock kernel_subkey"
57 exit 1
58 fi
59
60 # Make sure the tools we need are available.
61 for prog in fmap_decode vbutil_firmware; do
62 type -P "${prog}" &>/dev/null || \
63 { echo "${prog} tool not found."; exit 1; }
64 done
65
66 src_fd=$1
67 dst_fd=$2
68 firmware_datakey=$3
69 firmware_keyblock=$4
70 kernel_subkey=$5
71
72 # TODO(gauravsh): Figure out where the version comes from.
73 # Do we rev it manually?
74 VERSION=1
75
76 # Parse offsets and size of firmware data and vblocks
77 for i in "A" "B"
78 do
79 match_str="$i Key"
80 line=$(fmap_decode $1 | grep "$match_str")
81 offset="$(echo $line | sed -e 's/.*area_offset=\"\([a-f0-9x]*\)\".*/\1/')"
82 eval let \
83 fw${i}_vblock_offset="$offset"
84 size="$(echo $line | sed -e 's/.*area_size=\"\([a-f0-9x]*\)\".*/\1/')"
85 eval let \
86 fw${i}_vblock_size="$size"
87
88 match_str="$i Data"
89 line=$(fmap_decode $1 | grep "$match_str")
90 offset="$(echo $line | sed -e 's/.*area_offset=\"\([a-f0-9x]*\)\".*/\1/')"
91 eval let \
92 fw${i}_offset="$offset"
93 size="$(echo $line | sed -e 's/.*area_size=\"\([a-f0-9x]*\)\".*/\1/')"
94 eval let \
95 fw${i}_size="$size"
96 done
97
98 temp_fwimage=$(mktemp)
99 temp_out_vb=$(mktemp)
100 trap "rm -f ${temp_fwimage} ${temp_out_vb}" EXIT
101
102 # Extract out Firmware A data and generate signature using the right keys
103 dd if="${src_fd}" of="${temp_fwimage}" skip="${fwA_offset}" bs=1 \
104 count="${fwA_size}"
105
106 echo "Re-calculating Firmware A vblock"
107 vbutil_firmware \
108 --vblock "${temp_out_vb}" \
109 --keyblock "${firmware_keyblock}" \
110 --signprivate "${firmware_datakey}" \
111 --version "${VERSION}" \
112 --fv "${temp_fwimage}" \
113 --kernelkey "${kernel_subkey}"
114
115 # Create a copy of the input image and put in the new vblock for firmware A
116 cp "${src_fd}" "${dst_fd}"
117 dd if="${temp_out_vb}" of="${dst_fd}" seek="${fwA_vblock_offset}" bs=1 \
118 count="${fwA_vblock_size}" conv=notrunc
119
120 # Repeat for firmware B
121 dd if="${src_fd}" of="${temp_fwimage}" skip="${fwB_offset}" bs=1 \
122 count="${fwB_size}"
123 echo "Re-calculating Firmware B vblock"
124 vbutil_firmware \
125 --vblock "${temp_out_vb}" \
126 --keyblock "${firmware_keyblock}" \
127 --signprivate "${firmware_datakey}" \
128 --version "${VERSION}" \
129 --fv "${temp_fwimage}" \
130 --kernelkey "${kernel_subkey}"
131
132 # Destination image has already been created.
133 dd if="${temp_out_vb}" of="${dst_fd}" seek="${fwB_vblock_offset}" bs=1 \
134 count="${fwB_vblock_size}" conv=notrunc
135
136 echo "New signed image was output to ${dst_fd}"
OLDNEW
« no previous file with comments | « scripts/image_signing/cros_resign_image_standalone.sh ('k') | scripts/image_signing/unpack_firmwarefd.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698