1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*******************************************************************************
* Test the FWU SMC interface in Trusted Firmware-A, which is implemented in
* BL1.
******************************************************************************/
#include <bl1.h>
#include <debug.h>
#include <drivers/io/io_fip.h>
#include <errno.h>
#include <platform_def.h>
#include <smccc.h>
#include <status.h>
#include <tftf.h>
#include <tftf_lib.h>
typedef struct {
/* Description to print before sending the SMC */
const char *description;
/* The arguments to pass to the SMC */
const smc_args args;
/* The expected SMC return value */
u_register_t expect;
} ns_bl1u_test_t;
/*
* The tests consist in sending a succession of SMCs to trigger FWU operations
* in BL1. The order of the SMCs is important because they internally change the
* FWU state machine in Trusted Firmware-A.
*/
static const ns_bl1u_test_t tests[] = {
/* Basic FWU SMC handler test cases. */
{
.description = "BL1_SMC_CALL_COUNT",
.args = { BL1_SMC_CALL_COUNT, 0, 0, 0, 0 },
.expect = BL1_NUM_SMC_CALLS,
},
{
.description = "BL1_SMC_VERSION",
.args = { BL1_SMC_VERSION, 0, 0, 0, 0 },
.expect = BL1_VERSION,
},
{
.description = "Invalid SMC",
.args = { 0xdeadbeef, 0, 0, 0, 0 },
.expect = SMC_UNKNOWN,
},
/* FWU_SMC_IMAGE_COPY test cases. */
{
.description = "IMAGE_COPY with invalid image_id",
.args = { FWU_SMC_IMAGE_COPY, 0xdeadbeef, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with non-secure image_id",
.args = { FWU_SMC_IMAGE_COPY, NS_BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with valid args",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_COPY to copy an image_id again",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with source address not mapped",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with source size not mapped",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0xdeadbeef, 0xdeadbeef },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with image size more than secure mem",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40000, 0x40000 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with image size 0",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0, 0 },
.expect = -ENOMEM,
},
/*
* At this point, the FWU Certificate Image has been copied by a
* previous test. Try to load the BL2U image over it at the same
* address.
*/
{
.description = "IMAGE_COPY with an image that overlaps a different one",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x40 },
.expect = -EPERM,
},
/*
* The authentication of the FWU certificate will fail, which will set
* the state of this image to "RESET" for the following tests.
*/
{
.description = "IMAGE_AUTH with an invalid image",
.args = { FWU_SMC_IMAGE_AUTH, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = -EAUTH,
},
{
.description = "IMAGE_COPY with 1st block size in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH while copying the image",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with last block with invalid source in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, 0, 0x21, 0x40 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with last block size > total size in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x21, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH to RESET the image state",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0 },
.expect = -EAUTH,
},
{
.description = "IMAGE_COPY with block size > total size",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x21, 0x20 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_RESET to RESET the image state",
.args = { FWU_SMC_IMAGE_RESET, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = STATUS_SUCCESS,
},
/* FWU_SMC_IMAGE_AUTH test cases. */
{
.description = "IMAGE_AUTH with invalid image_id",
.args = { FWU_SMC_IMAGE_AUTH, 0, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_AUTH with secure image not copied",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_AUTH with source address not mapped",
.args = { FWU_SMC_IMAGE_AUTH, NS_BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_AUTH with source size not mapped",
.args = { FWU_SMC_IMAGE_AUTH, NS_BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0xdeadbeef, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY to copy after auth failure",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH with valid args for copied image",
.args = { FWU_SMC_IMAGE_AUTH, FWU_CERT_ID, 0, 0, 0 },
.expect = -EAUTH,
},
/* FWU_SMC_IMAGE_EXECUTE test cases. */
{
.description = "IMAGE_EXECUTE with invalid image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, 0, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_EXECUTE with non-executable image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, FWU_CERT_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_EXECUTE with un-authenticated image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
/* FWU_SMC_IMAGE_RESUME test case. */
{
.description = "IMAGE_RESUME with invalid args",
.args = { FWU_SMC_IMAGE_RESUME, 0, 0, 0, 0 },
.expect = -EPERM,
},
};
void ns_bl1u_fwu_test_main(void)
{
NOTICE("NS_BL1U: ***** Starting NS_BL1U FWU test *****\n");
for (int i = 0 ; i < ARRAY_SIZE(tests); ++i) {
u_register_t result;
INFO("NS_BL1U: %s\n", tests[i].description);
smc_ret_values smc_ret;
smc_ret = tftf_smc(&tests[i].args);
result = smc_ret.ret0;
if (result != tests[i].expect) {
ERROR("NS_BL1U: Unexpected SMC return value 0x%lX, "
"expected 0x%lX\n", result, tests[i].expect);
panic();
}
}
NOTICE("NS_BL1U: ***** All FWU test passed *****\n\n");
}
|