blob: 2504feec9c0a6436714b4e30ad12b8880eda3f3b [file] [log] [blame]
Anmolpreet Kaurdeae0f12019-01-17 11:48:48 +05301/* Copyright (c) 2017-2019, 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"
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070031#include "KeymasterClient.h"
32#include "libavb/libavb.h"
Shivaprasad Hongalf1fb0472017-05-23 20:05:16 -070033#include <Library/MenuKeysDetection.h>
Jeevan Shriram17f173d2017-10-24 22:11:07 -070034#include <Library/VerifiedBootMenu.h>
Zhen Kongbb3db752017-07-10 17:07:10 -070035#include <Library/LEOEMCertificate.h>
lijuangf0149ab2018-09-05 20:35:32 +080036#include <Library/HypervisorMvCalls.h>
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070037
38STATIC CONST CHAR8 *VerityMode = " androidboot.veritymode=";
39STATIC CONST CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
40STATIC CONST CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
Mukesh Ojha71be2c82018-02-02 19:13:10 +053041STATIC CONST CHAR8 *DmVerityCmd = " root=/dev/dm-0 dm=\"system none ro,0 1 "
42 "android-verity";
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070043STATIC CONST CHAR8 *Space = " ";
Jeevan Shriram17f173d2017-10-24 22:11:07 -070044
Monika Singh43598872018-10-15 12:04:02 +053045#define MAX_NUM_REQ_PARTITION 8
46
47static CHAR8 *avb_verify_partition_name[] = {
48 "boot",
49 "dtbo",
50 "vbmeta",
AnilKumar Chimata3597bc12018-07-05 15:53:25 +053051 "recovery",
52 "vm-linux"
Monika Singh43598872018-10-15 12:04:02 +053053};
54
Jeevan Shriram17f173d2017-10-24 22:11:07 -070055STATIC struct verified_boot_verity_mode VbVm[] = {
56 {FALSE, "logging"},
57 {TRUE, "enforcing"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070058};
59
Jeevan Shriram17f173d2017-10-24 22:11:07 -070060STATIC struct verified_boot_state_name VbSn[] = {
61 {GREEN, "green"},
62 {ORANGE, "orange"},
63 {YELLOW, "yellow"},
64 {RED, "red"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070065};
66
Jeevan Shriram17f173d2017-10-24 22:11:07 -070067struct boolean_string {
68 BOOLEAN value;
69 CHAR8 *name;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070070};
71
Jeevan Shriram17f173d2017-10-24 22:11:07 -070072STATIC struct boolean_string BooleanString[] = {
73 {FALSE, "false"},
74 {TRUE, "true"}
75};
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070076
77typedef struct {
Jeevan Shriram17f173d2017-10-24 22:11:07 -070078 AvbOps *Ops;
79 AvbSlotVerifyData *SlotData;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070080} VB2Data;
81
Jeevan Shriram17f173d2017-10-24 22:11:07 -070082UINT32
83GetAVBVersion ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070084{
Zhen Kongbb3db752017-07-10 17:07:10 -070085#if VERIFIED_BOOT_LE
86 return AVB_LE;
87#elif VERIFIED_BOOT_2
88 return AVB_2;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070089#elif VERIFIED_BOOT
Zhen Kongbb3db752017-07-10 17:07:10 -070090 return AVB_1;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070091#else
Zhen Kongbb3db752017-07-10 17:07:10 -070092 return NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070093#endif
94}
95
Jeevan Shriram17f173d2017-10-24 22:11:07 -070096BOOLEAN
97VerifiedBootEnbled ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070098{
Jeevan Shriram17f173d2017-10-24 22:11:07 -070099 return (GetAVBVersion () > NO_AVB);
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700100}
101
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700102STATIC EFI_STATUS
103AppendVBCmdLine (BootInfo *Info, CONST CHAR8 *Src)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700104{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700105 EFI_STATUS Status = EFI_SUCCESS;
106 INT32 SrcLen = AsciiStrLen (Src);
107 CHAR8 *Dst = Info->VBCmdLine + Info->VBCmdLineFilledLen;
108 INT32 DstLen = Info->VBCmdLineLen - Info->VBCmdLineFilledLen;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700109
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700110 GUARD (AsciiStrnCatS (Dst, DstLen, Src, SrcLen));
111 Info->VBCmdLineFilledLen += SrcLen;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700112
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700113 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700114}
115
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700116STATIC EFI_STATUS
117AppendVBCommonCmdLine (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700118{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700119 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700120
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700121 if (Info->VbIntf->Revision >= QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) {
122 GUARD (AppendVBCmdLine (Info, VerifiedState));
123 GUARD (AppendVBCmdLine (Info, VbSn[Info->BootState].name));
124 }
125 GUARD (AppendVBCmdLine (Info, KeymasterLoadState));
126 GUARD (AppendVBCmdLine (Info, Space));
127 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700128}
129
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700130STATIC EFI_STATUS
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700131NoAVBLoadReqImage (BootInfo *Info, VOID **DtboImage,
132 UINT32 *DtboSize, CHAR16 *Pname, CHAR16 *RequestedPartition)
Runmin Wang261d2bf2017-11-03 11:40:40 -0700133{
134 EFI_STATUS Status = EFI_SUCCESS;
135 Slot CurrentSlot;
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530136 CHAR8 *AsciiPname = NULL;
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530137 UINT64 PartSize = 0;
138 AvbIOResult AvbStatus;
139 AvbOpsUserData *UserData = NULL;
140 AvbOps *Ops = NULL;
Runmin Wang261d2bf2017-11-03 11:40:40 -0700141
Runmin Wang261d2bf2017-11-03 11:40:40 -0700142 GUARD ( StrnCpyS (Pname,
143 (UINTN)MAX_GPT_NAME_SIZE,
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700144 (CONST CHAR16 *)RequestedPartition,
145 StrLen (RequestedPartition)));
Runmin Wang261d2bf2017-11-03 11:40:40 -0700146
147 if (Info->MultiSlotBoot) {
148 CurrentSlot = GetCurrentSlotSuffix ();
149 GUARD ( StrnCatS (Pname, MAX_GPT_NAME_SIZE,
150 CurrentSlot.Suffix, StrLen (CurrentSlot.Suffix)));
151 }
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530152 if (GetPartitionIndex (Pname) == INVALID_PTN) {
153 Status = EFI_NO_MEDIA;
154 goto out;
155 }
156
157 /* Get Partition size & compare with MAX supported size
158 * If Partition size > DTBO_MAX_SIZE_ALLOWED return
159 * Allocate Partition size memory otherwise
160 */
161 UserData = avb_calloc (sizeof (AvbOpsUserData));
162 if (UserData == NULL) {
163 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOpsUserData\n"));
164 Status = EFI_OUT_OF_RESOURCES;
165 goto out;
166 }
167 Ops = AvbOpsNew (UserData);
168 if (Ops == NULL) {
169 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOps\n"));
170 Status = EFI_OUT_OF_RESOURCES;
171 goto out;
172 }
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530173 AsciiPname = avb_calloc (MAX_GPT_NAME_SIZE);
174 if (AsciiPname == NULL) {
175 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AsciiPname\n"));
176 Status = EFI_OUT_OF_RESOURCES;
177 goto out;
178 }
179 UnicodeStrToAsciiStr (Pname, AsciiPname);
180
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530181 AvbStatus = Ops->get_size_of_partition (Ops,
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530182 AsciiPname,
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530183 &PartSize);
184 if (AvbStatus != AVB_IO_RESULT_OK ||
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700185 PartSize == 0) {
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530186 DEBUG ((EFI_D_ERROR, "VB: Failed to get partition size "
187 "(or) DTBO size is too big: 0x%x\n", PartSize));
188 Status = EFI_OUT_OF_RESOURCES;
189 goto out;
190 }
191
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700192 if ((AsciiStrStr (AsciiPname, "dtbo")) &&
193 (PartSize > DTBO_MAX_SIZE_ALLOWED)) {
194 DEBUG ((EFI_D_ERROR, "DTBO size is too big: 0x%x\n", PartSize));
195 Status = EFI_OUT_OF_RESOURCES;
196 goto out;
197 }
198
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530199 DEBUG ((EFI_D_VERBOSE, "VB: Trying to allocate memory "
200 "for DTBO: 0x%x\n", PartSize));
201 *DtboSize = (UINT32) PartSize;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530202 *DtboImage = AllocateZeroPool (PartSize);
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530203
204 if (*DtboImage == NULL) {
205 DEBUG ((EFI_D_ERROR, "VB: Unable to allocate memory for DTBO\n"));
206 Status = EFI_OUT_OF_RESOURCES;
207 goto out;
208 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700209 Status = LoadImageFromPartition (*DtboImage, DtboSize, Pname);
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530210
211out:
212 if (Ops != NULL) {
213 AvbOpsFree (Ops);
214 }
215 if (UserData != NULL) {
216 avb_free (UserData);
217 }
Bhanuprakash Modem87f2c3e2018-07-09 19:08:13 +0530218 if (AsciiPname != NULL) {
219 avb_free (AsciiPname);
220 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700221 return Status;
222}
223
224STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700225VBCommonInit (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700226{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700227 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700228
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700229 Info->BootState = RED;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700230
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700231 Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL,
232 (VOID **)&(Info->VbIntf));
233 if (Status != EFI_SUCCESS) {
234 DEBUG ((EFI_D_ERROR, "Unable to locate VB protocol: %r\n", Status));
Zhen Kongdb33a732017-07-10 12:23:00 -0700235 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700236 }
237
238 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700239}
240
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700241/*
242 * Ensure Info->Pname is already updated before this function is called.
243 * If Command line already has "root=", return TRUE, else FALSE.
244 */
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700245STATIC EFI_STATUS
246VBAllocateCmdLine (BootInfo *Info)
Zhen Kongdb33a732017-07-10 12:23:00 -0700247{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700248 EFI_STATUS Status = EFI_SUCCESS;
Zhen Kongdb33a732017-07-10 12:23:00 -0700249
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700250 /* allocate VB command line*/
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530251 Info->VBCmdLine = AllocateZeroPool (DTB_PAD_SIZE);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700252 if (Info->VBCmdLine == NULL) {
253 DEBUG ((EFI_D_ERROR, "VB CmdLine allocation failed!\n"));
254 Status = EFI_OUT_OF_RESOURCES;
Zhen Kongdb33a732017-07-10 12:23:00 -0700255 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700256 }
257 Info->VBCmdLineLen = DTB_PAD_SIZE;
258 Info->VBCmdLineFilledLen = 0;
259 Info->VBCmdLine[Info->VBCmdLineFilledLen] = '\0';
260
261 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700262}
263
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700264STATIC
265BOOLEAN
266IsRootCmdLineUpdated (BootInfo *Info)
267{
268 CHAR8* ImageCmdLine = NULL;
269
270 ImageCmdLine =
271 (CHAR8*) & (((boot_img_hdr*) (Info->Images[0].ImageBuffer))->cmdline[0]);
272
273 ImageCmdLine[BOOT_ARGS_SIZE - 1] = '\0';
274 if (AsciiStrStr (ImageCmdLine, "root=")) {
275 return TRUE;
276 } else {
277 return FALSE;
278 }
279}
280
281
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700282STATIC EFI_STATUS
283LoadImageNoAuth (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700284{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700285 EFI_STATUS Status = EFI_SUCCESS;
Runmin Wang261d2bf2017-11-03 11:40:40 -0700286 CHAR16 Pname[MAX_GPT_NAME_SIZE];
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700287
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700288 if (Info->Images[0].ImageBuffer != NULL && Info->Images[0].ImageSize > 0) {
Jeevan Shrirame162e5e2018-04-12 15:59:52 -0700289 /* fastboot boot option, boot image is already loaded, check for dtbo */
290 goto load_dtbo;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700291 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700292
lijuang06904a32018-12-10 16:54:32 +0800293 Status = LoadImage (Info->BootIntoRecovery,
294 Info->Pname,
295 (VOID **)&(Info->Images[0].ImageBuffer),
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700296 (UINT32 *)&(Info->Images[0].ImageSize));
297 if (Status != EFI_SUCCESS) {
298 DEBUG ((EFI_D_ERROR, "ERROR: Failed to load image from partition: %r\n",
299 Status));
300 return EFI_LOAD_ERROR;
301 }
302 Info->NumLoadedImages = 1;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530303 Info->Images[0].Name = AllocateZeroPool (StrLen (Info->Pname) + 1);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700304 UnicodeStrToAsciiStr (Info->Pname, Info->Images[0].Name);
Runmin Wang261d2bf2017-11-03 11:40:40 -0700305
Jeevan Shrirame162e5e2018-04-12 15:59:52 -0700306
307load_dtbo:
Runmin Wang261d2bf2017-11-03 11:40:40 -0700308 /*load dt overlay when avb is disabled*/
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700309 Status = NoAVBLoadReqImage (Info, (VOID **)&(Info->Images[1].ImageBuffer),
310 (UINT32 *)&(Info->Images[1].ImageSize), Pname, L"dtbo");
Runmin Wang261d2bf2017-11-03 11:40:40 -0700311 if (Status == EFI_NO_MEDIA) {
312 DEBUG ((EFI_D_ERROR, "No dtbo partition is found, Skip dtbo\n"));
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530313 if (Info->Images[1].ImageBuffer != NULL) {
314 FreePool (Info->Images[1].ImageBuffer);
315 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700316 return EFI_SUCCESS;
317 }
318 else if (Status != EFI_SUCCESS) {
319 DEBUG ((EFI_D_ERROR,
320 "ERROR: Failed to load dtbo from partition: %r\n", Status));
Bhanuprakash Modemee92f012018-06-21 17:27:14 +0530321 if (Info->Images[1].ImageBuffer != NULL) {
322 FreePool (Info->Images[1].ImageBuffer);
323 }
Runmin Wang261d2bf2017-11-03 11:40:40 -0700324 return EFI_LOAD_ERROR;
325 }
326 Info-> NumLoadedImages = 2;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530327 Info-> Images[1].Name = AllocateZeroPool (StrLen (Pname) + 1);
Runmin Wang261d2bf2017-11-03 11:40:40 -0700328 UnicodeStrToAsciiStr (Pname, Info->Images[1].Name);
329
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700330 /* Load vm-linux if Verified boot is disabled */
331 if (IsVmEnabled ()) {
332 Status = NoAVBLoadReqImage (Info, (VOID **)&(Info->Images[2].ImageBuffer),
333 (UINT32 *)&(Info->Images[2].ImageSize), Pname,
334 L"vm-linux");
335 if (Status == EFI_NO_MEDIA) {
336 DEBUG ((EFI_D_ERROR, "No vm-linux partition is found, Skip..\n"));
337 if (Info->Images[2].ImageBuffer != NULL) {
338 FreePool (Info->Images[2].ImageBuffer);
339 }
340
341 return EFI_SUCCESS;
342 } else if (Status != EFI_SUCCESS) {
343 DEBUG ((EFI_D_ERROR,
344 "ERROR: Failed to load vm-linux from partition: %r\n", Status));
345 if (Info->Images[2].ImageBuffer != NULL) {
346 FreePool (Info->Images[2].ImageBuffer);
347 }
348
349 return EFI_LOAD_ERROR;
350 }
351
352 Info-> NumLoadedImages = 3;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530353 Info-> Images[2].Name = AllocateZeroPool (StrLen (Pname) + 1);
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700354 UnicodeStrToAsciiStr (Pname, Info->Images[2].Name);
355 }
356
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700357 return Status;
358}
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700359
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700360STATIC EFI_STATUS
361LoadImageNoAuthWrapper (BootInfo *Info)
362{
363 EFI_STATUS Status = EFI_SUCCESS;
364 CHAR8 *SystemPath = NULL;
365 UINT32 SystemPathLen = 0;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700366
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700367 GUARD (VBAllocateCmdLine (Info));
368 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700369
Mayank Grover1c051582019-02-26 14:42:27 +0530370 if (!IsDynamicPartitionSupport () &&
371 !IsRootCmdLineUpdated (Info)) {
lijuangf0149ab2018-09-05 20:35:32 +0800372 SystemPathLen = GetSystemPath (&SystemPath,
373 Info->MultiSlotBoot,
374 Info->BootIntoRecovery,
375 (CHAR16 *)L"system",
376 (CHAR8 *)"root");
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700377 if (SystemPathLen == 0 || SystemPath == NULL) {
378 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
379 return EFI_LOAD_ERROR;
Zhen Kongdb33a732017-07-10 12:23:00 -0700380 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700381 GUARD (AppendVBCmdLine (Info, SystemPath));
382 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700383
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700384 return Status;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700385}
386
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700387STATIC EFI_STATUS
388LoadImageAndAuthVB1 (BootInfo *Info)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700389{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700390 EFI_STATUS Status = EFI_SUCCESS;
391 CHAR8 StrPnameAscii[MAX_GPT_NAME_SIZE]; /* partition name starting with
392 / and no suffix */
393 CHAR8 PnameAscii[MAX_GPT_NAME_SIZE];
394 CHAR8 *SystemPath = NULL;
395 UINT32 SystemPathLen = 0;
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530396 CHAR8 *Temp = NULL;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700397
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700398 GUARD (VBCommonInit (Info));
399 GUARD (VBAllocateCmdLine (Info));
400 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700401
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700402 device_info_vb_t DevInfo_vb;
403 DevInfo_vb.is_unlocked = IsUnlocked ();
404 DevInfo_vb.is_unlock_critical = IsUnlockCritical ();
405 Status = Info->VbIntf->VBDeviceInit (Info->VbIntf,
406 (device_info_vb_t *)&DevInfo_vb);
407 if (Status != EFI_SUCCESS) {
408 DEBUG ((EFI_D_ERROR, "Error during VBDeviceInit: %r\n", Status));
409 return Status;
410 }
411
412 AsciiStrnCpyS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), "/",
413 AsciiStrLen ("/"));
414 UnicodeStrToAsciiStr (Info->Pname, PnameAscii);
415 if (Info->MultiSlotBoot) {
416 AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii,
417 AsciiStrLen (PnameAscii) - (MAX_SLOT_SUFFIX_SZ - 1));
418 } else {
419 AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii,
420 AsciiStrLen (PnameAscii));
421 }
422
423 Status =
424 Info->VbIntf->VBVerifyImage (Info->VbIntf, (UINT8 *)StrPnameAscii,
425 (UINT8 *)Info->Images[0].ImageBuffer,
426 Info->Images[0].ImageSize, &Info->BootState);
427 if (Status != EFI_SUCCESS || Info->BootState == BOOT_STATE_MAX) {
428 DEBUG ((EFI_D_ERROR, "VBVerifyImage failed with: %r\n", Status));
429 return Status;
430 }
431
432 Status = Info->VbIntf->VBSendRot (Info->VbIntf);
433 if (Status != EFI_SUCCESS) {
434 DEBUG ((EFI_D_ERROR, "Error sending Rot : %r\n", Status));
435 return Status;
436 }
437
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700438 if (!IsRootCmdLineUpdated (Info)) {
lijuangf0149ab2018-09-05 20:35:32 +0800439 SystemPathLen = GetSystemPath (&SystemPath,
440 Info->MultiSlotBoot,
441 Info->BootIntoRecovery,
442 (CHAR16 *)L"system",
443 (CHAR8 *)"root");
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700444 if (SystemPathLen == 0 || SystemPath == NULL) {
445 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
446 return EFI_LOAD_ERROR;
447 }
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530448 GUARD (AppendVBCmdLine (Info, DmVerityCmd));
449 /* Copy only the portion after "root=" in the SystemPath */
450 Temp = AsciiStrStr (SystemPath, "root=");
451 if (Temp) {
452 CopyMem (Temp, SystemPath + AsciiStrLen ("root=") + 1,
453 SystemPathLen - AsciiStrLen ("root=") - 1);
454 SystemPath[SystemPathLen - AsciiStrLen ("root=")] = '\0';
455 }
456
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700457 GUARD (AppendVBCmdLine (Info, SystemPath));
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530458 GUARD (AppendVBCmdLine (Info, "\""));
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700459 }
460 GUARD (AppendVBCommonCmdLine (Info));
461 GUARD (AppendVBCmdLine (Info, VerityMode));
462 GUARD (AppendVBCmdLine (Info, VbVm[IsEnforcing ()].name));
463
464 Info->VBData = NULL;
465 return Status;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700466}
467
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700468STATIC BOOLEAN
469ResultShouldContinue (AvbSlotVerifyResult Result)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700470{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700471 switch (Result) {
472 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
473 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
474 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
475 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
476 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
477 return FALSE;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700478
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700479 case AVB_SLOT_VERIFY_RESULT_OK:
480 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
481 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
482 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
483 return TRUE;
484 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700485
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700486 return FALSE;
487}
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700488
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700489STATIC EFI_STATUS
Zhen Kongbb3db752017-07-10 17:07:10 -0700490LEGetImageHash (QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
491 VB_HASH HashAlgorithm,
492 UINT8 *Img, UINTN ImgSize,
493 UINT8 *ImgHash, UINTN HashSize)
494{
495 EFI_STATUS Status = EFI_FAILURE;
496 EFI_GUID *HashAlgorithmGuid;
497 UINTN DigestSize = 0;
498 EFI_HASH2_OUTPUT Hash2Output;
499 EFI_HASH2_PROTOCOL *pEfiHash2Protocol = NULL;
500
501 if (pEfiQcomASN1X509Protocol == NULL ||
502 Img == NULL ||
503 ImgHash == NULL) {
504 DEBUG ((EFI_D_ERROR,
505 "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n"));
506 return EFI_INVALID_PARAMETER;
507 }
508
509 switch (HashAlgorithm) {
510 case VB_SHA256:
511 HashAlgorithmGuid = &gEfiHashAlgorithmSha256Guid;
512 break;
513 default:
514 DEBUG ((EFI_D_ERROR,
515 "VB: LEGetImageHash: not supported algorithm:%d\n", HashAlgorithm));
516 Status = EFI_UNSUPPORTED;
517 goto exit;
518 }
519
520 Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid,
521 NULL, (VOID **)&pEfiHash2Protocol);
522 if (Status != EFI_SUCCESS) {
523 DEBUG ((EFI_D_ERROR,
524 "VB:LEGetImageHash: LocateProtocol unsuccessful!Status: %r\n", Status));
525 goto exit;
526 }
527
528 Status = pEfiHash2Protocol->GetHashSize (pEfiHash2Protocol,
529 HashAlgorithmGuid, &DigestSize);
530 if (Status != EFI_SUCCESS) {
531 DEBUG ((EFI_D_ERROR,
532 "VB: LEGetImageHash: GetHashSize unsuccessful! Status: %r\n", Status));
533 goto exit;
534 }
535 if (HashSize != DigestSize) {
536 DEBUG ((EFI_D_ERROR,
537 "VB: LEGetImageHash: Invalid size! HashSize: %d, DigestSize: %d\n"
538 , HashSize, DigestSize));
539 Status = EFI_FAILURE;
540 goto exit;
541 }
542 Status = pEfiHash2Protocol->HashInit (pEfiHash2Protocol, HashAlgorithmGuid);
543 if (Status != EFI_SUCCESS) {
544 DEBUG ((EFI_D_ERROR,
545 "VB: LEGetImageHash: HashInit unsuccessful! Status: %r\n", Status));
546 goto exit;
547 }
548 Status = pEfiHash2Protocol->HashUpdate (pEfiHash2Protocol, Img, ImgSize);
549 if (EFI_SUCCESS != Status) {
550
551 DEBUG ((EFI_D_ERROR,
552 "VB: LEGetImageHash: HashUpdate unsuccessful(Img)!Status: %r\n"
553 , Status));
554 goto exit;
555 }
556 Status = pEfiHash2Protocol->HashFinal (pEfiHash2Protocol, &Hash2Output);
557 if (EFI_SUCCESS != Status) {
558
559 DEBUG ((EFI_D_ERROR,
560 "VB: LEGetImageHash: HashFinal unsuccessful! Status: %r\n", Status));
561 goto exit;
562 }
563 gBS->CopyMem ((VOID *)ImgHash, (VOID *)&Hash2Output, DigestSize);
564 Status = EFI_SUCCESS;
565
566exit:
567 return Status;
568}
569
570STATIC EFI_STATUS LEGetRSAPublicKeyInfoFromCertificate (
571 QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
572 CERTIFICATE *Certificate,
573 secasn1_data_type *Modulus,
574 secasn1_data_type *PublicExp,
575 UINT32 *PaddingType)
576{
577 EFI_STATUS Status = EFI_FAILURE;
578 RSA RsaKey = {NULL};
579
580 if (pEfiQcomASN1X509Protocol == NULL ||
581 Certificate == NULL ||
582 Modulus == NULL ||
583 PublicExp == NULL ||
584 PaddingType == NULL) {
585 DEBUG ((EFI_D_ERROR,
586 "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n"));
587 return EFI_INVALID_PARAMETER;
588 }
589
590 Status = pEfiQcomASN1X509Protocol->ASN1X509GetRSAFromCert
591 (pEfiQcomASN1X509Protocol, Certificate, &RsaKey);
592 if (Status != EFI_SUCCESS) {
593 DEBUG ((EFI_D_ERROR,
594 "VB: ASN1X509GetRSAFromCert unsuccessful! Status : %r\n", Status));
595 goto exit;
596 }
597 Status = pEfiQcomASN1X509Protocol->ASN1X509GetKeymaterial
598 (pEfiQcomASN1X509Protocol, &RsaKey, Modulus, PublicExp);
599 if (Status != EFI_SUCCESS) {
600 DEBUG ((EFI_D_ERROR,
601 "VB: ASN1X509GetKeymaterial unsuccessful! Status: %r\n", Status));
602 goto exit;
603 }
604 *PaddingType = CE_RSA_PAD_PKCS1_V1_5_SIG;
605exit:
606 return Status;
607}
608STATIC EFI_STATUS LEVerifyHashWithRSASignature (
609 UINT8 *ImgHash,
610 VB_HASH HashAlgorithm,
611 secasn1_data_type *Modulus,
612 secasn1_data_type *PublicExp,
613 UINT32 PaddingType,
614 CONST UINT8 *SignaturePtr,
615 UINT32 SignatureLen)
616{
617 EFI_STATUS Status = EFI_FAILURE;
618 CE_RSA_KEY Key = {0};
619 BigInt ModulusBi;
620 BigInt PublicExpBi;
621 INT32 HashIdx;
622 INT32 HashLen;
623 VOID *PaddingInfo = NULL;
624 QcomSecRsaProtocol *pEfiQcomSecRSAProtocol = NULL;
625 SetMem (&Key, sizeof (CE_RSA_KEY), 0);
626
627 if (ImgHash == NULL ||
628 Modulus == NULL ||
629 PublicExp == NULL ||
630 SignaturePtr == NULL) {
631 DEBUG ((EFI_D_ERROR, "LEVerifyHashWithRSASignature:Invalid pointer\n"));
632 return EFI_INVALID_PARAMETER;
633 }
634
635 switch (HashAlgorithm) {
636 case VB_SHA256:
637 HashIdx = CE_HASH_IDX_SHA256;
638 HashLen = VB_SHA256_SIZE;
639 break;
640 default:
641 DEBUG ((EFI_D_ERROR,
642 "VB: LEVerifySignature: Hash algorithm not supported\n"));
643 Status = EFI_UNSUPPORTED;
644 goto exit;
645 }
646
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530647 Key.N = AllocateZeroPool (sizeof (S_BIGINT));
Zhen Kongbb3db752017-07-10 17:07:10 -0700648 if (Key.N == NULL) {
649 DEBUG ((EFI_D_ERROR,
650 "VB: LEVerifySignature: mem allocation err for Key.N\n"));
651 goto exit;
652 }
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +0530653 Key.e = AllocateZeroPool (sizeof (S_BIGINT));
Zhen Kongbb3db752017-07-10 17:07:10 -0700654 if (Key.e == NULL) {
655 DEBUG ((EFI_D_ERROR,
656 "VB: LEVerifySignature: mem allocation err for Key.e\n"));
657 goto exit;
658 }
659 Status = gBS->LocateProtocol (&gEfiQcomSecRSAProtocolGuid,
660 NULL, (VOID **) &pEfiQcomSecRSAProtocol);
661 if ( Status != EFI_SUCCESS) {
662 DEBUG ((EFI_D_ERROR,
663 "VB: LEVerifySignature: LocateProtocol failed, Status: %r\n", Status));
664 goto exit;
665 }
666
667 Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin (
668 pEfiQcomSecRSAProtocol, Modulus->data, Modulus->Len, &ModulusBi);
669 if ( Status != EFI_SUCCESS) {
670 DEBUG ((EFI_D_ERROR,
671 "VB: LEVerifySignature: SecRSABigIntReadBin for Modulus failed!"
672 "Status: %r\n", Status));
673 goto exit;
674 }
675 Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin (
676 pEfiQcomSecRSAProtocol, PublicExp->data, PublicExp->Len, &PublicExpBi);
677 if ( Status != EFI_SUCCESS) {
678 DEBUG ((EFI_D_ERROR, "VB: LEVerifySignature: SecRSABigIntReadBin for"
679 " Modulus failed! Status: %r\n", Status));
680 goto exit;
681 }
682
683 Key.N->Bi = ModulusBi;
684 Key.e->Bi = PublicExpBi;
685 Key.e->Sign = S_BIGINT_POS;
686 Key.Type = CE_RSA_KEY_PUBLIC;
687
688 Status = pEfiQcomSecRSAProtocol->SecRSAVerifySig (pEfiQcomSecRSAProtocol,
689 &Key, PaddingType,
690 PaddingInfo, HashIdx,
691 ImgHash, HashLen, (UINT8*)SignaturePtr, SignatureLen);
692
693 if (Status != EFI_SUCCESS) {
694 DEBUG ((EFI_D_ERROR,
695 "VB: LEVerifySignature: SecRSAVerifySig failed! Status: %r\n", Status));
696 goto exit;
697 }
698
699 DEBUG ((EFI_D_VERBOSE, "VB: LEVerifySignature: SecRSAVerifySig success!"
700 " Status: %r\n", Status));
701
702 Status = EFI_SUCCESS;
703exit:
704 if (Key.N != NULL) {
705 FreePool (Key.N);
706 }
707 if (Key.e != NULL) {
708 FreePool (Key.e);
709 }
710 return Status;
711}
712
713STATIC EFI_STATUS LEVerifyHashWithSignature (
714 QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
715 UINT8 *ImgHash, VB_HASH HashAlgorithm,
716 CERTIFICATE *Certificate,
717 CONST UINT8 *SignaturePtr,
718 UINT32 SignatureLen)
719{
720 EFI_STATUS Status = EFI_FAILURE;
721 secasn1_data_type Modulus = {NULL};
722 secasn1_data_type PublicExp = {NULL};
723 UINT32 PaddingType = 0;
724
725 if (pEfiQcomASN1X509Protocol == NULL ||
726 ImgHash == NULL ||
727 Certificate == NULL ||
728 SignaturePtr == NULL) {
729 DEBUG ((EFI_D_ERROR, "LEVerifyHashWithSignature: Invalid pointer\n"));
730 return EFI_INVALID_PARAMETER;
731 }
732
733 /* TODO: get subject publick key info from certificate, implement new
734 algorithm in XBL*/
735 /* XBL implemented by default sha256 and rsaEncryption with
736 PKCS1_V1_5 padding*/
737
738 Status = LEGetRSAPublicKeyInfoFromCertificate (pEfiQcomASN1X509Protocol,
739 Certificate, &Modulus, &PublicExp, &PaddingType);
740 if (Status != EFI_SUCCESS) {
741 DEBUG ((EFI_D_ERROR, "VB: LEGetRSAPublicKeyInfoFromCertificate "
742 "unsuccessful! Status: %r\n", Status));
743 goto exit;
744 }
745
746 Status = LEVerifyHashWithRSASignature (ImgHash, HashAlgorithm,
747 &Modulus, &PublicExp, PaddingType,
748 SignaturePtr, SignatureLen);
749 if (Status != EFI_SUCCESS) {
750 DEBUG ((EFI_D_ERROR, "VB: LEVerifyHashWithSignature unsuccessful! "
751 "Status: %r\n", Status));
752 goto exit;
753 }
754 Status = EFI_SUCCESS;
755exit:
756 return Status;
757}
758
Monika Singh43598872018-10-15 12:04:02 +0530759static BOOLEAN GetHeaderVersion (AvbSlotVerifyData *SlotData)
760{
761 BOOLEAN HeaderVersion = 0;
762 UINTN LoadedIndex = 0;
763 for (LoadedIndex = 0; LoadedIndex < SlotData->num_loaded_partitions;
764 LoadedIndex++) {
765 if (avb_strcmp (SlotData->loaded_partitions[LoadedIndex].partition_name,
766 "recovery") == 0 )
767 return ( (boot_img_hdr *)
768 (SlotData->loaded_partitions[LoadedIndex].data))->header_version;
769 }
770 return HeaderVersion;
771}
772
773static VOID AddRequestedPartition (CHAR8 **RequestedPartititon, UINT32 Index)
774{
775 UINTN PartIndex = 0;
776 for (PartIndex = 0; PartIndex < MAX_NUM_REQ_PARTITION; PartIndex++) {
777 if (RequestedPartititon[PartIndex] == NULL) {
778 RequestedPartititon[PartIndex] =
779 avb_verify_partition_name[Index];
780 break;
781 }
782 }
783}
Zhen Kongbb3db752017-07-10 17:07:10 -0700784
785STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700786LoadImageAndAuthVB2 (BootInfo *Info)
787{
788 EFI_STATUS Status = EFI_SUCCESS;
789 AvbSlotVerifyResult Result;
790 AvbSlotVerifyData *SlotData = NULL;
791 VB2Data *VBData = NULL;
792 AvbOpsUserData *UserData = NULL;
793 AvbOps *Ops = NULL;
794 CHAR8 PnameAscii[MAX_GPT_NAME_SIZE] = {0};
795 CHAR8 *SlotSuffix = NULL;
796 BOOLEAN AllowVerificationError = IsUnlocked ();
Monika Singh43598872018-10-15 12:04:02 +0530797 CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
798 CHAR8 **RequestedPartition = NULL;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700799 UINTN NumRequestedPartition = 0;
AnilKumar Chimata3597bc12018-07-05 15:53:25 +0530800 INT32 Index = INVALID_PTN;
lijuang91071132019-02-13 16:20:09 +0800801 UINT32 ImageHdrSize = BOOT_IMG_MAX_PAGE_SIZE;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700802 UINT32 PageSize = 0;
803 UINT32 ImageSizeActual = 0;
804 VOID *ImageBuffer = NULL;
805 UINTN ImageSize = 0;
806 KMRotAndBootState Data = {0};
807 CONST boot_img_hdr *BootImgHdr = NULL;
808 AvbSlotVerifyFlags VerifyFlags =
809 AllowVerificationError ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
810 : AVB_SLOT_VERIFY_FLAGS_NONE;
811 AvbHashtreeErrorMode VerityFlags =
812 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700813
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700814 Info->BootState = RED;
815 GUARD (VBCommonInit (Info));
816 GUARD (VBAllocateCmdLine (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700817
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700818 UserData = avb_calloc (sizeof (AvbOpsUserData));
819 if (UserData == NULL) {
820 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOpsUserData\n"));
821 Status = EFI_OUT_OF_RESOURCES;
822 goto out;
823 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700824
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700825 Ops = AvbOpsNew (UserData);
826 if (Ops == NULL) {
827 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOps\n"));
828 Status = EFI_OUT_OF_RESOURCES;
829 goto out;
830 }
Shivaprasad Hongal82e18e92018-03-01 15:29:25 -0800831 UserData->IsMultiSlot = Info->MultiSlotBoot;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700832
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800833 if (Info->MultiSlotBoot) {
834 UnicodeStrToAsciiStr (Info->Pname, PnameAscii);
835 if ((MAX_SLOT_SUFFIX_SZ + 1) > AsciiStrLen (PnameAscii)) {
836 DEBUG ((EFI_D_ERROR, "ERROR: Can not determine slot suffix\n"));
837 Status = EFI_INVALID_PARAMETER;
838 goto out;
839 }
840 SlotSuffix = &PnameAscii[AsciiStrLen (PnameAscii) - MAX_SLOT_SUFFIX_SZ + 1];
841 } else {
842 SlotSuffix = "\0";
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700843 }
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -0700844
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700845 DEBUG ((EFI_D_VERBOSE, "Slot: %a, allow verification error: %a\n", SlotSuffix,
846 BooleanString[AllowVerificationError].name));
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -0700847
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700848 if (FixedPcdGetBool (AllowEio)) {
849 VerityFlags = IsEnforcing () ? AVB_HASHTREE_ERROR_MODE_RESTART
850 : AVB_HASHTREE_ERROR_MODE_EIO;
851 } else {
852 VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
853 }
Monika Singh43598872018-10-15 12:04:02 +0530854 RequestedPartition = RequestedPartitionAll;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700855
Monika Singh43598872018-10-15 12:04:02 +0530856 if ((!Info->MultiSlotBoot) &&
857 Info->BootIntoRecovery) {
858 AddRequestedPartition (RequestedPartitionAll, IMG_RECOVERY);
859 NumRequestedPartition += 1;
860 Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition,
861 SlotSuffix, VerifyFlags, VerityFlags, &SlotData);
Monika Singhe88af1f2018-11-12 13:52:41 +0530862 if (AllowVerificationError &&
863 ResultShouldContinue (Result)) {
864 DEBUG ((EFI_D_ERROR, "State: Unlocked, AvbSlotVerify returned "
865 "%a, continue boot\n",
866 avb_slot_verify_result_to_string (Result)));
867 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
Monika Singh43598872018-10-15 12:04:02 +0530868 DEBUG ((EFI_D_ERROR, "ERROR: Device State %a,AvbSlotVerify returned %a\n",
869 AllowVerificationError ? "Unlocked" : "Locked",
870 avb_slot_verify_result_to_string (Result)));
871 Status = EFI_LOAD_ERROR;
872 Info->BootState = RED;
873 goto out;
874 }
875 if (SlotData == NULL) {
876 Status = EFI_LOAD_ERROR;
877 Info->BootState = RED;
878 goto out;
879 }
880 BOOLEAN HeaderVersion = GetHeaderVersion (SlotData);
881 DEBUG ( (EFI_D_VERBOSE, "Recovery HeaderVersion %d \n", HeaderVersion));
882 if (!HeaderVersion) {
883 AddRequestedPartition (RequestedPartitionAll, IMG_DTBO);
884 NumRequestedPartition += 1;
885 if (SlotData != NULL) {
886 avb_slot_verify_data_free (SlotData);
887 }
888 Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition,
889 SlotSuffix, VerifyFlags, VerityFlags, &SlotData);
890 }
891 } else {
892 if (!Info->NumLoadedImages) {
893 AddRequestedPartition (RequestedPartitionAll, IMG_BOOT);
894 NumRequestedPartition += 1;
895 }
896 AddRequestedPartition (RequestedPartitionAll, IMG_DTBO);
897 NumRequestedPartition += 1;
AnilKumar Chimata3597bc12018-07-05 15:53:25 +0530898 if (IsVmEnabled ()) {
Jeevan Shriram0d619eb2018-10-08 15:42:11 -0700899 CHAR16 PartiName[MAX_GPT_NAME_SIZE];
900 Slot CurrentSlot;
901
902 GUARD (StrnCpyS (PartiName, (UINTN)MAX_GPT_NAME_SIZE,
903 (CONST CHAR16 *)L"vm-linux", StrLen (L"vm-linux")));
904
905 if (Info->MultiSlotBoot) {
906 CurrentSlot = GetCurrentSlotSuffix ();
907 GUARD (StrnCatS (PartiName, MAX_GPT_NAME_SIZE,
908 CurrentSlot.Suffix, StrLen (CurrentSlot.Suffix)));
909 }
910
911 Index = GetPartitionIndex (PartiName);
AnilKumar Chimata3597bc12018-07-05 15:53:25 +0530912 }
913 if (Index == INVALID_PTN ||
914 Index >= MAX_NUM_PARTITIONS) {
915 DEBUG ((EFI_D_ERROR, "Invalid vm-linux partition\n"));
916 } else {
917 AddRequestedPartition (RequestedPartitionAll, IMG_VMLINUX);
918 NumRequestedPartition += 1;
919 }
Monika Singh43598872018-10-15 12:04:02 +0530920 Result = avb_slot_verify (Ops, (CONST CHAR8 *CONST *)RequestedPartition,
921 SlotSuffix, VerifyFlags, VerityFlags, &SlotData);
922 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700923
Mukesh Ojha88a4fb92018-03-09 13:54:54 +0530924 if (SlotData == NULL) {
925 Status = EFI_LOAD_ERROR;
926 Info->BootState = RED;
927 goto out;
928 }
929
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700930 if (AllowVerificationError && ResultShouldContinue (Result)) {
931 DEBUG ((EFI_D_ERROR, "State: Unlocked, AvbSlotVerify returned "
932 "%a, continue boot\n",
933 avb_slot_verify_result_to_string (Result)));
934 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
935 DEBUG ((EFI_D_ERROR, "ERROR: Device State %a, AvbSlotVerify returned %a\n",
936 AllowVerificationError ? "Unlocked" : "Locked",
937 avb_slot_verify_result_to_string (Result)));
938 Status = EFI_LOAD_ERROR;
939 Info->BootState = RED;
940 goto out;
941 }
942
943 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
944 DEBUG ((EFI_D_VERBOSE, "Requested Partition: %a\n",
945 RequestedPartition[ReqIndex]));
946 for (UINTN LoadedIndex = 0; LoadedIndex < SlotData->num_loaded_partitions;
947 LoadedIndex++) {
948 DEBUG ((EFI_D_VERBOSE, "Loaded Partition: %a\n",
949 SlotData->loaded_partitions[LoadedIndex].partition_name));
950 if (!AsciiStrnCmp (
951 RequestedPartition[ReqIndex],
952 SlotData->loaded_partitions[LoadedIndex].partition_name,
953 AsciiStrLen (
954 SlotData->loaded_partitions[LoadedIndex].partition_name))) {
955 if (Info->NumLoadedImages >= ARRAY_SIZE (Info->Images)) {
956 DEBUG ((EFI_D_ERROR, "NumLoadedPartition"
957 "(%d) too large "
958 "max images(%d)\n",
959 Info->NumLoadedImages, ARRAY_SIZE (Info->Images)));
960 Status = EFI_LOAD_ERROR;
961 Info->BootState = RED;
962 goto out;
963 }
964 Info->Images[Info->NumLoadedImages].Name =
965 SlotData->loaded_partitions[LoadedIndex].partition_name;
966 Info->Images[Info->NumLoadedImages].ImageBuffer =
967 SlotData->loaded_partitions[LoadedIndex].data;
968 Info->Images[Info->NumLoadedImages].ImageSize =
969 SlotData->loaded_partitions[LoadedIndex].data_size;
970 Info->NumLoadedImages++;
971 break;
972 }
973 }
974 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700975
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800976 if (Info->NumLoadedImages < NumRequestedPartition) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700977 DEBUG ((EFI_D_ERROR, "ERROR: AvbSlotVerify slot data error: num of "
978 "loaded partitions %d, requested %d\n",
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800979 Info->NumLoadedImages, NumRequestedPartition));
Zhen Kong3b3a0df2017-10-04 19:00:09 -0700980 Status = EFI_LOAD_ERROR;
981 goto out;
982 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700983
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700984 DEBUG ((EFI_D_VERBOSE, "Total loaded partition %d\n", Info->NumLoadedImages));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700985
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700986 VBData = (VB2Data *)avb_calloc (sizeof (VB2Data));
987 if (VBData == NULL) {
988 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate VB2Data\n"));
989 Status = EFI_OUT_OF_RESOURCES;
990 goto out;
991 }
992 VBData->Ops = Ops;
993 VBData->SlotData = SlotData;
994 Info->VBData = (VOID *)VBData;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700995
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800996 GUARD_OUT (GetImage (Info, &ImageBuffer, &ImageSize,
997 ((!Info->MultiSlotBoot) &&
998 Info->BootIntoRecovery) ?
999 "recovery" : "boot"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001000
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001001 Status = CheckImageHeader (ImageBuffer, ImageHdrSize,
lijuang06904a32018-12-10 16:54:32 +08001002 &ImageSizeActual, &PageSize, Info->BootIntoRecovery);
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001003 if (Status != EFI_SUCCESS) {
1004 DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status));
1005 goto out;
1006 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001007
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001008 if (AllowVerificationError) {
1009 Info->BootState = ORANGE;
1010 } else {
1011 if (UserData->IsUserKey) {
1012 Info->BootState = YELLOW;
1013 } else {
1014 Info->BootState = GREEN;
1015 }
1016 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001017
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001018 /* command line */
1019 GUARD_OUT (AppendVBCommonCmdLine (Info));
1020 GUARD_OUT (AppendVBCmdLine (Info, SlotData->cmdline));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001021
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001022 /* Set Rot & Boot State*/
1023 Data.Color = Info->BootState;
Zhen Kongbb3db752017-07-10 17:07:10 -07001024 Data. IsUnlocked = AllowVerificationError;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001025 Data.PublicKeyLength = UserData->PublicKeyLen;
1026 Data.PublicKey = UserData->PublicKey;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001027
lijuangbcba7092018-04-10 19:57:54 +08001028 BootImgHdr = (boot_img_hdr *)ImageBuffer;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001029 Data.SystemSecurityLevel = (BootImgHdr->os_version & 0x7FF);
1030 Data.SystemVersion = (BootImgHdr->os_version & 0xFFFFF800) >> 11;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001031
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001032 GUARD_OUT (KeyMasterSetRotAndBootState (&Data));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001033
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001034 DEBUG ((EFI_D_INFO, "VB2: Authenticate complete! boot state is: %a\n",
1035 VbSn[Info->BootState].name));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001036
1037out:
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001038 if (Status != EFI_SUCCESS) {
1039 if (SlotData != NULL) {
1040 avb_slot_verify_data_free (SlotData);
1041 }
1042 if (Ops != NULL) {
1043 AvbOpsFree (Ops);
1044 }
1045 if (UserData != NULL) {
1046 avb_free (UserData);
1047 }
1048 if (VBData != NULL) {
1049 avb_free (VBData);
1050 }
1051 Info->BootState = RED;
AnilKumar Chimata681e0f42018-01-19 17:47:56 -08001052 if (Info->MultiSlotBoot) {
1053 HandleActiveSlotUnbootable ();
1054 /* HandleActiveSlotUnbootable should have swapped slots and
1055 * reboot the device. If no bootable slot found, enter fastboot
1056 */
1057 DEBUG ((EFI_D_WARN, "No bootable slots found enter fastboot mode\n"));
1058 } else {
1059 DEBUG ((EFI_D_WARN,
1060 "Non Multi-slot: Unbootable entering fastboot mode\n"));
1061 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001062 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001063
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001064 DEBUG ((EFI_D_ERROR, "VB2: boot state: %a(%d)\n", VbSn[Info->BootState].name,
1065 Info->BootState));
1066 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001067}
1068
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001069STATIC EFI_STATUS
1070DisplayVerifiedBootScreen (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001071{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001072 EFI_STATUS Status = EFI_SUCCESS;
1073 CHAR8 FfbmStr[FFBM_MODE_BUF_SIZE] = {'\0'};
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001074
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001075 if (GetAVBVersion () < AVB_1) {
1076 return EFI_SUCCESS;
1077 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001078
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001079 if (!StrnCmp (Info->Pname, L"boot", StrLen (L"boot"))) {
1080 Status = GetFfbmCommand (FfbmStr, FFBM_MODE_BUF_SIZE);
1081 if (Status != EFI_SUCCESS) {
1082 DEBUG ((EFI_D_VERBOSE, "No Ffbm cookie found, ignore: %r\n", Status));
1083 FfbmStr[0] = '\0';
1084 }
1085 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001086
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001087 DEBUG ((EFI_D_VERBOSE, "Boot State is : %d\n", Info->BootState));
1088 switch (Info->BootState) {
1089 case RED:
1090 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_RED);
1091 if (Status != EFI_SUCCESS) {
1092 DEBUG ((EFI_D_INFO,
1093 "Your device is corrupt. It can't be trusted and will not boot."
1094 "\nYour device will shutdown in 30s\n"));
1095 }
1096 MicroSecondDelay (30000000);
1097 ShutdownDevice ();
1098 break;
1099 case YELLOW:
1100 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_YELLOW);
1101 if (Status == EFI_SUCCESS) {
1102 WaitForExitKeysDetection ();
1103 } else {
1104 DEBUG ((EFI_D_INFO, "Your device has loaded a different operating system."
1105 "\nWait for 5 seconds before proceeding\n"));
1106 MicroSecondDelay (5000000);
1107 }
1108 break;
1109 case ORANGE:
1110 if (FfbmStr[0] != '\0' && !TargetBuildVariantUser ()) {
1111 DEBUG ((EFI_D_VERBOSE, "Device will boot into FFBM mode\n"));
1112 } else {
1113 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_ORANGE);
1114 if (Status == EFI_SUCCESS) {
1115 WaitForExitKeysDetection ();
1116 } else {
1117 DEBUG (
1118 (EFI_D_INFO, "Device is unlocked, Skipping boot verification\n"));
1119 MicroSecondDelay (5000000);
1120 }
1121 }
1122 break;
1123 default:
1124 break;
1125 }
lijuang3d51d3b2018-07-03 14:29:59 +08001126
1127 /* dm-verity warning */
Jeevan Shriram70d98572018-09-26 15:01:49 -07001128 if ((GetAVBVersion () != AVB_2) &&
1129 !IsEnforcing () &&
lijuang3d51d3b2018-07-03 14:29:59 +08001130 !Info->BootIntoRecovery) {
1131 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_EIO);
1132 if (Status == EFI_SUCCESS) {
1133 WaitForExitKeysDetection ();
1134 } else {
1135 DEBUG ((EFI_D_INFO, "The dm-verity is not started in restart mode." \
1136 "\nWait for 30 seconds before proceeding\n"));
1137 MicroSecondDelay (30000000);
1138 }
1139 }
1140
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001141 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001142}
1143
Zhen Kongbb3db752017-07-10 17:07:10 -07001144STATIC EFI_STATUS LoadImageAndAuthForLE (BootInfo *Info)
1145{
1146 EFI_STATUS Status = EFI_SUCCESS;
1147 QcomAsn1x509Protocol *QcomAsn1X509Protocal = NULL;
1148 CONST UINT8 *OemCertFile = LeOemCertificate;
1149 UINTN OemCertFileLen = sizeof (LeOemCertificate);
1150 CERTIFICATE OemCert = {NULL};
1151 UINTN HashSize;
1152 UINT8 *ImgHash = NULL;
1153 UINTN ImgSize;
1154 VB_HASH HashAlgorithm;
1155 UINT8 *SigAddr = NULL;
1156 UINT32 SigSize = 0;
mohamed sunfeer4987c692018-04-18 19:29:28 +05301157 CHAR8 *SystemPath = NULL;
1158 UINT32 SystemPathLen = 0;
Anmolpreet Kaurdeae0f12019-01-17 11:48:48 +05301159 BOOLEAN SecureDevice = FALSE;
Zhen Kongbb3db752017-07-10 17:07:10 -07001160 /*Load image*/
mohamed sunfeer4987c692018-04-18 19:29:28 +05301161 GUARD (VBAllocateCmdLine (Info));
Zhen Kongbb3db752017-07-10 17:07:10 -07001162 GUARD (VBCommonInit (Info));
1163 GUARD (LoadImageNoAuth (Info));
1164
Anmolpreet Kaurdeae0f12019-01-17 11:48:48 +05301165 Status = IsSecureDevice (&SecureDevice);
1166 if (Status != EFI_SUCCESS) {
1167 DEBUG ((EFI_D_ERROR, "VB: Failed read device state: %r\n", Status));
1168 return Status;
1169 }
1170
1171 if (!SecureDevice) {
1172 if (!TargetBuildVariantUser () ) {
1173 DEBUG ((EFI_D_INFO, "VB: verification skipped for debug builds\n"));
1174 goto skip_verification;
1175 }
Mohamed Sunfeer604b2ed2018-10-30 13:36:02 +05301176 }
1177
Zhen Kongbb3db752017-07-10 17:07:10 -07001178 /* Initialize Verified Boot*/
1179 device_info_vb_t DevInfo_vb;
1180 DevInfo_vb.is_unlocked = IsUnlocked ();
1181 DevInfo_vb.is_unlock_critical = IsUnlockCritical ();
1182 Status = Info->VbIntf->VBDeviceInit (Info->VbIntf,
1183 (device_info_vb_t *)&DevInfo_vb);
1184 if (Status != EFI_SUCCESS) {
1185 DEBUG ((EFI_D_ERROR, "VB: Error during VBDeviceInit: %r\n", Status));
1186 return Status;
1187 }
1188
1189 /* Locate QcomAsn1x509Protocol*/
1190 Status = gBS->LocateProtocol (&gEfiQcomASN1X509ProtocolGuid, NULL,
1191 (VOID **)&QcomAsn1X509Protocal);
1192 if (Status != EFI_SUCCESS) {
1193 DEBUG ((EFI_D_ERROR, "VB: Error LocateProtocol "
1194 "gEfiQcomASN1X509ProtocolGuid: %r\n", Status));
1195 return Status;
1196 }
1197
1198 /* Read OEM certificate from the embedded header file */
1199 Status = QcomAsn1X509Protocal->ASN1X509VerifyOEMCertificate
1200 (QcomAsn1X509Protocal, OemCertFile, OemCertFileLen, &OemCert);
1201 if (Status != EFI_SUCCESS) {
1202 DEBUG ((EFI_D_ERROR, "VB: Error during "
1203 "ASN1X509VerifyOEMCertificate: %r\n", Status));
1204 return Status;
1205 }
1206
1207 /*Calculate kernel image hash, SHA256 is used by default*/
1208 HashAlgorithm = VB_SHA256;
1209 HashSize = VB_SHA256_SIZE;
1210 ImgSize = Info->Images[0].ImageSize;
Bhanuprakash Modem763cdd52018-11-01 14:49:55 +05301211 ImgHash = AllocateZeroPool (HashSize);
Zhen Kongbb3db752017-07-10 17:07:10 -07001212 if (ImgHash == NULL) {
1213 DEBUG ((EFI_D_ERROR, "kernel image hash buffer allocation failed!\n"));
1214 Status = EFI_OUT_OF_RESOURCES;
1215 return Status;
1216 }
1217 Status = LEGetImageHash (QcomAsn1X509Protocal, HashAlgorithm,
1218 (UINT8 *)Info->Images[0].ImageBuffer,
1219 ImgSize, ImgHash, HashSize);
1220 if (Status != EFI_SUCCESS) {
1221 DEBUG ((EFI_D_ERROR, "VB: Error during VBGetImageHash: %r\n", Status));
1222 return Status;
1223 }
1224
1225 SigAddr = (UINT8 *)Info->Images[0].ImageBuffer + ImgSize;
1226 SigSize = LE_BOOTIMG_SIG_SIZE;
1227 Status = LEVerifyHashWithSignature (QcomAsn1X509Protocal, ImgHash,
1228 HashAlgorithm, &OemCert, SigAddr, SigSize);
1229
1230 if (Status != EFI_SUCCESS) {
1231 DEBUG ((EFI_D_ERROR, "VB: Error during "
1232 "LEVBVerifyHashWithSignature: %r\n", Status));
1233 return Status;
1234 }
1235 DEBUG ((EFI_D_INFO, "VB: LoadImageAndAuthForLE complete!\n"));
mohamed sunfeer4987c692018-04-18 19:29:28 +05301236
Mohamed Sunfeer604b2ed2018-10-30 13:36:02 +05301237skip_verification:
mohamed sunfeer4987c692018-04-18 19:29:28 +05301238 if (!IsRootCmdLineUpdated (Info)) {
lijuangf0149ab2018-09-05 20:35:32 +08001239 SystemPathLen = GetSystemPath (&SystemPath,
1240 Info->MultiSlotBoot,
1241 Info->BootIntoRecovery,
1242 (CHAR16 *)L"system",
1243 (CHAR8 *)"root");
mohamed sunfeer4987c692018-04-18 19:29:28 +05301244 if (SystemPathLen == 0 ||
1245 SystemPath == NULL) {
1246 return EFI_LOAD_ERROR;
1247 }
1248 GUARD (AppendVBCmdLine (Info, SystemPath));
1249 }
Zhen Kongbb3db752017-07-10 17:07:10 -07001250 return Status;
1251}
1252
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001253EFI_STATUS
1254LoadImageAndAuth (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001255{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001256 EFI_STATUS Status = EFI_SUCCESS;
1257 BOOLEAN MdtpActive = FALSE;
1258 QCOM_MDTP_PROTOCOL *MdtpProtocol;
1259 UINT32 AVBVersion = NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001260
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001261 if (Info == NULL) {
1262 DEBUG ((EFI_D_ERROR, "Invalid parameter Info\n"));
1263 return EFI_INVALID_PARAMETER;
1264 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001265
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001266 /* Get Partition Name*/
1267 if (!Info->MultiSlotBoot) {
1268 if (Info->BootIntoRecovery) {
1269 DEBUG ((EFI_D_INFO, "Booting Into Recovery Mode\n"));
1270 StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"recovery",
1271 StrLen (L"recovery"));
1272 } else {
1273 DEBUG ((EFI_D_INFO, "Booting Into Mission Mode\n"));
1274 StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot",
1275 StrLen (L"boot"));
1276 }
1277 } else {
1278 Slot CurrentSlot = {{0}};
Shivaprasad Hongalc017e812017-04-26 16:15:27 -07001279
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001280 GUARD (FindBootableSlot (&CurrentSlot));
1281 if (IsSuffixEmpty (&CurrentSlot)) {
1282 DEBUG ((EFI_D_ERROR, "No bootable slot\n"));
1283 return EFI_LOAD_ERROR;
1284 }
Shivaprasad Hongalc017e812017-04-26 16:15:27 -07001285
Mayank Grover1c051582019-02-26 14:42:27 +05301286 if (IsDynamicPartitionSupport () &&
1287 Info->BootIntoRecovery) {
1288 DEBUG ((EFI_D_INFO, "Booting Into Recovery Mode\n"));
1289 StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"recovery",
1290 StrLen (L"recovery"));
1291 } else {
1292 DEBUG ((EFI_D_INFO, "Booting Into Mission Mode\n"));
1293 GUARD (StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot",
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001294 StrLen (L"boot")));
Mayank Grover1c051582019-02-26 14:42:27 +05301295 }
1296
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001297 GUARD (StrnCatS (Info->Pname, ARRAY_SIZE (Info->Pname), CurrentSlot.Suffix,
1298 StrLen (CurrentSlot.Suffix)));
1299 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001300
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001301 DEBUG ((EFI_D_VERBOSE, "MultiSlot %a, partition name %s\n",
1302 BooleanString[Info->MultiSlotBoot].name, Info->Pname));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001303
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001304 if (FixedPcdGetBool (EnableMdtpSupport)) {
1305 Status = IsMdtpActive (&MdtpActive);
1306 if (EFI_ERROR (Status)) {
1307 DEBUG ((EFI_D_ERROR, "Failed to get activation state for MDTP, "
1308 "Status=%r."
1309 " Considering MDTP as active and continuing \n",
1310 Status));
1311 if (Status != EFI_NOT_FOUND)
1312 MdtpActive = TRUE;
1313 }
1314 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001315
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001316 AVBVersion = GetAVBVersion ();
1317 DEBUG ((EFI_D_VERBOSE, "AVB version %d\n", AVBVersion));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001318
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001319 /* Load and Authenticate */
1320 switch (AVBVersion) {
1321 case NO_AVB:
1322 return LoadImageNoAuthWrapper (Info);
1323 break;
1324 case AVB_1:
1325 Status = LoadImageAndAuthVB1 (Info);
1326 break;
1327 case AVB_2:
1328 Status = LoadImageAndAuthVB2 (Info);
1329 break;
Zhen Kongbb3db752017-07-10 17:07:10 -07001330 case AVB_LE:
1331 Status = LoadImageAndAuthForLE (Info);
1332 break;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001333 default:
1334 DEBUG ((EFI_D_ERROR, "Unsupported AVB version %d\n", AVBVersion));
1335 Status = EFI_UNSUPPORTED;
1336 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001337
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001338 // if MDTP is active Display Recovery UI
1339 if (Status != EFI_SUCCESS && MdtpActive) {
1340 Status = gBS->LocateProtocol (&gQcomMdtpProtocolGuid, NULL,
1341 (VOID **)&MdtpProtocol);
1342 if (EFI_ERROR (Status)) {
1343 DEBUG (
1344 (EFI_D_ERROR, "Failed to locate MDTP protocol, Status=%r\n", Status));
1345 return Status;
1346 }
1347 /* Perform Local Deactivation of MDTP */
1348 Status = MdtpProtocol->MdtpDeactivate (MdtpProtocol, FALSE);
1349 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001350
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001351 if (IsUnlocked () && Status != EFI_SUCCESS) {
1352 DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status));
1353 return Status;
1354 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001355
Zhen Kongbb3db752017-07-10 17:07:10 -07001356 if (AVBVersion != AVB_LE) {
1357 DisplayVerifiedBootScreen (Info);
1358 DEBUG ((EFI_D_VERBOSE, "Sending Milestone Call\n"));
1359 Status = Info->VbIntf->VBSendMilestone (Info->VbIntf);
1360 if (Status != EFI_SUCCESS) {
1361 DEBUG ((EFI_D_ERROR, "Error sending milestone call to TZ\n"));
1362 return Status;
1363 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001364 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001365 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001366}
1367
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001368VOID
1369FreeVerifiedBootResource (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001370{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001371 DEBUG ((EFI_D_VERBOSE, "FreeVerifiedBootResource\n"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001372
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001373 if (Info == NULL) {
1374 return;
1375 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001376
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001377 VB2Data *VBData = Info->VBData;
1378 if (VBData != NULL) {
1379 AvbOps *Ops = VBData->Ops;
1380 if (Ops != NULL) {
1381 if (Ops->user_data != NULL) {
1382 avb_free (Ops->user_data);
1383 }
1384 AvbOpsFree (Ops);
1385 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001386
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001387 AvbSlotVerifyData *SlotData = VBData->SlotData;
1388 if (SlotData != NULL) {
1389 avb_slot_verify_data_free (SlotData);
1390 }
1391 avb_free (VBData);
1392 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001393
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001394 if (Info->VBCmdLine != NULL) {
1395 FreePool (Info->VBCmdLine);
1396 }
1397 return;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001398}
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001399
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001400EFI_STATUS
1401GetCertFingerPrint (UINT8 *FingerPrint,
1402 UINTN FingerPrintLen,
1403 UINTN *FingerPrintLenOut)
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001404{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001405 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001406
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001407 if (FingerPrint == NULL || FingerPrintLenOut == NULL ||
1408 FingerPrintLen < AVB_SHA256_DIGEST_SIZE) {
1409 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: Invalid parameters\n"));
1410 return EFI_INVALID_PARAMETER;
1411 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001412
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001413 if (GetAVBVersion () == AVB_1) {
1414 QCOM_VERIFIEDBOOT_PROTOCOL *VbIntf = NULL;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001415
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001416 Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL,
1417 (VOID **)&VbIntf);
1418 if (Status != EFI_SUCCESS) {
1419 DEBUG ((EFI_D_ERROR, "Unable to locate VerifiedBoot Protocol\n"));
1420 return Status;
1421 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001422
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001423 if (VbIntf->Revision < QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) {
1424 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: VB1: not "
1425 "supported for this revision\n"));
1426 return EFI_UNSUPPORTED;
1427 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001428
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001429 Status = VbIntf->VBGetCertFingerPrint (VbIntf, FingerPrint, FingerPrintLen,
1430 FingerPrintLenOut);
1431 if (Status != EFI_SUCCESS) {
1432 DEBUG ((EFI_D_ERROR, "Failed Reading CERT FingerPrint\n"));
1433 return Status;
1434 }
1435 } else if (GetAVBVersion () == AVB_2) {
1436 CHAR8 *UserKeyBuffer = NULL;
1437 UINT32 UserKeyLength = 0;
1438 AvbSHA256Ctx UserKeyCtx = {{0}};
1439 CHAR8 *UserKeyDigest = NULL;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001440
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001441 GUARD (GetUserKey (&UserKeyBuffer, &UserKeyLength));
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001442
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001443 avb_sha256_init (&UserKeyCtx);
1444 avb_sha256_update (&UserKeyCtx, (UINT8 *)UserKeyBuffer, UserKeyLength);
1445 UserKeyDigest = (CHAR8 *)avb_sha256_final (&UserKeyCtx);
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001446
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001447 CopyMem (FingerPrint, UserKeyDigest, AVB_SHA256_DIGEST_SIZE);
1448 *FingerPrintLenOut = AVB_SHA256_DIGEST_SIZE;
1449 } else {
1450 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: not supported\n"));
1451 return EFI_UNSUPPORTED;
1452 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001453
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001454 return Status;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001455}