blob: 642747d28459778cc173057de03c5028f4c380ed [file] [log] [blame]
Monika Singh5e170362018-03-14 00:48:36 +05301/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#include "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
Jiten Patel2cb89192018-08-22 12:51:47 +053051
52char *avb_verify_partition_name[] = {
53 "boot",
54 "dtbo",
55 "vbmeta",
56 "recovery"
57};
Monika Singh5e170362018-03-14 00:48:36 +053058
59#ifndef MDTP_SUPPORT
60int mdtp_activated(bool * activated)
61{
62 return 0;
63}
64void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
65{
66 return;
67}
68#endif
69
70static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
71static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
72static const CHAR8 *Space = " ";
73#if !VERIFIED_BOOT_2
74static const CHAR8 *VerityMode = " androidboot.veritymode=";
75static struct verified_boot_verity_mode VbVm[] =
76{
77 {FALSE, "logging"},
78 {TRUE, "enforcing"},
79};
80#endif
81
82static struct verified_boot_state_name VbSn[] =
83{
84 {GREEN, "green"},
85 {ORANGE, "orange"},
86 {YELLOW, "yellow"},
87 {RED, "red"},
88};
89
90struct boolean_string
91{
92 BOOLEAN value;
93 CHAR8 *name;
94};
95
96static struct boolean_string BooleanString[] =
97{
98 {FALSE, "false"},
99 {TRUE, "true"}
100};
101
102
103typedef struct {
104 AvbOps *Ops;
105 AvbSlotVerifyData *SlotData;
106} VB2Data;
107
108UINT32 GetAVBVersion()
109{
110#if VERIFIED_BOOT_2
111 return 2;
112#elif VERIFIED_BOOT
113 return 1;
114#else
115 return 0;
116#endif
117}
118
119BOOLEAN VerifiedBootEnabled()
120{
121 return (GetAVBVersion() > NO_AVB);
122}
123
Monika Singh5e170362018-03-14 00:48:36 +0530124static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
125{
126 /* These checks are already done before calling auth remove from here */
127#if VERIFIED_BOOT || VERIFIED_BOOT_2
128 boot_verifier_init();
129#endif
130 return 0;
131}
132
Monika Singh5e170362018-03-14 00:48:36 +0530133static int HandleActiveSlotUnbootable()
134{
135 int curr_slot;
136 curr_slot = partition_find_active_slot();
137 partition_deactivate_slot(curr_slot);
138 partition_find_boot_slot();
139
140 // should not reach here
141 return ERROR;
142}
143
144/*
145 * Returns length = 0 when there is failure.
146 */
147uint32_t GetSystemPath(char **SysPath)
148{
149 INT32 Index;
150 UINT32 Lun;
151 CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
Monika Singh5e170362018-03-14 00:48:36 +0530152 CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
Monika Singh0f7bfc82018-04-16 23:14:29 +0530153 const char *current_slot_suffix;
154 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530155
156 *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
157 if (!*SysPath) {
158 dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
159 return 0;
160 }
161
Monika Singh87794672018-05-19 19:10:47 +0530162 strlcpy(PartitionName, "system", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530163 current_active_slot = partition_find_active_slot();
164 if (partition_multislot_is_supported()) {
165 if (current_active_slot == INVALID)
166 return 0;
167 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Monika Singh83dacd42018-05-16 12:13:37 +0530168 strlcat(PartitionName, current_slot_suffix, MAX_GPT_NAME_SIZE - 1);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530169 }
Monika Singh5e170362018-03-14 00:48:36 +0530170
171 Index = partition_get_index(PartitionName);
172 if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
173 dprintf(CRITICAL, "System partition does not exit\n");
174 free(*SysPath);
175 return 0;
176 }
177
178 Lun = partition_get_lun(Index);
179 if (platform_boot_dev_isemmc()) {
180 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
181 Index + 1);
182 } else {
183 snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
184 LunCharMapping[Lun],
185 partition_get_index_in_lun(PartitionName, Lun));
186 }
187
188 dprintf(DEBUG, "System Path - %s \n", *SysPath);
189
190 return strlen(*SysPath);
191}
192
193static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
194{
195 INT32 SrcLen = strlen(Src);
196 CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
197
198 strlcat(Dst, Src, SrcLen);
199 Info->vbcmdline_filled_len += SrcLen;
200
201 return EFI_SUCCESS;
202}
203
204static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
205{
206 EFI_STATUS Status = EFI_SUCCESS;
207
208 if (GetAVBVersion() >= AVB_1) {
209 GUARD(Appendvbcmdline(Info, VerifiedState));
210 GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
211 }
212 GUARD(Appendvbcmdline(Info, KeymasterLoadState));
213 GUARD(Appendvbcmdline(Info, Space));
214 return EFI_SUCCESS;
215}
216
217static EFI_STATUS VBCommonInit(bootinfo *Info)
218{
219 EFI_STATUS Status = EFI_SUCCESS;
220
221 Info->boot_state = RED;
222
223 // FIXME: Add boot call
224 /* allocate VB command line*/
225 Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
226 if (Info->vbcmdline == NULL) {
227 dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
228 Status = EFI_OUT_OF_RESOURCES;
229 return Status;
230 }
231 Info->vbcmdline_len = 2*DTB_PAD_SIZE;
232 Info->vbcmdline_filled_len = 0;
233 Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
234
235 return Status;
236}
237
238#if VERIFIED_BOOT_2
239/* Disable for VB 2.0 as this path is never taken */
240static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
241{
242 return ERROR;
243}
244static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
245{
246 return ERROR;
247}
248#else
249static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
250{
251 EFI_STATUS Status = EFI_SUCCESS;
252
253 if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
254 /* fastboot boot option image already loaded */
255 return Status;
256 }
257
258 Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
259 (UINT32 *)&(Info->images[0].imgsize));
260 if (Status != EFI_SUCCESS) {
261 dprintf(CRITICAL,
262 "ERROR: Failed to load image from partition: %d\n", Status);
263 return EFI_LOAD_ERROR;
264 }
265 Info->num_loaded_images = 1;
266 Info->images[0].name = malloc(strlen(Info->pname) + 1);
Monika Singh96b97212018-04-13 18:27:55 +0530267 strlcpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
Monika Singh5e170362018-03-14 00:48:36 +0530268 return Status;
269}
270
271static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
272{
273 EFI_STATUS Status = EFI_SUCCESS;
274 CHAR8 StrPname[MAX_GPT_NAME_SIZE];
275 CHAR8 Pname[MAX_GPT_NAME_SIZE];
276 CHAR8 *SystemPath = NULL;
277 UINT32 SystemPathLen = 0;
278 device_info DevInfo_vb;
279
280 GUARD(VBCommonInit(Info));
281 GUARD(LoadImageNoAuth(Info));
282 boot_verifier_init();
283
284 // FIXME: INIT devinfo()
285 DevInfo_vb.is_unlocked = !is_device_locked();
286 DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
287
Monika Singh96b97212018-04-13 18:27:55 +0530288 strlcpy(StrPname, "/", strlen("/"));
Monika Singh87794672018-05-19 19:10:47 +0530289 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530290 if (Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530291 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530292 } else {
Monika Singh87794672018-05-19 19:10:47 +0530293 strlcat(StrPname, Pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530294 }
295
296 Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
297 Info->images[0].imgsize,
298 StrPname,
299 &Info->boot_state);
300 if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
301 dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
302 return Status;
303 }
304
305 set_os_version((unsigned char *)Info->images[0].image_buffer);
306 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
307 return EFI_LOAD_ERROR;
308
309 SystemPathLen = GetSystemPath(&SystemPath);
310 if (SystemPathLen == 0 || SystemPath == NULL) {
311 dprintf(CRITICAL, "GetSystemPath failed!\n");
312 return EFI_LOAD_ERROR;
313 }
314 GUARD(AppendVBCommonCmdLine(Info));
315 GUARD(Appendvbcmdline(Info, VerityMode));
316 GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
317 GUARD(Appendvbcmdline(Info, SystemPath));
318
319 Info->vb_data = NULL;
320 return Status;
321}
322#endif
323
324static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
325{
326 switch (Result) {
327 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
328 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
329 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
330 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
331 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
332 return FALSE;
333
334 case AVB_SLOT_VERIFY_RESULT_OK:
335 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
336 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
337 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
338 return TRUE;
339 }
340
341 return FALSE;
342}
343
344char *pname[] = {
345 "sbl1",
346 "rpm",
347 "tz",
348 "aboot",
349};
350
Jiten Patel2cb89192018-08-22 12:51:47 +0530351VOID AddRequestedPartition(CHAR8 **requestedpartititon, UINT32 index)
352{
353 UINTN i;
354 for (i = 0; i < MAX_NUM_REQ_PARTITION; i++) {
355 if (requestedpartititon[i] == NULL){
356 requestedpartititon[i] = avb_verify_partition_name[index];
357 break;
358 }
359 }
360}
361
Monika Singh0b15c022019-04-10 15:24:20 +0530362static VOID ComputeVbMetaDigest (AvbSlotVerifyData* SlotData, CHAR8* Digest) {
363 size_t Index;
364 AvbSHA256Ctx Ctx;
365 avb_sha256_init (&Ctx);
366 for (Index = 0; Index < SlotData->num_vbmeta_images; Index++) {
367 avb_sha256_update (&Ctx,
368 SlotData->vbmeta_images[Index].vbmeta_data,
369 SlotData->vbmeta_images[Index].vbmeta_size);
370 }
371 avb_memcpy (Digest, avb_sha256_final(&Ctx), AVB_SHA256_DIGEST_SIZE);
372}
373
Monika Singh5e170362018-03-14 00:48:36 +0530374static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
375{
376 EFI_STATUS Status = EFI_SUCCESS;
377 AvbSlotVerifyResult Result;
378 AvbSlotVerifyData *SlotData = NULL;
379 VB2Data *VBData = NULL;
380 AvbOpsUserData *UserData = NULL;
381 AvbOps *Ops = NULL;
382 CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
383 CHAR8 *SlotSuffix = NULL;
384 BOOLEAN AllowVerificationError = !is_device_locked();
385 BOOLEAN VerityEnforcing = is_verity_enforcing();
Jiten Patel2cb89192018-08-22 12:51:47 +0530386 CHAR8 *RequestedPartitionAll[MAX_NUM_REQ_PARTITION] = {NULL};
Monika Singh5e170362018-03-14 00:48:36 +0530387 const CHAR8 **RequestedPartition = NULL;
388 UINTN NumRequestedPartition = 0;
Monika Singh2c8de342018-09-03 20:36:15 +0530389 UINT32 HeaderVersion = 0;
Monika Singh5e170362018-03-14 00:48:36 +0530390 UINT32 ImageHdrSize = 0;
391 UINT32 imgsizeActual = 0;
392 VOID *image_buffer = NULL;
393 UINT32 imgsize = 0;
394 AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
395 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
396 AVB_SLOT_VERIFY_FLAGS_NONE;
397 AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
398 device_info DevInfo_vb;
Monika Singh0b15c022019-04-10 15:24:20 +0530399 CHAR8 Digest[AVB_SHA256_DIGEST_SIZE] = {0};
Monika Singh5e170362018-03-14 00:48:36 +0530400
Monika Singh2c8de342018-09-03 20:36:15 +0530401 HeaderVersion = Info->header_version;
Monika Singh5e170362018-03-14 00:48:36 +0530402 Info->boot_state = RED;
403 GUARD(VBCommonInit(Info));
404
405 UserData = avb_calloc(sizeof(AvbOpsUserData));
406 if (UserData == NULL) {
407 dprintf(CRITICAL,
408 "ERROR: Failed to allocate AvbOpsUserData\n");
409 Status = EFI_OUT_OF_RESOURCES;
410 goto out;
411 }
412
413 Ops = AvbOpsNew(UserData);
414 if (Ops == NULL) {
415 dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
416 Status = EFI_OUT_OF_RESOURCES;
417 goto out;
418 }
Monika Singh2c9d2b82018-05-01 12:24:59 +0530419 UserData->IsMultiSlot = Info->multi_slot_boot;
420
Monika Singh5e170362018-03-14 00:48:36 +0530421 if(Info->multi_slot_boot) {
Monika Singh87794672018-05-19 19:10:47 +0530422 strlcpy(Pname, Info->pname, MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530423 if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
424 dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
425 Status = EFI_INVALID_PARAMETER;
426 goto out;
427 }
428 SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
429 } else {
430 SlotSuffix = "\0";
431 }
432
Monika Singhed04a2c2019-05-08 16:18:19 +0530433 if((!Info->multi_slot_boot || target_dynamic_partition_supported())
434 && Info->bootinto_recovery) {
Jiten Patel2cb89192018-08-22 12:51:47 +0530435 AddRequestedPartition(RequestedPartitionAll, IMG_RECOVERY);
436 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530437 /* Add dtbo validation if target supports dtbo image generation and
438 dtbo is not included in recovery i.e. HEADER VERSION is 0 */
439 if (is_target_support_dtbo() && HeaderVersion == BOOT_HEADER_VERSION_ZERO) {
440 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
441 NumRequestedPartition += 1;
442 }
Monika Singh5e170362018-03-14 00:48:36 +0530443 } else {
Jiten Patel2cb89192018-08-22 12:51:47 +0530444 AddRequestedPartition(RequestedPartitionAll, IMG_BOOT);
445 NumRequestedPartition += 1;
Monika Singh2c8de342018-09-03 20:36:15 +0530446 if (is_target_support_dtbo()) {
447 AddRequestedPartition(RequestedPartitionAll, IMG_DTBO);
448 NumRequestedPartition += 1;
449 }
Jiten Patel2cb89192018-08-22 12:51:47 +0530450 }
451
452 RequestedPartition = (const CHAR8 **)RequestedPartitionAll;
Monika Singh5e170362018-03-14 00:48:36 +0530453
Monika Singh5e170362018-03-14 00:48:36 +0530454 VerityFlags = VerityEnforcing ?
455 AVB_HASHTREE_ERROR_MODE_RESTART :
456 AVB_HASHTREE_ERROR_MODE_EIO;
457
458 Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
459 VerifyFlags, VerityFlags,
460 &SlotData);
461
462 if (AllowVerificationError && ResultShouldContinue(Result)) {
463 dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
464 "%s, continue boot\n",
465 avb_slot_verify_result_to_string(Result));
466 } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
467 dprintf(CRITICAL,
468 "ERROR: Device State %s, AvbSlotVerify returned %s\n",
469 AllowVerificationError ? "Unlocked" : "Locked",
470 avb_slot_verify_result_to_string(Result));
471 Status = EFI_LOAD_ERROR;
472 Info->boot_state = RED;
473 goto out;
474 }
Monika Singh0f7bfc82018-04-16 23:14:29 +0530475 if (SlotData == NULL) {
476 Status = EFI_LOAD_ERROR;
477 Info->boot_state = RED;
478 goto out;
479 }
Monika Singh5e170362018-03-14 00:48:36 +0530480
481 for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
482 dprintf(DEBUG, "Requested Partition: %s\n",
483 RequestedPartition[ReqIndex]);
484 for (UINTN loadedindex = 0;
485 loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
486 dprintf(DEBUG, "Loaded Partition: %s\n",
487 SlotData->loaded_partitions[loadedindex].partition_name);
Monika Singhcfa48842019-04-04 16:33:54 +0530488 UINTN PartIndex = Info->num_loaded_images;
Monika Singh87794672018-05-19 19:10:47 +0530489 if (!strncmp(((const char *)RequestedPartition[ReqIndex]),
490 SlotData->loaded_partitions[loadedindex].partition_name,MAX_GPT_NAME_SIZE))
491 {
Monika Singh5e170362018-03-14 00:48:36 +0530492 if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
493 dprintf(CRITICAL, "NumLoadedPartition"
494 "(%d) too large "
495 "max images(%d)\n",
496 Info->num_loaded_images,
497 ARRAY_SIZE(Info->images));
498 Status = EFI_LOAD_ERROR;
499 Info->boot_state = RED;
500 goto out;
501 }
Monika Singhcfa48842019-04-04 16:33:54 +0530502
503 if (!strncmp("boot", SlotData->loaded_partitions[loadedindex].partition_name, strlen("boot")))
504 PartIndex = IMG_BOOT;
505 else if (!strncmp("dtbo", SlotData->loaded_partitions[loadedindex].partition_name, strlen("dtbo")))
506 PartIndex = IMG_DTBO;
507 else if (!strncmp("recovery", SlotData->loaded_partitions[loadedindex].partition_name,
508 strlen("recovery")))
509 PartIndex = IMG_RECOVERY;
510 else
511 Info->num_loaded_images++;
512 Info->images[PartIndex].name =
513 SlotData->loaded_partitions[loadedindex].partition_name;
514 Info->images[PartIndex].image_buffer =
515 SlotData->loaded_partitions[loadedindex].data;
516 Info->images[PartIndex].imgsize =
517 SlotData->loaded_partitions[loadedindex].data_size;
Monika Singh5e170362018-03-14 00:48:36 +0530518 break;
519 }
520 }
521 }
522
523 if (Info->num_loaded_images < NumRequestedPartition) {
lijuang1f8c8322018-06-20 18:21:19 +0800524 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 +0530525 Status = EFI_LOAD_ERROR;
526 goto out;
527 }
528
529 dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
530
531 VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
532 if (VBData == NULL) {
533 dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
534 Status = EFI_OUT_OF_RESOURCES;
535 goto out;
536 }
537 VBData->Ops = Ops;
538 VBData->SlotData = SlotData;
539 Info->vb_data = (VOID *)VBData;
540
541 ImageHdrSize = get_page_size();
Monika Singhed04a2c2019-05-08 16:18:19 +0530542 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 +0530543
544 Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
545 if (Status != EFI_SUCCESS) {
546 dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
547 goto out;
548 }
549
550 if (imgsizeActual > imgsize) {
551 Status = EFI_BUFFER_TOO_SMALL;
552 dprintf(CRITICAL,
553 "Boot size in vbmeta less than actual boot image size "
554 "flash corresponding vbmeta.img\n");
555 goto out;
556 }
557 if (AllowVerificationError) {
558 Info->boot_state = ORANGE;
559 } else {
560 if (UserData->IsUserKey) {
561 Info->boot_state = YELLOW;
562 } else {
563 Info->boot_state = GREEN;
564 }
565 }
566
567 /* command line */
568 GUARD_OUT(AppendVBCommonCmdLine(Info));
569 GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
570 DevInfo_vb.is_unlocked = !is_device_locked();
Monika Singh871d4b12018-10-08 00:06:18 +0530571 set_os_version(ADD_SALT_BUFF_OFFSET(Info->images[0].image_buffer));
Monika Singh5e170362018-03-14 00:48:36 +0530572 if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
573 return EFI_LOAD_ERROR;
Monika Singh0b15c022019-04-10 15:24:20 +0530574
575 ComputeVbMetaDigest(SlotData, (CHAR8 *)&Digest);
576 GUARD_OUT(set_verified_boot_hash((const CHAR8 *)&Digest, sizeof(Digest)));
Monika Singh5e170362018-03-14 00:48:36 +0530577 dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
578 VbSn[Info->boot_state].name);
579
580out:
581 if (Status != EFI_SUCCESS) {
582 if (SlotData != NULL) {
583 avb_slot_verify_data_free(SlotData);
584 }
585 if (Ops != NULL) {
586 AvbOpsFree(Ops);
587 }
588 if (UserData != NULL) {
589 avb_free(UserData);
590 }
591 if (VBData != NULL) {
592 avb_free(VBData);
593 }
594 Info->boot_state = RED;
595 if(Info->multi_slot_boot) {
596 HandleActiveSlotUnbootable();
597 /* HandleActiveSlotUnbootable should have swapped slots and
598 * reboot the device. If no bootable slot found, enter fastboot */
599 dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
600 } else {
601 dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
602 }
603
604 }
605
606 dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
607 VbSn[Info->boot_state].name, Info->boot_state);
608 return Status;
609}
610
611static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
612{
613 EFI_STATUS Status = EFI_SUCCESS;
614 CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
615
616 if (GetAVBVersion() < AVB_1) {
617 return EFI_SUCCESS;
618 }
619
Monika Singh87794672018-05-19 19:10:47 +0530620 if (!strncmp(Info->pname, "boot", MAX_GPT_NAME_SIZE)) {
Monika Singh5e170362018-03-14 00:48:36 +0530621 Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
622 if (Status != EFI_SUCCESS) {
623 dprintf(DEBUG,
624 "No Ffbm cookie found, ignore: %d\n", Status);
625 ffbm_mode_string[0] = '\0';
626 }
627 }
628
629 dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
630 switch (Info->boot_state)
631 {
632 case RED:
633 display_bootverify_menu(DISPLAY_MENU_RED);
634 //if (Status != EFI_SUCCESS) {
635 dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
636 "\nYour device will shutdown in 30s\n");
637 //}
638 udelay(30000000);
639 shutdown_device();
640 break;
641 case YELLOW:
642 display_bootverify_menu(DISPLAY_MENU_YELLOW);
643 //if (Status == EFI_SUCCESS) {
644 wait_for_users_action();
645 //} else {
646 dprintf(INFO, "Your device has loaded a different operating system." \
647 "\nWait for 5 seconds before proceeding\n");
648 udelay(5000000);
649 //}
650 break;
651 case ORANGE:
652 if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
653 dprintf(DEBUG, "Device will boot into FFBM mode\n");
654 } else {
Monika Singh90cf4b12018-04-09 16:47:15 +0530655 display_bootverify_menu(DISPLAY_MENU_ORANGE);
656 if (Status == EFI_SUCCESS) {
657 wait_for_users_action();
658 } else {
Monika Singh5e170362018-03-14 00:48:36 +0530659 dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
660 udelay(5000000);
Monika Singh90cf4b12018-04-09 16:47:15 +0530661 }
Monika Singh5e170362018-03-14 00:48:36 +0530662 }
663 break;
664 default:
665 break;
666 }
667 return EFI_SUCCESS;
668}
669
670EFI_STATUS load_image_and_auth(bootinfo *Info)
671{
672 EFI_STATUS Status = EFI_SUCCESS;
673 BOOLEAN MdtpActive = FALSE;
674 UINT32 AVBVersion = NO_AVB;
675 mdtp_ext_partition_verification_t ext_partition;
Monika Singh0f7bfc82018-04-16 23:14:29 +0530676 const char *current_slot_suffix;
677 int current_active_slot;
Monika Singh5e170362018-03-14 00:48:36 +0530678
679 if (Info == NULL) {
680 dprintf(CRITICAL, "Invalid parameter Info\n");
681 return EFI_INVALID_PARAMETER;
682 }
683
684 if (!Info->multi_slot_boot) {
685 if (Info->bootinto_recovery) {
686 dprintf(INFO, "Booting Into Recovery Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530687 strlcpy(Info->pname, "recovery", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530688 } else {
689 dprintf(INFO, "Booting Into Mission Mode\n");
Monika Singh87794672018-05-19 19:10:47 +0530690 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh5e170362018-03-14 00:48:36 +0530691 }
692 } else {
Monika Singh87794672018-05-19 19:10:47 +0530693 strlcpy(Info->pname, "boot", MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530694 current_active_slot = partition_find_active_slot();
695 if (current_active_slot != INVALID ) {
696 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
697 if (strlen(current_slot_suffix) == 0) {
698 dprintf(CRITICAL, "No bootable slot\n");
699 return EFI_LOAD_ERROR;
700 }
Monika Singh87794672018-05-19 19:10:47 +0530701 strlcat(Info->pname, current_slot_suffix, MAX_GPT_NAME_SIZE);
Monika Singh0f7bfc82018-04-16 23:14:29 +0530702 }
Monika Singh5e170362018-03-14 00:48:36 +0530703 }
704
705 dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
706 BooleanString[Info->multi_slot_boot].name, Info->pname);
707
708 Status = mdtp_activated(&MdtpActive);
709 if (Status) {
710 dprintf(CRITICAL,
711 "Failed to get activation state for MDTP, "
712 "Status=%d."
713 " Considering MDTP as active and continuing \n",
714 Status);
715 if (Status != -1)
716 MdtpActive = TRUE;
717 }
718
719 AVBVersion = GetAVBVersion();
720 dprintf(DEBUG, "AVB version %d\n", AVBVersion);
721
722 /* Load and Authenticate */
723 switch (AVBVersion) {
724 case NO_AVB:
725 return LoadImageNoAuth(Info);
726 break;
727 case AVB_1:
728 Status = load_image_and_authVB1(Info);
729 break;
730 case AVB_2:
731 Status = load_image_and_authVB2(Info);
732 break;
733 default:
734 dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
735 Status = EFI_UNSUPPORTED;
736 }
737
738 // if MDTP is active Display Recovery UI
739 if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
740 //FIXME: Hard coded to BOOT
741 ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
742 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
743 ext_partition.page_size = get_page_size();
744 ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
745 ext_partition.image_size = Info->images[0].imgsize;
746 ext_partition.sig_avail = FALSE;
747 mdtp_fwlock_verify_lock(&ext_partition);
748 }
749
750 if (!is_device_locked() && Status != EFI_SUCCESS) {
751 dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
752 return Status;
753 }
754
755 DisplayVerifiedBootScreen(Info);
756
757 return Status;
758}
759
760#if VERIFIED_BOOT_2
761VOID free_verified_boot_resource(bootinfo *Info)
762{
763 dprintf(DEBUG, "free_verified_boot_resource\n");
764
765 if (Info == NULL) {
766 return;
767 }
768
769 VB2Data *VBData = Info->vb_data;
770 if (VBData != NULL) {
771 AvbOps *Ops = VBData->Ops;
772 if (Ops != NULL) {
773 if (Ops->user_data != NULL) {
774 avb_free(Ops->user_data);
775 }
776 AvbOpsFree(Ops);
777 }
778
779 AvbSlotVerifyData *SlotData = VBData->SlotData;
780 if (SlotData != NULL) {
781 avb_slot_verify_data_free(SlotData);
782 }
783 avb_free(VBData);
784 }
785
786 if (Info->vbcmdline != NULL) {
787 free(Info->vbcmdline);
788 }
789 return;
790}
791#else
792VOID free_verified_boot_resource(bootinfo *Info)
793{
794 return;
795}
796#endif