diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index e7a7b39..b3cdff7 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -3761,8 +3761,14 @@ static void cb_flashing(struct usb_ep *ep, struct usb_request *req) strcpy(response, "FAILset rpmb key failed!"); } else strcpy(response, "OKAY"); + } else if (endswith(cmd, FASTBOOT_SET_VBMETA_PUBLIC_KEY)) { + if (avb_set_public_key(interface.transfer_buffer, + download_bytes)) + strcpy(response, "FAILcan't set public key!"); + else + strcpy(response, "OKAY"); } -#endif +#endif /* CONFIG_ANDROID_AUTO_SUPPORT */ #endif /* CONFIG_IMX_TRUSTY_OS */ else if (endswith(cmd, "unlock_critical")) { strcpy(response, "OKAY"); diff --git a/include/fsl_avb.h b/include/fsl_avb.h index 90a84e0..c377d3a 100644 --- a/include/fsl_avb.h +++ b/include/fsl_avb.h @@ -265,4 +265,7 @@ bool at_unlock_vboot_is_disabled(void); /* disable at unlock vboot */ int at_disable_vboot_unlock(void); + +/* Set vbmeta public key */ +int avb_set_public_key(uint8_t *staged_buffer, uint32_t size); #endif /* __FSL_AVB_H__ */ diff --git a/include/fsl_fastboot.h b/include/fsl_fastboot.h index 0bec935..972b549 100644 --- a/include/fsl_fastboot.h +++ b/include/fsl_fastboot.h @@ -83,8 +83,11 @@ #define FASTBOOT_PARTITION_FBMISC "fbmisc" #endif +#ifdef CONFIG_IMX_TRUSTY_OS #ifdef CONFIG_ANDROID_AUTO_SUPPORT #define FASTBOOT_SET_RPMB_KEY "set-rpmb-key" +#define FASTBOOT_SET_VBMETA_PUBLIC_KEY "set-public-key" +#endif #endif #if defined(CONFIG_AVB_ATX) || defined(CONFIG_ANDROID_AUTO_SUPPORT) diff --git a/include/interface/avb/avb.h b/include/interface/avb/avb.h index 5ce338e..608f6af 100644 --- a/include/interface/avb/avb.h +++ b/include/interface/avb/avb.h @@ -42,6 +42,8 @@ enum avb_command { READ_LOCK_STATE = (5 << AVB_REQ_SHIFT), WRITE_LOCK_STATE = (6 << AVB_REQ_SHIFT), LOCK_BOOT_STATE = (7 << AVB_REQ_SHIFT), + READ_VBMETA_PUBLIC_KEY = (8 << AVB_REQ_SHIFT), + WRITE_VBMETA_PUBLIC_KEY = (9 << AVB_REQ_SHIFT), }; /** diff --git a/include/trusty/avb.h b/include/trusty/avb.h index f54a3ff..daaac2c 100644 --- a/include/trusty/avb.h +++ b/include/trusty/avb.h @@ -78,6 +78,24 @@ int trusty_read_permanent_attributes(uint8_t *attributes, uint32_t size); */ int trusty_write_permanent_attributes(uint8_t *attributes, uint32_t size); /* + * Send request to secure side to read vbmeta public key. + * + * Copies public key received by secure side to |publickey|. If |size| does not + * match the size returned by the secure side, an error is returned. Returns one + * of trusty_err. + * + * @publickey: caller allocated buffer + * @size: size of |publickey| + */ +int trusty_read_vbmeta_public_key(uint8_t *publickey, uint32_t size); +/* + * Send request to secure side to write vbmeta public key. Public key + * can only be written to storage once. + * + * Returns one of trusty_err. + */ +int trusty_write_vbmeta_public_key(uint8_t *publickey, uint32_t size); +/* * Send request to secure side to read device lock state from RPMB. * * Returns one of trusty_err. diff --git a/lib/avb/fsl/fsl_avb.c b/lib/avb/fsl/fsl_avb.c index ee9f34f..fce01fc 100644 --- a/lib/avb/fsl/fsl_avb.c +++ b/lib/avb/fsl/fsl_avb.c @@ -20,7 +20,7 @@ #include "fsl_atx_attributes.h" #define FSL_AVB_DEV "mmc" - +#define AVB_MAX_BUFFER_LENGTH 2048 static struct blk_desc *fs_dev_desc = NULL; static struct blk_desc *get_mmc_desc(void) { @@ -604,11 +604,27 @@ AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops, assert(ops != NULL && out_is_trusted != NULL); *out_is_trusted = false; +#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT) + uint8_t public_key_buf[AVB_MAX_BUFFER_LENGTH]; + if (trusty_read_vbmeta_public_key(public_key_buf, + public_key_length) != 0) { + ERR("Read public key error\n"); + /* We're not going to return error code here because it will + * abort the following avb verify process even we allow the + * verification error. Return AVB_IO_RESULT_OK and keep the + * 'out_is_trusted' as false, avb will handle the error + * depends on the 'allow_verification_error' flag. + */ + return AVB_IO_RESULT_OK; + } + + if (memcmp(public_key_buf, public_key_data, public_key_length)) { +#else /* match given public key */ if (memcmp(fsl_public_key, public_key_data, public_key_length)) { - ret = AVB_IO_RESULT_ERROR_IO; +#endif ERR("public key not match\n"); - return AVB_IO_RESULT_ERROR_IO; + return AVB_IO_RESULT_OK; } *out_is_trusted = true; diff --git a/lib/avb/fsl/fsl_avbkey.c b/lib/avb/fsl/fsl_avbkey.c index 890ff71..85428db 100644 --- a/lib/avb/fsl/fsl_avbkey.c +++ b/lib/avb/fsl/fsl_avbkey.c @@ -15,6 +15,7 @@ #include #include +#include "trusty/avb.h" #ifdef CONFIG_IMX_TRUSTY_OS #include #endif @@ -1127,5 +1128,20 @@ fail: return ret; } + +int avb_set_public_key(uint8_t *staged_buffer, uint32_t size) { + + if ((staged_buffer == NULL) || (size <= 0)) { + ERR("Error. Get null staged_buffer\n"); + return -1; + } + if (trusty_write_vbmeta_public_key(staged_buffer, size)) { + ERR("Error. Failed to write vbmeta public key into secure storage\n"); + return -1; + } else + printf("Set vbmeta public key successfully!\n"); + + return 0; +} #endif /* CONFIG_IMX_TRUSTY_OS && CONFIG_ANDROID_AUTO_SUPPORT */ #endif /* CONFIG_SPL_BUILD */ diff --git a/lib/trusty/ql-tipc/avb.c b/lib/trusty/ql-tipc/avb.c index 2f2a418..b8dab40 100644 --- a/lib/trusty/ql-tipc/avb.c +++ b/lib/trusty/ql-tipc/avb.c @@ -220,6 +220,29 @@ int trusty_write_permanent_attributes(uint8_t *attributes, uint32_t size) NULL); } +int trusty_read_vbmeta_public_key(uint8_t *publickey, uint32_t size) +{ + uint8_t resp_buf[AVB_MAX_BUFFER_LENGTH]; + uint32_t resp_size = AVB_MAX_BUFFER_LENGTH; + int rc = avb_do_tipc(READ_VBMETA_PUBLIC_KEY, NULL, 0, resp_buf, + &resp_size); + if (rc != 0) { + return rc; + } + /* ensure caller passed size matches size returned by Trusty */ + if (size != resp_size) { + return TRUSTY_ERR_INVALID_ARGS; + } + trusty_memcpy(publickey, resp_buf, resp_size); + return rc; +} + +int trusty_write_vbmeta_public_key(uint8_t *publickey, uint32_t size) +{ + return avb_do_tipc(WRITE_VBMETA_PUBLIC_KEY, publickey, size, NULL, + NULL); +} + int trusty_read_lock_state(uint8_t *lock_state) { uint32_t resp_size = sizeof(*lock_state);