blob: 4150f9ad7ef54fc3064df30fe9aab9069bef2bfb [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
Monika Singh5e170362018-03-14 00:48:36 +0530113static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
114{
115 /* These checks are already done before calling auth remove from here */
116#if VERIFIED_BOOT || VERIFIED_BOOT_2
117 boot_verifier_init();
118#endif
119 return 0;
120}
121
Monika Singh5e170362018-03-14 00:48:36 +0530122static int HandleActiveSlotUnbootable()
123{
124 int curr_slot;
125 curr_slot = partition_find_active_slot();
126 partition_deactivate_slot(curr_slot);
127 partition_find_boot_slot();
128
129 // should not reach here
130 return ERROR;
131}
132
133/*
134 * Returns length = 0 when there is failure.
135 */
136uint32_t GetSystemPath(char **SysPath)
137{
138 INT32 Index;
139 UINT32 Lun;
140 CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
Monika Singh5e170362018-03-14 00:48:36 +0530141 CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
Monika Singh0f7bfc82018-04-16 23:14:29 +0530142 const char *current_slot_suffix;
143 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530144
145 *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
146 if (!*SysPath) {
147 dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
148 return 0;
149 }
150
Monika Singh87794672018-05-19 19:10:47 +0530151 strlcpy(PartitionName, "system", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530152 current_active_slot = partition_find_active_slot();
153 if (partition_multislot_is_supported()) {
154 if (current_active_slot == INVALID)
155 return 0;
156 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Monika Singh83dacd42018-05-16 12:13:37 +0530157 strlcat(PartitionName, current_slot_suffix, MAX_GPT_NAME_SIZE - 1);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530158 }
Monika Singh5e170362018-03-14 00:48:36 +0530159
160 Index = partition_get_index(PartitionName);
161 if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
162 dprintf(CRITICAL, "System partition does not exit\n");
163 free(*SysPath);
164 return 0;
165 }
166
167 Lun = partition_get_lun(Index);
168 if (platform_boot_dev_isemmc()) {
169 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
170 Index + 1);
171 } else {
172 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
173 LunCharMapping[Lun],
174 partition_get_index_in_lun(PartitionName, Lun));
175 }
176
177 dprintf(DEBUG, "System Path - %s \n", *SysPath);
178
179 return strlen(*SysPath);
180}
181
182static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
183{
184 INT32 SrcLen = strlen(Src);
185 CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
186
187 strlcat(Dst, Src, SrcLen);
188 Info->vbcmdline_filled_len += SrcLen;
189
190 return EFI_SUCCESS;
191}
192
193static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
194{
195 EFI_STATUS Status = EFI_SUCCESS;
196
197 if (GetAVBVersion() >= AVB_1) {
198 GUARD(Appendvbcmdline(Info, VerifiedState));
199 GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
200 }
201 GUARD(Appendvbcmdline(Info, KeymasterLoadState));
202 GUARD(Appendvbcmdline(Info, Space));
203 return EFI_SUCCESS;
204}
205
206static EFI_STATUS VBCommonInit(bootinfo *Info)
207{
208 EFI_STATUS Status = EFI_SUCCESS;
209
210 Info->boot_state = RED;
211
212 // FIXME: Add boot call
213 /* allocate VB command line*/
214 Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
215 if (Info->vbcmdline == NULL) {
216 dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
217 Status = EFI_OUT_OF_RESOURCES;
218 return Status;
219 }
220 Info->vbcmdline_len = 2*DTB_PAD_SIZE;
221 Info->vbcmdline_filled_len = 0;
222 Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
223
224 return Status;
225}
226
227#if VERIFIED_BOOT_2
228/* Disable for VB 2.0 as this path is never taken */
229static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
230{
231 return ERROR;
232}
233static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
234{
235 return ERROR;
236}
237#else
238static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
239{
240 EFI_STATUS Status = EFI_SUCCESS;
241
242 if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
243 /* fastboot boot option image already loaded */
244 return Status;
245 }
246
247 Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
248 (UINT32 *)&(Info->images[0].imgsize));
249 if (Status != EFI_SUCCESS) {
250 dprintf(CRITICAL,
251 "ERROR: Failed to load image from partition: %d\n", Status);
252 return EFI_LOAD_ERROR;
253 }
254 Info->num_loaded_images = 1;
255 Info->images[0].name = malloc(strlen(Info->pname) + 1);
Monika Singh96b97212018-04-13 18:27:55 +0530256 strlcpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
Monika Singh5e170362018-03-14 00:48:36 +0530257 return Status;
258}
259
260static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
261{
262 EFI_STATUS Status = EFI_SUCCESS;
263 CHAR8 StrPname[MAX_GPT_NAME_SIZE];
264 CHAR8 Pname[MAX_GPT_NAME_SIZE];
265 CHAR8 *SystemPath = NULL;
266 UINT32 SystemPathLen = 0;
267 device_info DevInfo_vb;
268
269 GUARD(VBCommonInit(Info));
270 GUARD(LoadImageNoAuth(Info));
271 boot_verifier_init();
272
273 // FIXME: INIT devinfo()
274 DevInfo_vb.is_unlocked = !is_device_locked();
275 DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
276
Monika Singh96b97212018-04-13 18:27:55 +0530277 strlcpy(StrPname, "/", strlen("/"));
Monika Singh87794672018-05-19 19:10:47 +0530278 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530279 if (Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530280 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530281 } else {
Monika Singh87794672018-05-19 19:10:47 +0530282 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530283 }
284
285 Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
286 Info->images[0].imgsize,
287 StrPname,
288 &Info->boot_state);
289 if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
290 dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
291 return Status;
292 }
293
294 set_os_version((unsigned char *)Info->images[0].image_buffer);
295 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
296 return EFI_LOAD_ERROR;
297
298 SystemPathLen = GetSystemPath(&SystemPath);
299 if (SystemPathLen == 0 || SystemPath == NULL) {
300 dprintf(CRITICAL, "GetSystemPath failed!\n");
301 return EFI_LOAD_ERROR;
302 }
303 GUARD(AppendVBCommonCmdLine(Info));
304 GUARD(Appendvbcmdline(Info, VerityMode));
305 GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
306 GUARD(Appendvbcmdline(Info, SystemPath));
307
308 Info->vb_data = NULL;
309 return Status;
310}
311#endif
312
313static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
314{
315 switch (Result) {
316 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
317 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
318 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
319 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
320 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
321 return FALSE;
322
323 case AVB_SLOT_VERIFY_RESULT_OK:
324 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
325 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
326 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
327 return TRUE;
328 }
329
330 return FALSE;
331}
332
333char *pname[] = {
334 "sbl1",
335 "rpm",
336 "tz",
337 "aboot",
338};
339
340static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
341{
342 EFI_STATUS Status = EFI_SUCCESS;
343 AvbSlotVerifyResult Result;
344 AvbSlotVerifyData *SlotData = NULL;
345 VB2Data *VBData = NULL;
346 AvbOpsUserData *UserData = NULL;
347 AvbOps *Ops = NULL;
348 CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
349 CHAR8 *SlotSuffix = NULL;
350 BOOLEAN AllowVerificationError = !is_device_locked();
351 BOOLEAN VerityEnforcing = is_verity_enforcing();
352 const CHAR8 *RequestedPartitionMission[] = {"boot", "dtbo", NULL};
353 const CHAR8 *RequestedPartitionRecovery[] = {"recovery", "dtbo", NULL};
354 const CHAR8 **RequestedPartition = NULL;
355 UINTN NumRequestedPartition = 0;
356 UINT32 ImageHdrSize = 0;
357 UINT32 imgsizeActual = 0;
358 VOID *image_buffer = NULL;
359 UINT32 imgsize = 0;
360 AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
361 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
362 AVB_SLOT_VERIFY_FLAGS_NONE;
363 AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
364 device_info DevInfo_vb;
365
366 Info->boot_state = RED;
367 GUARD(VBCommonInit(Info));
368
369 UserData = avb_calloc(sizeof(AvbOpsUserData));
370 if (UserData == NULL) {
371 dprintf(CRITICAL,
372 "ERROR: Failed to allocate AvbOpsUserData\n");
373 Status = EFI_OUT_OF_RESOURCES;
374 goto out;
375 }
376
377 Ops = AvbOpsNew(UserData);
378 if (Ops == NULL) {
379 dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
380 Status = EFI_OUT_OF_RESOURCES;
381 goto out;
382 }
Monika Singh2c9d2b82018-05-01 12:24:59 +0530383 UserData->IsMultiSlot = Info->multi_slot_boot;
384
Monika Singh5e170362018-03-14 00:48:36 +0530385 if(Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530386 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530387 if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
388 dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
389 Status = EFI_INVALID_PARAMETER;
390 goto out;
391 }
392 SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
393 } else {
394 SlotSuffix = "\0";
395 }
396
397 if(!Info->multi_slot_boot && Info->bootinto_recovery) {
398 RequestedPartition = RequestedPartitionRecovery;
399 NumRequestedPartition = ARRAY_SIZE (RequestedPartitionRecovery) - 1;
400 if (Info->num_loaded_images) {
401 /* fastboot boot option, skip Index 0, as boot image already
402 * loaded */
403 RequestedPartition = &RequestedPartitionRecovery[1];
404 }
405 } else {
406 RequestedPartition = RequestedPartitionMission;
407 NumRequestedPartition = ARRAY_SIZE(RequestedPartitionMission) - 1;
408 if (Info->num_loaded_images) {
409 /* fastboot boot option, skip Index 0, as boot image already
410 * loaded */
411 RequestedPartition = &RequestedPartitionMission[1];
412 }
413 }
414 if (Info->num_loaded_images) {
415 NumRequestedPartition--;
416 }
417
418 // FIXME: is this correct?
419 VerityFlags = VerityEnforcing ?
420 AVB_HASHTREE_ERROR_MODE_RESTART :
421 AVB_HASHTREE_ERROR_MODE_EIO;
422
423 Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
424 VerifyFlags, VerityFlags,
425 &SlotData);
426
427 if (AllowVerificationError && ResultShouldContinue(Result)) {
428 dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
429 "%s, continue boot\n",
430 avb_slot_verify_result_to_string(Result));
431 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
432 dprintf(CRITICAL,
433 "ERROR: Device State %s, AvbSlotVerify returned %s\n",
434 AllowVerificationError ? "Unlocked" : "Locked",
435 avb_slot_verify_result_to_string(Result));
436 Status = EFI_LOAD_ERROR;
437 Info->boot_state = RED;
438 goto out;
439 }
Monika Singh0f7bfc82018-04-16 23:14:29 +0530440 if (SlotData == NULL) {
441 Status = EFI_LOAD_ERROR;
442 Info->boot_state = RED;
443 goto out;
444 }
Monika Singh5e170362018-03-14 00:48:36 +0530445
446 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
447 dprintf(DEBUG, "Requested Partition: %s\n",
448 RequestedPartition[ReqIndex]);
449 for (UINTN loadedindex = 0;
450 loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
451 dprintf(DEBUG, "Loaded Partition: %s\n",
452 SlotData->loaded_partitions[loadedindex].partition_name);
Monika Singh87794672018-05-19 19:10:47 +0530453 if (!strncmp(((const char *)RequestedPartition[ReqIndex]),
454 SlotData->loaded_partitions[loadedindex].partition_name,MAX_GPT_NAME_SIZE))
455 {
Monika Singh5e170362018-03-14 00:48:36 +0530456 if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
457 dprintf(CRITICAL, "NumLoadedPartition"
458 "(%d) too large "
459 "max images(%d)\n",
460 Info->num_loaded_images,
461 ARRAY_SIZE(Info->images));
462 Status = EFI_LOAD_ERROR;
463 Info->boot_state = RED;
464 goto out;
465 }
466 Info->images[Info->num_loaded_images].name =
467 SlotData->loaded_partitions[loadedindex].partition_name;
468 Info->images[Info->num_loaded_images].image_buffer =
469 SlotData->loaded_partitions[loadedindex].data;
470 Info->images[Info->num_loaded_images].imgsize =
471 SlotData->loaded_partitions[loadedindex].data_size;
472 Info->num_loaded_images++;
473 break;
474 }
475 }
476 }
477
478 if (Info->num_loaded_images < NumRequestedPartition) {
lijuang1f8c8322018-06-20 18:21:19 +0800479 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 +0530480 Status = EFI_LOAD_ERROR;
481 goto out;
482 }
483
484 dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
485
486 VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
487 if (VBData == NULL) {
488 dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
489 Status = EFI_OUT_OF_RESOURCES;
490 goto out;
491 }
492 VBData->Ops = Ops;
493 VBData->SlotData = SlotData;
494 Info->vb_data = (VOID *)VBData;
495
496 ImageHdrSize = get_page_size();
497 GUARD_OUT(getimage(Info, &image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
498
499 Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
500 if (Status != EFI_SUCCESS) {
501 dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
502 goto out;
503 }
504
505 if (imgsizeActual > imgsize) {
506 Status = EFI_BUFFER_TOO_SMALL;
507 dprintf(CRITICAL,
508 "Boot size in vbmeta less than actual boot image size "
509 "flash corresponding vbmeta.img\n");
510 goto out;
511 }
512 if (AllowVerificationError) {
513 Info->boot_state = ORANGE;
514 } else {
515 if (UserData->IsUserKey) {
516 Info->boot_state = YELLOW;
517 } else {
518 Info->boot_state = GREEN;
519 }
520 }
521
522 /* command line */
523 GUARD_OUT(AppendVBCommonCmdLine(Info));
524 GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
525 DevInfo_vb.is_unlocked = !is_device_locked();
526 set_os_version((unsigned char *)Info->images[0].image_buffer);
527 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
528 return EFI_LOAD_ERROR;
529 dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
530 VbSn[Info->boot_state].name);
531
532out:
533 if (Status != EFI_SUCCESS) {
534 if (SlotData != NULL) {
535 avb_slot_verify_data_free(SlotData);
536 }
537 if (Ops != NULL) {
538 AvbOpsFree(Ops);
539 }
540 if (UserData != NULL) {
541 avb_free(UserData);
542 }
543 if (VBData != NULL) {
544 avb_free(VBData);
545 }
546 Info->boot_state = RED;
547 if(Info->multi_slot_boot) {
548 HandleActiveSlotUnbootable();
549 /* HandleActiveSlotUnbootable should have swapped slots and
550 * reboot the device. If no bootable slot found, enter fastboot */
551 dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
552 } else {
553 dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
554 }
555
556 }
557
558 dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
559 VbSn[Info->boot_state].name, Info->boot_state);
560 return Status;
561}
562
563static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
564{
565 EFI_STATUS Status = EFI_SUCCESS;
566 CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
567
568 if (GetAVBVersion() < AVB_1) {
569 return EFI_SUCCESS;
570 }
571
Monika Singh87794672018-05-19 19:10:47 +0530572 if (!strncmp(Info->pname, "boot", MAX_GPT_NAME_SIZE)) {
Monika Singh5e170362018-03-14 00:48:36 +0530573 Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
574 if (Status != EFI_SUCCESS) {
575 dprintf(DEBUG,
576 "No Ffbm cookie found, ignore: %d\n", Status);
577 ffbm_mode_string[0] = '\0';
578 }
579 }
580
581 dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
582 switch (Info->boot_state)
583 {
584 case RED:
585 display_bootverify_menu(DISPLAY_MENU_RED);
586 //if (Status != EFI_SUCCESS) {
587 dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
588 "\nYour device will shutdown in 30s\n");
589 //}
590 udelay(30000000);
591 shutdown_device();
592 break;
593 case YELLOW:
594 display_bootverify_menu(DISPLAY_MENU_YELLOW);
595 //if (Status == EFI_SUCCESS) {
596 wait_for_users_action();
597 //} else {
598 dprintf(INFO, "Your device has loaded a different operating system." \
599 "\nWait for 5 seconds before proceeding\n");
600 udelay(5000000);
601 //}
602 break;
603 case ORANGE:
604 if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
605 dprintf(DEBUG, "Device will boot into FFBM mode\n");
606 } else {
Monika Singh90cf4b12018-04-09 16:47:15 +0530607 display_bootverify_menu(DISPLAY_MENU_ORANGE);
608 if (Status == EFI_SUCCESS) {
609 wait_for_users_action();
610 } else {
Monika Singh5e170362018-03-14 00:48:36 +0530611 dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
612 udelay(5000000);
Monika Singh90cf4b12018-04-09 16:47:15 +0530613 }
Monika Singh5e170362018-03-14 00:48:36 +0530614 }
615 break;
616 default:
617 break;
618 }
619 return EFI_SUCCESS;
620}
621
622EFI_STATUS load_image_and_auth(bootinfo *Info)
623{
624 EFI_STATUS Status = EFI_SUCCESS;
625 BOOLEAN MdtpActive = FALSE;
626 UINT32 AVBVersion = NO_AVB;
627 mdtp_ext_partition_verification_t ext_partition;
Monika Singh0f7bfc82018-04-16 23:14:29 +0530628 const char *current_slot_suffix;
629 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530630
631 if (Info == NULL) {
632 dprintf(CRITICAL, "Invalid parameter Info\n");
633 return EFI_INVALID_PARAMETER;
634 }
635
636 if (!Info->multi_slot_boot) {
637 if (Info->bootinto_recovery) {
638 dprintf(INFO, "Booting Into Recovery Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530639 strlcpy(Info->pname, "recovery", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530640 } else {
641 dprintf(INFO, "Booting Into Mission Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530642 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530643 }
644 } else {
Monika Singh87794672018-05-19 19:10:47 +0530645 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530646 current_active_slot = partition_find_active_slot();
647 if (current_active_slot != INVALID ) {
648 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
649 if (strlen(current_slot_suffix) == 0) {
650 dprintf(CRITICAL, "No bootable slot\n");
651 return EFI_LOAD_ERROR;
652 }
Monika Singh87794672018-05-19 19:10:47 +0530653 strlcat(Info->pname, current_slot_suffix, MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530654 }
Monika Singh5e170362018-03-14 00:48:36 +0530655 }
656
657 dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
658 BooleanString[Info->multi_slot_boot].name, Info->pname);
659
660 Status = mdtp_activated(&MdtpActive);
661 if (Status) {
662 dprintf(CRITICAL,
663 "Failed to get activation state for MDTP, "
664 "Status=%d."
665 " Considering MDTP as active and continuing \n",
666 Status);
667 if (Status != -1)
668 MdtpActive = TRUE;
669 }
670
671 AVBVersion = GetAVBVersion();
672 dprintf(DEBUG, "AVB version %d\n", AVBVersion);
673
674 /* Load and Authenticate */
675 switch (AVBVersion) {
676 case NO_AVB:
677 return LoadImageNoAuth(Info);
678 break;
679 case AVB_1:
680 Status = load_image_and_authVB1(Info);
681 break;
682 case AVB_2:
683 Status = load_image_and_authVB2(Info);
684 break;
685 default:
686 dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
687 Status = EFI_UNSUPPORTED;
688 }
689
690 // if MDTP is active Display Recovery UI
691 if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
692 //FIXME: Hard coded to BOOT
693 ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
694 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
695 ext_partition.page_size = get_page_size();
696 ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
697 ext_partition.image_size = Info->images[0].imgsize;
698 ext_partition.sig_avail = FALSE;
699 mdtp_fwlock_verify_lock(&ext_partition);
700 }
701
702 if (!is_device_locked() && Status != EFI_SUCCESS) {
703 dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
704 return Status;
705 }
706
707 DisplayVerifiedBootScreen(Info);
708
709 return Status;
710}
711
712#if VERIFIED_BOOT_2
713VOID free_verified_boot_resource(bootinfo *Info)
714{
715 dprintf(DEBUG, "free_verified_boot_resource\n");
716
717 if (Info == NULL) {
718 return;
719 }
720
721 VB2Data *VBData = Info->vb_data;
722 if (VBData != NULL) {
723 AvbOps *Ops = VBData->Ops;
724 if (Ops != NULL) {
725 if (Ops->user_data != NULL) {
726 avb_free(Ops->user_data);
727 }
728 AvbOpsFree(Ops);
729 }
730
731 AvbSlotVerifyData *SlotData = VBData->SlotData;
732 if (SlotData != NULL) {
733 avb_slot_verify_data_free(SlotData);
734 }
735 avb_free(VBData);
736 }
737
738 if (Info->vbcmdline != NULL) {
739 free(Info->vbcmdline);
740 }
741 return;
742}
743#else
744VOID free_verified_boot_resource(bootinfo *Info)
745{
746 return;
747}
748#endif