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