blob: 759078d7eaba8c75d33898cc40bbe1b334959847 [file] [log] [blame]
Venkata Rao Kakanib0c29dc2021-05-28 13:17:55 +05301/* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07002 *
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 Ananta07469562019-10-11 08:53:20 -070031#include "BootImage.h"
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070032#include "KeymasterClient.h"
33#include "libavb/libavb.h"
jianzhoub8a6fe02020-05-06 16:28:19 +080034#include <FastbootLib/FastbootCmds.h>
Shivaprasad Hongalf1fb0472017-05-23 20:05:16 -070035#include <Library/MenuKeysDetection.h>
Jeevan Shriram17f173d2017-10-24 22:11:07 -070036#include <Library/VerifiedBootMenu.h>
Zhen Kongbb3db752017-07-10 17:07:10 -070037#include <Library/LEOEMCertificate.h>
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070038
39STATIC CONST CHAR8 *VerityMode = " androidboot.veritymode=";
40STATIC CONST CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
41STATIC CONST CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
Mukesh Ojha71be2c82018-02-02 19:13:10 +053042STATIC CONST CHAR8 *DmVerityCmd = " root=/dev/dm-0 dm=\"system none ro,0 1 "
43 "android-verity";
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070044STATIC CONST CHAR8 *Space = " ";
Jeevan Shriram17f173d2017-10-24 22:11:07 -070045
Monika Singh43598872018-10-15 12:04:02 +053046#define MAX_NUM_REQ_PARTITION 8
Monika Singh93298782019-04-01 16:29:29 +053047#define MAX_PROPERTY_SIZE 10
Monika Singh43598872018-10-15 12:04:02 +053048
49static CHAR8 *avb_verify_partition_name[] = {
50 "boot",
51 "dtbo",
52 "vbmeta",
AnilKumar Chimata3597bc12018-07-05 15:53:25 +053053 "recovery",
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -080054 "vendor_boot"
Monika Singh43598872018-10-15 12:04:02 +053055};
56
Jeevan Shriram17f173d2017-10-24 22:11:07 -070057STATIC struct verified_boot_verity_mode VbVm[] = {
58 {FALSE, "logging"},
59 {TRUE, "enforcing"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070060};
61
Jeevan Shriram17f173d2017-10-24 22:11:07 -070062STATIC struct verified_boot_state_name VbSn[] = {
63 {GREEN, "green"},
64 {ORANGE, "orange"},
65 {YELLOW, "yellow"},
66 {RED, "red"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070067};
68
Jeevan Shriram17f173d2017-10-24 22:11:07 -070069struct boolean_string {
70 BOOLEAN value;
71 CHAR8 *name;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070072};
73
Jeevan Shriram17f173d2017-10-24 22:11:07 -070074STATIC struct boolean_string BooleanString[] = {
75 {FALSE, "false"},
76 {TRUE, "true"}
77};
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070078
79typedef struct {
Jeevan Shriram17f173d2017-10-24 22:11:07 -070080 AvbOps *Ops;
81 AvbSlotVerifyData *SlotData;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070082} VB2Data;
83
Jeevan Shriram17f173d2017-10-24 22:11:07 -070084UINT32
85GetAVBVersion ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070086{
Zhen Kongbb3db752017-07-10 17:07:10 -070087#if VERIFIED_BOOT_LE
88 return AVB_LE;
89#elif VERIFIED_BOOT_2
90 return AVB_2;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070091#elif VERIFIED_BOOT
Zhen Kongbb3db752017-07-10 17:07:10 -070092 return AVB_1;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070093#else
Zhen Kongbb3db752017-07-10 17:07:10 -070094 return NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070095#endif
96}
97
Jeevan Shriram17f173d2017-10-24 22:11:07 -070098BOOLEAN
99VerifiedBootEnbled ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700100{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700101 return (GetAVBVersion () > NO_AVB);
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700102}
103
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700104STATIC EFI_STATUS
105AppendVBCmdLine (BootInfo *Info, CONST CHAR8 *Src)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700106{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700107 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 Hongala2c4dd72017-04-27 14:33:18 -0700111
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700112 GUARD (AsciiStrnCatS (Dst, DstLen, Src, SrcLen));
113 Info->VBCmdLineFilledLen += SrcLen;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700114
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700115 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700116}
117
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700118STATIC EFI_STATUS
119AppendVBCommonCmdLine (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700120{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700121 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700122
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700123 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 Hongala2c4dd72017-04-27 14:33:18 -0700130}
131
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700132STATIC EFI_STATUS
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700133NoAVBLoadReqImage (BootInfo *Info, VOID **DtboImage,
134 UINT32 *DtboSize, CHAR16 *Pname, CHAR16 *RequestedPartition)
Runmin Wang261d2bf2017-11-03 11:40:40 -0700135{
136 EFI_STATUS Status = EFI_SUCCESS;
137 Slot CurrentSlot;
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530138 CHAR8 *AsciiPname = NULL;
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530139 UINT64 PartSize = 0;
140 AvbIOResult AvbStatus;
141 AvbOpsUserData *UserData = NULL;
142 AvbOps *Ops = NULL;
Runmin Wang261d2bf2017-11-03 11:40:40 -0700143
Runmin Wang261d2bf2017-11-03 11:40:40 -0700144 GUARD ( StrnCpyS (Pname,
145 (UINTN)MAX_GPT_NAME_SIZE,
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700146 (CONST CHAR16 *)RequestedPartition,
147 StrLen (RequestedPartition)));
Runmin Wang261d2bf2017-11-03 11:40:40 -0700148
149 if (Info->MultiSlotBoot) {
150 CurrentSlot = GetCurrentSlotSuffix ();
151 GUARD ( StrnCatS (Pname, MAX_GPT_NAME_SIZE,
152 CurrentSlot.Suffix, StrLen (CurrentSlot.Suffix)));
153 }
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530154 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 Modem87f2c3e2018-07-09 19:08:13 +0530175 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 Modemee92f012018-06-21 17:27:14 +0530183 AvbStatus = Ops->get_size_of_partition (Ops,
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530184 AsciiPname,
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530185 &PartSize);
186 if (AvbStatus != AVB_IO_RESULT_OK ||
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700187 PartSize == 0) {
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530188 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 Shriram0d619eb2018-10-08 15:42:11 -0700194 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 Modemee92f012018-06-21 17:27:14 +0530201 DEBUG ((EFI_D_VERBOSE, "VB: Trying to allocate memory "
202 "for DTBO: 0x%x\n", PartSize));
203 *DtboSize = (UINT32) PartSize;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530204 *DtboImage = AllocateZeroPool (PartSize);
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530205
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 Wang261d2bf2017-11-03 11:40:40 -0700211 Status = LoadImageFromPartition (*DtboImage, DtboSize, Pname);
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530212
213out:
214 if (Ops != NULL) {
215 AvbOpsFree (Ops);
216 }
217 if (UserData != NULL) {
218 avb_free (UserData);
219 }
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530220 if (AsciiPname != NULL) {
221 avb_free (AsciiPname);
222 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700223 return Status;
224}
225
226STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700227VBCommonInit (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700228{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700229 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700230
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700231 Info->BootState = RED;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700232
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700233 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 Kongdb33a732017-07-10 12:23:00 -0700237 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700238 }
239
240 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700241}
242
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700243/*
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 Shriram17f173d2017-10-24 22:11:07 -0700247STATIC EFI_STATUS
248VBAllocateCmdLine (BootInfo *Info)
Zhen Kongdb33a732017-07-10 12:23:00 -0700249{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700250 EFI_STATUS Status = EFI_SUCCESS;
Zhen Kongdb33a732017-07-10 12:23:00 -0700251
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700252 /* allocate VB command line*/
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530253 Info->VBCmdLine = AllocateZeroPool (DTB_PAD_SIZE);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700254 if (Info->VBCmdLine == NULL) {
255 DEBUG ((EFI_D_ERROR, "VB CmdLine allocation failed!\n"));
256 Status = EFI_OUT_OF_RESOURCES;
Zhen Kongdb33a732017-07-10 12:23:00 -0700257 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700258 }
259 Info->VBCmdLineLen = DTB_PAD_SIZE;
260 Info->VBCmdLineFilledLen = 0;
261 Info->VBCmdLine[Info->VBCmdLineFilledLen] = '\0';
262
263 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700264}
265
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700266STATIC
267BOOLEAN
268IsRootCmdLineUpdated (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 Ananta07469562019-10-11 08:53:20 -0700284/**
285 Load Vendor Boot image if the boot image is v3
286**/
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700287STATIC EFI_STATUS
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700288NoAVBLoadVendorBootImage (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700289{
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700290 EFI_STATUS Status;
Runmin Wang261d2bf2017-11-03 11:40:40 -0700291 CHAR16 Pname[MAX_GPT_NAME_SIZE];
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700292 UINT8 ImgIdx = Info->NumLoadedImages;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700293
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700294 Status = NoAVBLoadReqImage (Info,
295 (VOID **)&(Info->Images[ImgIdx].ImageBuffer),
296 (UINT32 *)&(Info->Images[ImgIdx].ImageSize),
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -0800297 Pname, (CHAR16 *)L"vendor_boot");
Runmin Wang261d2bf2017-11-03 11:40:40 -0700298 if (Status == EFI_NO_MEDIA) {
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -0800299 DEBUG ((EFI_D_INFO, "No vendor_boot partition is found, Skipping\n"));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700300 if (Info->Images[ImgIdx].ImageBuffer != NULL) {
301 FreePool (Info->Images[ImgIdx].ImageBuffer);
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530302 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700303 return EFI_SUCCESS;
304 }
305 else if (Status != EFI_SUCCESS) {
306 DEBUG ((EFI_D_ERROR,
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -0800307 "ERROR: Failed to load vendor_boot from partition: %r\n", Status));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700308 if (Info->Images[ImgIdx].ImageBuffer != NULL) {
309 goto Err;
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530310 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700311 }
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700312
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
324Err:
325 FreePool (Info->Images[ImgIdx].ImageBuffer);
326 return Status;
327}
328
329STATIC EFI_STATUS
330LoadVendorBootImageHeader (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 Anantac3668a22020-01-13 18:20:02 -0800338 (CHAR16 *)L"vendor_boot", StrLen ((CHAR16 *)L"vendor_boot"));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700339
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
349STATIC EFI_STATUS
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700350LoadBootImageNoAuth (BootInfo *Info, UINT32 *PageSize, BOOLEAN *FastbootPath)
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700351{
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 Ananta4713a512019-10-13 07:30:11 -0700358 BOOLEAN BootIntoRecovery = FALSE;
359 BOOLEAN BootImageLoaded;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700360
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 Ananta4713a512019-10-13 07:30:11 -0700365 BootImageLoaded = (Info->Images[0].ImageBuffer != NULL) &&
366 (Info->Images[0].ImageSize > 0);
367 *FastbootPath = BootImageLoaded;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700368
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700369 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 Ananta07469562019-10-11 08:53:20 -0700385 }
386
387 Info->HeaderVersion = ((boot_img_hdr *)(ImageHdrBuffer))->header_version;
388
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -0800389 /* Additional vendor_boot image header needs be loaded for header
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700390 * 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 Anantac3668a22020-01-13 18:20:02 -0800397 "ERROR: Failed to load vendor_boot Image header: %r\n", Status));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700398 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 Ananta4713a512019-10-13 07:30:11 -0700407 &ImageSizeActual, PageSize, BootIntoRecovery);
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700408 if (Status != EFI_SUCCESS) {
409 DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status));
410 goto Err;
411 }
412
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700413 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 Ananta07469562019-10-11 08:53:20 -0700429 }
430
431 Info->Images[0].ImageSize = ImageSizeActual;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700432
433 if (Info->HeaderVersion >= BOOT_HEADER_VERSION_THREE) {
434 Status = NoAVBLoadVendorBootImage (Info);
435 if (Status != EFI_SUCCESS) {
436 DEBUG ((EFI_D_ERROR,
Raghavendra Rao Anantac3668a22020-01-13 18:20:02 -0800437 "ERROR: Failed to load vendor_boot Image : %r\n", Status));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700438 goto ErrImgName;
439 }
440 }
441
442 return EFI_SUCCESS;
443
444ErrImgName:
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700445 if (!BootImageLoaded &&
446 Info->Images[0].Name) {
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700447 FreePool (Info->Images[0].Name);
448 }
449ErrImg:
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700450 if (!BootImageLoaded &&
451 Info->Images[0].ImageBuffer) {
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700452 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 }
457Err:
458 if (VendorImageHdrBuffer) {
459 FreePages (VendorImageHdrBuffer,
460 ALIGN_PAGES (BOOT_IMG_MAX_PAGE_SIZE, ALIGNMENT_MASK_4KB));
461 }
462ErrV3:
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700463 if (!BootImageLoaded &&
464 ImageHdrBuffer) {
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700465 FreePages (ImageHdrBuffer,
466 ALIGN_PAGES (BOOT_IMG_MAX_PAGE_SIZE, ALIGNMENT_MASK_4KB));
467 }
468
469 return Status;
470}
471
472STATIC EFI_STATUS
473LoadImageNoAuth (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 Ananta4713a512019-10-13 07:30:11 -0700479 BOOLEAN FastbootPath;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700480
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700481 Status = LoadBootImageNoAuth (Info, &PageSize, &FastbootPath);
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700482 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 Wang261d2bf2017-11-03 11:40:40 -0700512
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700513 return EFI_SUCCESS;
514
515Err:
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 Ananta4713a512019-10-13 07:30:11 -0700527 * using AllocPages(). Although, ignore if we are coming from a
528 * fastboot boot path.
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700529 */
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700530 if (FastbootPath)
531 goto err_out;
532
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -0700533 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 Shriram0d619eb2018-10-08 15:42:11 -0700544 }
545
Raghavendra Rao Ananta4713a512019-10-13 07:30:11 -0700546err_out:
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700547 return Status;
548}
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700549
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700550STATIC EFI_STATUS
551LoadImageNoAuthWrapper (BootInfo *Info)
552{
553 EFI_STATUS Status = EFI_SUCCESS;
554 CHAR8 *SystemPath = NULL;
555 UINT32 SystemPathLen = 0;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700556
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700557 GUARD (VBAllocateCmdLine (Info));
558 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700559
Mayank Grover1c051582019-02-26 14:42:27 +0530560 if (!IsDynamicPartitionSupport () &&
561 !IsRootCmdLineUpdated (Info)) {
Venkata Narendra Kumar Guttad1cbfd22020-01-07 13:27:33 -0800562 SystemPathLen = GetSystemPath (&SystemPath, Info);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700563 if (SystemPathLen == 0 || SystemPath == NULL) {
564 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
565 return EFI_LOAD_ERROR;
Zhen Kongdb33a732017-07-10 12:23:00 -0700566 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700567 GUARD (AppendVBCmdLine (Info, SystemPath));
568 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700569
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700570 return Status;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700571}
572
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700573STATIC EFI_STATUS
574LoadImageAndAuthVB1 (BootInfo *Info)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700575{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700576 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 Ojha71be2c82018-02-02 19:13:10 +0530582 CHAR8 *Temp = NULL;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700583
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700584 GUARD (VBCommonInit (Info));
585 GUARD (VBAllocateCmdLine (Info));
586 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700587
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700588 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 Shriram615b1e12017-10-12 14:10:06 -0700624 if (!IsRootCmdLineUpdated (Info)) {
Venkata Narendra Kumar Guttad1cbfd22020-01-07 13:27:33 -0800625 SystemPathLen = GetSystemPath (&SystemPath, Info);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700626 if (SystemPathLen == 0 || SystemPath == NULL) {
627 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
628 return EFI_LOAD_ERROR;
629 }
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530630 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 Shriram17f173d2017-10-24 22:11:07 -0700639 GUARD (AppendVBCmdLine (Info, SystemPath));
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530640 GUARD (AppendVBCmdLine (Info, "\""));
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700641 }
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 Hongale3b53392017-04-27 17:32:47 -0700648}
649
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700650STATIC BOOLEAN
651ResultShouldContinue (AvbSlotVerifyResult Result)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700652{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700653 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 Hongale3b53392017-04-27 17:32:47 -0700660
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700661 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 Hongale3b53392017-04-27 17:32:47 -0700667
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700668 return FALSE;
669}
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700670
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700671STATIC EFI_STATUS
Zhen Kongbb3db752017-07-10 17:07:10 -0700672LEGetImageHash (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
748exit:
749 return Status;
750}
751
752STATIC 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;
787exit:
788 return Status;
789}
790STATIC 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 Modem763cdd52018-11-01 14:49:55 +0530829 Key.N = AllocateZeroPool (sizeof (S_BIGINT));
Zhen Kongbb3db752017-07-10 17:07:10 -0700830 if (Key.N == NULL) {
831 DEBUG ((EFI_D_ERROR,
832 "VB: LEVerifySignature: mem allocation err for Key.N\n"));
833 goto exit;
834 }
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530835 Key.e = AllocateZeroPool (sizeof (S_BIGINT));
Zhen Kongbb3db752017-07-10 17:07:10 -0700836 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;
885exit:
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
895STATIC 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;
937exit:
938 return Status;
939}
940
Venkata Rao Kakanib0c29dc2021-05-28 13:17:55 +0530941static BOOLEAN GetHeaderVersion (AvbSlotVerifyData *SlotData, CHAR8 *ImageName)
Monika Singh43598872018-10-15 12:04:02 +0530942{
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 Kakanib0c29dc2021-05-28 13:17:55 +0530948 ImageName) == 0 )
Monika Singh43598872018-10-15 12:04:02 +0530949 return ( (boot_img_hdr *)
950 (SlotData->loaded_partitions[LoadedIndex].data))->header_version;
951 }
952 return HeaderVersion;
953}
954
955static 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 Kongbb3db752017-07-10 17:07:10 -0700966
Barani Muthukumaranaf2a7462019-03-20 15:40:57 -0700967STATIC VOID
968ComputeVbMetaDigest (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 Singh93298782019-04-01 16:29:29 +0530980static 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 Ananta07469562019-10-11 08:53:20 -07001017STATIC BOOLEAN
1018IsValidPartition (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 Kongbb3db752017-07-10 17:07:10 -07001039STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001040LoadImageAndAuthVB2 (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 Singh43598872018-10-15 12:04:02 +05301051 CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
1052 CHAR8 **RequestedPartition = NULL;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001053 UINTN NumRequestedPartition = 0;
lijuang91071132019-02-13 16:20:09 +08001054 UINT32 ImageHdrSize = BOOT_IMG_MAX_PAGE_SIZE;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001055 UINT32 PageSize = 0;
1056 UINT32 ImageSizeActual = 0;
1057 VOID *ImageBuffer = NULL;
1058 UINTN ImageSize = 0;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001059 VOID *VendorBootImageBuffer = NULL;
1060 UINTN VendorBootImageSize = 0;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001061 KMRotAndBootState Data = {0};
Monika Singh93298782019-04-01 16:29:29 +05301062 CONST CHAR8 *BootSecurityLevel = NULL;
1063 size_t BootSecurityLevelSize = 0;
1064 BOOLEAN DateSupport = FALSE;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001065 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 Muthukumaranaf2a7462019-03-20 15:40:57 -07001071 CHAR8 Digest[AVB_SHA256_DIGEST_SIZE];
Gaurav Kashyap39f011d2019-04-01 11:19:57 -07001072 BOOLEAN UpdateRollback = FALSE;
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001073 UINT32 OSVersion;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001074
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001075 Info->BootState = RED;
1076 GUARD (VBCommonInit (Info));
1077 GUARD (VBAllocateCmdLine (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001078
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001079 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 Hongale3b53392017-04-27 17:32:47 -07001085
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001086 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 Hongal82e18e92018-03-01 15:29:25 -08001092 UserData->IsMultiSlot = Info->MultiSlotBoot;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001093
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001094 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 Shriram17f173d2017-10-24 22:11:07 -07001104 }
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -07001105
Gaurav Kashyap39f011d2019-04-01 11:19:57 -07001106 /* 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 Shriram17f173d2017-10-24 22:11:07 -07001122 DEBUG ((EFI_D_VERBOSE, "Slot: %a, allow verification error: %a\n", SlotSuffix,
1123 BooleanString[AllowVerificationError].name));
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -07001124
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001125 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 Singh43598872018-10-15 12:04:02 +05301131 RequestedPartition = RequestedPartitionAll;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001132
Monika Singh8bfc66a2019-03-08 12:18:17 +05301133 if ( ( (!Info->MultiSlotBoot) ||
1134 IsDynamicPartitionSupport ()) &&
Prakruthi Deepak Heragu70ad7f42020-02-03 16:33:59 -08001135 (Info->BootIntoRecovery &&
1136 !IsBuildUseRecoveryAsBoot ())) {
David Zeuthen93ff0e42020-01-16 18:17:30 +05301137 if (!Info->MultiSlotBoot)
1138 VerifyFlags = VerifyFlags | AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION;
Monika Singh43598872018-10-15 12:04:02 +05301139 AddRequestedPartition (RequestedPartitionAll, IMG_RECOVERY);
1140 NumRequestedPartition += 1;
1141 Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition,
1142 SlotSuffix, VerifyFlags, VerityFlags, &SlotData);
Monika Singhe88af1f2018-11-12 13:52:41 +05301143 if (AllowVerificationError &&
1144 ResultShouldContinue (Result)) {
lijuangf2eb1fa2019-09-23 14:10:20 +08001145 DEBUG ((EFI_D_VERBOSE, "State: Unlocked, AvbSlotVerify returned "
Monika Singhe88af1f2018-11-12 13:52:41 +05301146 "%a, continue boot\n",
1147 avb_slot_verify_result_to_string (Result)));
1148 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
Monika Singh43598872018-10-15 12:04:02 +05301149 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 Kakanib0c29dc2021-05-28 13:17:55 +05301161 BOOLEAN HeaderVersion = GetHeaderVersion (SlotData, "recovery");
Monika Singh43598872018-10-15 12:04:02 +05301162 DEBUG ( (EFI_D_VERBOSE, "Recovery HeaderVersion %d \n", HeaderVersion));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001163
1164 if (HeaderVersion == BOOT_HEADER_VERSION_ZERO ||
1165 HeaderVersion >= BOOT_HEADER_VERSION_THREE) {
Monika Singh43598872018-10-15 12:04:02 +05301166 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 Ananta07469562019-10-11 08:53:20 -07001175 Slot CurrentSlot;
1176
Monika Singh43598872018-10-15 12:04:02 +05301177 if (!Info->NumLoadedImages) {
1178 AddRequestedPartition (RequestedPartitionAll, IMG_BOOT);
1179 NumRequestedPartition += 1;
1180 }
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001181
Monika Singh43598872018-10-15 12:04:02 +05301182 AddRequestedPartition (RequestedPartitionAll, IMG_DTBO);
1183 NumRequestedPartition += 1;
Jeevan Shriram0d619eb2018-10-08 15:42:11 -07001184
Venkata Rao Kakanib0c29dc2021-05-28 13:17:55 +05301185 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 Ananta07469562019-10-11 08:53:20 -07001209 if (Info->MultiSlotBoot) {
Jeevan Shriram0d619eb2018-10-08 15:42:11 -07001210 CurrentSlot = GetCurrentSlotSuffix ();
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001211 }
Jeevan Shriram0d619eb2018-10-08 15:42:11 -07001212
Venkata Rao Kakani4412bdf2021-06-10 18:01:28 +05301213 /* 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 Kakanib0c29dc2021-05-28 13:17:55 +05301219 if (IsValidPartition (&CurrentSlot, L"vendor_boot") &&
Venkata Rao Kakani4412bdf2021-06-10 18:01:28 +05301220 (HeaderVersion == BOOT_HEADER_VERSION_ZERO ||
1221 HeaderVersion >= BOOT_HEADER_VERSION_THREE)) {
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001222 AddRequestedPartition (RequestedPartitionAll, IMG_VENDOR_BOOT);
AnilKumar Chimata3597bc12018-07-05 15:53:25 +05301223 NumRequestedPartition += 1;
Venkata Rao Kakanib0c29dc2021-05-28 13:17:55 +05301224 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 Ananta07469562019-10-11 08:53:20 -07001229 } else {
Venkata Rao Kakanib0c29dc2021-05-28 13:17:55 +05301230 DEBUG ((EFI_D_ERROR, "Invalid vendor_boot partition. Skipping\n"));
AnilKumar Chimata3597bc12018-07-05 15:53:25 +05301231 }
Monika Singh43598872018-10-15 12:04:02 +05301232 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001233
Mukesh Ojha88a4fb92018-03-09 13:54:54 +05301234 if (SlotData == NULL) {
1235 Status = EFI_LOAD_ERROR;
1236 Info->BootState = RED;
1237 goto out;
1238 }
1239
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001240 if (AllowVerificationError && ResultShouldContinue (Result)) {
lijuangf2eb1fa2019-09-23 14:10:20 +08001241 DEBUG ((EFI_D_VERBOSE, "State: Unlocked, AvbSlotVerify returned "
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001242 "%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 Hongale3b53392017-04-27 17:32:47 -07001285
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001286 if (Info->NumLoadedImages < NumRequestedPartition) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001287 DEBUG ((EFI_D_ERROR, "ERROR: AvbSlotVerify slot data error: num of "
1288 "loaded partitions %d, requested %d\n",
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001289 Info->NumLoadedImages, NumRequestedPartition));
Zhen Kong3b3a0df2017-10-04 19:00:09 -07001290 Status = EFI_LOAD_ERROR;
1291 goto out;
1292 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001293
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001294 DEBUG ((EFI_D_VERBOSE, "Total loaded partition %d\n", Info->NumLoadedImages));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001295
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001296 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 Hongale3b53392017-04-27 17:32:47 -07001305
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001306 GUARD_OUT (GetImage (Info, &ImageBuffer, &ImageSize,
Monika Singh8bfc66a2019-03-08 12:18:17 +05301307 ( (!Info->MultiSlotBoot ||
1308 IsDynamicPartitionSupport ()) &&
Prakruthi Deepak Heragu70ad7f42020-02-03 16:33:59 -08001309 (Info->BootIntoRecovery &&
1310 !IsBuildUseRecoveryAsBoot ())) ?
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001311 "recovery" : "boot"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001312
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001313 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 Anantac3668a22020-01-13 18:20:02 -08001323 &VendorBootImageSize, "vendor_boot"));
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001324 }
1325
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001326 Status = CheckImageHeader (ImageBuffer, ImageHdrSize,
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001327 VendorBootImageBuffer, VendorBootImageSize,
1328 &ImageSizeActual, &PageSize,
1329 Info->BootIntoRecovery);
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001330 if (Status != EFI_SUCCESS) {
1331 DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status));
1332 goto out;
1333 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001334
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001335 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 Hongale3b53392017-04-27 17:32:47 -07001344
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001345 /* command line */
1346 GUARD_OUT (AppendVBCommonCmdLine (Info));
1347 GUARD_OUT (AppendVBCmdLine (Info, SlotData->cmdline));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001348
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001349 /* Set Rot & Boot State*/
1350 Data.Color = Info->BootState;
Zhen Kongbb3db752017-07-10 17:07:10 -07001351 Data. IsUnlocked = AllowVerificationError;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001352 Data.PublicKeyLength = UserData->PublicKeyLen;
1353 Data.PublicKey = UserData->PublicKey;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001354
Monika Singh93298782019-04-01 16:29:29 +05301355 GUARD_OUT (KeyMasterGetDateSupport (&DateSupport));
1356
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001357 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 Singh93298782019-04-01 16:29:29 +05301363 /* 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 */
lijuangf2eb1fa2019-09-23 14:10:20 +08001366 DEBUG ((EFI_D_VERBOSE, "DateSupport: %d\n", DateSupport));
Monika Singh93298782019-04-01 16:29:29 +05301367 if (DateSupport) {
Monika Singh93298782019-04-01 16:29:29 +05301368 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 Ananta07469562019-10-11 08:53:20 -07001385 Data.SystemSecurityLevel = (OSVersion & 0x7FF);
Monika Singh93298782019-04-01 16:29:29 +05301386 }
1387 }
1388 else {
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001389 Data.SystemSecurityLevel = (OSVersion & 0x7FF);
Monika Singh93298782019-04-01 16:29:29 +05301390 }
Raghavendra Rao Ananta07469562019-10-11 08:53:20 -07001391 Data.SystemVersion = (OSVersion & 0xFFFFF800) >> 11;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001392
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001393 GUARD_OUT (KeyMasterSetRotAndBootState (&Data));
Barani Muthukumaranaf2a7462019-03-20 15:40:57 -07001394 ComputeVbMetaDigest (SlotData, (CHAR8 *)&Digest);
1395 GUARD_OUT (SetVerifiedBootHash ((CONST CHAR8 *)&Digest, sizeof(Digest)));
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001396 DEBUG ((EFI_D_INFO, "VB2: Authenticate complete! boot state is: %a\n",
1397 VbSn[Info->BootState].name));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001398
1399out:
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001400 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 Chimata681e0f42018-01-19 17:47:56 -08001414 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 Shriram17f173d2017-10-24 22:11:07 -07001424 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001425
lijuangf2eb1fa2019-09-23 14:10:20 +08001426 DEBUG ((EFI_D_INFO, "VB2: boot state: %a(%d)\n",
1427 VbSn[Info->BootState].name, Info->BootState));
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001428 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001429}
1430
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001431STATIC EFI_STATUS
1432DisplayVerifiedBootScreen (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001433{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001434 EFI_STATUS Status = EFI_SUCCESS;
1435 CHAR8 FfbmStr[FFBM_MODE_BUF_SIZE] = {'\0'};
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001436
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001437 if (GetAVBVersion () < AVB_1) {
1438 return EFI_SUCCESS;
1439 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001440
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001441 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 Hongala2c4dd72017-04-27 14:33:18 -07001448
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001449 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 }
lijuang3d51d3b2018-07-03 14:29:59 +08001488
1489 /* dm-verity warning */
Jeevan Shriram70d98572018-09-26 15:01:49 -07001490 if ((GetAVBVersion () != AVB_2) &&
1491 !IsEnforcing () &&
lijuang3d51d3b2018-07-03 14:29:59 +08001492 !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 Shriram17f173d2017-10-24 22:11:07 -07001503 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001504}
1505
Zhen Kongbb3db752017-07-10 17:07:10 -07001506STATIC 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 sunfeer4987c692018-04-18 19:29:28 +05301519 CHAR8 *SystemPath = NULL;
1520 UINT32 SystemPathLen = 0;
Anmolpreet Kaurdeae0f12019-01-17 11:48:48 +05301521 BOOLEAN SecureDevice = FALSE;
Zhen Kongbb3db752017-07-10 17:07:10 -07001522 /*Load image*/
mohamed sunfeer4987c692018-04-18 19:29:28 +05301523 GUARD (VBAllocateCmdLine (Info));
Zhen Kongbb3db752017-07-10 17:07:10 -07001524 GUARD (VBCommonInit (Info));
1525 GUARD (LoadImageNoAuth (Info));
1526
Anmolpreet Kaurdeae0f12019-01-17 11:48:48 +05301527 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 Sunfeer604b2ed2018-10-30 13:36:02 +05301538 }
1539
Zhen Kongbb3db752017-07-10 17:07:10 -07001540 /* 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 Modem763cdd52018-11-01 14:49:55 +05301573 ImgHash = AllocateZeroPool (HashSize);
Zhen Kongbb3db752017-07-10 17:07:10 -07001574 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 sunfeer4987c692018-04-18 19:29:28 +05301598
Mohamed Sunfeer604b2ed2018-10-30 13:36:02 +05301599skip_verification:
mohamed sunfeer4987c692018-04-18 19:29:28 +05301600 if (!IsRootCmdLineUpdated (Info)) {
Venkata Narendra Kumar Guttad1cbfd22020-01-07 13:27:33 -08001601 SystemPathLen = GetSystemPath (&SystemPath, Info);
mohamed sunfeer4987c692018-04-18 19:29:28 +05301602 if (SystemPathLen == 0 ||
1603 SystemPath == NULL) {
1604 return EFI_LOAD_ERROR;
1605 }
1606 GUARD (AppendVBCmdLine (Info, SystemPath));
1607 }
Zhen Kongbb3db752017-07-10 17:07:10 -07001608 return Status;
1609}
1610
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001611EFI_STATUS
1612LoadImageAndAuth (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001613{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001614 EFI_STATUS Status = EFI_SUCCESS;
1615 BOOLEAN MdtpActive = FALSE;
1616 QCOM_MDTP_PROTOCOL *MdtpProtocol;
1617 UINT32 AVBVersion = NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001618
jianzhoub8a6fe02020-05-06 16:28:19 +08001619 WaitForFlashFinished ();
1620
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001621 if (Info == NULL) {
1622 DEBUG ((EFI_D_ERROR, "Invalid parameter Info\n"));
1623 return EFI_INVALID_PARAMETER;
1624 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001625
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001626 /* 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 Hongalc017e812017-04-26 16:15:27 -07001639
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001640 GUARD (FindBootableSlot (&CurrentSlot));
1641 if (IsSuffixEmpty (&CurrentSlot)) {
1642 DEBUG ((EFI_D_ERROR, "No bootable slot\n"));
1643 return EFI_LOAD_ERROR;
1644 }
Shivaprasad Hongalc017e812017-04-26 16:15:27 -07001645
Mayank Grover1c051582019-02-26 14:42:27 +05301646 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 Shriram17f173d2017-10-24 22:11:07 -07001654 StrLen (L"boot")));
Mayank Grover1c051582019-02-26 14:42:27 +05301655 }
1656
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001657 GUARD (StrnCatS (Info->Pname, ARRAY_SIZE (Info->Pname), CurrentSlot.Suffix,
1658 StrLen (CurrentSlot.Suffix)));
1659 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001660
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001661 DEBUG ((EFI_D_VERBOSE, "MultiSlot %a, partition name %s\n",
1662 BooleanString[Info->MultiSlotBoot].name, Info->Pname));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001663
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001664 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 Hongala2c4dd72017-04-27 14:33:18 -07001675
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001676 AVBVersion = GetAVBVersion ();
1677 DEBUG ((EFI_D_VERBOSE, "AVB version %d\n", AVBVersion));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001678
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001679 /* 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 Kongbb3db752017-07-10 17:07:10 -07001690 case AVB_LE:
1691 Status = LoadImageAndAuthForLE (Info);
1692 break;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001693 default:
1694 DEBUG ((EFI_D_ERROR, "Unsupported AVB version %d\n", AVBVersion));
1695 Status = EFI_UNSUPPORTED;
1696 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001697
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001698 // 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 Hongala2c4dd72017-04-27 14:33:18 -07001710
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001711 if (IsUnlocked () && Status != EFI_SUCCESS) {
1712 DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status));
1713 return Status;
1714 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001715
Zhen Kongbb3db752017-07-10 17:07:10 -07001716 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 Shriram17f173d2017-10-24 22:11:07 -07001724 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001725 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001726}
1727
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001728VOID
1729FreeVerifiedBootResource (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001730{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001731 DEBUG ((EFI_D_VERBOSE, "FreeVerifiedBootResource\n"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001732
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001733 if (Info == NULL) {
1734 return;
1735 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001736
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001737 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 Hongale3b53392017-04-27 17:32:47 -07001746
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001747 AvbSlotVerifyData *SlotData = VBData->SlotData;
1748 if (SlotData != NULL) {
1749 avb_slot_verify_data_free (SlotData);
1750 }
1751 avb_free (VBData);
1752 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001753
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001754 if (Info->VBCmdLine != NULL) {
1755 FreePool (Info->VBCmdLine);
1756 }
1757 return;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001758}
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001759
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001760EFI_STATUS
1761GetCertFingerPrint (UINT8 *FingerPrint,
1762 UINTN FingerPrintLen,
1763 UINTN *FingerPrintLenOut)
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001764{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001765 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001766
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001767 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 Hongal7fd6a522017-05-10 13:56:28 -07001772
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001773 if (GetAVBVersion () == AVB_1) {
1774 QCOM_VERIFIEDBOOT_PROTOCOL *VbIntf = NULL;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001775
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001776 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 Hongal7fd6a522017-05-10 13:56:28 -07001782
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001783 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 Hongal7fd6a522017-05-10 13:56:28 -07001788
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001789 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 Hongal7fd6a522017-05-10 13:56:28 -07001800
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001801 GUARD (GetUserKey (&UserKeyBuffer, &UserKeyLength));
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001802
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001803 avb_sha256_init (&UserKeyCtx);
1804 avb_sha256_update (&UserKeyCtx, (UINT8 *)UserKeyBuffer, UserKeyLength);
1805 UserKeyDigest = (CHAR8 *)avb_sha256_final (&UserKeyCtx);
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001806
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001807 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 Hongal7fd6a522017-05-10 13:56:28 -07001813
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001814 return Status;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001815}