blob: ec455d3ff943612063878d898787316c57b381ca [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>
41
42#ifndef DTB_PAD_SIZE
43#define DTB_PAD_SIZE 2048
44#endif
45#define INTERMEDIATE_DIGEST_LENGTH 64
46#define MAX_PART_NAME_SIZE 10
47
48#ifndef MDTP_SUPPORT
49int mdtp_activated(bool * activated)
50{
51 return 0;
52}
53void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
54{
55 return;
56}
57#endif
58
59static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
60static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
61static const CHAR8 *Space = " ";
62#if !VERIFIED_BOOT_2
63static const CHAR8 *VerityMode = " androidboot.veritymode=";
64static struct verified_boot_verity_mode VbVm[] =
65{
66 {FALSE, "logging"},
67 {TRUE, "enforcing"},
68};
69#endif
70
71static struct verified_boot_state_name VbSn[] =
72{
73 {GREEN, "green"},
74 {ORANGE, "orange"},
75 {YELLOW, "yellow"},
76 {RED, "red"},
77};
78
79struct boolean_string
80{
81 BOOLEAN value;
82 CHAR8 *name;
83};
84
85static struct boolean_string BooleanString[] =
86{
87 {FALSE, "false"},
88 {TRUE, "true"}
89};
90
91
92typedef struct {
93 AvbOps *Ops;
94 AvbSlotVerifyData *SlotData;
95} VB2Data;
96
97UINT32 GetAVBVersion()
98{
99#if VERIFIED_BOOT_2
100 return 2;
101#elif VERIFIED_BOOT
102 return 1;
103#else
104 return 0;
105#endif
106}
107
108BOOLEAN VerifiedBootEnabled()
109{
110 return (GetAVBVersion() > NO_AVB);
111}
112
113static int GetCurrentSlotSuffix(Slot *CurrentSlot)
114{
115 if (!partition_multislot_is_supported())
116 return ERR_INVALID_ARGS;
117
118 strncpy(CurrentSlot->Suffix,
119 SUFFIX_SLOT(partition_find_active_slot()),
120 MAX_SLOT_SUFFIX_SZ);
121 return 0;
122}
123
124static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
125{
126 /* These checks are already done before calling auth remove from here */
127#if VERIFIED_BOOT || VERIFIED_BOOT_2
128 boot_verifier_init();
129#endif
130 return 0;
131}
132
133static int GetActiveSlot(Slot *ActiveSlot)
134{
135 if (!partition_multislot_is_supported())
136 return ERR_INVALID_ARGS;
137 int idx = partition_find_active_slot();
138 if (idx != INVALID)
139 {
140 strncpy(ActiveSlot->Suffix,
141 SUFFIX_SLOT(partition_find_active_slot()),
142 MAX_SLOT_SUFFIX_SZ);
143 return 0;
144 }
145 return ERR_NOT_FOUND;
146}
147
148static int FindBootableSlot(Slot *BootableSlot)
149{
150 int Status = 0;
151
152 if (BootableSlot == NULL) {
153 dprintf(CRITICAL,"FindBootableSlot: input parameter invalid\n");
154 return -ERR_INVALID_ARGS;
155 }
156
157 Status = GetActiveSlot(BootableSlot);
158 if (Status != 0) {
159 /* clear bootable slot */
160 BootableSlot->Suffix[0] = '\0';
161 }
162 return Status;
163}
164
165bool IsSuffixEmpty(Slot *CheckSlot)
166{
167 if (CheckSlot == NULL) {
168 return TRUE;
169 }
170
171 if (strlen((char *)CheckSlot->Suffix) == 0) {
172 return TRUE;
173 }
174 return FALSE;
175}
176
177static int HandleActiveSlotUnbootable()
178{
179 int curr_slot;
180 curr_slot = partition_find_active_slot();
181 partition_deactivate_slot(curr_slot);
182 partition_find_boot_slot();
183
184 // should not reach here
185 return ERROR;
186}
187
188/*
189 * Returns length = 0 when there is failure.
190 */
191uint32_t GetSystemPath(char **SysPath)
192{
193 INT32 Index;
194 UINT32 Lun;
195 CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
196 Slot CurSlot;
197 CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
198
199 if (GetCurrentSlotSuffix(&CurSlot))
200 return 0;
201
202 *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
203 if (!*SysPath) {
204 dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
205 return 0;
206 }
207
208 strncpy(PartitionName, "system", strlen("system") + 1);
209 strncat(PartitionName, CurSlot.Suffix, MAX_GPT_NAME_SIZE - 1);
210
211 Index = partition_get_index(PartitionName);
212 if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
213 dprintf(CRITICAL, "System partition does not exit\n");
214 free(*SysPath);
215 return 0;
216 }
217
218 Lun = partition_get_lun(Index);
219 if (platform_boot_dev_isemmc()) {
220 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
221 Index + 1);
222 } else {
223 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
224 LunCharMapping[Lun],
225 partition_get_index_in_lun(PartitionName, Lun));
226 }
227
228 dprintf(DEBUG, "System Path - %s \n", *SysPath);
229
230 return strlen(*SysPath);
231}
232
233static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
234{
235 INT32 SrcLen = strlen(Src);
236 CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
237
238 strlcat(Dst, Src, SrcLen);
239 Info->vbcmdline_filled_len += SrcLen;
240
241 return EFI_SUCCESS;
242}
243
244static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
245{
246 EFI_STATUS Status = EFI_SUCCESS;
247
248 if (GetAVBVersion() >= AVB_1) {
249 GUARD(Appendvbcmdline(Info, VerifiedState));
250 GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
251 }
252 GUARD(Appendvbcmdline(Info, KeymasterLoadState));
253 GUARD(Appendvbcmdline(Info, Space));
254 return EFI_SUCCESS;
255}
256
257static EFI_STATUS VBCommonInit(bootinfo *Info)
258{
259 EFI_STATUS Status = EFI_SUCCESS;
260
261 Info->boot_state = RED;
262
263 // FIXME: Add boot call
264 /* allocate VB command line*/
265 Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
266 if (Info->vbcmdline == NULL) {
267 dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
268 Status = EFI_OUT_OF_RESOURCES;
269 return Status;
270 }
271 Info->vbcmdline_len = 2*DTB_PAD_SIZE;
272 Info->vbcmdline_filled_len = 0;
273 Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
274
275 return Status;
276}
277
278#if VERIFIED_BOOT_2
279/* Disable for VB 2.0 as this path is never taken */
280static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
281{
282 return ERROR;
283}
284static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
285{
286 return ERROR;
287}
288#else
289static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
290{
291 EFI_STATUS Status = EFI_SUCCESS;
292
293 if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
294 /* fastboot boot option image already loaded */
295 return Status;
296 }
297
298 Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
299 (UINT32 *)&(Info->images[0].imgsize));
300 if (Status != EFI_SUCCESS) {
301 dprintf(CRITICAL,
302 "ERROR: Failed to load image from partition: %d\n", Status);
303 return EFI_LOAD_ERROR;
304 }
305 Info->num_loaded_images = 1;
306 Info->images[0].name = malloc(strlen(Info->pname) + 1);
307 strncpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
308 return Status;
309}
310
311static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
312{
313 EFI_STATUS Status = EFI_SUCCESS;
314 CHAR8 StrPname[MAX_GPT_NAME_SIZE];
315 CHAR8 Pname[MAX_GPT_NAME_SIZE];
316 CHAR8 *SystemPath = NULL;
317 UINT32 SystemPathLen = 0;
318 device_info DevInfo_vb;
319
320 GUARD(VBCommonInit(Info));
321 GUARD(LoadImageNoAuth(Info));
322 boot_verifier_init();
323
324 // FIXME: INIT devinfo()
325 DevInfo_vb.is_unlocked = !is_device_locked();
326 DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
327
328 strncpy(StrPname, "/", strlen("/"));
329 strncpy(Pname, Info->pname, strlen(Info->pname));
330 if (Info->multi_slot_boot) {
331 strncat(StrPname, Pname,
332 strlen(Pname) - (MAX_SLOT_SUFFIX_SZ - 1));
333 } else {
334 strncat(StrPname, Pname, strlen(Pname));
335 }
336
337 Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
338 Info->images[0].imgsize,
339 StrPname,
340 &Info->boot_state);
341 if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
342 dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
343 return Status;
344 }
345
346 set_os_version((unsigned char *)Info->images[0].image_buffer);
347 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
348 return EFI_LOAD_ERROR;
349
350 SystemPathLen = GetSystemPath(&SystemPath);
351 if (SystemPathLen == 0 || SystemPath == NULL) {
352 dprintf(CRITICAL, "GetSystemPath failed!\n");
353 return EFI_LOAD_ERROR;
354 }
355 GUARD(AppendVBCommonCmdLine(Info));
356 GUARD(Appendvbcmdline(Info, VerityMode));
357 GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
358 GUARD(Appendvbcmdline(Info, SystemPath));
359
360 Info->vb_data = NULL;
361 return Status;
362}
363#endif
364
365static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
366{
367 switch (Result) {
368 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
369 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
370 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
371 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
372 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
373 return FALSE;
374
375 case AVB_SLOT_VERIFY_RESULT_OK:
376 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
377 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
378 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
379 return TRUE;
380 }
381
382 return FALSE;
383}
384
385char *pname[] = {
386 "sbl1",
387 "rpm",
388 "tz",
389 "aboot",
390};
391
392static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
393{
394 EFI_STATUS Status = EFI_SUCCESS;
395 AvbSlotVerifyResult Result;
396 AvbSlotVerifyData *SlotData = NULL;
397 VB2Data *VBData = NULL;
398 AvbOpsUserData *UserData = NULL;
399 AvbOps *Ops = NULL;
400 CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
401 CHAR8 *SlotSuffix = NULL;
402 BOOLEAN AllowVerificationError = !is_device_locked();
403 BOOLEAN VerityEnforcing = is_verity_enforcing();
404 const CHAR8 *RequestedPartitionMission[] = {"boot", "dtbo", NULL};
405 const CHAR8 *RequestedPartitionRecovery[] = {"recovery", "dtbo", NULL};
406 const CHAR8 **RequestedPartition = NULL;
407 UINTN NumRequestedPartition = 0;
408 UINT32 ImageHdrSize = 0;
409 UINT32 imgsizeActual = 0;
410 VOID *image_buffer = NULL;
411 UINT32 imgsize = 0;
412 AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
413 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
414 AVB_SLOT_VERIFY_FLAGS_NONE;
415 AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
416 device_info DevInfo_vb;
417
418 Info->boot_state = RED;
419 GUARD(VBCommonInit(Info));
420
421 UserData = avb_calloc(sizeof(AvbOpsUserData));
422 if (UserData == NULL) {
423 dprintf(CRITICAL,
424 "ERROR: Failed to allocate AvbOpsUserData\n");
425 Status = EFI_OUT_OF_RESOURCES;
426 goto out;
427 }
428
429 Ops = AvbOpsNew(UserData);
430 if (Ops == NULL) {
431 dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
432 Status = EFI_OUT_OF_RESOURCES;
433 goto out;
434 }
435 if(Info->multi_slot_boot) {
436 strncpy(Pname, Info->pname, strlen(Info->pname));
437 if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
438 dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
439 Status = EFI_INVALID_PARAMETER;
440 goto out;
441 }
442 SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
443 } else {
444 SlotSuffix = "\0";
445 }
446
447 if(!Info->multi_slot_boot && Info->bootinto_recovery) {
448 RequestedPartition = RequestedPartitionRecovery;
449 NumRequestedPartition = ARRAY_SIZE (RequestedPartitionRecovery) - 1;
450 if (Info->num_loaded_images) {
451 /* fastboot boot option, skip Index 0, as boot image already
452 * loaded */
453 RequestedPartition = &RequestedPartitionRecovery[1];
454 }
455 } else {
456 RequestedPartition = RequestedPartitionMission;
457 NumRequestedPartition = ARRAY_SIZE(RequestedPartitionMission) - 1;
458 if (Info->num_loaded_images) {
459 /* fastboot boot option, skip Index 0, as boot image already
460 * loaded */
461 RequestedPartition = &RequestedPartitionMission[1];
462 }
463 }
464 if (Info->num_loaded_images) {
465 NumRequestedPartition--;
466 }
467
468 // FIXME: is this correct?
469 VerityFlags = VerityEnforcing ?
470 AVB_HASHTREE_ERROR_MODE_RESTART :
471 AVB_HASHTREE_ERROR_MODE_EIO;
472
473 Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
474 VerifyFlags, VerityFlags,
475 &SlotData);
476
477 if (AllowVerificationError && ResultShouldContinue(Result)) {
478 dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
479 "%s, continue boot\n",
480 avb_slot_verify_result_to_string(Result));
481 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
482 dprintf(CRITICAL,
483 "ERROR: Device State %s, AvbSlotVerify returned %s\n",
484 AllowVerificationError ? "Unlocked" : "Locked",
485 avb_slot_verify_result_to_string(Result));
486 Status = EFI_LOAD_ERROR;
487 Info->boot_state = RED;
488 goto out;
489 }
490
491 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
492 dprintf(DEBUG, "Requested Partition: %s\n",
493 RequestedPartition[ReqIndex]);
494 for (UINTN loadedindex = 0;
495 loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
496 dprintf(DEBUG, "Loaded Partition: %s\n",
497 SlotData->loaded_partitions[loadedindex].partition_name);
498 if (!strncmp((const char *)
499 RequestedPartition[ReqIndex],
500 SlotData->loaded_partitions[loadedindex].partition_name,
501 strlen(SlotData->loaded_partitions[loadedindex]
502 .partition_name))) {
503 if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
504 dprintf(CRITICAL, "NumLoadedPartition"
505 "(%d) too large "
506 "max images(%d)\n",
507 Info->num_loaded_images,
508 ARRAY_SIZE(Info->images));
509 Status = EFI_LOAD_ERROR;
510 Info->boot_state = RED;
511 goto out;
512 }
513 Info->images[Info->num_loaded_images].name =
514 SlotData->loaded_partitions[loadedindex].partition_name;
515 Info->images[Info->num_loaded_images].image_buffer =
516 SlotData->loaded_partitions[loadedindex].data;
517 Info->images[Info->num_loaded_images].imgsize =
518 SlotData->loaded_partitions[loadedindex].data_size;
519 Info->num_loaded_images++;
520 break;
521 }
522 }
523 }
524
525 if (Info->num_loaded_images < NumRequestedPartition) {
526 dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %lu\n",Info->num_loaded_images, NumRequestedPartition);
527 Status = EFI_LOAD_ERROR;
528 goto out;
529 }
530
531 dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
532
533 VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
534 if (VBData == NULL) {
535 dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
536 Status = EFI_OUT_OF_RESOURCES;
537 goto out;
538 }
539 VBData->Ops = Ops;
540 VBData->SlotData = SlotData;
541 Info->vb_data = (VOID *)VBData;
542
543 ImageHdrSize = get_page_size();
544 GUARD_OUT(getimage(Info, &image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
545
546 Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
547 if (Status != EFI_SUCCESS) {
548 dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
549 goto out;
550 }
551
552 if (imgsizeActual > imgsize) {
553 Status = EFI_BUFFER_TOO_SMALL;
554 dprintf(CRITICAL,
555 "Boot size in vbmeta less than actual boot image size "
556 "flash corresponding vbmeta.img\n");
557 goto out;
558 }
559 if (AllowVerificationError) {
560 Info->boot_state = ORANGE;
561 } else {
562 if (UserData->IsUserKey) {
563 Info->boot_state = YELLOW;
564 } else {
565 Info->boot_state = GREEN;
566 }
567 }
568
569 /* command line */
570 GUARD_OUT(AppendVBCommonCmdLine(Info));
571 GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
572 DevInfo_vb.is_unlocked = !is_device_locked();
573 set_os_version((unsigned char *)Info->images[0].image_buffer);
574 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
575 return EFI_LOAD_ERROR;
576 dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
577 VbSn[Info->boot_state].name);
578
579out:
580 if (Status != EFI_SUCCESS) {
581 if (SlotData != NULL) {
582 avb_slot_verify_data_free(SlotData);
583 }
584 if (Ops != NULL) {
585 AvbOpsFree(Ops);
586 }
587 if (UserData != NULL) {
588 avb_free(UserData);
589 }
590 if (VBData != NULL) {
591 avb_free(VBData);
592 }
593 Info->boot_state = RED;
594 if(Info->multi_slot_boot) {
595 HandleActiveSlotUnbootable();
596 /* HandleActiveSlotUnbootable should have swapped slots and
597 * reboot the device. If no bootable slot found, enter fastboot */
598 dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
599 } else {
600 dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
601 }
602
603 }
604
605 dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
606 VbSn[Info->boot_state].name, Info->boot_state);
607 return Status;
608}
609
610static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
611{
612 EFI_STATUS Status = EFI_SUCCESS;
613 CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
614
615 if (GetAVBVersion() < AVB_1) {
616 return EFI_SUCCESS;
617 }
618
619 if (!strncmp(Info->pname, "boot", strlen("boot"))) {
620 Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
621 if (Status != EFI_SUCCESS) {
622 dprintf(DEBUG,
623 "No Ffbm cookie found, ignore: %d\n", Status);
624 ffbm_mode_string[0] = '\0';
625 }
626 }
627
628 dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
629 switch (Info->boot_state)
630 {
631 case RED:
632 display_bootverify_menu(DISPLAY_MENU_RED);
633 //if (Status != EFI_SUCCESS) {
634 dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
635 "\nYour device will shutdown in 30s\n");
636 //}
637 udelay(30000000);
638 shutdown_device();
639 break;
640 case YELLOW:
641 display_bootverify_menu(DISPLAY_MENU_YELLOW);
642 //if (Status == EFI_SUCCESS) {
643 wait_for_users_action();
644 //} else {
645 dprintf(INFO, "Your device has loaded a different operating system." \
646 "\nWait for 5 seconds before proceeding\n");
647 udelay(5000000);
648 //}
649 break;
650 case ORANGE:
651 if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
652 dprintf(DEBUG, "Device will boot into FFBM mode\n");
653 } else {
654 //display_bootverify_menu(DISPLAY_MENU_ORANGE);
655 //if (Status == EFI_SUCCESS) {
656 // wait_for_users_action();
657 //} else {
658 dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
659 udelay(5000000);
660 //}
661 }
662 break;
663 default:
664 break;
665 }
666 return EFI_SUCCESS;
667}
668
669EFI_STATUS load_image_and_auth(bootinfo *Info)
670{
671 EFI_STATUS Status = EFI_SUCCESS;
672 BOOLEAN MdtpActive = FALSE;
673 UINT32 AVBVersion = NO_AVB;
674 mdtp_ext_partition_verification_t ext_partition;
675
676 if (Info == NULL) {
677 dprintf(CRITICAL, "Invalid parameter Info\n");
678 return EFI_INVALID_PARAMETER;
679 }
680
681 if (!Info->multi_slot_boot) {
682 if (Info->bootinto_recovery) {
683 dprintf(INFO, "Booting Into Recovery Mode\n");
684 strncpy(Info->pname, "recovery", strlen("recovery"));
685 } else {
686 dprintf(INFO, "Booting Into Mission Mode\n");
687 strncpy(Info->pname, "boot", strlen("boot"));
688 }
689 } else {
690 Slot CurrentSlot = {{0}};
691
692 GUARD(FindBootableSlot(&CurrentSlot));
693 if (IsSuffixEmpty(&CurrentSlot)) {
694 dprintf(CRITICAL, "No bootable slot\n");
695 return EFI_LOAD_ERROR;
696 }
697 strncpy(Info->pname, "boot", strlen("boot"));
698 strncat(Info->pname, CurrentSlot.Suffix, strlen(CurrentSlot.Suffix));
699 }
700
701 dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
702 BooleanString[Info->multi_slot_boot].name, Info->pname);
703
704 Status = mdtp_activated(&MdtpActive);
705 if (Status) {
706 dprintf(CRITICAL,
707 "Failed to get activation state for MDTP, "
708 "Status=%d."
709 " Considering MDTP as active and continuing \n",
710 Status);
711 if (Status != -1)
712 MdtpActive = TRUE;
713 }
714
715 AVBVersion = GetAVBVersion();
716 dprintf(DEBUG, "AVB version %d\n", AVBVersion);
717
718 /* Load and Authenticate */
719 switch (AVBVersion) {
720 case NO_AVB:
721 return LoadImageNoAuth(Info);
722 break;
723 case AVB_1:
724 Status = load_image_and_authVB1(Info);
725 break;
726 case AVB_2:
727 Status = load_image_and_authVB2(Info);
728 break;
729 default:
730 dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
731 Status = EFI_UNSUPPORTED;
732 }
733
734 // if MDTP is active Display Recovery UI
735 if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
736 //FIXME: Hard coded to BOOT
737 ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
738 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
739 ext_partition.page_size = get_page_size();
740 ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
741 ext_partition.image_size = Info->images[0].imgsize;
742 ext_partition.sig_avail = FALSE;
743 mdtp_fwlock_verify_lock(&ext_partition);
744 }
745
746 if (!is_device_locked() && Status != EFI_SUCCESS) {
747 dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
748 return Status;
749 }
750
751 DisplayVerifiedBootScreen(Info);
752
753 return Status;
754}
755
756#if VERIFIED_BOOT_2
757VOID free_verified_boot_resource(bootinfo *Info)
758{
759 dprintf(DEBUG, "free_verified_boot_resource\n");
760
761 if (Info == NULL) {
762 return;
763 }
764
765 VB2Data *VBData = Info->vb_data;
766 if (VBData != NULL) {
767 AvbOps *Ops = VBData->Ops;
768 if (Ops != NULL) {
769 if (Ops->user_data != NULL) {
770 avb_free(Ops->user_data);
771 }
772 AvbOpsFree(Ops);
773 }
774
775 AvbSlotVerifyData *SlotData = VBData->SlotData;
776 if (SlotData != NULL) {
777 avb_slot_verify_data_free(SlotData);
778 }
779 avb_free(VBData);
780 }
781
782 if (Info->vbcmdline != NULL) {
783 free(Info->vbcmdline);
784 }
785 return;
786}
787#else
788VOID free_verified_boot_resource(bootinfo *Info)
789{
790 return;
791}
792#endif