From: Ji Luo Date: Thu, 15 Aug 2019 12:53:53 +0000 (+0800) Subject: MA-15321-3 Support secure unlock feature X-Git-Tag: rel_imx_4.19.35_1.1.0~75 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=631149fc0fc8ce035311949db643c2708e41435a;p=u-boot.git MA-15321-3 Support secure unlock feature Decrypt and verify the secure credential in keymaster TA, unlock operation can only be allowed after secure credential verify pass. Since the mppubk can only be generated on hab closed imx8q, so secure unlock feature can only supported when hab is closed. Test: secure unlock credential verify on hab closed imx8mm_evk. Change-Id: I1ab5e24df28d1e75ff853de3adf29f34da1d0a71 Signed-off-by: Ji Luo --- diff --git a/drivers/fastboot/fb_fsl/fb_fsl_command.c b/drivers/fastboot/fb_fsl/fb_fsl_command.c index 7b033ba32a..c5b1e447f9 100755 --- a/drivers/fastboot/fb_fsl/fb_fsl_command.c +++ b/drivers/fastboot/fb_fsl/fb_fsl_command.c @@ -362,6 +362,21 @@ static FbLockState do_fastboot_unlock(bool force) if ((fastboot_lock_enable() == FASTBOOT_UL_ENABLE) || force) { printf("It is able to unlock device. %d\n",fastboot_lock_enable()); +#if defined(CONFIG_SECURE_UNLOCK) && defined(CONFIG_IMX_TRUSTY_OS) + if ((fastboot_bytes_received == 0) || !hab_is_enabled()) { + printf("No unlock credential found or hab is not closed!\n"); + return FASTBOOT_LOCK_ERROR; + } else { + char *serial = get_serial(); + status = trusty_verify_secure_unlock(fastboot_buf_addr, + fastboot_bytes_received, + serial, 16); + if (status < 0) { + printf("verify secure unlock credential fail due Trusty return %d\n", status); + return FASTBOOT_LOCK_ERROR; + } + } +#endif wipe_all_userdata(); status = fastboot_set_lock_stat(FASTBOOT_UNLOCK); if (status < 0) diff --git a/include/fsl_avb.h b/include/fsl_avb.h index abc751e68d..89396708c9 100644 --- a/include/fsl_avb.h +++ b/include/fsl_avb.h @@ -275,6 +275,9 @@ int avb_set_public_key(uint8_t *staged_buffer, uint32_t size); /* Get manufacture protection public key */ int fastboot_get_mppubk(uint8_t *staged_buffer, uint32_t *size); +/* Check if hab is closed. */ +bool hab_is_enabled(void); + /* Return if device is in spl recovery mode. */ bool is_spl_recovery(void); diff --git a/include/interface/keymaster/keymaster.h b/include/interface/keymaster/keymaster.h index 1b1fc63315..c98442d757 100644 --- a/include/interface/keymaster/keymaster.h +++ b/include/interface/keymaster/keymaster.h @@ -65,7 +65,8 @@ enum keymaster_command { KM_SET_PRODUCT_ID = (0x9000 << KEYMASTER_REQ_SHIFT), KM_SET_ATTESTATION_KEY_ENC = (0xa000 << KEYMASTER_REQ_SHIFT), KM_APPEND_ATTESTATION_CERT_CHAIN_ENC = (0xb000 << KEYMASTER_REQ_SHIFT), - KM_GET_MPPUBK = (0xc000 << KEYMASTER_REQ_SHIFT) + KM_GET_MPPUBK = (0xc000 << KEYMASTER_REQ_SHIFT), + KM_VERIFY_SECURE_UNLOCK = (0xd000 << KEYMASTER_REQ_SHIFT) }; typedef enum { @@ -223,6 +224,20 @@ struct km_get_mppubk_resp { uint8_t data[64]; } TRUSTY_ATTR_PACKED; +/** + * km_secure_unlock_data - represents the secure unlock data + * + * @serial_size: size of |serial_data| + * @serial_data: serial_data (serial number) + * @credential_size: size of |credential_data| + * @credential_data: credential data + */ +struct km_secure_unlock_data { + uint32_t serial_size; + const uint8_t *serial_data; + uint32_t credential_size; + const uint8_t *credential_data; +} TRUSTY_ATTR_PACKED; /** * km_set_ca_response_begin_req - starts the process to set the ATAP CA Response * diff --git a/include/trusty/keymaster.h b/include/trusty/keymaster.h index 6c8d2e94ae..3776dbc5a5 100644 --- a/include/trusty/keymaster.h +++ b/include/trusty/keymaster.h @@ -135,4 +135,16 @@ int trusty_set_product_id(const uint8_t *product_id, uint32_t size); */ int trusty_get_mppubk(uint8_t *mppubk, uint32_t* size); +/* trusty_verify_secure_unlock is called to the verify the secure unlock + * credential. + * + * @unlock_credential: Poniter to the unlock credential. + * @credential_size: credential size. + * @serial: serial number to verify. + * @serial_size: serial number size. + */ +int trusty_verify_secure_unlock(uint8_t *unlock_credential, + uint32_t credential_size, + uint8_t *serial, uint32_t serial_size); + #endif /* TRUSTY_KEYMASTER_H_ */ diff --git a/include/trusty/keymaster_serializable.h b/include/trusty/keymaster_serializable.h index 196e606fe8..a8295dffed 100644 --- a/include/trusty/keymaster_serializable.h +++ b/include/trusty/keymaster_serializable.h @@ -67,6 +67,14 @@ int km_boot_params_serialize(const struct km_boot_params *params, uint8_t **out, int km_attestation_data_serialize(const struct km_attestation_data *data, uint8_t **out, uint32_t *out_size); +/** + * Serializes a km_secure_unlock_data structure. On success, allocates |*out_size| + * bytes to |*out| and writes the serialized |data| to |*out|. Caller takes + * ownership of |*out|. Returns one of trusty_err. + */ +int km_secure_unlock_data_serialize(const struct km_secure_unlock_data *data, + uint8_t **out, uint32_t *out_size); + /** * Serializes a km_raw_buffer structure. On success, allocates |*out_size| * bytes to |*out| and writes the serialized |data| to |*out|. Caller takes diff --git a/lib/Kconfig b/lib/Kconfig index fde52077d6..7bf4f6eeec 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -246,6 +246,8 @@ config DUAL_BOOTLOADER config AT_AUTHENTICATE_UNLOCK bool "Enable authenticate unlock for Android Things devices" +config SECURE_UNLOCK + bool "Enable secure unlock for Android devices, it can only be enabled on HAB closed board" endmenu menu "Hashing Support" diff --git a/lib/avb/fsl/fsl_avbkey.c b/lib/avb/fsl/fsl_avbkey.c index b971530f60..2ba373e26c 100644 --- a/lib/avb/fsl/fsl_avbkey.c +++ b/lib/avb/fsl/fsl_avbkey.c @@ -1148,6 +1148,18 @@ extern struct imx_sec_config_fuse_t const imx_sec_config_fuse; /* Check hab status, this is basically copied from imx_hab_is_enabled() */ bool hab_is_enabled(void) { +#ifdef CONFIG_ARCH_IMX8 + sc_err_t err; + uint16_t lc; + + err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); + if (err != SC_ERR_NONE) { + printf("Error in get lifecycle\n"); + return false; + } + + if (lc != 0x80) +#else struct imx_sec_config_fuse_t *fuse = (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; uint32_t reg; @@ -1155,11 +1167,15 @@ bool hab_is_enabled(void) ret = fuse_read(fuse->bank, fuse->word, ®); if (ret) { - puts("\nSecure boot fuse read error\n"); - return ret; + puts("\nSecure boot fuse read error!\n"); + return false; } - return (reg & HAB_ENABLED_BIT) == HAB_ENABLED_BIT; + if (!((reg & HAB_ENABLED_BIT) == HAB_ENABLED_BIT)) +#endif + return false; + else + return true; } int do_rpmb_key_set(uint8_t *key, uint32_t key_size) @@ -1297,23 +1313,11 @@ int avb_set_public_key(uint8_t *staged_buffer, uint32_t size) { int fastboot_get_mppubk(uint8_t *staged_buffer, uint32_t *size) { -#ifdef CONFIG_ARCH_IMX8 - sc_err_t err; - uint16_t lc; - - err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); - if (err != SC_ERR_NONE) { - printf("Error in get lifecycle\n"); - return -1; - } - - if (lc != 0x80) { -#else if (!hab_is_enabled()) { -#endif ERR("Error. This command can only be used when hab is closed!!\n"); return -1; } + if ((staged_buffer == NULL) || (size == NULL)) { ERR("Error. Get null staged_buffer!\n"); return -1; diff --git a/lib/trusty/ql-tipc/keymaster.c b/lib/trusty/ql-tipc/keymaster.c index 01828e0bd7..210420496f 100644 --- a/lib/trusty/ql-tipc/keymaster.c +++ b/lib/trusty/ql-tipc/keymaster.c @@ -523,3 +523,34 @@ int trusty_get_mppubk(uint8_t *mppubk, uint32_t *size) memcpy(mppubk, resp.data, resp.data_size); return TRUSTY_ERR_NONE; } + +int trusty_verify_secure_unlock(uint8_t *unlock_credential, + uint32_t credential_size, + uint8_t *serial, uint32_t serial_size) +{ + int rc = TRUSTY_ERR_GENERIC; + uint8_t *req = NULL; + uint32_t req_size = 0; + + struct km_secure_unlock_data secure_unlock_data = { + .serial_size = serial_size, + .serial_data = serial, + .credential_size = credential_size, + .credential_data = unlock_credential, + }; + + rc = km_secure_unlock_data_serialize(&secure_unlock_data, + &req, &req_size); + + if (rc < 0) { + trusty_error("failed (%d) to serialize request\n", rc); + goto end; + } + rc = km_do_tipc(KM_VERIFY_SECURE_UNLOCK, req, req_size, NULL, NULL); + +end: + if (req) { + trusty_free(req); + } + return rc; +} diff --git a/lib/trusty/ql-tipc/keymaster_serializable.c b/lib/trusty/ql-tipc/keymaster_serializable.c index 65bcca0545..6d9297d099 100644 --- a/lib/trusty/ql-tipc/keymaster_serializable.c +++ b/lib/trusty/ql-tipc/keymaster_serializable.c @@ -97,6 +97,27 @@ int km_attestation_data_serialize(const struct km_attestation_data *data, return TRUSTY_ERR_NONE; } +int km_secure_unlock_data_serialize(const struct km_secure_unlock_data *data, + uint8_t** out, uint32_t *out_size) +{ + uint8_t *tmp; + + if (!out || !data || !out_size) { + return TRUSTY_ERR_INVALID_ARGS; + } + *out_size = (sizeof(data->serial_size) + sizeof(data->credential_size) + + data->serial_size + data->credential_size); + *out = trusty_calloc(*out_size, 1); + if (!*out) { + return TRUSTY_ERR_NO_MEMORY; + } + + tmp = append_sized_buf_to_buf(*out, data->serial_data, data->serial_size); + tmp = append_sized_buf_to_buf(tmp, data->credential_data, data->credential_size); + + return TRUSTY_ERR_NONE; +} + int km_raw_buffer_serialize(const struct km_raw_buffer *buf, uint8_t** out, uint32_t *out_size) {