Skip to content

Commit 50a4d4b

Browse files
committed
Add Marvell/Synaptics Berlin family bootable images
These chips are not used widely these days, but they powered all early-generation Chromecast and Google Home devices as well as the Steam Link streaming box and perhaps others.
1 parent e6a75bb commit 50a4d4b

File tree

2 files changed

+301
-0
lines changed

2 files changed

+301
-0
lines changed

firmware/marvell_berlin_image.ksy

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
meta:
2+
id: marvell_berlin_image
3+
title: Marvell/Synaptics BG2/BG2CD secure boot image
4+
license: CC0-1.0
5+
endian: le
6+
7+
doc: |
8+
This format describes the bootable image header, which supports both signing
9+
and encryption, used by older versions of Marvell (now Synaptics)'s Berlin
10+
multimedia SoCs. The Chromecast 1 and Steam Link use these chips.
11+
12+
Field names were taken from the DWARF debugging metadata in the
13+
berlin_tools/enc_tool_z2a0 binary from the Chromecast 1 bootloader source code
14+
release (linked below).
15+
16+
doc-ref: https://drive.google.com/file/d/0B3j4zj2IQp7MeFZFTk5uVzFjbHM/view?usp=drive_link
17+
18+
seq:
19+
- id: parent_key_id
20+
type: u4
21+
doc: 0 for unencrypted images
22+
- id: reserved0
23+
type: u4
24+
- id: key_data
25+
size: 0x38
26+
doc: |
27+
AES encryption key, wrapped into a 24-byte blob using a custom algorithm
28+
that involves 6 rounds of ECB encryption and some word-swapping and XOR
29+
that I can't be bothered to figure out; see keyWrap() in enc_tool_z2a0
30+
- id: signing_key_id
31+
type: u4
32+
- id: sign_type
33+
type: u1
34+
- id: sign_len
35+
type: u1
36+
- id: reserved1
37+
type: u2
38+
- id: hash_val
39+
size: 24
40+
doc: SHA-1 hash (why 4 extra bytes?) of all data bytes, not signed directly
41+
- id: bind_info
42+
size: 16
43+
- id: reserved2
44+
size: 12
45+
- id: image_size
46+
type: u4
47+
- id: signature
48+
size: sign_len
49+
- id: data
50+
size: image_size - sign_len

