test/py: secure: Add secure tests for Zynq & ZynqMP
[pandora-u-boot.git] / test / py / tests / test_zynq_secure.py
1 # SPDX-License-Identifier: GPL-2.0
2 # (C) Copyright 2023, Advanced Micro Devices, Inc.
3
4 import pytest
5 import re
6 import u_boot_utils
7 import test_net
8
9 """
10 This test verifies different type of secure boot images to authentication and
11 decryption using AES and RSA features for AMD's Zynq SoC.
12
13 Note: This test relies on boardenv_* containing configuration values to define
14 the network available and files to be used for testing. Without this, this test
15 will be automatically skipped. It also relies on dhcp or setup_static net test
16 to support tftp to load files from a TFTP server.
17
18 For example:
19
20 # Details regarding the files that may be read from a TFTP server and addresses
21 # and size for aes and rsa cases respectively. This variable may be omitted or
22 # set to None if zynqmp secure testing is not possible or desired.
23 env__zynq_aes_readable_file = {
24     'fn': 'zynq_aes_image.bin',
25     'fnbit': 'zynq_aes_bit.bin',
26     'fnpbit': 'zynq_aes_par_bit.bin',
27     'srcaddr': 0x1000000,
28     'dstaddr': 0x2000000,
29     'dstlen': 0x1000000,
30 }
31
32 env__zynq_rsa_readable_file = {
33     'fn': 'zynq_rsa_image.bin',
34     'fninvalid': 'zynq_rsa_image_invalid.bin',
35     'srcaddr': 0x1000000,
36 }
37 """
38
39 def zynq_secure_pre_commands(u_boot_console):
40     output = u_boot_console.run_command('print modeboot')
41     if not 'modeboot=' in output:
42         pytest.skip('bootmode cannnot be determined')
43     m = re.search('modeboot=(.+?)boot', output)
44     if not m:
45         pytest.skip('bootmode cannnot be determined')
46     bootmode = m.group(1)
47     if bootmode == 'jtag':
48         pytest.skip('skipping due to jtag bootmode')
49
50 @pytest.mark.buildconfigspec('cmd_zynq_aes')
51 def test_zynq_aes_image(u_boot_console):
52     f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
53     if not f:
54         pytest.skip('No TFTP readable file for zynq secure aes case to read')
55
56     dstaddr = f.get('dstaddr', None)
57     if not dstaddr:
58         pytest.skip('No dstaddr specified in env file to read')
59
60     dstsize = f.get('dstlen', None)
61     if not dstsize:
62         pytest.skip('No dstlen specified in env file to read')
63
64     zynq_secure_pre_commands(u_boot_console)
65     test_net.test_net_dhcp(u_boot_console)
66     if not test_net.net_set_up:
67         test_net.test_net_setup_static(u_boot_console)
68
69     srcaddr = f.get('srcaddr', None)
70     if not srcaddr:
71         addr = u_boot_utils.find_ram_base(u_boot_console)
72
73     expected_tftp = 'Bytes transferred = '
74     fn = f['fn']
75     output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
76     assert expected_tftp in output
77
78     expected_op = 'zynq aes [operation type] <srcaddr>'
79     output = u_boot_console.run_command(
80         'zynq aes %x $filesize %x %x' % (srcaddr, dstaddr, dstsize)
81     )
82     assert expected_op not in output
83     output = u_boot_console.run_command('echo $?')
84     assert output.endswith('0')
85
86 @pytest.mark.buildconfigspec('cmd_zynq_aes')
87 def test_zynq_aes_bitstream(u_boot_console):
88     f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
89     if not f:
90         pytest.skip('No TFTP readable file for zynq secure aes case to read')
91
92     zynq_secure_pre_commands(u_boot_console)
93     test_net.test_net_dhcp(u_boot_console)
94     if not test_net.net_set_up:
95         test_net.test_net_setup_static(u_boot_console)
96
97     srcaddr = f.get('srcaddr', None)
98     if not srcaddr:
99         addr = u_boot_utils.find_ram_base(u_boot_console)
100
101     expected_tftp = 'Bytes transferred = '
102     fn = f['fnbit']
103     output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
104     assert expected_tftp in output
105
106     expected_op = 'zynq aes [operation type] <srcaddr>'
107     output = u_boot_console.run_command(
108         'zynq aes load %x $filesize' % (srcaddr)
109     )
110     assert expected_op not in output
111     output = u_boot_console.run_command('echo $?')
112     assert output.endswith('0')
113
114 @pytest.mark.buildconfigspec('cmd_zynq_aes')
115 def test_zynq_aes_partial_bitstream(u_boot_console):
116     f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
117     if not f:
118         pytest.skip('No TFTP readable file for zynq secure aes case to read')
119
120     zynq_secure_pre_commands(u_boot_console)
121     test_net.test_net_dhcp(u_boot_console)
122     if not test_net.net_set_up:
123         test_net.test_net_setup_static(u_boot_console)
124
125     srcaddr = f.get('srcaddr', None)
126     if not srcaddr:
127         addr = u_boot_utils.find_ram_base(u_boot_console)
128
129     expected_tftp = 'Bytes transferred = '
130     fn = f['fnpbit']
131     output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
132     assert expected_tftp in output
133
134     expected_op = 'zynq aes [operation type] <srcaddr>'
135     output = u_boot_console.run_command('zynq aes loadp %x $filesize' % (srcaddr))
136     assert expected_op not in output
137     output = u_boot_console.run_command('echo $?')
138     assert output.endswith('0')
139
140 @pytest.mark.buildconfigspec('cmd_zynq_rsa')
141 def test_zynq_rsa_image(u_boot_console):
142     f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
143     if not f:
144         pytest.skip('No TFTP readable file for zynq secure rsa case to read')
145
146     zynq_secure_pre_commands(u_boot_console)
147     test_net.test_net_dhcp(u_boot_console)
148     if not test_net.net_set_up:
149         test_net.test_net_setup_static(u_boot_console)
150
151     srcaddr = f.get('srcaddr', None)
152     if not srcaddr:
153         addr = u_boot_utils.find_ram_base(u_boot_console)
154
155     expected_tftp = 'Bytes transferred = '
156     fn = f['fn']
157     output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
158     assert expected_tftp in output
159
160     expected_op = 'zynq rsa <baseaddr>'
161     output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
162     assert expected_op not in output
163     output = u_boot_console.run_command('echo $?')
164     assert output.endswith('0')
165
166 @pytest.mark.buildconfigspec('cmd_zynq_rsa')
167 def test_zynq_rsa_image_invalid(u_boot_console):
168     f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
169     if not f:
170         pytest.skip('No TFTP readable file for zynq secure rsa case to read')
171
172     zynq_secure_pre_commands(u_boot_console)
173     test_net.test_net_dhcp(u_boot_console)
174     if not test_net.net_set_up:
175         test_net.test_net_setup_static(u_boot_console)
176
177     srcaddr = f.get('srcaddr', None)
178     if not srcaddr:
179         addr = u_boot_utils.find_ram_base(u_boot_console)
180
181     expected_tftp = 'Bytes transferred = '
182     fninvalid = f['fninvalid']
183     output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fninvalid))
184     assert expected_tftp in output
185
186     expected_op = 'zynq rsa <baseaddr>'
187     output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
188     assert expected_op in output
189     output = u_boot_console.run_command('echo $?')
190     assert not output.endswith('0')