blob: 585d6a961147554a1b5bdd3cb7f039fd512b645f [file] [log] [blame]
Monika Singh5e170362018-03-14 00:48:36 +05301/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#include "libavb/libavb.h"
30#include <malloc.h>
31
32#include <boot_verifier.h>
33#include <ab_partition_parser.h>
34#include <partition_parser.h>
35#include <recovery.h>
36#include <display_menu.h>
37#include <../../../app/aboot/mdtp.h>
38#include <platform/timer.h>
39#include "verifiedboot.h"
40#include <err.h>
Jiten Patel2cb89192018-08-22 12:51:47 +053041#include <target.h>
Monika Singh5e170362018-03-14 00:48:36 +053042
43#ifndef DTB_PAD_SIZE
44#define DTB_PAD_SIZE 2048
45#endif
46#define INTERMEDIATE_DIGEST_LENGTH 64
47#define MAX_PART_NAME_SIZE 10
Jiten Patel2cb89192018-08-22 12:51:47 +053048#define MAX_NUM_REQ_PARTITION 8
Monika Singh2c8de342018-09-03 20:36:15 +053049#define BOOT_HEADER_VERSION_ZERO 0
Jiten Patel2cb89192018-08-22 12:51:47 +053050
51char *avb_verify_partition_name[] = {
52 "boot",
53 "dtbo",
54 "vbmeta",
55 "recovery"
56};
Monika Singh5e170362018-03-14 00:48:36 +053057
58#ifndef MDTP_SUPPORT
59int mdtp_activated(bool * activated)
60{
61 return 0;
62}
63void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
64{
65 return;
66}
67#endif
68
69static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
70static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
71static const CHAR8 *Space = " ";
72#if !VERIFIED_BOOT_2
73static const CHAR8 *VerityMode = " androidboot.veritymode=";
74static struct verified_boot_verity_mode VbVm[] =
75{
76 {FALSE, "logging"},
77 {TRUE, "enforcing"},
78};
79#endif
80
81static struct verified_boot_state_name VbSn[] =
82{
83 {GREEN, "green"},
84 {ORANGE, "orange"},
85 {YELLOW, "yellow"},
86 {RED, "red"},
87};
88
89struct boolean_string
90{
91 BOOLEAN value;
92 CHAR8 *name;
93};
94
95static struct boolean_string BooleanString[] =
96{
97 {FALSE, "false"},
98 {TRUE, "true"}
99};
100
101
102typedef struct {
103 AvbOps *Ops;
104 AvbSlotVerifyData *SlotData;
105} VB2Data;
106
107UINT32 GetAVBVersion()
108{
109#if VERIFIED_BOOT_2
110 return 2;
111#elif VERIFIED_BOOT
112 return 1;
113#else
114 return 0;
115#endif
116}
117
118BOOLEAN VerifiedBootEnabled()
119{
120 return (GetAVBVersion() > NO_AVB);
121}
122
Monika Singh5e170362018-03-14 00:48:36 +0530123static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
124{
125 /* These checks are already done before calling auth remove from here */
126#if VERIFIED_BOOT || VERIFIED_BOOT_2
127 boot_verifier_init();
128#endif
129 return 0;
130}
131
Monika Singh5e170362018-03-14 00:48:36 +0530132static int HandleActiveSlotUnbootable()
133{
134 int curr_slot;
135 curr_slot = partition_find_active_slot();
136 partition_deactivate_slot(curr_slot);
137 partition_find_boot_slot();
138
139 // should not reach here
140 return ERROR;
141}
142
143/*
144 * Returns length = 0 when there is failure.
145 */
146uint32_t GetSystemPath(char **SysPath)
147{
148 INT32 Index;
149 UINT32 Lun;
150 CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
Monika Singh5e170362018-03-14 00:48:36 +0530151 CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
Monika Singh0f7bfc82018-04-16 23:14:29 +0530152 const char *current_slot_suffix;
153 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530154
155 *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
156 if (!*SysPath) {
157 dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
158 return 0;
159 }
160
Monika Singh87794672018-05-19 19:10:47 +0530161 strlcpy(PartitionName, "system", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530162 current_active_slot = partition_find_active_slot();
163 if (partition_multislot_is_supported()) {
164 if (current_active_slot == INVALID)
165 return 0;
166 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Monika Singh83dacd42018-05-16 12:13:37 +0530167 strlcat(PartitionName, current_slot_suffix, MAX_GPT_NAME_SIZE - 1);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530168 }
Monika Singh5e170362018-03-14 00:48:36 +0530169
170 Index = partition_get_index(PartitionName);
171 if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
172 dprintf(CRITICAL, "System partition does not exit\n");
173 free(*SysPath);
174 return 0;
175 }
176
177 Lun = partition_get_lun(Index);
178 if (platform_boot_dev_isemmc()) {
179 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
180 Index + 1);
181 } else {
182 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
183 LunCharMapping[Lun],
184 partition_get_index_in_lun(PartitionName, Lun));
185 }
186
187 dprintf(DEBUG, "System Path - %s \n", *SysPath);
188
189 return strlen(*SysPath);
190}
191
192static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
193{
194 INT32 SrcLen = strlen(Src);
195 CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
196
197 strlcat(Dst, Src, SrcLen);
198 Info->vbcmdline_filled_len += SrcLen;
199
200 return EFI_SUCCESS;
201}
202
203static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
204{
205 EFI_STATUS Status = EFI_SUCCESS;
206
207 if (GetAVBVersion() >= AVB_1) {
208 GUARD(Appendvbcmdline(Info, VerifiedState));
209 GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
210 }
211 GUARD(Appendvbcmdline(Info, KeymasterLoadState));
212 GUARD(Appendvbcmdline(Info, Space));
213 return EFI_SUCCESS;
214}
215
216static EFI_STATUS VBCommonInit(bootinfo *Info)
217{
218 EFI_STATUS Status = EFI_SUCCESS;
219
220 Info->boot_state = RED;
221
222 // FIXME: Add boot call
223 /* allocate VB command line*/
224 Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
225 if (Info->vbcmdline == NULL) {
226 dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
227 Status = EFI_OUT_OF_RESOURCES;
228 return Status;
229 }
230 Info->vbcmdline_len = 2*DTB_PAD_SIZE;
231 Info->vbcmdline_filled_len = 0;
232 Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
233
234 return Status;
235}
236
237#if VERIFIED_BOOT_2
238/* Disable for VB 2.0 as this path is never taken */
239static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
240{
241 return ERROR;
242}
243static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
244{
245 return ERROR;
246}
247#else
248static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
249{
250 EFI_STATUS Status = EFI_SUCCESS;
251
252 if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
253 /* fastboot boot option image already loaded */
254 return Status;
255 }
256
257 Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
258 (UINT32 *)&(Info->images[0].imgsize));
259 if (Status != EFI_SUCCESS) {
260 dprintf(CRITICAL,
261 "ERROR: Failed to load image from partition: %d\n", Status);
262 return EFI_LOAD_ERROR;
263 }
264 Info->num_loaded_images = 1;
265 Info->images[0].name = malloc(strlen(Info->pname) + 1);
Monika Singh96b97212018-04-13 18:27:55 +0530266 strlcpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
Monika Singh5e170362018-03-14 00:48:36 +0530267 return Status;
268}
269
270static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
271{
272 EFI_STATUS Status = EFI_SUCCESS;
273 CHAR8 StrPname[MAX_GPT_NAME_SIZE];
274 CHAR8 Pname[MAX_GPT_NAME_SIZE];
275 CHAR8 *SystemPath = NULL;
276 UINT32 SystemPathLen = 0;
277 device_info DevInfo_vb;
278
279 GUARD(VBCommonInit(Info));
280 GUARD(LoadImageNoAuth(Info));
281 boot_verifier_init();
282
283 // FIXME: INIT devinfo()
284 DevInfo_vb.is_unlocked = !is_device_locked();
285 DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
286
Monika Singh96b97212018-04-13 18:27:55 +0530287 strlcpy(StrPname, "/", strlen("/"));
Monika Singh87794672018-05-19 19:10:47 +0530288 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530289 if (Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530290 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530291 } else {
Monika Singh87794672018-05-19 19:10:47 +0530292 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530293 }
294
295 Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
296 Info->images[0].imgsize,
297 StrPname,
298 &Info->boot_state);
299 if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
300 dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
301 return Status;
302 }
303
304 set_os_version((unsigned char *)Info->images[0].image_buffer);
305 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
306 return EFI_LOAD_ERROR;
307
308 SystemPathLen = GetSystemPath(&SystemPath);
309 if (SystemPathLen == 0 || SystemPath == NULL) {
310 dprintf(CRITICAL, "GetSystemPath failed!\n");
311 return EFI_LOAD_ERROR;
312 }
313 GUARD(AppendVBCommonCmdLine(Info));
314 GUARD(Appendvbcmdline(Info, VerityMode));
315 GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
316 GUARD(Appendvbcmdline(Info, SystemPath));
317
318 Info->vb_data = NULL;
319 return Status;
320}
321#endif
322
323static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
324{
325 switch (Result) {
326 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
327 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
328 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
329 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
330 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
331 return FALSE;
332
333 case AVB_SLOT_VERIFY_RESULT_OK:
334 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
335 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
336 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
337 return TRUE;
338 }
339
340 return FALSE;
341}
342
343char *pname[] = {
344 "sbl1",
345 "rpm",
346 "tz",
347 "aboot",
348};
349
Jiten Patel2cb89192018-08-22 12:51:47 +0530350VOID AddRequestedPartition(CHAR8 **requestedpartititon, UINT32 index)
351{
352 UINTN i;
353 for (i = 0; i < MAX_NUM_REQ_PARTITION; i++) {
354 if (requestedpartititon[i] == NULL){
355 requestedpartititon[i] = avb_verify_partition_name[index];
356 break;
357 }
358 }
359}
360
Monika Singh5e170362018-03-14 00:48:36 +0530361static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
362{
363 EFI_STATUS Status = EFI_SUCCESS;
364 AvbSlotVerifyResult Result;
365 AvbSlotVerifyData *SlotData = NULL;
366 VB2Data *VBData = NULL;
367 AvbOpsUserData *UserData = NULL;
368 AvbOps *Ops = NULL;
369 CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
370 CHAR8 *SlotSuffix = NULL;
371 BOOLEAN AllowVerificationError = !is_device_locked();
372 BOOLEAN VerityEnforcing = is_verity_enforcing();
Jiten Patel2cb89192018-08-22 12:51:47 +0530373 CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
Monika Singh5e170362018-03-14 00:48:36 +0530374 const CHAR8 **RequestedPartition = NULL;
375 UINTN NumRequestedPartition = 0;
Monika Singh2c8de342018-09-03 20:36:15 +0530376 UINT32 HeaderVersion = 0;
Monika Singh5e170362018-03-14 00:48:36 +0530377 UINT32 ImageHdrSize = 0;
378 UINT32 imgsizeActual = 0;
379 VOID *image_buffer = NULL;
380 UINT32 imgsize = 0;
381 AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
382 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
383 AVB_SLOT_VERIFY_FLAGS_NONE;
384 AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
385 device_info DevInfo_vb;
386
Monika Singh2c8de342018-09-03 20:36:15 +0530387 HeaderVersion = Info->header_version;
Monika Singh5e170362018-03-14 00:48:36 +0530388 Info->boot_state = RED;
389 GUARD(VBCommonInit(Info));
390
391 UserData = avb_calloc(sizeof(AvbOpsUserData));
392 if (UserData == NULL) {
393 dprintf(CRITICAL,
394 "ERROR: Failed to allocate AvbOpsUserData\n");
395 Status = EFI_OUT_OF_RESOURCES;
396 goto out;
397 }
398
399 Ops = AvbOpsNew(UserData);
400 if (Ops == NULL) {
401 dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
402 Status = EFI_OUT_OF_RESOURCES;
403 goto out;
404 }
Monika Singh2c9d2b82018-05-01 12:24:59 +0530405 UserData->IsMultiSlot = Info->multi_slot_boot;
406
Monika Singh5e170362018-03-14 00:48:36 +0530407 if(Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530408 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530409 if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
410 dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
411 Status = EFI_INVALID_PARAMETER;
412 goto out;
413 }
414 SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
415 } else {
416 SlotSuffix = "\0";
417 }
418
419 if(!Info->multi_slot_boot && Info->bootinto_recovery) {
Jiten Patel2cb89192018-08-22 12:51:47 +0530420 AddRequestedPartition(RequestedPartitionAll, IMG_RECOVERY);
421 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530422 /* Add dtbo validation if target supports dtbo image generation and
423 dtbo is not included in recovery i.e. HEADER VERSION is 0 */
424 if (is_target_support_dtbo() && HeaderVersion == BOOT_HEADER_VERSION_ZERO) {
425 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
426 NumRequestedPartition += 1;
427 }
Monika Singh5e170362018-03-14 00:48:36 +0530428 } else {
Jiten Patel2cb89192018-08-22 12:51:47 +0530429 AddRequestedPartition(RequestedPartitionAll, IMG_BOOT);
430 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530431 if (is_target_support_dtbo()) {
432 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
433 NumRequestedPartition += 1;
434 }
Jiten Patel2cb89192018-08-22 12:51:47 +0530435 }
436
437 RequestedPartition = (const CHAR8 **)RequestedPartitionAll;
Monika Singh5e170362018-03-14 00:48:36 +0530438 if (Info->num_loaded_images) {
Jiten Patel2cb89192018-08-22 12:51:47 +0530439 /* fastboot boot option, skip Index 0, boot image already loaded */
440 RequestedPartition = (const CHAR8 **)&RequestedPartitionAll[1];
Monika Singh5e170362018-03-14 00:48:36 +0530441 NumRequestedPartition--;
442 }
443
Monika Singh5e170362018-03-14 00:48:36 +0530444 VerityFlags = VerityEnforcing ?
445 AVB_HASHTREE_ERROR_MODE_RESTART :
446 AVB_HASHTREE_ERROR_MODE_EIO;
447
448 Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
449 VerifyFlags, VerityFlags,
450 &SlotData);
451
452 if (AllowVerificationError && ResultShouldContinue(Result)) {
453 dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
454 "%s, continue boot\n",
455 avb_slot_verify_result_to_string(Result));
456 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
457 dprintf(CRITICAL,
458 "ERROR: Device State %s, AvbSlotVerify returned %s\n",
459 AllowVerificationError ? "Unlocked" : "Locked",
460 avb_slot_verify_result_to_string(Result));
461 Status = EFI_LOAD_ERROR;
462 Info->boot_state = RED;
463 goto out;
464 }
Monika Singh0f7bfc82018-04-16 23:14:29 +0530465 if (SlotData == NULL) {
466 Status = EFI_LOAD_ERROR;
467 Info->boot_state = RED;
468 goto out;
469 }
Monika Singh5e170362018-03-14 00:48:36 +0530470
471 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
472 dprintf(DEBUG, "Requested Partition: %s\n",
473 RequestedPartition[ReqIndex]);
474 for (UINTN loadedindex = 0;
475 loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
476 dprintf(DEBUG, "Loaded Partition: %s\n",
477 SlotData->loaded_partitions[loadedindex].partition_name);
Monika Singh87794672018-05-19 19:10:47 +0530478 if (!strncmp(((const char *)RequestedPartition[ReqIndex]),
479 SlotData->loaded_partitions[loadedindex].partition_name,MAX_GPT_NAME_SIZE))
480 {
Monika Singh5e170362018-03-14 00:48:36 +0530481 if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
482 dprintf(CRITICAL, "NumLoadedPartition"
483 "(%d) too large "
484 "max images(%d)\n",
485 Info->num_loaded_images,
486 ARRAY_SIZE(Info->images));
487 Status = EFI_LOAD_ERROR;
488 Info->boot_state = RED;
489 goto out;
490 }
491 Info->images[Info->num_loaded_images].name =
492 SlotData->loaded_partitions[loadedindex].partition_name;
493 Info->images[Info->num_loaded_images].image_buffer =
494 SlotData->loaded_partitions[loadedindex].data;
495 Info->images[Info->num_loaded_images].imgsize =
496 SlotData->loaded_partitions[loadedindex].data_size;
497 Info->num_loaded_images++;
498 break;
499 }
500 }
501 }
502
503 if (Info->num_loaded_images < NumRequestedPartition) {
lijuang1f8c8322018-06-20 18:21:19 +0800504 dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %llu\n",Info->num_loaded_images, NumRequestedPartition);
Monika Singh5e170362018-03-14 00:48:36 +0530505 Status = EFI_LOAD_ERROR;
506 goto out;
507 }
508
509 dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
510
511 VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
512 if (VBData == NULL) {
513 dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
514 Status = EFI_OUT_OF_RESOURCES;
515 goto out;
516 }
517 VBData->Ops = Ops;
518 VBData->SlotData = SlotData;
519 Info->vb_data = (VOID *)VBData;
520
521 ImageHdrSize = get_page_size();
Mayank Grover698adb02018-09-04 20:15:06 +0530522 GUARD_OUT(getimage(&image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
Monika Singh5e170362018-03-14 00:48:36 +0530523
524 Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
525 if (Status != EFI_SUCCESS) {
526 dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
527 goto out;
528 }
529
530 if (imgsizeActual > imgsize) {
531 Status = EFI_BUFFER_TOO_SMALL;
532 dprintf(CRITICAL,
533 "Boot size in vbmeta less than actual boot image size "
534 "flash corresponding vbmeta.img\n");
535 goto out;
536 }
537 if (AllowVerificationError) {
538 Info->boot_state = ORANGE;
539 } else {
540 if (UserData->IsUserKey) {
541 Info->boot_state = YELLOW;
542 } else {
543 Info->boot_state = GREEN;
544 }
545 }
546
547 /* command line */
548 GUARD_OUT(AppendVBCommonCmdLine(Info));
549 GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
550 DevInfo_vb.is_unlocked = !is_device_locked();
551 set_os_version((unsigned char *)Info->images[0].image_buffer);
552 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
553 return EFI_LOAD_ERROR;
554 dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
555 VbSn[Info->boot_state].name);
556
557out:
558 if (Status != EFI_SUCCESS) {
559 if (SlotData != NULL) {
560 avb_slot_verify_data_free(SlotData);
561 }
562 if (Ops != NULL) {
563 AvbOpsFree(Ops);
564 }
565 if (UserData != NULL) {
566 avb_free(UserData);
567 }
568 if (VBData != NULL) {
569 avb_free(VBData);
570 }
571 Info->boot_state = RED;
572 if(Info->multi_slot_boot) {
573 HandleActiveSlotUnbootable();
574 /* HandleActiveSlotUnbootable should have swapped slots and
575 * reboot the device. If no bootable slot found, enter fastboot */
576 dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
577 } else {
578 dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
579 }
580
581 }
582
583 dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
584 VbSn[Info->boot_state].name, Info->boot_state);
585 return Status;
586}
587
588static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
589{
590 EFI_STATUS Status = EFI_SUCCESS;
591 CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
592
593 if (GetAVBVersion() < AVB_1) {
594 return EFI_SUCCESS;
595 }
596
Monika Singh87794672018-05-19 19:10:47 +0530597 if (!strncmp(Info->pname, "boot", MAX_GPT_NAME_SIZE)) {
Monika Singh5e170362018-03-14 00:48:36 +0530598 Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
599 if (Status != EFI_SUCCESS) {
600 dprintf(DEBUG,
601 "No Ffbm cookie found, ignore: %d\n", Status);
602 ffbm_mode_string[0] = '\0';
603 }
604 }
605
606 dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
607 switch (Info->boot_state)
608 {
609 case RED:
610 display_bootverify_menu(DISPLAY_MENU_RED);
611 //if (Status != EFI_SUCCESS) {
612 dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
613 "\nYour device will shutdown in 30s\n");
614 //}
615 udelay(30000000);
616 shutdown_device();
617 break;
618 case YELLOW:
619 display_bootverify_menu(DISPLAY_MENU_YELLOW);
620 //if (Status == EFI_SUCCESS) {
621 wait_for_users_action();
622 //} else {
623 dprintf(INFO, "Your device has loaded a different operating system." \
624 "\nWait for 5 seconds before proceeding\n");
625 udelay(5000000);
626 //}
627 break;
628 case ORANGE:
629 if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
630 dprintf(DEBUG, "Device will boot into FFBM mode\n");
631 } else {
Monika Singh90cf4b12018-04-09 16:47:15 +0530632 display_bootverify_menu(DISPLAY_MENU_ORANGE);
633 if (Status == EFI_SUCCESS) {
634 wait_for_users_action();
635 } else {
Monika Singh5e170362018-03-14 00:48:36 +0530636 dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
637 udelay(5000000);
Monika Singh90cf4b12018-04-09 16:47:15 +0530638 }
Monika Singh5e170362018-03-14 00:48:36 +0530639 }
640 break;
641 default:
642 break;
643 }
644 return EFI_SUCCESS;
645}
646
647EFI_STATUS load_image_and_auth(bootinfo *Info)
648{
649 EFI_STATUS Status = EFI_SUCCESS;
650 BOOLEAN MdtpActive = FALSE;
651 UINT32 AVBVersion = NO_AVB;
652 mdtp_ext_partition_verification_t ext_partition;
Monika Singh0f7bfc82018-04-16 23:14:29 +0530653 const char *current_slot_suffix;
654 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530655
656 if (Info == NULL) {
657 dprintf(CRITICAL, "Invalid parameter Info\n");
658 return EFI_INVALID_PARAMETER;
659 }
660
661 if (!Info->multi_slot_boot) {
662 if (Info->bootinto_recovery) {
663 dprintf(INFO, "Booting Into Recovery Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530664 strlcpy(Info->pname, "recovery", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530665 } else {
666 dprintf(INFO, "Booting Into Mission Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530667 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530668 }
669 } else {
Monika Singh87794672018-05-19 19:10:47 +0530670 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530671 current_active_slot = partition_find_active_slot();
672 if (current_active_slot != INVALID ) {
673 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
674 if (strlen(current_slot_suffix) == 0) {
675 dprintf(CRITICAL, "No bootable slot\n");
676 return EFI_LOAD_ERROR;
677 }
Monika Singh87794672018-05-19 19:10:47 +0530678 strlcat(Info->pname, current_slot_suffix, MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530679 }
Monika Singh5e170362018-03-14 00:48:36 +0530680 }
681
682 dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
683 BooleanString[Info->multi_slot_boot].name, Info->pname);
684
685 Status = mdtp_activated(&MdtpActive);
686 if (Status) {
687 dprintf(CRITICAL,
688 "Failed to get activation state for MDTP, "
689 "Status=%d."
690 " Considering MDTP as active and continuing \n",
691 Status);
692 if (Status != -1)
693 MdtpActive = TRUE;
694 }
695
696 AVBVersion = GetAVBVersion();
697 dprintf(DEBUG, "AVB version %d\n", AVBVersion);
698
699 /* Load and Authenticate */
700 switch (AVBVersion) {
701 case NO_AVB:
702 return LoadImageNoAuth(Info);
703 break;
704 case AVB_1:
705 Status = load_image_and_authVB1(Info);
706 break;
707 case AVB_2:
708 Status = load_image_and_authVB2(Info);
709 break;
710 default:
711 dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
712 Status = EFI_UNSUPPORTED;
713 }
714
715 // if MDTP is active Display Recovery UI
716 if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
717 //FIXME: Hard coded to BOOT
718 ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
719 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
720 ext_partition.page_size = get_page_size();
721 ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
722 ext_partition.image_size = Info->images[0].imgsize;
723 ext_partition.sig_avail = FALSE;
724 mdtp_fwlock_verify_lock(&ext_partition);
725 }
726
727 if (!is_device_locked() && Status != EFI_SUCCESS) {
728 dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
729 return Status;
730 }
731
732 DisplayVerifiedBootScreen(Info);
733
734 return Status;
735}
736
737#if VERIFIED_BOOT_2
738VOID free_verified_boot_resource(bootinfo *Info)
739{
740 dprintf(DEBUG, "free_verified_boot_resource\n");
741
742 if (Info == NULL) {
743 return;
744 }
745
746 VB2Data *VBData = Info->vb_data;
747 if (VBData != NULL) {
748 AvbOps *Ops = VBData->Ops;
749 if (Ops != NULL) {
750 if (Ops->user_data != NULL) {
751 avb_free(Ops->user_data);
752 }
753 AvbOpsFree(Ops);
754 }
755
756 AvbSlotVerifyData *SlotData = VBData->SlotData;
757 if (SlotData != NULL) {
758 avb_slot_verify_data_free(SlotData);
759 }
760 avb_free(VBData);
761 }
762
763 if (Info->vbcmdline != NULL) {
764 free(Info->vbcmdline);
765 }
766 return;
767}
768#else
769VOID free_verified_boot_resource(bootinfo *Info)
770{
771 return;
772}
773#endif