Commit 60868c0f462162d8312ec71416174c9124c7ddec

Authored by Luo Ji
1 parent 1fb1eb7bea

MA-11626-1 [Android] Enable AVB only for legacy i.mx6/7

Enable AVB verify of boot/recovery for legacy(imx6/7)
on normal Android. A/B slot is not enabled on legacy
due to the limitation of storage capacity.

Change-Id: I7f636df6c82172d8a8d8588d45b385f32332a9cc
Signed-off-by: Luo Ji <ji.luo@nxp.com>

Showing 5 changed files with 147 additions and 18 deletions Side-by-side Diff

drivers/usb/gadget/f_fastboot.c
... ... @@ -93,8 +93,8 @@
93 93 */
94 94 static unsigned int download_size;
95 95 static unsigned int download_bytes;
96   -#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
97   -static bool is_recovery_mode;
  96 +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC)
  97 +static bool is_recovery_mode = false;
98 98 #endif
99 99  
100 100 /* common variables of fastboot getvar command */
... ... @@ -1474,9 +1474,6 @@
1474 1474 case BOOTMODE_FASTBOOT_BCB_CMD:
1475 1475 /* Make the boot into fastboot mode*/
1476 1476 puts("Fastboot: Got bootloader commands!\n");
1477   -#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
1478   - is_recovery_mode = false;
1479   -#endif
1480 1477 run_command("fastboot 0", 0);
1481 1478 break;
1482 1479 #ifdef CONFIG_ANDROID_RECOVERY
... ... @@ -1484,7 +1481,7 @@
1484 1481 case BOOTMODE_RECOVERY_KEY_PRESSED:
1485 1482 /* Make the boot into recovery mode */
1486 1483 puts("Fastboot: Got Recovery key pressing or recovery commands!\n");
1487   -#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
  1484 +#if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC)
1488 1485 is_recovery_mode = true;
1489 1486 #else
1490 1487 board_recovery_setup();
... ... @@ -1493,9 +1490,6 @@
1493 1490 #endif
1494 1491 default:
1495 1492 /* skip special mode boot*/
1496   -#ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
1497   - is_recovery_mode = false;
1498   -#endif
1499 1493 puts("Fastboot: Normal\n");
1500 1494 break;
1501 1495 }
... ... @@ -1538,8 +1532,6 @@
1538 1532 static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN);
1539 1533  
1540 1534 #if defined(CONFIG_AVB_SUPPORT) && defined(CONFIG_MMC)
1541   -/* we can use avb to verify Trusty if we want */
1542   -const char *requested_partitions[] = {"boot", 0};
1543 1535  
1544 1536 int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
1545 1537  
1546 1538  
... ... @@ -1568,9 +1560,25 @@
1568 1560 }
1569 1561 bool allow_fail = (lock_status == FASTBOOT_UNLOCK ? true : false);
1570 1562 avb_metric = get_timer(0);
1571   - /* if in lock state, do avb verify */
  1563 + /* For imx6 on Android, we don't have a/b slot and we want to verify
  1564 + * boot/recovery with AVB. For imx8 and Android Things we don't have
  1565 + * recovery and support a/b slot for boot */
  1566 +#ifdef CONFIG_ANDROID_AB_SUPPORT
  1567 + /* we can use avb to verify Trusty if we want */
  1568 + const char *requested_partitions[] = {"boot", 0};
1572 1569 avb_result = avb_ab_flow_fast(&fsl_avb_ab_ops, requested_partitions, allow_fail,
1573 1570 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_out_data);
  1571 +#else /* CONFIG_ANDROID_AB_SUPPORT */
  1572 + if (!is_recovery_mode) {
  1573 + const char *requested_partitions[] = {"boot", 0};
  1574 + avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail,
  1575 + AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data);
  1576 + } else {
  1577 + const char *requested_partitions[] = {"recovery", 0};
  1578 + avb_result = avb_single_flow(&fsl_avb_ab_ops, requested_partitions, allow_fail,
  1579 + AVB_HASHTREE_ERROR_MODE_RESTART, &avb_out_data);
  1580 + }
  1581 +#endif /* CONFIG_ANDROID_AB_SUPPORT */
1574 1582 /* get the duration of avb */
1575 1583 metrics.avb = get_timer(avb_metric);
1576 1584  
... ... @@ -1613,7 +1621,7 @@
1613 1621 else
1614 1622 fastboot_setup_system_boot_args(avb_out_data->ab_suffix, true);
1615 1623 }
1616   -#endif
  1624 +#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */
