blob: 03e77f9878d05595263221bcf62912bd960a80b4 [file] [log] [blame]
Randall Spangler49cb0d32013-01-29 14:28:16 -08001/* Copyright (c) 2013 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_kernel.c
6 */
7
Bill Richardson0c3ba242013-03-29 11:09:30 -07008#include <stdint.h>
Randall Spangler49cb0d32013-01-29 14:28:16 -08009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "cgptlib.h"
Duncan Laurie162f7882014-10-01 09:58:10 -070014#include "cgptlib_internal.h"
Randall Spangler49cb0d32013-01-29 14:28:16 -080015#include "gbb_header.h"
16#include "gpt.h"
17#include "host_common.h"
18#include "load_kernel_fw.h"
19#include "test_common.h"
20#include "vboot_api.h"
21#include "vboot_common.h"
22#include "vboot_kernel.h"
23#include "vboot_nvstorage.h"
24
25#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
26#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
27
Duncan Laurie162f7882014-10-01 09:58:10 -070028#define MOCK_SECTOR_SIZE 512
29#define MOCK_SECTOR_COUNT 1024
30
Randall Spangler5d0a2e72013-01-30 13:19:19 -080031/* Mock kernel partition */
32struct mock_part {
33 uint32_t start;
34 uint32_t size;
35};
36
37/* Partition list; ends with a 0-size partition. */
38#define MOCK_PART_COUNT 8
39static struct mock_part mock_parts[MOCK_PART_COUNT];
40static int mock_part_next;
41
Randall Spangler49cb0d32013-01-29 14:28:16 -080042/* Mock data */
43static char call_log[4096];
Randall Spangler5d0a2e72013-01-30 13:19:19 -080044static uint8_t kernel_buffer[80000];
45static int disk_read_to_fail;
46static int disk_write_to_fail;
Randall Spangler49cb0d32013-01-29 14:28:16 -080047static int gpt_init_fail;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080048static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
49static int preamble_verify_fail;
Randall Spangler3e9cf902013-02-01 13:31:20 -080050static int verify_data_fail;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080051static RSAPublicKey *mock_data_key;
52static int mock_data_key_allocated;
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -080053static int gpt_flag_external;
Randall Spangler49cb0d32013-01-29 14:28:16 -080054
Simon Glass527ba812013-07-25 08:48:47 -060055static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
56static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader*)gbb_data;
Randall Spangler49cb0d32013-01-29 14:28:16 -080057static VbExDiskHandle_t handle;
58static VbNvContext vnc;
59static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
60static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
61static LoadKernelParams lkp;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080062static VbKeyBlockHeader kbh;
63static VbKernelPreambleHeader kph;
Simon Glass527ba812013-07-25 08:48:47 -060064static VbCommonParams cparams;
Duncan Laurie162f7882014-10-01 09:58:10 -070065static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
66static GptHeader *mock_gpt_primary =
67 (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
68static GptHeader *mock_gpt_secondary =
69 (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
70
71
72/**
73 * Prepare a valid GPT header that will pass CheckHeader() tests
74 */
75static void SetupGptHeader(GptHeader *h, int is_secondary)
76{
77 Memset(h, '\0', MOCK_SECTOR_SIZE);
78
79 /* "EFI PART" */
80 memcpy(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE);
81 h->revision = GPT_HEADER_REVISION;
82 h->size = MIN_SIZE_OF_HEADER;
83
84 /* 16KB: 128 entries of 128 bytes */
85 h->size_of_entry = sizeof(GptEntry);
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -080086 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
Duncan Laurie162f7882014-10-01 09:58:10 -070087
88 /* Set LBA pointers for primary or secondary header */
89 if (is_secondary) {
90 h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
Nam T. Nguyen32004012014-12-12 09:38:35 -080091 h->entries_lba = h->my_lba - CalculateEntriesSectors(h);
Duncan Laurie162f7882014-10-01 09:58:10 -070092 } else {
93 h->my_lba = GPT_PMBR_SECTORS;
94 h->entries_lba = h->my_lba + 1;
95 }
96
Nam T. Nguyen32004012014-12-12 09:38:35 -080097 h->first_usable_lba = 2 + CalculateEntriesSectors(h);
98 h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h);
Duncan Laurie162f7882014-10-01 09:58:10 -070099
100 h->header_crc32 = HeaderCrc(h);
101}
Randall Spangler49cb0d32013-01-29 14:28:16 -0800102
103static void ResetCallLog(void)
104{
105 *call_log = 0;
106}
107
108/**
109 * Reset mock data (for use before each test)
110 */
111static void ResetMocks(void)
112{
113 ResetCallLog();
114
Duncan Laurie162f7882014-10-01 09:58:10 -0700115 memset(&mock_disk, 0, sizeof(mock_disk));
116 SetupGptHeader(mock_gpt_primary, 0);
117 SetupGptHeader(mock_gpt_secondary, 1);
118
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800119 disk_read_to_fail = -1;
120 disk_write_to_fail = -1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800121
122 gpt_init_fail = 0;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800123 key_block_verify_fail = 0;
124 preamble_verify_fail = 0;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800125 verify_data_fail = 0;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800126
127 mock_data_key = (RSAPublicKey *)"TestDataKey";
128 mock_data_key_allocated = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800129
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800130 gpt_flag_external = 0;
131
Han Shen1a113812013-09-03 11:23:30 -0700132 memset(gbb, 0, sizeof(*gbb));
Simon Glass527ba812013-07-25 08:48:47 -0600133 gbb->major_version = GBB_MAJOR_VER;
134 gbb->minor_version = GBB_MINOR_VER;
135 gbb->flags = 0;
136
137 memset(&cparams, '\0', sizeof(cparams));
138 cparams.gbb = gbb;
139 cparams.gbb_data = gbb;
140 cparams.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800141
142 memset(&vnc, 0, sizeof(vnc));
143 VbNvSetup(&vnc);
144 VbNvTeardown(&vnc); /* So CRC gets generated */
145
146 memset(&shared_data, 0, sizeof(shared_data));
147 VbSharedDataInit(shared, sizeof(shared_data));
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800148 shared->kernel_version_tpm = 0x20001;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800149
150 memset(&lkp, 0, sizeof(lkp));
151 lkp.nv_context = &vnc;
152 lkp.shared_data_blob = shared;
Simon Glass527ba812013-07-25 08:48:47 -0600153 lkp.gbb_data = gbb;
154 lkp.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800155 lkp.bytes_per_lba = 512;
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800156 lkp.streaming_lba_count = 1024;
157 lkp.gpt_lba_count = 1024;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800158 lkp.kernel_buffer = kernel_buffer;
159 lkp.kernel_buffer_size = sizeof(kernel_buffer);
Randall Spangler4184e622014-10-08 16:41:01 -0700160 lkp.disk_handle = (VbExDiskHandle_t)1;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800161
162 memset(&kbh, 0, sizeof(kbh));
163 kbh.data_key.key_version = 2;
164 kbh.key_block_flags = -1;
165 kbh.key_block_size = sizeof(kbh);
166
167 memset(&kph, 0, sizeof(kph));
168 kph.kernel_version = 1;
169 kph.preamble_size = 4096 - kbh.key_block_size;
Randall Spangler4184e622014-10-08 16:41:01 -0700170 kph.body_signature.data_size = 70144;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800171 kph.bootloader_address = 0xbeadd008;
172 kph.bootloader_size = 0x1234;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800173
174 memset(mock_parts, 0, sizeof(mock_parts));
175 mock_parts[0].start = 100;
176 mock_parts[0].size = 150; /* 75 KB */
177 mock_part_next = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800178}
179
180/* Mocks */
181
182VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
183 uint64_t lba_count, void *buffer)
184{
185 LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
186
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800187 if ((int)lba_start == disk_read_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800188 return VBERROR_SIMULATED;
189
Duncan Laurie162f7882014-10-01 09:58:10 -0700190 memcpy(buffer, &mock_disk[lba_start * MOCK_SECTOR_SIZE],
191 lba_count * MOCK_SECTOR_SIZE);
192
Randall Spangler49cb0d32013-01-29 14:28:16 -0800193 return VBERROR_SUCCESS;
194}
195
196VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
197 uint64_t lba_count, const void *buffer)
198{
199 LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
200
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800201 if ((int)lba_start == disk_write_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800202 return VBERROR_SIMULATED;
203
Duncan Laurie162f7882014-10-01 09:58:10 -0700204 memcpy(&mock_disk[lba_start * MOCK_SECTOR_SIZE], buffer,
205 lba_count * MOCK_SECTOR_SIZE);
206
Randall Spangler49cb0d32013-01-29 14:28:16 -0800207 return VBERROR_SUCCESS;
208}
209
210int GptInit(GptData *gpt)
211{
212 return gpt_init_fail;
213}
214
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800215int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
216{
217 struct mock_part *p = mock_parts + mock_part_next;
218
219 if (!p->size)
220 return GPT_ERROR_NO_VALID_KERNEL;
221
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800222 if (gpt->flags & GPT_FLAG_EXTERNAL)
223 gpt_flag_external++;
224
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800225 gpt->current_kernel = mock_part_next;
226 *start_sector = p->start;
227 *size = p->size;
228 mock_part_next++;
229 return GPT_SUCCESS;
230}
231
Randall Spangler3e9cf902013-02-01 13:31:20 -0800232void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
233{
234 static char fake_guid[] = "FakeGuid";
235
236 memcpy(dest, fake_guid, sizeof(fake_guid));
237}
238
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800239int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
240 const VbPublicKey *key, int hash_only) {
241
242 if (hash_only && key_block_verify_fail >= 2)
243 return VBERROR_SIMULATED;
244 else if (!hash_only && key_block_verify_fail >= 1)
245 return VBERROR_SIMULATED;
246
247 /* Use this as an opportunity to override the key block */
248 memcpy((void *)block, &kbh, sizeof(kbh));
249 return VBERROR_SUCCESS;
250}
251
252RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
253{
254 TEST_EQ(mock_data_key_allocated, 0, " mock data key not allocated");
255
256 if (mock_data_key)
257 mock_data_key_allocated++;
258
259 return mock_data_key;
260}
261
262void RSAPublicKeyFree(RSAPublicKey* key)
263{
264 TEST_EQ(mock_data_key_allocated, 1, " mock data key allocated");
265 TEST_PTR_EQ(key, mock_data_key, " data key ptr");
266 mock_data_key_allocated--;
267}
268
269int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
270 uint64_t size, const RSAPublicKey *key)
271{
272 if (preamble_verify_fail)
273 return VBERROR_SIMULATED;
274
275 /* Use this as an opportunity to override the preamble */
276 memcpy((void *)preamble, &kph, sizeof(kph));
277 return VBERROR_SUCCESS;
278}
279
Randall Spangler3e9cf902013-02-01 13:31:20 -0800280int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
281 const RSAPublicKey *key)
282{
283 if (verify_data_fail)
284 return VBERROR_SIMULATED;
285
286 return VBERROR_SUCCESS;
287}
288
289
Randall Spangler49cb0d32013-01-29 14:28:16 -0800290/**
291 * Test reading/writing GPT
292 */
293static void ReadWriteGptTest(void)
294{
295 GptData g;
296 GptHeader *h;
297
Duncan Laurie162f7882014-10-01 09:58:10 -0700298 g.sector_bytes = MOCK_SECTOR_SIZE;
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800299 g.streaming_drive_sectors = g.gpt_drive_sectors = MOCK_SECTOR_COUNT;
Duncan Laurie162f7882014-10-01 09:58:10 -0700300 g.valid_headers = g.valid_entries = MASK_BOTH;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800301
302 ResetMocks();
303 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
304 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
305 "VbExDiskRead(h, 2, 32)\n"
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700306 "VbExDiskRead(h, 1023, 1)\n"
307 "VbExDiskRead(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800308 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600309 /*
310 * Valgrind complains about access to uninitialized memory here, so
311 * zero the primary header before each test.
312 */
313 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800314 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
315 TEST_CALLS("");
316
Duncan Laurie162f7882014-10-01 09:58:10 -0700317 /*
318 * Invalidate primary GPT header,
319 * check that AllocAndReadGptData still succeeds
320 */
321 ResetMocks();
322 Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
323 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
324 "AllocAndRead primary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800325 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
326 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800327 1, "Primary header is invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800328 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
329 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800330 0, "Secondary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700331 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
332 "VbExDiskRead(h, 1023, 1)\n"
333 "VbExDiskRead(h, 991, 32)\n");
334 WriteAndFreeGptData(handle, &g);
335
336 /*
337 * Invalidate secondary GPT header,
338 * check that AllocAndReadGptData still succeeds
339 */
340 ResetMocks();
341 Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
342 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
343 "AllocAndRead secondary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800344 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
345 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800346 0, "Primary header is valid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800347 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
348 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800349 1, "Secondary header is invalid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700350 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
351 "VbExDiskRead(h, 2, 32)\n"
352 "VbExDiskRead(h, 1023, 1)\n");
353 WriteAndFreeGptData(handle, &g);
354
355 /*
356 * Invalidate primary AND secondary GPT header,
357 * check that AllocAndReadGptData fails.
358 */
359 ResetMocks();
360 Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
361 Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
362 TEST_EQ(AllocAndReadGptData(handle, &g), 1,
363 "AllocAndRead primary and secondary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800364 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
365 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800366 1, "Primary header is invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800367 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
368 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800369 1, "Secondary header is invalid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700370 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
371 "VbExDiskRead(h, 1023, 1)\n");
372 WriteAndFreeGptData(handle, &g);
373
374 /*
375 * Invalidate primary GPT header and check that it is
376 * repaired by GptRepair().
377 *
378 * This would normally be called by LoadKernel()->GptInit()
379 * but this callback is mocked in these tests.
380 */
381 ResetMocks();
382 Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
383 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
384 "Fix Primary GPT: AllocAndRead");
385 /* Call GptRepair() with input indicating secondary GPT is valid */
386 g.valid_headers = g.valid_entries = MASK_SECONDARY;
387 GptRepair(&g);
388 TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
389 "Fix Primary GPT: WriteAndFreeGptData");
390 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
391 "VbExDiskRead(h, 1023, 1)\n"
392 "VbExDiskRead(h, 991, 32)\n"
393 "VbExDiskWrite(h, 1, 1)\n"
394 "VbExDiskWrite(h, 2, 32)\n");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800395 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
396 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800397 0, "Fix Primary GPT: Primary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700398
399 /*
400 * Invalidate secondary GPT header and check that it can be
401 * repaired by GptRepair().
402 *
403 * This would normally be called by LoadKernel()->GptInit()
404 * but this callback is mocked in these tests.
405 */
406 ResetMocks();
407 Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
408 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
409 "Fix Secondary GPT: AllocAndRead");
410 /* Call GptRepair() with input indicating primary GPT is valid */
411 g.valid_headers = g.valid_entries = MASK_PRIMARY;
412 GptRepair(&g);
413 TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
414 "Fix Secondary GPT: WriteAndFreeGptData");
415 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
416 "VbExDiskRead(h, 2, 32)\n"
417 "VbExDiskRead(h, 1023, 1)\n"
418 "VbExDiskWrite(h, 1023, 1)\n"
419 "VbExDiskWrite(h, 991, 32)\n");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800420 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
421 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800422 0, "Fix Secondary GPT: Secondary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700423
Randall Spangler49cb0d32013-01-29 14:28:16 -0800424 /* Data which is changed is written */
425 ResetMocks();
426 AllocAndReadGptData(handle, &g);
427 g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
428 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600429 Memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700430 h = (GptHeader*)g.primary_header;
431 h->entries_lba = 2;
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -0800432 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
433 h->size_of_entry = sizeof(GptEntry);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800434 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
435 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
436 "VbExDiskWrite(h, 2, 32)\n");
437
438 /* Data which is changed is written */
439 ResetMocks();
440 AllocAndReadGptData(handle, &g);
441 g.modified = -1;
442 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600443 Memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700444 h = (GptHeader*)g.primary_header;
445 h->entries_lba = 2;
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -0800446 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
447 h->size_of_entry = sizeof(GptEntry);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700448 h = (GptHeader*)g.secondary_header;
449 h->entries_lba = 991;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800450 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
451 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
452 "VbExDiskWrite(h, 2, 32)\n"
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700453 "VbExDiskWrite(h, 1023, 1)\n"
454 "VbExDiskWrite(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800455
456 /* If legacy signature, don't modify GPT header/entries 1 */
457 ResetMocks();
458 AllocAndReadGptData(handle, &g);
459 h = (GptHeader *)g.primary_header;
460 memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
461 g.modified = -1;
462 ResetCallLog();
463 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700464 TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
465 "VbExDiskWrite(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800466
467 /* Error reading */
468 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800469 disk_read_to_fail = 1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800470 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600471 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800472 WriteAndFreeGptData(handle, &g);
473
Randall Spangler3e9cf902013-02-01 13:31:20 -0800474 ResetMocks();
475 disk_read_to_fail = 2;
476 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600477 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800478 WriteAndFreeGptData(handle, &g);
479
480 ResetMocks();
481 disk_read_to_fail = 991;
482 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600483 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800484 WriteAndFreeGptData(handle, &g);
485
486 ResetMocks();
487 disk_read_to_fail = 1023;
488 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600489 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800490 WriteAndFreeGptData(handle, &g);
491
Randall Spangler49cb0d32013-01-29 14:28:16 -0800492 /* Error writing */
493 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800494 disk_write_to_fail = 1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800495 AllocAndReadGptData(handle, &g);
496 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600497 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800498 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800499
500 ResetMocks();
501 disk_write_to_fail = 2;
502 AllocAndReadGptData(handle, &g);
503 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600504 Memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700505 h = (GptHeader*)g.primary_header;
506 h->entries_lba = 2;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800507 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
508
509 ResetMocks();
510 disk_write_to_fail = 991;
511 AllocAndReadGptData(handle, &g);
512 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600513 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800514 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
515
516 ResetMocks();
517 disk_write_to_fail = 1023;
518 AllocAndReadGptData(handle, &g);
519 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600520 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800521 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
522
Randall Spangler49cb0d32013-01-29 14:28:16 -0800523}
524
525/**
526 * Trivial invalid calls to LoadKernel()
527 */
528static void InvalidParamsTest(void)
529{
530 ResetMocks();
531 lkp.bytes_per_lba = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600532 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
533 "Bad lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800534
535 ResetMocks();
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800536 lkp.streaming_lba_count = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600537 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
538 "Bad lba count");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800539
540 ResetMocks();
541 lkp.bytes_per_lba = 128*1024;
Simon Glass527ba812013-07-25 08:48:47 -0600542 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
543 "Huge lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800544
545 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800546 disk_read_to_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600547 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
548 "Can't read disk");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800549
550 ResetMocks();
551 gpt_init_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600552 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
553 "Bad GPT");
Randall Spangler4184e622014-10-08 16:41:01 -0700554
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800555 ResetMocks();
556 lkp.gpt_lba_count = 0;
557 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
558 "GPT size = 0");
559
Randall Spangler4184e622014-10-08 16:41:01 -0700560 /* This causes the stream open call to fail */
561 ResetMocks();
562 lkp.disk_handle = NULL;
563 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
564 "Bad disk handle");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800565}
566
Randall Spangler3e9cf902013-02-01 13:31:20 -0800567static void LoadKernelTest(void)
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800568{
Randall Spangler3e9cf902013-02-01 13:31:20 -0800569 uint32_t u;
570
571 ResetMocks();
Randall Spangler4184e622014-10-08 16:41:01 -0700572
573 u = LoadKernel(&lkp, &cparams);
574 TEST_EQ(u, 0, "First kernel good");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800575 TEST_EQ(lkp.partition_number, 1, " part num");
576 TEST_EQ(lkp.bootloader_address, 0xbeadd008, " bootloader addr");
577 TEST_EQ(lkp.bootloader_size, 0x1234, " bootloader size");
578 TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", " guid");
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800579 TEST_EQ(gpt_flag_external, 0, "GPT was internal");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800580 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
581 TEST_EQ(u, 0, " recovery request");
582
583 ResetMocks();
584 mock_parts[1].start = 300;
585 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600586 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two good kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800587 TEST_EQ(lkp.partition_number, 1, " part num");
588 TEST_EQ(mock_part_next, 1, " didn't read second one");
589
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800590 /* Fail if no kernels found */
591 ResetMocks();
592 mock_parts[0].size = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600593 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND, "No kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800594 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
595 TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800596
597 /* Skip kernels which are too small */
598 ResetMocks();
599 mock_parts[0].size = 10;
Simon Glass527ba812013-07-25 08:48:47 -0600600 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Too small");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800601 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
602 TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800603
604 ResetMocks();
605 disk_read_to_fail = 100;
Simon Glass527ba812013-07-25 08:48:47 -0600606 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800607 "Fail reading kernel start");
608
609 ResetMocks();
610 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600611 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800612 "Fail key block sig");
613
614 /* In dev mode, fail if hash is bad too */
615 ResetMocks();
616 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
617 key_block_verify_fail = 2;
Simon Glass527ba812013-07-25 08:48:47 -0600618 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800619 "Fail key block dev hash");
620
Randall Spangler3e9cf902013-02-01 13:31:20 -0800621 /* But just bad sig is ok */
622 ResetMocks();
623 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
624 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600625 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed key block dev sig");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800626
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800627 /* In dev mode and requiring signed kernel, fail if sig is bad */
628 ResetMocks();
629 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
630 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
631 VbNvTeardown(&vnc);
632 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600633 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800634 "Fail key block dev sig");
635
636 /* Check key block flag mismatches */
637 ResetMocks();
638 kbh.key_block_flags =
639 KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600640 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800641 "Key block dev flag mismatch");
642
643 ResetMocks();
644 kbh.key_block_flags =
645 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600646 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800647 "Key block rec flag mismatch");
648
649 ResetMocks();
650 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
651 kbh.key_block_flags =
652 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600653 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800654 "Key block recdev flag mismatch");
655
656 ResetMocks();
657 lkp.boot_flags |= BOOT_FLAG_RECOVERY | BOOT_FLAG_DEVELOPER;
658 kbh.key_block_flags =
659 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600660 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800661 "Key block rec!dev flag mismatch");
662
663 ResetMocks();
664 kbh.data_key.key_version = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600665 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800666 "Key block kernel key rollback");
667
668 ResetMocks();
669 kbh.data_key.key_version = 0x10000;
Simon Glass527ba812013-07-25 08:48:47 -0600670 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800671 "Key block kernel key version too big");
672
Randall Spangler3e9cf902013-02-01 13:31:20 -0800673 ResetMocks();
674 kbh.data_key.key_version = 3;
Simon Glass527ba812013-07-25 08:48:47 -0600675 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key block version roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800676 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
677
678 ResetMocks();
679 kbh.data_key.key_version = 3;
680 mock_parts[1].start = 300;
681 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600682 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two kernels roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800683 TEST_EQ(mock_part_next, 2, " read both");
684 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
685
686 ResetMocks();
687 kbh.data_key.key_version = 1;
688 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600689 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800690
691 ResetMocks();
692 kbh.data_key.key_version = 1;
693 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600694 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800695
696 ResetMocks();
697 mock_data_key = NULL;
Simon Glass527ba812013-07-25 08:48:47 -0600698 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
699 "Bad data key");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800700
701 ResetMocks();
702 preamble_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600703 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
704 "Bad preamble");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800705
706 ResetMocks();
707 kph.kernel_version = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600708 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800709 "Kernel version rollback");
710
Randall Spangler3e9cf902013-02-01 13:31:20 -0800711 ResetMocks();
712 kph.kernel_version = 0;
713 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600714 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800715
716 ResetMocks();
717 kph.kernel_version = 0;
718 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600719 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800720
721 ResetMocks();
722 kph.preamble_size |= 0x07;
Simon Glass527ba812013-07-25 08:48:47 -0600723 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800724 "Kernel body offset");
725
Randall Spangler4184e622014-10-08 16:41:01 -0700726 ResetMocks();
727 kph.preamble_size += 65536;
728 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
729 "Kernel body offset huge");
730
Randall Spangler3e9cf902013-02-01 13:31:20 -0800731 /* Check getting kernel load address from header */
732 ResetMocks();
733 kph.body_load_address = (size_t)kernel_buffer;
734 lkp.kernel_buffer = NULL;
Simon Glass527ba812013-07-25 08:48:47 -0600735 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Get load address from preamble");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800736 TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, " address");
737 /* Size is rounded up to nearest sector */
738 TEST_EQ(lkp.kernel_buffer_size, 70144, " size");
739
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800740 ResetMocks();
741 lkp.kernel_buffer_size = 8192;
Simon Glass527ba812013-07-25 08:48:47 -0600742 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800743 "Kernel too big for buffer");
744
745 ResetMocks();
746 mock_parts[0].size = 130;
Simon Glass527ba812013-07-25 08:48:47 -0600747 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800748 "Kernel too big for partition");
749
Randall Spangler3e9cf902013-02-01 13:31:20 -0800750 ResetMocks();
Randall Spangler4184e622014-10-08 16:41:01 -0700751 kph.body_signature.data_size = 8192;
752 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel tiny");
753
754 ResetMocks();
755 disk_read_to_fail = 228;
Simon Glass527ba812013-07-25 08:48:47 -0600756 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler3e9cf902013-02-01 13:31:20 -0800757 "Fail reading kernel data");
758
759 ResetMocks();
760 verify_data_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600761 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Bad data");
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800762
763 /* Check that EXTERNAL_GPT flag makes it down */
764 ResetMocks();
765 lkp.boot_flags |= BOOT_FLAG_EXTERNAL_GPT;
766 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed external GPT");
767 TEST_EQ(gpt_flag_external, 1, "GPT was external");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800768}
769
Randall Spangler49cb0d32013-01-29 14:28:16 -0800770int main(void)
771{
772 ReadWriteGptTest();
773 InvalidParamsTest();
Randall Spangler3e9cf902013-02-01 13:31:20 -0800774 LoadKernelTest();
Randall Spangler49cb0d32013-01-29 14:28:16 -0800775
Simon Glass25001852013-08-16 02:47:57 -0600776 if (vboot_api_stub_check_memory())
777 return 255;
778
Randall Spangler49cb0d32013-01-29 14:28:16 -0800779 return gTestSuccess ? 0 : 255;
780}