firmware/marvell_berlin_image2.ksy

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
meta:
2+
id: marvell_berlin_image2
3+
title: Marvell/Synaptics BG2CDP/BG3/BG4CDP secure boot image
4+
license: CC0-1.0
5+
endian: le
6+
7+
doc: |
8+
This format describes both the bootable image header, which supports both
9+
signing and encryption, and the keystore block, which chains additional keys
10+
to the root of trust and is often prepended to bootable images, used by newer
11+
versions of Marvell (now Synaptics)'s Berlin multimedia SoCs. The Chromecast
12+
2, Chromecast Audio, Chromecast 3, and Chromecast Ultra use these chips.
13+
14+
Field names for v1 structures were taken from the DWARF debugging metadata in
15+
the berlin_tools/sign_image binary from the BG2CDP Chromecast bootloader
16+
source code release (linked below). Field names for v4 structures were
17+
similarly taken from berlin_tools/sign_image_v4 in the BG4CDP bootloader.
18+
19+
doc-ref: https://drive.google.com/file/d/1KblViXoRkhFfjfXV-DQEhY0GdODwHBVg/view?usp=drive_link
20+
21+
seq:
22+
- id: header_version
23+
type: u4
24+
- id: magic_number
25+
type: u2
26+
enum: image_type
27+
- id: image
28+
type:
29+
switch-on: magic_number
30+
cases:
31+
'image_type::code': image_code
32+
'image_type::rsa': image_ext_rsa_key_v1
33+
'image_type::rsa2k': image_ext_rsa_key_v4(2048)
34+
'image_type::rsa4k': image_ext_rsa_key_v4(4096)
35+
'image_type::rsa8k': image_ext_rsa_key_v4(8192)
36+
'image_type::cust_key': image_cust_key_v1
37+
38+
types:
39+
image_code:
40+
seq:
41+
- id: versioned_image
42+
type:
43+
switch-on: _parent.header_version
44+
cases:
45+
1: image_code_v1
46+
0x20000000: image_code_v4
47+
48+
image_code_v1:
49+
seq:
50+
- id: cust_key_type
51+
type: u1
52+
doc: 0 for unencrypted images
53+
- id: code_type
54+
type: u1
55+
enum: code_type
56+
- id: security_level
57+
type: u1
58+
- id: reserved0
59+
type: u1
60+
- id: user_data
61+
type: u2
62+
- id: wrapped_user_key
63+
size: 16
64+
- id: constraints
65+
type: constraints
66+
- id: reserved2
67+
type: u2
68+
- id: image_size
69+
type: u4
70+
- id: image_hash
71+
size: 32
72+
doc: SHA-256 hash of all data bytes, not signed directly
73+
- id: signature
74+
size: 256
75+
doc: Signature of all prior bytes in header
76+
- id: data
77+
size: image_size
78+
79+
image_code_v4:
80+
seq:
81+
- id: cust_key_type
82+
type: u1
83+
doc: 0x00 for signing only
84+
- id: code_type
85+
type: u1
86+
enum: code_type
87+
- id: security_level
88+
type: u1
89+
- id: ext_rsa_type
90+
type: u1
91+
- id: user_data
92+
type: u2
93+
- id: wrapped_user_key
94+
size: 16
95+
- id: constraints
96+
type: constraints
97+
- id: header_hash_size
98+
type: u1
99+
- id: padding0
100+
size: 1
101+
- id: image_hash_size
102+
type: u2
103+
doc: 0x20 for SHA-256, 0x40 for SHA-512
104+
- id: padding1
105+
size: 2
106+
- id: image_size
107+
type: u4
108+
- id: image_hash
109+
size: 64
110+
type: padded_data(image_hash_size)
111+
doc: Hash of all data bytes, not signed directly
112+
- id: signature
113+
size: 1024
114+
doc: Signature of all prior bytes in header
115+
- id: data
116+
size: image_size
117+
118+
image_ext_rsa_key_v1:
119+
seq:
120+
- id: cust_key_type
121+
type: u1
122+
- id: reserved0
123+
type: u1
124+
- id: signing_rights
125+
type: u2
126+
- id: root_rsa_key
127+
type: u1
128+
- id: pub_exponent
129+
type: u1
130+
- id: constraints
131+
type: constraints
132+
- id: reserved1
133+
type: u2
134+
- id: rsa_modulus
135+
size: 256
136+
- id: root_key_modulus
137+
size: 256
138+
- id: signature
139+
size: 256
140+
doc: Signature of all prior bytes in header
141+
142+
instances:
143+
next:
144+
pos: 0x400
145+
size-eos: true
146+
type: marvell_berlin_image2
147+
148+
image_ext_rsa_key_v4:
149+
params:
150+
- id: key_size
151+
type: u4
152+
153+
seq:
154+
- id: cust_key_type
155+
type: u1
156+
- id: rsa_size
157+
type: u1
158+
- id: signing_rights
159+
type: u2
160+
- id: root_rsa_key
161+
type: u1
162+
- id: pub_exponent
163+
type: u1
164+
- id: constraints
165+
type: constraints
166+
- id: hash_size
167+
type: u2
168+
- id: rsa_modulus
169+
size: 1024
170+
type: padded_data(key_size / 8)
171+
# Montgomery parameters
172+
- id: rr
173+
size: 1024
174+
type: padded_data(key_size / 8)
175+
- id: n0_inv
176+
type: u4
177+
- id: reserved
178+
size: 12
179+
- id: signature
180+
size: 1024
181+
doc: Signature of all prior bytes in header
182+
183+
instances:
184+
next:
185+
pos: 0x1000
186+
size-eos: true
187+
type: marvell_berlin_image2
188+
189+
# v4 signing still uses v1 of this struct
190+
image_cust_key_v1:
191+
seq:
192+
- id: type
193+
type: u1
194+
- id: primary_aes_key_id
195+
type: u1
196+
- id: root_key_index
197+
type: u1
198+
- id: root_key_param
199+
type: u1
200+
- id: reserved0
201+
type: u2
202+
- id: wrapped_cust_key
203+
size: 16
204+
- id: signature
205+
size: 16
206+
207+
instances:
208+
next:
209+
pos: 0x400
210+
size-eos: true
211+
type: marvell_berlin_image2
212+
213+
constraints:
214+
seq:
215+
- id: market_id
216+
type: u4
217+
- id: market_id_mask
218+
type: u4
219+
- id: version
220+
type: u1
221+
- id: version_mask
222+
type: u1
223+
224+
padded_data:
225+
params:
226+
- id: size
227+
type: u4
228+
229+
seq:
230+
- id: data
231+
size: size
232+
233+
enums:
234+
image_type:
235+
0xc0de: code
236+
0xa2e1: rsa # v1
237+
0x8f02: rsa2k # v4
238+
0x2f04: rsa4k # v4
239+
0xed08: rsa8k # v4
240+
0xc237: cust_key
241+
242+
code_type:
243+
# From dump() in sign_image_v4
244+
0: level_1_boot
245+
1: level_2_boot
246+
2: marvell_av_firmware
247+
3: trustzone
248+
4: kernel
249+
5: oem_firmware
250+
6: arm_applications
251+
15: data

0 commit comments

Comments
 (0)