From aebefa8046bb01b9a4f0f86e2c34bec2847a287a Mon Sep 17 00:00:00 2001 From: Ji Luo Date: Sun, 26 Aug 2018 10:09:14 +0800 Subject: [PATCH] [iot] Support command 'oem at-disable-unlock-vboot' Device will be locked permanently after disabling the unlcok vboot, store the disable unlock vboot status into fuse. Since the fuse write operation is irreversible so config 'CONFIG_AVB_FUSE' is disabled by default, user need to add this config manually and run this command again. Test: Disable unlock vboot bit is set after enabling "CONFIG_AVB_FUSE", device was locked permanently after running this command. This is verified on both imx7d_pico and AIY. Change-Id: Iad8991a238763b1d662e33cba65f0b9eb44e97ef Signed-off-by: Ji Luo --- drivers/usb/gadget/f_fastboot.c | 41 ++++++++++++++++------ include/configs/imx8mq_evk_androidthings.h | 11 ++++-- include/configs/pico-imx7dandroidthings.h | 2 ++ include/fsl_avb.h | 5 +++ include/fsl_fastboot.h | 1 + lib/avb/fsl/fsl_avbkey.c | 41 +++++++++++++++++++++- 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 4a2cde2bfd..1374bbfcbd 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -3333,20 +3333,25 @@ static void cb_flashing(struct usb_ep *ep, struct usb_request *req) else strcpy(response, "OKAY"); } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) { + if (at_unlock_vboot_is_disabled()) { + printf("unlock vboot already disabled, can't unlock the device!\n"); + strcpy(response, "FAILunlock vboot already disabled!."); + } else { #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK - if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, - interface.transfer_buffer)) - strcpy(response, "FAILIncorrect unlock credential!"); - else { + if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, + interface.transfer_buffer)) + strcpy(response, "FAILIncorrect unlock credential!"); + else { #endif - status = do_fastboot_unlock(true); - if (status != FASTBOOT_LOCK_ERROR) - strcpy(response, "OKAY"); - else - strcpy(response, "FAILunlock device failed."); + status = do_fastboot_unlock(true); + if (status != FASTBOOT_LOCK_ERROR) + strcpy(response, "OKAY"); + else + strcpy(response, "FAILunlock device failed."); #ifdef CONFIG_AT_AUTHENTICATE_UNLOCK + } +#endif } -#endif } else if (endswith(cmd, FASTBOOT_AT_LOCK_VBOOT)) { if (perm_attr_are_fused()) { status = do_fastboot_lock(); @@ -3356,6 +3361,22 @@ static void cb_flashing(struct usb_ep *ep, struct usb_request *req) strcpy(response, "FAILlock device failed."); } else strcpy(response, "FAILpermanent attributes not fused!"); + } else if (endswith(cmd, FASTBOOT_AT_DISABLE_UNLOCK_VBOOT)) { + /* This command can only be called after 'oem at-lock-vboot' */ + status = fastboot_get_lock_stat(); + if (status == FASTBOOT_LOCK) { + if (at_unlock_vboot_is_disabled()) { + printf("unlock vboot already disabled!\n"); + strcpy(response, "OKAY"); + } + else { + if (!at_disable_vboot_unlock()) + strcpy(response, "OKAY"); + else + strcpy(response, "FAILdisable unlock vboot fail!"); + } + } else + strcpy(response, "FAILplease lock the device first!"); } #endif /* CONFIG_AVB_ATX */ #ifdef CONFIG_ANDROID_THINGS_SUPPORT diff --git a/include/configs/imx8mq_evk_androidthings.h b/include/configs/imx8mq_evk_androidthings.h index 184a9ed4b3..de00f44c2e 100644 --- a/include/configs/imx8mq_evk_androidthings.h +++ b/include/configs/imx8mq_evk_androidthings.h @@ -12,12 +12,17 @@ #define CONFIG_ANDROID_AB_SUPPORT #define CONFIG_SUPPORT_EMMC_RPMB #define CONFIG_SYSTEM_RAMDISK_SUPPORT -#define CONFIG_AVB_FUSE_BANK_SIZEW 0 -#define CONFIG_AVB_FUSE_BANK_START 0 -#define CONFIG_AVB_FUSE_BANK_END 0 +#define CONFIG_AVB_FUSE_BANK_SIZEW 4 +#define CONFIG_AVB_FUSE_BANK_START 14 +#define CONFIG_AVB_FUSE_BANK_END 14 #define CONFIG_FASTBOOT_LOCK #define FSL_FASTBOOT_FB_DEV "mmc" +#ifdef CONFIG_AVB_ATX +#define UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD 0 +#define UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT 0 +#endif + #define CONFIG_ENABLE_LOCKSTATUS_SUPPORT #ifdef CONFIG_SYS_MALLOC_LEN diff --git a/include/configs/pico-imx7dandroidthings.h b/include/configs/pico-imx7dandroidthings.h index f878f8f05c..d06e0c1305 100644 --- a/include/configs/pico-imx7dandroidthings.h +++ b/include/configs/pico-imx7dandroidthings.h @@ -19,6 +19,8 @@ #ifdef CONFIG_AVB_ATX #define PERMANENT_ATTRIBUTE_HASH_OFFSET 0 +#define UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD 3 +#define UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT 16 #endif #define AVB_RPMB diff --git a/include/fsl_avb.h b/include/fsl_avb.h index 1b8d5f9d01..90a84e0a08 100644 --- a/include/fsl_avb.h +++ b/include/fsl_avb.h @@ -260,4 +260,9 @@ int avb_atx_verify_unlock_credential(struct AvbAtxOps* atx_ops, /* Check if the perm-attr have been fused. */ bool perm_attr_are_fused(void); +/* Check if the unlock vboot is already disabled */ +bool at_unlock_vboot_is_disabled(void); + +/* disable at unlock vboot */ +int at_disable_vboot_unlock(void); #endif /* __FSL_AVB_H__ */ diff --git a/include/fsl_fastboot.h b/include/fsl_fastboot.h index 7ea2b5477f..0bec935839 100644 --- a/include/fsl_fastboot.h +++ b/include/fsl_fastboot.h @@ -98,6 +98,7 @@ #define FASTBOOT_AVB_AT_PERM_ATTR "fuse at-perm-attr" #define FASTBOOT_AT_UNLOCK_VBOOT "at-unlock-vboot" #define FASTBOOT_AT_LOCK_VBOOT "at-lock-vboot" +#define FASTBOOT_AT_DISABLE_UNLOCK_VBOOT "at-disable-unlock-vboot" #define FASTBOOT_AT_GET_UNLOCK_CHALLENGE "at-get-vboot-unlock-challenge" #endif /* CONFIG_AVB_ATX */ #endif /* CONFIG_ANDROID_THINGS_SUPPORT */ diff --git a/lib/avb/fsl/fsl_avbkey.c b/lib/avb/fsl/fsl_avbkey.c index 5ac88a3bb3..18fd9d36f5 100644 --- a/lib/avb/fsl/fsl_avbkey.c +++ b/lib/avb/fsl/fsl_avbkey.c @@ -48,7 +48,7 @@ #define RESULT_OK 0 #ifndef CONFIG_SPL_BUILD -#if defined(CONFIG_AVB_ATX) && !defined(CONFIG_ARM64) +#if defined(CONFIG_AVB_ATX) static int fsl_fuse_ops(uint32_t *buffer, uint32_t length, uint32_t offset, const uint8_t read) { @@ -300,6 +300,45 @@ bool perm_attr_are_fused(void) #endif } +bool at_unlock_vboot_is_disabled(void) +{ + uint32_t unlock_vboot_status; + + if (fsl_fuse_read(&unlock_vboot_status, 1, + UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) { + printf("Read at unlock vboot status error!\n"); + return false; + } + + if (unlock_vboot_status & (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT)) + return true; + else + return false; +} + +int at_disable_vboot_unlock(void) +{ + uint32_t unlock_vboot_status = 0; + + /* Read the status first */ + if (fsl_fuse_read(&unlock_vboot_status, 1, + UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) { + ERR("Read unlock vboot status error!\n"); + return -1; + } + + /* Set the disable unlock vboot bit */ + unlock_vboot_status |= (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT); + + /* Write disable unlock vboot bit to fuse */ + if (fsl_fuse_write(&unlock_vboot_status, 1, + UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) { + ERR("Write unlock vboot status fail!\n"); + return -1; + } + + return 0; +} /* Reads permanent |attributes| data. There are no restrictions on where this * data is stored. On success, returns AVB_IO_RESULT_OK and populates * |attributes|.