xref: /aosp_15_r20/external/vboot_reference/tests/vb2_ec_sync_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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