1617 1625 image_size = avb_loadpart->data_size;
1618 1626 #if defined (CONFIG_ARCH_IMX8) || defined (CONFIG_ARCH_IMX8M)
1619 1627 /* If we are using uncompressed kernel image, copy it directly to
... ... @@ -1652,7 +1660,17 @@
1652 1660 size_t num_read;
1653 1661 hdr = &boothdr;
1654 1662  
1655   - char bootimg[8];
  1663 + char bootimg[10];
  1664 + /* we don't have a/b slot for imx6 on normal Android*/
  1665 +#ifndef CONFIG_ANDROID_AB_SUPPORT
  1666 + char *slot = "";
  1667 + if (!is_recovery_mode) {
  1668 + sprintf(bootimg, "boot");
  1669 + } else {
  1670 + sprintf(bootimg, "recovery");
  1671 + }
  1672 + printf("boot '%s' still\n", bootimg);
  1673 +#else
1656 1674 char *slot = select_slot(&fsl_avb_ab_ops);
1657 1675 if (slot == NULL) {
1658 1676 printf("boota: no bootable slot\n");
... ... @@ -1660,6 +1678,7 @@
1660 1678 }
1661 1679 sprintf(bootimg, "boot%s", slot);
1662 1680 printf(" boot '%s' still\n", bootimg);
  1681 +#endif
1663 1682 /* maybe we should use bootctl to select a/b
1664 1683 * but libavb doesn't export a/b select */
1665 1684 if (fsl_avb_ops.read_from_partition(&fsl_avb_ops, bootimg,
... ... @@ -1710,7 +1729,6 @@
1710 1729 }
1711 1730 hdr = (struct andr_img_hdr *)(ulong)(hdr->kernel_addr - hdr->page_size);
1712 1731 #endif /* CONFIG_ARCH_IMX8 || CONFIG_ARCH_IMX8M */
1713   -
1714 1732 char bootargs_sec[ANDR_BOOT_ARGS_SIZE];
1715 1733 sprintf(bootargs_sec,
1716 1734 "androidboot.verifiedbootstate=orange androidboot.slot_suffix=%s", slot);
... ... @@ -1718,7 +1736,7 @@
1718 1736 #ifdef CONFIG_SYSTEM_RAMDISK_SUPPORT
1719 1737 if(!is_recovery_mode)
1720 1738 fastboot_setup_system_boot_args(slot, true);
1721   -#endif
  1739 +#endif /* CONFIG_SYSTEM_RAMDISK_SUPPORT */
1722 1740 #ifdef CONFIG_FASTBOOT_LOCK
1723 1741 }
1724 1742 #endif
include/fsl_fastboot.h
... ... @@ -42,6 +42,10 @@
42 42 #define FASTBOOT_PARTITION_TEE "tos"
43 43 #define FASTBOOT_PARTITION_PRDATA "presistdata"
44 44  
  45 +#ifdef CONFIG_AVB_SUPPORT
  46 +#define FASTBOOT_PARTITION_AVBKEY "avbkey"
  47 +#endif
  48 +
45 49 #ifdef CONFIG_ANDROID_AB_SUPPORT
46 50 #define FASTBOOT_PARTITION_BOOT_A "boot_a"
47 51 #define FASTBOOT_PARTITION_RECOVERY "recovery"
... ... @@ -53,7 +57,6 @@
53 57 #ifdef CONFIG_AVB_SUPPORT
54 58 #define FASTBOOT_PARTITION_VBMETA_A "vbmeta_a"
55 59 #define FASTBOOT_PARTITION_VBMETA_B "vbmeta_b"
56   -#define FASTBOOT_PARTITION_AVBKEY "avbkey"
57 60 #endif
58 61 #define FASTBOOT_PARTITION_MISC "misc"
59 62 #define FASTBOOT_PARTITION_GPT "gpt"
lib/avb/fsl/fsl_avbkey.c
... ... @@ -42,8 +42,12 @@
42 42 #define RESULT_ERROR -1
43 43 #define RESULT_OK 0
44 44  
45   -#ifndef CONFIG_FSL_CAAM_KB
  45 +#if !defined(CONFIG_FSL_CAAM_KB) || !defined(ANDROID_AB_SUPPORT)
