1 /* Copyright 2013 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for vboot_api_kernel, part 3 - software sync
6 */
7
8 #include "2common.h"
9 #include "2misc.h"
10 #include "2nvstorage.h"
11 #include "2secdata.h"
12 #include "2sysincludes.h"
13 #include "common/tests.h"
14 #include "host_common.h"
15 #include "vboot_struct.h"
16
17 /* Mock data */
18 static int ec_ro_updated;
19 static int ec_rw_updated;
20 static int ec_rw_protected;
21 static int ec_run_image; /* 0 = RO, 1 = RW */
22
23 static vb2_error_t in_rw_retval;
24 static int protect_retval;
25 static int jump_retval;
26 static int update_retval;
27 static int get_expected_retval;
28 static int shutdown_request_calls_left;
29 static vb2_error_t ec_vboot_done_retval;
30 static int ec_vboot_done_calls;
31
32 static int mock_display_available;
33 static int need_display_called;
34 static uint8_t mock_ec_ro_hash[32];
35 static uint8_t mock_ec_rw_hash[32];
36 static uint8_t hmir[32];
37 static int mock_ec_ro_hash_size;
38 static int mock_ec_rw_hash_size;
39 static uint8_t hexp[32];
40 static uint8_t update_hash;
41 static int hexp_size;
42 static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
43 __attribute__((aligned(VB2_WORKBUF_ALIGN)));
44 static struct vb2_context *ctx;
45 static struct vb2_shared_data *sd;
46 static struct vb2_gbb_header gbb;
47
48 /* Reset mock data (for use before each test) */
ResetMocks(void)49 static void ResetMocks(void)
50 {
51 TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
52 "vb2api_init passed");
53
54 ctx->flags = VB2_CONTEXT_EC_SYNC_SUPPORTED;
55 vb2_nv_init(ctx);
56
57 sd = vb2_get_sd(ctx);
58
59 memset(&gbb, 0, sizeof(gbb));
60
61 mock_display_available = 1;
62 need_display_called = 0;
63
64 ec_ro_updated = 0;
65 ec_rw_updated = 0;
66 ec_rw_protected = 0;
67 ec_run_image = 0;
68
69 in_rw_retval = VB2_SUCCESS;
70 protect_retval = VB2_SUCCESS;
71 update_retval = VB2_SUCCESS;
72 jump_retval = VB2_SUCCESS;
73 get_expected_retval = VB2_SUCCESS;
74 shutdown_request_calls_left = -1;
75 ec_vboot_done_retval = VB2_SUCCESS;
76 ec_vboot_done_calls = 0;
77
78 memset(mock_ec_ro_hash, 0, sizeof(mock_ec_ro_hash));
79 mock_ec_ro_hash[0] = 42;
80 mock_ec_ro_hash_size = sizeof(mock_ec_ro_hash);
81
82 memset(mock_ec_rw_hash, 0, sizeof(mock_ec_rw_hash));
83 mock_ec_rw_hash[0] = 42;
84 mock_ec_rw_hash_size = sizeof(mock_ec_rw_hash);
85
86 memset(hexp, 0, sizeof(hexp));
87 hexp[0] = 42;
88 hexp_size = sizeof(hexp);
89
90 update_hash = 42;
91
92 vb2api_secdata_kernel_create(ctx);
93 vb2_secdata_kernel_init(ctx);
94
95 memset(hmir, 0, sizeof(hmir));
96 hmir[0] = 42;
97 vb2_secdata_kernel_set_ec_hash(ctx, hmir);
98
99 /*
100 * This flag should not involve in the steps deciding whether EC is
101 * running RW. The only concern here is we need to clear this flag after
102 * attempting a jump to RW.
103 */
104 ctx->flags |= VB2_CONTEXT_EC_TRUSTED;
105 }
106
107 /* Mock functions */
vb2_get_gbb(struct vb2_context * c)108 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
109 {
110 return &gbb;
111 }
112
vb2api_need_reboot_for_display(struct vb2_context * c)113 int vb2api_need_reboot_for_display(struct vb2_context *c)
114 {
115 need_display_called = 1;
116 return !mock_display_available;
117 }
118
vb2ex_ec_running_rw(int * in_rw)119 vb2_error_t vb2ex_ec_running_rw(int *in_rw)
120 {
121 *in_rw = ec_run_image;
122 return in_rw_retval;
123 }
124
vb2ex_ec_protect(void)125 vb2_error_t vb2ex_ec_protect(void)
126 {
127 if (protect_retval)
128 return protect_retval;
129
130 ec_rw_protected = 1;
131
132 return VB2_SUCCESS;
133 }
134
vb2ex_ec_disable_jump(void)135 vb2_error_t vb2ex_ec_disable_jump(void)
136 {
137 return VB2_SUCCESS;
138 }
139
vb2ex_ec_jump_to_rw(void)140 vb2_error_t vb2ex_ec_jump_to_rw(void)
141 {
142 if (jump_retval == VB2_SUCCESS)
143 ec_run_image = 1;
144
145 return jump_retval;
146 }
147
vb2ex_ec_hash_image(enum vb2_firmware_selection select,const uint8_t ** hash,int * hash_size)148 vb2_error_t vb2ex_ec_hash_image(enum vb2_firmware_selection select,
149 const uint8_t **hash, int *hash_size)
150 {
151 *hash = select == VB_SELECT_FIRMWARE_READONLY ?
152 mock_ec_ro_hash : mock_ec_rw_hash;
153 *hash_size = select == VB_SELECT_FIRMWARE_READONLY ?
154 mock_ec_ro_hash_size : mock_ec_rw_hash_size;
155 return *hash_size ? VB2_SUCCESS : VB2_ERROR_MOCK;
156 }
157
vb2ex_ec_get_expected_image_hash(enum vb2_firmware_selection select,const uint8_t ** hash,int * hash_size)158 vb2_error_t vb2ex_ec_get_expected_image_hash(enum vb2_firmware_selection select,
159 const uint8_t **hash, int *hash_size)
160 {
161 *hash = hexp;
162 *hash_size = hexp_size;
163
164 return hexp_size ? VB2_SUCCESS : VB2_ERROR_MOCK;
165 }
166
vb2ex_ec_update_image(enum vb2_firmware_selection select)167 vb2_error_t vb2ex_ec_update_image(enum vb2_firmware_selection select)
168 {
169 if (update_retval)
170 return update_retval;
171
172 if (ctx->flags & VB2_CONTEXT_EC_SYNC_SLOW)
173 if (vb2api_need_reboot_for_display(ctx))
174 return VB2_REQUEST_REBOOT;
175
176 if (select == VB_SELECT_FIRMWARE_READONLY) {
177 ec_ro_updated = 1;
178 mock_ec_ro_hash[0] = update_hash;
179 } else {
180 ec_rw_updated = 1;
181 mock_ec_rw_hash[0] = update_hash;
182 }
183 return VB2_SUCCESS;
184 }
185
vb2ex_ec_vboot_done(struct vb2_context * c)186 vb2_error_t vb2ex_ec_vboot_done(struct vb2_context *c)
187 {
188 ec_vboot_done_calls++;
189 return ec_vboot_done_retval;
190 }
191
test_ssync(vb2_error_t retval,int recovery_reason,const char * desc)192 static void test_ssync(vb2_error_t retval, int recovery_reason,
193 const char *desc)
194 {
195 TEST_EQ(vb2api_ec_sync(ctx), retval, desc);
196 TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
197 recovery_reason, " recovery reason");
198 struct vb2_secdata_kernel_v1 *sec = (void *)ctx->secdata_kernel;
199 if (sec->struct_version >= VB2_SECDATA_KERNEL_VERSION_V10) {
200 const uint8_t *hash = vb2_secdata_kernel_get_ec_hash(ctx);
201 TEST_EQ(memcmp(hash, hexp, sizeof(hexp)), 0, "Hmir synced");
202 }
203 }
204
205 /* Tests */
206
VbSoftwareSyncTest(void)207 static void VbSoftwareSyncTest(void)
208 {
209 /* Check flag toggling */
210 ResetMocks();
211 test_ssync(VB2_SUCCESS, 0, "Normal (no) sync");
212 TEST_NEQ(sd->status & VB2_SD_STATUS_EC_SYNC_COMPLETE, 0,
213 " EC sync complete");
214 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
215 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
216 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
217 TEST_EQ(ec_run_image, 1, " ec run image");
218 TEST_EQ(ec_vboot_done_calls, 1, "ec_vboot_done calls");
219 /* Sync again to check ec_vboot_done */
220 test_ssync(VB2_SUCCESS, 0, "Normal sync");
221 TEST_EQ(ec_vboot_done_calls, 1, "ec_vboot_done calls");
222
223 ResetMocks();
224 sd->status |= VB2_SD_STATUS_EC_SYNC_COMPLETE;
225 test_ssync(VB2_SUCCESS, 0, "EC sync already complete");
226 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
227 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
228 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
229 TEST_EQ(ec_run_image, 0, " ec run image");
230 TEST_EQ(ec_vboot_done_calls, 0, "ec_vboot_done calls");
231
232 ResetMocks();
233 ctx->flags &= ~VB2_CONTEXT_EC_SYNC_SUPPORTED;
234 test_ssync(VB2_SUCCESS, 0, "EC sync not supported");
235 TEST_NEQ(sd->status & VB2_SD_STATUS_EC_SYNC_COMPLETE, 0,
236 " EC sync complete");
237 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
238 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
239 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
240 TEST_EQ(ec_run_image, 0, " ec run image");
241 TEST_EQ(ec_vboot_done_calls, 1, "ec_vboot_done calls");
242
243 ResetMocks();
244 gbb.flags |= VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC;
245 test_ssync(VB2_SUCCESS, 0, "EC sync disabled by GBB");
246 TEST_NEQ(sd->status & VB2_SD_STATUS_EC_SYNC_COMPLETE, 0,
247 " EC sync complete");
248 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
249 TEST_EQ(ec_rw_updated, 0, " ec rw updated");;
250 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
251 TEST_EQ(ec_run_image, 0, " ec run image");
252 TEST_EQ(ec_vboot_done_calls, 1, "ec_vboot_done calls");
253
254 /* AP-RO cases */
255 ResetMocks();
256 in_rw_retval = VB2_ERROR_MOCK;
257 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
258 VB2_RECOVERY_EC_UNKNOWN_IMAGE, "Unknown EC image");
259 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
260 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
261 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
262 TEST_EQ(ec_run_image, 0, " ec run image");
263
264 /* Calculate hashes */
265 ResetMocks();
266 mock_ec_rw_hash_size = 0;
267 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
268 VB2_RECOVERY_EC_HASH_FAILED, "Bad EC hash");
269 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
270 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
271 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
272 TEST_EQ(ec_run_image, 0, " ec run image");
273
274 ResetMocks();
275 mock_ec_rw_hash_size = 16;
276 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
277 VB2_RECOVERY_EC_HASH_SIZE, "Bad EC hash size");
278 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
279 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
280 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
281 TEST_EQ(ec_run_image, 0, " ec run image");
282
283 ResetMocks();
284 hexp_size = 0;
285 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
286 VB2_RECOVERY_EC_EXPECTED_HASH, "Bad precalculated hash");
287 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
288 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
289 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
290 TEST_EQ(ec_run_image, 0, " ec run image");
291
292 ResetMocks();
293 hexp_size = 16;
294 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
295 VB2_RECOVERY_EC_HASH_SIZE,
296 "Hash size mismatch");
297 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
298 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
299 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
300 TEST_EQ(ec_run_image, 0, " ec run image");
301
302 ResetMocks();
303 hexp_size = 4;
304 mock_ec_rw_hash_size = 4;
305 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO, VB2_RECOVERY_EC_HASH_SIZE,
306 "Custom hash size secdata_kernel v1");
307 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
308 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
309 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
310 TEST_EQ(ec_run_image, 0, " ec run image");
311
312 ResetMocks();
313 vb2api_secdata_kernel_create_v0(ctx);
314 vb2_secdata_kernel_init(ctx);
315 hexp_size = 4;
316 mock_ec_rw_hash_size = 4;
317 test_ssync(0, 0, "Custom hash size secdata_kernel v0");
318 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
319 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
320 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
321 TEST_EQ(ec_run_image, 1, " ec run image");
322
323 /* Updates required */
324 ResetMocks();
325 ec_run_image = 1;
326 mock_ec_rw_hash[0]++;
327 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
328 0, "Pending update needs reboot");
329 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
330 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
331 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
332 TEST_EQ(ec_run_image, 1, " ec run image");
333
334 /* Hexp != Hmir == Heff */
335 ResetMocks();
336 hmir[0] = 43;
337 vb2_secdata_kernel_set_ec_hash(ctx, hmir);
338 ec_run_image = 1;
339 mock_ec_rw_hash[0] = 43;
340 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
341 0, "Reboot after synching Hmir");
342 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
343 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
344 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
345 TEST_EQ(ec_run_image, 1, " ec run image");
346
347 /* Hexp != Hmir == Heff (display not available) */
348 ResetMocks();
349 hmir[0] = 43;
350 vb2_secdata_kernel_set_ec_hash(ctx, hmir);
351 ec_run_image = 1;
352 mock_ec_rw_hash[0] = 43;
353 mock_display_available = 0;
354 ctx->flags |= VB2_CONTEXT_EC_SYNC_SLOW;
355 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
356 0, "Reboot after synching Hmir (display not available)");
357 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
358 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
359 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
360 TEST_EQ(ec_run_image, 1, " ec run image");
361 TEST_TRUE(need_display_called, " need display");
362
363 /* Hexp == Hmir != Heff */
364 ResetMocks();
365 ec_run_image = 0;
366 ctx->flags |= VB2_CONTEXT_NO_BOOT;
367 mock_ec_rw_hash[0] = 43;
368 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
369 0, "Reboot after synching Heff");
370 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
371 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
372 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
373 TEST_EQ(ec_run_image, 0, " ec run image");
374
375 /* Hexp != Hmir != Heff */
376 ResetMocks();
377 hmir[0] = 44;
378 vb2_secdata_kernel_set_ec_hash(ctx, hmir);
379 ec_run_image = 0;
380 ctx->flags |= VB2_CONTEXT_NO_BOOT;
381 mock_ec_rw_hash[0] = 43;
382 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
383 0, "Reboot after synching Hmir and Heff");
384 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
385 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
386 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
387 TEST_EQ(ec_run_image, 0, " ec run image");
388
389 /* Hexp == Heff != Hmir */
390 ResetMocks();
391 hmir[0] = 44;
392 vb2_secdata_kernel_set_ec_hash(ctx, hmir);
393 ec_run_image = 0;
394 ctx->flags |= VB2_CONTEXT_NO_BOOT;
395 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
396 0, "Reboot after synching Hmir");
397 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
398 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
399 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
400 TEST_EQ(ec_run_image, 0, " ec run image");
401
402 ResetMocks();
403 mock_ec_rw_hash[0]++;
404 vb2_nv_set(ctx, VB2_NV_TRY_RO_SYNC, 1);
405 test_ssync(0, 0, "Update rw without reboot");
406 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
407 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
408 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
409 TEST_EQ(ec_run_image, 1, " ec run image");
410
411 ResetMocks();
412 mock_ec_rw_hash[0]++;
413 mock_ec_ro_hash[0]++;
414 vb2_nv_set(ctx, VB2_NV_TRY_RO_SYNC, 1);
415 test_ssync(0, 0, "Update rw and ro images without reboot");
416 TEST_EQ(ec_ro_updated, 1, " ec ro updated");
417 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
418 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
419 TEST_EQ(ec_run_image, 1, " ec run image");
420
421 ResetMocks();
422 vb2_nv_set(ctx, VB2_NV_TRY_RO_SYNC, 1);
423 mock_ec_ro_hash[0]++;
424 vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
425 test_ssync(0, 0, "rw update not needed");
426 TEST_EQ(ec_ro_updated, 1, " ec ro updated");
427 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
428 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
429 TEST_EQ(ec_run_image, 1, " ec run image");
430 TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST), 1,
431 " DISPLAY_REQUEST left untouched");
432
433 ResetMocks();
434 mock_ec_rw_hash[0]++;
435 mock_ec_ro_hash[0]++;
436 test_ssync(0, 0, "ro update not requested");
437 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
438 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
439 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
440 TEST_EQ(ec_run_image, 1, " ec run image");
441
442 ResetMocks();
443 mock_ec_rw_hash[0]++;
444 update_hash++;
445 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
446 VB2_RECOVERY_EC_UPDATE, "Updated hash mismatch");
447 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
448 TEST_EQ(ec_rw_updated, 1, " ec rw updated");
449 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
450 TEST_EQ(ec_run_image, 0, " ec run image");
451
452 ResetMocks();
453 mock_ec_rw_hash[0]++;
454 update_retval = VB2_REQUEST_REBOOT_EC_TO_RO;
455 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
456 0, "Reboot for rw update");
457 TEST_EQ(ec_ro_updated, 0, " ec rw updated");
458 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
459 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
460 TEST_EQ(ec_run_image, 0, " ec run image");
461
462 ResetMocks();
463 mock_ec_rw_hash[0]++;
464 update_retval = VB2_ERROR_MOCK;
465 test_ssync(VB2_ERROR_MOCK,
466 VB2_RECOVERY_EC_UPDATE, "Update failed");
467 TEST_EQ(ec_ro_updated, 0, " ec rw updated");
468 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
469 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
470 TEST_EQ(ec_run_image, 0, " ec run image");
471
472 /* Display not available - RW */
473 ResetMocks();
474 mock_ec_rw_hash[0]++;
475 mock_display_available = 0;
476 ctx->flags |= VB2_CONTEXT_EC_SYNC_SLOW;
477 test_ssync(VB2_REQUEST_REBOOT, 0,
478 "Reboot for display - ec rw");
479 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
480 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
481 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
482 TEST_EQ(ec_run_image, 0, " ec run image");
483 TEST_TRUE(need_display_called, " need display");
484
485 /* Display not available - RO */
486 ResetMocks();
487 vb2_nv_set(ctx, VB2_NV_TRY_RO_SYNC, 1);
488 mock_ec_ro_hash[0]++;
489 mock_display_available = 0;
490 ctx->flags |= VB2_CONTEXT_EC_SYNC_SLOW;
491 test_ssync(VB2_REQUEST_REBOOT, 0,
492 "Reboot for display - ec ro");
493 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
494 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
495 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
496 TEST_EQ(ec_run_image, 1, " ec run image");
497 TEST_TRUE(need_display_called, " need display");
498
499 /* RW cases, no update */
500 ResetMocks();
501 ec_run_image = 1;
502 test_ssync(0, 0, "AP-RW, EC-RW");
503 TEST_EQ(ec_ro_updated, 0, "ec ro updated");
504 TEST_EQ(ec_rw_updated, 0, "ec rw updated");
505 TEST_EQ(ec_rw_protected, 1, "ec rw protected");
506 TEST_EQ(ec_run_image, 1, "ec run image");
507 TEST_FALSE(ctx->flags & VB2_CONTEXT_EC_TRUSTED,
508 " VB2_CONTEXT_EC_TRUSTED is cleared");
509
510 ResetMocks();
511 test_ssync(0, 0, "AP-RW, EC-RO -> EC-RW");
512 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
513 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
514 TEST_EQ(ec_rw_protected, 1, " ec rw protected");
515 TEST_EQ(ec_run_image, 1, " ec run image");
516 TEST_FALSE(ctx->flags & VB2_CONTEXT_EC_TRUSTED,
517 " VB2_CONTEXT_EC_TRUSTED is cleared");
518
519 ResetMocks();
520 jump_retval = VB2_ERROR_MOCK;
521 test_ssync(VB2_ERROR_MOCK,
522 VB2_RECOVERY_EC_JUMP_RW, "Jump to RW fail");
523 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
524 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
525 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
526 TEST_EQ(ec_run_image, 0, " ec run image");
527 TEST_FALSE(ctx->flags & VB2_CONTEXT_EC_TRUSTED,
528 " VB2_CONTEXT_EC_TRUSTED is cleared");
529
530 ResetMocks();
531 jump_retval = VB2_REQUEST_REBOOT_EC_TO_RO;
532 test_ssync(VB2_REQUEST_REBOOT_EC_TO_RO,
533 0, "Jump to RW fail because locked");
534 TEST_EQ(ec_ro_updated, 0, " ec ro updated");
535 TEST_EQ(ec_rw_updated, 0, " ec rw updated");
536 TEST_EQ(ec_rw_protected, 0, " ec rw protected");
537 TEST_EQ(ec_run_image, 0, " ec run image");
538 TEST_FALSE(ctx->flags & VB2_CONTEXT_EC_TRUSTED,
539 " VB2_CONTEXT_EC_TRUSTED is cleared");
540
541 ResetMocks();
542 protect_retval = VB2_ERROR_MOCK;
543 test_ssync(VB2_ERROR_MOCK, VB2_RECOVERY_EC_PROTECT, "Protect error");
544 TEST_EQ(ec_ro_updated, 0, "ec ro updated");
545 TEST_EQ(ec_rw_updated, 0, "ec rw updated");
546 TEST_EQ(ec_rw_protected, 0, "ec rw protected");
547 TEST_EQ(ec_run_image, 1, "ec run image");
548 TEST_FALSE(ctx->flags & VB2_CONTEXT_EC_TRUSTED,
549 " VB2_CONTEXT_EC_TRUSTED is cleared");
550
551 /* No longer check for shutdown requested */
552 ResetMocks();
553 shutdown_request_calls_left = 0;
554 test_ssync(0, 0, "AP-RW, EC-RO -> EC-RW shutdown requested");
555 TEST_EQ(ec_ro_updated, 0, "ec ro updated");
556 TEST_EQ(ec_rw_updated, 0, "ec rw updated");
557 TEST_EQ(ec_rw_protected, 1, "ec rw protected");
558 TEST_EQ(ec_run_image, 1, "ec run image");
559
560 ResetMocks();
561 ec_run_image = 1;
562 shutdown_request_calls_left = 0;
563 test_ssync(0, 0, "AP-RW shutdown requested");
564 TEST_EQ(ec_ro_updated, 0, "ec ro updated");
565 TEST_EQ(ec_rw_updated, 0, "ec rw updated");
566 TEST_EQ(ec_rw_protected, 1, "ec rw protected");
567 TEST_EQ(ec_run_image, 1, "ec run image");
568
569 /* EC sync not allowed in recovery mode */
570 ResetMocks();
571 ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
572 test_ssync(0, 0, "No sync in recovery mode");
573 TEST_EQ(ec_ro_updated, 0, "ec ro updated");
574 TEST_EQ(ec_rw_updated, 0, "ec rw updated");
575 TEST_EQ(ec_rw_protected, 0, "ec rw protected");
576 TEST_EQ(ec_run_image, 0, "ec run image");
577 }
578
main(void)579 int main(void)
580 {
581 VbSoftwareSyncTest();
582
583 return gTestSuccess ? 0 : 255;
584 }
585