]> git.proxmox.com Git - efi-boot-shim.git/blob - test-sbat.c
New upstream version 15.6
[efi-boot-shim.git] / test-sbat.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
2 /*
3 * test-sbat.c - test our sbat functions.
4 */
5
6 #ifndef SHIM_UNIT_TEST
7 #define SHIM_UNIT_TEST
8 #endif
9 #include "shim.h"
10
11 #include <stdio.h>
12
13 #define MAX_SIZE 512
14
15 list_t sbat_var;
16
17 BOOLEAN
18 secure_mode() {
19 return 1;
20 }
21
22 #if 0
23 /*
24 * Mock test helpers
25 */
26 static struct sbat_entry *
27 create_mock_sbat_entry(const char* comp_name, const char* comp_gen,
28 const char* vend_name, const char* vend_pkg_name,
29 const char* vend_ver, const char* vend_url)
30 {
31 struct sbat_entry *new_entry = AllocatePool(sizeof(*new_entry));
32 if (!new_entry)
33 return NULL;
34 new_entry->component_name = comp_name;
35 new_entry->component_generation = comp_gen;
36 new_entry->vendor_name = vend_name;
37 new_entry->vendor_package_name = vend_pkg_name;
38 new_entry->vendor_version = vend_ver;
39 new_entry->vendor_url = vend_url;
40 return new_entry;
41 }
42
43 void
44 free_mock_sbat_entry(struct sbat_entry *entry)
45 {
46 if (entry)
47 FreePool(entry);
48 }
49
50 static struct sbat *
51 create_mock_sbat_one_entry(char* comp_name, char* comp_gen, char* vend_name,
52 char* vend_pkg_name, char* vend_ver, char* vend_url)
53 {
54 struct sbat *new_entry = AllocatePool(sizeof(*new_entry));
55 if (!new_entry)
56 return NULL;
57 struct sbat_entry *test_entry;
58 struct sbat_entry **entries = AllocatePool(sizeof(*entries));
59 if (!entries)
60 return NULL;
61 test_entry = create_mock_sbat_entry(comp_name, comp_gen, vend_name,
62 vend_pkg_name, vend_ver, vend_url);
63 if (!test_entry)
64 return NULL;
65 entries[0] = test_entry;
66 new_entry->size = 1;
67 new_entry->entries = entries;
68 return new_entry;
69 }
70
71 static struct sbat *
72 create_mock_sbat_multiple_entries(struct sbat_entry *entry_array,
73 size_t num_elem)
74 {
75 unsigned int i;
76 struct sbat *new_entry = AllocatePool(sizeof(*new_entry));
77 if (!new_entry)
78 return NULL;
79 struct sbat_entry *test_entry;
80 struct sbat_entry **entries = AllocatePool(num_elem * sizeof(*entries));
81 if (!entries)
82 return NULL;
83 for (i = 0; i < num_elem; i++) {
84 test_entry = create_mock_sbat_entry(entry_array[i].component_name,
85 entry_array[i].component_generation,
86 entry_array[i].vendor_name,
87 entry_array[i].vendor_package_name,
88 entry_array[i].vendor_version,
89 entry_array[i].vendor_url);
90 if (!test_entry)
91 return NULL;
92 entries[i] = test_entry;
93 }
94 new_entry->size = num_elem;
95 new_entry->entries = entries;
96
97 return new_entry;
98 }
99
100 void
101 free_mock_sbat(struct sbat *sbat)
102 {
103 unsigned int i;
104 if (sbat) {
105 for (i = 0; i < sbat->size; i++) {
106 if (sbat->entries[i]) {
107 FreePool(sbat->entries[i]);
108 }
109 }
110 FreePool(sbat);
111 }
112 }
113
114 static struct sbat_var *
115 create_mock_sbat_var_entry(const char* comp_name, const char* comp_gen)
116 {
117 struct sbat_var *new_entry = AllocatePool(sizeof(*new_entry));
118 if (!new_entry)
119 return NULL;
120 INIT_LIST_HEAD(&new_entry->list);
121 int comp_name_size = strlen(comp_name) + 1;
122 CHAR8 *alloc_comp_name = AllocatePool(comp_name_size * sizeof(*alloc_comp_name));
123 if (!alloc_comp_name)
124 return NULL;
125 int comp_gen_size = strlen(comp_gen) + 1;
126 CHAR8 *alloc_comp_gen = AllocatePool(comp_gen_size * sizeof(*alloc_comp_gen));
127 if (!alloc_comp_gen)
128 return NULL;
129 CopyMem(alloc_comp_name, comp_name, comp_name_size);
130 CopyMem(alloc_comp_gen, comp_gen, comp_gen_size);
131 new_entry->component_name = alloc_comp_name;
132 new_entry->component_generation = alloc_comp_gen;
133 return new_entry;
134 }
135
136 static list_t *
137 create_mock_sbat_entries_one_entry(char* name, char* gen)
138 {
139 list_t *test_sbat_entries = AllocatePool(sizeof(*test_sbat_entries));
140 if (!test_sbat_entries)
141 return NULL;
142 INIT_LIST_HEAD(test_sbat_entries);
143 struct sbat_var *test_entry;
144 test_entry = create_mock_sbat_var_entry(name, gen);
145 if (!test_entry)
146 return NULL;
147 list_add(&test_entry->list, test_sbat_entries);
148 return test_sbat_entries;
149 }
150
151 static list_t *
152 create_mock_sbat_entries_multiple_entries(struct sbat_var *var_array,
153 size_t num_elem)
154 {
155 unsigned int i;
156 list_t *test_sbat_entries = AllocatePool(sizeof(*test_sbat_entries));
157 if (!test_sbat_entries)
158 return NULL;
159 INIT_LIST_HEAD(test_sbat_entries);
160 struct sbat_var *test_entry;
161 for (i = 0; i < num_elem; i++) {
162 test_entry = create_mock_sbat_var_entry(var_array[i].component_name,
163 var_array[i].component_generation);
164 if (!test_entry)
165 return NULL;
166 list_add(&test_entry->list, test_sbat_entries);
167 }
168 return test_sbat_entries;
169 }
170
171 void
172 free_mock_sbat_entries(list_t *entries)
173 {
174 list_t *pos = NULL;
175 list_t *n = NULL;
176 struct sbat_var *entry;
177
178 if (entries)
179 {
180 list_for_each_safe(pos, n, entries)
181 {
182 entry = list_entry(pos, struct sbat_var, list);
183 list_del(&entry->list);
184 if (entry->component_name)
185 FreePool((CHAR8 *)entry->component_name);
186 if (entry->component_generation)
187 FreePool((CHAR8 *)entry->component_generation);
188 FreePool(entry);
189 }
190 FreePool(entries);
191 }
192 }
193 #endif
194
195 /*
196 * parse_sbat_section() tests
197 */
198 int
199 test_parse_sbat_section_null_sbat_base(void)
200 {
201 char *section_base = NULL;
202 size_t section_size = 20;
203 struct sbat_section_entry **entries;
204 size_t n = 0;
205 EFI_STATUS status;
206
207 status = parse_sbat_section(section_base, section_size, &n, &entries);
208 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
209
210 return 0;
211 }
212
213 int
214 test_parse_sbat_section_zero_sbat_size(void)
215 {
216 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
217 size_t section_size = 0;
218 struct sbat_section_entry **entries;
219 size_t n = 0;
220 EFI_STATUS status;
221
222 status = parse_sbat_section(section_base, section_size, &n, &entries);
223 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
224
225 return 0;
226 }
227
228 int
229 test_parse_sbat_section_null_entries(void)
230 {
231 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
232 /* intentionally not NUL terminated */
233 size_t section_size = sizeof(section_base) - 1;
234 size_t n = 0;
235 EFI_STATUS status;
236
237 status = parse_sbat_section(section_base, section_size, &n, NULL);
238 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
239
240 return 0;
241 }
242
243 int
244 test_parse_sbat_section_null_count(void)
245 {
246 char section_base[] = "test1,1,SBAT test1,acme,1,testURL\n";
247 /* intentionally not NUL terminated */
248 size_t section_size = sizeof(section_base) - 1;
249 struct sbat_section_entry **entries;
250 EFI_STATUS status;
251
252 status = parse_sbat_section(section_base, section_size, NULL, &entries);
253 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
254
255 return 0;
256 }
257
258 int
259 test_parse_sbat_section_no_newline(void)
260 {
261 char section_base[] = "test1,1,SBAT test1,acme,1,testURL";
262 /* intentionally not NUL terminated */
263 size_t section_size = sizeof(section_base) - 1;
264 struct sbat_section_entry **entries;
265 size_t n = 0;
266 EFI_STATUS status;
267
268 status = parse_sbat_section(section_base, section_size, &n, &entries);
269 cleanup_sbat_section_entries(n, entries);
270 assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
271
272 return 0;
273 }
274
275 int
276 test_parse_sbat_section_no_commas(void)
277 {
278 char section_base[] = "test1";
279 /* intentionally not NUL terminated */
280 size_t section_size = sizeof(section_base) - 1;
281 struct sbat_section_entry **entries;
282 size_t n = 0;
283 EFI_STATUS status;
284
285 status = parse_sbat_section(section_base, section_size, &n, &entries);
286 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
287
288 return 0;
289 }
290
291 int
292 test_parse_sbat_section_too_few_elem(void)
293 {
294 char section_base[] = "test1,1,acme";
295 /* intentionally not NUL terminated */
296 size_t section_size = sizeof(section_base) - 1;
297 struct sbat_section_entry **entries;
298 size_t n = 0;
299 EFI_STATUS status;
300
301 status = parse_sbat_section(section_base, section_size, &n, &entries);
302 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
303
304 return 0;
305 }
306
307 int
308 test_parse_sbat_section_too_many_elem(void)
309 {
310 char section_base[] = "test1,1,SBAT test1,acme1,1,testURL1,other1,stuff,is,here\n"
311 "test2,2,SBAT test2,acme2,2,testURL2,other2";
312 /* intentionally not NUL terminated */
313 size_t section_size = sizeof(section_base) - 1;
314 struct sbat_section_entry **entries;
315 size_t n = 0, i;
316 list_t *pos = NULL;
317 EFI_STATUS status;
318 struct sbat_section_entry test_section_entry1 = {
319 "test1", "1", "SBAT test1", "acme1", "1", "testURL1"
320 };
321 struct sbat_section_entry test_section_entry2 = {
322 "test2", "2", "SBAT test2", "acme2", "2", "testURL2"
323 };
324 struct sbat_section_entry *test_entries[] = {
325 &test_section_entry1, &test_section_entry2,
326 };
327 int rc = -1;
328
329 status = parse_sbat_section(section_base, section_size, &n, &entries);
330 assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
331
332 for (i = 0; i < n; i++) {
333 struct sbat_section_entry *entry = entries[i];
334 struct sbat_section_entry *test_entry = test_entries[i];
335
336 #define mkassert(a) \
337 assert_equal_goto(strcmp(entry-> a, test_entry-> a), 0, fail, \
338 "got %zu expected %d\n")
339
340 mkassert(component_name);
341 mkassert(component_generation);
342 mkassert(vendor_name);
343 mkassert(vendor_package_name);
344 mkassert(vendor_version);
345 mkassert(vendor_url);
346
347 #undef mkassert
348 }
349 assert_equal_goto(n, 2, fail, "got %zu expected %d\n");
350 rc = 0;
351 fail:
352 cleanup_sbat_section_entries(n, entries);
353 return rc;
354 }
355
356 /*
357 * parse_sbat_var() tests
358 */
359 int
360 test_parse_sbat_var_null_list(void)
361 {
362 EFI_STATUS status;
363
364 INIT_LIST_HEAD(&sbat_var);
365 status = parse_sbat_var(NULL);
366 cleanup_sbat_var(&sbat_var);
367 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
368
369 return 0;
370 }
371
372 int
373 test_parse_sbat_var_data_null_list(void)
374 {
375 char sbat_var_data[] = "test1,1,2021022400";
376 /*
377 * intentionally including the NUL termination, because
378 * get_variable() will always include it.
379 */
380 size_t sbat_var_data_size = sizeof(sbat_var_data);
381 EFI_STATUS status;
382
383 INIT_LIST_HEAD(&sbat_var);
384 status = parse_sbat_var_data(NULL, sbat_var_data, sbat_var_data_size);
385 cleanup_sbat_var(&sbat_var);
386
387 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
388
389 return 0;
390 }
391
392 int
393 test_parse_sbat_var_data_null_data(void)
394 {
395 size_t sbat_var_data_size = 4;
396 EFI_STATUS status;
397
398 INIT_LIST_HEAD(&sbat_var);
399 status = parse_sbat_var_data(&sbat_var, NULL, sbat_var_data_size);
400 cleanup_sbat_var(&sbat_var);
401
402 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
403
404 return 0;
405 }
406
407 int
408 test_parse_sbat_var_data_zero_size(void)
409 {
410 char sbat_var_data[] = "test1,1,2021022400";
411 EFI_STATUS status;
412
413 INIT_LIST_HEAD(&sbat_var);
414 status = parse_sbat_var_data(&sbat_var, sbat_var_data, 0);
415 cleanup_sbat_var(&sbat_var);
416
417 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
418
419 return 0;
420 }
421
422 int
423 test_parse_sbat_var_data(void)
424 {
425 char sbat_var_data[] = "test1,1,2021022400";
426 EFI_STATUS status;
427
428 INIT_LIST_HEAD(&sbat_var);
429 status = parse_sbat_var_data(&sbat_var, sbat_var_data, 0);
430
431 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "got %#hhx expected %#hhx\n");
432
433 return 0;
434 }
435
436 /*
437 * verify_sbat() tests
438 * Note: verify_sbat also frees the underlying "sbat_entries" memory.
439 */
440 int
441 test_verify_sbat_null_sbat_section(void)
442 {
443 char sbat_var_data[] = "test1,1";
444 EFI_STATUS status;
445 list_t test_sbat_var;
446 size_t n = 0;
447 struct sbat_section_entry **entries = NULL;
448 int rc = -1;
449
450 INIT_LIST_HEAD(&test_sbat_var);
451 status = parse_sbat_var_data(&test_sbat_var, sbat_var_data, sizeof(sbat_var_data));
452 assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
453
454 status = verify_sbat_helper(&test_sbat_var, n, entries);
455 assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
456 rc = 0;
457 err:
458 cleanup_sbat_var(&test_sbat_var);
459
460 return rc;
461 }
462
463 #if 0
464 int
465 test_verify_sbat_null_sbat_entries(void)
466 {
467 struct sbat *test_sbat;
468 test_sbat = create_mock_sbat_one_entry("test1","1","SBAT test1",
469 "acme","1","testURL");
470 if (!test_sbat)
471 return -1;
472
473 list_t sbat_entries;
474 INIT_LIST_HEAD(&sbat_entries);
475 EFI_STATUS status;
476
477 status = verify_sbat(test_sbat, &sbat_entries);
478
479 assert(status == EFI_INVALID_PARAMETER);
480 free_mock_sbat(test_sbat);
481 return 0;
482 }
483
484 int
485 test_verify_sbat_match_one_exact(void)
486 {
487 struct sbat *test_sbat;
488 struct sbat_entry sbat_entry_array[2];
489 sbat_entry_array[0].component_name = "test1";
490 sbat_entry_array[0].component_generation = "1";
491 sbat_entry_array[0].vendor_name = "SBAT test1";
492 sbat_entry_array[0].vendor_package_name = "acme";
493 sbat_entry_array[0].vendor_version = "1";
494 sbat_entry_array[0].vendor_url = "testURL";
495 sbat_entry_array[1].component_name = "test2";
496 sbat_entry_array[1].component_generation = "2";
497 sbat_entry_array[1].vendor_name = "SBAT test2";
498 sbat_entry_array[1].vendor_package_name = "acme2";
499 sbat_entry_array[1].vendor_version = "2";
500 sbat_entry_array[1].vendor_url = "testURL2";
501 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
502 if (!test_sbat)
503 return -1;
504
505 list_t *test_sbat_entries;
506 test_sbat_entries = create_mock_sbat_entries_one_entry("test1", "1");
507 if (!test_sbat_entries)
508 return -1;
509 EFI_STATUS status;
510
511 status = verify_sbat(test_sbat, test_sbat_entries);
512
513 assert(status == EFI_SUCCESS);
514 free_mock_sbat(test_sbat);
515 free_mock_sbat_entries(test_sbat_entries);
516 return 0;
517 }
518
519 int
520 test_verify_sbat_match_one_higher(void)
521 {
522 struct sbat *test_sbat;
523 struct sbat_entry sbat_entry_array[2];
524 sbat_entry_array[0].component_name = "test1";
525 sbat_entry_array[0].component_generation = "1";
526 sbat_entry_array[0].vendor_name = "SBAT test1";
527 sbat_entry_array[0].vendor_package_name = "acme";
528 sbat_entry_array[0].vendor_version = "1";
529 sbat_entry_array[0].vendor_url = "testURL";
530 sbat_entry_array[1].component_name = "test2";
531 sbat_entry_array[1].component_generation = "2";
532 sbat_entry_array[1].vendor_name = "SBAT test2";
533 sbat_entry_array[1].vendor_package_name = "acme2";
534 sbat_entry_array[1].vendor_version = "2";
535 sbat_entry_array[1].vendor_url = "testURL2";
536 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
537 if (!test_sbat)
538 return -1;
539
540 list_t *test_sbat_entries;
541 test_sbat_entries = create_mock_sbat_entries_one_entry("test2", "1");
542 if (!test_sbat_entries)
543 return -1;
544 EFI_STATUS status;
545
546 status = verify_sbat(test_sbat, test_sbat_entries);
547
548 assert(status == EFI_SUCCESS);
549 free_mock_sbat(test_sbat);
550 free_mock_sbat_entries(test_sbat_entries);
551 return 0;
552 }
553
554 int
555 test_verify_sbat_reject_one(void)
556 {
557 struct sbat *test_sbat;
558 struct sbat_entry sbat_entry_array[2];
559 sbat_entry_array[0].component_name = "test1";
560 sbat_entry_array[0].component_generation = "1";
561 sbat_entry_array[0].vendor_name = "SBAT test1";
562 sbat_entry_array[0].vendor_package_name = "acme";
563 sbat_entry_array[0].vendor_version = "1";
564 sbat_entry_array[0].vendor_url = "testURL";
565 sbat_entry_array[1].component_name = "test2";
566 sbat_entry_array[1].component_generation = "2";
567 sbat_entry_array[1].vendor_name = "SBAT test2";
568 sbat_entry_array[1].vendor_package_name = "acme2";
569 sbat_entry_array[1].vendor_version = "2";
570 sbat_entry_array[1].vendor_url = "testURL2";
571 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array, 2);
572 if (!test_sbat)
573 return -1;
574
575 list_t *test_sbat_entries;
576 test_sbat_entries = create_mock_sbat_entries_one_entry("test2", "3");
577 if (!test_sbat_entries)
578 return -1;
579 EFI_STATUS status;
580
581 status = verify_sbat(test_sbat, test_sbat_entries);
582
583 assert(status == EFI_SECURITY_VIOLATION);
584 free_mock_sbat(test_sbat);
585 free_mock_sbat_entries(test_sbat_entries);
586 return 0;
587 }
588
589 int
590 test_verify_sbat_reject_many(void)
591 {
592 struct sbat *test_sbat;
593 unsigned int sbat_entry_array_size = 2;
594 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
595 sbat_entry_array[0].component_name = "test1";
596 sbat_entry_array[0].component_generation = "1";
597 sbat_entry_array[0].vendor_name = "SBAT test1";
598 sbat_entry_array[0].vendor_package_name = "acme";
599 sbat_entry_array[0].vendor_version = "1";
600 sbat_entry_array[0].vendor_url = "testURL";
601 sbat_entry_array[1].component_name = "test2";
602 sbat_entry_array[1].component_generation = "2";
603 sbat_entry_array[1].vendor_name = "SBAT test2";
604 sbat_entry_array[1].vendor_package_name = "acme2";
605 sbat_entry_array[1].vendor_version = "2";
606 sbat_entry_array[1].vendor_url = "testURL2";
607 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
608 sbat_entry_array_size);
609 if (!test_sbat)
610 return -1;
611
612 list_t *test_sbat_entries;
613 unsigned int sbat_var_array_size = 2;
614 struct sbat_var sbat_var_array[sbat_var_array_size];
615 sbat_var_array[0].component_name = "test1";
616 sbat_var_array[0].component_generation = "1";
617 sbat_var_array[1].component_name = "test2";
618 sbat_var_array[1].component_generation = "3";
619 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
620 sbat_var_array_size);
621 if (!test_sbat_entries)
622 return -1;
623 EFI_STATUS status;
624
625 status = verify_sbat(test_sbat, test_sbat_entries);
626
627 assert(status == EFI_SECURITY_VIOLATION);
628 free_mock_sbat(test_sbat);
629 free_mock_sbat_entries(test_sbat_entries);
630 return 0;
631 }
632
633 int
634 test_verify_sbat_match_many_higher(void)
635 {
636 struct sbat *test_sbat;
637 unsigned int sbat_entry_array_size = 2;
638 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
639 sbat_entry_array[0].component_name = "test1";
640 sbat_entry_array[0].component_generation = "3";
641 sbat_entry_array[0].vendor_name = "SBAT test1";
642 sbat_entry_array[0].vendor_package_name = "acme";
643 sbat_entry_array[0].vendor_version = "1";
644 sbat_entry_array[0].vendor_url = "testURL";
645 sbat_entry_array[1].component_name = "test2";
646 sbat_entry_array[1].component_generation = "5";
647 sbat_entry_array[1].vendor_name = "SBAT test2";
648 sbat_entry_array[1].vendor_package_name = "acme2";
649 sbat_entry_array[1].vendor_version = "2";
650 sbat_entry_array[1].vendor_url = "testURL2";
651 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
652 sbat_entry_array_size);
653 if (!test_sbat)
654 return -1;
655
656 list_t *test_sbat_entries;
657 unsigned int sbat_var_array_size = 2;
658 struct sbat_var sbat_var_array[sbat_var_array_size];
659 sbat_var_array[0].component_name = "test1";
660 sbat_var_array[0].component_generation = "1";
661 sbat_var_array[1].component_name = "test2";
662 sbat_var_array[1].component_generation = "2";
663 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
664 sbat_var_array_size);
665 if (!test_sbat_entries)
666 return -1;
667 EFI_STATUS status;
668
669 status = verify_sbat(test_sbat, test_sbat_entries);
670
671 assert(status == EFI_SUCCESS);
672 free_mock_sbat(test_sbat);
673 free_mock_sbat_entries(test_sbat_entries);
674 return 0;
675 }
676
677 int
678 test_verify_sbat_match_many_exact(void)
679 {
680 struct sbat *test_sbat;
681 unsigned int sbat_entry_array_size = 2;
682 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
683 sbat_entry_array[0].component_name = "test1";
684 sbat_entry_array[0].component_generation = "1";
685 sbat_entry_array[0].vendor_name = "SBAT test1";
686 sbat_entry_array[0].vendor_package_name = "acme";
687 sbat_entry_array[0].vendor_version = "1";
688 sbat_entry_array[0].vendor_url = "testURL";
689 sbat_entry_array[1].component_name = "test2";
690 sbat_entry_array[1].component_generation = "2";
691 sbat_entry_array[1].vendor_name = "SBAT test2";
692 sbat_entry_array[1].vendor_package_name = "acme2";
693 sbat_entry_array[1].vendor_version = "2";
694 sbat_entry_array[1].vendor_url = "testURL2";
695 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
696 sbat_entry_array_size);
697 if (!test_sbat)
698 return -1;
699
700 list_t *test_sbat_entries;
701 unsigned int sbat_var_array_size = 2;
702 struct sbat_var sbat_var_array[sbat_var_array_size];
703 sbat_var_array[0].component_name = "test1";
704 sbat_var_array[0].component_generation = "1";
705 sbat_var_array[1].component_name = "test2";
706 sbat_var_array[1].component_generation = "2";
707 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
708 sbat_var_array_size);
709 if (!test_sbat_entries)
710 return -1;
711 EFI_STATUS status;
712
713 status = verify_sbat(test_sbat, test_sbat_entries);
714
715 assert(status == EFI_SUCCESS);
716 free_mock_sbat(test_sbat);
717 free_mock_sbat_entries(test_sbat_entries);
718 return 0;
719 }
720
721 int
722 test_verify_sbat_reject_many_all(void)
723 {
724 struct sbat *test_sbat;
725 unsigned int sbat_entry_array_size = 2;
726 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
727 sbat_entry_array[0].component_name = "test1";
728 sbat_entry_array[0].component_generation = "1";
729 sbat_entry_array[0].vendor_name = "SBAT test1";
730 sbat_entry_array[0].vendor_package_name = "acme";
731 sbat_entry_array[0].vendor_version = "1";
732 sbat_entry_array[0].vendor_url = "testURL";
733 sbat_entry_array[1].component_name = "test2";
734 sbat_entry_array[1].component_generation = "2";
735 sbat_entry_array[1].vendor_name = "SBAT test2";
736 sbat_entry_array[1].vendor_package_name = "acme2";
737 sbat_entry_array[1].vendor_version = "2";
738 sbat_entry_array[1].vendor_url = "testURL2";
739 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
740 sbat_entry_array_size);
741 if (!test_sbat)
742 return -1;
743
744 list_t *test_sbat_entries;
745 unsigned int sbat_var_array_size = 2;
746 struct sbat_var sbat_var_array[sbat_var_array_size];
747 sbat_var_array[0].component_name = "test1";
748 sbat_var_array[0].component_generation = "3";
749 sbat_var_array[1].component_name = "test2";
750 sbat_var_array[1].component_generation = "5";
751 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
752 sbat_var_array_size);
753 if (!test_sbat_entries)
754 return -1;
755 EFI_STATUS status;
756
757 status = verify_sbat(test_sbat, test_sbat_entries);
758
759 assert(status == EFI_SECURITY_VIOLATION);
760 free_mock_sbat(test_sbat);
761 free_mock_sbat_entries(test_sbat_entries);
762 return 0;
763 }
764
765 int
766 test_verify_sbat_match_diff_name(void)
767 {
768 struct sbat *test_sbat;
769 unsigned int sbat_entry_array_size = 2;
770 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
771 sbat_entry_array[0].component_name = "test1";
772 sbat_entry_array[0].component_generation = "1";
773 sbat_entry_array[0].vendor_name = "SBAT test1";
774 sbat_entry_array[0].vendor_package_name = "acme";
775 sbat_entry_array[0].vendor_version = "1";
776 sbat_entry_array[0].vendor_url = "testURL";
777 sbat_entry_array[1].component_name = "test2";
778 sbat_entry_array[1].component_generation = "2";
779 sbat_entry_array[1].vendor_name = "SBAT test2";
780 sbat_entry_array[1].vendor_package_name = "acme2";
781 sbat_entry_array[1].vendor_version = "2";
782 sbat_entry_array[1].vendor_url = "testURL2";
783 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
784 sbat_entry_array_size);
785 if (!test_sbat)
786 return -1;
787
788 list_t *test_sbat_entries;
789 unsigned int sbat_var_array_size = 2;
790 struct sbat_var sbat_var_array[sbat_var_array_size];
791 sbat_var_array[0].component_name = "foo";
792 sbat_var_array[0].component_generation = "5";
793 sbat_var_array[1].component_name = "bar";
794 sbat_var_array[1].component_generation = "2";
795 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
796 sbat_var_array_size);
797 if (!test_sbat_entries)
798 return -1;
799 EFI_STATUS status;
800
801 status = verify_sbat(test_sbat, test_sbat_entries);
802
803 assert(status == EFI_SUCCESS);
804 free_mock_sbat(test_sbat);
805 free_mock_sbat_entries(test_sbat_entries);
806 return 0;
807 }
808
809 int
810 test_verify_sbat_match_diff_name_mixed(void)
811 {
812 struct sbat *test_sbat;
813 unsigned int sbat_entry_array_size = 2;
814 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
815 sbat_entry_array[0].component_name = "test1";
816 sbat_entry_array[0].component_generation = "1";
817 sbat_entry_array[0].vendor_name = "SBAT test1";
818 sbat_entry_array[0].vendor_package_name = "acme";
819 sbat_entry_array[0].vendor_version = "1";
820 sbat_entry_array[0].vendor_url = "testURL";
821 sbat_entry_array[1].component_name = "test2";
822 sbat_entry_array[1].component_generation = "2";
823 sbat_entry_array[1].vendor_name = "SBAT test2";
824 sbat_entry_array[1].vendor_package_name = "acme2";
825 sbat_entry_array[1].vendor_version = "2";
826 sbat_entry_array[1].vendor_url = "testURL2";
827 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
828 sbat_entry_array_size);
829 if (!test_sbat)
830 return -1;
831
832 list_t *test_sbat_entries;
833 unsigned int sbat_var_array_size = 2;
834 struct sbat_var sbat_var_array[sbat_var_array_size];
835 sbat_var_array[0].component_name = "test1";
836 sbat_var_array[0].component_generation = "1";
837 sbat_var_array[1].component_name = "bar";
838 sbat_var_array[1].component_generation = "2";
839 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
840 sbat_var_array_size);
841 if (!test_sbat_entries)
842 return -1;
843 EFI_STATUS status;
844
845 status = verify_sbat(test_sbat, test_sbat_entries);
846
847 assert(status == EFI_SUCCESS);
848 free_mock_sbat(test_sbat);
849 free_mock_sbat_entries(test_sbat_entries);
850 return 0;
851 }
852
853 int
854 test_verify_sbat_reject_diff_name_mixed(void)
855 {
856 struct sbat *test_sbat;
857 unsigned int sbat_entry_array_size = 2;
858 struct sbat_entry sbat_entry_array[sbat_entry_array_size];
859 sbat_entry_array[0].component_name = "test1";
860 sbat_entry_array[0].component_generation = "1";
861 sbat_entry_array[0].vendor_name = "SBAT test1";
862 sbat_entry_array[0].vendor_package_name = "acme";
863 sbat_entry_array[0].vendor_version = "1";
864 sbat_entry_array[0].vendor_url = "testURL";
865 sbat_entry_array[1].component_name = "test2";
866 sbat_entry_array[1].component_generation = "2";
867 sbat_entry_array[1].vendor_name = "SBAT test2";
868 sbat_entry_array[1].vendor_package_name = "acme2";
869 sbat_entry_array[1].vendor_version = "2";
870 sbat_entry_array[1].vendor_url = "testURL2";
871 test_sbat = create_mock_sbat_multiple_entries(sbat_entry_array,
872 sbat_entry_array_size);
873 if (!test_sbat)
874 return -1;
875
876 list_t *test_sbat_entries;
877 unsigned int sbat_var_array_size = 2;
878 struct sbat_var sbat_var_array[sbat_var_array_size];
879 sbat_var_array[0].component_name = "test1";
880 sbat_var_array[0].component_generation = "5";
881 sbat_var_array[1].component_name = "bar";
882 sbat_var_array[1].component_generation = "2";
883 test_sbat_entries = create_mock_sbat_entries_multiple_entries(sbat_var_array,
884 sbat_var_array_size);
885 if (!test_sbat_entries)
886 return -1;
887 EFI_STATUS status;
888
889 status = verify_sbat(test_sbat, test_sbat_entries);
890
891 assert(status == EFI_SECURITY_VIOLATION);
892 free_mock_sbat(test_sbat);
893 free_mock_sbat_entries(test_sbat_entries);
894 return 0;
895 }
896 #endif
897
898 int
899 test_parse_and_verify(void)
900 {
901 EFI_STATUS status;
902 char sbat_section[] =
903 "test1,1,SBAT test1,acme1,1,testURL1\n"
904 "test2,2,SBAT test2,acme2,2,testURL2\n";
905 struct sbat_section_entry **section_entries = NULL;
906 size_t n_section_entries = 0, i;
907 struct sbat_section_entry test_section_entry1 = {
908 "test1", "1", "SBAT test1", "acme1", "1", "testURL1"
909 };
910 struct sbat_section_entry test_section_entry2 = {
911 "test2", "2", "SBAT test2", "acme2", "2", "testURL2"
912 };
913 struct sbat_section_entry *test_entries[] = {
914 &test_section_entry1, &test_section_entry2,
915 };
916 int rc = -1;
917
918 status = parse_sbat_section(sbat_section, sizeof(sbat_section)-1,
919 &n_section_entries, &section_entries);
920 eassert(status == EFI_SUCCESS, "expected %d got %d\n",
921 EFI_SUCCESS, status);
922 eassert(section_entries != NULL, "expected non-NULL got NULL\n");
923
924 for (i = 0; i < n_section_entries; i++) {
925 struct sbat_section_entry *entry = section_entries[i];
926 struct sbat_section_entry *test_entry = test_entries[i];
927
928 #define mkassert(a) \
929 eassert(strcmp(entry-> a, test_entry-> a) == 0, \
930 "expected \"%s\" got \"%s\"\n", \
931 test_entry-> a, entry-> a )
932
933 mkassert(component_name);
934 mkassert(component_generation);
935 mkassert(vendor_name);
936 mkassert(vendor_package_name);
937 mkassert(vendor_version);
938 mkassert(vendor_url);
939
940 #undef mkassert
941 }
942
943 eassert(n_section_entries == 2, "expected %d got %d\n",
944 2, n_section_entries);
945
946 char sbat_var_data[] = "test1,5\nbar,2\n";
947 size_t sbat_var_data_size = sizeof(sbat_var_data);
948 char *sbat_var_alloced = calloc(1, sbat_var_data_size);
949 if (!sbat_var_alloced)
950 return -1;
951 memcpy(sbat_var_alloced, sbat_var_data, sbat_var_data_size);
952
953 INIT_LIST_HEAD(&sbat_var);
954 status = parse_sbat_var_data(&sbat_var, sbat_var_alloced, sbat_var_data_size);
955 free(sbat_var_alloced);
956 if (status != EFI_SUCCESS || list_empty(&sbat_var))
957 return -1;
958
959 status = verify_sbat(n_section_entries, section_entries);
960 assert_equal_goto(status, EFI_SECURITY_VIOLATION, err, "expected %#x got %#x\n");
961
962 rc = 0;
963 err:
964 cleanup_sbat_section_entries(n_section_entries, section_entries);
965 cleanup_sbat_var(&sbat_var);
966
967 return rc;
968 }
969
970 int
971 test_preserve_sbat_uefi_variable_good(void)
972 {
973 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
974 char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\n";
975 size_t sbat_size = sizeof(sbat);
976 UINT32 attributes = SBAT_VAR_ATTRS;
977
978 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
979 return 0;
980 else
981 return -1;
982 }
983
984 int
985 test_preserve_sbat_uefi_variable_version_newer(void)
986 {
987 char sbat[] = "sbat,2,2022030218\ncomponent,2,\n";
988 char sbatvar[] = "sbat,1,2021030218\ncomponent,2,\n";
989 size_t sbat_size = sizeof(sbat);
990 UINT32 attributes = SBAT_VAR_ATTRS;
991
992 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
993 return 0;
994 else
995 return -1;
996 }
997
998 int
999 test_preserve_sbat_uefi_variable_version_newerlonger(void)
1000 {
1001 char sbat[] = "sbat,10,2022030218\ncomponent,2,\n";
1002 char sbatvar[] = "sbat,2,2021030218\ncomponent,2,\n";
1003 size_t sbat_size = sizeof(sbat);
1004 UINT32 attributes = SBAT_VAR_ATTRS;
1005
1006 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1007 return 0;
1008 else
1009 return -1;
1010 }
1011
1012 int
1013 test_preserve_sbat_uefi_variable_version_older(void)
1014 {
1015 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1016 char sbatvar[] = "sbat,2,2022030218\ncomponent,2,\n";
1017 size_t sbat_size = sizeof(sbat);
1018 UINT32 attributes = SBAT_VAR_ATTRS;
1019
1020 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1021 return -1;
1022 else
1023 return 0;
1024 }
1025
1026 int
1027 test_preserve_sbat_uefi_variable_version_olderlonger(void)
1028 {
1029 char sbat[] = "sbat,2,2021030218\ncomponent,2,\n";
1030 char sbatvar[] = "sbat,10,2022030218\ncomponent,2,\n";
1031 size_t sbat_size = sizeof(sbat);
1032 UINT32 attributes = SBAT_VAR_ATTRS;
1033
1034 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1035 return -1;
1036 else
1037 return 0;
1038 }
1039
1040
1041 int
1042 test_preserve_sbat_uefi_variable_newer(void)
1043 {
1044 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1045 char sbatvar[] = "sbat,1,2025030218\ncomponent,5,\ncomponent,3";
1046 size_t sbat_size = sizeof(sbat);
1047 UINT32 attributes = SBAT_VAR_ATTRS;
1048
1049 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1050 return -1;
1051 else
1052 return 0;
1053 }
1054 int
1055 test_preserve_sbat_uefi_variable_older(void)
1056 {
1057 char sbat[] = "sbat,1,2025030218\ncomponent,2,\ncomponent,3";
1058 char sbatvar[] = "sbat,1,2020030218\ncomponent,1,\n";
1059 size_t sbat_size = sizeof(sbat);
1060 UINT32 attributes = SBAT_VAR_ATTRS;
1061
1062 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1063 return 0;
1064 else
1065 return -1;
1066 }
1067
1068 int
1069 test_preserve_sbat_uefi_variable_bad_sig(void)
1070 {
1071 char sbat[] = "bad_sig,1,2021030218\ncomponent,2,\n";
1072 char sbatvar[] = "sbat,1,2021030218\n";
1073 size_t sbat_size = sizeof(sbat);
1074 UINT32 attributes = SBAT_VAR_ATTRS;
1075
1076 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1077 return -1;
1078 else
1079 return 0;
1080 }
1081
1082 int
1083 test_preserve_sbat_uefi_variable_bad_attr(void)
1084 {
1085 char sbat[] = "sbat,1,2021030218\ncomponent,2,\n";
1086 char sbatvar[] = "sbat,1,2021030218\n";
1087 size_t sbat_size = sizeof(sbat);
1088 UINT32 attributes = 0;
1089
1090 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1091 return -1;
1092 else
1093 return 0;
1094 }
1095
1096 int
1097 test_preserve_sbat_uefi_variable_bad_short(void)
1098 {
1099 char sbat[] = "sba";
1100 char sbatvar[] = "sbat,1,2021030218\n";
1101 size_t sbat_size = sizeof(sbat);
1102 UINT32 attributes = SBAT_VAR_ATTRS;
1103
1104 if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes, sbatvar))
1105 return -1;
1106 else
1107 return 0;
1108 }
1109
1110 int
1111 main(void)
1112 {
1113 int status = 0;
1114 // parse_sbat section tests
1115 test(test_parse_sbat_section_null_sbat_base);
1116 test(test_parse_sbat_section_zero_sbat_size);
1117 test(test_parse_sbat_section_null_entries);
1118 test(test_parse_sbat_section_null_count);
1119 test(test_parse_sbat_section_no_newline);
1120 test(test_parse_sbat_section_no_commas);
1121 test(test_parse_sbat_section_too_few_elem);
1122 test(test_parse_sbat_section_too_many_elem);
1123
1124 // parse_sbat_var tests
1125 test(test_parse_sbat_var_null_list);
1126 test(test_parse_sbat_var_data_null_list);
1127 test(test_parse_sbat_var_data_null_data);
1128 test(test_parse_sbat_var_data_zero_size);
1129
1130 // verify_sbat tests
1131 test(test_verify_sbat_null_sbat_section);
1132 #if 0
1133 test(test_verify_sbat_null_sbat_entries);
1134 test(test_verify_sbat_match_one_exact);
1135 test(test_verify_sbat_match_one_higher);
1136 test(test_verify_sbat_reject_one);
1137 test(test_verify_sbat_reject_many);
1138 test(test_verify_sbat_match_many_higher);
1139 test(test_verify_sbat_match_many_exact);
1140 test(test_verify_sbat_reject_many_all);
1141 test(test_verify_sbat_match_diff_name);
1142 test(test_verify_sbat_match_diff_name_mixed);
1143 test(test_verify_sbat_reject_diff_name_mixed);
1144 #endif
1145 test(test_parse_and_verify);
1146
1147 test(test_preserve_sbat_uefi_variable_good);
1148 test(test_preserve_sbat_uefi_variable_newer);
1149 test(test_preserve_sbat_uefi_variable_older);
1150 test(test_preserve_sbat_uefi_variable_bad_sig);
1151 test(test_preserve_sbat_uefi_variable_bad_attr);
1152 test(test_preserve_sbat_uefi_variable_bad_short);
1153 test(test_preserve_sbat_uefi_variable_version_newer);
1154 test(test_preserve_sbat_uefi_variable_version_newerlonger);
1155 test(test_preserve_sbat_uefi_variable_version_older);
1156 test(test_preserve_sbat_uefi_variable_version_olderlonger);
1157
1158 return 0;
1159 }
1160
1161 // vim:fenc=utf-8:tw=75:noet