blob: 51aa5bb193f58d87d9eadcd634edcf5bd7209776 [file] [log] [blame]
Mukesh Ojha71be2c82018-02-02 19:13:10 +05301/* Copyright (c) 2017-2018, 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>
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070036
37STATIC CONST CHAR8 *VerityMode = " androidboot.veritymode=";
38STATIC CONST CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
39STATIC CONST CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
Mukesh Ojha71be2c82018-02-02 19:13:10 +053040STATIC CONST CHAR8 *DmVerityCmd = " root=/dev/dm-0 dm=\"system none ro,0 1 "
41 "android-verity";
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070042STATIC CONST CHAR8 *Space = " ";
Jeevan Shriram17f173d2017-10-24 22:11:07 -070043
44STATIC struct verified_boot_verity_mode VbVm[] = {
45 {FALSE, "logging"},
46 {TRUE, "enforcing"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070047};
48
Jeevan Shriram17f173d2017-10-24 22:11:07 -070049STATIC struct verified_boot_state_name VbSn[] = {
50 {GREEN, "green"},
51 {ORANGE, "orange"},
52 {YELLOW, "yellow"},
53 {RED, "red"},
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070054};
55
Jeevan Shriram17f173d2017-10-24 22:11:07 -070056struct boolean_string {
57 BOOLEAN value;
58 CHAR8 *name;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070059};
60
Jeevan Shriram17f173d2017-10-24 22:11:07 -070061STATIC struct boolean_string BooleanString[] = {
62 {FALSE, "false"},
63 {TRUE, "true"}
64};
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070065
66typedef struct {
Jeevan Shriram17f173d2017-10-24 22:11:07 -070067 AvbOps *Ops;
68 AvbSlotVerifyData *SlotData;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070069} VB2Data;
70
Jeevan Shriram17f173d2017-10-24 22:11:07 -070071UINT32
72GetAVBVersion ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070073{
Zhen Kongbb3db752017-07-10 17:07:10 -070074#if VERIFIED_BOOT_LE
75 return AVB_LE;
76#elif VERIFIED_BOOT_2
77 return AVB_2;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -070078#elif VERIFIED_BOOT
Zhen Kongbb3db752017-07-10 17:07:10 -070079 return AVB_1;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070080#else
Zhen Kongbb3db752017-07-10 17:07:10 -070081 return NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070082#endif
83}
84
Jeevan Shriram17f173d2017-10-24 22:11:07 -070085BOOLEAN
86VerifiedBootEnbled ()
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070087{
Jeevan Shriram17f173d2017-10-24 22:11:07 -070088 return (GetAVBVersion () > NO_AVB);
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070089}
90
Jeevan Shriram17f173d2017-10-24 22:11:07 -070091STATIC EFI_STATUS
92AppendVBCmdLine (BootInfo *Info, CONST CHAR8 *Src)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070093{
Jeevan Shriram17f173d2017-10-24 22:11:07 -070094 EFI_STATUS Status = EFI_SUCCESS;
95 INT32 SrcLen = AsciiStrLen (Src);
96 CHAR8 *Dst = Info->VBCmdLine + Info->VBCmdLineFilledLen;
97 INT32 DstLen = Info->VBCmdLineLen - Info->VBCmdLineFilledLen;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -070098
Jeevan Shriram17f173d2017-10-24 22:11:07 -070099 GUARD (AsciiStrnCatS (Dst, DstLen, Src, SrcLen));
100 Info->VBCmdLineFilledLen += SrcLen;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700101
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700102 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700103}
104
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700105STATIC EFI_STATUS
106AppendVBCommonCmdLine (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700107{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700108 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700109
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700110 if (Info->VbIntf->Revision >= QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) {
111 GUARD (AppendVBCmdLine (Info, VerifiedState));
112 GUARD (AppendVBCmdLine (Info, VbSn[Info->BootState].name));
113 }
114 GUARD (AppendVBCmdLine (Info, KeymasterLoadState));
115 GUARD (AppendVBCmdLine (Info, Space));
116 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700117}
118
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700119STATIC EFI_STATUS
Runmin Wang261d2bf2017-11-03 11:40:40 -0700120NoAVBLoadDtboImage (BootInfo *Info, VOID **DtboImage,
121 UINT32 *DtboSize, CHAR16 *Pname)
122{
123 EFI_STATUS Status = EFI_SUCCESS;
124 Slot CurrentSlot;
125
126 *DtboSize = (UINT32) DTBO_MAX_SIZE_ALLOWED;
127 *DtboImage = AllocatePool (DTBO_MAX_SIZE_ALLOWED);
128 GUARD ( StrnCpyS (Pname,
129 (UINTN)MAX_GPT_NAME_SIZE,
130 (CONST CHAR16 *)L"dtbo",
131 StrLen (L"dtbo")));
132
133 if (Info->MultiSlotBoot) {
134 CurrentSlot = GetCurrentSlotSuffix ();
135 GUARD ( StrnCatS (Pname, MAX_GPT_NAME_SIZE,
136 CurrentSlot.Suffix, StrLen (CurrentSlot.Suffix)));
137 }
138 Status = LoadImageFromPartition (*DtboImage, DtboSize, Pname);
139 return Status;
140}
141
142STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700143VBCommonInit (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700144{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700145 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700146
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700147 Info->BootState = RED;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700148
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700149 Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL,
150 (VOID **)&(Info->VbIntf));
151 if (Status != EFI_SUCCESS) {
152 DEBUG ((EFI_D_ERROR, "Unable to locate VB protocol: %r\n", Status));
Zhen Kongdb33a732017-07-10 12:23:00 -0700153 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700154 }
155
156 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700157}
158
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700159/*
160 * Ensure Info->Pname is already updated before this function is called.
161 * If Command line already has "root=", return TRUE, else FALSE.
162 */
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700163STATIC EFI_STATUS
164VBAllocateCmdLine (BootInfo *Info)
Zhen Kongdb33a732017-07-10 12:23:00 -0700165{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700166 EFI_STATUS Status = EFI_SUCCESS;
Zhen Kongdb33a732017-07-10 12:23:00 -0700167
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700168 /* allocate VB command line*/
169 Info->VBCmdLine = AllocatePool (DTB_PAD_SIZE);
170 if (Info->VBCmdLine == NULL) {
171 DEBUG ((EFI_D_ERROR, "VB CmdLine allocation failed!\n"));
172 Status = EFI_OUT_OF_RESOURCES;
Zhen Kongdb33a732017-07-10 12:23:00 -0700173 return Status;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700174 }
175 Info->VBCmdLineLen = DTB_PAD_SIZE;
176 Info->VBCmdLineFilledLen = 0;
177 Info->VBCmdLine[Info->VBCmdLineFilledLen] = '\0';
178
179 return Status;
Zhen Kongdb33a732017-07-10 12:23:00 -0700180}
181
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700182STATIC
183BOOLEAN
184IsRootCmdLineUpdated (BootInfo *Info)
185{
186 CHAR8* ImageCmdLine = NULL;
187
188 ImageCmdLine =
189 (CHAR8*) & (((boot_img_hdr*) (Info->Images[0].ImageBuffer))->cmdline[0]);
190
191 ImageCmdLine[BOOT_ARGS_SIZE - 1] = '\0';
192 if (AsciiStrStr (ImageCmdLine, "root=")) {
193 return TRUE;
194 } else {
195 return FALSE;
196 }
197}
198
199
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700200STATIC EFI_STATUS
201LoadImageNoAuth (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700202{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700203 EFI_STATUS Status = EFI_SUCCESS;
Runmin Wang261d2bf2017-11-03 11:40:40 -0700204 CHAR16 Pname[MAX_GPT_NAME_SIZE];
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700205
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700206 if (Info->Images[0].ImageBuffer != NULL && Info->Images[0].ImageSize > 0) {
207 /* fastboot boot option image already loaded */
208 return Status;
209 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700210
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700211 Status = LoadImage (Info->Pname, (VOID **)&(Info->Images[0].ImageBuffer),
212 (UINT32 *)&(Info->Images[0].ImageSize));
213 if (Status != EFI_SUCCESS) {
214 DEBUG ((EFI_D_ERROR, "ERROR: Failed to load image from partition: %r\n",
215 Status));
216 return EFI_LOAD_ERROR;
217 }
218 Info->NumLoadedImages = 1;
219 Info->Images[0].Name = AllocatePool (StrLen (Info->Pname) + 1);
220 UnicodeStrToAsciiStr (Info->Pname, Info->Images[0].Name);
Runmin Wang261d2bf2017-11-03 11:40:40 -0700221
222 /*load dt overlay when avb is disabled*/
223 Status = NoAVBLoadDtboImage (Info, (VOID **)&(Info->Images[1].ImageBuffer),
224 (UINT32 *)&(Info->Images[1].ImageSize), Pname);
225 if (Status == EFI_NO_MEDIA) {
226 DEBUG ((EFI_D_ERROR, "No dtbo partition is found, Skip dtbo\n"));
227 FreePool (Info->Images[1].ImageBuffer);
228 return EFI_SUCCESS;
229 }
230 else if (Status != EFI_SUCCESS) {
231 DEBUG ((EFI_D_ERROR,
232 "ERROR: Failed to load dtbo from partition: %r\n", Status));
233 FreePool (Info->Images[1].ImageBuffer);
234 return EFI_LOAD_ERROR;
235 }
236 Info-> NumLoadedImages = 2;
237 Info-> Images[1].Name = AllocatePool (StrLen (Pname) + 1);
238 UnicodeStrToAsciiStr (Pname, Info->Images[1].Name);
239
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700240 return Status;
241}
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700242
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700243STATIC EFI_STATUS
244LoadImageNoAuthWrapper (BootInfo *Info)
245{
246 EFI_STATUS Status = EFI_SUCCESS;
247 CHAR8 *SystemPath = NULL;
248 UINT32 SystemPathLen = 0;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700249
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700250 GUARD (VBAllocateCmdLine (Info));
251 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700252
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700253 if (!IsRootCmdLineUpdated (Info)) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700254 SystemPathLen = GetSystemPath (&SystemPath);
255 if (SystemPathLen == 0 || SystemPath == NULL) {
256 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
257 return EFI_LOAD_ERROR;
Zhen Kongdb33a732017-07-10 12:23:00 -0700258 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700259 GUARD (AppendVBCmdLine (Info, SystemPath));
260 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700261
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700262 return Status;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700263}
264
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700265STATIC EFI_STATUS
266LoadImageAndAuthVB1 (BootInfo *Info)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700267{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700268 EFI_STATUS Status = EFI_SUCCESS;
269 CHAR8 StrPnameAscii[MAX_GPT_NAME_SIZE]; /* partition name starting with
270 / and no suffix */
271 CHAR8 PnameAscii[MAX_GPT_NAME_SIZE];
272 CHAR8 *SystemPath = NULL;
273 UINT32 SystemPathLen = 0;
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530274 CHAR8 *Temp = NULL;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700275
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700276 GUARD (VBCommonInit (Info));
277 GUARD (VBAllocateCmdLine (Info));
278 GUARD (LoadImageNoAuth (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700279
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700280 device_info_vb_t DevInfo_vb;
281 DevInfo_vb.is_unlocked = IsUnlocked ();
282 DevInfo_vb.is_unlock_critical = IsUnlockCritical ();
283 Status = Info->VbIntf->VBDeviceInit (Info->VbIntf,
284 (device_info_vb_t *)&DevInfo_vb);
285 if (Status != EFI_SUCCESS) {
286 DEBUG ((EFI_D_ERROR, "Error during VBDeviceInit: %r\n", Status));
287 return Status;
288 }
289
290 AsciiStrnCpyS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), "/",
291 AsciiStrLen ("/"));
292 UnicodeStrToAsciiStr (Info->Pname, PnameAscii);
293 if (Info->MultiSlotBoot) {
294 AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii,
295 AsciiStrLen (PnameAscii) - (MAX_SLOT_SUFFIX_SZ - 1));
296 } else {
297 AsciiStrnCatS (StrPnameAscii, ARRAY_SIZE (StrPnameAscii), PnameAscii,
298 AsciiStrLen (PnameAscii));
299 }
300
301 Status =
302 Info->VbIntf->VBVerifyImage (Info->VbIntf, (UINT8 *)StrPnameAscii,
303 (UINT8 *)Info->Images[0].ImageBuffer,
304 Info->Images[0].ImageSize, &Info->BootState);
305 if (Status != EFI_SUCCESS || Info->BootState == BOOT_STATE_MAX) {
306 DEBUG ((EFI_D_ERROR, "VBVerifyImage failed with: %r\n", Status));
307 return Status;
308 }
309
310 Status = Info->VbIntf->VBSendRot (Info->VbIntf);
311 if (Status != EFI_SUCCESS) {
312 DEBUG ((EFI_D_ERROR, "Error sending Rot : %r\n", Status));
313 return Status;
314 }
315
Jeevan Shriram615b1e12017-10-12 14:10:06 -0700316 if (!IsRootCmdLineUpdated (Info)) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700317 SystemPathLen = GetSystemPath (&SystemPath);
318 if (SystemPathLen == 0 || SystemPath == NULL) {
319 DEBUG ((EFI_D_ERROR, "GetSystemPath failed!\n"));
320 return EFI_LOAD_ERROR;
321 }
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530322 GUARD (AppendVBCmdLine (Info, DmVerityCmd));
323 /* Copy only the portion after "root=" in the SystemPath */
324 Temp = AsciiStrStr (SystemPath, "root=");
325 if (Temp) {
326 CopyMem (Temp, SystemPath + AsciiStrLen ("root=") + 1,
327 SystemPathLen - AsciiStrLen ("root=") - 1);
328 SystemPath[SystemPathLen - AsciiStrLen ("root=")] = '\0';
329 }
330
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700331 GUARD (AppendVBCmdLine (Info, SystemPath));
Mukesh Ojha71be2c82018-02-02 19:13:10 +0530332 GUARD (AppendVBCmdLine (Info, "\""));
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700333 }
334 GUARD (AppendVBCommonCmdLine (Info));
335 GUARD (AppendVBCmdLine (Info, VerityMode));
336 GUARD (AppendVBCmdLine (Info, VbVm[IsEnforcing ()].name));
337
338 Info->VBData = NULL;
339 return Status;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700340}
341
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700342STATIC BOOLEAN
343ResultShouldContinue (AvbSlotVerifyResult Result)
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700344{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700345 switch (Result) {
346 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
347 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
348 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
349 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
350 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
351 return FALSE;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700352
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700353 case AVB_SLOT_VERIFY_RESULT_OK:
354 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
355 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
356 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
357 return TRUE;
358 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700359
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700360 return FALSE;
361}
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700362
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700363STATIC EFI_STATUS
Zhen Kongbb3db752017-07-10 17:07:10 -0700364LEGetImageHash (QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
365 VB_HASH HashAlgorithm,
366 UINT8 *Img, UINTN ImgSize,
367 UINT8 *ImgHash, UINTN HashSize)
368{
369 EFI_STATUS Status = EFI_FAILURE;
370 EFI_GUID *HashAlgorithmGuid;
371 UINTN DigestSize = 0;
372 EFI_HASH2_OUTPUT Hash2Output;
373 EFI_HASH2_PROTOCOL *pEfiHash2Protocol = NULL;
374
375 if (pEfiQcomASN1X509Protocol == NULL ||
376 Img == NULL ||
377 ImgHash == NULL) {
378 DEBUG ((EFI_D_ERROR,
379 "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n"));
380 return EFI_INVALID_PARAMETER;
381 }
382
383 switch (HashAlgorithm) {
384 case VB_SHA256:
385 HashAlgorithmGuid = &gEfiHashAlgorithmSha256Guid;
386 break;
387 default:
388 DEBUG ((EFI_D_ERROR,
389 "VB: LEGetImageHash: not supported algorithm:%d\n", HashAlgorithm));
390 Status = EFI_UNSUPPORTED;
391 goto exit;
392 }
393
394 Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid,
395 NULL, (VOID **)&pEfiHash2Protocol);
396 if (Status != EFI_SUCCESS) {
397 DEBUG ((EFI_D_ERROR,
398 "VB:LEGetImageHash: LocateProtocol unsuccessful!Status: %r\n", Status));
399 goto exit;
400 }
401
402 Status = pEfiHash2Protocol->GetHashSize (pEfiHash2Protocol,
403 HashAlgorithmGuid, &DigestSize);
404 if (Status != EFI_SUCCESS) {
405 DEBUG ((EFI_D_ERROR,
406 "VB: LEGetImageHash: GetHashSize unsuccessful! Status: %r\n", Status));
407 goto exit;
408 }
409 if (HashSize != DigestSize) {
410 DEBUG ((EFI_D_ERROR,
411 "VB: LEGetImageHash: Invalid size! HashSize: %d, DigestSize: %d\n"
412 , HashSize, DigestSize));
413 Status = EFI_FAILURE;
414 goto exit;
415 }
416 Status = pEfiHash2Protocol->HashInit (pEfiHash2Protocol, HashAlgorithmGuid);
417 if (Status != EFI_SUCCESS) {
418 DEBUG ((EFI_D_ERROR,
419 "VB: LEGetImageHash: HashInit unsuccessful! Status: %r\n", Status));
420 goto exit;
421 }
422 Status = pEfiHash2Protocol->HashUpdate (pEfiHash2Protocol, Img, ImgSize);
423 if (EFI_SUCCESS != Status) {
424
425 DEBUG ((EFI_D_ERROR,
426 "VB: LEGetImageHash: HashUpdate unsuccessful(Img)!Status: %r\n"
427 , Status));
428 goto exit;
429 }
430 Status = pEfiHash2Protocol->HashFinal (pEfiHash2Protocol, &Hash2Output);
431 if (EFI_SUCCESS != Status) {
432
433 DEBUG ((EFI_D_ERROR,
434 "VB: LEGetImageHash: HashFinal unsuccessful! Status: %r\n", Status));
435 goto exit;
436 }
437 gBS->CopyMem ((VOID *)ImgHash, (VOID *)&Hash2Output, DigestSize);
438 Status = EFI_SUCCESS;
439
440exit:
441 return Status;
442}
443
444STATIC EFI_STATUS LEGetRSAPublicKeyInfoFromCertificate (
445 QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
446 CERTIFICATE *Certificate,
447 secasn1_data_type *Modulus,
448 secasn1_data_type *PublicExp,
449 UINT32 *PaddingType)
450{
451 EFI_STATUS Status = EFI_FAILURE;
452 RSA RsaKey = {NULL};
453
454 if (pEfiQcomASN1X509Protocol == NULL ||
455 Certificate == NULL ||
456 Modulus == NULL ||
457 PublicExp == NULL ||
458 PaddingType == NULL) {
459 DEBUG ((EFI_D_ERROR,
460 "LEGetRSAPublicKeyInfoFromCertificate: Invalid pointer\n"));
461 return EFI_INVALID_PARAMETER;
462 }
463
464 Status = pEfiQcomASN1X509Protocol->ASN1X509GetRSAFromCert
465 (pEfiQcomASN1X509Protocol, Certificate, &RsaKey);
466 if (Status != EFI_SUCCESS) {
467 DEBUG ((EFI_D_ERROR,
468 "VB: ASN1X509GetRSAFromCert unsuccessful! Status : %r\n", Status));
469 goto exit;
470 }
471 Status = pEfiQcomASN1X509Protocol->ASN1X509GetKeymaterial
472 (pEfiQcomASN1X509Protocol, &RsaKey, Modulus, PublicExp);
473 if (Status != EFI_SUCCESS) {
474 DEBUG ((EFI_D_ERROR,
475 "VB: ASN1X509GetKeymaterial unsuccessful! Status: %r\n", Status));
476 goto exit;
477 }
478 *PaddingType = CE_RSA_PAD_PKCS1_V1_5_SIG;
479exit:
480 return Status;
481}
482STATIC EFI_STATUS LEVerifyHashWithRSASignature (
483 UINT8 *ImgHash,
484 VB_HASH HashAlgorithm,
485 secasn1_data_type *Modulus,
486 secasn1_data_type *PublicExp,
487 UINT32 PaddingType,
488 CONST UINT8 *SignaturePtr,
489 UINT32 SignatureLen)
490{
491 EFI_STATUS Status = EFI_FAILURE;
492 CE_RSA_KEY Key = {0};
493 BigInt ModulusBi;
494 BigInt PublicExpBi;
495 INT32 HashIdx;
496 INT32 HashLen;
497 VOID *PaddingInfo = NULL;
498 QcomSecRsaProtocol *pEfiQcomSecRSAProtocol = NULL;
499 SetMem (&Key, sizeof (CE_RSA_KEY), 0);
500
501 if (ImgHash == NULL ||
502 Modulus == NULL ||
503 PublicExp == NULL ||
504 SignaturePtr == NULL) {
505 DEBUG ((EFI_D_ERROR, "LEVerifyHashWithRSASignature:Invalid pointer\n"));
506 return EFI_INVALID_PARAMETER;
507 }
508
509 switch (HashAlgorithm) {
510 case VB_SHA256:
511 HashIdx = CE_HASH_IDX_SHA256;
512 HashLen = VB_SHA256_SIZE;
513 break;
514 default:
515 DEBUG ((EFI_D_ERROR,
516 "VB: LEVerifySignature: Hash algorithm not supported\n"));
517 Status = EFI_UNSUPPORTED;
518 goto exit;
519 }
520
521 Key.N = AllocatePool (sizeof (S_BIGINT));
522 if (Key.N == NULL) {
523 DEBUG ((EFI_D_ERROR,
524 "VB: LEVerifySignature: mem allocation err for Key.N\n"));
525 goto exit;
526 }
527 Key.e = AllocatePool (sizeof (S_BIGINT));
528 if (Key.e == NULL) {
529 DEBUG ((EFI_D_ERROR,
530 "VB: LEVerifySignature: mem allocation err for Key.e\n"));
531 goto exit;
532 }
533 Status = gBS->LocateProtocol (&gEfiQcomSecRSAProtocolGuid,
534 NULL, (VOID **) &pEfiQcomSecRSAProtocol);
535 if ( Status != EFI_SUCCESS) {
536 DEBUG ((EFI_D_ERROR,
537 "VB: LEVerifySignature: LocateProtocol failed, Status: %r\n", Status));
538 goto exit;
539 }
540
541 Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin (
542 pEfiQcomSecRSAProtocol, Modulus->data, Modulus->Len, &ModulusBi);
543 if ( Status != EFI_SUCCESS) {
544 DEBUG ((EFI_D_ERROR,
545 "VB: LEVerifySignature: SecRSABigIntReadBin for Modulus failed!"
546 "Status: %r\n", Status));
547 goto exit;
548 }
549 Status = pEfiQcomSecRSAProtocol->SecRSABigIntReadBin (
550 pEfiQcomSecRSAProtocol, PublicExp->data, PublicExp->Len, &PublicExpBi);
551 if ( Status != EFI_SUCCESS) {
552 DEBUG ((EFI_D_ERROR, "VB: LEVerifySignature: SecRSABigIntReadBin for"
553 " Modulus failed! Status: %r\n", Status));
554 goto exit;
555 }
556
557 Key.N->Bi = ModulusBi;
558 Key.e->Bi = PublicExpBi;
559 Key.e->Sign = S_BIGINT_POS;
560 Key.Type = CE_RSA_KEY_PUBLIC;
561
562 Status = pEfiQcomSecRSAProtocol->SecRSAVerifySig (pEfiQcomSecRSAProtocol,
563 &Key, PaddingType,
564 PaddingInfo, HashIdx,
565 ImgHash, HashLen, (UINT8*)SignaturePtr, SignatureLen);
566
567 if (Status != EFI_SUCCESS) {
568 DEBUG ((EFI_D_ERROR,
569 "VB: LEVerifySignature: SecRSAVerifySig failed! Status: %r\n", Status));
570 goto exit;
571 }
572
573 DEBUG ((EFI_D_VERBOSE, "VB: LEVerifySignature: SecRSAVerifySig success!"
574 " Status: %r\n", Status));
575
576 Status = EFI_SUCCESS;
577exit:
578 if (Key.N != NULL) {
579 FreePool (Key.N);
580 }
581 if (Key.e != NULL) {
582 FreePool (Key.e);
583 }
584 return Status;
585}
586
587STATIC EFI_STATUS LEVerifyHashWithSignature (
588 QcomAsn1x509Protocol *pEfiQcomASN1X509Protocol,
589 UINT8 *ImgHash, VB_HASH HashAlgorithm,
590 CERTIFICATE *Certificate,
591 CONST UINT8 *SignaturePtr,
592 UINT32 SignatureLen)
593{
594 EFI_STATUS Status = EFI_FAILURE;
595 secasn1_data_type Modulus = {NULL};
596 secasn1_data_type PublicExp = {NULL};
597 UINT32 PaddingType = 0;
598
599 if (pEfiQcomASN1X509Protocol == NULL ||
600 ImgHash == NULL ||
601 Certificate == NULL ||
602 SignaturePtr == NULL) {
603 DEBUG ((EFI_D_ERROR, "LEVerifyHashWithSignature: Invalid pointer\n"));
604 return EFI_INVALID_PARAMETER;
605 }
606
607 /* TODO: get subject publick key info from certificate, implement new
608 algorithm in XBL*/
609 /* XBL implemented by default sha256 and rsaEncryption with
610 PKCS1_V1_5 padding*/
611
612 Status = LEGetRSAPublicKeyInfoFromCertificate (pEfiQcomASN1X509Protocol,
613 Certificate, &Modulus, &PublicExp, &PaddingType);
614 if (Status != EFI_SUCCESS) {
615 DEBUG ((EFI_D_ERROR, "VB: LEGetRSAPublicKeyInfoFromCertificate "
616 "unsuccessful! Status: %r\n", Status));
617 goto exit;
618 }
619
620 Status = LEVerifyHashWithRSASignature (ImgHash, HashAlgorithm,
621 &Modulus, &PublicExp, PaddingType,
622 SignaturePtr, SignatureLen);
623 if (Status != EFI_SUCCESS) {
624 DEBUG ((EFI_D_ERROR, "VB: LEVerifyHashWithSignature unsuccessful! "
625 "Status: %r\n", Status));
626 goto exit;
627 }
628 Status = EFI_SUCCESS;
629exit:
630 return Status;
631}
632
633
634STATIC EFI_STATUS
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700635LoadImageAndAuthVB2 (BootInfo *Info)
636{
637 EFI_STATUS Status = EFI_SUCCESS;
638 AvbSlotVerifyResult Result;
639 AvbSlotVerifyData *SlotData = NULL;
640 VB2Data *VBData = NULL;
641 AvbOpsUserData *UserData = NULL;
642 AvbOps *Ops = NULL;
643 CHAR8 PnameAscii[MAX_GPT_NAME_SIZE] = {0};
644 CHAR8 *SlotSuffix = NULL;
645 BOOLEAN AllowVerificationError = IsUnlocked ();
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800646 CONST CHAR8 *RequestedPartitionMission[] = {"boot", "dtbo", NULL};
647 CONST CHAR8 *RequestedPartitionRecovery[] = {"recovery", "dtbo", NULL};
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700648 CONST CHAR8 *CONST *RequestedPartition = NULL;
649 UINTN NumRequestedPartition = 0;
650 UINT32 ImageHdrSize = 0;
651 UINT32 PageSize = 0;
652 UINT32 ImageSizeActual = 0;
653 VOID *ImageBuffer = NULL;
654 UINTN ImageSize = 0;
655 KMRotAndBootState Data = {0};
656 CONST boot_img_hdr *BootImgHdr = NULL;
657 AvbSlotVerifyFlags VerifyFlags =
658 AllowVerificationError ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
659 : AVB_SLOT_VERIFY_FLAGS_NONE;
660 AvbHashtreeErrorMode VerityFlags =
661 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700662
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700663 Info->BootState = RED;
664 GUARD (VBCommonInit (Info));
665 GUARD (VBAllocateCmdLine (Info));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700666
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700667 UserData = avb_calloc (sizeof (AvbOpsUserData));
668 if (UserData == NULL) {
669 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOpsUserData\n"));
670 Status = EFI_OUT_OF_RESOURCES;
671 goto out;
672 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700673
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700674 Ops = AvbOpsNew (UserData);
675 if (Ops == NULL) {
676 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate AvbOps\n"));
677 Status = EFI_OUT_OF_RESOURCES;
678 goto out;
679 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700680
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800681 if (Info->MultiSlotBoot) {
682 UnicodeStrToAsciiStr (Info->Pname, PnameAscii);
683 if ((MAX_SLOT_SUFFIX_SZ + 1) > AsciiStrLen (PnameAscii)) {
684 DEBUG ((EFI_D_ERROR, "ERROR: Can not determine slot suffix\n"));
685 Status = EFI_INVALID_PARAMETER;
686 goto out;
687 }
688 SlotSuffix = &PnameAscii[AsciiStrLen (PnameAscii) - MAX_SLOT_SUFFIX_SZ + 1];
689 } else {
690 SlotSuffix = "\0";
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700691 }
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -0700692
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700693 DEBUG ((EFI_D_VERBOSE, "Slot: %a, allow verification error: %a\n", SlotSuffix,
694 BooleanString[AllowVerificationError].name));
Shivaprasad Hongal39236ae2017-06-06 16:10:35 -0700695
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800696 if ((!Info->MultiSlotBoot) &&
697 Info->BootIntoRecovery) {
698 RequestedPartition = RequestedPartitionRecovery;
699 NumRequestedPartition = ARRAY_SIZE (RequestedPartitionRecovery) - 1;
700 if (Info->NumLoadedImages) {
701 /* fastboot boot option, skip Index 0, as boot image already
702 * loaded */
703 RequestedPartition = &RequestedPartitionRecovery[1];
704 }
705 } else {
706 RequestedPartition = RequestedPartitionMission;
707 NumRequestedPartition = ARRAY_SIZE (RequestedPartitionMission) - 1;
708 if (Info->NumLoadedImages) {
709 /* fastboot boot option, skip Index 0, as boot image already
710 * loaded */
711 RequestedPartition = &RequestedPartitionMission[1];
712 }
713 }
714
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700715 if (Info->NumLoadedImages) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700716 NumRequestedPartition--;
717 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700718
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700719 if (FixedPcdGetBool (AllowEio)) {
720 VerityFlags = IsEnforcing () ? AVB_HASHTREE_ERROR_MODE_RESTART
721 : AVB_HASHTREE_ERROR_MODE_EIO;
722 } else {
723 VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
724 }
725
726 Result = avb_slot_verify (Ops, RequestedPartition, SlotSuffix, VerifyFlags,
727 VerityFlags, &SlotData);
728
Mukesh Ojha88a4fb92018-03-09 13:54:54 +0530729 if (SlotData == NULL) {
730 Status = EFI_LOAD_ERROR;
731 Info->BootState = RED;
732 goto out;
733 }
734
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700735 if (AllowVerificationError && ResultShouldContinue (Result)) {
736 DEBUG ((EFI_D_ERROR, "State: Unlocked, AvbSlotVerify returned "
737 "%a, continue boot\n",
738 avb_slot_verify_result_to_string (Result)));
739 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
740 DEBUG ((EFI_D_ERROR, "ERROR: Device State %a, AvbSlotVerify returned %a\n",
741 AllowVerificationError ? "Unlocked" : "Locked",
742 avb_slot_verify_result_to_string (Result)));
743 Status = EFI_LOAD_ERROR;
744 Info->BootState = RED;
745 goto out;
746 }
747
748 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
749 DEBUG ((EFI_D_VERBOSE, "Requested Partition: %a\n",
750 RequestedPartition[ReqIndex]));
751 for (UINTN LoadedIndex = 0; LoadedIndex < SlotData->num_loaded_partitions;
752 LoadedIndex++) {
753 DEBUG ((EFI_D_VERBOSE, "Loaded Partition: %a\n",
754 SlotData->loaded_partitions[LoadedIndex].partition_name));
755 if (!AsciiStrnCmp (
756 RequestedPartition[ReqIndex],
757 SlotData->loaded_partitions[LoadedIndex].partition_name,
758 AsciiStrLen (
759 SlotData->loaded_partitions[LoadedIndex].partition_name))) {
760 if (Info->NumLoadedImages >= ARRAY_SIZE (Info->Images)) {
761 DEBUG ((EFI_D_ERROR, "NumLoadedPartition"
762 "(%d) too large "
763 "max images(%d)\n",
764 Info->NumLoadedImages, ARRAY_SIZE (Info->Images)));
765 Status = EFI_LOAD_ERROR;
766 Info->BootState = RED;
767 goto out;
768 }
769 Info->Images[Info->NumLoadedImages].Name =
770 SlotData->loaded_partitions[LoadedIndex].partition_name;
771 Info->Images[Info->NumLoadedImages].ImageBuffer =
772 SlotData->loaded_partitions[LoadedIndex].data;
773 Info->Images[Info->NumLoadedImages].ImageSize =
774 SlotData->loaded_partitions[LoadedIndex].data_size;
775 Info->NumLoadedImages++;
776 break;
777 }
778 }
779 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700780
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800781 if (Info->NumLoadedImages < NumRequestedPartition) {
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700782 DEBUG ((EFI_D_ERROR, "ERROR: AvbSlotVerify slot data error: num of "
783 "loaded partitions %d, requested %d\n",
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800784 Info->NumLoadedImages, NumRequestedPartition));
Zhen Kong3b3a0df2017-10-04 19:00:09 -0700785 Status = EFI_LOAD_ERROR;
786 goto out;
787 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700788
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700789 DEBUG ((EFI_D_VERBOSE, "Total loaded partition %d\n", Info->NumLoadedImages));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700790
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700791 VBData = (VB2Data *)avb_calloc (sizeof (VB2Data));
792 if (VBData == NULL) {
793 DEBUG ((EFI_D_ERROR, "ERROR: Failed to allocate VB2Data\n"));
794 Status = EFI_OUT_OF_RESOURCES;
795 goto out;
796 }
797 VBData->Ops = Ops;
798 VBData->SlotData = SlotData;
799 Info->VBData = (VOID *)VBData;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700800
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700801 GetPageSize (&ImageHdrSize);
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800802 GUARD_OUT (GetImage (Info, &ImageBuffer, &ImageSize,
803 ((!Info->MultiSlotBoot) &&
804 Info->BootIntoRecovery) ?
805 "recovery" : "boot"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700806
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800807 Status = CheckImageHeader (ImageBuffer, ImageHdrSize,
808 &ImageSizeActual, &PageSize);
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700809 if (Status != EFI_SUCCESS) {
810 DEBUG ((EFI_D_ERROR, "Invalid boot image header:%r\n", Status));
811 goto out;
812 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700813
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700814 if (ImageSizeActual > ImageSize) {
815 Status = EFI_BUFFER_TOO_SMALL;
816 DEBUG ((EFI_D_ERROR, "Boot size in vbmeta less than actual boot image size "
817 "flash corresponding vbmeta.img\n"));
818 goto out;
819 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700820
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700821 if (AllowVerificationError) {
822 Info->BootState = ORANGE;
823 } else {
824 if (UserData->IsUserKey) {
825 Info->BootState = YELLOW;
826 } else {
827 Info->BootState = GREEN;
828 }
829 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700830
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700831 /* command line */
832 GUARD_OUT (AppendVBCommonCmdLine (Info));
833 GUARD_OUT (AppendVBCmdLine (Info, SlotData->cmdline));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700834
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700835 /* Set Rot & Boot State*/
836 Data.Color = Info->BootState;
Zhen Kongbb3db752017-07-10 17:07:10 -0700837 Data. IsUnlocked = AllowVerificationError;
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700838 Data.PublicKeyLength = UserData->PublicKeyLen;
839 Data.PublicKey = UserData->PublicKey;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700840
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700841 BootImgHdr = (struct boot_img_hdr *)ImageBuffer;
842 Data.SystemSecurityLevel = (BootImgHdr->os_version & 0x7FF);
843 Data.SystemVersion = (BootImgHdr->os_version & 0xFFFFF800) >> 11;
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700844
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700845 GUARD_OUT (KeyMasterSetRotAndBootState (&Data));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700846
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700847 DEBUG ((EFI_D_INFO, "VB2: Authenticate complete! boot state is: %a\n",
848 VbSn[Info->BootState].name));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700849
850out:
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700851 if (Status != EFI_SUCCESS) {
852 if (SlotData != NULL) {
853 avb_slot_verify_data_free (SlotData);
854 }
855 if (Ops != NULL) {
856 AvbOpsFree (Ops);
857 }
858 if (UserData != NULL) {
859 avb_free (UserData);
860 }
861 if (VBData != NULL) {
862 avb_free (VBData);
863 }
864 Info->BootState = RED;
AnilKumar Chimata681e0f42018-01-19 17:47:56 -0800865 if (Info->MultiSlotBoot) {
866 HandleActiveSlotUnbootable ();
867 /* HandleActiveSlotUnbootable should have swapped slots and
868 * reboot the device. If no bootable slot found, enter fastboot
869 */
870 DEBUG ((EFI_D_WARN, "No bootable slots found enter fastboot mode\n"));
871 } else {
872 DEBUG ((EFI_D_WARN,
873 "Non Multi-slot: Unbootable entering fastboot mode\n"));
874 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700875 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -0700876
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700877 DEBUG ((EFI_D_ERROR, "VB2: boot state: %a(%d)\n", VbSn[Info->BootState].name,
878 Info->BootState));
879 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700880}
881
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700882STATIC EFI_STATUS
883DisplayVerifiedBootScreen (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700884{
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700885 EFI_STATUS Status = EFI_SUCCESS;
886 CHAR8 FfbmStr[FFBM_MODE_BUF_SIZE] = {'\0'};
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700887
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700888 if (GetAVBVersion () < AVB_1) {
889 return EFI_SUCCESS;
890 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700891
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700892 if (!StrnCmp (Info->Pname, L"boot", StrLen (L"boot"))) {
893 Status = GetFfbmCommand (FfbmStr, FFBM_MODE_BUF_SIZE);
894 if (Status != EFI_SUCCESS) {
895 DEBUG ((EFI_D_VERBOSE, "No Ffbm cookie found, ignore: %r\n", Status));
896 FfbmStr[0] = '\0';
897 }
898 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700899
Jeevan Shriram17f173d2017-10-24 22:11:07 -0700900 DEBUG ((EFI_D_VERBOSE, "Boot State is : %d\n", Info->BootState));
901 switch (Info->BootState) {
902 case RED:
903 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_RED);
904 if (Status != EFI_SUCCESS) {
905 DEBUG ((EFI_D_INFO,
906 "Your device is corrupt. It can't be trusted and will not boot."
907 "\nYour device will shutdown in 30s\n"));
908 }
909 MicroSecondDelay (30000000);
910 ShutdownDevice ();
911 break;
912 case YELLOW:
913 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_YELLOW);
914 if (Status == EFI_SUCCESS) {
915 WaitForExitKeysDetection ();
916 } else {
917 DEBUG ((EFI_D_INFO, "Your device has loaded a different operating system."
918 "\nWait for 5 seconds before proceeding\n"));
919 MicroSecondDelay (5000000);
920 }
921 break;
922 case ORANGE:
923 if (FfbmStr[0] != '\0' && !TargetBuildVariantUser ()) {
924 DEBUG ((EFI_D_VERBOSE, "Device will boot into FFBM mode\n"));
925 } else {
926 Status = DisplayVerifiedBootMenu (DISPLAY_MENU_ORANGE);
927 if (Status == EFI_SUCCESS) {
928 WaitForExitKeysDetection ();
929 } else {
930 DEBUG (
931 (EFI_D_INFO, "Device is unlocked, Skipping boot verification\n"));
932 MicroSecondDelay (5000000);
933 }
934 }
935 break;
936 default:
937 break;
938 }
939 return EFI_SUCCESS;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -0700940}
941
Zhen Kongbb3db752017-07-10 17:07:10 -0700942STATIC EFI_STATUS LoadImageAndAuthForLE (BootInfo *Info)
943{
944 EFI_STATUS Status = EFI_SUCCESS;
945 QcomAsn1x509Protocol *QcomAsn1X509Protocal = NULL;
946 CONST UINT8 *OemCertFile = LeOemCertificate;
947 UINTN OemCertFileLen = sizeof (LeOemCertificate);
948 CERTIFICATE OemCert = {NULL};
949 UINTN HashSize;
950 UINT8 *ImgHash = NULL;
951 UINTN ImgSize;
952 VB_HASH HashAlgorithm;
953 UINT8 *SigAddr = NULL;
954 UINT32 SigSize = 0;
955
956 /*Load image*/
957 GUARD (VBCommonInit (Info));
958 GUARD (LoadImageNoAuth (Info));
959
960 /* Initialize Verified Boot*/
961 device_info_vb_t DevInfo_vb;
962 DevInfo_vb.is_unlocked = IsUnlocked ();
963 DevInfo_vb.is_unlock_critical = IsUnlockCritical ();
964 Status = Info->VbIntf->VBDeviceInit (Info->VbIntf,
965 (device_info_vb_t *)&DevInfo_vb);
966 if (Status != EFI_SUCCESS) {
967 DEBUG ((EFI_D_ERROR, "VB: Error during VBDeviceInit: %r\n", Status));
968 return Status;
969 }
970
971 /* Locate QcomAsn1x509Protocol*/
972 Status = gBS->LocateProtocol (&gEfiQcomASN1X509ProtocolGuid, NULL,
973 (VOID **)&QcomAsn1X509Protocal);
974 if (Status != EFI_SUCCESS) {
975 DEBUG ((EFI_D_ERROR, "VB: Error LocateProtocol "
976 "gEfiQcomASN1X509ProtocolGuid: %r\n", Status));
977 return Status;
978 }
979
980 /* Read OEM certificate from the embedded header file */
981 Status = QcomAsn1X509Protocal->ASN1X509VerifyOEMCertificate
982 (QcomAsn1X509Protocal, OemCertFile, OemCertFileLen, &OemCert);
983 if (Status != EFI_SUCCESS) {
984 DEBUG ((EFI_D_ERROR, "VB: Error during "
985 "ASN1X509VerifyOEMCertificate: %r\n", Status));
986 return Status;
987 }
988
989 /*Calculate kernel image hash, SHA256 is used by default*/
990 HashAlgorithm = VB_SHA256;
991 HashSize = VB_SHA256_SIZE;
992 ImgSize = Info->Images[0].ImageSize;
993 ImgHash = AllocatePool (HashSize);
994 if (ImgHash == NULL) {
995 DEBUG ((EFI_D_ERROR, "kernel image hash buffer allocation failed!\n"));
996 Status = EFI_OUT_OF_RESOURCES;
997 return Status;
998 }
999 Status = LEGetImageHash (QcomAsn1X509Protocal, HashAlgorithm,
1000 (UINT8 *)Info->Images[0].ImageBuffer,
1001 ImgSize, ImgHash, HashSize);
1002 if (Status != EFI_SUCCESS) {
1003 DEBUG ((EFI_D_ERROR, "VB: Error during VBGetImageHash: %r\n", Status));
1004 return Status;
1005 }
1006
1007 SigAddr = (UINT8 *)Info->Images[0].ImageBuffer + ImgSize;
1008 SigSize = LE_BOOTIMG_SIG_SIZE;
1009 Status = LEVerifyHashWithSignature (QcomAsn1X509Protocal, ImgHash,
1010 HashAlgorithm, &OemCert, SigAddr, SigSize);
1011
1012 if (Status != EFI_SUCCESS) {
1013 DEBUG ((EFI_D_ERROR, "VB: Error during "
1014 "LEVBVerifyHashWithSignature: %r\n", Status));
1015 return Status;
1016 }
1017 DEBUG ((EFI_D_INFO, "VB: LoadImageAndAuthForLE complete!\n"));
1018 return Status;
1019}
1020
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001021EFI_STATUS
1022LoadImageAndAuth (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001023{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001024 EFI_STATUS Status = EFI_SUCCESS;
1025 BOOLEAN MdtpActive = FALSE;
1026 QCOM_MDTP_PROTOCOL *MdtpProtocol;
1027 UINT32 AVBVersion = NO_AVB;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001028
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001029 if (Info == NULL) {
1030 DEBUG ((EFI_D_ERROR, "Invalid parameter Info\n"));
1031 return EFI_INVALID_PARAMETER;
1032 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001033
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001034 /* Get Partition Name*/
1035 if (!Info->MultiSlotBoot) {
1036 if (Info->BootIntoRecovery) {
1037 DEBUG ((EFI_D_INFO, "Booting Into Recovery Mode\n"));
1038 StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"recovery",
1039 StrLen (L"recovery"));
1040 } else {
1041 DEBUG ((EFI_D_INFO, "Booting Into Mission Mode\n"));
1042 StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot",
1043 StrLen (L"boot"));
1044 }
1045 } else {
1046 Slot CurrentSlot = {{0}};
Shivaprasad Hongalc017e812017-04-26 16:15:27 -07001047
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001048 GUARD (FindBootableSlot (&CurrentSlot));
1049 if (IsSuffixEmpty (&CurrentSlot)) {
1050 DEBUG ((EFI_D_ERROR, "No bootable slot\n"));
1051 return EFI_LOAD_ERROR;
1052 }
Shivaprasad Hongalc017e812017-04-26 16:15:27 -07001053
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001054 GUARD (StrnCpyS (Info->Pname, ARRAY_SIZE (Info->Pname), L"boot",
1055 StrLen (L"boot")));
1056 GUARD (StrnCatS (Info->Pname, ARRAY_SIZE (Info->Pname), CurrentSlot.Suffix,
1057 StrLen (CurrentSlot.Suffix)));
1058 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001059
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001060 DEBUG ((EFI_D_VERBOSE, "MultiSlot %a, partition name %s\n",
1061 BooleanString[Info->MultiSlotBoot].name, Info->Pname));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001062
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001063 if (FixedPcdGetBool (EnableMdtpSupport)) {
1064 Status = IsMdtpActive (&MdtpActive);
1065 if (EFI_ERROR (Status)) {
1066 DEBUG ((EFI_D_ERROR, "Failed to get activation state for MDTP, "
1067 "Status=%r."
1068 " Considering MDTP as active and continuing \n",
1069 Status));
1070 if (Status != EFI_NOT_FOUND)
1071 MdtpActive = TRUE;
1072 }
1073 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001074
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001075 AVBVersion = GetAVBVersion ();
1076 DEBUG ((EFI_D_VERBOSE, "AVB version %d\n", AVBVersion));
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001077
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001078 /* Load and Authenticate */
1079 switch (AVBVersion) {
1080 case NO_AVB:
1081 return LoadImageNoAuthWrapper (Info);
1082 break;
1083 case AVB_1:
1084 Status = LoadImageAndAuthVB1 (Info);
1085 break;
1086 case AVB_2:
1087 Status = LoadImageAndAuthVB2 (Info);
1088 break;
Zhen Kongbb3db752017-07-10 17:07:10 -07001089 case AVB_LE:
1090 Status = LoadImageAndAuthForLE (Info);
1091 break;
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001092 default:
1093 DEBUG ((EFI_D_ERROR, "Unsupported AVB version %d\n", AVBVersion));
1094 Status = EFI_UNSUPPORTED;
1095 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001096
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001097 // if MDTP is active Display Recovery UI
1098 if (Status != EFI_SUCCESS && MdtpActive) {
1099 Status = gBS->LocateProtocol (&gQcomMdtpProtocolGuid, NULL,
1100 (VOID **)&MdtpProtocol);
1101 if (EFI_ERROR (Status)) {
1102 DEBUG (
1103 (EFI_D_ERROR, "Failed to locate MDTP protocol, Status=%r\n", Status));
1104 return Status;
1105 }
1106 /* Perform Local Deactivation of MDTP */
1107 Status = MdtpProtocol->MdtpDeactivate (MdtpProtocol, FALSE);
1108 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001109
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001110 if (IsUnlocked () && Status != EFI_SUCCESS) {
1111 DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status));
1112 return Status;
1113 }
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001114
Zhen Kongbb3db752017-07-10 17:07:10 -07001115 if (AVBVersion != AVB_LE) {
1116 DisplayVerifiedBootScreen (Info);
1117 DEBUG ((EFI_D_VERBOSE, "Sending Milestone Call\n"));
1118 Status = Info->VbIntf->VBSendMilestone (Info->VbIntf);
1119 if (Status != EFI_SUCCESS) {
1120 DEBUG ((EFI_D_ERROR, "Error sending milestone call to TZ\n"));
1121 return Status;
1122 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001123 }
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001124 return Status;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001125}
1126
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001127VOID
1128FreeVerifiedBootResource (BootInfo *Info)
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001129{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001130 DEBUG ((EFI_D_VERBOSE, "FreeVerifiedBootResource\n"));
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001131
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001132 if (Info == NULL) {
1133 return;
1134 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001135
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001136 VB2Data *VBData = Info->VBData;
1137 if (VBData != NULL) {
1138 AvbOps *Ops = VBData->Ops;
1139 if (Ops != NULL) {
1140 if (Ops->user_data != NULL) {
1141 avb_free (Ops->user_data);
1142 }
1143 AvbOpsFree (Ops);
1144 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001145
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001146 AvbSlotVerifyData *SlotData = VBData->SlotData;
1147 if (SlotData != NULL) {
1148 avb_slot_verify_data_free (SlotData);
1149 }
1150 avb_free (VBData);
1151 }
Shivaprasad Hongale3b53392017-04-27 17:32:47 -07001152
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001153 if (Info->VBCmdLine != NULL) {
1154 FreePool (Info->VBCmdLine);
1155 }
1156 return;
Shivaprasad Hongala2c4dd72017-04-27 14:33:18 -07001157}
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001158
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001159EFI_STATUS
1160GetCertFingerPrint (UINT8 *FingerPrint,
1161 UINTN FingerPrintLen,
1162 UINTN *FingerPrintLenOut)
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001163{
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001164 EFI_STATUS Status = EFI_SUCCESS;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001165
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001166 if (FingerPrint == NULL || FingerPrintLenOut == NULL ||
1167 FingerPrintLen < AVB_SHA256_DIGEST_SIZE) {
1168 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: Invalid parameters\n"));
1169 return EFI_INVALID_PARAMETER;
1170 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001171
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001172 if (GetAVBVersion () == AVB_1) {
1173 QCOM_VERIFIEDBOOT_PROTOCOL *VbIntf = NULL;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001174
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001175 Status = gBS->LocateProtocol (&gEfiQcomVerifiedBootProtocolGuid, NULL,
1176 (VOID **)&VbIntf);
1177 if (Status != EFI_SUCCESS) {
1178 DEBUG ((EFI_D_ERROR, "Unable to locate VerifiedBoot Protocol\n"));
1179 return Status;
1180 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001181
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001182 if (VbIntf->Revision < QCOM_VERIFIEDBOOT_PROTOCOL_REVISION) {
1183 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: VB1: not "
1184 "supported for this revision\n"));
1185 return EFI_UNSUPPORTED;
1186 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001187
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001188 Status = VbIntf->VBGetCertFingerPrint (VbIntf, FingerPrint, FingerPrintLen,
1189 FingerPrintLenOut);
1190 if (Status != EFI_SUCCESS) {
1191 DEBUG ((EFI_D_ERROR, "Failed Reading CERT FingerPrint\n"));
1192 return Status;
1193 }
1194 } else if (GetAVBVersion () == AVB_2) {
1195 CHAR8 *UserKeyBuffer = NULL;
1196 UINT32 UserKeyLength = 0;
1197 AvbSHA256Ctx UserKeyCtx = {{0}};
1198 CHAR8 *UserKeyDigest = NULL;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001199
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001200 GUARD (GetUserKey (&UserKeyBuffer, &UserKeyLength));
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001201
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001202 avb_sha256_init (&UserKeyCtx);
1203 avb_sha256_update (&UserKeyCtx, (UINT8 *)UserKeyBuffer, UserKeyLength);
1204 UserKeyDigest = (CHAR8 *)avb_sha256_final (&UserKeyCtx);
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001205
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001206 CopyMem (FingerPrint, UserKeyDigest, AVB_SHA256_DIGEST_SIZE);
1207 *FingerPrintLenOut = AVB_SHA256_DIGEST_SIZE;
1208 } else {
1209 DEBUG ((EFI_D_ERROR, "GetCertFingerPrint: not supported\n"));
1210 return EFI_UNSUPPORTED;
1211 }
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001212
Jeevan Shriram17f173d2017-10-24 22:11:07 -07001213 return Status;
Shivaprasad Hongal7fd6a522017-05-10 13:56:28 -07001214}