Commit 60868c0f462162d8312ec71416174c9124c7ddec
1 parent
1fb1eb7bea
Exists in
smarc-imx_v2017.03_o8.1.0_1.3.0_8m
and in
1 other branch
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. |