blob: 92a2c158a392d0b6af155ff27ae377fe745c46b9 [file] [log] [blame]
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "libavb/libavb.h"
#include <malloc.h>
#include <boot_verifier.h>
#include <ab_partition_parser.h>
#include <partition_parser.h>
#include <recovery.h>
#include <display_menu.h>
#include <../../../app/aboot/mdtp.h>
#include <platform/timer.h>
#include "verifiedboot.h"
#include <err.h>
#include <target.h>
#include <libavb/avb_sha.h>
#ifndef DTB_PAD_SIZE
#define DTB_PAD_SIZE 2048
#endif
#define INTERMEDIATE_DIGEST_LENGTH 64
#define MAX_PART_NAME_SIZE 10
#define MAX_NUM_REQ_PARTITION 8
#define BOOT_HEADER_VERSION_ZERO 0
char *avb_verify_partition_name[] = {
"boot",
"dtbo",
"vbmeta",
"recovery"
};
#ifndef MDTP_SUPPORT
int mdtp_activated(bool * activated)
{
return 0;
}
void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
{
return;
}
#endif
static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
static const CHAR8 *Space = " ";
#if !VERIFIED_BOOT_2
static const CHAR8 *VerityMode = " androidboot.veritymode=";
static struct verified_boot_verity_mode VbVm[] =
{
{FALSE, "logging"},
{TRUE, "enforcing"},
};
#endif
static struct verified_boot_state_name VbSn[] =
{
{GREEN, "green"},
{ORANGE, "orange"},
{YELLOW, "yellow"},
{RED, "red"},
};
struct boolean_string
{
BOOLEAN value;
CHAR8 *name;
};
static struct boolean_string BooleanString[] =
{
{FALSE, "false"},
{TRUE, "true"}
};
typedef struct {
AvbOps *Ops;
AvbSlotVerifyData *SlotData;
} VB2Data;
UINT32 GetAVBVersion()
{
#if VERIFIED_BOOT_2
return 2;
#elif VERIFIED_BOOT
return 1;
#else
return 0;
#endif
}
BOOLEAN VerifiedBootEnabled()
{
return (GetAVBVersion() > NO_AVB);
}
static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
{
/* These checks are already done before calling auth remove from here */
#if VERIFIED_BOOT || VERIFIED_BOOT_2
boot_verifier_init();
#endif
return 0;
}
static int HandleActiveSlotUnbootable()
{
int curr_slot;
curr_slot = partition_find_active_slot();
partition_deactivate_slot(curr_slot);
partition_find_boot_slot();
// should not reach here
return ERROR;
}
/*
* Returns length = 0 when there is failure.
*/
uint32_t GetSystemPath(char **SysPath)
{
INT32 Index;
UINT32 Lun;
CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
const char *current_slot_suffix;
int current_active_slot;
*SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
if (!*SysPath) {
dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
return 0;
}
strlcpy(PartitionName, "system", MAX_GPT_NAME_SIZE);
current_active_slot = partition_find_active_slot();
if (partition_multislot_is_supported()) {
if (current_active_slot == INVALID)
return 0;
current_slot_suffix = SUFFIX_SLOT(current_active_slot);
strlcat(PartitionName, current_slot_suffix, MAX_GPT_NAME_SIZE - 1);
}
Index = partition_get_index(PartitionName);
if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
dprintf(CRITICAL, "System partition does not exit\n");
free(*SysPath);
return 0;
}
Lun = partition_get_lun(Index);
if (platform_boot_dev_isemmc()) {
snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
Index + 1);
} else {
snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
LunCharMapping[Lun],
partition_get_index_in_lun(PartitionName, Lun));
}
dprintf(DEBUG, "System Path - %s \n", *SysPath);
return strlen(*SysPath);
}
static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
{
INT32 SrcLen = strlen(Src);
CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
strlcat(Dst, Src, SrcLen);
Info->vbcmdline_filled_len += SrcLen;
return EFI_SUCCESS;
}
static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
if (GetAVBVersion() >= AVB_1) {
GUARD(Appendvbcmdline(Info, VerifiedState));
GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
}
GUARD(Appendvbcmdline(Info, KeymasterLoadState));
GUARD(Appendvbcmdline(Info, Space));
return EFI_SUCCESS;
}
static EFI_STATUS VBCommonInit(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
Info->boot_state = RED;
// FIXME: Add boot call
/* allocate VB command line*/
Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
if (Info->vbcmdline == NULL) {
dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
Info->vbcmdline_len = 2*DTB_PAD_SIZE;
Info->vbcmdline_filled_len = 0;
Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
return Status;
}
#if VERIFIED_BOOT_2
/* Disable for VB 2.0 as this path is never taken */
static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
{
return ERROR;
}
static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
{
return ERROR;
}
#else
static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
/* fastboot boot option image already loaded */
return Status;
}
Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
(UINT32 *)&(Info->images[0].imgsize));
if (Status != EFI_SUCCESS) {
dprintf(CRITICAL,
"ERROR: Failed to load image from partition: %d\n", Status);
return EFI_LOAD_ERROR;
}
Info->num_loaded_images = 1;
Info->images[0].name = malloc(strlen(Info->pname) + 1);
strlcpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
return Status;
}
static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
CHAR8 StrPname[MAX_GPT_NAME_SIZE];
CHAR8 Pname[MAX_GPT_NAME_SIZE];
CHAR8 *SystemPath = NULL;
UINT32 SystemPathLen = 0;
device_info DevInfo_vb;
GUARD(VBCommonInit(Info));
GUARD(LoadImageNoAuth(Info));
boot_verifier_init();
// FIXME: INIT devinfo()
DevInfo_vb.is_unlocked = !is_device_locked();
DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
strlcpy(StrPname, "/", strlen("/"));
strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
if (Info->multi_slot_boot) {
strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
} else {
strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
}
Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
Info->images[0].imgsize,
StrPname,
&Info->boot_state);
if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
return Status;
}
set_os_version((unsigned char *)Info->images[0].image_buffer);
if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
return EFI_LOAD_ERROR;
SystemPathLen = GetSystemPath(&SystemPath);
if (SystemPathLen == 0 || SystemPath == NULL) {
dprintf(CRITICAL, "GetSystemPath failed!\n");
return EFI_LOAD_ERROR;
}
GUARD(AppendVBCommonCmdLine(Info));
GUARD(Appendvbcmdline(Info, VerityMode));
GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
GUARD(Appendvbcmdline(Info, SystemPath));
Info->vb_data = NULL;
return Status;
}
#endif
static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
{
switch (Result) {
case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
return FALSE;
case AVB_SLOT_VERIFY_RESULT_OK:
case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
return TRUE;
}
return FALSE;
}
char *pname[] = {
"sbl1",
"rpm",
"tz",
"aboot",
};
VOID AddRequestedPartition(CHAR8 **requestedpartititon, UINT32 index)
{
UINTN i;
for (i = 0; i < MAX_NUM_REQ_PARTITION; i++) {
if (requestedpartititon[i] == NULL){
requestedpartititon[i] = avb_verify_partition_name[index];
break;
}
}
}
static VOID ComputeVbMetaDigest (AvbSlotVerifyData* SlotData, CHAR8* Digest) {
size_t Index;
AvbSHA256Ctx Ctx;
avb_sha256_init (&Ctx);
for (Index = 0; Index < SlotData->num_vbmeta_images; Index++) {
avb_sha256_update (&Ctx,
SlotData->vbmeta_images[Index].vbmeta_data,
SlotData->vbmeta_images[Index].vbmeta_size);
}
avb_memcpy (Digest, avb_sha256_final(&Ctx), AVB_SHA256_DIGEST_SIZE);
}
static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
AvbSlotVerifyResult Result;
AvbSlotVerifyData *SlotData = NULL;
VB2Data *VBData = NULL;
AvbOpsUserData *UserData = NULL;
AvbOps *Ops = NULL;
CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
CHAR8 *SlotSuffix = NULL;
BOOLEAN AllowVerificationError = !is_device_locked();
BOOLEAN VerityEnforcing = is_verity_enforcing();
CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
const CHAR8 **RequestedPartition = NULL;
UINTN NumRequestedPartition = 0;
UINT32 HeaderVersion = 0;
UINT32 ImageHdrSize = 0;
UINT32 imgsizeActual = 0;
VOID *image_buffer = NULL;
UINT32 imgsize = 0;
AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
AVB_SLOT_VERIFY_FLAGS_NONE;
AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
device_info DevInfo_vb;
CHAR8 Digest[AVB_SHA256_DIGEST_SIZE] = {0};
HeaderVersion = Info->header_version;
Info->boot_state = RED;
GUARD(VBCommonInit(Info));
UserData = avb_calloc(sizeof(AvbOpsUserData));
if (UserData == NULL) {
dprintf(CRITICAL,
"ERROR: Failed to allocate AvbOpsUserData\n");
Status = EFI_OUT_OF_RESOURCES;
goto out;
}
Ops = AvbOpsNew(UserData);
if (Ops == NULL) {
dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
Status = EFI_OUT_OF_RESOURCES;
goto out;
}
UserData->IsMultiSlot = Info->multi_slot_boot;
if(Info->multi_slot_boot) {
strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
Status = EFI_INVALID_PARAMETER;
goto out;
}
SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
} else {
SlotSuffix = "\0";
}
if(!Info->multi_slot_boot && Info->bootinto_recovery) {
AddRequestedPartition(RequestedPartitionAll, IMG_RECOVERY);
NumRequestedPartition += 1;
/* Add dtbo validation if target supports dtbo image generation and
dtbo is not included in recovery i.e. HEADER VERSION is 0 */
if (is_target_support_dtbo() && HeaderVersion == BOOT_HEADER_VERSION_ZERO) {
AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
NumRequestedPartition += 1;
}
} else {
AddRequestedPartition(RequestedPartitionAll, IMG_BOOT);
NumRequestedPartition += 1;
if (is_target_support_dtbo()) {
AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
NumRequestedPartition += 1;
}
}
RequestedPartition = (const CHAR8 **)RequestedPartitionAll;
if (Info->num_loaded_images) {
/* fastboot boot option, skip Index 0, boot image already loaded */
RequestedPartition = (const CHAR8 **)&RequestedPartitionAll[1];
NumRequestedPartition--;
}
VerityFlags = VerityEnforcing ?
AVB_HASHTREE_ERROR_MODE_RESTART :
AVB_HASHTREE_ERROR_MODE_EIO;
Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
VerifyFlags, VerityFlags,
&SlotData);
if (AllowVerificationError && ResultShouldContinue(Result)) {
dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
"%s, continue boot\n",
avb_slot_verify_result_to_string(Result));
} else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
dprintf(CRITICAL,
"ERROR: Device State %s, AvbSlotVerify returned %s\n",
AllowVerificationError ? "Unlocked" : "Locked",
avb_slot_verify_result_to_string(Result));
Status = EFI_LOAD_ERROR;
Info->boot_state = RED;
goto out;
}
if (SlotData == NULL) {
Status = EFI_LOAD_ERROR;
Info->boot_state = RED;
goto out;
}
for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
dprintf(DEBUG, "Requested Partition: %s\n",
RequestedPartition[ReqIndex]);
for (UINTN loadedindex = 0;
loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
dprintf(DEBUG, "Loaded Partition: %s\n",
SlotData->loaded_partitions[loadedindex].partition_name);
if (!strncmp(((const char *)RequestedPartition[ReqIndex]),
SlotData->loaded_partitions[loadedindex].partition_name,MAX_GPT_NAME_SIZE))
{
if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
dprintf(CRITICAL, "NumLoadedPartition"
"(%d) too large "
"max images(%d)\n",
Info->num_loaded_images,
ARRAY_SIZE(Info->images));
Status = EFI_LOAD_ERROR;
Info->boot_state = RED;
goto out;
}
Info->images[Info->num_loaded_images].name =
SlotData->loaded_partitions[loadedindex].partition_name;
Info->images[Info->num_loaded_images].image_buffer =
SlotData->loaded_partitions[loadedindex].data;
Info->images[Info->num_loaded_images].imgsize =
SlotData->loaded_partitions[loadedindex].data_size;
Info->num_loaded_images++;
break;
}
}
}
if (Info->num_loaded_images < NumRequestedPartition) {
dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %llu\n",Info->num_loaded_images, NumRequestedPartition);
Status = EFI_LOAD_ERROR;
goto out;
}
dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
if (VBData == NULL) {
dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
Status = EFI_OUT_OF_RESOURCES;
goto out;
}
VBData->Ops = Ops;
VBData->SlotData = SlotData;
Info->vb_data = (VOID *)VBData;
ImageHdrSize = get_page_size();
GUARD_OUT(getimage(&image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
if (Status != EFI_SUCCESS) {
dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
goto out;
}
if (imgsizeActual > imgsize) {
Status = EFI_BUFFER_TOO_SMALL;
dprintf(CRITICAL,
"Boot size in vbmeta less than actual boot image size "
"flash corresponding vbmeta.img\n");
goto out;
}
if (AllowVerificationError) {
Info->boot_state = ORANGE;
} else {
if (UserData->IsUserKey) {
Info->boot_state = YELLOW;
} else {
Info->boot_state = GREEN;
}
}
/* command line */
GUARD_OUT(AppendVBCommonCmdLine(Info));
GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
DevInfo_vb.is_unlocked = !is_device_locked();
set_os_version(ADD_SALT_BUFF_OFFSET(Info->images[0].image_buffer));
if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
return EFI_LOAD_ERROR;
ComputeVbMetaDigest(SlotData, (CHAR8 *)&Digest);
GUARD_OUT(set_verified_boot_hash((const CHAR8 *)&Digest, sizeof(Digest)));
dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
VbSn[Info->boot_state].name);
out:
if (Status != EFI_SUCCESS) {
if (SlotData != NULL) {
avb_slot_verify_data_free(SlotData);
}
if (Ops != NULL) {
AvbOpsFree(Ops);
}
if (UserData != NULL) {
avb_free(UserData);
}
if (VBData != NULL) {
avb_free(VBData);
}
Info->boot_state = RED;
if(Info->multi_slot_boot) {
HandleActiveSlotUnbootable();
/* HandleActiveSlotUnbootable should have swapped slots and
* reboot the device. If no bootable slot found, enter fastboot */
dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
} else {
dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
}
}
dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
VbSn[Info->boot_state].name, Info->boot_state);
return Status;
}
static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
if (GetAVBVersion() < AVB_1) {
return EFI_SUCCESS;
}
if (!strncmp(Info->pname, "boot", MAX_GPT_NAME_SIZE)) {
Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
if (Status != EFI_SUCCESS) {
dprintf(DEBUG,
"No Ffbm cookie found, ignore: %d\n", Status);
ffbm_mode_string[0] = '\0';
}
}
dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
switch (Info->boot_state)
{
case RED:
display_bootverify_menu(DISPLAY_MENU_RED);
//if (Status != EFI_SUCCESS) {
dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
"\nYour device will shutdown in 30s\n");
//}
udelay(30000000);
shutdown_device();
break;
case YELLOW:
display_bootverify_menu(DISPLAY_MENU_YELLOW);
//if (Status == EFI_SUCCESS) {
wait_for_users_action();
//} else {
dprintf(INFO, "Your device has loaded a different operating system." \
"\nWait for 5 seconds before proceeding\n");
udelay(5000000);
//}
break;
case ORANGE:
if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
dprintf(DEBUG, "Device will boot into FFBM mode\n");
} else {
display_bootverify_menu(DISPLAY_MENU_ORANGE);
if (Status == EFI_SUCCESS) {
wait_for_users_action();
} else {
dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
udelay(5000000);
}
}
break;
default:
break;
}
return EFI_SUCCESS;
}
EFI_STATUS load_image_and_auth(bootinfo *Info)
{
EFI_STATUS Status = EFI_SUCCESS;
BOOLEAN MdtpActive = FALSE;
UINT32 AVBVersion = NO_AVB;
mdtp_ext_partition_verification_t ext_partition;
const char *current_slot_suffix;
int current_active_slot;
if (Info == NULL) {
dprintf(CRITICAL, "Invalid parameter Info\n");
return EFI_INVALID_PARAMETER;
}
if (!Info->multi_slot_boot) {
if (Info->bootinto_recovery) {
dprintf(INFO, "Booting Into Recovery Mode\n");
strlcpy(Info->pname, "recovery", MAX_GPT_NAME_SIZE);
} else {
dprintf(INFO, "Booting Into Mission Mode\n");
strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
}
} else {
strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
current_active_slot = partition_find_active_slot();
if (current_active_slot != INVALID ) {
current_slot_suffix = SUFFIX_SLOT(current_active_slot);
if (strlen(current_slot_suffix) == 0) {
dprintf(CRITICAL, "No bootable slot\n");
return EFI_LOAD_ERROR;
}
strlcat(Info->pname, current_slot_suffix, MAX_GPT_NAME_SIZE);
}
}
dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
BooleanString[Info->multi_slot_boot].name, Info->pname);
Status = mdtp_activated(&MdtpActive);
if (Status) {
dprintf(CRITICAL,
"Failed to get activation state for MDTP, "
"Status=%d."
" Considering MDTP as active and continuing \n",
Status);
if (Status != -1)
MdtpActive = TRUE;
}
AVBVersion = GetAVBVersion();
dprintf(DEBUG, "AVB version %d\n", AVBVersion);
/* Load and Authenticate */
switch (AVBVersion) {
case NO_AVB:
return LoadImageNoAuth(Info);
break;
case AVB_1:
Status = load_image_and_authVB1(Info);
break;
case AVB_2:
Status = load_image_and_authVB2(Info);
break;
default:
dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
Status = EFI_UNSUPPORTED;
}
// if MDTP is active Display Recovery UI
if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
//FIXME: Hard coded to BOOT
ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
ext_partition.page_size = get_page_size();
ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
ext_partition.image_size = Info->images[0].imgsize;
ext_partition.sig_avail = FALSE;
mdtp_fwlock_verify_lock(&ext_partition);
}
if (!is_device_locked() && Status != EFI_SUCCESS) {
dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
return Status;
}
DisplayVerifiedBootScreen(Info);
return Status;
}
#if VERIFIED_BOOT_2
VOID free_verified_boot_resource(bootinfo *Info)
{
dprintf(DEBUG, "free_verified_boot_resource\n");
if (Info == NULL) {
return;
}
VB2Data *VBData = Info->vb_data;
if (VBData != NULL) {
AvbOps *Ops = VBData->Ops;
if (Ops != NULL) {
if (Ops->user_data != NULL) {
avb_free(Ops->user_data);
}
AvbOpsFree(Ops);
}
AvbSlotVerifyData *SlotData = VBData->SlotData;
if (SlotData != NULL) {
avb_slot_verify_data_free(SlotData);
}
avb_free(VBData);
}
if (Info->vbcmdline != NULL) {
free(Info->vbcmdline);
}
return;
}
#else
VOID free_verified_boot_resource(bootinfo *Info)
{
return;
}
#endif