1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
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_firmware library.
6  */
7 
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "gbb_header.h"
14 #include "host_common.h"
15 #include "load_firmware_fw.h"
16 #include "test_common.h"
17 #include "vboot_common.h"
18 #include "vboot_nvstorage.h"
19 #include "vboot_struct.h"
20 
21 /* Mock data */
22 static VbCommonParams cparams;
23 static VbSelectFirmwareParams fparams;
24 static VbKeyBlockHeader vblock[2];
25 static VbFirmwarePreambleHeader mpreamble[2];
26 static VbNvContext vnc;
27 static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
28 static VbSharedDataHeader* shared = (VbSharedDataHeader*)shared_data;
29 static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
30 static GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)gbb_data;
31 static RSAPublicKey data_key;
32 static uint32_t digest_size;
33 static uint8_t* digest_returned;
34 static uint8_t* digest_expect_ptr;
35 static int hash_fw_index;
36 
37 #define TEST_KEY_DATA	\
38 	"Test contents for the root key this should be 64 chars long."
39 
40 /* Reset mock data (for use before each test) */
ResetMocks(void)41 static void ResetMocks(void) {
42   VbPublicKey *root_key;
43   uint8_t *root_key_data;
44   int i;
45 
46   Memset(&cparams, 0, sizeof(cparams));
47   cparams.shared_data_blob = shared_data;
48   cparams.gbb_data = gbb_data;
49   cparams.gbb_size = sizeof(gbb_data);
50   cparams.gbb = gbb;
51 
52   Memset(&fparams, 0, sizeof(fparams));
53   fparams.verification_block_A = vblock;
54   fparams.verification_size_A = sizeof(VbKeyBlockHeader);
55   fparams.verification_block_B = vblock + 1;
56   fparams.verification_size_B = sizeof(VbKeyBlockHeader);
57 
58   Memset(vblock, 0, sizeof(vblock));
59   Memset(mpreamble, 0, sizeof(mpreamble));
60   for (i = 0; i < 2; i++) {
61     /* Default verification blocks to working in all modes */
62     vblock[i].key_block_flags = 0x0F;
63     vblock[i].data_key.key_version = 2;
64     /* Fix up offsets to preambles */
65     vblock[i].key_block_size =
66         (uint8_t*)(mpreamble + i) - (uint8_t*)(vblock + i);
67 
68     mpreamble[i].header_version_minor = 1;  /* Supports preamble flags */
69     mpreamble[i].firmware_version = 4;
70     /* Point kernel subkey to some data following the key header */
71     PublicKeyInit(&mpreamble[i].kernel_subkey,
72                   (uint8_t*)&mpreamble[i].body_signature, 20);
73     mpreamble[i].kernel_subkey.algorithm = 7 + i;
74     mpreamble[i].body_signature.data_size = 20000 + 1000 * i;
75   }
76 
77   Memset(&vnc, 0, sizeof(vnc));
78   VbNvSetup(&vnc);
79 
80   Memset(&shared_data, 0, sizeof(shared_data));
81   VbSharedDataInit(shared, sizeof(shared_data));
82   shared->fw_version_tpm = 0x00020004;
83 
84   Memset(&gbb_data, 0, sizeof(gbb_data));
85   gbb->rootkey_offset = sizeof(GoogleBinaryBlockHeader);
86   root_key = (VbPublicKey *)(gbb_data + gbb->rootkey_offset);
87   root_key_data = (uint8_t *)(root_key + 1);
88   strcpy((char *)root_key_data, TEST_KEY_DATA);
89   PublicKeyInit(root_key, (uint8_t *)root_key_data, sizeof(TEST_KEY_DATA));
90 
91   gbb->major_version = GBB_MAJOR_VER;
92   gbb->minor_version = GBB_MINOR_VER;
93   gbb->flags = 0;
94 
95   Memset(&data_key, 0, sizeof(data_key));
96 
97   digest_size = 1234;
98   digest_returned = NULL;
99   digest_expect_ptr = NULL;
100   hash_fw_index = -1;
101 }
102 
103 /****************************************************************************/
104 /* Mocked verification functions */
105 
KeyBlockVerify(const VbKeyBlockHeader * block,uint64_t size,const VbPublicKey * key,int hash_only)106 int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
107                    const VbPublicKey *key, int hash_only) {
108 
109   TEST_EQ(hash_only, 0, "  Don't verify firmware with hash");
110 
111   /*
112    * We cannot check the address of key, since it will be allocated. We
113    * check the contents instead.
114    */
115   TEST_STR_EQ((char *)GetPublicKeyDataC(key), TEST_KEY_DATA,
116               "  Verify with root key");
117   TEST_NEQ(block==vblock || block==vblock+1, 0, "  Verify a valid key block");
118 
119   /* Mock uses header_version_major to hold return value */
120   return block->header_version_major;
121 }
122 
VerifyFirmwarePreamble(const VbFirmwarePreambleHeader * preamble,uint64_t size,const RSAPublicKey * key)123 int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble,
124                            uint64_t size, const RSAPublicKey* key) {
125   TEST_PTR_EQ(key, &data_key, "  Verify preamble data key");
126   TEST_NEQ(preamble==mpreamble || preamble==mpreamble+1, 0,
127            "  Verify a valid preamble");
128 
129   /* Mock uses header_version_major to hold return value */
130   return preamble->header_version_major;
131 }
132 
PublicKeyToRSA(const VbPublicKey * key)133 RSAPublicKey* PublicKeyToRSA(const VbPublicKey* key) {
134   /* Mock uses algorithm!0 to mean invalid key */
135   if (key->algorithm)
136     return NULL;
137   /* Mock uses data key len to hold number of alloc'd keys */
138   data_key.len++;
139   return &data_key;
140 }
141 
RSAPublicKeyFree(RSAPublicKey * key)142 void RSAPublicKeyFree(RSAPublicKey* key) {
143   TEST_PTR_EQ(key, &data_key, "  RSA data key");
144   data_key.len--;
145 }
146 
DigestInit(DigestContext * ctx,int sig_algorithm)147 void DigestInit(DigestContext* ctx, int sig_algorithm) {
148   digest_size = 0;
149 }
150 
DigestUpdate(DigestContext * ctx,const uint8_t * data,uint32_t len)151 void DigestUpdate(DigestContext* ctx, const uint8_t* data, uint32_t len) {
152   TEST_PTR_EQ(data, digest_expect_ptr, "  Digesting expected data");
153   digest_size += len;
154 }
155 
DigestFinal(DigestContext * ctx)156 uint8_t* DigestFinal(DigestContext* ctx) {
157   digest_returned = (uint8_t*)VbExMalloc(4);
158   return digest_returned;
159 }
160 
VbExHashFirmwareBody(VbCommonParams * cparams,uint32_t firmware_index)161 VbError_t VbExHashFirmwareBody(VbCommonParams* cparams,
162                                uint32_t firmware_index) {
163   if (VB_SELECT_FIRMWARE_A == firmware_index)
164     hash_fw_index = 0;
165   else if (VB_SELECT_FIRMWARE_B == firmware_index)
166     hash_fw_index = 1;
167   else
168     return VBERROR_INVALID_PARAMETER;
169 
170   digest_expect_ptr = (uint8_t*)(vblock + hash_fw_index) + 5;
171   VbUpdateFirmwareBodyHash(
172       cparams, digest_expect_ptr,
173       mpreamble[hash_fw_index].body_signature.data_size - 1024);
174   VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 1024);
175 
176   /* If signature offset is 42, hash the wrong amount and return success */
177   if (42 == mpreamble[hash_fw_index].body_signature.sig_offset) {
178     VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 4);
179     return VBERROR_SUCCESS;
180   }
181 
182   /* Otherwise, mocked function uses body signature offset as returned value */
183   return mpreamble[hash_fw_index].body_signature.sig_offset;
184 }
185 
VerifyDigest(const uint8_t * digest,const VbSignature * sig,const RSAPublicKey * key)186 int VerifyDigest(const uint8_t* digest, const VbSignature *sig,
187                  const RSAPublicKey* key) {
188   TEST_PTR_EQ(digest, digest_returned, "Verifying expected digest");
189   TEST_PTR_EQ(key, &data_key, "Verifying using data key");
190   TEST_PTR_EQ(sig, &mpreamble[hash_fw_index].body_signature, "Verifying sig");
191   /* Mocked function uses sig size as return value for verifying digest */
192   return sig->sig_size;
193 }
194 
195 /****************************************************************************/
196 /* Test LoadFirmware() and check expected return value and recovery reason */
TestLoadFirmware(VbError_t expected_retval,uint8_t expected_recovery,const char * desc)197 static void TestLoadFirmware(VbError_t expected_retval,
198                              uint8_t expected_recovery, const char* desc) {
199   uint32_t rr = 256;
200 
201   TEST_EQ(LoadFirmware(&cparams, &fparams, &vnc), expected_retval, desc);
202   VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr);
203   TEST_EQ(rr, expected_recovery, "  recovery request");
204   TEST_EQ(data_key.len, 0, "  Data key free must be paired with alloc");
205 }
206 
207 /****************************************************************************/
208 
LoadFirmwareTest(void)209 static void LoadFirmwareTest(void) {
210   uint32_t u;
211 
212   /* Require GBB */
213   ResetMocks();
214   cparams.gbb_data = NULL;
215   TestLoadFirmware(VBERROR_INVALID_GBB, VBNV_RECOVERY_RO_UNSPECIFIED,
216                    "No GBB");
217 
218   /* Key block flags must match */
219   /* Normal boot */
220   ResetMocks();
221   vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_1;
222   vblock[1].key_block_flags =
223       KEY_BLOCK_FLAG_DEVELOPER_0 | KEY_BLOCK_FLAG_RECOVERY_1;
224   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
225                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
226                     VBSD_LF_CHECK_REC_MISMATCH),
227                    "Flags mismatch dev=0");
228   TEST_EQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0,
229           "Dev flag in shared.flags dev=0");
230   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH,
231           "Key block flag mismatch for dev=0");
232   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH,
233           "Key block flag mismatch for rec=0");
234   /* Developer boot */
235   ResetMocks();
236   shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
237   vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0;
238   vblock[1].key_block_flags =
239       KEY_BLOCK_FLAG_DEVELOPER_1 | KEY_BLOCK_FLAG_RECOVERY_1;
240   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
241                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
242                     VBSD_LF_CHECK_REC_MISMATCH),
243                    "Flags mismatch dev=1");
244   TEST_NEQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0,
245           "Dev flag in shared.flags dev=1");
246   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH,
247           "Key block flag mismatch for dev=1");
248   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH,
249           "Key block flag mismatch for rec=1");
250 
251   /* Test key block verification with A and key version rollback with B */
252   ResetMocks();
253   vblock[0].header_version_major = 1;  /* Simulate failure */
254   vblock[1].data_key.key_version = 1;  /* Simulate rollback */
255   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
256                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
257                     VBSD_LF_CHECK_KEY_ROLLBACK),
258                    "Key block invalid / key version rollback");
259   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_KEYBLOCK,
260           "Key block invalid");
261   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_KEY_ROLLBACK,
262           "Key version rollback ");
263   TEST_EQ(shared->fw_version_lowest, 0, "Lowest valid version");
264   TEST_EQ(shared->fw_version_tpm, 0x20004, "TPM version");
265 
266   /* Test invalid key version with A and bad data key with B */
267   ResetMocks();
268   vblock[0].data_key.key_version = 0x10003;  /* Version > 0xFFFF is invalid */
269   vblock[1].data_key.algorithm = 1;  /* Simulate invalid data key */
270   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
271                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
272                     VBSD_LF_CHECK_DATA_KEY_PARSE),
273                    "Key version overflow / invalid data key");
274   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_KEY_ROLLBACK,
275           "Key version overflow");
276   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_DATA_KEY_PARSE,
277           "Data key invalid");
278 
279   /* Test invalid key version with GBB bypass-rollback flag */
280   ResetMocks();
281   vblock[0].data_key.key_version = 1;  /* Simulate rollback */
282   gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK;
283   TestLoadFirmware(VBERROR_SUCCESS, 0, "Key version check + GBB override");
284   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
285           "Key version rollback + GBB override");
286 
287   /* Test invalid preamble with A */
288   ResetMocks();
289   mpreamble[0].header_version_major = 1;  /* Simulate failure */
290   vblock[1].key_block_flags = 0;  /* Invalid */
291   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
292                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
293                     VBSD_LF_CHECK_VERIFY_PREAMBLE),
294                    "Preamble invalid");
295   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_PREAMBLE,
296           "Preamble invalid A");
297 
298   /* Test invalid firmware versions */
299   ResetMocks();
300   mpreamble[0].firmware_version = 3;  /* Simulate rollback */
301   mpreamble[1].firmware_version = 0x10001;  /* Check overflow */
302   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
303                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
304                     VBSD_LF_CHECK_FW_ROLLBACK),
305                    "Firmware version check");
306   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_FW_ROLLBACK,
307           "Firmware version rollback");
308   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_FW_ROLLBACK,
309           "Firmware version overflow");
310 
311   /* Test invalid firmware versions with GBB bypass-rollback flag */
312   ResetMocks();
313   mpreamble[0].firmware_version = 3;  /* Simulate rollback */
314   mpreamble[1].firmware_version = 0x10001;  /* Check overflow */
315   gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK;
316   TestLoadFirmware(VBERROR_SUCCESS, 0, "Firmware version check + GBB bypass");
317   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
318           "Firmware version rollback + GBB override");
319   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID,
320           "Firmware version overflow + GBB override");
321 
322   /* Test RO normal with A */
323   ResetMocks();
324   mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
325   vblock[1].key_block_flags = 0;  /* Invalid */
326   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
327                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
328                     VBSD_LF_CHECK_NO_RO_NORMAL),
329                    "Preamble asked for RO normal but fw doesn't support it");
330   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_NO_RO_NORMAL,
331           "No RO normal A");
332 
333   /* If RO normal is supported, don't need to verify the firmware body */
334   ResetMocks();
335   mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
336   /* Mock bad sig, to ensure we didn't use it */
337   mpreamble[0].body_signature.sig_size = 1;
338   shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
339   vblock[1].key_block_flags = 0;  /* Invalid */
340   TestLoadFirmware(VBERROR_SUCCESS, 0, "RO normal A");
341   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid");
342   TEST_EQ(shared->firmware_index, 0, "Boot A shared index");
343   TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags,
344           "Copy key block flags");
345   TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey");
346 
347   /* If both A and B are valid and same version as TPM, A is selected
348    * and B isn't attempted. */
349   ResetMocks();
350   mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
351   mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
352   shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
353   TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B");
354   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid");
355   TEST_EQ(shared->check_fw_b_result, 0, "RO normal B not checked ");
356   TEST_EQ(shared->firmware_index, 0, "Boot A");
357   TEST_EQ(shared->flags & VBSD_FWB_TRIED, 0, "Didn't try firmware B");
358   TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey");
359   /* But if try B flag is set, B is selected and A not attempted */
360   ResetMocks();
361   mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
362   mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
363   shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
364   VbNvSet(&vnc, VBNV_TRY_B_COUNT, 5);
365   TestLoadFirmware(VBERROR_SUCCESS, 0, "Check B then A");
366   TEST_EQ(shared->check_fw_a_result, 0, "RO normal A not checked ");
367   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_VALID, "RO normal B valid");
368   TEST_EQ(shared->firmware_index, 1, "Boot B");
369   TEST_NEQ(shared->flags & VBSD_FWB_TRIED, 0, "Tried firmware B");
370   TEST_EQ(shared->kernel_subkey.algorithm, 8, "Copy kernel subkey");
371   VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u);
372   TEST_EQ(u, 4, "Used up a try");
373 
374   /* If both A and B are valid and grater version than TPM, A is
375    * selected and B preamble (but not body) is verified. */
376   ResetMocks();
377   mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL;
378   mpreamble[1].flags = 0;
379   mpreamble[0].firmware_version = 5;
380   mpreamble[1].firmware_version = 6;
381   shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
382   TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B advancing version");
383   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid");
384   TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID,
385           "RO normal B header valid");
386   TEST_EQ(shared->firmware_index, 0, "Boot A");
387   TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags, "Key block A");
388   TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey");
389   TEST_EQ(shared->fw_version_lowest, 0x20005, "Lowest valid version");
390   TEST_EQ(shared->fw_version_tpm, 0x20005, "TPM version advanced");
391 
392   /* Verify firmware data */
393   ResetMocks();
394   vblock[1].key_block_flags = 0;  /* Invalid */
395   TestLoadFirmware(VBERROR_SUCCESS, 0, "Verify firmware body");
396   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
397           "Firmware body A valid");
398   TEST_EQ(shared->firmware_index, 0, "Boot A shared index");
399   TEST_EQ(hash_fw_index, 0, "Hash firmware data A");
400   TEST_EQ(digest_size, mpreamble[0].body_signature.data_size,
401           "Verified all data expected");
402 
403   /* Test error getting firmware body */
404   ResetMocks();
405   mpreamble[0].body_signature.sig_offset = VBERROR_UNKNOWN;
406   vblock[1].key_block_flags = 0;  /* Invalid */
407   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
408                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
409                     VBSD_LF_CHECK_GET_FW_BODY),
410                    "Error getting firmware body");
411   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_GET_FW_BODY,
412           "Firmware body A");
413 
414   /* Test digesting the wrong amount */
415   ResetMocks();
416   mpreamble[0].body_signature.sig_offset = 42;  /* Mock hashing wrong amount */
417   vblock[1].key_block_flags = 0;  /* Invalid */
418   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
419                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
420                     VBSD_LF_CHECK_HASH_WRONG_SIZE),
421                    "Hash wrong size");
422   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_HASH_WRONG_SIZE,
423           "Firmware hash wrong size A");
424 
425   /* Test bad signature */
426   ResetMocks();
427   mpreamble[0].body_signature.sig_size = 1;  /* Mock bad sig */
428   vblock[1].key_block_flags = 0;  /* Invalid */
429   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
430                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
431                     VBSD_LF_CHECK_VERIFY_BODY),
432                    "Bad signature");
433   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_BODY,
434           "Bad signature A");
435 
436   /* Test unable to store kernel data key */
437   ResetMocks();
438   mpreamble[0].kernel_subkey.key_size = VB_SHARED_DATA_MIN_SIZE + 1;
439   vblock[1].key_block_flags = 0;  /* Invalid */
440   TestLoadFirmware(VBERROR_LOAD_FIRMWARE,
441                    (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
442                     VBSD_LF_CHECK_VALID),
443                    "Kernel key too big");
444   TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID,
445           "Kernel key too big");
446 }
447 
448 
main(int argc,char * argv[])449 int main(int argc, char* argv[]) {
450   int error_code = 0;
451 
452   LoadFirmwareTest();
453 
454   if (vboot_api_stub_check_memory())
455     error_code = 255;
456   if (!gTestSuccess)
457     error_code = 255;
458 
459   return error_code;
460 }
461