• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash -eux
2# Copyright 2014 The ChromiumOS Authors
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
12# Helper utility to modify binary blobs
13REPLACE="${BUILD_RUN}/tests/futility/binary_editor"
14
15# First, let's test the basic functionality
16
17# For simplicity, we'll use the same size for all properties.
18"${FUTILITY}" gbb -c 16,0x10,16,0x10 "${TMP}.blob"
19
20# Flags
21"${FUTILITY}" gbb -s --flags=0xdeadbeef "${TMP}.blob"
22"${FUTILITY}" gbb -g --flags "${TMP}.blob" | grep -i 0xdeadbeef
23
24# HWID length should include the terminating null - this is too long
25if "${FUTILITY}" gbb -s --hwid="0123456789ABCDEF" "${TMP}.blob"; then
26  false;
27fi
28# This works
29"${FUTILITY}" gbb -s --hwid="0123456789ABCDE" "${TMP}.blob"
30# Read it back?
31"${FUTILITY}" gbb -g "${TMP}.blob" | grep "0123456789ABCDE"
32
33# Same kind of tests for the other fields, but they need binary files.
34
35# too long
36dd if=/dev/urandom bs=17 count=1 of="${TMP}.data1.toolong"
37dd if=/dev/urandom bs=17 count=1 of="${TMP}.data2.toolong"
38if "${FUTILITY}" gbb -s --rootkey     "${TMP}.data1.toolong" "${TMP}.blob";
39  then false; fi
40if "${FUTILITY}" gbb -s --recoverykey "${TMP}.data2.toolong" "${TMP}.blob";
41  then false; fi
42
43# shorter than max should be okay, though
44dd if=/dev/urandom bs=10 count=1 of="${TMP}.data1.short"
45dd if=/dev/urandom bs=10 count=1 of="${TMP}.data2.short"
46"${FUTILITY}" gbb -s \
47  --rootkey     "${TMP}.data1.short" \
48  --recoverykey "${TMP}.data2.short" "${TMP}.blob"
49# read 'em back
50"${FUTILITY}" gbb -g \
51  --rootkey     "${TMP}.read1" \
52  --recoverykey "${TMP}.read2" "${TMP}.blob"
53# Verify (but remember, it's short)
54cmp -n 10 "${TMP}.data1.short" "${TMP}.read1"
55cmp -n 10 "${TMP}.data2.short" "${TMP}.read2"
56
57# Okay
58dd if=/dev/urandom bs=16 count=1 of="${TMP}.data1"
59dd if=/dev/urandom bs=16 count=1 of="${TMP}.data2"
60dd if=/dev/urandom bs=16 count=1 of="${TMP}.data3"
61"${FUTILITY}" gbb -s --rootkey     "${TMP}.data1" "${TMP}.blob"
62"${FUTILITY}" gbb -s --recoverykey "${TMP}.data2" "${TMP}.blob"
63
64# Read 'em back.
65"${FUTILITY}" gbb -g --rootkey     "${TMP}.read1" "${TMP}.blob"
66"${FUTILITY}" gbb -g --recoverykey "${TMP}.read2" "${TMP}.blob"
67# Verify
68cmp "${TMP}.data1" "${TMP}.read1"
69cmp "${TMP}.data2" "${TMP}.read2"
70
71# Basic get and set test using flashrom
72# The implementation requires an FMAP so use a full firmware image
73PEPPY_BIOS="${SCRIPT_DIR}/futility/data/bios_peppy_mp.bin"
74cp "${PEPPY_BIOS}" "${TMP}.full.blob"
75"${FUTILITY}" gbb -s --emulate="${TMP}.full.blob" --flags="0xdeadbeef"
76"${FUTILITY}" gbb -g --emulate="${TMP}.full.blob" --flags | grep -i "0xdeadbeef"
77
78# Okay, creating GBB blobs seems to work. Now let's make sure that corrupted
79# blobs are rejected.
80
81# Danger Will Robinson! We assume that ${TMP}.blob has this binary struct:
82#
83# Field                 Offset  Value
84#
85# signature:            0x0000  $GBB
86# major_version:        0x0004  0x0001
87# minor_version:        0x0006  0x0001
88# header_size:          0x0008  0x00000080
89# flags:                0x000c  0xdeadbeef
90# hwid_offset:          0x0010  0x00000080
91# hwid_size:            0x0014  0x00000010
92# rootkey_offset:       0x0018  0x00000090
93# rootkey_size:         0x001c  0x00000010
94# bmpfv_offset:         0x0020  0x000000a0
95# bmpfv_size:           0x0024  0x00000010
96# recovery_key_offset:  0x0028  0x000000b0
97# recovery_key_size:    0x002c  0x00000010
98# pad:                  0x0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
99#                       0x0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
100#                       0x0050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
101#                       0x0060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
102#                       0x0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
103# (HWID)                0x0080  30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 00
104# (rootkey)             0x0090  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
105# (bmpfv)               0x00a0  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
106# (recovery_key)        0x00b0  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
107#                       0x00c0  <EOF>
108#
109
110# bad major_version
111"${REPLACE}" 0x4 2 < "${TMP}.blob" > "${TMP}.blob.bad"
112if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
113
114# header size too large
115"${REPLACE}" 0x8 0x81 < "${TMP}.blob" > "${TMP}.blob.bad"
116if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
117
118# header size too small
119"${REPLACE}" 0x8 0x7f < "${TMP}.blob" > "${TMP}.blob.bad"
120if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
121
122# HWID not null-terminated is invalid
123"${REPLACE}" 0x8f 0x41 < "${TMP}.blob" > "${TMP}.blob.bad"
124if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
125
126# HWID of length zero is okay
127"${REPLACE}" 0x14 0x00 < "${TMP}.blob" > "${TMP}.blob.ok"
128"${FUTILITY}" gbb "${TMP}.blob.ok"
129# And HWID of length 1 consisting only of '\0' is okay, too.
130"${REPLACE}" 0x14 0x01 < "${TMP}.blob" | "${REPLACE}" 0x80 0x00 \
131  > "${TMP}.blob.ok"
132"${FUTILITY}" gbb "${TMP}.blob.ok"
133
134# zero-length HWID not null-terminated is invalid
135"${REPLACE}" 0x8f 0x41 < "${TMP}.blob" > "${TMP}.blob.bad"
136if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
137
138#  hwid_offset < GBB_HEADER_SIZE is invalid
139"${REPLACE}" 0x10 0x7f < "${TMP}.blob" > "${TMP}.blob.bad"
140if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
141"${REPLACE}" 0x10 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
142if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
143
144#  rootkey_offset < GBB_HEADER_SIZE is invalid
145"${REPLACE}" 0x18 0x7f < "${TMP}.blob" > "${TMP}.blob.bad"
146if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
147"${REPLACE}" 0x18 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
148if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
149
150#  recovery_key_offset < GBB_HEADER_SIZE is invalid
151"${REPLACE}" 0x28 0x7f < "${TMP}.blob" > "${TMP}.blob.bad"
152if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
153"${REPLACE}" 0x28 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
154if "${FUTILITY}" gbb "${TMP}.blob.bad"; then false; fi
155
156#  hwid: offset + size  == end of file is okay; beyond is invalid
157"${REPLACE}" 0x14 0x40 < "${TMP}.blob" > "${TMP}.blob.bad"
158"${FUTILITY}" gbb -g "${TMP}.blob.bad"
159"${REPLACE}" 0x14 0x41 < "${TMP}.blob" > "${TMP}.blob.bad"
160if "${FUTILITY}" gbb -g "${TMP}.blob.bad"; then false; fi
161
162#  rootkey: offset + size  == end of file is okay; beyond is invalid
163"${REPLACE}" 0x1c 0x30 < "${TMP}.blob" > "${TMP}.blob.bad"
164"${FUTILITY}" gbb -g "${TMP}.blob.bad"
165"${REPLACE}" 0x1c 0x31 < "${TMP}.blob" > "${TMP}.blob.bad"
166if "${FUTILITY}" gbb -g "${TMP}.blob.bad"; then false; fi
167
168#  recovery_key: offset + size  == end of file is okay; beyond is invalid
169"${REPLACE}" 0x2c 0x10 < "${TMP}.blob" > "${TMP}.blob.bad"
170"${FUTILITY}" gbb -g "${TMP}.blob.bad"
171"${REPLACE}" 0x2c 0x11 < "${TMP}.blob" > "${TMP}.blob.bad"
172if "${FUTILITY}" gbb -g "${TMP}.blob.bad"; then false; fi
173
174# hwid_size == 0 doesn't complain, but can't be set
175"${REPLACE}" 0x14 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
176"${FUTILITY}" gbb -g "${TMP}.blob.bad"
177if "${FUTILITY}" gbb -s --hwid="A" "${TMP}.blob.bad"; then false; fi
178
179# rootkey_size == 0 gives warning, gets nothing, can't be set
180"${REPLACE}" 0x1c 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
181"${FUTILITY}" gbb -g --rootkey     "${TMP}.read1" "${TMP}.blob.bad"
182if "${FUTILITY}" gbb -s --rootkey  "${TMP}.data1" "${TMP}.blob.bad";
183  then false; fi
184
185# recovery_key_size == 0 gives warning, gets nothing, can't be set
186"${REPLACE}" 0x2c 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
187"${FUTILITY}" gbb -g --recoverykey "${TMP}.read2" "${TMP}.blob.bad"
188if "${FUTILITY}" gbb -s --recoverykey "${TMP}.data2" "${TMP}.blob.bad";
189  then false; fi
190
191
192# GBB v1.2 adds a sha256 digest field in what was previously padding:
193#
194# hwid_digest:          0x0030  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
195#                       0x0040  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
196# pad:                  0x0050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
197#                       0x0060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
198#                       0x0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
199# (HWID)                0x0080  30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 00
200
201# See that the digest is updated properly.
202hwid="123456789ABCDEF"
203"${FUTILITY}" gbb -s --hwid="${hwid}" "${TMP}.blob"
204expect=$(echo -n "$hwid" | sha256sum | cut -d ' ' -f 1)
205[ "$(echo -n "${expect}" | wc -c)" == "64" ]
206"${FUTILITY}" gbb -g --digest "${TMP}.blob" | grep "${expect}"
207
208# Garble the digest, see that it's noticed.
209# (assuming these zeros aren't present)
210"${REPLACE}" 0x33 0x00 0x00 0x00 0x00 0x00 < "${TMP}.blob" > "${TMP}.blob.bad"
211"${FUTILITY}" gbb -g --digest "${TMP}.blob.bad" | grep '0000000000'
212"${FUTILITY}" gbb -g --digest "${TMP}.blob.bad" | grep 'invalid'
213
214# Garble the HWID. The digest is unchanged, but now invalid.
215"${REPLACE}" 0x84 0x70 0x71 0x72 < "${TMP}.blob" > "${TMP}.blob.bad"
216"${FUTILITY}" gbb -g --digest "${TMP}.blob.bad" | grep 'invalid'
217
218# cleanup
219rm -f "${TMP}"*
220exit 0
221