blob: 057e2dd3e1e53f3588fa941081c178495c83e530 [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
Randall Spangler7c3ae422016-05-11 13:50:18 -070013#include "2sysincludes.h"
14#include "2common.h"
15#include "2sha.h"
Randall Spangler49cb0d32013-01-29 14:28:16 -080016#include "cgptlib.h"
Duncan Laurie162f7882014-10-01 09:58:10 -070017#include "cgptlib_internal.h"
Dan Ehrenbergd7da7062015-04-22 11:00:51 -070018#include "crc32.h"
Randall Spangler49cb0d32013-01-29 14:28:16 -080019#include "gbb_header.h"
20#include "gpt.h"
21#include "host_common.h"
22#include "load_kernel_fw.h"
Randall Spangler946abf12016-04-15 14:49:40 -070023#include "rollback_index.h"
Randall Spangler49cb0d32013-01-29 14:28:16 -080024#include "test_common.h"
Randall Spangler13b10972016-10-14 11:04:27 -070025#include "vb2_struct.h"
Randall Spangler49cb0d32013-01-29 14:28:16 -080026#include "vboot_api.h"
27#include "vboot_common.h"
28#include "vboot_kernel.h"
29#include "vboot_nvstorage.h"
30
31#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
32#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
33
Duncan Laurie162f7882014-10-01 09:58:10 -070034#define MOCK_SECTOR_SIZE 512
35#define MOCK_SECTOR_COUNT 1024
36
Randall Spangler5d0a2e72013-01-30 13:19:19 -080037/* Mock kernel partition */
38struct mock_part {
39 uint32_t start;
40 uint32_t size;
41};
42
43/* Partition list; ends with a 0-size partition. */
44#define MOCK_PART_COUNT 8
45static struct mock_part mock_parts[MOCK_PART_COUNT];
46static int mock_part_next;
47
Randall Spangler49cb0d32013-01-29 14:28:16 -080048/* Mock data */
49static char call_log[4096];
Randall Spangler5d0a2e72013-01-30 13:19:19 -080050static uint8_t kernel_buffer[80000];
51static int disk_read_to_fail;
52static int disk_write_to_fail;
Randall Spangler49cb0d32013-01-29 14:28:16 -080053static int gpt_init_fail;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080054static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
55static int preamble_verify_fail;
Randall Spangler3e9cf902013-02-01 13:31:20 -080056static int verify_data_fail;
Randall Spangler13b10972016-10-14 11:04:27 -070057static int unpack_key_fail;
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -080058static int gpt_flag_external;
Randall Spangler49cb0d32013-01-29 14:28:16 -080059
Simon Glass527ba812013-07-25 08:48:47 -060060static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
61static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader*)gbb_data;
Randall Spangler49cb0d32013-01-29 14:28:16 -080062static VbExDiskHandle_t handle;
63static VbNvContext vnc;
64static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
65static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
66static LoadKernelParams lkp;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080067static VbKeyBlockHeader kbh;
68static VbKernelPreambleHeader kph;
Simon Glass527ba812013-07-25 08:48:47 -060069static VbCommonParams cparams;
Randall Spangler946abf12016-04-15 14:49:40 -070070static struct RollbackSpaceFwmp fwmp;
Duncan Laurie162f7882014-10-01 09:58:10 -070071static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
72static GptHeader *mock_gpt_primary =
73 (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
74static GptHeader *mock_gpt_secondary =
75 (GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
Randall Spangler7c3ae422016-05-11 13:50:18 -070076static uint8_t mock_digest[VB2_SHA256_DIGEST_SIZE] = {12, 34, 56, 78};
Duncan Laurie162f7882014-10-01 09:58:10 -070077
78/**
79 * Prepare a valid GPT header that will pass CheckHeader() tests
80 */
81static void SetupGptHeader(GptHeader *h, int is_secondary)
82{
Randall Spangler664096b2016-10-13 16:16:41 -070083 memset(h, '\0', MOCK_SECTOR_SIZE);
Duncan Laurie162f7882014-10-01 09:58:10 -070084
85 /* "EFI PART" */
86 memcpy(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE);
87 h->revision = GPT_HEADER_REVISION;
88 h->size = MIN_SIZE_OF_HEADER;
89
90 /* 16KB: 128 entries of 128 bytes */
91 h->size_of_entry = sizeof(GptEntry);
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -080092 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
Duncan Laurie162f7882014-10-01 09:58:10 -070093
94 /* Set LBA pointers for primary or secondary header */
95 if (is_secondary) {
96 h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
Nam T. Nguyen32004012014-12-12 09:38:35 -080097 h->entries_lba = h->my_lba - CalculateEntriesSectors(h);
Duncan Laurie162f7882014-10-01 09:58:10 -070098 } else {
99 h->my_lba = GPT_PMBR_SECTORS;
100 h->entries_lba = h->my_lba + 1;
101 }
102
Nam T. Nguyen32004012014-12-12 09:38:35 -0800103 h->first_usable_lba = 2 + CalculateEntriesSectors(h);
104 h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h);
Duncan Laurie162f7882014-10-01 09:58:10 -0700105
106 h->header_crc32 = HeaderCrc(h);
107}
Randall Spangler49cb0d32013-01-29 14:28:16 -0800108
109static void ResetCallLog(void)
110{
111 *call_log = 0;
112}
113
114/**
115 * Reset mock data (for use before each test)
116 */
117static void ResetMocks(void)
118{
119 ResetCallLog();
120
Duncan Laurie162f7882014-10-01 09:58:10 -0700121 memset(&mock_disk, 0, sizeof(mock_disk));
122 SetupGptHeader(mock_gpt_primary, 0);
123 SetupGptHeader(mock_gpt_secondary, 1);
124
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800125 disk_read_to_fail = -1;
126 disk_write_to_fail = -1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800127
128 gpt_init_fail = 0;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800129 key_block_verify_fail = 0;
130 preamble_verify_fail = 0;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800131 verify_data_fail = 0;
Randall Spangler13b10972016-10-14 11:04:27 -0700132 unpack_key_fail = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800133
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800134 gpt_flag_external = 0;
135
Han Shen1a113812013-09-03 11:23:30 -0700136 memset(gbb, 0, sizeof(*gbb));
Simon Glass527ba812013-07-25 08:48:47 -0600137 gbb->major_version = GBB_MAJOR_VER;
138 gbb->minor_version = GBB_MINOR_VER;
139 gbb->flags = 0;
140
141 memset(&cparams, '\0', sizeof(cparams));
142 cparams.gbb = gbb;
143 cparams.gbb_data = gbb;
144 cparams.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800145
146 memset(&vnc, 0, sizeof(vnc));
147 VbNvSetup(&vnc);
148 VbNvTeardown(&vnc); /* So CRC gets generated */
149
150 memset(&shared_data, 0, sizeof(shared_data));
151 VbSharedDataInit(shared, sizeof(shared_data));
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800152 shared->kernel_version_tpm = 0x20001;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800153
154 memset(&lkp, 0, sizeof(lkp));
155 lkp.nv_context = &vnc;
156 lkp.shared_data_blob = shared;
Simon Glass527ba812013-07-25 08:48:47 -0600157 lkp.gbb_data = gbb;
158 lkp.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800159 lkp.bytes_per_lba = 512;
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800160 lkp.streaming_lba_count = 1024;
161 lkp.gpt_lba_count = 1024;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800162 lkp.kernel_buffer = kernel_buffer;
163 lkp.kernel_buffer_size = sizeof(kernel_buffer);
Randall Spangler4184e622014-10-08 16:41:01 -0700164 lkp.disk_handle = (VbExDiskHandle_t)1;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800165
166 memset(&kbh, 0, sizeof(kbh));
167 kbh.data_key.key_version = 2;
168 kbh.key_block_flags = -1;
169 kbh.key_block_size = sizeof(kbh);
170
171 memset(&kph, 0, sizeof(kph));
172 kph.kernel_version = 1;
173 kph.preamble_size = 4096 - kbh.key_block_size;
Randall Spangler4184e622014-10-08 16:41:01 -0700174 kph.body_signature.data_size = 70144;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800175 kph.bootloader_address = 0xbeadd008;
176 kph.bootloader_size = 0x1234;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800177
Randall Spangler946abf12016-04-15 14:49:40 -0700178 memset(&fwmp, 0, sizeof(fwmp));
179 memcpy(fwmp.dev_key_hash, mock_digest, sizeof(fwmp.dev_key_hash));
180
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800181 memset(mock_parts, 0, sizeof(mock_parts));
182 mock_parts[0].start = 100;
183 mock_parts[0].size = 150; /* 75 KB */
184 mock_part_next = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800185}
186
187/* Mocks */
188
189VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
190 uint64_t lba_count, void *buffer)
191{
192 LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
193
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800194 if ((int)lba_start == disk_read_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800195 return VBERROR_SIMULATED;
196
Duncan Laurie162f7882014-10-01 09:58:10 -0700197 memcpy(buffer, &mock_disk[lba_start * MOCK_SECTOR_SIZE],
198 lba_count * MOCK_SECTOR_SIZE);
199
Randall Spangler49cb0d32013-01-29 14:28:16 -0800200 return VBERROR_SUCCESS;
201}
202
203VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
204 uint64_t lba_count, const void *buffer)
205{
206 LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
207
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800208 if ((int)lba_start == disk_write_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800209 return VBERROR_SIMULATED;
210
Duncan Laurie162f7882014-10-01 09:58:10 -0700211 memcpy(&mock_disk[lba_start * MOCK_SECTOR_SIZE], buffer,
212 lba_count * MOCK_SECTOR_SIZE);
213
Randall Spangler49cb0d32013-01-29 14:28:16 -0800214 return VBERROR_SUCCESS;
215}
216
217int GptInit(GptData *gpt)
218{
219 return gpt_init_fail;
220}
221
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800222int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
223{
224 struct mock_part *p = mock_parts + mock_part_next;
225
226 if (!p->size)
227 return GPT_ERROR_NO_VALID_KERNEL;
228
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800229 if (gpt->flags & GPT_FLAG_EXTERNAL)
230 gpt_flag_external++;
231
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800232 gpt->current_kernel = mock_part_next;
233 *start_sector = p->start;
234 *size = p->size;
235 mock_part_next++;
236 return GPT_SUCCESS;
237}
238
Randall Spangler3e9cf902013-02-01 13:31:20 -0800239void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
240{
241 static char fake_guid[] = "FakeGuid";
242
243 memcpy(dest, fake_guid, sizeof(fake_guid));
244}
245
Randall Spangler13b10972016-10-14 11:04:27 -0700246int vb2_unpack_key(struct vb2_public_key *key,
247 const uint8_t *buf,
248 uint32_t size)
249{
250 if (--unpack_key_fail == 0)
251 return VB2_ERROR_MOCK;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800252
Randall Spangler13b10972016-10-14 11:04:27 -0700253 return VB2_SUCCESS;
254}
255
256int vb2_verify_keyblock(struct vb2_keyblock *block,
257 uint32_t size,
258 const struct vb2_public_key *key,
259 const struct vb2_workbuf *wb)
260{
261 if (key_block_verify_fail >= 1)
262 return VB2_ERROR_MOCK;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800263
264 /* Use this as an opportunity to override the key block */
265 memcpy((void *)block, &kbh, sizeof(kbh));
Randall Spangler13b10972016-10-14 11:04:27 -0700266 return VB2_SUCCESS;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800267}
268
Randall Spangler13b10972016-10-14 11:04:27 -0700269int vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
270 uint32_t size,
271 const struct vb2_workbuf *wb)
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800272{
Randall Spangler13b10972016-10-14 11:04:27 -0700273 if (key_block_verify_fail >= 2)
274 return VB2_ERROR_MOCK;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800275
Randall Spangler13b10972016-10-14 11:04:27 -0700276 /* Use this as an opportunity to override the key block */
277 memcpy((void *)block, &kbh, sizeof(kbh));
278 return VB2_SUCCESS;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800279}
280
Randall Spangler13b10972016-10-14 11:04:27 -0700281int vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
282 uint32_t size,
283 const struct vb2_public_key *key,
284 const struct vb2_workbuf *wb)
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800285{
286 if (preamble_verify_fail)
Randall Spangler13b10972016-10-14 11:04:27 -0700287 return VB2_ERROR_MOCK;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800288
289 /* Use this as an opportunity to override the preamble */
290 memcpy((void *)preamble, &kph, sizeof(kph));
Randall Spangler13b10972016-10-14 11:04:27 -0700291 return VB2_SUCCESS;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800292}
293
Randall Spangler13b10972016-10-14 11:04:27 -0700294int vb2_verify_data(const uint8_t *data,
295 uint32_t size,
296 struct vb2_signature *sig,
297 const struct vb2_public_key *key,
298 const struct vb2_workbuf *wb)
Randall Spangler3e9cf902013-02-01 13:31:20 -0800299{
300 if (verify_data_fail)
Randall Spangler13b10972016-10-14 11:04:27 -0700301 return VB2_ERROR_MOCK;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800302
Randall Spangler13b10972016-10-14 11:04:27 -0700303 return VB2_SUCCESS;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800304}
305
Randall Spangler7c3ae422016-05-11 13:50:18 -0700306int vb2_digest_buffer(const uint8_t *buf,
307 uint32_t size,
308 enum vb2_hash_algorithm hash_alg,
309 uint8_t *digest,
310 uint32_t digest_size)
Randall Spangler946abf12016-04-15 14:49:40 -0700311{
Randall Spangler664096b2016-10-13 16:16:41 -0700312 memcpy(digest, mock_digest, sizeof(mock_digest));
Randall Spangler7c3ae422016-05-11 13:50:18 -0700313 return VB2_SUCCESS;
Randall Spangler946abf12016-04-15 14:49:40 -0700314}
Randall Spangler3e9cf902013-02-01 13:31:20 -0800315
Randall Spangler49cb0d32013-01-29 14:28:16 -0800316/**
317 * Test reading/writing GPT
318 */
319static void ReadWriteGptTest(void)
320{
321 GptData g;
322 GptHeader *h;
323
Duncan Laurie162f7882014-10-01 09:58:10 -0700324 g.sector_bytes = MOCK_SECTOR_SIZE;
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800325 g.streaming_drive_sectors = g.gpt_drive_sectors = MOCK_SECTOR_COUNT;
Duncan Laurie162f7882014-10-01 09:58:10 -0700326 g.valid_headers = g.valid_entries = MASK_BOTH;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800327
328 ResetMocks();
329 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
330 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
331 "VbExDiskRead(h, 2, 32)\n"
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700332 "VbExDiskRead(h, 1023, 1)\n"
333 "VbExDiskRead(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800334 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600335 /*
336 * Valgrind complains about access to uninitialized memory here, so
337 * zero the primary header before each test.
338 */
Randall Spangler664096b2016-10-13 16:16:41 -0700339 memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800340 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
341 TEST_CALLS("");
342
Duncan Laurie162f7882014-10-01 09:58:10 -0700343 /*
344 * Invalidate primary GPT header,
345 * check that AllocAndReadGptData still succeeds
346 */
347 ResetMocks();
Randall Spangler664096b2016-10-13 16:16:41 -0700348 memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
Duncan Laurie162f7882014-10-01 09:58:10 -0700349 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
350 "AllocAndRead primary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800351 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
352 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800353 1, "Primary header is invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800354 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
355 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800356 0, "Secondary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700357 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
358 "VbExDiskRead(h, 1023, 1)\n"
359 "VbExDiskRead(h, 991, 32)\n");
360 WriteAndFreeGptData(handle, &g);
361
362 /*
363 * Invalidate secondary GPT header,
364 * check that AllocAndReadGptData still succeeds
365 */
366 ResetMocks();
Randall Spangler664096b2016-10-13 16:16:41 -0700367 memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
Duncan Laurie162f7882014-10-01 09:58:10 -0700368 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
369 "AllocAndRead secondary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800370 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
371 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800372 0, "Primary header is valid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800373 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
374 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800375 1, "Secondary header is invalid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700376 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
377 "VbExDiskRead(h, 2, 32)\n"
378 "VbExDiskRead(h, 1023, 1)\n");
379 WriteAndFreeGptData(handle, &g);
380
381 /*
382 * Invalidate primary AND secondary GPT header,
383 * check that AllocAndReadGptData fails.
384 */
385 ResetMocks();
Randall Spangler664096b2016-10-13 16:16:41 -0700386 memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
387 memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
Duncan Laurie162f7882014-10-01 09:58:10 -0700388 TEST_EQ(AllocAndReadGptData(handle, &g), 1,
389 "AllocAndRead primary and secondary invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800390 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
391 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800392 1, "Primary header is invalid");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800393 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
394 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800395 1, "Secondary header is invalid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700396 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
397 "VbExDiskRead(h, 1023, 1)\n");
398 WriteAndFreeGptData(handle, &g);
399
400 /*
401 * Invalidate primary GPT header and check that it is
402 * repaired by GptRepair().
403 *
404 * This would normally be called by LoadKernel()->GptInit()
405 * but this callback is mocked in these tests.
406 */
407 ResetMocks();
Randall Spangler664096b2016-10-13 16:16:41 -0700408 memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
Duncan Laurie162f7882014-10-01 09:58:10 -0700409 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
410 "Fix Primary GPT: AllocAndRead");
411 /* Call GptRepair() with input indicating secondary GPT is valid */
412 g.valid_headers = g.valid_entries = MASK_SECONDARY;
413 GptRepair(&g);
414 TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
415 "Fix Primary GPT: WriteAndFreeGptData");
416 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
417 "VbExDiskRead(h, 1023, 1)\n"
418 "VbExDiskRead(h, 991, 32)\n"
419 "VbExDiskWrite(h, 1, 1)\n"
420 "VbExDiskWrite(h, 2, 32)\n");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800421 TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
422 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800423 0, "Fix Primary GPT: Primary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700424
425 /*
426 * Invalidate secondary GPT header and check that it can be
427 * repaired by GptRepair().
428 *
429 * This would normally be called by LoadKernel()->GptInit()
430 * but this callback is mocked in these tests.
431 */
432 ResetMocks();
Randall Spangler664096b2016-10-13 16:16:41 -0700433 memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
Duncan Laurie162f7882014-10-01 09:58:10 -0700434 TEST_EQ(AllocAndReadGptData(handle, &g), 0,
435 "Fix Secondary GPT: AllocAndRead");
436 /* Call GptRepair() with input indicating primary GPT is valid */
437 g.valid_headers = g.valid_entries = MASK_PRIMARY;
438 GptRepair(&g);
439 TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
440 "Fix Secondary GPT: WriteAndFreeGptData");
441 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
442 "VbExDiskRead(h, 2, 32)\n"
443 "VbExDiskRead(h, 1023, 1)\n"
444 "VbExDiskWrite(h, 1023, 1)\n"
445 "VbExDiskWrite(h, 991, 32)\n");
Dan Ehrenbergb3d38f52014-12-09 13:42:15 -0800446 TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
447 g.gpt_drive_sectors, 0),
Dan Ehrenberga524a3a2014-11-06 16:22:24 -0800448 0, "Fix Secondary GPT: Secondary header is valid");
Duncan Laurie162f7882014-10-01 09:58:10 -0700449
Randall Spangler49cb0d32013-01-29 14:28:16 -0800450 /* Data which is changed is written */
451 ResetMocks();
452 AllocAndReadGptData(handle, &g);
453 g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
454 ResetCallLog();
Randall Spangler664096b2016-10-13 16:16:41 -0700455 memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700456 h = (GptHeader*)g.primary_header;
457 h->entries_lba = 2;
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -0800458 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
459 h->size_of_entry = sizeof(GptEntry);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800460 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
461 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
462 "VbExDiskWrite(h, 2, 32)\n");
463
464 /* Data which is changed is written */
465 ResetMocks();
466 AllocAndReadGptData(handle, &g);
467 g.modified = -1;
468 ResetCallLog();
Randall Spangler664096b2016-10-13 16:16:41 -0700469 memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700470 h = (GptHeader*)g.primary_header;
471 h->entries_lba = 2;
Dan Ehrenbergf3f7fca2015-01-02 14:39:38 -0800472 h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
473 h->size_of_entry = sizeof(GptEntry);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700474 h = (GptHeader*)g.secondary_header;
475 h->entries_lba = 991;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800476 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
477 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
478 "VbExDiskWrite(h, 2, 32)\n"
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700479 "VbExDiskWrite(h, 1023, 1)\n"
480 "VbExDiskWrite(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800481
482 /* If legacy signature, don't modify GPT header/entries 1 */
483 ResetMocks();
484 AllocAndReadGptData(handle, &g);
485 h = (GptHeader *)g.primary_header;
486 memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
487 g.modified = -1;
488 ResetCallLog();
489 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700490 TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
491 "VbExDiskWrite(h, 991, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800492
493 /* Error reading */
494 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800495 disk_read_to_fail = 1;
Dan Ehrenbergd7da7062015-04-22 11:00:51 -0700496 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
497 g.valid_headers = g.valid_entries = MASK_SECONDARY;
498 GptRepair(&g);
499 ResetCallLog();
500 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
501 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
502 "VbExDiskWrite(h, 2, 32)\n");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800503
Randall Spangler3e9cf902013-02-01 13:31:20 -0800504 ResetMocks();
505 disk_read_to_fail = 2;
Dan Ehrenbergd7da7062015-04-22 11:00:51 -0700506 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
507 g.valid_headers = MASK_BOTH;
508 g.valid_entries = MASK_SECONDARY;
509 GptRepair(&g);
510 ResetCallLog();
511 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
512 TEST_CALLS("VbExDiskWrite(h, 2, 32)\n");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800513
514 ResetMocks();
515 disk_read_to_fail = 991;
Dan Ehrenbergd7da7062015-04-22 11:00:51 -0700516 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
517 g.valid_headers = MASK_BOTH;
518 g.valid_entries = MASK_PRIMARY;
519 GptRepair(&g);
520 ResetCallLog();
521 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
522 TEST_CALLS("VbExDiskWrite(h, 991, 32)\n");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800523
524 ResetMocks();
525 disk_read_to_fail = 1023;
Dan Ehrenbergd7da7062015-04-22 11:00:51 -0700526 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
527 g.valid_headers = g.valid_entries = MASK_PRIMARY;
528 GptRepair(&g);
529 ResetCallLog();
530 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 2");
531 TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
532 "VbExDiskWrite(h, 991, 32)\n");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800533
Randall Spangler49cb0d32013-01-29 14:28:16 -0800534 /* Error writing */
535 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800536 disk_write_to_fail = 1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800537 AllocAndReadGptData(handle, &g);
538 g.modified = -1;
Randall Spangler664096b2016-10-13 16:16:41 -0700539 memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800540 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800541
542 ResetMocks();
543 disk_write_to_fail = 2;
544 AllocAndReadGptData(handle, &g);
545 g.modified = -1;
Randall Spangler664096b2016-10-13 16:16:41 -0700546 memset(g.primary_header, '\0', g.sector_bytes);
Nam T. Nguyena2d72f72014-08-22 15:01:38 -0700547 h = (GptHeader*)g.primary_header;
548 h->entries_lba = 2;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800549 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
550
551 ResetMocks();
552 disk_write_to_fail = 991;
553 AllocAndReadGptData(handle, &g);
554 g.modified = -1;
Randall Spangler664096b2016-10-13 16:16:41 -0700555 memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800556 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
557
558 ResetMocks();
559 disk_write_to_fail = 1023;
560 AllocAndReadGptData(handle, &g);
561 g.modified = -1;
Randall Spangler664096b2016-10-13 16:16:41 -0700562 memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800563 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
564
Randall Spangler49cb0d32013-01-29 14:28:16 -0800565}
566
567/**
568 * Trivial invalid calls to LoadKernel()
569 */
570static void InvalidParamsTest(void)
571{
572 ResetMocks();
573 lkp.bytes_per_lba = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600574 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
575 "Bad lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800576
577 ResetMocks();
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800578 lkp.streaming_lba_count = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600579 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
580 "Bad lba count");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800581
582 ResetMocks();
583 lkp.bytes_per_lba = 128*1024;
Simon Glass527ba812013-07-25 08:48:47 -0600584 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
585 "Huge lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800586
587 ResetMocks();
Randall Spangler49cb0d32013-01-29 14:28:16 -0800588 gpt_init_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600589 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
590 "Bad GPT");
Randall Spangler4184e622014-10-08 16:41:01 -0700591
592 /* This causes the stream open call to fail */
593 ResetMocks();
594 lkp.disk_handle = NULL;
595 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
596 "Bad disk handle");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800597}
598
Randall Spangler3e9cf902013-02-01 13:31:20 -0800599static void LoadKernelTest(void)
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800600{
Randall Spangler3e9cf902013-02-01 13:31:20 -0800601 uint32_t u;
602
603 ResetMocks();
Randall Spangler4184e622014-10-08 16:41:01 -0700604
605 u = LoadKernel(&lkp, &cparams);
606 TEST_EQ(u, 0, "First kernel good");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800607 TEST_EQ(lkp.partition_number, 1, " part num");
608 TEST_EQ(lkp.bootloader_address, 0xbeadd008, " bootloader addr");
609 TEST_EQ(lkp.bootloader_size, 0x1234, " bootloader size");
610 TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", " guid");
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800611 TEST_EQ(gpt_flag_external, 0, "GPT was internal");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800612 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
613 TEST_EQ(u, 0, " recovery request");
614
615 ResetMocks();
616 mock_parts[1].start = 300;
617 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600618 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two good kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800619 TEST_EQ(lkp.partition_number, 1, " part num");
620 TEST_EQ(mock_part_next, 1, " didn't read second one");
621
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800622 /* Fail if no kernels found */
623 ResetMocks();
624 mock_parts[0].size = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600625 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND, "No kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800626 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
627 TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800628
629 /* Skip kernels which are too small */
630 ResetMocks();
631 mock_parts[0].size = 10;
Simon Glass527ba812013-07-25 08:48:47 -0600632 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Too small");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800633 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
634 TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800635
636 ResetMocks();
637 disk_read_to_fail = 100;
Simon Glass527ba812013-07-25 08:48:47 -0600638 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800639 "Fail reading kernel start");
640
641 ResetMocks();
642 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600643 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800644 "Fail key block sig");
645
646 /* In dev mode, fail if hash is bad too */
647 ResetMocks();
648 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
649 key_block_verify_fail = 2;
Simon Glass527ba812013-07-25 08:48:47 -0600650 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800651 "Fail key block dev hash");
652
Randall Spangler3e9cf902013-02-01 13:31:20 -0800653 /* But just bad sig is ok */
654 ResetMocks();
655 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
656 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600657 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed key block dev sig");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800658
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800659 /* In dev mode and requiring signed kernel, fail if sig is bad */
660 ResetMocks();
661 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
662 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
663 VbNvTeardown(&vnc);
664 key_block_verify_fail = 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 "Fail key block dev sig");
667
Randall Spangler946abf12016-04-15 14:49:40 -0700668 ResetMocks();
669 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
670 lkp.fwmp = &fwmp;
671 fwmp.flags |= FWMP_DEV_ENABLE_OFFICIAL_ONLY;
672 key_block_verify_fail = 1;
673 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
674 "Fail key block dev sig fwmp");
675
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800676 /* Check key block flag mismatches */
677 ResetMocks();
678 kbh.key_block_flags =
679 KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600680 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800681 "Key block dev flag mismatch");
682
683 ResetMocks();
684 kbh.key_block_flags =
685 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600686 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800687 "Key block rec flag mismatch");
688
689 ResetMocks();
690 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
691 kbh.key_block_flags =
692 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600693 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800694 "Key block recdev flag mismatch");
695
696 ResetMocks();
697 lkp.boot_flags |= BOOT_FLAG_RECOVERY | BOOT_FLAG_DEVELOPER;
698 kbh.key_block_flags =
699 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600700 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800701 "Key block rec!dev flag mismatch");
702
703 ResetMocks();
704 kbh.data_key.key_version = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600705 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800706 "Key block kernel key rollback");
707
708 ResetMocks();
709 kbh.data_key.key_version = 0x10000;
Simon Glass527ba812013-07-25 08:48:47 -0600710 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800711 "Key block kernel key version too big");
712
Randall Spangler3e9cf902013-02-01 13:31:20 -0800713 ResetMocks();
714 kbh.data_key.key_version = 3;
Simon Glass527ba812013-07-25 08:48:47 -0600715 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key block version roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800716 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
717
718 ResetMocks();
719 kbh.data_key.key_version = 3;
720 mock_parts[1].start = 300;
721 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600722 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two kernels roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800723 TEST_EQ(mock_part_next, 2, " read both");
724 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
725
726 ResetMocks();
727 kbh.data_key.key_version = 1;
728 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600729 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800730
731 ResetMocks();
732 kbh.data_key.key_version = 1;
733 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600734 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800735
736 ResetMocks();
Randall Spangler13b10972016-10-14 11:04:27 -0700737 unpack_key_fail = 2;
Simon Glass527ba812013-07-25 08:48:47 -0600738 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
739 "Bad data key");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800740
741 ResetMocks();
742 preamble_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600743 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
744 "Bad preamble");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800745
746 ResetMocks();
747 kph.kernel_version = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600748 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800749 "Kernel version rollback");
750
Randall Spangler3e9cf902013-02-01 13:31:20 -0800751 ResetMocks();
752 kph.kernel_version = 0;
753 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600754 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800755
756 ResetMocks();
757 kph.kernel_version = 0;
758 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600759 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800760
Randall Spangler946abf12016-04-15 14:49:40 -0700761 /* Check developer key hash - bad */
762 ResetMocks();
763 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
764 lkp.fwmp = &fwmp;
765 fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
766 fwmp.dev_key_hash[0]++;
767 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
768 "Fail key block dev fwmp hash");
769
770 /* Check developer key hash - good */
771 ResetMocks();
772 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
773 lkp.fwmp = &fwmp;
774 fwmp.flags |= FWMP_DEV_USE_KEY_HASH;
775 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Good key block dev fwmp hash");
776
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800777 ResetMocks();
778 kph.preamble_size |= 0x07;
Simon Glass527ba812013-07-25 08:48:47 -0600779 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800780 "Kernel body offset");
781
Randall Spangler4184e622014-10-08 16:41:01 -0700782 ResetMocks();
783 kph.preamble_size += 65536;
784 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
785 "Kernel body offset huge");
786
Randall Spangler3e9cf902013-02-01 13:31:20 -0800787 /* Check getting kernel load address from header */
788 ResetMocks();
789 kph.body_load_address = (size_t)kernel_buffer;
790 lkp.kernel_buffer = NULL;
Simon Glass527ba812013-07-25 08:48:47 -0600791 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Get load address from preamble");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800792 TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, " address");
793 /* Size is rounded up to nearest sector */
794 TEST_EQ(lkp.kernel_buffer_size, 70144, " size");
795
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800796 ResetMocks();
797 lkp.kernel_buffer_size = 8192;
Simon Glass527ba812013-07-25 08:48:47 -0600798 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800799 "Kernel too big for buffer");
800
801 ResetMocks();
802 mock_parts[0].size = 130;
Simon Glass527ba812013-07-25 08:48:47 -0600803 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800804 "Kernel too big for partition");
805
Randall Spangler3e9cf902013-02-01 13:31:20 -0800806 ResetMocks();
Randall Spangler4184e622014-10-08 16:41:01 -0700807 kph.body_signature.data_size = 8192;
808 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel tiny");
809
810 ResetMocks();
811 disk_read_to_fail = 228;
Simon Glass527ba812013-07-25 08:48:47 -0600812 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler3e9cf902013-02-01 13:31:20 -0800813 "Fail reading kernel data");
814
815 ResetMocks();
816 verify_data_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600817 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Bad data");
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800818
819 /* Check that EXTERNAL_GPT flag makes it down */
820 ResetMocks();
821 lkp.boot_flags |= BOOT_FLAG_EXTERNAL_GPT;
822 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed external GPT");
823 TEST_EQ(gpt_flag_external, 1, "GPT was external");
Dan Ehrenbergd7da7062015-04-22 11:00:51 -0700824
825 /* Check recovery from unreadble primary GPT */
826 ResetMocks();
827 disk_read_to_fail = 1;
828 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Can't read disk");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800829}
830
Randall Spangler49cb0d32013-01-29 14:28:16 -0800831int main(void)
832{
833 ReadWriteGptTest();
834 InvalidParamsTest();
Randall Spangler3e9cf902013-02-01 13:31:20 -0800835 LoadKernelTest();
Randall Spangler49cb0d32013-01-29 14:28:16 -0800836
Randall Spangler49cb0d32013-01-29 14:28:16 -0800837 return gTestSuccess ? 0 : 255;
838}