blob: ee164ceac080d8a87fd5d718d62d0e80655a90e3 [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"
14#include "gbb_header.h"
15#include "gpt.h"
16#include "host_common.h"
17#include "load_kernel_fw.h"
18#include "test_common.h"
19#include "vboot_api.h"
20#include "vboot_common.h"
21#include "vboot_kernel.h"
22#include "vboot_nvstorage.h"
23
24#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
25#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
26
Randall Spangler5d0a2e72013-01-30 13:19:19 -080027/* Mock kernel partition */
28struct mock_part {
29 uint32_t start;
30 uint32_t size;
31};
32
33/* Partition list; ends with a 0-size partition. */
34#define MOCK_PART_COUNT 8
35static struct mock_part mock_parts[MOCK_PART_COUNT];
36static int mock_part_next;
37
Randall Spangler49cb0d32013-01-29 14:28:16 -080038/* Mock data */
39static char call_log[4096];
Randall Spangler5d0a2e72013-01-30 13:19:19 -080040static uint8_t kernel_buffer[80000];
41static int disk_read_to_fail;
42static int disk_write_to_fail;
Randall Spangler49cb0d32013-01-29 14:28:16 -080043static int gpt_init_fail;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080044static int key_block_verify_fail; /* 0=ok, 1=sig, 2=hash */
45static int preamble_verify_fail;
Randall Spangler3e9cf902013-02-01 13:31:20 -080046static int verify_data_fail;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080047static RSAPublicKey *mock_data_key;
48static int mock_data_key_allocated;
Randall Spangler49cb0d32013-01-29 14:28:16 -080049
Simon Glass527ba812013-07-25 08:48:47 -060050static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
51static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader*)gbb_data;
Randall Spangler49cb0d32013-01-29 14:28:16 -080052static VbExDiskHandle_t handle;
53static VbNvContext vnc;
54static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
55static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
56static LoadKernelParams lkp;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080057static VbKeyBlockHeader kbh;
58static VbKernelPreambleHeader kph;
Simon Glass527ba812013-07-25 08:48:47 -060059static VbCommonParams cparams;
Randall Spangler49cb0d32013-01-29 14:28:16 -080060
61static void ResetCallLog(void)
62{
63 *call_log = 0;
64}
65
66/**
67 * Reset mock data (for use before each test)
68 */
69static void ResetMocks(void)
70{
71 ResetCallLog();
72
Randall Spangler5d0a2e72013-01-30 13:19:19 -080073 disk_read_to_fail = -1;
74 disk_write_to_fail = -1;
Randall Spangler49cb0d32013-01-29 14:28:16 -080075
76 gpt_init_fail = 0;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080077 key_block_verify_fail = 0;
78 preamble_verify_fail = 0;
Randall Spangler3e9cf902013-02-01 13:31:20 -080079 verify_data_fail = 0;
Randall Spangler5d0a2e72013-01-30 13:19:19 -080080
81 mock_data_key = (RSAPublicKey *)"TestDataKey";
82 mock_data_key_allocated = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -080083
Han Shen1a113812013-09-03 11:23:30 -070084 memset(gbb, 0, sizeof(*gbb));
Simon Glass527ba812013-07-25 08:48:47 -060085 gbb->major_version = GBB_MAJOR_VER;
86 gbb->minor_version = GBB_MINOR_VER;
87 gbb->flags = 0;
88
89 memset(&cparams, '\0', sizeof(cparams));
90 cparams.gbb = gbb;
91 cparams.gbb_data = gbb;
92 cparams.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -080093
94 memset(&vnc, 0, sizeof(vnc));
95 VbNvSetup(&vnc);
96 VbNvTeardown(&vnc); /* So CRC gets generated */
97
98 memset(&shared_data, 0, sizeof(shared_data));
99 VbSharedDataInit(shared, sizeof(shared_data));
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800100 shared->kernel_version_tpm = 0x20001;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800101
102 memset(&lkp, 0, sizeof(lkp));
103 lkp.nv_context = &vnc;
104 lkp.shared_data_blob = shared;
Simon Glass527ba812013-07-25 08:48:47 -0600105 lkp.gbb_data = gbb;
106 lkp.gbb_size = sizeof(gbb_data);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800107 lkp.bytes_per_lba = 512;
108 lkp.ending_lba = 1023;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800109 lkp.kernel_buffer = kernel_buffer;
110 lkp.kernel_buffer_size = sizeof(kernel_buffer);
111
112 memset(&kbh, 0, sizeof(kbh));
113 kbh.data_key.key_version = 2;
114 kbh.key_block_flags = -1;
115 kbh.key_block_size = sizeof(kbh);
116
117 memset(&kph, 0, sizeof(kph));
118 kph.kernel_version = 1;
119 kph.preamble_size = 4096 - kbh.key_block_size;
120 kph.body_signature.data_size = 70000;
Randall Spangler3e9cf902013-02-01 13:31:20 -0800121 kph.bootloader_address = 0xbeadd008;
122 kph.bootloader_size = 0x1234;
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800123
124 memset(mock_parts, 0, sizeof(mock_parts));
125 mock_parts[0].start = 100;
126 mock_parts[0].size = 150; /* 75 KB */
127 mock_part_next = 0;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800128}
129
130/* Mocks */
131
132VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
133 uint64_t lba_count, void *buffer)
134{
135 LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
136
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800137 if ((int)lba_start == disk_read_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800138 return VBERROR_SIMULATED;
139
Simon Glass527ba812013-07-25 08:48:47 -0600140 /* Keep valgrind happy */
141 Memset(buffer, '\0', lba_count);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800142 return VBERROR_SUCCESS;
143}
144
145VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
146 uint64_t lba_count, const void *buffer)
147{
148 LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
149
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800150 if ((int)lba_start == disk_write_to_fail)
Randall Spangler49cb0d32013-01-29 14:28:16 -0800151 return VBERROR_SIMULATED;
152
153 return VBERROR_SUCCESS;
154}
155
156int GptInit(GptData *gpt)
157{
158 return gpt_init_fail;
159}
160
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800161int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
162{
163 struct mock_part *p = mock_parts + mock_part_next;
164
165 if (!p->size)
166 return GPT_ERROR_NO_VALID_KERNEL;
167
168 gpt->current_kernel = mock_part_next;
169 *start_sector = p->start;
170 *size = p->size;
171 mock_part_next++;
172 return GPT_SUCCESS;
173}
174
Randall Spangler3e9cf902013-02-01 13:31:20 -0800175void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
176{
177 static char fake_guid[] = "FakeGuid";
178
179 memcpy(dest, fake_guid, sizeof(fake_guid));
180}
181
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800182int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
183 const VbPublicKey *key, int hash_only) {
184
185 if (hash_only && key_block_verify_fail >= 2)
186 return VBERROR_SIMULATED;
187 else if (!hash_only && key_block_verify_fail >= 1)
188 return VBERROR_SIMULATED;
189
190 /* Use this as an opportunity to override the key block */
191 memcpy((void *)block, &kbh, sizeof(kbh));
192 return VBERROR_SUCCESS;
193}
194
195RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
196{
197 TEST_EQ(mock_data_key_allocated, 0, " mock data key not allocated");
198
199 if (mock_data_key)
200 mock_data_key_allocated++;
201
202 return mock_data_key;
203}
204
205void RSAPublicKeyFree(RSAPublicKey* key)
206{
207 TEST_EQ(mock_data_key_allocated, 1, " mock data key allocated");
208 TEST_PTR_EQ(key, mock_data_key, " data key ptr");
209 mock_data_key_allocated--;
210}
211
212int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
213 uint64_t size, const RSAPublicKey *key)
214{
215 if (preamble_verify_fail)
216 return VBERROR_SIMULATED;
217
218 /* Use this as an opportunity to override the preamble */
219 memcpy((void *)preamble, &kph, sizeof(kph));
220 return VBERROR_SUCCESS;
221}
222
Randall Spangler3e9cf902013-02-01 13:31:20 -0800223int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
224 const RSAPublicKey *key)
225{
226 if (verify_data_fail)
227 return VBERROR_SIMULATED;
228
229 return VBERROR_SUCCESS;
230}
231
232
Randall Spangler49cb0d32013-01-29 14:28:16 -0800233/**
234 * Test reading/writing GPT
235 */
236static void ReadWriteGptTest(void)
237{
238 GptData g;
239 GptHeader *h;
240
241 g.sector_bytes = 512;
242 g.drive_sectors = 1024;
243
244 ResetMocks();
245 TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
246 TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
247 "VbExDiskRead(h, 2, 32)\n"
248 "VbExDiskRead(h, 991, 32)\n"
249 "VbExDiskRead(h, 1023, 1)\n");
250 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600251 /*
252 * Valgrind complains about access to uninitialized memory here, so
253 * zero the primary header before each test.
254 */
255 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800256 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
257 TEST_CALLS("");
258
259 /* Data which is changed is written */
260 ResetMocks();
261 AllocAndReadGptData(handle, &g);
262 g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
263 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600264 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800265 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
266 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
267 "VbExDiskWrite(h, 2, 32)\n");
268
269 /* Data which is changed is written */
270 ResetMocks();
271 AllocAndReadGptData(handle, &g);
272 g.modified = -1;
273 ResetCallLog();
Simon Glass527ba812013-07-25 08:48:47 -0600274 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800275 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
276 TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
277 "VbExDiskWrite(h, 2, 32)\n"
278 "VbExDiskWrite(h, 991, 32)\n"
279 "VbExDiskWrite(h, 1023, 1)\n");
280
281 /* If legacy signature, don't modify GPT header/entries 1 */
282 ResetMocks();
283 AllocAndReadGptData(handle, &g);
284 h = (GptHeader *)g.primary_header;
285 memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
286 g.modified = -1;
287 ResetCallLog();
288 TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
289 TEST_CALLS("VbExDiskWrite(h, 991, 32)\n"
290 "VbExDiskWrite(h, 1023, 1)\n");
291
292 /* Error reading */
293 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800294 disk_read_to_fail = 1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800295 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600296 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800297 WriteAndFreeGptData(handle, &g);
298
Randall Spangler3e9cf902013-02-01 13:31:20 -0800299 ResetMocks();
300 disk_read_to_fail = 2;
301 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600302 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800303 WriteAndFreeGptData(handle, &g);
304
305 ResetMocks();
306 disk_read_to_fail = 991;
307 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600308 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800309 WriteAndFreeGptData(handle, &g);
310
311 ResetMocks();
312 disk_read_to_fail = 1023;
313 TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
Simon Glass527ba812013-07-25 08:48:47 -0600314 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800315 WriteAndFreeGptData(handle, &g);
316
Randall Spangler49cb0d32013-01-29 14:28:16 -0800317 /* Error writing */
318 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800319 disk_write_to_fail = 1;
Randall Spangler49cb0d32013-01-29 14:28:16 -0800320 AllocAndReadGptData(handle, &g);
321 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600322 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler49cb0d32013-01-29 14:28:16 -0800323 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800324
325 ResetMocks();
326 disk_write_to_fail = 2;
327 AllocAndReadGptData(handle, &g);
328 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600329 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800330 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
331
332 ResetMocks();
333 disk_write_to_fail = 991;
334 AllocAndReadGptData(handle, &g);
335 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600336 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800337 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
338
339 ResetMocks();
340 disk_write_to_fail = 1023;
341 AllocAndReadGptData(handle, &g);
342 g.modified = -1;
Simon Glass527ba812013-07-25 08:48:47 -0600343 Memset(g.primary_header, '\0', g.sector_bytes);
Randall Spangler3e9cf902013-02-01 13:31:20 -0800344 TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
345
Randall Spangler49cb0d32013-01-29 14:28:16 -0800346}
347
348/**
349 * Trivial invalid calls to LoadKernel()
350 */
351static void InvalidParamsTest(void)
352{
353 ResetMocks();
354 lkp.bytes_per_lba = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600355 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
356 "Bad lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800357
358 ResetMocks();
359 lkp.ending_lba = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600360 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
361 "Bad lba count");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800362
363 ResetMocks();
364 lkp.bytes_per_lba = 128*1024;
Simon Glass527ba812013-07-25 08:48:47 -0600365 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
366 "Huge lba size");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800367
368 ResetMocks();
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800369 disk_read_to_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600370 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
371 "Can't read disk");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800372
373 ResetMocks();
374 gpt_init_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600375 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
376 "Bad GPT");
Randall Spangler49cb0d32013-01-29 14:28:16 -0800377}
378
Randall Spangler3e9cf902013-02-01 13:31:20 -0800379static void LoadKernelTest(void)
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800380{
Randall Spangler3e9cf902013-02-01 13:31:20 -0800381 uint32_t u;
382
383 ResetMocks();
Simon Glass527ba812013-07-25 08:48:47 -0600384 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "First kernel good");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800385 TEST_EQ(lkp.partition_number, 1, " part num");
386 TEST_EQ(lkp.bootloader_address, 0xbeadd008, " bootloader addr");
387 TEST_EQ(lkp.bootloader_size, 0x1234, " bootloader size");
388 TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", " guid");
389 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
390 TEST_EQ(u, 0, " recovery request");
391
392 ResetMocks();
393 mock_parts[1].start = 300;
394 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600395 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two good kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800396 TEST_EQ(lkp.partition_number, 1, " part num");
397 TEST_EQ(mock_part_next, 1, " didn't read second one");
398
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800399 /* Fail if no kernels found */
400 ResetMocks();
401 mock_parts[0].size = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600402 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND, "No kernels");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800403 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
404 TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800405
406 /* Skip kernels which are too small */
407 ResetMocks();
408 mock_parts[0].size = 10;
Simon Glass527ba812013-07-25 08:48:47 -0600409 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Too small");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800410 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
411 TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, " recovery request");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800412
413 ResetMocks();
414 disk_read_to_fail = 100;
Simon Glass527ba812013-07-25 08:48:47 -0600415 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800416 "Fail reading kernel start");
417
418 ResetMocks();
419 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600420 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800421 "Fail key block sig");
422
423 /* In dev mode, fail if hash is bad too */
424 ResetMocks();
425 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
426 key_block_verify_fail = 2;
Simon Glass527ba812013-07-25 08:48:47 -0600427 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800428 "Fail key block dev hash");
429
Randall Spangler3e9cf902013-02-01 13:31:20 -0800430 /* But just bad sig is ok */
431 ResetMocks();
432 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
433 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600434 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed key block dev sig");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800435
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800436 /* In dev mode and requiring signed kernel, fail if sig is bad */
437 ResetMocks();
438 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
439 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
440 VbNvTeardown(&vnc);
441 key_block_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600442 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800443 "Fail key block dev sig");
444
445 /* Check key block flag mismatches */
446 ResetMocks();
447 kbh.key_block_flags =
448 KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600449 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800450 "Key block dev flag mismatch");
451
452 ResetMocks();
453 kbh.key_block_flags =
454 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600455 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800456 "Key block rec flag mismatch");
457
458 ResetMocks();
459 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
460 kbh.key_block_flags =
461 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_1;
Simon Glass527ba812013-07-25 08:48:47 -0600462 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800463 "Key block recdev flag mismatch");
464
465 ResetMocks();
466 lkp.boot_flags |= BOOT_FLAG_RECOVERY | BOOT_FLAG_DEVELOPER;
467 kbh.key_block_flags =
468 KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
Simon Glass527ba812013-07-25 08:48:47 -0600469 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800470 "Key block rec!dev flag mismatch");
471
472 ResetMocks();
473 kbh.data_key.key_version = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600474 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800475 "Key block kernel key rollback");
476
477 ResetMocks();
478 kbh.data_key.key_version = 0x10000;
Simon Glass527ba812013-07-25 08:48:47 -0600479 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800480 "Key block kernel key version too big");
481
Randall Spangler3e9cf902013-02-01 13:31:20 -0800482 ResetMocks();
483 kbh.data_key.key_version = 3;
Simon Glass527ba812013-07-25 08:48:47 -0600484 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key block version roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800485 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
486
487 ResetMocks();
488 kbh.data_key.key_version = 3;
489 mock_parts[1].start = 300;
490 mock_parts[1].size = 150;
Simon Glass527ba812013-07-25 08:48:47 -0600491 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two kernels roll forward");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800492 TEST_EQ(mock_part_next, 2, " read both");
493 TEST_EQ(shared->kernel_version_tpm, 0x30001, " shared version");
494
495 ResetMocks();
496 kbh.data_key.key_version = 1;
497 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600498 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800499
500 ResetMocks();
501 kbh.data_key.key_version = 1;
502 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600503 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800504
505 ResetMocks();
506 mock_data_key = NULL;
Simon Glass527ba812013-07-25 08:48:47 -0600507 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
508 "Bad data key");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800509
510 ResetMocks();
511 preamble_verify_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600512 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
513 "Bad preamble");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800514
515 ResetMocks();
516 kph.kernel_version = 0;
Simon Glass527ba812013-07-25 08:48:47 -0600517 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800518 "Kernel version rollback");
519
Randall Spangler3e9cf902013-02-01 13:31:20 -0800520 ResetMocks();
521 kph.kernel_version = 0;
522 lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
Simon Glass527ba812013-07-25 08:48:47 -0600523 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in dev mode");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800524
525 ResetMocks();
526 kph.kernel_version = 0;
527 lkp.boot_flags |= BOOT_FLAG_RECOVERY;
Simon Glass527ba812013-07-25 08:48:47 -0600528 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in rec mode");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800529
530 ResetMocks();
531 kph.preamble_size |= 0x07;
Simon Glass527ba812013-07-25 08:48:47 -0600532 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800533 "Kernel body offset");
534
Randall Spangler3e9cf902013-02-01 13:31:20 -0800535 /* Check getting kernel load address from header */
536 ResetMocks();
537 kph.body_load_address = (size_t)kernel_buffer;
538 lkp.kernel_buffer = NULL;
Simon Glass527ba812013-07-25 08:48:47 -0600539 TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Get load address from preamble");
Randall Spangler3e9cf902013-02-01 13:31:20 -0800540 TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, " address");
541 /* Size is rounded up to nearest sector */
542 TEST_EQ(lkp.kernel_buffer_size, 70144, " size");
543
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800544 ResetMocks();
545 lkp.kernel_buffer_size = 8192;
Simon Glass527ba812013-07-25 08:48:47 -0600546 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800547 "Kernel too big for buffer");
548
549 ResetMocks();
550 mock_parts[0].size = 130;
Simon Glass527ba812013-07-25 08:48:47 -0600551 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800552 "Kernel too big for partition");
553
Randall Spangler3e9cf902013-02-01 13:31:20 -0800554 ResetMocks();
555 disk_read_to_fail = 108;
Simon Glass527ba812013-07-25 08:48:47 -0600556 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
Randall Spangler3e9cf902013-02-01 13:31:20 -0800557 "Fail reading kernel data");
558
559 ResetMocks();
560 verify_data_fail = 1;
Simon Glass527ba812013-07-25 08:48:47 -0600561 TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Bad data");
Randall Spangler5d0a2e72013-01-30 13:19:19 -0800562}
563
Randall Spangler49cb0d32013-01-29 14:28:16 -0800564int main(void)
565{
566 ReadWriteGptTest();
567 InvalidParamsTest();
Randall Spangler3e9cf902013-02-01 13:31:20 -0800568 LoadKernelTest();
Randall Spangler49cb0d32013-01-29 14:28:16 -0800569
Simon Glass25001852013-08-16 02:47:57 -0600570 if (vboot_api_stub_check_memory())
571 return 255;
572
Randall Spangler49cb0d32013-01-29 14:28:16 -0800573 return gTestSuccess ? 0 : 255;
574}