1#!/bin/bash -eux
2# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6me=${0##*/}
7TMP="$me.tmp"
8
9# Work in scratch directory
10cd "$OUTDIR"
11
12DEVKEYS=${SRCDIR}/tests/devkeys
13
14echo "hi there" > ${TMP}.config.txt
15echo "hello boys" > ${TMP}.config2.txt
16dd if=/dev/urandom bs=512 count=1 of=${TMP}.bootloader.bin
17dd if=/dev/urandom bs=512 count=1 of=${TMP}.bootloader2.bin
18dd if=/dev/urandom bs=1M count=16 of=${TMP}.kern_partition
19
20# default padding
21padding=49152
22
23try_arch () {
24  local arch=$1
25
26  echo -n "${arch}: 1 " 1>&3
27
28  # pack it up the old way
29  ${FUTILITY} vbutil_kernel --debug \
30    --pack ${TMP}.blob1.${arch} \
31    --keyblock ${DEVKEYS}/recovery_kernel.keyblock \
32    --signprivate ${DEVKEYS}/recovery_kernel_data_key.vbprivk \
33    --version 1 \
34    --config ${TMP}.config.txt \
35    --bootloader ${TMP}.bootloader.bin \
36    --vmlinuz ${SCRIPTDIR}/data/vmlinuz-${arch}.bin \
37    --arch ${arch} \
38    --pad ${padding} \
39    --kloadaddr 0x11000
40
41  # verify the old way
42  ${FUTILITY} vbutil_kernel --verify ${TMP}.blob1.${arch} \
43    --pad ${padding} \
44    --signpubkey ${DEVKEYS}/recovery_key.vbpubk > ${TMP}.verify1
45
46  # pack it up the new way
47  ${FUTILITY} sign --debug \
48    --keyblock ${DEVKEYS}/recovery_kernel.keyblock \
49    --signprivate ${DEVKEYS}/recovery_kernel_data_key.vbprivk \
50    --version 1 \
51    --config ${TMP}.config.txt \
52    --bootloader ${TMP}.bootloader.bin \
53    --vmlinuz ${SCRIPTDIR}/data/vmlinuz-${arch}.bin \
54    --arch ${arch} \
55    --pad ${padding} \
56    --kloadaddr 0x11000 \
57    --outfile ${TMP}.blob2.${arch}
58
59  ${FUTILITY} vbutil_kernel --verify ${TMP}.blob2.${arch} \
60    --pad ${padding} \
61    --signpubkey ${DEVKEYS}/recovery_key.vbpubk > ${TMP}.verify2
62
63  # they should be identical
64  cmp ${TMP}.blob1.${arch} ${TMP}.blob2.${arch}
65  diff ${TMP}.verify1 ${TMP}.verify2
66
67  echo -n "2 " 1>&3
68
69  # repack it the old way
70  ${FUTILITY} vbutil_kernel --debug \
71    --repack ${TMP}.blob3.${arch} \
72    --oldblob ${TMP}.blob1.${arch} \
73    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
74    --keyblock ${DEVKEYS}/kernel.keyblock \
75    --version 2 \
76    --pad ${padding} \
77    --config ${TMP}.config2.txt \
78    --bootloader ${TMP}.bootloader2.bin
79
80  # verify the old way
81  ${FUTILITY} vbutil_kernel --verify ${TMP}.blob3.${arch} \
82    --pad ${padding} \
83    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify3
84
85  # repack it the new way
86  ${FUTILITY} sign --debug \
87    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
88    --keyblock ${DEVKEYS}/kernel.keyblock \
89    --version 2 \
90    --pad ${padding} \
91    --config ${TMP}.config2.txt \
92    --bootloader ${TMP}.bootloader2.bin \
93    ${TMP}.blob2.${arch} \
94    ${TMP}.blob4.${arch}
95
96  ${FUTILITY} vbutil_kernel --verify ${TMP}.blob4.${arch} \
97    --pad ${padding} \
98    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify4
99
100  # they should be identical
101  cmp ${TMP}.blob3.${arch} ${TMP}.blob4.${arch}
102  diff ${TMP}.verify3 ${TMP}.verify4
103
104  echo -n "3 " 1>&3
105
106  # repack it the new way, in-place
107  cp ${TMP}.blob2.${arch} ${TMP}.blob5.${arch}
108  ${FUTILITY} sign --debug \
109    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
110    --keyblock ${DEVKEYS}/kernel.keyblock \
111    --version 2 \
112    --pad ${padding} \
113    --config ${TMP}.config2.txt \
114    --bootloader ${TMP}.bootloader2.bin \
115    ${TMP}.blob5.${arch}
116
117  ${FUTILITY} vbutil_kernel --verify ${TMP}.blob5.${arch} \
118    --pad ${padding} \
119    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify5
120
121  # they should be identical
122  cmp ${TMP}.blob3.${arch} ${TMP}.blob5.${arch}
123  diff ${TMP}.verify3 ${TMP}.verify5
124
125  # and now just the vblocks...
126  echo -n "4 " 1>&3
127
128  # pack the old way
129  ${FUTILITY} vbutil_kernel \
130    --pack ${TMP}.blob1.${arch}.vb1 \
131    --vblockonly \
132    --keyblock ${DEVKEYS}/recovery_kernel.keyblock \
133    --signprivate ${DEVKEYS}/recovery_kernel_data_key.vbprivk \
134    --version 1 \
135    --config ${TMP}.config.txt \
136    --bootloader ${TMP}.bootloader.bin \
137    --vmlinuz ${SCRIPTDIR}/data/vmlinuz-${arch}.bin \
138    --arch ${arch} \
139    --pad ${padding} \
140    --kloadaddr 0x11000
141
142  # compare this new vblock with the one from the full pack
143  dd bs=${padding} count=1 if=${TMP}.blob1.${arch} of=${TMP}.blob1.${arch}.vb0
144  cmp ${TMP}.blob1.${arch}.vb0 ${TMP}.blob1.${arch}.vb1
145
146  # pack the new way
147  ${FUTILITY} sign --debug \
148    --keyblock ${DEVKEYS}/recovery_kernel.keyblock \
149    --signprivate ${DEVKEYS}/recovery_kernel_data_key.vbprivk \
150    --version 1 \
151    --config ${TMP}.config.txt \
152    --bootloader ${TMP}.bootloader.bin \
153    --vmlinuz ${SCRIPTDIR}/data/vmlinuz-${arch}.bin \
154    --arch ${arch} \
155    --pad ${padding} \
156    --kloadaddr 0x11000 \
157    --vblockonly \
158    ${TMP}.blob2.${arch}.vb1
159
160  # compare this new vblock with the one from the full pack
161  dd bs=${padding} count=1 if=${TMP}.blob2.${arch} of=${TMP}.blob2.${arch}.vb0
162  cmp ${TMP}.blob2.${arch}.vb0 ${TMP}.blob2.${arch}.vb1
163
164  echo -n "5 " 1>&3
165
166  # now repack the old way, again emitting just the vblock
167  ${FUTILITY} vbutil_kernel \
168    --repack ${TMP}.blob3.${arch}.vb1 \
169    --vblockonly \
170    --oldblob ${TMP}.blob1.${arch} \
171    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
172    --keyblock ${DEVKEYS}/kernel.keyblock \
173    --version 2 \
174    --pad ${padding} \
175    --config ${TMP}.config2.txt \
176    --bootloader ${TMP}.bootloader2.bin
177
178  # compare the full repacked vblock with the new repacked vblock
179  dd bs=${padding} count=1 if=${TMP}.blob3.${arch} of=${TMP}.blob3.${arch}.vb0
180  cmp ${TMP}.blob3.${arch}.vb0 ${TMP}.blob3.${arch}.vb1
181
182  # extract just the kernel blob
183  dd bs=${padding} skip=1 if=${TMP}.blob3.${arch} of=${TMP}.blob3.${arch}.kb0
184  # and verify it using the new vblock (no way to do that with vbutil_kernel)
185  ${FUTILITY} verify --debug \
186    --pad ${padding} \
187    --publickey ${DEVKEYS}/kernel_subkey.vbpubk \
188    --fv ${TMP}.blob3.${arch}.kb0 \
189    ${TMP}.blob3.${arch}.vb1 > ${TMP}.verify3v
190
191  # repack the new way
192  ${FUTILITY} sign --debug \
193    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
194    --keyblock ${DEVKEYS}/kernel.keyblock \
195    --version 2 \
196    --config ${TMP}.config2.txt \
197    --bootloader ${TMP}.bootloader2.bin \
198    --pad ${padding} \
199    --vblockonly \
200    ${TMP}.blob2.${arch} \
201    ${TMP}.blob4.${arch}.vb1 \
202
203  # compare the full repacked vblock with the new repacked vblock
204  dd bs=${padding} count=1 if=${TMP}.blob4.${arch} of=${TMP}.blob4.${arch}.vb0
205  cmp ${TMP}.blob4.${arch}.vb0 ${TMP}.blob4.${arch}.vb1
206
207  # extract just the kernel blob
208  dd bs=${padding} skip=1 if=${TMP}.blob4.${arch} of=${TMP}.blob4.${arch}.kb0
209  # and verify it using the new vblock (no way to do that with vbutil_kernel)
210  ${FUTILITY} verify --debug \
211    --pad ${padding} \
212    --publickey ${DEVKEYS}/kernel_subkey.vbpubk \
213    --fv ${TMP}.blob4.${arch}.kb0 \
214    ${TMP}.blob4.${arch}.vb1 > ${TMP}.verify4v
215
216
217  echo -n "6 " 1>&3
218
219  # Now lets repack some kernel partitions, not just blobs.
220  cp ${TMP}.kern_partition ${TMP}.part1.${arch}
221  dd if=${TMP}.blob1.${arch} of=${TMP}.part1.${arch} conv=notrunc
222
223  # Make sure the partitions verify
224  ${FUTILITY} vbutil_kernel --verify ${TMP}.part1.${arch} \
225    --pad ${padding} \
226    --signpubkey ${DEVKEYS}/recovery_key.vbpubk > ${TMP}.verify6
227
228  # The partition should verify the same way as the blob
229  diff ${TMP}.verify1 ${TMP}.verify6
230
231  # repack it the old way
232  ${FUTILITY} vbutil_kernel --debug \
233    --repack ${TMP}.part6.${arch} \
234    --oldblob ${TMP}.part1.${arch} \
235    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
236    --keyblock ${DEVKEYS}/kernel.keyblock \
237    --version 2 \
238    --pad ${padding} \
239    --config ${TMP}.config2.txt \
240    --bootloader ${TMP}.bootloader2.bin
241
242  # verify the old way
243  ${FUTILITY} vbutil_kernel --verify ${TMP}.part6.${arch} \
244    --pad ${padding} \
245    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify6.old
246
247  # this "partition" should actually be the same as the old-way blob
248  cmp ${TMP}.blob3.${arch} ${TMP}.part6.${arch}
249
250  # repack it the new way, in-place
251  cp ${TMP}.part1.${arch} ${TMP}.part6.${arch}.new1
252  ${FUTILITY} sign --debug \
253    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
254    --keyblock ${DEVKEYS}/kernel.keyblock \
255    --version 2 \
256    --pad ${padding} \
257    --config ${TMP}.config2.txt \
258    --bootloader ${TMP}.bootloader2.bin \
259    ${TMP}.part6.${arch}.new1
260
261  ${FUTILITY} vbutil_kernel --verify ${TMP}.part6.${arch}.new1 \
262    --pad ${padding} \
263    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify6.new1
264
265  # The verification should be indentical
266  diff ${TMP}.verify6.old ${TMP}.verify6.new1
267  # But the content should only match up to the size of the kernel blob, since
268  # we're modifying an entire partition in-place.
269  blobsize=$(stat -c '%s' ${TMP}.part6.${arch})
270  cmp -n ${blobsize} ${TMP}.part6.${arch} ${TMP}.part6.${arch}.new1
271  # The rest of the partition should be unchanged.
272  cmp -i ${blobsize} ${TMP}.part1.${arch} ${TMP}.part6.${arch}.new1
273
274  # repack it the new way, from input to output
275  cp ${TMP}.part1.${arch} ${TMP}.part1.${arch}.in
276  ${FUTILITY} sign --debug \
277    --signprivate ${DEVKEYS}/kernel_data_key.vbprivk \
278    --keyblock ${DEVKEYS}/kernel.keyblock \
279    --version 2 \
280    --pad ${padding} \
281    --config ${TMP}.config2.txt \
282    --bootloader ${TMP}.bootloader2.bin \
283    ${TMP}.part1.${arch}.in \
284    ${TMP}.part6.${arch}.new2
285
286  ${FUTILITY} vbutil_kernel --verify ${TMP}.part6.${arch}.new2 \
287    --pad ${padding} \
288    --signpubkey ${DEVKEYS}/kernel_subkey.vbpubk > ${TMP}.verify6.new2
289
290  # The input file should not have changed (just being sure).
291  cmp ${TMP}.part1.${arch} ${TMP}.part1.${arch}.in
292  # The verification should be indentical
293  diff ${TMP}.verify6.old ${TMP}.verify6.new2
294  # And creating a new output file should only emit a blob's worth
295  cmp ${TMP}.part6.${arch} ${TMP}.part6.${arch}.new2
296
297  # Note: We specifically do not test repacking with a different --kloadaddr,
298  # because the old way has a bug and does not update params->cmd_line_ptr to
299  # point at the new on-disk location. Apparently (and not surprisingly), no
300  # one has ever done that.
301}
302
303try_arch amd64
304try_arch arm
305
306# cleanup
307rm -rf ${TMP}*
308exit 0
309