Skip to content

Commit 757b79e

Browse files
committed
imgtool: Add tests for dumpinfo command
Signed-off-by: Rustam Ismayilov <[email protected]> Change-Id: I380e2839ae14ceca706e5b03f5ecf2d4ed53af5c
1 parent 18ef1d4 commit 757b79e

File tree

1 file changed

+328
-0
lines changed

1 file changed

+328
-0
lines changed

scripts/tests/test_dumpinfo.py

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
# Copyright 2024 Arm Limited
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from pathlib import Path
18+
from tempfile import mktemp
19+
20+
import pytest
21+
from click.testing import CliRunner
22+
23+
from imgtool.main import imgtool
24+
from tests.constants import tmp_name, KEY_TYPES, signed_images_dir
25+
26+
DUMPINFO_SUCCESS_LITERAL = "dumpinfo has run successfully"
27+
28+
DUMPINFO_TRAILER = """
29+
swap status: (len: unknown)
30+
enc. keys: Image not encrypted
31+
swap size: unknown
32+
swap_info: INVALID (0xff)
33+
copy_done: INVALID (0xff)
34+
image_ok: SET (0x1)
35+
boot magic: """
36+
37+
DUMPINFO_ENCRYPTED_TRAILER = """
38+
swap status: (len: unknown)
39+
enc. keys: (len: 0x20, if BOOT_SWAP_SAVE_ENCTLV is unset)
40+
swap size: unknown
41+
swap_info: INVALID (0xff)
42+
copy_done: INVALID (0xff)
43+
image_ok: INVALID (0xff)
44+
boot magic: """
45+
46+
47+
class TestDumpInfo:
48+
image = None
49+
image_signed = None
50+
runner = CliRunner()
51+
dumpfile = mktemp("dump.dat")
52+
53+
@pytest.fixture(scope="session")
54+
def tmp_path_persistent(self, tmp_path_factory):
55+
return tmp_path_factory.mktemp("keys")
56+
57+
@pytest.fixture(autouse=True)
58+
def setup(self, tmp_path_persistent, key_type="rsa-2048"):
59+
"""Generate keys and images for testing"""
60+
61+
self.key = tmp_name(tmp_path_persistent, key_type, ".key")
62+
self.runner.invoke(
63+
imgtool, ["keygen", "--key", str(self.key), "--type", key_type]
64+
)
65+
66+
self.image = "./images/zero.bin"
67+
self.image_signed = tmp_name(tmp_path_persistent, "image", ".signed")
68+
69+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
70+
def test_dumpinfo(self, tmp_path_persistent, key_type):
71+
self.image_signed = signed_images_dir + "/basic/" + key_type + ".bin"
72+
73+
result = self.runner.invoke(
74+
imgtool, ["dumpinfo", str(self.image_signed)]
75+
)
76+
assert result.exit_code == 0
77+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
78+
79+
result = self.runner.invoke(
80+
imgtool, ["dumpinfo", "invalid"]
81+
)
82+
assert result.exit_code != 0
83+
assert "Error: Image file not found" in result.stdout
84+
85+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
86+
def test_dumpinfo_silent(self, tmp_path_persistent, key_type):
87+
self.image_signed = signed_images_dir + "/basic/" + key_type + ".bin"
88+
89+
result = self.runner.invoke(
90+
imgtool, ["dumpinfo", str(self.image_signed), "-s"]
91+
)
92+
assert result.exit_code == 0
93+
assert result.stdout == ""
94+
95+
result = self.runner.invoke(
96+
imgtool, ["dumpinfo", "invalid", "-s"]
97+
)
98+
assert result.exit_code != 0
99+
assert "Error: Image file not found" in result.stdout
100+
101+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
102+
def test_dumpinfo_tlv(self, tmp_path_persistent, key_type):
103+
self.image_signed = signed_images_dir + "/customTLV/" + key_type + ".bin"
104+
105+
result = self.runner.invoke(
106+
imgtool, ["dumpinfo", str(self.image_signed)]
107+
)
108+
assert result.exit_code == 0
109+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
110+
assert "type: UNKNOWN (0xa0)" in result.stdout
111+
112+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
113+
def test_dumpinfo_tlv_outfile(self, tmp_path_persistent, key_type):
114+
self.image_signed = signed_images_dir + "/customTLV/" + key_type + ".bin"
115+
116+
result = self.runner.invoke(
117+
imgtool, ["dumpinfo", "-o", self.dumpfile, str(self.image_signed)]
118+
)
119+
assert result.exit_code == 0
120+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
121+
assert Path(self.dumpfile).exists()
122+
123+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
124+
@pytest.mark.parametrize("align", ('1', '2', '4', '8', '16', '32',))
125+
def test_dumpinfo_align_pad(self, tmp_path_persistent, key_type, align):
126+
result = self.runner.invoke(
127+
imgtool,
128+
[
129+
"sign",
130+
"--key",
131+
self.key,
132+
"--align",
133+
align,
134+
"--version",
135+
"1.0.0",
136+
"--header-size",
137+
"0x400",
138+
"--slot-size",
139+
"0x10000",
140+
"--pad-header",
141+
"--pad",
142+
"--confirm",
143+
str(self.image),
144+
str(self.image_signed),
145+
],
146+
)
147+
assert result.exit_code == 0
148+
149+
result = self.runner.invoke(
150+
imgtool, ["dumpinfo", str(self.image_signed)]
151+
)
152+
assert result.exit_code == 0
153+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
154+
assert DUMPINFO_TRAILER in result.stdout
155+
156+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
157+
@pytest.mark.parametrize("align", ('1', '2', '4', '8', '16', '32',))
158+
def test_dumpinfo_align_pad_outfile(self, tmp_path_persistent, key_type, align):
159+
result = self.runner.invoke(
160+
imgtool,
161+
[
162+
"sign",
163+
"--key",
164+
self.key,
165+
"--align",
166+
align,
167+
"--version",
168+
"1.0.0",
169+
"--header-size",
170+
"0x400",
171+
"--slot-size",
172+
"0x10000",
173+
"--pad-header",
174+
"--pad",
175+
"--confirm",
176+
str(self.image),
177+
str(self.image_signed),
178+
],
179+
)
180+
assert result.exit_code == 0
181+
182+
result = self.runner.invoke(
183+
imgtool, ["dumpinfo", "-o", self.dumpfile, str(self.image_signed)]
184+
)
185+
assert result.exit_code == 0
186+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
187+
assert DUMPINFO_TRAILER in result.stdout
188+
assert Path(self.dumpfile).exists()
189+
190+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
191+
@pytest.mark.parametrize("align", ('1', '2', '4', '8', '16', '32',))
192+
def test_dumpinfo_max_align_pad(self, tmp_path_persistent, key_type, align):
193+
result = self.runner.invoke(
194+
imgtool,
195+
[
196+
"sign",
197+
"--key",
198+
self.key,
199+
"--align",
200+
align,
201+
"--version",
202+
"1.0.0",
203+
"--header-size",
204+
"0x400",
205+
"--slot-size",
206+
"0x10000",
207+
"--pad-header",
208+
"--pad",
209+
"--confirm",
210+
"--max-align",
211+
"32",
212+
str(self.image),
213+
str(self.image_signed),
214+
],
215+
)
216+
assert result.exit_code == 0
217+
218+
result = self.runner.invoke(
219+
imgtool, ["dumpinfo", str(self.image_signed)]
220+
)
221+
assert result.exit_code == 0
222+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
223+
assert DUMPINFO_TRAILER in result.stdout
224+
225+
@pytest.mark.parametrize("key_type", KEY_TYPES[:-1])
226+
def test_dumpinfo_encrypted_clear(self, tmp_path_persistent, key_type):
227+
encoding = "pem"
228+
enckey = "./keys/" + key_type + ".key"
229+
pub_key = tmp_name(tmp_path_persistent, key_type, ".pub." + encoding)
230+
self.image_signed = signed_images_dir + "/encryptedClear/" + key_type + ".enc"
231+
232+
self.runner.invoke(
233+
imgtool,
234+
[
235+
"getpub",
236+
"--key",
237+
str(enckey),
238+
"--output",
239+
str(pub_key),
240+
"--encoding",
241+
encoding,
242+
],
243+
)
244+
245+
result = self.runner.invoke(
246+
imgtool, ["dumpinfo", str(self.image_signed)]
247+
)
248+
assert result.exit_code == 0
249+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
250+
251+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
252+
def test_dumpinfo_encrypted_padded_outfile(self, tmp_path_persistent, key_type):
253+
self.image_signed = signed_images_dir + "/pad_sig_enc_16.bin"
254+
result = self.runner.invoke(
255+
imgtool, ["dumpinfo", "-o", self.dumpfile, self.image_signed]
256+
)
257+
assert result.exit_code == 0
258+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
259+
assert DUMPINFO_ENCRYPTED_TRAILER in result.stdout
260+
assert Path(self.dumpfile).exists()
261+
262+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
263+
def test_dumpinfo_encrypted_padded_invalid(self, tmp_path_persistent, key_type):
264+
self.image_signed = signed_images_dir + "/pad_2.3K_sig_enc_16_inv.bin"
265+
result = self.runner.invoke(
266+
imgtool, ["dumpinfo", self.image_signed]
267+
)
268+
assert result.exit_code == 0
269+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
270+
assert "Warning: the trailer magic value is invalid!" in result.stdout
271+
272+
@pytest.mark.parametrize("key_type", ("rsa-2048",))
273+
def test_dumpinfo_padded_multiflag(self, tmp_path_persistent, key_type):
274+
encoding = "pem"
275+
enckey = tmp_name(tmp_path_persistent, key_type, ".key")
276+
pub_key = tmp_name(tmp_path_persistent, key_type, ".pub." + encoding)
277+
278+
self.runner.invoke(
279+
imgtool, ["keygen", "--key", str(enckey), "--type", key_type]
280+
)
281+
282+
self.runner.invoke(
283+
imgtool,
284+
[
285+
"getpub",
286+
"--key",
287+
str(enckey),
288+
"--output",
289+
str(pub_key),
290+
"--encoding",
291+
encoding,
292+
],
293+
)
294+
295+
result = self.runner.invoke(
296+
imgtool,
297+
[
298+
"sign",
299+
"--key",
300+
self.key,
301+
"--encrypt",
302+
pub_key,
303+
"--align",
304+
"16",
305+
"--version",
306+
"1.0.0",
307+
"--header-size",
308+
"0x400",
309+
"--slot-size",
310+
"0x2300",
311+
"--pad-header",
312+
"--pad",
313+
"--rom-fixed",
314+
"32",
315+
str(self.image),
316+
str(self.image_signed),
317+
],
318+
)
319+
assert result.exit_code == 0
320+
321+
result = self.runner.invoke(
322+
imgtool, ["dumpinfo", str(self.image_signed)]
323+
)
324+
assert result.exit_code == 0
325+
assert "ENCRYPTED_AES128" in result.stdout
326+
assert "ROM_FIXED" in result.stdout
327+
assert DUMPINFO_SUCCESS_LITERAL in result.stdout
328+
assert DUMPINFO_ENCRYPTED_TRAILER in result.stdout

0 commit comments

Comments
 (0)