From cae5d25c4a4cbda2b47a5b6a14e70f36ba882dc8 Mon Sep 17 00:00:00 2001 From: j4nn <531585+j4nn@users.noreply.github.com> Date: Mon, 7 Sep 2020 23:03:10 +0200 Subject: [PATCH] hide sony bootloader unlock status in QSEE api call This patch forces bootloader unlock status returned from trust zone in sony proprietary api to be always as "locked". It does not fix kernel command line args that are set by verified bootloader with unlock related options and thus does not interfere with other android default verified boot policy. Instead it only fixes handling in original sony drm blobs that can be beneficial particularly if sony device (drm) key has been restored after unlock. Without this patch, following log can be observed: libdevice_security_static: get_rooting_status.cpp:80 rooting_status 2 With this patch, following is logged instead: libdevice_security_static: get_rooting_status.cpp:80 rooting_status 1 This patch has been tested in today's build of los 17.1 in both TA partition states, i.e. lost and restored device key. Please note also that the same api returns decrypted device key at offset 0x20 (16 bytes) if it has been restored in 66667 TA unit. If the device key has been lost and not restored, 16 zero bytes are returned at offset 0x20 instead. That means this way userspace proprietary libs may actually use the device key without directly reading it from the TA unit, if the still locked flag check is passed (just a theory without reverse engineering proof). Change-Id: I4cea5b666377d71fb63d985839d095aa4240fb44 --- drivers/misc/qseecom.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index c25eeeaac4e1a..304fb319e5ff4 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -3398,6 +3398,8 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, void *cmd_buf = NULL; size_t cmd_len; struct sglist_info *table = data->sglistinfo_ptr; + uint32_t *sb = NULL; + uint32_t *rb = NULL; reqd_len_sb_in = req->cmd_req_len + req->resp_len; /* find app_id & img_name from list */ @@ -3425,6 +3427,19 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, return -ENOENT; } + if (!memcmp(data->client.app_name, "tzxflattest", strlen("tzxflattest"))) + { + sb = (void *)__qseecom_uvirt_to_kvirt(data, + (uintptr_t)req->cmd_req_buf); + rb = (void *)__qseecom_uvirt_to_kvirt(data, + (uintptr_t)req->resp_buf); + if (sb != NULL) + if (sb[0] != 0x07 || sb[1] != 0x04) + sb = NULL; + if (sb == NULL) + rb = NULL; + } + if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_req.app_id = data->client.app_id; send_data_req.req_ptr = (uint32_t)(__qseecom_uvirt_to_kphys( @@ -3525,6 +3540,22 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, pr_err("cache operation failed %d\n", ret2); return ret2; } + + if (sb != NULL && rb != NULL) { + if (rb[0] == 0) { + if (strncmp((uint8_t *)rb + 0x31, + "HWC_Yoshino_Com_", 16) == 0) + { + ((uint8_t *)rb)[0x30] = 1; + // 0=not_allowed, 1=locked, 2=unlocked, + // 3=allowed_when_sl_is_unlocked, + // 4=allowed_since_sl_is_unlocked, + // 5=unsupported_bl_status->generic error + // (no info in security test screen "none") + } + } + } + return ret; }