46 46 /* ARM64 won't avbkey and rollback index in this stage directly. */
  47 +/* For legacy imx6/7, we won't enable A/B due to the limitation of
  48 + * storage capacity, but we still want to verify the boot/recovery
  49 + * with AVB. In this case, we won't check and store the rollback
  50 + * index. */
47 51 int avbkey_init(uint8_t *plainkey, uint32_t keylen) {
48 52 return 0;
49 53 }
lib/avb/libavb_ab/avb_ab_flow.c
... ... @@ -406,6 +406,103 @@
406 406 return ret;
407 407 }
408 408  
  409 +/* For legacy i.mx6/7, we won't enable A/B due to the limitation of
  410 + * storage capacity, but we still want to verify boot/recovery with
  411 + * AVB. */
  412 +AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
  413 + const char* const* requested_partitions,
  414 + AvbSlotVerifyFlags flags,
  415 + AvbHashtreeErrorMode hashtree_error_mode,
  416 + AvbSlotVerifyData** out_data) {
  417 + AvbOps* ops = ab_ops->ops;
  418 + AvbSlotVerifyData* slot_data = NULL;
  419 + AvbSlotVerifyData* data = NULL;
  420 + AvbABFlowResult ret;
  421 + bool saw_and_allowed_verification_error = false;
  422 +
  423 + /* Validate boot/recovery. */
  424 + AvbSlotVerifyResult verify_result;
  425 +
  426 + verify_result = avb_slot_verify(ops,
  427 + requested_partitions,
  428 + "",
  429 + flags,
  430 + hashtree_error_mode,
  431 + &slot_data);
  432 + switch (verify_result) {
  433 + case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
  434 + ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
  435 + goto out;
  436 +
  437 + case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
  438 + ret = AVB_AB_FLOW_RESULT_ERROR_IO;
  439 + goto out;
  440 +
  441 + case AVB_SLOT_VERIFY_RESULT_OK:
  442 + break;
  443 +
  444 + case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
  445 + case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
  446 + /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
  447 + * these mean game over.
  448 + */
  449 + ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
  450 + goto out;
  451 +
  452 + /* explicit fallthrough. */
  453 + case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
  454 + case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
  455 + case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
  456 + if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
  457 + /* Do nothing since we allow this. */
  458 + avb_debugv("Allowing slot ",
  459 + slot_suffixes[n],
  460 + " which verified "
  461 + "with result ",
  462 + avb_slot_verify_result_to_string(verify_result),
  463 + " because "
  464 + "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
  465 + "is set.\n",
  466 + NULL);
  467 + saw_and_allowed_verification_error = true;
  468 + } else {
  469 + ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
  470 + goto out;
  471 + }
  472 + break;
  473 +
  474 + case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
  475 + ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
  476 + goto out;
  477 + /* Do not add a 'default:' case here because of -Wswitch. */
  478 + }
  479 +
  480 + avb_assert(slot_data != NULL);
  481 + data = slot_data;
  482 + slot_data = NULL;
  483 + if (saw_and_allowed_verification_error) {
  484 + avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
  485 + ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
  486 + } else {
  487 + ret = AVB_AB_FLOW_RESULT_OK;
  488 + }
  489 +
  490 +out:
  491 + if (slot_data != NULL) {
  492 + avb_slot_verify_data_free(slot_data);
  493 + }
  494 +
  495 + if (out_data != NULL) {
  496 + *out_data = data;
  497 + } else {
  498 + if (data != NULL) {
  499 + avb_slot_verify_data_free(data);
  500 + }
  501 + }
  502 +
  503 + return ret;
  504 +}
  505 +
409 506 AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
410 507 const char* const* requested_partitions,
411 508 AvbSlotVerifyFlags flags,
lib/avb/libavb_ab/avb_ab_flow.h
... ... @@ -228,6 +228,13 @@
228 228 AvbSlotVerifyFlags flags,
229 229 AvbHashtreeErrorMode hashtree_error_mode,
230 230 AvbSlotVerifyData** out_data);
  231 +/* This is for legacy i.mx6/7 which don't enable A/B but want to
  232 + * verify boot/recovery with AVB */
  233 +AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
  234 + const char* const* requested_partitions,
  235 + AvbSlotVerifyFlags flags,
  236 + AvbHashtreeErrorMode hashtree_error_mode,
  237 + AvbSlotVerifyData** out_data);
231 238  
232 239 /* Marks the slot with the given slot number as active. Returns
233 240 * AVB_IO_RESULT_OK on success, error code otherwise.