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)
/* 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);
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 {
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
*
*/
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_ */
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
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"
/* 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;
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)
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;
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;
+}
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)
{