Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1 | /* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 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 "VerifiedBoot.h" |
| 30 | #include "BootLinux.h" |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 31 | #include "BootImage.h" |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 32 | #include "KeymasterClient.h" |
| 33 | #include "libavb/libavb.h" |
jianzhou | b8a6fe0 | 2020-05-06 16:28:19 +0800 | [diff] [blame] | 34 | #include <FastbootLib/FastbootCmds.h> |
Shivaprasad Hongal | f1fb047 | 2017-05-23 20:05:16 -0700 | [diff] [blame] | 35 | #include <Library/MenuKeysDetection.h> |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 36 | #include <Library/VerifiedBootMenu.h> |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 37 | #include <Library/LEOEMCertificate.h> |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 38 | |
| 39 | STATIC CONST CHAR8 *VerityMode = " androidboot.veritymode="; |
| 40 | STATIC CONST CHAR8 *VerifiedState = " androidboot.verifiedbootstate="; |
| 41 | STATIC CONST CHAR8 *KeymasterLoadState = " androidboot.keymaster=1"; |
Mukesh Ojha | 71be2c8 | 2018-02-02 19:13:10 +0530 | [diff] [blame] | 42 | STATIC CONST CHAR8 *DmVerityCmd = " root=/dev/dm-0 dm=\"system none ro,0 1 " |
| 43 | "android-verity"; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 44 | STATIC CONST CHAR8 *Space = " "; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 45 | |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 46 | #define MAX_NUM_REQ_PARTITION 8 |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 47 | #define MAX_PROPERTY_SIZE 10 |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 48 | |
| 49 | static CHAR8 *avb_verify_partition_name[] = { |
| 50 | "boot", |
| 51 | "dtbo", |
| 52 | "vbmeta", |
AnilKumar Chimata | 3597bc1 | 2018-07-05 15:53:25 +0530 | [diff] [blame] | 53 | "recovery", |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 54 | "vendor_boot" |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 55 | }; |
| 56 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 57 | STATIC struct verified_boot_verity_mode VbVm[] = { |
| 58 | {FALSE, "logging"}, |
| 59 | {TRUE, "enforcing"}, |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 60 | }; |
| 61 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 62 | STATIC struct verified_boot_state_name VbSn[] = { |
| 63 | {GREEN, "green"}, |
| 64 | {ORANGE, "orange"}, |
| 65 | {YELLOW, "yellow"}, |
| 66 | {RED, "red"}, |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 67 | }; |
| 68 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 69 | struct boolean_string { |
| 70 | BOOLEAN value; |
| 71 | CHAR8 *name; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 72 | }; |
| 73 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 74 | STATIC struct boolean_string BooleanString[] = { |
| 75 | {FALSE, "false"}, |
| 76 | {TRUE, "true"} |
| 77 | }; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 78 | |
| 79 | typedef struct { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 80 | AvbOps *Ops; |
| 81 | AvbSlotVerifyData *SlotData; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 82 | } VB2Data; |
| 83 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 84 | UINT32 |
| 85 | GetAVBVersion () |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 86 | { |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 87 | #if VERIFIED_BOOT_LE |
| 88 | return AVB_LE; |
| 89 | #elif VERIFIED_BOOT_2 |
| 90 | return AVB_2; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 91 | #elif VERIFIED_BOOT |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 92 | return AVB_1; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 93 | #else |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 94 | return NO_AVB; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 95 | #endif |
| 96 | } |
| 97 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 98 | BOOLEAN |
| 99 | VerifiedBootEnbled () |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 100 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 101 | return (GetAVBVersion () > NO_AVB); |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 102 | } |
| 103 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 104 | STATIC EFI_STATUS |
| 105 | AppendVBCmdLine (BootInfo *Info, CONST CHAR8 *Src) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 106 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 107 | EFI_STATUS Status = EFI_SUCCESS; |
| 108 | INT32 SrcLen = AsciiStrLen (Src); |
| 109 | CHAR8 *Dst = Info->VBCmdLine + Info->VBCmdLineFilledLen; |
| 110 | INT32 DstLen = Info->VBCmdLineLen - Info->VBCmdLineFilledLen; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 111 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 112 | GUARD (AsciiStrnCatS (Dst, DstLen, Src, SrcLen)); |
| 113 | Info->VBCmdLineFilledLen += SrcLen; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 114 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 115 | return EFI_SUCCESS; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 116 | } |
| 117 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 118 | STATIC EFI_STATUS |
| 119 | AppendVBCommonCmdLine (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 120 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 121 | EFI_STATUS Status = EFI_SUCCESS; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 122 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 123 | if (Info->VbIntf->Revision >= QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) { |
| 124 | GUARD (AppendVBCmdLine (Info, VerifiedState)); |
| 125 | GUARD (AppendVBCmdLine (Info, VbSn[Info->BootState].name)); |
| 126 | } |
| 127 | GUARD (AppendVBCmdLine (Info, KeymasterLoadState)); |
| 128 | GUARD (AppendVBCmdLine (Info, Space)); |
| 129 | return EFI_SUCCESS; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 130 | } |
| 131 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 132 | STATIC EFI_STATUS |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 133 | NoAVBLoadReqImage (BootInfo *Info, VOID **DtboImage, |
| 134 | UINT32 *DtboSize, CHAR16 *Pname, CHAR16 *RequestedPartition) |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 135 | { |
| 136 | EFI_STATUS Status = EFI_SUCCESS; |
| 137 | Slot CurrentSlot; |
Bhanuprakash Modem | 87f2c3e | 2018-07-09 19:08:13 +0530 | [diff] [blame] | 138 | CHAR8 *AsciiPname = NULL; |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 139 | UINT64 PartSize = 0; |
| 140 | AvbIOResult AvbStatus; |
| 141 | AvbOpsUserData *UserData = NULL; |
| 142 | AvbOps *Ops = NULL; |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 143 | |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 144 | GUARD ( StrnCpyS (Pname, |
| 145 | (UINTN)MAX_GPT_NAME_SIZE, |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 146 | (CONST CHAR16 *)RequestedPartition, |
| 147 | StrLen (RequestedPartition))); |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 148 | |
| 149 | if (Info->MultiSlotBoot) { |
| 150 | CurrentSlot = GetCurrentSlotSuffix (); |
| 151 | GUARD ( StrnCatS (Pname, MAX_GPT_NAME_SIZE, |
| 152 | CurrentSlot.Suffix, StrLen (CurrentSlot.Suffix))); |
| 153 | } |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 154 | if (GetPartitionIndex (Pname) == INVALID_PTN) { |
| 155 | Status = EFI_NO_MEDIA; |
| 156 | goto out; |
| 157 | } |
| 158 | |
| 159 | /* Get Partition size & compare with MAX supported size |
| 160 | * If Partition size > DTBO_MAX_SIZE_ALLOWED return |
| 161 | * Allocate Partition size memory otherwise |
| 162 | */ |
| 163 | UserData = avb_calloc (sizeof (AvbOpsUserData)); |
| 164 | if (UserData == NULL) { |
| 165 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOpsUserData\n")); |
| 166 | Status = EFI_OUT_OF_RESOURCES; |
| 167 | goto out; |
| 168 | } |
| 169 | Ops = AvbOpsNew (UserData); |
| 170 | if (Ops == NULL) { |
| 171 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOps\n")); |
| 172 | Status = EFI_OUT_OF_RESOURCES; |
| 173 | goto out; |
| 174 | } |
Bhanuprakash Modem | 87f2c3e | 2018-07-09 19:08:13 +0530 | [diff] [blame] | 175 | AsciiPname = avb_calloc (MAX_GPT_NAME_SIZE); |
| 176 | if (AsciiPname == NULL) { |
| 177 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AsciiPname\n")); |
| 178 | Status = EFI_OUT_OF_RESOURCES; |
| 179 | goto out; |
| 180 | } |
| 181 | UnicodeStrToAsciiStr (Pname, AsciiPname); |
| 182 | |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 183 | AvbStatus = Ops->get_size_of_partition (Ops, |
Bhanuprakash Modem | 87f2c3e | 2018-07-09 19:08:13 +0530 | [diff] [blame] | 184 | AsciiPname, |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 185 | &PartSize); |
| 186 | if (AvbStatus != AVB_IO_RESULT_OK || |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 187 | PartSize == 0) { |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 188 | DEBUG ((EFI_D_ERROR, "VB: Failed to get partition size " |
| 189 | "(or) DTBO size is too big: 0x%x\n", PartSize)); |
| 190 | Status = EFI_OUT_OF_RESOURCES; |
| 191 | goto out; |
| 192 | } |
| 193 | |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 194 | if ((AsciiStrStr (AsciiPname, "dtbo")) && |
| 195 | (PartSize > DTBO_MAX_SIZE_ALLOWED)) { |
| 196 | DEBUG ((EFI_D_ERROR, "DTBO size is too big: 0x%x\n", PartSize)); |
| 197 | Status = EFI_OUT_OF_RESOURCES; |
| 198 | goto out; |
| 199 | } |
| 200 | |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 201 | DEBUG ((EFI_D_VERBOSE, "VB: Trying to allocate memory " |
| 202 | "for DTBO: 0x%x\n", PartSize)); |
| 203 | *DtboSize = (UINT32) PartSize; |
Bhanuprakash Modem | 763cdd5 | 2018-11-01 14:49:55 +0530 | [diff] [blame] | 204 | *DtboImage = AllocateZeroPool (PartSize); |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 205 | |
| 206 | if (*DtboImage == NULL) { |
| 207 | DEBUG ((EFI_D_ERROR, "VB: Unable to allocate memory for DTBO\n")); |
| 208 | Status = EFI_OUT_OF_RESOURCES; |
| 209 | goto out; |
| 210 | } |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 211 | Status = LoadImageFromPartition (*DtboImage, DtboSize, Pname); |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 212 | |
| 213 | out: |
| 214 | if (Ops != NULL) { |
| 215 | AvbOpsFree (Ops); |
| 216 | } |
| 217 | if (UserData != NULL) { |
| 218 | avb_free (UserData); |
| 219 | } |
Bhanuprakash Modem | 87f2c3e | 2018-07-09 19:08:13 +0530 | [diff] [blame] | 220 | if (AsciiPname != NULL) { |
| 221 | avb_free (AsciiPname); |
| 222 | } |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 223 | return Status; |
| 224 | } |
| 225 | |
| 226 | STATIC EFI_STATUS |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 227 | VBCommonInit (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 228 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 229 | EFI_STATUS Status = EFI_SUCCESS; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 230 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 231 | Info->BootState = RED; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 232 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 233 | Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL, |
| 234 | (VOID **)&(Info->VbIntf)); |
| 235 | if (Status != EFI_SUCCESS) { |
| 236 | DEBUG ((EFI_D_ERROR, "Unable to locate VB protocol: %r\n", Status)); |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 237 | return Status; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 238 | } |
| 239 | |
| 240 | return Status; |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 241 | } |
| 242 | |
Jeevan Shriram | 615b1e1 | 2017-10-12 14:10:06 -0700 | [diff] [blame] | 243 | /* |
| 244 | * Ensure Info->Pname is already updated before this function is called. |
| 245 | * If Command line already has "root=", return TRUE, else FALSE. |
| 246 | */ |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 247 | STATIC EFI_STATUS |
| 248 | VBAllocateCmdLine (BootInfo *Info) |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 249 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 250 | EFI_STATUS Status = EFI_SUCCESS; |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 251 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 252 | /* allocate VB command line*/ |
Bhanuprakash Modem | 763cdd5 | 2018-11-01 14:49:55 +0530 | [diff] [blame] | 253 | Info->VBCmdLine = AllocateZeroPool (DTB_PAD_SIZE); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 254 | if (Info->VBCmdLine == NULL) { |
| 255 | DEBUG ((EFI_D_ERROR, "VB CmdLine allocation failed!\n")); |
| 256 | Status = EFI_OUT_OF_RESOURCES; |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 257 | return Status; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 258 | } |
| 259 | Info->VBCmdLineLen = DTB_PAD_SIZE; |
| 260 | Info->VBCmdLineFilledLen = 0; |
| 261 | Info->VBCmdLine[Info->VBCmdLineFilledLen] = '\0'; |
| 262 | |
| 263 | return Status; |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 264 | } |
| 265 | |
Jeevan Shriram | 615b1e1 | 2017-10-12 14:10:06 -0700 | [diff] [blame] | 266 | STATIC |
| 267 | BOOLEAN |
| 268 | IsRootCmdLineUpdated (BootInfo *Info) |
| 269 | { |
| 270 | CHAR8* ImageCmdLine = NULL; |
| 271 | |
| 272 | ImageCmdLine = |
| 273 | (CHAR8*) & (((boot_img_hdr*) (Info->Images[0].ImageBuffer))->cmdline[0]); |
| 274 | |
| 275 | ImageCmdLine[BOOT_ARGS_SIZE - 1] = '\0'; |
| 276 | if (AsciiStrStr (ImageCmdLine, "root=")) { |
| 277 | return TRUE; |
| 278 | } else { |
| 279 | return FALSE; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 284 | /** |
| 285 | Load Vendor Boot image if the boot image is v3 |
| 286 | **/ |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 287 | STATIC EFI_STATUS |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 288 | NoAVBLoadVendorBootImage (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 289 | { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 290 | EFI_STATUS Status; |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 291 | CHAR16 Pname[MAX_GPT_NAME_SIZE]; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 292 | UINT8 ImgIdx = Info->NumLoadedImages; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 293 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 294 | Status = NoAVBLoadReqImage (Info, |
| 295 | (VOID **)&(Info->Images[ImgIdx].ImageBuffer), |
| 296 | (UINT32 *)&(Info->Images[ImgIdx].ImageSize), |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 297 | Pname, (CHAR16 *)L"vendor_boot"); |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 298 | if (Status == EFI_NO_MEDIA) { |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 299 | DEBUG ((EFI_D_INFO, "No vendor_boot partition is found, Skipping\n")); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 300 | if (Info->Images[ImgIdx].ImageBuffer != NULL) { |
| 301 | FreePool (Info->Images[ImgIdx].ImageBuffer); |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 302 | } |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 303 | return EFI_SUCCESS; |
| 304 | } |
| 305 | else if (Status != EFI_SUCCESS) { |
| 306 | DEBUG ((EFI_D_ERROR, |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 307 | "ERROR: Failed to load vendor_boot from partition: %r\n", Status)); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 308 | if (Info->Images[ImgIdx].ImageBuffer != NULL) { |
| 309 | goto Err; |
Bhanuprakash Modem | ee92f01 | 2018-06-21 17:27:14 +0530 | [diff] [blame] | 310 | } |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 311 | } |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 312 | |
| 313 | Info-> Images[ImgIdx].Name = AllocateZeroPool (StrLen (Pname) + 1); |
| 314 | if (!Info-> Images[ImgIdx].Name) { |
| 315 | Status = EFI_OUT_OF_RESOURCES; |
| 316 | goto Err; |
| 317 | } |
| 318 | |
| 319 | UnicodeStrToAsciiStr (Pname, Info->Images[ImgIdx].Name); |
| 320 | Info-> NumLoadedImages++; |
| 321 | |
| 322 | return EFI_SUCCESS; |
| 323 | |
| 324 | Err: |
| 325 | FreePool (Info->Images[ImgIdx].ImageBuffer); |
| 326 | return Status; |
| 327 | } |
| 328 | |
| 329 | STATIC EFI_STATUS |
| 330 | LoadVendorBootImageHeader (BootInfo *Info, |
| 331 | VOID **VendorImageHdrBuffer, |
| 332 | UINT32 *VendorImageHdrSize) |
| 333 | { |
| 334 | EFI_STATUS Status = EFI_SUCCESS; |
| 335 | CHAR16 Pname[MAX_GPT_NAME_SIZE] = {0}; |
| 336 | |
| 337 | StrnCpyS (Pname, ARRAY_SIZE (Pname), |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 338 | (CHAR16 *)L"vendor_boot", StrLen ((CHAR16 *)L"vendor_boot")); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 339 | |
| 340 | if (Info->MultiSlotBoot) { |
| 341 | GUARD (StrnCatS (Pname, ARRAY_SIZE (Pname), |
| 342 | GetCurrentSlotSuffix ().Suffix, |
| 343 | StrLen (GetCurrentSlotSuffix ().Suffix))); |
| 344 | } |
| 345 | |
| 346 | return LoadImageHeader (Pname, VendorImageHdrBuffer, VendorImageHdrSize); |
| 347 | } |
| 348 | |
| 349 | STATIC EFI_STATUS |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 350 | LoadBootImageNoAuth (BootInfo *Info, UINT32 *PageSize, BOOLEAN *FastbootPath) |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 351 | { |
| 352 | EFI_STATUS Status = EFI_SUCCESS; |
| 353 | VOID *ImageHdrBuffer = NULL; |
| 354 | UINT32 ImageHdrSize = 0; |
| 355 | UINT32 ImageSizeActual = 0; |
| 356 | VOID *VendorImageHdrBuffer = NULL; |
| 357 | UINT32 VendorImageHdrSize = 0; |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 358 | BOOLEAN BootIntoRecovery = FALSE; |
| 359 | BOOLEAN BootImageLoaded; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 360 | |
| 361 | /** The Images[0].ImageBuffer would have been loaded with the boot image |
| 362 | * already if we are coming from fastboot boot path. Ignore loading it |
| 363 | * again. |
| 364 | **/ |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 365 | BootImageLoaded = (Info->Images[0].ImageBuffer != NULL) && |
| 366 | (Info->Images[0].ImageSize > 0); |
| 367 | *FastbootPath = BootImageLoaded; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 368 | |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 369 | if (BootImageLoaded) { |
| 370 | ImageHdrBuffer = Info->Images[0].ImageBuffer; |
| 371 | ImageHdrSize = BOOT_IMG_MAX_PAGE_SIZE; |
| 372 | } else { |
| 373 | Status = LoadImageHeader (Info->Pname, &ImageHdrBuffer, &ImageHdrSize); |
| 374 | if (Status != EFI_SUCCESS || |
| 375 | ImageHdrBuffer == NULL) { |
| 376 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to load image header: %r\n", Status)); |
| 377 | return Status; |
| 378 | } else if (ImageHdrSize < sizeof (boot_img_hdr)) { |
| 379 | DEBUG ((EFI_D_ERROR, |
| 380 | "ERROR: Invalid image header size: %u\n", ImageHdrSize)); |
| 381 | return EFI_BAD_BUFFER_SIZE; |
| 382 | } |
| 383 | |
| 384 | BootIntoRecovery = Info->BootIntoRecovery; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | Info->HeaderVersion = ((boot_img_hdr *)(ImageHdrBuffer))->header_version; |
| 388 | |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 389 | /* Additional vendor_boot image header needs be loaded for header |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 390 | * versions than 3. Consider both the headers for validation. |
| 391 | */ |
| 392 | if (Info->HeaderVersion >= BOOT_HEADER_VERSION_THREE) { |
| 393 | Status = LoadVendorBootImageHeader (Info, &VendorImageHdrBuffer, |
| 394 | &VendorImageHdrSize); |
| 395 | if (Status != EFI_SUCCESS) { |
| 396 | DEBUG ((EFI_D_ERROR, |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 397 | "ERROR: Failed to load vendor_boot Image header: %r\n", Status)); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 398 | goto ErrV3; |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | /* Add check for boot image header, kernel page size, |
| 403 | * and ensure kernel command line is terminate. |
| 404 | */ |
| 405 | Status = CheckImageHeader (ImageHdrBuffer, ImageHdrSize, |
| 406 | VendorImageHdrBuffer, VendorImageHdrSize, |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 407 | &ImageSizeActual, PageSize, BootIntoRecovery); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 408 | if (Status != EFI_SUCCESS) { |
| 409 | DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status)); |
| 410 | goto Err; |
| 411 | } |
| 412 | |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 413 | if (!BootImageLoaded) { |
| 414 | Status = LoadImage (Info->Pname, (VOID **)&(Info->Images[0].ImageBuffer), |
| 415 | ImageSizeActual, *PageSize); |
| 416 | if (Status != EFI_SUCCESS) { |
| 417 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to load image from partition: %r\n", |
| 418 | Status)); |
| 419 | goto Err; |
| 420 | } |
| 421 | |
| 422 | Info->Images[0].Name = AllocateZeroPool (StrLen (Info->Pname) + 1); |
| 423 | if (!Info->Images[0].Name) { |
| 424 | Status = EFI_OUT_OF_RESOURCES; |
| 425 | goto ErrImg; |
| 426 | } |
| 427 | UnicodeStrToAsciiStr (Info->Pname, Info->Images[0].Name); |
| 428 | Info->NumLoadedImages = 1; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 429 | } |
| 430 | |
| 431 | Info->Images[0].ImageSize = ImageSizeActual; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 432 | |
| 433 | if (Info->HeaderVersion >= BOOT_HEADER_VERSION_THREE) { |
| 434 | Status = NoAVBLoadVendorBootImage (Info); |
| 435 | if (Status != EFI_SUCCESS) { |
| 436 | DEBUG ((EFI_D_ERROR, |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 437 | "ERROR: Failed to load vendor_boot Image : %r\n", Status)); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 438 | goto ErrImgName; |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | return EFI_SUCCESS; |
| 443 | |
| 444 | ErrImgName: |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 445 | if (!BootImageLoaded && |
| 446 | Info->Images[0].Name) { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 447 | FreePool (Info->Images[0].Name); |
| 448 | } |
| 449 | ErrImg: |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 450 | if (!BootImageLoaded && |
| 451 | Info->Images[0].ImageBuffer) { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 452 | UINT32 ImageSize = |
| 453 | ADD_OF (ROUND_TO_PAGE (ImageSizeActual, (*PageSize - 1)), *PageSize); |
| 454 | FreePages (Info->Images[0].ImageBuffer, |
| 455 | ALIGN_PAGES (ImageSize, ALIGNMENT_MASK_4KB)); |
| 456 | } |
| 457 | Err: |
| 458 | if (VendorImageHdrBuffer) { |
| 459 | FreePages (VendorImageHdrBuffer, |
| 460 | ALIGN_PAGES (BOOT_IMG_MAX_PAGE_SIZE, ALIGNMENT_MASK_4KB)); |
| 461 | } |
| 462 | ErrV3: |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 463 | if (!BootImageLoaded && |
| 464 | ImageHdrBuffer) { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 465 | FreePages (ImageHdrBuffer, |
| 466 | ALIGN_PAGES (BOOT_IMG_MAX_PAGE_SIZE, ALIGNMENT_MASK_4KB)); |
| 467 | } |
| 468 | |
| 469 | return Status; |
| 470 | } |
| 471 | |
| 472 | STATIC EFI_STATUS |
| 473 | LoadImageNoAuth (BootInfo *Info) |
| 474 | { |
| 475 | EFI_STATUS Status = EFI_SUCCESS; |
| 476 | CHAR16 Pname[MAX_GPT_NAME_SIZE]; |
| 477 | UINTN *ImgIdx = &Info->NumLoadedImages; |
| 478 | UINT32 PageSize = 0; |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 479 | BOOLEAN FastbootPath; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 480 | |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 481 | Status = LoadBootImageNoAuth (Info, &PageSize, &FastbootPath); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 482 | if (Status != EFI_SUCCESS) { |
| 483 | return Status; |
| 484 | } |
| 485 | |
| 486 | /*load dt overlay when avb is disabled*/ |
| 487 | Status = NoAVBLoadReqImage (Info, |
| 488 | (VOID **)&(Info->Images[*ImgIdx].ImageBuffer), |
| 489 | (UINT32 *)&(Info->Images[*ImgIdx].ImageSize), |
| 490 | Pname, (CHAR16 *)L"dtbo"); |
| 491 | if (Status == EFI_NO_MEDIA) { |
| 492 | DEBUG ((EFI_D_INFO, "No dtbo partition is found, Skip dtbo\n")); |
| 493 | if (Info->Images[*ImgIdx].ImageBuffer != NULL) { |
| 494 | FreePool (Info->Images[*ImgIdx].ImageBuffer); |
| 495 | } |
| 496 | } |
| 497 | else if (Status != EFI_SUCCESS) { |
| 498 | DEBUG ((EFI_D_ERROR, |
| 499 | "ERROR: Failed to load dtbo from partition: %r\n", Status)); |
| 500 | Status = EFI_LOAD_ERROR; |
| 501 | goto Err; |
| 502 | } else { /* EFI_SUCCESS */ |
| 503 | Info-> Images[*ImgIdx].Name = AllocateZeroPool (StrLen (Pname) + 1); |
| 504 | if (!Info->Images[*ImgIdx].Name) { |
| 505 | Status = EFI_OUT_OF_RESOURCES; |
| 506 | goto Err; |
| 507 | } |
| 508 | |
| 509 | UnicodeStrToAsciiStr (Pname, Info->Images[*ImgIdx].Name); |
| 510 | ++(*ImgIdx); |
| 511 | } |
Runmin Wang | 261d2bf | 2017-11-03 11:40:40 -0700 | [diff] [blame] | 512 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 513 | return EFI_SUCCESS; |
| 514 | |
| 515 | Err: |
| 516 | /* Free all the Images' memory that was allocated */ |
| 517 | for (--(*ImgIdx); *ImgIdx; --(*ImgIdx)) { |
| 518 | if (Info->Images[*ImgIdx].ImageBuffer != NULL) { |
| 519 | FreePool (Info->Images[*ImgIdx].ImageBuffer); |
| 520 | } |
| 521 | if (Info->Images[*ImgIdx].Name != NULL) { |
| 522 | FreePool (Info->Images[*ImgIdx].Name); |
| 523 | } |
| 524 | } |
| 525 | |
| 526 | /* Images[0] needs to be freed in a special way as it was allocated |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 527 | * using AllocPages(). Although, ignore if we are coming from a |
| 528 | * fastboot boot path. |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 529 | */ |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 530 | if (FastbootPath) |
| 531 | goto err_out; |
| 532 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 533 | if (Info->Images[0].ImageBuffer) { |
| 534 | UINT32 ImageSize = |
| 535 | ADD_OF (ROUND_TO_PAGE (Info->Images[0].ImageSize, |
| 536 | (PageSize - 1)), PageSize); |
| 537 | |
| 538 | FreePages (Info->Images[0].ImageBuffer, |
| 539 | ALIGN_PAGES (ImageSize, ALIGNMENT_MASK_4KB)); |
| 540 | } |
| 541 | |
| 542 | if (Info->Images[0].Name) { |
| 543 | FreePool (Info->Images[0].Name); |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 544 | } |
| 545 | |
Raghavendra Rao Ananta | 4713a51 | 2019-10-13 07:30:11 -0700 | [diff] [blame] | 546 | err_out: |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 547 | return Status; |
| 548 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 549 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 550 | STATIC EFI_STATUS |
| 551 | LoadImageNoAuthWrapper (BootInfo *Info) |
| 552 | { |
| 553 | EFI_STATUS Status = EFI_SUCCESS; |
| 554 | CHAR8 *SystemPath = NULL; |
| 555 | UINT32 SystemPathLen = 0; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 556 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 557 | GUARD (VBAllocateCmdLine (Info)); |
| 558 | GUARD (LoadImageNoAuth (Info)); |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 559 | |
Mayank Grover | 1c05158 | 2019-02-26 14:42:27 +0530 | [diff] [blame] | 560 | if (!IsDynamicPartitionSupport () && |
| 561 | !IsRootCmdLineUpdated (Info)) { |
Venkata Narendra Kumar Gutta | d1cbfd2 | 2020-01-07 13:27:33 -0800 | [diff] [blame] | 562 | SystemPathLen = GetSystemPath (&SystemPath, Info); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 563 | if (SystemPathLen == 0 || SystemPath == NULL) { |
| 564 | DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n")); |
| 565 | return EFI_LOAD_ERROR; |
Zhen Kong | db33a73 | 2017-07-10 12:23:00 -0700 | [diff] [blame] | 566 | } |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 567 | GUARD (AppendVBCmdLine (Info, SystemPath)); |
| 568 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 569 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 570 | return Status; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 571 | } |
| 572 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 573 | STATIC EFI_STATUS |
| 574 | LoadImageAndAuthVB1 (BootInfo *Info) |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 575 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 576 | EFI_STATUS Status = EFI_SUCCESS; |
| 577 | CHAR8 StrPnameAscii[MAX_GPT_NAME_SIZE]; /* partition name starting with |
| 578 | / and no suffix */ |
| 579 | CHAR8 PnameAscii[MAX_GPT_NAME_SIZE]; |
| 580 | CHAR8 *SystemPath = NULL; |
| 581 | UINT32 SystemPathLen = 0; |
Mukesh Ojha | 71be2c8 | 2018-02-02 19:13:10 +0530 | [diff] [blame] | 582 | CHAR8 *Temp = NULL; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 583 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 584 | GUARD (VBCommonInit (Info)); |
| 585 | GUARD (VBAllocateCmdLine (Info)); |
| 586 | GUARD (LoadImageNoAuth (Info)); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 587 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 588 | device_info_vb_t DevInfo_vb; |
| 589 | DevInfo_vb.is_unlocked = IsUnlocked (); |
| 590 | DevInfo_vb.is_unlock_critical = IsUnlockCritical (); |
| 591 | Status = Info->VbIntf->VBDeviceInit (Info->VbIntf, |
| 592 | (device_info_vb_t *)&DevInfo_vb); |
| 593 | if (Status != EFI_SUCCESS) { |
| 594 | DEBUG ((EFI_D_ERROR, "Error during VBDeviceInit: %r\n", Status)); |
| 595 | return Status; |
| 596 | } |
| 597 | |
| 598 | AsciiStrnCpyS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), "/", |
| 599 | AsciiStrLen ("/")); |
| 600 | UnicodeStrToAsciiStr (Info->Pname, PnameAscii); |
| 601 | if (Info->MultiSlotBoot) { |
| 602 | AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii, |
| 603 | AsciiStrLen (PnameAscii) - (MAX_SLOT_SUFFIX_SZ - 1)); |
| 604 | } else { |
| 605 | AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii, |
| 606 | AsciiStrLen (PnameAscii)); |
| 607 | } |
| 608 | |
| 609 | Status = |
| 610 | Info->VbIntf->VBVerifyImage (Info->VbIntf, (UINT8 *)StrPnameAscii, |
| 611 | (UINT8 *)Info->Images[0].ImageBuffer, |
| 612 | Info->Images[0].ImageSize, &Info->BootState); |
| 613 | if (Status != EFI_SUCCESS || Info->BootState == BOOT_STATE_MAX) { |
| 614 | DEBUG ((EFI_D_ERROR, "VBVerifyImage failed with: %r\n", Status)); |
| 615 | return Status; |
| 616 | } |
| 617 | |
| 618 | Status = Info->VbIntf->VBSendRot (Info->VbIntf); |
| 619 | if (Status != EFI_SUCCESS) { |
| 620 | DEBUG ((EFI_D_ERROR, "Error sending Rot : %r\n", Status)); |
| 621 | return Status; |
| 622 | } |
| 623 | |
Jeevan Shriram | 615b1e1 | 2017-10-12 14:10:06 -0700 | [diff] [blame] | 624 | if (!IsRootCmdLineUpdated (Info)) { |
Venkata Narendra Kumar Gutta | d1cbfd2 | 2020-01-07 13:27:33 -0800 | [diff] [blame] | 625 | SystemPathLen = GetSystemPath (&SystemPath, Info); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 626 | if (SystemPathLen == 0 || SystemPath == NULL) { |
| 627 | DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n")); |
| 628 | return EFI_LOAD_ERROR; |
| 629 | } |
Mukesh Ojha | 71be2c8 | 2018-02-02 19:13:10 +0530 | [diff] [blame] | 630 | GUARD (AppendVBCmdLine (Info, DmVerityCmd)); |
| 631 | /* Copy only the portion after "root=" in the SystemPath */ |
| 632 | Temp = AsciiStrStr (SystemPath, "root="); |
| 633 | if (Temp) { |
| 634 | CopyMem (Temp, SystemPath + AsciiStrLen ("root=") + 1, |
| 635 | SystemPathLen - AsciiStrLen ("root=") - 1); |
| 636 | SystemPath[SystemPathLen - AsciiStrLen ("root=")] = '\0'; |
| 637 | } |
| 638 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 639 | GUARD (AppendVBCmdLine (Info, SystemPath)); |
Mukesh Ojha | 71be2c8 | 2018-02-02 19:13:10 +0530 | [diff] [blame] | 640 | GUARD (AppendVBCmdLine (Info, "\"")); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 641 | } |
| 642 | GUARD (AppendVBCommonCmdLine (Info)); |
| 643 | GUARD (AppendVBCmdLine (Info, VerityMode)); |
| 644 | GUARD (AppendVBCmdLine (Info, VbVm[IsEnforcing ()].name)); |
| 645 | |
| 646 | Info->VBData = NULL; |
| 647 | return Status; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 648 | } |
| 649 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 650 | STATIC BOOLEAN |
| 651 | ResultShouldContinue (AvbSlotVerifyResult Result) |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 652 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 653 | switch (Result) { |
| 654 | case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: |
| 655 | case AVB_SLOT_VERIFY_RESULT_ERROR_IO: |
| 656 | case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: |
| 657 | case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: |
| 658 | case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: |
| 659 | return FALSE; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 660 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 661 | case AVB_SLOT_VERIFY_RESULT_OK: |
| 662 | case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: |
| 663 | case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: |
| 664 | case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: |
| 665 | return TRUE; |
| 666 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 667 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 668 | return FALSE; |
| 669 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 670 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 671 | STATIC EFI_STATUS |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 672 | LEGetImageHash (QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol, |
| 673 | VB_HASH HashAlgorithm, |
| 674 | UINT8 *Img, UINTN ImgSize, |
| 675 | UINT8 *ImgHash, UINTN HashSize) |
| 676 | { |
| 677 | EFI_STATUS Status = EFI_FAILURE; |
| 678 | EFI_GUID *HashAlgorithmGuid; |
| 679 | UINTN DigestSize = 0; |
| 680 | EFI_HASH2_OUTPUT Hash2Output; |
| 681 | EFI_HASH2_PROTOCOL *pEfiHash2Protocol = NULL; |
| 682 | |
| 683 | if (pEfiQcomASN1X509Protocol == NULL || |
| 684 | Img == NULL || |
| 685 | ImgHash == NULL) { |
| 686 | DEBUG ((EFI_D_ERROR, |
| 687 | "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n")); |
| 688 | return EFI_INVALID_PARAMETER; |
| 689 | } |
| 690 | |
| 691 | switch (HashAlgorithm) { |
| 692 | case VB_SHA256: |
| 693 | HashAlgorithmGuid = &gEfiHashAlgorithmSha256Guid; |
| 694 | break; |
| 695 | default: |
| 696 | DEBUG ((EFI_D_ERROR, |
| 697 | "VB: LEGetImageHash: not supported algorithm:%d\n", HashAlgorithm)); |
| 698 | Status = EFI_UNSUPPORTED; |
| 699 | goto exit; |
| 700 | } |
| 701 | |
| 702 | Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, |
| 703 | NULL, (VOID **)&pEfiHash2Protocol); |
| 704 | if (Status != EFI_SUCCESS) { |
| 705 | DEBUG ((EFI_D_ERROR, |
| 706 | "VB:LEGetImageHash: LocateProtocol unsuccessful!Status: %r\n", Status)); |
| 707 | goto exit; |
| 708 | } |
| 709 | |
| 710 | Status = pEfiHash2Protocol->GetHashSize (pEfiHash2Protocol, |
| 711 | HashAlgorithmGuid, &DigestSize); |
| 712 | if (Status != EFI_SUCCESS) { |
| 713 | DEBUG ((EFI_D_ERROR, |
| 714 | "VB: LEGetImageHash: GetHashSize unsuccessful! Status: %r\n", Status)); |
| 715 | goto exit; |
| 716 | } |
| 717 | if (HashSize != DigestSize) { |
| 718 | DEBUG ((EFI_D_ERROR, |
| 719 | "VB: LEGetImageHash: Invalid size! HashSize: %d, DigestSize: %d\n" |
| 720 | , HashSize, DigestSize)); |
| 721 | Status = EFI_FAILURE; |
| 722 | goto exit; |
| 723 | } |
| 724 | Status = pEfiHash2Protocol->HashInit (pEfiHash2Protocol, HashAlgorithmGuid); |
| 725 | if (Status != EFI_SUCCESS) { |
| 726 | DEBUG ((EFI_D_ERROR, |
| 727 | "VB: LEGetImageHash: HashInit unsuccessful! Status: %r\n", Status)); |
| 728 | goto exit; |
| 729 | } |
| 730 | Status = pEfiHash2Protocol->HashUpdate (pEfiHash2Protocol, Img, ImgSize); |
| 731 | if (EFI_SUCCESS != Status) { |
| 732 | |
| 733 | DEBUG ((EFI_D_ERROR, |
| 734 | "VB: LEGetImageHash: HashUpdate unsuccessful(Img)!Status: %r\n" |
| 735 | , Status)); |
| 736 | goto exit; |
| 737 | } |
| 738 | Status = pEfiHash2Protocol->HashFinal (pEfiHash2Protocol, &Hash2Output); |
| 739 | if (EFI_SUCCESS != Status) { |
| 740 | |
| 741 | DEBUG ((EFI_D_ERROR, |
| 742 | "VB: LEGetImageHash: HashFinal unsuccessful! Status: %r\n", Status)); |
| 743 | goto exit; |
| 744 | } |
| 745 | gBS->CopyMem ((VOID *)ImgHash, (VOID *)&Hash2Output, DigestSize); |
| 746 | Status = EFI_SUCCESS; |
| 747 | |
| 748 | exit: |
| 749 | return Status; |
| 750 | } |
| 751 | |
| 752 | STATIC EFI_STATUS LEGetRSAPublicKeyInfoFromCertificate ( |
| 753 | QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol, |
| 754 | CERTIFICATE *Certificate, |
| 755 | secasn1_data_type *Modulus, |
| 756 | secasn1_data_type *PublicExp, |
| 757 | UINT32 *PaddingType) |
| 758 | { |
| 759 | EFI_STATUS Status = EFI_FAILURE; |
| 760 | RSA RsaKey = {NULL}; |
| 761 | |
| 762 | if (pEfiQcomASN1X509Protocol == NULL || |
| 763 | Certificate == NULL || |
| 764 | Modulus == NULL || |
| 765 | PublicExp == NULL || |
| 766 | PaddingType == NULL) { |
| 767 | DEBUG ((EFI_D_ERROR, |
| 768 | "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n")); |
| 769 | return EFI_INVALID_PARAMETER; |
| 770 | } |
| 771 | |
| 772 | Status = pEfiQcomASN1X509Protocol->ASN1X509GetRSAFromCert |
| 773 | (pEfiQcomASN1X509Protocol, Certificate, &RsaKey); |
| 774 | if (Status != EFI_SUCCESS) { |
| 775 | DEBUG ((EFI_D_ERROR, |
| 776 | "VB: ASN1X509GetRSAFromCert unsuccessful! Status : %r\n", Status)); |
| 777 | goto exit; |
| 778 | } |
| 779 | Status = pEfiQcomASN1X509Protocol->ASN1X509GetKeymaterial |
| 780 | (pEfiQcomASN1X509Protocol, &RsaKey, Modulus, PublicExp); |
| 781 | if (Status != EFI_SUCCESS) { |
| 782 | DEBUG ((EFI_D_ERROR, |
| 783 | "VB: ASN1X509GetKeymaterial unsuccessful! Status: %r\n", Status)); |
| 784 | goto exit; |
| 785 | } |
| 786 | *PaddingType = CE_RSA_PAD_PKCS1_V1_5_SIG; |
| 787 | exit: |
| 788 | return Status; |
| 789 | } |
| 790 | STATIC EFI_STATUS LEVerifyHashWithRSASignature ( |
| 791 | UINT8 *ImgHash, |
| 792 | VB_HASH HashAlgorithm, |
| 793 | secasn1_data_type *Modulus, |
| 794 | secasn1_data_type *PublicExp, |
| 795 | UINT32 PaddingType, |
| 796 | CONST UINT8 *SignaturePtr, |
| 797 | UINT32 SignatureLen) |
| 798 | { |
| 799 | EFI_STATUS Status = EFI_FAILURE; |
| 800 | CE_RSA_KEY Key = {0}; |
| 801 | BigInt ModulusBi; |
| 802 | BigInt PublicExpBi; |
| 803 | INT32 HashIdx; |
| 804 | INT32 HashLen; |
| 805 | VOID *PaddingInfo = NULL; |
| 806 | QcomSecRsaProtocol *pEfiQcomSecRSAProtocol = NULL; |
| 807 | SetMem (&Key, sizeof (CE_RSA_KEY), 0); |
| 808 | |
| 809 | if (ImgHash == NULL || |
| 810 | Modulus == NULL || |
| 811 | PublicExp == NULL || |
| 812 | SignaturePtr == NULL) { |
| 813 | DEBUG ((EFI_D_ERROR, "LEVerifyHashWithRSASignature:Invalid pointer\n")); |
| 814 | return EFI_INVALID_PARAMETER; |
| 815 | } |
| 816 | |
| 817 | switch (HashAlgorithm) { |
| 818 | case VB_SHA256: |
| 819 | HashIdx = CE_HASH_IDX_SHA256; |
| 820 | HashLen = VB_SHA256_SIZE; |
| 821 | break; |
| 822 | default: |
| 823 | DEBUG ((EFI_D_ERROR, |
| 824 | "VB: LEVerifySignature: Hash algorithm not supported\n")); |
| 825 | Status = EFI_UNSUPPORTED; |
| 826 | goto exit; |
| 827 | } |
| 828 | |
Bhanuprakash Modem | 763cdd5 | 2018-11-01 14:49:55 +0530 | [diff] [blame] | 829 | Key.N = AllocateZeroPool (sizeof (S_BIGINT)); |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 830 | if (Key.N == NULL) { |
| 831 | DEBUG ((EFI_D_ERROR, |
| 832 | "VB: LEVerifySignature: mem allocation err for Key.N\n")); |
| 833 | goto exit; |
| 834 | } |
Bhanuprakash Modem | 763cdd5 | 2018-11-01 14:49:55 +0530 | [diff] [blame] | 835 | Key.e = AllocateZeroPool (sizeof (S_BIGINT)); |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 836 | if (Key.e == NULL) { |
| 837 | DEBUG ((EFI_D_ERROR, |
| 838 | "VB: LEVerifySignature: mem allocation err for Key.e\n")); |
| 839 | goto exit; |
| 840 | } |
| 841 | Status = gBS->LocateProtocol (&gEfiQcomSecRSAProtocolGuid, |
| 842 | NULL, (VOID **) &pEfiQcomSecRSAProtocol); |
| 843 | if ( Status != EFI_SUCCESS) { |
| 844 | DEBUG ((EFI_D_ERROR, |
| 845 | "VB: LEVerifySignature: LocateProtocol failed, Status: %r\n", Status)); |
| 846 | goto exit; |
| 847 | } |
| 848 | |
| 849 | Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin ( |
| 850 | pEfiQcomSecRSAProtocol, Modulus->data, Modulus->Len, &ModulusBi); |
| 851 | if ( Status != EFI_SUCCESS) { |
| 852 | DEBUG ((EFI_D_ERROR, |
| 853 | "VB: LEVerifySignature: SecRSABigIntReadBin for Modulus failed!" |
| 854 | "Status: %r\n", Status)); |
| 855 | goto exit; |
| 856 | } |
| 857 | Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin ( |
| 858 | pEfiQcomSecRSAProtocol, PublicExp->data, PublicExp->Len, &PublicExpBi); |
| 859 | if ( Status != EFI_SUCCESS) { |
| 860 | DEBUG ((EFI_D_ERROR, "VB: LEVerifySignature: SecRSABigIntReadBin for" |
| 861 | " Modulus failed! Status: %r\n", Status)); |
| 862 | goto exit; |
| 863 | } |
| 864 | |
| 865 | Key.N->Bi = ModulusBi; |
| 866 | Key.e->Bi = PublicExpBi; |
| 867 | Key.e->Sign = S_BIGINT_POS; |
| 868 | Key.Type = CE_RSA_KEY_PUBLIC; |
| 869 | |
| 870 | Status = pEfiQcomSecRSAProtocol->SecRSAVerifySig (pEfiQcomSecRSAProtocol, |
| 871 | &Key, PaddingType, |
| 872 | PaddingInfo, HashIdx, |
| 873 | ImgHash, HashLen, (UINT8*)SignaturePtr, SignatureLen); |
| 874 | |
| 875 | if (Status != EFI_SUCCESS) { |
| 876 | DEBUG ((EFI_D_ERROR, |
| 877 | "VB: LEVerifySignature: SecRSAVerifySig failed! Status: %r\n", Status)); |
| 878 | goto exit; |
| 879 | } |
| 880 | |
| 881 | DEBUG ((EFI_D_VERBOSE, "VB: LEVerifySignature: SecRSAVerifySig success!" |
| 882 | " Status: %r\n", Status)); |
| 883 | |
| 884 | Status = EFI_SUCCESS; |
| 885 | exit: |
| 886 | if (Key.N != NULL) { |
| 887 | FreePool (Key.N); |
| 888 | } |
| 889 | if (Key.e != NULL) { |
| 890 | FreePool (Key.e); |
| 891 | } |
| 892 | return Status; |
| 893 | } |
| 894 | |
| 895 | STATIC EFI_STATUS LEVerifyHashWithSignature ( |
| 896 | QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol, |
| 897 | UINT8 *ImgHash, VB_HASH HashAlgorithm, |
| 898 | CERTIFICATE *Certificate, |
| 899 | CONST UINT8 *SignaturePtr, |
| 900 | UINT32 SignatureLen) |
| 901 | { |
| 902 | EFI_STATUS Status = EFI_FAILURE; |
| 903 | secasn1_data_type Modulus = {NULL}; |
| 904 | secasn1_data_type PublicExp = {NULL}; |
| 905 | UINT32 PaddingType = 0; |
| 906 | |
| 907 | if (pEfiQcomASN1X509Protocol == NULL || |
| 908 | ImgHash == NULL || |
| 909 | Certificate == NULL || |
| 910 | SignaturePtr == NULL) { |
| 911 | DEBUG ((EFI_D_ERROR, "LEVerifyHashWithSignature: Invalid pointer\n")); |
| 912 | return EFI_INVALID_PARAMETER; |
| 913 | } |
| 914 | |
| 915 | /* TODO: get subject publick key info from certificate, implement new |
| 916 | algorithm in XBL*/ |
| 917 | /* XBL implemented by default sha256 and rsaEncryption with |
| 918 | PKCS1_V1_5 padding*/ |
| 919 | |
| 920 | Status = LEGetRSAPublicKeyInfoFromCertificate (pEfiQcomASN1X509Protocol, |
| 921 | Certificate, &Modulus, &PublicExp, &PaddingType); |
| 922 | if (Status != EFI_SUCCESS) { |
| 923 | DEBUG ((EFI_D_ERROR, "VB: LEGetRSAPublicKeyInfoFromCertificate " |
| 924 | "unsuccessful! Status: %r\n", Status)); |
| 925 | goto exit; |
| 926 | } |
| 927 | |
| 928 | Status = LEVerifyHashWithRSASignature (ImgHash, HashAlgorithm, |
| 929 | &Modulus, &PublicExp, PaddingType, |
| 930 | SignaturePtr, SignatureLen); |
| 931 | if (Status != EFI_SUCCESS) { |
| 932 | DEBUG ((EFI_D_ERROR, "VB: LEVerifyHashWithSignature unsuccessful! " |
| 933 | "Status: %r\n", Status)); |
| 934 | goto exit; |
| 935 | } |
| 936 | Status = EFI_SUCCESS; |
| 937 | exit: |
| 938 | return Status; |
| 939 | } |
| 940 | |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 941 | static BOOLEAN GetHeaderVersion (AvbSlotVerifyData *SlotData, CHAR8 *ImageName) |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 942 | { |
| 943 | BOOLEAN HeaderVersion = 0; |
| 944 | UINTN LoadedIndex = 0; |
| 945 | for (LoadedIndex = 0; LoadedIndex < SlotData->num_loaded_partitions; |
| 946 | LoadedIndex++) { |
| 947 | if (avb_strcmp (SlotData->loaded_partitions[LoadedIndex].partition_name, |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 948 | ImageName) == 0 ) |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 949 | return ( (boot_img_hdr *) |
| 950 | (SlotData->loaded_partitions[LoadedIndex].data))->header_version; |
| 951 | } |
| 952 | return HeaderVersion; |
| 953 | } |
| 954 | |
| 955 | static VOID AddRequestedPartition (CHAR8 **RequestedPartititon, UINT32 Index) |
| 956 | { |
| 957 | UINTN PartIndex = 0; |
| 958 | for (PartIndex = 0; PartIndex < MAX_NUM_REQ_PARTITION; PartIndex++) { |
| 959 | if (RequestedPartititon[PartIndex] == NULL) { |
| 960 | RequestedPartititon[PartIndex] = |
| 961 | avb_verify_partition_name[Index]; |
| 962 | break; |
| 963 | } |
| 964 | } |
| 965 | } |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 966 | |
Barani Muthukumaran | af2a746 | 2019-03-20 15:40:57 -0700 | [diff] [blame] | 967 | STATIC VOID |
| 968 | ComputeVbMetaDigest (AvbSlotVerifyData* SlotData, CHAR8* Digest) { |
| 969 | size_t Index; |
| 970 | AvbSHA256Ctx Ctx; |
| 971 | avb_sha256_init (&Ctx); |
| 972 | for (Index = 0; Index < SlotData->num_vbmeta_images; Index++) { |
| 973 | avb_sha256_update (&Ctx, |
| 974 | SlotData->vbmeta_images[Index].vbmeta_data, |
| 975 | SlotData->vbmeta_images[Index].vbmeta_size); |
| 976 | } |
| 977 | avb_memcpy (Digest, avb_sha256_final(&Ctx), AVB_SHA256_DIGEST_SIZE); |
| 978 | } |
| 979 | |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 980 | static UINT32 ParseBootSecurityLevel (CONST CHAR8 *BootSecurityLevel, |
| 981 | size_t BootSecurityLevelSize) |
| 982 | { |
| 983 | UINT32 PatchLevelDate = 0; |
| 984 | UINT32 PatchLevelMonth = 0; |
| 985 | UINT32 PatchLevelYear = 0; |
| 986 | UINT32 SeparatorCount = 0; |
| 987 | UINT32 Count = 0; |
| 988 | |
| 989 | /*Parse the value of security patch as per YYYY-MM-DD format*/ |
| 990 | while (Count < BootSecurityLevelSize) { |
| 991 | if (BootSecurityLevel[Count] == '-') { |
| 992 | SeparatorCount++; |
| 993 | } |
| 994 | else if (SeparatorCount == 2) { |
| 995 | PatchLevelDate *= 10; |
| 996 | PatchLevelDate += (BootSecurityLevel[Count] - '0'); |
| 997 | } |
| 998 | else if (SeparatorCount == 1) { |
| 999 | PatchLevelMonth *= 10; |
| 1000 | PatchLevelMonth += (BootSecurityLevel[Count] - '0'); |
| 1001 | } |
| 1002 | else if (SeparatorCount == 0) { |
| 1003 | PatchLevelYear *= 10; |
| 1004 | PatchLevelYear += (BootSecurityLevel[Count] - '0'); |
| 1005 | } |
| 1006 | else { |
| 1007 | return -1; |
| 1008 | } |
| 1009 | Count++; |
| 1010 | } |
| 1011 | |
| 1012 | PatchLevelDate = PatchLevelDate << 11; |
| 1013 | PatchLevelYear = (PatchLevelYear - 2000) << 4; |
| 1014 | return (PatchLevelDate | PatchLevelYear | PatchLevelMonth); |
| 1015 | } |
| 1016 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1017 | STATIC BOOLEAN |
| 1018 | IsValidPartition (Slot *Slot, CONST CHAR16 *Name) |
| 1019 | { |
| 1020 | CHAR16 PartiName[MAX_GPT_NAME_SIZE] = {0}; |
| 1021 | EFI_STATUS Status; |
| 1022 | INT32 Index; |
| 1023 | |
| 1024 | GUARD (StrnCpyS (PartiName, (UINTN)MAX_GPT_NAME_SIZE, Name, StrLen (Name))); |
| 1025 | |
| 1026 | /* If *Slot is filled, it means that it's for multi-slot */ |
| 1027 | if (Slot) { |
| 1028 | GUARD (StrnCatS (PartiName, MAX_GPT_NAME_SIZE, |
| 1029 | Slot->Suffix, StrLen (Slot->Suffix))); |
| 1030 | } |
| 1031 | |
| 1032 | Index = GetPartitionIndex (PartiName); |
| 1033 | |
| 1034 | return (Index == INVALID_PTN || |
| 1035 | Index >= MAX_NUM_PARTITIONS) ? |
| 1036 | FALSE : TRUE; |
| 1037 | } |
| 1038 | |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1039 | STATIC EFI_STATUS |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1040 | LoadImageAndAuthVB2 (BootInfo *Info) |
| 1041 | { |
| 1042 | EFI_STATUS Status = EFI_SUCCESS; |
| 1043 | AvbSlotVerifyResult Result; |
| 1044 | AvbSlotVerifyData *SlotData = NULL; |
| 1045 | VB2Data *VBData = NULL; |
| 1046 | AvbOpsUserData *UserData = NULL; |
| 1047 | AvbOps *Ops = NULL; |
| 1048 | CHAR8 PnameAscii[MAX_GPT_NAME_SIZE] = {0}; |
| 1049 | CHAR8 *SlotSuffix = NULL; |
| 1050 | BOOLEAN AllowVerificationError = IsUnlocked (); |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1051 | CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL}; |
| 1052 | CHAR8 **RequestedPartition = NULL; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1053 | UINTN NumRequestedPartition = 0; |
lijuang | 9107113 | 2019-02-13 16:20:09 +0800 | [diff] [blame] | 1054 | UINT32 ImageHdrSize = BOOT_IMG_MAX_PAGE_SIZE; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1055 | UINT32 PageSize = 0; |
| 1056 | UINT32 ImageSizeActual = 0; |
| 1057 | VOID *ImageBuffer = NULL; |
| 1058 | UINTN ImageSize = 0; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1059 | VOID *VendorBootImageBuffer = NULL; |
| 1060 | UINTN VendorBootImageSize = 0; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1061 | KMRotAndBootState Data = {0}; |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1062 | CONST CHAR8 *BootSecurityLevel = NULL; |
| 1063 | size_t BootSecurityLevelSize = 0; |
| 1064 | BOOLEAN DateSupport = FALSE; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1065 | CONST boot_img_hdr *BootImgHdr = NULL; |
| 1066 | AvbSlotVerifyFlags VerifyFlags = |
| 1067 | AllowVerificationError ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR |
| 1068 | : AVB_SLOT_VERIFY_FLAGS_NONE; |
| 1069 | AvbHashtreeErrorMode VerityFlags = |
| 1070 | AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE; |
Barani Muthukumaran | af2a746 | 2019-03-20 15:40:57 -0700 | [diff] [blame] | 1071 | CHAR8 Digest[AVB_SHA256_DIGEST_SIZE]; |
Gaurav Kashyap | 39f011d | 2019-04-01 11:19:57 -0700 | [diff] [blame] | 1072 | BOOLEAN UpdateRollback = FALSE; |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1073 | UINT32 OSVersion; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1074 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1075 | Info->BootState = RED; |
| 1076 | GUARD (VBCommonInit (Info)); |
| 1077 | GUARD (VBAllocateCmdLine (Info)); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1078 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1079 | UserData = avb_calloc (sizeof (AvbOpsUserData)); |
| 1080 | if (UserData == NULL) { |
| 1081 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOpsUserData\n")); |
| 1082 | Status = EFI_OUT_OF_RESOURCES; |
| 1083 | goto out; |
| 1084 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1085 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1086 | Ops = AvbOpsNew (UserData); |
| 1087 | if (Ops == NULL) { |
| 1088 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOps\n")); |
| 1089 | Status = EFI_OUT_OF_RESOURCES; |
| 1090 | goto out; |
| 1091 | } |
Shivaprasad Hongal | 82e18e9 | 2018-03-01 15:29:25 -0800 | [diff] [blame] | 1092 | UserData->IsMultiSlot = Info->MultiSlotBoot; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1093 | |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1094 | if (Info->MultiSlotBoot) { |
| 1095 | UnicodeStrToAsciiStr (Info->Pname, PnameAscii); |
| 1096 | if ((MAX_SLOT_SUFFIX_SZ + 1) > AsciiStrLen (PnameAscii)) { |
| 1097 | DEBUG ((EFI_D_ERROR, "ERROR: Can not determine slot suffix\n")); |
| 1098 | Status = EFI_INVALID_PARAMETER; |
| 1099 | goto out; |
| 1100 | } |
| 1101 | SlotSuffix = &PnameAscii[AsciiStrLen (PnameAscii) - MAX_SLOT_SUFFIX_SZ + 1]; |
| 1102 | } else { |
| 1103 | SlotSuffix = "\0"; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1104 | } |
Shivaprasad Hongal | 39236ae | 2017-06-06 16:10:35 -0700 | [diff] [blame] | 1105 | |
Gaurav Kashyap | 39f011d | 2019-04-01 11:19:57 -0700 | [diff] [blame] | 1106 | /* Check if slot is bootable and call into TZ to update rollback version. |
| 1107 | * This is similar to the update done later for vbmeta bound images. |
| 1108 | * However, here we call into TZ irrespective of version check and let |
| 1109 | * the secure environment make the decision on updating rollback version |
| 1110 | */ |
| 1111 | |
| 1112 | UpdateRollback = avb_should_update_rollback (UserData->IsMultiSlot); |
| 1113 | if (UpdateRollback) { |
| 1114 | Status = UpdateRollbackSyscall (); |
| 1115 | if (Status != EFI_SUCCESS) { |
| 1116 | DEBUG ((EFI_D_ERROR, "LoadImageAndAuthVB2: Error int TZ Rollback Version " |
| 1117 | "syscall; ScmCall Status: (0x%x)\r\n", Status)); |
| 1118 | return Status; |
| 1119 | } |
| 1120 | } |
| 1121 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1122 | DEBUG ((EFI_D_VERBOSE, "Slot: %a, allow verification error: %a\n", SlotSuffix, |
| 1123 | BooleanString[AllowVerificationError].name)); |
Shivaprasad Hongal | 39236ae | 2017-06-06 16:10:35 -0700 | [diff] [blame] | 1124 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1125 | if (FixedPcdGetBool (AllowEio)) { |
| 1126 | VerityFlags = IsEnforcing () ? AVB_HASHTREE_ERROR_MODE_RESTART |
| 1127 | : AVB_HASHTREE_ERROR_MODE_EIO; |
| 1128 | } else { |
| 1129 | VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE; |
| 1130 | } |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1131 | RequestedPartition = RequestedPartitionAll; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1132 | |
Monika Singh | 8bfc66a | 2019-03-08 12:18:17 +0530 | [diff] [blame] | 1133 | if ( ( (!Info->MultiSlotBoot) || |
| 1134 | IsDynamicPartitionSupport ()) && |
Prakruthi Deepak Heragu | 70ad7f4 | 2020-02-03 16:33:59 -0800 | [diff] [blame] | 1135 | (Info->BootIntoRecovery && |
| 1136 | !IsBuildUseRecoveryAsBoot ())) { |
David Zeuthen | 93ff0e4 | 2020-01-16 18:17:30 +0530 | [diff] [blame] | 1137 | if (!Info->MultiSlotBoot) |
| 1138 | VerifyFlags = VerifyFlags | AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION; |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1139 | AddRequestedPartition (RequestedPartitionAll, IMG_RECOVERY); |
| 1140 | NumRequestedPartition += 1; |
| 1141 | Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition, |
| 1142 | SlotSuffix, VerifyFlags, VerityFlags, &SlotData); |
Monika Singh | e88af1f | 2018-11-12 13:52:41 +0530 | [diff] [blame] | 1143 | if (AllowVerificationError && |
| 1144 | ResultShouldContinue (Result)) { |
lijuang | f2eb1fa | 2019-09-23 14:10:20 +0800 | [diff] [blame] | 1145 | DEBUG ((EFI_D_VERBOSE, "State: Unlocked, AvbSlotVerify returned " |
Monika Singh | e88af1f | 2018-11-12 13:52:41 +0530 | [diff] [blame] | 1146 | "%a, continue boot\n", |
| 1147 | avb_slot_verify_result_to_string (Result))); |
| 1148 | } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) { |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1149 | DEBUG ((EFI_D_ERROR, "ERROR: Device State %a,AvbSlotVerify returned %a\n", |
| 1150 | AllowVerificationError ? "Unlocked" : "Locked", |
| 1151 | avb_slot_verify_result_to_string (Result))); |
| 1152 | Status = EFI_LOAD_ERROR; |
| 1153 | Info->BootState = RED; |
| 1154 | goto out; |
| 1155 | } |
| 1156 | if (SlotData == NULL) { |
| 1157 | Status = EFI_LOAD_ERROR; |
| 1158 | Info->BootState = RED; |
| 1159 | goto out; |
| 1160 | } |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1161 | BOOLEAN HeaderVersion = GetHeaderVersion (SlotData, "recovery"); |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1162 | DEBUG ( (EFI_D_VERBOSE, "Recovery HeaderVersion %d \n", HeaderVersion)); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1163 | |
| 1164 | if (HeaderVersion == BOOT_HEADER_VERSION_ZERO || |
| 1165 | HeaderVersion >= BOOT_HEADER_VERSION_THREE) { |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1166 | AddRequestedPartition (RequestedPartitionAll, IMG_DTBO); |
| 1167 | NumRequestedPartition += 1; |
| 1168 | if (SlotData != NULL) { |
| 1169 | avb_slot_verify_data_free (SlotData); |
| 1170 | } |
| 1171 | Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition, |
| 1172 | SlotSuffix, VerifyFlags, VerityFlags, &SlotData); |
| 1173 | } |
| 1174 | } else { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1175 | Slot CurrentSlot; |
| 1176 | |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1177 | if (!Info->NumLoadedImages) { |
| 1178 | AddRequestedPartition (RequestedPartitionAll, IMG_BOOT); |
| 1179 | NumRequestedPartition += 1; |
| 1180 | } |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1181 | |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1182 | AddRequestedPartition (RequestedPartitionAll, IMG_DTBO); |
| 1183 | NumRequestedPartition += 1; |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 1184 | |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1185 | Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition, |
| 1186 | SlotSuffix, VerifyFlags, VerityFlags, &SlotData); |
| 1187 | if (AllowVerificationError && |
| 1188 | ResultShouldContinue (Result)) { |
| 1189 | DEBUG ((EFI_D_VERBOSE, "State: Unlocked, AvbSlotVerify returned " |
| 1190 | "%a, continue boot\n", |
| 1191 | avb_slot_verify_result_to_string (Result))); |
| 1192 | } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) { |
| 1193 | DEBUG ((EFI_D_ERROR, "ERROR: Device State %a,AvbSlotVerify returned %a\n", |
| 1194 | AllowVerificationError ? "Unlocked" : "Locked", |
| 1195 | avb_slot_verify_result_to_string (Result))); |
| 1196 | Status = EFI_LOAD_ERROR; |
| 1197 | Info->BootState = RED; |
| 1198 | goto out; |
| 1199 | } |
| 1200 | if (SlotData == NULL) { |
| 1201 | Status = EFI_LOAD_ERROR; |
| 1202 | Info->BootState = RED; |
| 1203 | goto out; |
| 1204 | } |
| 1205 | BOOLEAN HeaderVersion = GetHeaderVersion (SlotData, "boot"); |
| 1206 | DEBUG ( (EFI_D_VERBOSE, "Boot HeaderVersion %d \n", HeaderVersion)); |
| 1207 | |
| 1208 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1209 | if (Info->MultiSlotBoot) { |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 1210 | CurrentSlot = GetCurrentSlotSuffix (); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1211 | } |
Jeevan Shriram | 0d619eb | 2018-10-08 15:42:11 -0700 | [diff] [blame] | 1212 | |
Venkata Rao Kakani | 4412bdf | 2021-06-10 18:01:28 +0530 | [diff] [blame] | 1213 | /* Load vendor boot in following conditions |
| 1214 | * 1. In Ram load case where Header version is 0 because |
| 1215 | * boot image is not loaded in the flow& Valid partition. |
| 1216 | * 2. In Case of header version 3 & valid partititon. |
| 1217 | */ |
| 1218 | |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1219 | if (IsValidPartition (&CurrentSlot, L"vendor_boot") && |
Venkata Rao Kakani | 4412bdf | 2021-06-10 18:01:28 +0530 | [diff] [blame] | 1220 | (HeaderVersion == BOOT_HEADER_VERSION_ZERO || |
| 1221 | HeaderVersion >= BOOT_HEADER_VERSION_THREE)) { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1222 | AddRequestedPartition (RequestedPartitionAll, IMG_VENDOR_BOOT); |
AnilKumar Chimata | 3597bc1 | 2018-07-05 15:53:25 +0530 | [diff] [blame] | 1223 | NumRequestedPartition += 1; |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1224 | if (SlotData != NULL) { |
| 1225 | avb_slot_verify_data_free (SlotData); |
| 1226 | } |
| 1227 | Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition, |
| 1228 | SlotSuffix, VerifyFlags, VerityFlags, &SlotData); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1229 | } else { |
Venkata Rao Kakani | b0c29dc | 2021-05-28 13:17:55 +0530 | [diff] [blame] | 1230 | DEBUG ((EFI_D_ERROR, "Invalid vendor_boot partition. Skipping\n")); |
AnilKumar Chimata | 3597bc1 | 2018-07-05 15:53:25 +0530 | [diff] [blame] | 1231 | } |
Monika Singh | 4359887 | 2018-10-15 12:04:02 +0530 | [diff] [blame] | 1232 | } |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1233 | |
Mukesh Ojha | 88a4fb9 | 2018-03-09 13:54:54 +0530 | [diff] [blame] | 1234 | if (SlotData == NULL) { |
| 1235 | Status = EFI_LOAD_ERROR; |
| 1236 | Info->BootState = RED; |
| 1237 | goto out; |
| 1238 | } |
| 1239 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1240 | if (AllowVerificationError && ResultShouldContinue (Result)) { |
lijuang | f2eb1fa | 2019-09-23 14:10:20 +0800 | [diff] [blame] | 1241 | DEBUG ((EFI_D_VERBOSE, "State: Unlocked, AvbSlotVerify returned " |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1242 | "%a, continue boot\n", |
| 1243 | avb_slot_verify_result_to_string (Result))); |
| 1244 | } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) { |
| 1245 | DEBUG ((EFI_D_ERROR, "ERROR: Device State %a, AvbSlotVerify returned %a\n", |
| 1246 | AllowVerificationError ? "Unlocked" : "Locked", |
| 1247 | avb_slot_verify_result_to_string (Result))); |
| 1248 | Status = EFI_LOAD_ERROR; |
| 1249 | Info->BootState = RED; |
| 1250 | goto out; |
| 1251 | } |
| 1252 | |
| 1253 | for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) { |
| 1254 | DEBUG ((EFI_D_VERBOSE, "Requested Partition: %a\n", |
| 1255 | RequestedPartition[ReqIndex])); |
| 1256 | for (UINTN LoadedIndex = 0; LoadedIndex < SlotData->num_loaded_partitions; |
| 1257 | LoadedIndex++) { |
| 1258 | DEBUG ((EFI_D_VERBOSE, "Loaded Partition: %a\n", |
| 1259 | SlotData->loaded_partitions[LoadedIndex].partition_name)); |
| 1260 | if (!AsciiStrnCmp ( |
| 1261 | RequestedPartition[ReqIndex], |
| 1262 | SlotData->loaded_partitions[LoadedIndex].partition_name, |
| 1263 | AsciiStrLen ( |
| 1264 | SlotData->loaded_partitions[LoadedIndex].partition_name))) { |
| 1265 | if (Info->NumLoadedImages >= ARRAY_SIZE (Info->Images)) { |
| 1266 | DEBUG ((EFI_D_ERROR, "NumLoadedPartition" |
| 1267 | "(%d) too large " |
| 1268 | "max images(%d)\n", |
| 1269 | Info->NumLoadedImages, ARRAY_SIZE (Info->Images))); |
| 1270 | Status = EFI_LOAD_ERROR; |
| 1271 | Info->BootState = RED; |
| 1272 | goto out; |
| 1273 | } |
| 1274 | Info->Images[Info->NumLoadedImages].Name = |
| 1275 | SlotData->loaded_partitions[LoadedIndex].partition_name; |
| 1276 | Info->Images[Info->NumLoadedImages].ImageBuffer = |
| 1277 | SlotData->loaded_partitions[LoadedIndex].data; |
| 1278 | Info->Images[Info->NumLoadedImages].ImageSize = |
| 1279 | SlotData->loaded_partitions[LoadedIndex].data_size; |
| 1280 | Info->NumLoadedImages++; |
| 1281 | break; |
| 1282 | } |
| 1283 | } |
| 1284 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1285 | |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1286 | if (Info->NumLoadedImages < NumRequestedPartition) { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1287 | DEBUG ((EFI_D_ERROR, "ERROR: AvbSlotVerify slot data error: num of " |
| 1288 | "loaded partitions %d, requested %d\n", |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1289 | Info->NumLoadedImages, NumRequestedPartition)); |
Zhen Kong | 3b3a0df | 2017-10-04 19:00:09 -0700 | [diff] [blame] | 1290 | Status = EFI_LOAD_ERROR; |
| 1291 | goto out; |
| 1292 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1293 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1294 | DEBUG ((EFI_D_VERBOSE, "Total loaded partition %d\n", Info->NumLoadedImages)); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1295 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1296 | VBData = (VB2Data *)avb_calloc (sizeof (VB2Data)); |
| 1297 | if (VBData == NULL) { |
| 1298 | DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate VB2Data\n")); |
| 1299 | Status = EFI_OUT_OF_RESOURCES; |
| 1300 | goto out; |
| 1301 | } |
| 1302 | VBData->Ops = Ops; |
| 1303 | VBData->SlotData = SlotData; |
| 1304 | Info->VBData = (VOID *)VBData; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1305 | |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1306 | GUARD_OUT (GetImage (Info, &ImageBuffer, &ImageSize, |
Monika Singh | 8bfc66a | 2019-03-08 12:18:17 +0530 | [diff] [blame] | 1307 | ( (!Info->MultiSlotBoot || |
| 1308 | IsDynamicPartitionSupport ()) && |
Prakruthi Deepak Heragu | 70ad7f4 | 2020-02-03 16:33:59 -0800 | [diff] [blame] | 1309 | (Info->BootIntoRecovery && |
| 1310 | !IsBuildUseRecoveryAsBoot ())) ? |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1311 | "recovery" : "boot")); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1312 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1313 | if (ImageSize < sizeof (boot_img_hdr)) { |
| 1314 | DEBUG ((EFI_D_ERROR, "Invalid boot image header size: %u\n", ImageSize)); |
| 1315 | Status = EFI_BAD_BUFFER_SIZE; |
| 1316 | goto out; |
| 1317 | } |
| 1318 | |
| 1319 | BootImgHdr = (boot_img_hdr *)ImageBuffer; |
| 1320 | |
| 1321 | if (BootImgHdr->header_version >= BOOT_HEADER_VERSION_THREE) { |
| 1322 | GUARD_OUT (GetImage (Info, &VendorBootImageBuffer, |
Raghavendra Rao Ananta | c3668a2 | 2020-01-13 18:20:02 -0800 | [diff] [blame] | 1323 | &VendorBootImageSize, "vendor_boot")); |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1324 | } |
| 1325 | |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1326 | Status = CheckImageHeader (ImageBuffer, ImageHdrSize, |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1327 | VendorBootImageBuffer, VendorBootImageSize, |
| 1328 | &ImageSizeActual, &PageSize, |
| 1329 | Info->BootIntoRecovery); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1330 | if (Status != EFI_SUCCESS) { |
| 1331 | DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status)); |
| 1332 | goto out; |
| 1333 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1334 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1335 | if (AllowVerificationError) { |
| 1336 | Info->BootState = ORANGE; |
| 1337 | } else { |
| 1338 | if (UserData->IsUserKey) { |
| 1339 | Info->BootState = YELLOW; |
| 1340 | } else { |
| 1341 | Info->BootState = GREEN; |
| 1342 | } |
| 1343 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1344 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1345 | /* command line */ |
| 1346 | GUARD_OUT (AppendVBCommonCmdLine (Info)); |
| 1347 | GUARD_OUT (AppendVBCmdLine (Info, SlotData->cmdline)); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1348 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1349 | /* Set Rot & Boot State*/ |
| 1350 | Data.Color = Info->BootState; |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1351 | Data. IsUnlocked = AllowVerificationError; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1352 | Data.PublicKeyLength = UserData->PublicKeyLen; |
| 1353 | Data.PublicKey = UserData->PublicKey; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1354 | |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1355 | GUARD_OUT (KeyMasterGetDateSupport (&DateSupport)); |
| 1356 | |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1357 | if (BootImgHdr->header_version >= BOOT_HEADER_VERSION_THREE) { |
| 1358 | OSVersion = ((boot_img_hdr_v3 *)(ImageBuffer))->os_version; |
| 1359 | } else { |
| 1360 | OSVersion = BootImgHdr->os_version; |
| 1361 | } |
| 1362 | |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1363 | /* Send date value in security patch only when KM TA supports it and the |
| 1364 | * property is available in vbmeta data, send the old value in other cases |
| 1365 | */ |
lijuang | f2eb1fa | 2019-09-23 14:10:20 +0800 | [diff] [blame] | 1366 | DEBUG ((EFI_D_VERBOSE, "DateSupport: %d\n", DateSupport)); |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1367 | if (DateSupport) { |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1368 | BootSecurityLevel = avb_property_lookup ( |
| 1369 | SlotData->vbmeta_images[0].vbmeta_data, |
| 1370 | SlotData->vbmeta_images[0].vbmeta_size, |
| 1371 | "com.android.build.boot.security_patch", |
| 1372 | 0, &BootSecurityLevelSize); |
| 1373 | |
| 1374 | if (BootSecurityLevel != NULL && |
| 1375 | BootSecurityLevelSize == MAX_PROPERTY_SIZE) { |
| 1376 | Data.SystemSecurityLevel = ParseBootSecurityLevel (BootSecurityLevel, |
| 1377 | BootSecurityLevelSize); |
| 1378 | if (Data.SystemSecurityLevel < 0) { |
| 1379 | DEBUG ((EFI_D_ERROR, "System security patch level format invalid\n")); |
| 1380 | Status = EFI_INVALID_PARAMETER; |
| 1381 | goto out; |
| 1382 | } |
| 1383 | } |
| 1384 | else { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1385 | Data.SystemSecurityLevel = (OSVersion & 0x7FF); |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1386 | } |
| 1387 | } |
| 1388 | else { |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1389 | Data.SystemSecurityLevel = (OSVersion & 0x7FF); |
Monika Singh | 9329878 | 2019-04-01 16:29:29 +0530 | [diff] [blame] | 1390 | } |
Raghavendra Rao Ananta | 0746956 | 2019-10-11 08:53:20 -0700 | [diff] [blame] | 1391 | Data.SystemVersion = (OSVersion & 0xFFFFF800) >> 11; |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1392 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1393 | GUARD_OUT (KeyMasterSetRotAndBootState (&Data)); |
Barani Muthukumaran | af2a746 | 2019-03-20 15:40:57 -0700 | [diff] [blame] | 1394 | ComputeVbMetaDigest (SlotData, (CHAR8 *)&Digest); |
| 1395 | GUARD_OUT (SetVerifiedBootHash ((CONST CHAR8 *)&Digest, sizeof(Digest))); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1396 | DEBUG ((EFI_D_INFO, "VB2: Authenticate complete! boot state is: %a\n", |
| 1397 | VbSn[Info->BootState].name)); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1398 | |
| 1399 | out: |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1400 | if (Status != EFI_SUCCESS) { |
| 1401 | if (SlotData != NULL) { |
| 1402 | avb_slot_verify_data_free (SlotData); |
| 1403 | } |
| 1404 | if (Ops != NULL) { |
| 1405 | AvbOpsFree (Ops); |
| 1406 | } |
| 1407 | if (UserData != NULL) { |
| 1408 | avb_free (UserData); |
| 1409 | } |
| 1410 | if (VBData != NULL) { |
| 1411 | avb_free (VBData); |
| 1412 | } |
| 1413 | Info->BootState = RED; |
AnilKumar Chimata | 681e0f4 | 2018-01-19 17:47:56 -0800 | [diff] [blame] | 1414 | if (Info->MultiSlotBoot) { |
| 1415 | HandleActiveSlotUnbootable (); |
| 1416 | /* HandleActiveSlotUnbootable should have swapped slots and |
| 1417 | * reboot the device. If no bootable slot found, enter fastboot |
| 1418 | */ |
| 1419 | DEBUG ((EFI_D_WARN, "No bootable slots found enter fastboot mode\n")); |
| 1420 | } else { |
| 1421 | DEBUG ((EFI_D_WARN, |
| 1422 | "Non Multi-slot: Unbootable entering fastboot mode\n")); |
| 1423 | } |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1424 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1425 | |
lijuang | f2eb1fa | 2019-09-23 14:10:20 +0800 | [diff] [blame] | 1426 | DEBUG ((EFI_D_INFO, "VB2: boot state: %a(%d)\n", |
| 1427 | VbSn[Info->BootState].name, Info->BootState)); |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1428 | return Status; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1429 | } |
| 1430 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1431 | STATIC EFI_STATUS |
| 1432 | DisplayVerifiedBootScreen (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1433 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1434 | EFI_STATUS Status = EFI_SUCCESS; |
| 1435 | CHAR8 FfbmStr[FFBM_MODE_BUF_SIZE] = {'\0'}; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1436 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1437 | if (GetAVBVersion () < AVB_1) { |
| 1438 | return EFI_SUCCESS; |
| 1439 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1440 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1441 | if (!StrnCmp (Info->Pname, L"boot", StrLen (L"boot"))) { |
| 1442 | Status = GetFfbmCommand (FfbmStr, FFBM_MODE_BUF_SIZE); |
| 1443 | if (Status != EFI_SUCCESS) { |
| 1444 | DEBUG ((EFI_D_VERBOSE, "No Ffbm cookie found, ignore: %r\n", Status)); |
| 1445 | FfbmStr[0] = '\0'; |
| 1446 | } |
| 1447 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1448 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1449 | DEBUG ((EFI_D_VERBOSE, "Boot State is : %d\n", Info->BootState)); |
| 1450 | switch (Info->BootState) { |
| 1451 | case RED: |
| 1452 | Status = DisplayVerifiedBootMenu (DISPLAY_MENU_RED); |
| 1453 | if (Status != EFI_SUCCESS) { |
| 1454 | DEBUG ((EFI_D_INFO, |
| 1455 | "Your device is corrupt. It can't be trusted and will not boot." |
| 1456 | "\nYour device will shutdown in 30s\n")); |
| 1457 | } |
| 1458 | MicroSecondDelay (30000000); |
| 1459 | ShutdownDevice (); |
| 1460 | break; |
| 1461 | case YELLOW: |
| 1462 | Status = DisplayVerifiedBootMenu (DISPLAY_MENU_YELLOW); |
| 1463 | if (Status == EFI_SUCCESS) { |
| 1464 | WaitForExitKeysDetection (); |
| 1465 | } else { |
| 1466 | DEBUG ((EFI_D_INFO, "Your device has loaded a different operating system." |
| 1467 | "\nWait for 5 seconds before proceeding\n")); |
| 1468 | MicroSecondDelay (5000000); |
| 1469 | } |
| 1470 | break; |
| 1471 | case ORANGE: |
| 1472 | if (FfbmStr[0] != '\0' && !TargetBuildVariantUser ()) { |
| 1473 | DEBUG ((EFI_D_VERBOSE, "Device will boot into FFBM mode\n")); |
| 1474 | } else { |
| 1475 | Status = DisplayVerifiedBootMenu (DISPLAY_MENU_ORANGE); |
| 1476 | if (Status == EFI_SUCCESS) { |
| 1477 | WaitForExitKeysDetection (); |
| 1478 | } else { |
| 1479 | DEBUG ( |
| 1480 | (EFI_D_INFO, "Device is unlocked, Skipping boot verification\n")); |
| 1481 | MicroSecondDelay (5000000); |
| 1482 | } |
| 1483 | } |
| 1484 | break; |
| 1485 | default: |
| 1486 | break; |
| 1487 | } |
lijuang | 3d51d3b | 2018-07-03 14:29:59 +0800 | [diff] [blame] | 1488 | |
| 1489 | /* dm-verity warning */ |
Jeevan Shriram | 70d9857 | 2018-09-26 15:01:49 -0700 | [diff] [blame] | 1490 | if ((GetAVBVersion () != AVB_2) && |
| 1491 | !IsEnforcing () && |
lijuang | 3d51d3b | 2018-07-03 14:29:59 +0800 | [diff] [blame] | 1492 | !Info->BootIntoRecovery) { |
| 1493 | Status = DisplayVerifiedBootMenu (DISPLAY_MENU_EIO); |
| 1494 | if (Status == EFI_SUCCESS) { |
| 1495 | WaitForExitKeysDetection (); |
| 1496 | } else { |
| 1497 | DEBUG ((EFI_D_INFO, "The dm-verity is not started in restart mode." \ |
| 1498 | "\nWait for 30 seconds before proceeding\n")); |
| 1499 | MicroSecondDelay (30000000); |
| 1500 | } |
| 1501 | } |
| 1502 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1503 | return EFI_SUCCESS; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1504 | } |
| 1505 | |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1506 | STATIC EFI_STATUS LoadImageAndAuthForLE (BootInfo *Info) |
| 1507 | { |
| 1508 | EFI_STATUS Status = EFI_SUCCESS; |
| 1509 | QcomAsn1x509Protocol *QcomAsn1X509Protocal = NULL; |
| 1510 | CONST UINT8 *OemCertFile = LeOemCertificate; |
| 1511 | UINTN OemCertFileLen = sizeof (LeOemCertificate); |
| 1512 | CERTIFICATE OemCert = {NULL}; |
| 1513 | UINTN HashSize; |
| 1514 | UINT8 *ImgHash = NULL; |
| 1515 | UINTN ImgSize; |
| 1516 | VB_HASH HashAlgorithm; |
| 1517 | UINT8 *SigAddr = NULL; |
| 1518 | UINT32 SigSize = 0; |
mohamed sunfeer | 4987c69 | 2018-04-18 19:29:28 +0530 | [diff] [blame] | 1519 | CHAR8 *SystemPath = NULL; |
| 1520 | UINT32 SystemPathLen = 0; |
Anmolpreet Kaur | deae0f1 | 2019-01-17 11:48:48 +0530 | [diff] [blame] | 1521 | BOOLEAN SecureDevice = FALSE; |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1522 | /*Load image*/ |
mohamed sunfeer | 4987c69 | 2018-04-18 19:29:28 +0530 | [diff] [blame] | 1523 | GUARD (VBAllocateCmdLine (Info)); |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1524 | GUARD (VBCommonInit (Info)); |
| 1525 | GUARD (LoadImageNoAuth (Info)); |
| 1526 | |
Anmolpreet Kaur | deae0f1 | 2019-01-17 11:48:48 +0530 | [diff] [blame] | 1527 | Status = IsSecureDevice (&SecureDevice); |
| 1528 | if (Status != EFI_SUCCESS) { |
| 1529 | DEBUG ((EFI_D_ERROR, "VB: Failed read device state: %r\n", Status)); |
| 1530 | return Status; |
| 1531 | } |
| 1532 | |
| 1533 | if (!SecureDevice) { |
| 1534 | if (!TargetBuildVariantUser () ) { |
| 1535 | DEBUG ((EFI_D_INFO, "VB: verification skipped for debug builds\n")); |
| 1536 | goto skip_verification; |
| 1537 | } |
Mohamed Sunfeer | 604b2ed | 2018-10-30 13:36:02 +0530 | [diff] [blame] | 1538 | } |
| 1539 | |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1540 | /* Initialize Verified Boot*/ |
| 1541 | device_info_vb_t DevInfo_vb; |
| 1542 | DevInfo_vb.is_unlocked = IsUnlocked (); |
| 1543 | DevInfo_vb.is_unlock_critical = IsUnlockCritical (); |
| 1544 | Status = Info->VbIntf->VBDeviceInit (Info->VbIntf, |
| 1545 | (device_info_vb_t *)&DevInfo_vb); |
| 1546 | if (Status != EFI_SUCCESS) { |
| 1547 | DEBUG ((EFI_D_ERROR, "VB: Error during VBDeviceInit: %r\n", Status)); |
| 1548 | return Status; |
| 1549 | } |
| 1550 | |
| 1551 | /* Locate QcomAsn1x509Protocol*/ |
| 1552 | Status = gBS->LocateProtocol (&gEfiQcomASN1X509ProtocolGuid, NULL, |
| 1553 | (VOID **)&QcomAsn1X509Protocal); |
| 1554 | if (Status != EFI_SUCCESS) { |
| 1555 | DEBUG ((EFI_D_ERROR, "VB: Error LocateProtocol " |
| 1556 | "gEfiQcomASN1X509ProtocolGuid: %r\n", Status)); |
| 1557 | return Status; |
| 1558 | } |
| 1559 | |
| 1560 | /* Read OEM certificate from the embedded header file */ |
| 1561 | Status = QcomAsn1X509Protocal->ASN1X509VerifyOEMCertificate |
| 1562 | (QcomAsn1X509Protocal, OemCertFile, OemCertFileLen, &OemCert); |
| 1563 | if (Status != EFI_SUCCESS) { |
| 1564 | DEBUG ((EFI_D_ERROR, "VB: Error during " |
| 1565 | "ASN1X509VerifyOEMCertificate: %r\n", Status)); |
| 1566 | return Status; |
| 1567 | } |
| 1568 | |
| 1569 | /*Calculate kernel image hash, SHA256 is used by default*/ |
| 1570 | HashAlgorithm = VB_SHA256; |
| 1571 | HashSize = VB_SHA256_SIZE; |
| 1572 | ImgSize = Info->Images[0].ImageSize; |
Bhanuprakash Modem | 763cdd5 | 2018-11-01 14:49:55 +0530 | [diff] [blame] | 1573 | ImgHash = AllocateZeroPool (HashSize); |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1574 | if (ImgHash == NULL) { |
| 1575 | DEBUG ((EFI_D_ERROR, "kernel image hash buffer allocation failed!\n")); |
| 1576 | Status = EFI_OUT_OF_RESOURCES; |
| 1577 | return Status; |
| 1578 | } |
| 1579 | Status = LEGetImageHash (QcomAsn1X509Protocal, HashAlgorithm, |
| 1580 | (UINT8 *)Info->Images[0].ImageBuffer, |
| 1581 | ImgSize, ImgHash, HashSize); |
| 1582 | if (Status != EFI_SUCCESS) { |
| 1583 | DEBUG ((EFI_D_ERROR, "VB: Error during VBGetImageHash: %r\n", Status)); |
| 1584 | return Status; |
| 1585 | } |
| 1586 | |
| 1587 | SigAddr = (UINT8 *)Info->Images[0].ImageBuffer + ImgSize; |
| 1588 | SigSize = LE_BOOTIMG_SIG_SIZE; |
| 1589 | Status = LEVerifyHashWithSignature (QcomAsn1X509Protocal, ImgHash, |
| 1590 | HashAlgorithm, &OemCert, SigAddr, SigSize); |
| 1591 | |
| 1592 | if (Status != EFI_SUCCESS) { |
| 1593 | DEBUG ((EFI_D_ERROR, "VB: Error during " |
| 1594 | "LEVBVerifyHashWithSignature: %r\n", Status)); |
| 1595 | return Status; |
| 1596 | } |
| 1597 | DEBUG ((EFI_D_INFO, "VB: LoadImageAndAuthForLE complete!\n")); |
mohamed sunfeer | 4987c69 | 2018-04-18 19:29:28 +0530 | [diff] [blame] | 1598 | |
Mohamed Sunfeer | 604b2ed | 2018-10-30 13:36:02 +0530 | [diff] [blame] | 1599 | skip_verification: |
mohamed sunfeer | 4987c69 | 2018-04-18 19:29:28 +0530 | [diff] [blame] | 1600 | if (!IsRootCmdLineUpdated (Info)) { |
Venkata Narendra Kumar Gutta | d1cbfd2 | 2020-01-07 13:27:33 -0800 | [diff] [blame] | 1601 | SystemPathLen = GetSystemPath (&SystemPath, Info); |
mohamed sunfeer | 4987c69 | 2018-04-18 19:29:28 +0530 | [diff] [blame] | 1602 | if (SystemPathLen == 0 || |
| 1603 | SystemPath == NULL) { |
| 1604 | return EFI_LOAD_ERROR; |
| 1605 | } |
| 1606 | GUARD (AppendVBCmdLine (Info, SystemPath)); |
| 1607 | } |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1608 | return Status; |
| 1609 | } |
| 1610 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1611 | EFI_STATUS |
| 1612 | LoadImageAndAuth (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1613 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1614 | EFI_STATUS Status = EFI_SUCCESS; |
| 1615 | BOOLEAN MdtpActive = FALSE; |
| 1616 | QCOM_MDTP_PROTOCOL *MdtpProtocol; |
| 1617 | UINT32 AVBVersion = NO_AVB; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1618 | |
jianzhou | b8a6fe0 | 2020-05-06 16:28:19 +0800 | [diff] [blame] | 1619 | WaitForFlashFinished (); |
| 1620 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1621 | if (Info == NULL) { |
| 1622 | DEBUG ((EFI_D_ERROR, "Invalid parameter Info\n")); |
| 1623 | return EFI_INVALID_PARAMETER; |
| 1624 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1625 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1626 | /* Get Partition Name*/ |
| 1627 | if (!Info->MultiSlotBoot) { |
| 1628 | if (Info->BootIntoRecovery) { |
| 1629 | DEBUG ((EFI_D_INFO, "Booting Into Recovery Mode\n")); |
| 1630 | StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"recovery", |
| 1631 | StrLen (L"recovery")); |
| 1632 | } else { |
| 1633 | DEBUG ((EFI_D_INFO, "Booting Into Mission Mode\n")); |
| 1634 | StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot", |
| 1635 | StrLen (L"boot")); |
| 1636 | } |
| 1637 | } else { |
| 1638 | Slot CurrentSlot = {{0}}; |
Shivaprasad Hongal | c017e81 | 2017-04-26 16:15:27 -0700 | [diff] [blame] | 1639 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1640 | GUARD (FindBootableSlot (&CurrentSlot)); |
| 1641 | if (IsSuffixEmpty (&CurrentSlot)) { |
| 1642 | DEBUG ((EFI_D_ERROR, "No bootable slot\n")); |
| 1643 | return EFI_LOAD_ERROR; |
| 1644 | } |
Shivaprasad Hongal | c017e81 | 2017-04-26 16:15:27 -0700 | [diff] [blame] | 1645 | |
Mayank Grover | 1c05158 | 2019-02-26 14:42:27 +0530 | [diff] [blame] | 1646 | if (IsDynamicPartitionSupport () && |
| 1647 | Info->BootIntoRecovery) { |
| 1648 | DEBUG ((EFI_D_INFO, "Booting Into Recovery Mode\n")); |
| 1649 | StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"recovery", |
| 1650 | StrLen (L"recovery")); |
| 1651 | } else { |
| 1652 | DEBUG ((EFI_D_INFO, "Booting Into Mission Mode\n")); |
| 1653 | GUARD (StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot", |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1654 | StrLen (L"boot"))); |
Mayank Grover | 1c05158 | 2019-02-26 14:42:27 +0530 | [diff] [blame] | 1655 | } |
| 1656 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1657 | GUARD (StrnCatS (Info->Pname, ARRAY_SIZE (Info->Pname), CurrentSlot.Suffix, |
| 1658 | StrLen (CurrentSlot.Suffix))); |
| 1659 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1660 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1661 | DEBUG ((EFI_D_VERBOSE, "MultiSlot %a, partition name %s\n", |
| 1662 | BooleanString[Info->MultiSlotBoot].name, Info->Pname)); |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1663 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1664 | if (FixedPcdGetBool (EnableMdtpSupport)) { |
| 1665 | Status = IsMdtpActive (&MdtpActive); |
| 1666 | if (EFI_ERROR (Status)) { |
| 1667 | DEBUG ((EFI_D_ERROR, "Failed to get activation state for MDTP, " |
| 1668 | "Status=%r." |
| 1669 | " Considering MDTP as active and continuing \n", |
| 1670 | Status)); |
| 1671 | if (Status != EFI_NOT_FOUND) |
| 1672 | MdtpActive = TRUE; |
| 1673 | } |
| 1674 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1675 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1676 | AVBVersion = GetAVBVersion (); |
| 1677 | DEBUG ((EFI_D_VERBOSE, "AVB version %d\n", AVBVersion)); |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1678 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1679 | /* Load and Authenticate */ |
| 1680 | switch (AVBVersion) { |
| 1681 | case NO_AVB: |
| 1682 | return LoadImageNoAuthWrapper (Info); |
| 1683 | break; |
| 1684 | case AVB_1: |
| 1685 | Status = LoadImageAndAuthVB1 (Info); |
| 1686 | break; |
| 1687 | case AVB_2: |
| 1688 | Status = LoadImageAndAuthVB2 (Info); |
| 1689 | break; |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1690 | case AVB_LE: |
| 1691 | Status = LoadImageAndAuthForLE (Info); |
| 1692 | break; |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1693 | default: |
| 1694 | DEBUG ((EFI_D_ERROR, "Unsupported AVB version %d\n", AVBVersion)); |
| 1695 | Status = EFI_UNSUPPORTED; |
| 1696 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1697 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1698 | // if MDTP is active Display Recovery UI |
| 1699 | if (Status != EFI_SUCCESS && MdtpActive) { |
| 1700 | Status = gBS->LocateProtocol (&gQcomMdtpProtocolGuid, NULL, |
| 1701 | (VOID **)&MdtpProtocol); |
| 1702 | if (EFI_ERROR (Status)) { |
| 1703 | DEBUG ( |
| 1704 | (EFI_D_ERROR, "Failed to locate MDTP protocol, Status=%r\n", Status)); |
| 1705 | return Status; |
| 1706 | } |
| 1707 | /* Perform Local Deactivation of MDTP */ |
| 1708 | Status = MdtpProtocol->MdtpDeactivate (MdtpProtocol, FALSE); |
| 1709 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1710 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1711 | if (IsUnlocked () && Status != EFI_SUCCESS) { |
| 1712 | DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status)); |
| 1713 | return Status; |
| 1714 | } |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1715 | |
Zhen Kong | bb3db75 | 2017-07-10 17:07:10 -0700 | [diff] [blame] | 1716 | if (AVBVersion != AVB_LE) { |
| 1717 | DisplayVerifiedBootScreen (Info); |
| 1718 | DEBUG ((EFI_D_VERBOSE, "Sending Milestone Call\n")); |
| 1719 | Status = Info->VbIntf->VBSendMilestone (Info->VbIntf); |
| 1720 | if (Status != EFI_SUCCESS) { |
| 1721 | DEBUG ((EFI_D_ERROR, "Error sending milestone call to TZ\n")); |
| 1722 | return Status; |
| 1723 | } |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1724 | } |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1725 | return Status; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1726 | } |
| 1727 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1728 | VOID |
| 1729 | FreeVerifiedBootResource (BootInfo *Info) |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1730 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1731 | DEBUG ((EFI_D_VERBOSE, "FreeVerifiedBootResource\n")); |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1732 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1733 | if (Info == NULL) { |
| 1734 | return; |
| 1735 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1736 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1737 | VB2Data *VBData = Info->VBData; |
| 1738 | if (VBData != NULL) { |
| 1739 | AvbOps *Ops = VBData->Ops; |
| 1740 | if (Ops != NULL) { |
| 1741 | if (Ops->user_data != NULL) { |
| 1742 | avb_free (Ops->user_data); |
| 1743 | } |
| 1744 | AvbOpsFree (Ops); |
| 1745 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1746 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1747 | AvbSlotVerifyData *SlotData = VBData->SlotData; |
| 1748 | if (SlotData != NULL) { |
| 1749 | avb_slot_verify_data_free (SlotData); |
| 1750 | } |
| 1751 | avb_free (VBData); |
| 1752 | } |
Shivaprasad Hongal | e3b5339 | 2017-04-27 17:32:47 -0700 | [diff] [blame] | 1753 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1754 | if (Info->VBCmdLine != NULL) { |
| 1755 | FreePool (Info->VBCmdLine); |
| 1756 | } |
| 1757 | return; |
Shivaprasad Hongal | a2c4dd7 | 2017-04-27 14:33:18 -0700 | [diff] [blame] | 1758 | } |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1759 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1760 | EFI_STATUS |
| 1761 | GetCertFingerPrint (UINT8 *FingerPrint, |
| 1762 | UINTN FingerPrintLen, |
| 1763 | UINTN *FingerPrintLenOut) |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1764 | { |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1765 | EFI_STATUS Status = EFI_SUCCESS; |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1766 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1767 | if (FingerPrint == NULL || FingerPrintLenOut == NULL || |
| 1768 | FingerPrintLen < AVB_SHA256_DIGEST_SIZE) { |
| 1769 | DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: Invalid parameters\n")); |
| 1770 | return EFI_INVALID_PARAMETER; |
| 1771 | } |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1772 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1773 | if (GetAVBVersion () == AVB_1) { |
| 1774 | QCOM_VERIFIEDBOOT_PROTOCOL *VbIntf = NULL; |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1775 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1776 | Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL, |
| 1777 | (VOID **)&VbIntf); |
| 1778 | if (Status != EFI_SUCCESS) { |
| 1779 | DEBUG ((EFI_D_ERROR, "Unable to locate VerifiedBoot Protocol\n")); |
| 1780 | return Status; |
| 1781 | } |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1782 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1783 | if (VbIntf->Revision < QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) { |
| 1784 | DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: VB1: not " |
| 1785 | "supported for this revision\n")); |
| 1786 | return EFI_UNSUPPORTED; |
| 1787 | } |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1788 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1789 | Status = VbIntf->VBGetCertFingerPrint (VbIntf, FingerPrint, FingerPrintLen, |
| 1790 | FingerPrintLenOut); |
| 1791 | if (Status != EFI_SUCCESS) { |
| 1792 | DEBUG ((EFI_D_ERROR, "Failed Reading CERT FingerPrint\n")); |
| 1793 | return Status; |
| 1794 | } |
| 1795 | } else if (GetAVBVersion () == AVB_2) { |
| 1796 | CHAR8 *UserKeyBuffer = NULL; |
| 1797 | UINT32 UserKeyLength = 0; |
| 1798 | AvbSHA256Ctx UserKeyCtx = {{0}}; |
| 1799 | CHAR8 *UserKeyDigest = NULL; |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1800 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1801 | GUARD (GetUserKey (&UserKeyBuffer, &UserKeyLength)); |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1802 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1803 | avb_sha256_init (&UserKeyCtx); |
| 1804 | avb_sha256_update (&UserKeyCtx, (UINT8 *)UserKeyBuffer, UserKeyLength); |
| 1805 | UserKeyDigest = (CHAR8 *)avb_sha256_final (&UserKeyCtx); |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1806 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1807 | CopyMem (FingerPrint, UserKeyDigest, AVB_SHA256_DIGEST_SIZE); |
| 1808 | *FingerPrintLenOut = AVB_SHA256_DIGEST_SIZE; |
| 1809 | } else { |
| 1810 | DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: not supported\n")); |
| 1811 | return EFI_UNSUPPORTED; |
| 1812 | } |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1813 | |
Jeevan Shriram | 17f173d | 2017-10-24 22:11:07 -0700 | [diff] [blame] | 1814 | return Status; |
Shivaprasad Hongal | 7fd6a52 | 2017-05-10 13:56:28 -0700 | [diff] [blame] | 1815 | } |