blob: a322e5d686c0776fb7775ac1ea7623366e598b99 [file] [log] [blame]
Monika Singh51876762019-05-22 18:47:22 +05301/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Monika Singh5e170362018-03-14 00:48:36 +05302 *
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 "libavb/libavb.h"
30#include <malloc.h>
31
32#include <boot_verifier.h>
33#include <ab_partition_parser.h>
34#include <partition_parser.h>
35#include <recovery.h>
36#include <display_menu.h>
37#include <../../../app/aboot/mdtp.h>
38#include <platform/timer.h>
39#include "verifiedboot.h"
40#include <err.h>
Jiten Patel2cb89192018-08-22 12:51:47 +053041#include <target.h>
Monika Singh0b15c022019-04-10 15:24:20 +053042#include <libavb/avb_sha.h>
Monika Singh5e170362018-03-14 00:48:36 +053043
44#ifndef DTB_PAD_SIZE
45#define DTB_PAD_SIZE 2048
46#endif
47#define INTERMEDIATE_DIGEST_LENGTH 64
48#define MAX_PART_NAME_SIZE 10
Jiten Patel2cb89192018-08-22 12:51:47 +053049#define MAX_NUM_REQ_PARTITION 8
Monika Singh2c8de342018-09-03 20:36:15 +053050#define BOOT_HEADER_VERSION_ZERO 0
Monika Singh51876762019-05-22 18:47:22 +053051#define MAX_PROPERTY_SIZE 10
Jiten Patel2cb89192018-08-22 12:51:47 +053052
53char *avb_verify_partition_name[] = {
54 "boot",
55 "dtbo",
56 "vbmeta",
57 "recovery"
58};
Monika Singh5e170362018-03-14 00:48:36 +053059
60#ifndef MDTP_SUPPORT
61int mdtp_activated(bool * activated)
62{
63 return 0;
64}
65void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
66{
67 return;
68}
69#endif
70
71static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
72static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
73static const CHAR8 *Space = " ";
74#if !VERIFIED_BOOT_2
75static const CHAR8 *VerityMode = " androidboot.veritymode=";
76static struct verified_boot_verity_mode VbVm[] =
77{
78 {FALSE, "logging"},
79 {TRUE, "enforcing"},
80};
81#endif
82
83static struct verified_boot_state_name VbSn[] =
84{
85 {GREEN, "green"},
86 {ORANGE, "orange"},
87 {YELLOW, "yellow"},
88 {RED, "red"},
89};
90
91struct boolean_string
92{
93 BOOLEAN value;
94 CHAR8 *name;
95};
96
97static struct boolean_string BooleanString[] =
98{
99 {FALSE, "false"},
100 {TRUE, "true"}
101};
102
103
104typedef struct {
105 AvbOps *Ops;
106 AvbSlotVerifyData *SlotData;
107} VB2Data;
108
109UINT32 GetAVBVersion()
110{
111#if VERIFIED_BOOT_2
112 return 2;
113#elif VERIFIED_BOOT
114 return 1;
115#else
116 return 0;
117#endif
118}
119
120BOOLEAN VerifiedBootEnabled()
121{
122 return (GetAVBVersion() > NO_AVB);
123}
124
Monika Singh5e170362018-03-14 00:48:36 +0530125static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
126{
127 /* These checks are already done before calling auth remove from here */
128#if VERIFIED_BOOT || VERIFIED_BOOT_2
129 boot_verifier_init();
130#endif
131 return 0;
132}
133
Monika Singh5e170362018-03-14 00:48:36 +0530134static int HandleActiveSlotUnbootable()
135{
136 int curr_slot;
137 curr_slot = partition_find_active_slot();
138 partition_deactivate_slot(curr_slot);
139 partition_find_boot_slot();
140
141 // should not reach here
142 return ERROR;
143}
144
145/*
146 * Returns length = 0 when there is failure.
147 */
148uint32_t GetSystemPath(char **SysPath)
149{
150 INT32 Index;
151 UINT32 Lun;
152 CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
Monika Singh5e170362018-03-14 00:48:36 +0530153 CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
Monika Singh0f7bfc82018-04-16 23:14:29 +0530154 const char *current_slot_suffix;
155 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530156
157 *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
158 if (!*SysPath) {
159 dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
160 return 0;
161 }
162
Monika Singh87794672018-05-19 19:10:47 +0530163 strlcpy(PartitionName, "system", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530164 current_active_slot = partition_find_active_slot();
165 if (partition_multislot_is_supported()) {
166 if (current_active_slot == INVALID)
167 return 0;
168 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Monika Singh83dacd42018-05-16 12:13:37 +0530169 strlcat(PartitionName, current_slot_suffix, MAX_GPT_NAME_SIZE - 1);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530170 }
Monika Singh5e170362018-03-14 00:48:36 +0530171
172 Index = partition_get_index(PartitionName);
173 if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
174 dprintf(CRITICAL, "System partition does not exit\n");
175 free(*SysPath);
176 return 0;
177 }
178
179 Lun = partition_get_lun(Index);
180 if (platform_boot_dev_isemmc()) {
181 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
182 Index + 1);
183 } else {
184 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
185 LunCharMapping[Lun],
186 partition_get_index_in_lun(PartitionName, Lun));
187 }
188
189 dprintf(DEBUG, "System Path - %s \n", *SysPath);
190
191 return strlen(*SysPath);
192}
193
194static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
195{
196 INT32 SrcLen = strlen(Src);
197 CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
198
199 strlcat(Dst, Src, SrcLen);
200 Info->vbcmdline_filled_len += SrcLen;
201
202 return EFI_SUCCESS;
203}
204
205static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
206{
207 EFI_STATUS Status = EFI_SUCCESS;
208
209 if (GetAVBVersion() >= AVB_1) {
210 GUARD(Appendvbcmdline(Info, VerifiedState));
211 GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
212 }
213 GUARD(Appendvbcmdline(Info, KeymasterLoadState));
214 GUARD(Appendvbcmdline(Info, Space));
215 return EFI_SUCCESS;
216}
217
218static EFI_STATUS VBCommonInit(bootinfo *Info)
219{
220 EFI_STATUS Status = EFI_SUCCESS;
221
222 Info->boot_state = RED;
223
224 // FIXME: Add boot call
225 /* allocate VB command line*/
226 Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
227 if (Info->vbcmdline == NULL) {
228 dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
229 Status = EFI_OUT_OF_RESOURCES;
230 return Status;
231 }
232 Info->vbcmdline_len = 2*DTB_PAD_SIZE;
233 Info->vbcmdline_filled_len = 0;
234 Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
235
236 return Status;
237}
238
239#if VERIFIED_BOOT_2
240/* Disable for VB 2.0 as this path is never taken */
241static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
242{
243 return ERROR;
244}
245static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
246{
247 return ERROR;
248}
249#else
250static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
251{
252 EFI_STATUS Status = EFI_SUCCESS;
253
254 if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
255 /* fastboot boot option image already loaded */
256 return Status;
257 }
258
259 Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
260 (UINT32 *)&(Info->images[0].imgsize));
261 if (Status != EFI_SUCCESS) {
262 dprintf(CRITICAL,
263 "ERROR: Failed to load image from partition: %d\n", Status);
264 return EFI_LOAD_ERROR;
265 }
266 Info->num_loaded_images = 1;
267 Info->images[0].name = malloc(strlen(Info->pname) + 1);
Monika Singh96b97212018-04-13 18:27:55 +0530268 strlcpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
Monika Singh5e170362018-03-14 00:48:36 +0530269 return Status;
270}
271
272static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
273{
274 EFI_STATUS Status = EFI_SUCCESS;
275 CHAR8 StrPname[MAX_GPT_NAME_SIZE];
276 CHAR8 Pname[MAX_GPT_NAME_SIZE];
277 CHAR8 *SystemPath = NULL;
278 UINT32 SystemPathLen = 0;
279 device_info DevInfo_vb;
280
281 GUARD(VBCommonInit(Info));
282 GUARD(LoadImageNoAuth(Info));
283 boot_verifier_init();
284
285 // FIXME: INIT devinfo()
286 DevInfo_vb.is_unlocked = !is_device_locked();
287 DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
288
Monika Singh96b97212018-04-13 18:27:55 +0530289 strlcpy(StrPname, "/", strlen("/"));
Monika Singh87794672018-05-19 19:10:47 +0530290 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530291 if (Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530292 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530293 } else {
Monika Singh87794672018-05-19 19:10:47 +0530294 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530295 }
296
297 Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
298 Info->images[0].imgsize,
299 StrPname,
300 &Info->boot_state);
301 if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
302 dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
303 return Status;
304 }
305
306 set_os_version((unsigned char *)Info->images[0].image_buffer);
307 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
308 return EFI_LOAD_ERROR;
309
310 SystemPathLen = GetSystemPath(&SystemPath);
311 if (SystemPathLen == 0 || SystemPath == NULL) {
312 dprintf(CRITICAL, "GetSystemPath failed!\n");
313 return EFI_LOAD_ERROR;
314 }
315 GUARD(AppendVBCommonCmdLine(Info));
316 GUARD(Appendvbcmdline(Info, VerityMode));
317 GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
318 GUARD(Appendvbcmdline(Info, SystemPath));
319
320 Info->vb_data = NULL;
321 return Status;
322}
323#endif
324
325static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
326{
327 switch (Result) {
328 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
329 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
330 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
331 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
332 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
333 return FALSE;
334
335 case AVB_SLOT_VERIFY_RESULT_OK:
336 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
337 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
338 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
339 return TRUE;
340 }
341
342 return FALSE;
343}
344
345char *pname[] = {
346 "sbl1",
347 "rpm",
348 "tz",
349 "aboot",
350};
351
Jiten Patel2cb89192018-08-22 12:51:47 +0530352VOID AddRequestedPartition(CHAR8 **requestedpartititon, UINT32 index)
353{
354 UINTN i;
355 for (i = 0; i < MAX_NUM_REQ_PARTITION; i++) {
356 if (requestedpartititon[i] == NULL){
357 requestedpartititon[i] = avb_verify_partition_name[index];
358 break;
359 }
360 }
361}
362
Monika Singh51876762019-05-22 18:47:22 +0530363static UINT32 ParseBootSecurityLevel (const CHAR8 *BootSecurityLevel,
364 size_t BootSecurityLevelStrSize)
365{
366 UINT32 PatchLevelDate = 0;
367 UINT32 PatchLevelMonth = 0;
368 UINT32 PatchLevelYear = 0;
369 UINT32 SeparatorCount = 0;
370 UINT32 Count = 0;
371
372 /*Parse the value of security patch as per YYYY-MM-DD format*/
373 while (Count < BootSecurityLevelStrSize) {
374 if (BootSecurityLevel[Count] == '-') {
375 SeparatorCount++;
376 }
377 else if (SeparatorCount == 2) {
378 PatchLevelDate *= 10;
379 PatchLevelDate += (BootSecurityLevel[Count] - '0');
380 }
381 else if (SeparatorCount == 1) {
382 PatchLevelMonth *= 10;
383 PatchLevelMonth += (BootSecurityLevel[Count] - '0');
384 }
385 else if (SeparatorCount == 0) {
386 PatchLevelYear *= 10;
387 PatchLevelYear += (BootSecurityLevel[Count] - '0');
388 }
389 else {
390 return -1;
391 }
392 Count++;
393 }
394
395 PatchLevelDate = PatchLevelDate << 11;
396 PatchLevelYear = (PatchLevelYear - 2000) << 4;
397 return (PatchLevelDate | PatchLevelYear | PatchLevelMonth);
398}
399
Monika Singh0b15c022019-04-10 15:24:20 +0530400static VOID ComputeVbMetaDigest (AvbSlotVerifyData* SlotData, CHAR8* Digest) {
401 size_t Index;
402 AvbSHA256Ctx Ctx;
403 avb_sha256_init (&Ctx);
404 for (Index = 0; Index < SlotData->num_vbmeta_images; Index++) {
405 avb_sha256_update (&Ctx,
406 SlotData->vbmeta_images[Index].vbmeta_data,
407 SlotData->vbmeta_images[Index].vbmeta_size);
408 }
409 avb_memcpy (Digest, avb_sha256_final(&Ctx), AVB_SHA256_DIGEST_SIZE);
410}
411
Monika Singh5e170362018-03-14 00:48:36 +0530412static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
413{
414 EFI_STATUS Status = EFI_SUCCESS;
415 AvbSlotVerifyResult Result;
416 AvbSlotVerifyData *SlotData = NULL;
417 VB2Data *VBData = NULL;
418 AvbOpsUserData *UserData = NULL;
419 AvbOps *Ops = NULL;
420 CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
421 CHAR8 *SlotSuffix = NULL;
422 BOOLEAN AllowVerificationError = !is_device_locked();
423 BOOLEAN VerityEnforcing = is_verity_enforcing();
Jiten Patel2cb89192018-08-22 12:51:47 +0530424 CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
Monika Singh5e170362018-03-14 00:48:36 +0530425 const CHAR8 **RequestedPartition = NULL;
426 UINTN NumRequestedPartition = 0;
Monika Singh2c8de342018-09-03 20:36:15 +0530427 UINT32 HeaderVersion = 0;
Monika Singh5e170362018-03-14 00:48:36 +0530428 UINT32 ImageHdrSize = 0;
429 UINT32 imgsizeActual = 0;
430 VOID *image_buffer = NULL;
431 UINT32 imgsize = 0;
432 AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
433 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
434 AVB_SLOT_VERIFY_FLAGS_NONE;
435 AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
436 device_info DevInfo_vb;
Monika Singh0b15c022019-04-10 15:24:20 +0530437 CHAR8 Digest[AVB_SHA256_DIGEST_SIZE] = {0};
Monika Singh51876762019-05-22 18:47:22 +0530438 const CHAR8 *BootSecurityLevelStr = NULL;
439 size_t BootSecurityLevelStrSize = 0;
440 INT32 BootSecurityLevel = 0;
Monika Singh5e170362018-03-14 00:48:36 +0530441
Monika Singh2c8de342018-09-03 20:36:15 +0530442 HeaderVersion = Info->header_version;
Monika Singh5e170362018-03-14 00:48:36 +0530443 Info->boot_state = RED;
444 GUARD(VBCommonInit(Info));
445
446 UserData = avb_calloc(sizeof(AvbOpsUserData));
447 if (UserData == NULL) {
448 dprintf(CRITICAL,
449 "ERROR: Failed to allocate AvbOpsUserData\n");
450 Status = EFI_OUT_OF_RESOURCES;
451 goto out;
452 }
453
454 Ops = AvbOpsNew(UserData);
455 if (Ops == NULL) {
456 dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
457 Status = EFI_OUT_OF_RESOURCES;
458 goto out;
459 }
Monika Singh2c9d2b82018-05-01 12:24:59 +0530460 UserData->IsMultiSlot = Info->multi_slot_boot;
461
Monika Singh5e170362018-03-14 00:48:36 +0530462 if(Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530463 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530464 if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
465 dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
466 Status = EFI_INVALID_PARAMETER;
467 goto out;
468 }
469 SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
470 } else {
471 SlotSuffix = "\0";
472 }
473
Monika Singhed04a2c2019-05-08 16:18:19 +0530474 if((!Info->multi_slot_boot || target_dynamic_partition_supported())
475 && Info->bootinto_recovery) {
Jiten Patel2cb89192018-08-22 12:51:47 +0530476 AddRequestedPartition(RequestedPartitionAll, IMG_RECOVERY);
477 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530478 /* Add dtbo validation if target supports dtbo image generation and
479 dtbo is not included in recovery i.e. HEADER VERSION is 0 */
480 if (is_target_support_dtbo() && HeaderVersion == BOOT_HEADER_VERSION_ZERO) {
481 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
482 NumRequestedPartition += 1;
483 }
Monika Singh5e170362018-03-14 00:48:36 +0530484 } else {
Jiten Patel2cb89192018-08-22 12:51:47 +0530485 AddRequestedPartition(RequestedPartitionAll, IMG_BOOT);
486 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530487 if (is_target_support_dtbo()) {
488 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
489 NumRequestedPartition += 1;
490 }
Jiten Patel2cb89192018-08-22 12:51:47 +0530491 }
492
493 RequestedPartition = (const CHAR8 **)RequestedPartitionAll;
Monika Singh5e170362018-03-14 00:48:36 +0530494
Monika Singh5e170362018-03-14 00:48:36 +0530495 VerityFlags = VerityEnforcing ?
496 AVB_HASHTREE_ERROR_MODE_RESTART :
497 AVB_HASHTREE_ERROR_MODE_EIO;
498
499 Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
500 VerifyFlags, VerityFlags,
501 &SlotData);
502
503 if (AllowVerificationError && ResultShouldContinue(Result)) {
504 dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
505 "%s, continue boot\n",
506 avb_slot_verify_result_to_string(Result));
507 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
508 dprintf(CRITICAL,
509 "ERROR: Device State %s, AvbSlotVerify returned %s\n",
510 AllowVerificationError ? "Unlocked" : "Locked",
511 avb_slot_verify_result_to_string(Result));
512 Status = EFI_LOAD_ERROR;
513 Info->boot_state = RED;
514 goto out;
515 }
Monika Singh0f7bfc82018-04-16 23:14:29 +0530516 if (SlotData == NULL) {
517 Status = EFI_LOAD_ERROR;
518 Info->boot_state = RED;
519 goto out;
520 }
Monika Singh5e170362018-03-14 00:48:36 +0530521
522 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
523 dprintf(DEBUG, "Requested Partition: %s\n",
524 RequestedPartition[ReqIndex]);
525 for (UINTN loadedindex = 0;
526 loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
527 dprintf(DEBUG, "Loaded Partition: %s\n",
528 SlotData->loaded_partitions[loadedindex].partition_name);
Monika Singhcfa48842019-04-04 16:33:54 +0530529 UINTN PartIndex = Info->num_loaded_images;
Monika Singh87794672018-05-19 19:10:47 +0530530 if (!strncmp(((const char *)RequestedPartition[ReqIndex]),
531 SlotData->loaded_partitions[loadedindex].partition_name,MAX_GPT_NAME_SIZE))
532 {
Monika Singh5e170362018-03-14 00:48:36 +0530533 if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
534 dprintf(CRITICAL, "NumLoadedPartition"
535 "(%d) too large "
536 "max images(%d)\n",
537 Info->num_loaded_images,
538 ARRAY_SIZE(Info->images));
539 Status = EFI_LOAD_ERROR;
540 Info->boot_state = RED;
541 goto out;
542 }
Monika Singhcfa48842019-04-04 16:33:54 +0530543
544 if (!strncmp("boot", SlotData->loaded_partitions[loadedindex].partition_name, strlen("boot")))
545 PartIndex = IMG_BOOT;
546 else if (!strncmp("dtbo", SlotData->loaded_partitions[loadedindex].partition_name, strlen("dtbo")))
547 PartIndex = IMG_DTBO;
548 else if (!strncmp("recovery", SlotData->loaded_partitions[loadedindex].partition_name,
549 strlen("recovery")))
550 PartIndex = IMG_RECOVERY;
551 else
552 Info->num_loaded_images++;
553 Info->images[PartIndex].name =
554 SlotData->loaded_partitions[loadedindex].partition_name;
555 Info->images[PartIndex].image_buffer =
556 SlotData->loaded_partitions[loadedindex].data;
557 Info->images[PartIndex].imgsize =
558 SlotData->loaded_partitions[loadedindex].data_size;
Monika Singh5e170362018-03-14 00:48:36 +0530559 break;
560 }
561 }
562 }
563
564 if (Info->num_loaded_images < NumRequestedPartition) {
lijuang1f8c8322018-06-20 18:21:19 +0800565 dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %llu\n",Info->num_loaded_images, NumRequestedPartition);
Monika Singh5e170362018-03-14 00:48:36 +0530566 Status = EFI_LOAD_ERROR;
567 goto out;
568 }
569
570 dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
571
572 VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
573 if (VBData == NULL) {
574 dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
575 Status = EFI_OUT_OF_RESOURCES;
576 goto out;
577 }
578 VBData->Ops = Ops;
579 VBData->SlotData = SlotData;
580 Info->vb_data = (VOID *)VBData;
581
582 ImageHdrSize = get_page_size();
Monika Singhed04a2c2019-05-08 16:18:19 +0530583 GUARD_OUT(getimage(&image_buffer, &imgsize,((!Info->multi_slot_boot || target_dynamic_partition_supported()) && Info->bootinto_recovery) ? "recovery" : "boot") );
Monika Singh5e170362018-03-14 00:48:36 +0530584
585 Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
586 if (Status != EFI_SUCCESS) {
587 dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
588 goto out;
589 }
590
591 if (imgsizeActual > imgsize) {
592 Status = EFI_BUFFER_TOO_SMALL;
593 dprintf(CRITICAL,
594 "Boot size in vbmeta less than actual boot image size "
595 "flash corresponding vbmeta.img\n");
596 goto out;
597 }
598 if (AllowVerificationError) {
599 Info->boot_state = ORANGE;
600 } else {
601 if (UserData->IsUserKey) {
602 Info->boot_state = YELLOW;
603 } else {
604 Info->boot_state = GREEN;
605 }
606 }
607
608 /* command line */
609 GUARD_OUT(AppendVBCommonCmdLine(Info));
610 GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
611 DevInfo_vb.is_unlocked = !is_device_locked();
Monika Singh51876762019-05-22 18:47:22 +0530612
613 /* Send date value in security patch only when KM TA supports it and the
614 * property is available in vbmeta data, send the old value in other cases
615 */
616 BootSecurityLevelStr = avb_property_lookup (
617 SlotData->vbmeta_images[0].vbmeta_data,
618 SlotData->vbmeta_images[0].vbmeta_size,
619 "com.android.build.boot.security_patch",
620 0, &BootSecurityLevelStrSize);
621
622 if (BootSecurityLevelStr != NULL &&
623 BootSecurityLevelStrSize == MAX_PROPERTY_SIZE) {
624 BootSecurityLevel = ParseBootSecurityLevel (BootSecurityLevelStr,
625 BootSecurityLevelStrSize);
626 if (BootSecurityLevel < 0) {
627 dprintf (CRITICAL, "System security patch level format invalid\n");
628 Status = EFI_INVALID_PARAMETER;
629 goto out;
630 }
631 }
632
633 set_os_version_with_date(ADD_SALT_BUFF_OFFSET(Info->images[0].image_buffer), BootSecurityLevel);
Monika Singh5e170362018-03-14 00:48:36 +0530634 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
635 return EFI_LOAD_ERROR;
Monika Singh0b15c022019-04-10 15:24:20 +0530636
637 ComputeVbMetaDigest(SlotData, (CHAR8 *)&Digest);
638 GUARD_OUT(set_verified_boot_hash((const CHAR8 *)&Digest, sizeof(Digest)));
Monika Singh5e170362018-03-14 00:48:36 +0530639 dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
640 VbSn[Info->boot_state].name);
641
642out:
643 if (Status != EFI_SUCCESS) {
644 if (SlotData != NULL) {
645 avb_slot_verify_data_free(SlotData);
646 }
647 if (Ops != NULL) {
648 AvbOpsFree(Ops);
649 }
650 if (UserData != NULL) {
651 avb_free(UserData);
652 }
653 if (VBData != NULL) {
654 avb_free(VBData);
655 }
656 Info->boot_state = RED;
657 if(Info->multi_slot_boot) {
658 HandleActiveSlotUnbootable();
659 /* HandleActiveSlotUnbootable should have swapped slots and
660 * reboot the device. If no bootable slot found, enter fastboot */
661 dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
662 } else {
663 dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
664 }
665
666 }
667
668 dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
669 VbSn[Info->boot_state].name, Info->boot_state);
670 return Status;
671}
672
673static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
674{
675 EFI_STATUS Status = EFI_SUCCESS;
676 CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
677
678 if (GetAVBVersion() < AVB_1) {
679 return EFI_SUCCESS;
680 }
681
Monika Singh87794672018-05-19 19:10:47 +0530682 if (!strncmp(Info->pname, "boot", MAX_GPT_NAME_SIZE)) {
Monika Singh5e170362018-03-14 00:48:36 +0530683 Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
684 if (Status != EFI_SUCCESS) {
685 dprintf(DEBUG,
686 "No Ffbm cookie found, ignore: %d\n", Status);
687 ffbm_mode_string[0] = '\0';
688 }
689 }
690
691 dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
692 switch (Info->boot_state)
693 {
694 case RED:
Monika Singha3893622019-09-16 16:01:17 +0530695#if FBCON_DISPLAY_MSG
Monika Singh5e170362018-03-14 00:48:36 +0530696 display_bootverify_menu(DISPLAY_MENU_RED);
Monika Singha3893622019-09-16 16:01:17 +0530697 wait_for_users_action();
698#else
699 dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
700 "\nYour device will shutdown in 30s\n");
Monika Singh5e170362018-03-14 00:48:36 +0530701 udelay(30000000);
702 shutdown_device();
Monika Singha3893622019-09-16 16:01:17 +0530703#endif
Monika Singh5e170362018-03-14 00:48:36 +0530704 break;
705 case YELLOW:
Monika Singha3893622019-09-16 16:01:17 +0530706#if FBCON_DISPLAY_MSG
Monika Singh5e170362018-03-14 00:48:36 +0530707 display_bootverify_menu(DISPLAY_MENU_YELLOW);
Monika Singha3893622019-09-16 16:01:17 +0530708 wait_for_users_action();
Monika Singh5e170362018-03-14 00:48:36 +0530709 wait_for_users_action();
Monika Singha3893622019-09-16 16:01:17 +0530710#else
711 dprintf(INFO, "Your device has loaded a different operating system." \
712 "\nWait for 5 seconds before proceeding\n");
713 udelay(5000000);
714#endif
Monika Singh5e170362018-03-14 00:48:36 +0530715 break;
716 case ORANGE:
717 if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
718 dprintf(DEBUG, "Device will boot into FFBM mode\n");
719 } else {
Monika Singha3893622019-09-16 16:01:17 +0530720#if FBCON_DISPLAY_MSG
Monika Singh90cf4b12018-04-09 16:47:15 +0530721 display_bootverify_menu(DISPLAY_MENU_ORANGE);
Monika Singha3893622019-09-16 16:01:17 +0530722 wait_for_users_action();
723#else
724 dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
725 udelay(5000000);
726#endif
Monika Singh5e170362018-03-14 00:48:36 +0530727 }
728 break;
729 default:
730 break;
731 }
732 return EFI_SUCCESS;
733}
734
735EFI_STATUS load_image_and_auth(bootinfo *Info)
736{
737 EFI_STATUS Status = EFI_SUCCESS;
738 BOOLEAN MdtpActive = FALSE;
739 UINT32 AVBVersion = NO_AVB;
740 mdtp_ext_partition_verification_t ext_partition;
Monika Singh0f7bfc82018-04-16 23:14:29 +0530741 const char *current_slot_suffix;
742 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530743
744 if (Info == NULL) {
745 dprintf(CRITICAL, "Invalid parameter Info\n");
746 return EFI_INVALID_PARAMETER;
747 }
748
749 if (!Info->multi_slot_boot) {
750 if (Info->bootinto_recovery) {
751 dprintf(INFO, "Booting Into Recovery Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530752 strlcpy(Info->pname, "recovery", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530753 } else {
754 dprintf(INFO, "Booting Into Mission Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530755 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530756 }
757 } else {
Monika Singh87794672018-05-19 19:10:47 +0530758 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530759 current_active_slot = partition_find_active_slot();
760 if (current_active_slot != INVALID ) {
761 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
762 if (strlen(current_slot_suffix) == 0) {
763 dprintf(CRITICAL, "No bootable slot\n");
764 return EFI_LOAD_ERROR;
765 }
Monika Singh87794672018-05-19 19:10:47 +0530766 strlcat(Info->pname, current_slot_suffix, MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530767 }
Monika Singh5e170362018-03-14 00:48:36 +0530768 }
769
770 dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
771 BooleanString[Info->multi_slot_boot].name, Info->pname);
772
773 Status = mdtp_activated(&MdtpActive);
774 if (Status) {
775 dprintf(CRITICAL,
776 "Failed to get activation state for MDTP, "
777 "Status=%d."
778 " Considering MDTP as active and continuing \n",
779 Status);
780 if (Status != -1)
781 MdtpActive = TRUE;
782 }
783
784 AVBVersion = GetAVBVersion();
785 dprintf(DEBUG, "AVB version %d\n", AVBVersion);
786
787 /* Load and Authenticate */
788 switch (AVBVersion) {
789 case NO_AVB:
790 return LoadImageNoAuth(Info);
791 break;
792 case AVB_1:
793 Status = load_image_and_authVB1(Info);
794 break;
795 case AVB_2:
796 Status = load_image_and_authVB2(Info);
797 break;
798 default:
799 dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
800 Status = EFI_UNSUPPORTED;
801 }
802
803 // if MDTP is active Display Recovery UI
804 if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
805 //FIXME: Hard coded to BOOT
806 ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
807 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
808 ext_partition.page_size = get_page_size();
809 ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
810 ext_partition.image_size = Info->images[0].imgsize;
811 ext_partition.sig_avail = FALSE;
812 mdtp_fwlock_verify_lock(&ext_partition);
813 }
814
815 if (!is_device_locked() && Status != EFI_SUCCESS) {
816 dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
817 return Status;
818 }
819
820 DisplayVerifiedBootScreen(Info);
821
822 return Status;
823}
824
825#if VERIFIED_BOOT_2
826VOID free_verified_boot_resource(bootinfo *Info)
827{
828 dprintf(DEBUG, "free_verified_boot_resource\n");
829
830 if (Info == NULL) {
831 return;
832 }
833
834 VB2Data *VBData = Info->vb_data;
835 if (VBData != NULL) {
836 AvbOps *Ops = VBData->Ops;
837 if (Ops != NULL) {
838 if (Ops->user_data != NULL) {
839 avb_free(Ops->user_data);
840 }
841 AvbOpsFree(Ops);
842 }
843
844 AvbSlotVerifyData *SlotData = VBData->SlotData;
845 if (SlotData != NULL) {
846 avb_slot_verify_data_free(SlotData);
847 }
848 avb_free(VBData);
849 }
850
851 if (Info->vbcmdline != NULL) {
852 free(Info->vbcmdline);
853 }
854 return;
855}
856#else
857VOID free_verified_boot_resource(bootinfo *Info)
858{
859 return;
860}
861#endif