[iot] Support fastboot variable 'at-vboot-state'
Add support for fastboot variable 'at-vboot-state', it's composed
by 6 sub-variable: 'bootloader-locked', 'bootloader-min-versions',
'avb-perm-attr-set', 'avb-locked', 'avb-unlock-disabled' and
'avb-min-versions'.
Test: All 'at-vboot-state' variables are returned
correctly on imx7d_pico and AIY.
Change-Id: Ibb855cbcc7c41657af62dafb98a96c4dfb96ef22
Signed-off-by: Ji Luo <ji.luo@nxp.com>
This commit is contained in:
parent
aebefa8046
commit
b57739cac7
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
#if defined(CONFIG_SECURE_BOOT)
|
#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_AVB_ATX)
|
||||||
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
|
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
|
||||||
.bank = 1,
|
.bank = 1,
|
||||||
.word = 3,
|
.word = 3,
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ static void isolate_resource(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SECURE_BOOT)
|
#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_AVB_ATX)
|
||||||
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
|
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
|
||||||
.bank = 1,
|
.bank = 1,
|
||||||
.word = 3,
|
.word = 3,
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ extern void trusty_os_init(void);
|
||||||
#ifdef CONFIG_ANDROID_THINGS_SUPPORT
|
#ifdef CONFIG_ANDROID_THINGS_SUPPORT
|
||||||
#include <asm-generic/gpio.h>
|
#include <asm-generic/gpio.h>
|
||||||
#include <asm/mach-imx/gpio.h>
|
#include <asm/mach-imx/gpio.h>
|
||||||
|
#include "../lib/avb/fsl/fsl_avbkey.h"
|
||||||
|
#include "../arch/arm/include/asm/mach-imx/hab.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FASTBOOT_VERSION "0.4"
|
#define FASTBOOT_VERSION "0.4"
|
||||||
|
|
@ -155,6 +157,22 @@ char *fastboot_common_var[FASTBOOT_COMMON_VAR_NUM] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* at-vboot-state variable list */
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
#define AT_VBOOT_STATE_VAR_NUM 6
|
||||||
|
extern struct imx_sec_config_fuse_t const imx_sec_config_fuse;
|
||||||
|
extern int fuse_read(u32 bank, u32 word, u32 *val);
|
||||||
|
|
||||||
|
char *fastboot_at_vboot_state_var[AT_VBOOT_STATE_VAR_NUM] = {
|
||||||
|
"bootloader-locked",
|
||||||
|
"bootloader-min-versions",
|
||||||
|
"avb-perm-attr-set",
|
||||||
|
"avb-locked",
|
||||||
|
"avb-unlock-disabled",
|
||||||
|
"avb-min-versions"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Boot metric variables */
|
/* Boot metric variables */
|
||||||
boot_metric metrics = {
|
boot_metric metrics = {
|
||||||
.bll_1 = 0,
|
.bll_1 = 0,
|
||||||
|
|
@ -2957,7 +2975,7 @@ int get_imx8m_baseboard_id(void);
|
||||||
static int get_single_var(char *cmd, char *response)
|
static int get_single_var(char *cmd, char *response)
|
||||||
{
|
{
|
||||||
char *str = cmd;
|
char *str = cmd;
|
||||||
size_t chars_left;
|
int chars_left;
|
||||||
const char *s;
|
const char *s;
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
int mmc_dev_no;
|
int mmc_dev_no;
|
||||||
|
|
@ -3085,6 +3103,138 @@ static int get_single_var(char *cmd, char *response)
|
||||||
} else
|
} else
|
||||||
snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id);
|
snprintf(response + strlen(response), chars_left, "0x%x", baseboard_id);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
else if (!strcmp_l1("bootloader-locked", cmd)) {
|
||||||
|
|
||||||
|
/* Below is basically copied from is_hab_enabled() */
|
||||||
|
struct imx_sec_config_fuse_t *fuse =
|
||||||
|
(struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
|
||||||
|
uint32_t reg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Read the secure boot status from fuse. */
|
||||||
|
ret = fuse_read(fuse->bank, fuse->word, ®);
|
||||||
|
if (ret) {
|
||||||
|
printf("\nSecure boot fuse read error!\n");
|
||||||
|
strncat(response, "Secure boot fuse read error!", chars_left);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Check if the secure boot bit is enabled */
|
||||||
|
if ((reg & 0x2000000) == 0x2000000)
|
||||||
|
strncat(response, "1", chars_left);
|
||||||
|
else
|
||||||
|
strncat(response, "0", chars_left);
|
||||||
|
} else if (!strcmp_l1("bootloader-min-versions", cmd)) {
|
||||||
|
#ifndef CONFIG_ARM64
|
||||||
|
/* We don't support bootloader rbindex protection for
|
||||||
|
* ARM32(like imx7d) and the format is: "bootloader,tee". */
|
||||||
|
strncat(response, "-1,-1", chars_left);
|
||||||
|
|
||||||
|
#elif defined(CONFIG_DUAL_BOOTLOADER)
|
||||||
|
/* Rbindex protection for bootloader is supported only when the
|
||||||
|
* 'dual bootloader' feature is enabled. U-boot will get the rbindx
|
||||||
|
* from RAM which is passed by spl because we can only get the rbindex
|
||||||
|
* at spl stage. The format in this case is: "spl,atf,tee,u-boot".
|
||||||
|
*/
|
||||||
|
struct bl_rbindex_package *bl_rbindex;
|
||||||
|
uint32_t rbindex;
|
||||||
|
|
||||||
|
bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR;
|
||||||
|
if (!strncmp(bl_rbindex->magic, BL_RBINDEX_MAGIC,
|
||||||
|
BL_RBINDEX_MAGIC_LEN)) {
|
||||||
|
rbindex = bl_rbindex->rbindex;
|
||||||
|
snprintf(response + strlen(response), chars_left,
|
||||||
|
"-1,%d,%d,%d",rbindex, rbindex, rbindex);
|
||||||
|
} else {
|
||||||
|
printf("Error bootloader rbindex magic!\n");
|
||||||
|
strncat(response, "Get bootloader rbindex fail!", chars_left);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Return -1 for all partition if 'dual bootloader' feature
|
||||||
|
* is not enabled */
|
||||||
|
strncat(response, "-1,-1,-1,-1", chars_left);
|
||||||
|
#endif
|
||||||
|
} else if (!strcmp_l1("avb-perm-attr-set", cmd)) {
|
||||||
|
if (perm_attr_are_fused())
|
||||||
|
strncat(response, "1", chars_left);
|
||||||
|
else
|
||||||
|
strncat(response, "0", chars_left);
|
||||||
|
} else if (!strcmp_l1("avb-locked", cmd)) {
|
||||||
|
FbLockState status;
|
||||||
|
|
||||||
|
status = fastboot_get_lock_stat();
|
||||||
|
if (status == FASTBOOT_LOCK)
|
||||||
|
strncat(response, "1", chars_left);
|
||||||
|
else if (status == FASTBOOT_UNLOCK)
|
||||||
|
strncat(response, "0", chars_left);
|
||||||
|
else {
|
||||||
|
printf("Get lock state error!\n");
|
||||||
|
strncat(response, "Get lock state failed!", chars_left);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (!strcmp_l1("avb-unlock-disabled", cmd)) {
|
||||||
|
if (at_unlock_vboot_is_disabled())
|
||||||
|
strncat(response, "1", chars_left);
|
||||||
|
else
|
||||||
|
strncat(response, "0", chars_left);
|
||||||
|
} else if (!strcmp_l1("avb-min-versions", cmd)) {
|
||||||
|
int i = 0;
|
||||||
|
/* rbindex location/value can be very large
|
||||||
|
* number so we reserve enough space here.
|
||||||
|
*/
|
||||||
|
char buffer[35];
|
||||||
|
uint32_t rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2];
|
||||||
|
uint32_t location;
|
||||||
|
uint64_t rbindex;
|
||||||
|
|
||||||
|
memset(buffer, '\0', sizeof(buffer));
|
||||||
|
|
||||||
|
/* Set rbindex locations. */
|
||||||
|
for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++)
|
||||||
|
rbindex_location[i] = i;
|
||||||
|
|
||||||
|
/* Set Android Things key version rbindex locations */
|
||||||
|
rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS]
|
||||||
|
= AVB_ATX_PIK_VERSION_LOCATION;
|
||||||
|
rbindex_location[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1]
|
||||||
|
= AVB_ATX_PSK_VERSION_LOCATION;
|
||||||
|
|
||||||
|
/* Read rollback index and set the reponse*/
|
||||||
|
for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 2; i++) {
|
||||||
|
location = rbindex_location[i];
|
||||||
|
if (fsl_avb_ops.read_rollback_index(&fsl_avb_ops,
|
||||||
|
location, &rbindex)
|
||||||
|
!= AVB_IO_RESULT_OK) {
|
||||||
|
printf("Read rollback index error!\n");
|
||||||
|
snprintf(response, sizeof(response),
|
||||||
|
"INFOread rollback index error when get avb-min-versions");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Generate the "location:value" pair */
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d:%lld", location, rbindex);
|
||||||
|
if (i != AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS + 1)
|
||||||
|
strncat(buffer, ",", strlen(","));
|
||||||
|
|
||||||
|
if ((chars_left - (int)strlen(buffer)) >= 0) {
|
||||||
|
strncat(response, buffer, strlen(buffer));
|
||||||
|
chars_left -= strlen(buffer);
|
||||||
|
} else {
|
||||||
|
strncat(response, buffer, chars_left);
|
||||||
|
/* reponse buffer is full, send it first */
|
||||||
|
fastboot_tx_write_more(response);
|
||||||
|
/* reset the reponse buffer for next round */
|
||||||
|
memset(response, '\0', sizeof(response));
|
||||||
|
strncpy(response, "INFO", 5);
|
||||||
|
/* Copy left strings from 'buffer' to 'response' */
|
||||||
|
strncat(response, buffer + chars_left, strlen(buffer));
|
||||||
|
chars_left = FASTBOOT_RESPONSE_LEN -
|
||||||
|
strlen(response) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
char envstr[32];
|
char envstr[32];
|
||||||
|
|
@ -3108,10 +3258,10 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char *cmd = req->buf;
|
char *cmd = req->buf;
|
||||||
char var_name[FASTBOOT_RESPONSE_LEN - 1];
|
char var_name[FASTBOOT_RESPONSE_LEN];
|
||||||
char partition_base_name[MAX_PTN][16];
|
char partition_base_name[MAX_PTN][16];
|
||||||
char slot_suffix[2][5] = {"a","b"};
|
char slot_suffix[2][5] = {"a","b"};
|
||||||
char response[FASTBOOT_RESPONSE_LEN - 1];
|
char response[FASTBOOT_RESPONSE_LEN];
|
||||||
|
|
||||||
strsep(&cmd, ":");
|
strsep(&cmd, ":");
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
|
|
@ -3122,7 +3272,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
|
||||||
|
|
||||||
if (!strcmp_l1("all", cmd)) {
|
if (!strcmp_l1("all", cmd)) {
|
||||||
|
|
||||||
memset(response, '\0', FASTBOOT_RESPONSE_LEN - 1);
|
memset(response, '\0', FASTBOOT_RESPONSE_LEN);
|
||||||
|
|
||||||
|
|
||||||
/* get common variables */
|
/* get common variables */
|
||||||
|
|
@ -3132,6 +3282,14 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
|
||||||
fastboot_tx_write_more(response);
|
fastboot_tx_write_more(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get at-vboot-state variables */
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) {
|
||||||
|
snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]);
|
||||||
|
get_single_var(fastboot_at_vboot_state_var[n], response);
|
||||||
|
fastboot_tx_write_more(response);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* get partition type */
|
/* get partition type */
|
||||||
for (n = 0; n < g_pcount; n++) {
|
for (n = 0; n < g_pcount; n++) {
|
||||||
snprintf(response, sizeof(response), "INFOpartition-type:%s:", g_ptable[n].name);
|
snprintf(response, sizeof(response), "INFOpartition-type:%s:", g_ptable[n].name);
|
||||||
|
|
@ -3191,7 +3349,35 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
|
||||||
fastboot_tx_write_more(response);
|
fastboot_tx_write_more(response);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
else if (!strcmp_l1("at-vboot-state", cmd)) {
|
||||||
|
/* get at-vboot-state variables */
|
||||||
|
for (n = 0; n < AT_VBOOT_STATE_VAR_NUM; n++) {
|
||||||
|
snprintf(response, sizeof(response), "INFO%s:", fastboot_at_vboot_state_var[n]);
|
||||||
|
get_single_var(fastboot_at_vboot_state_var[n], response);
|
||||||
|
fastboot_tx_write_more(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(response, "OKAY", 5);
|
||||||
|
fastboot_tx_write_more(response);
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if ((!strcmp_l1("bootloader-locked", cmd)) ||
|
||||||
|
(!strcmp_l1("bootloader-min-versions", cmd)) ||
|
||||||
|
(!strcmp_l1("avb-perm-attr-set", cmd)) ||
|
||||||
|
(!strcmp_l1("avb-locked", cmd)) ||
|
||||||
|
(!strcmp_l1("avb-unlock-disabled", cmd)) ||
|
||||||
|
(!strcmp_l1("avb-min-versions", cmd))) {
|
||||||
|
|
||||||
|
printf("Can't get this variable alone, get 'at-vboot-state' instead!\n");
|
||||||
|
snprintf(response, sizeof(response),
|
||||||
|
"FAILCan't get this variable alone, get 'at-vboot-state' instead.");
|
||||||
|
fastboot_tx_write_str(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
|
||||||
strncpy(response, "OKAY", 5);
|
strncpy(response, "OKAY", 5);
|
||||||
status = get_single_var(cmd, response);
|
status = get_single_var(cmd, response);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,13 @@
|
||||||
|
|
||||||
#define CONFIG_ANDROID_RECOVERY
|
#define CONFIG_ANDROID_RECOVERY
|
||||||
|
|
||||||
|
/* Use below address to store the bootloader rbindex,
|
||||||
|
* it's 4k offset to CONFIG_SYS_SPL_PTE_RAM_BASE
|
||||||
|
* */
|
||||||
|
#if defined(CONFIG_AVB_ATX) && defined(CONFIG_DUAL_BOOTLOADER)
|
||||||
|
#define BL_RBINDEX_LOAD_ADDR 0x4157F000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CONFIG_CMD_BOOTA
|
#define CONFIG_CMD_BOOTA
|
||||||
#define CONFIG_SUPPORT_RAW_INITRD
|
#define CONFIG_SUPPORT_RAW_INITRD
|
||||||
#define CONFIG_SERIAL_TAG
|
#define CONFIG_SERIAL_TAG
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,9 @@ static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot,
|
||||||
kblb_hdr_t hdr;
|
kblb_hdr_t hdr;
|
||||||
kblb_tag_t *rbk;
|
kblb_tag_t *rbk;
|
||||||
uint64_t extract_idx;
|
uint64_t extract_idx;
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
struct bl_rbindex_package *bl_rbindex;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Make sure rollback index has been initialized before verify */
|
/* Make sure rollback index has been initialized before verify */
|
||||||
if (rpmb_init()) {
|
if (rpmb_init()) {
|
||||||
|
|
@ -241,6 +244,16 @@ static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_AVB_ATX
|
||||||
|
/* Pass bootloader rbindex to u-boot here. */
|
||||||
|
bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR;
|
||||||
|
memcpy(bl_rbindex->magic, BL_RBINDEX_MAGIC, BL_RBINDEX_MAGIC_LEN);
|
||||||
|
if (slot->successful_boot != 0)
|
||||||
|
bl_rbindex->rbindex = spl_image->rbindex;
|
||||||
|
else
|
||||||
|
bl_rbindex->rbindex = extract_idx;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
printf("Rollback index verify rejected!\n");
|
printf("Rollback index verify rejected!\n");
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,15 @@
|
||||||
#define AVB_KBLB_MAGIC "\0KBLB!"
|
#define AVB_KBLB_MAGIC "\0KBLB!"
|
||||||
#define AVB_KBLB_MAGIC_LEN 6
|
#define AVB_KBLB_MAGIC_LEN 6
|
||||||
|
|
||||||
|
#if defined(CONFIG_AVB_ATX) && defined(CONFIG_DUAL_BOOTLOADER)
|
||||||
|
#define BL_RBINDEX_MAGIC "BL_RBINDEX"
|
||||||
|
#define BL_RBINDEX_MAGIC_LEN 11
|
||||||
|
struct bl_rbindex_package {
|
||||||
|
char magic[BL_RBINDEX_MAGIC_LEN];
|
||||||
|
uint32_t rbindex;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ANDROID_AUTO_SUPPORT
|
#ifdef CONFIG_ANDROID_AUTO_SUPPORT
|
||||||
#define RPMB_KEY_MAGIC "RPMB"
|
#define RPMB_KEY_MAGIC "RPMB"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue