app/aboot: platform/msm_shared: Add send rot command for sending Root of Trust
Verified boot update requires apps bootloader to send a binding
of device state and key used for signing as a Root of Trust to
trustzone.
Change-Id: Iec9dfbd1641803e6e58149674f5b1f9b27b84e72
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index d399afc..62675db 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -386,6 +386,98 @@
return dev_boot_state;
}
+bool send_rot_command()
+{
+ int ret = 0;
+ const unsigned char *input;
+ char *rot_input = NULL;
+ unsigned int digest[8];
+ uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
+ uint32_t boot_device_state = boot_verify_get_state();
+ uint32_t len = 0;
+ int app_handle = 0;
+ km_set_rot_req_t *read_req;
+ km_set_rot_rsp_t read_rsp;
+ app_handle = get_secapp_handle();
+ switch (boot_device_state)
+ {
+ case GREEN:
+ // Locked device and boot.img verified against OEM keystore.
+ // Send hash of OEM KEYSTORE + Boot device state
+ input = OEM_KEYSTORE;
+ len = read_der_message_length((unsigned char *)input) + sizeof(uint32_t);
+ if(!(rot_input = malloc(len)))
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
+ ASSERT(0);
+ }
+ snprintf(rot_input, len, "%s%ul", input, boot_device_state);
+ break;
+ case YELLOW:
+ case RED:
+ // Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
+ // Send hash of certificate + boot device state
+ if (rsa_from_cert)
+ len = RSA_size(rsa_from_cert);
+ else
+ {
+ dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
+ ASSERT(0);
+ }
+ hash_find((unsigned char *)rsa_from_cert, len, (unsigned char *) &digest, auth_algo);
+ len = sizeof(digest) + sizeof(unsigned int);
+ if(!(rot_input = malloc(len)))
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
+ ASSERT(0);
+ }
+ memcpy(rot_input, digest, sizeof(digest));
+ memcpy(rot_input + sizeof(digest), (unsigned char *) boot_device_state, sizeof(unsigned int));
+ break;
+ case ORANGE:
+ // Unlocked device and no verification done.
+ // Send the hash of boot device state
+ input = NULL;
+ len = sizeof(uint32_t);
+ if(!(rot_input = malloc(len)))
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
+ ASSERT(0);
+ }
+ snprintf(rot_input, len, "%ul", boot_device_state);
+ break;
+ }
+
+ hash_find((unsigned char *) rot_input, len, (unsigned char *)&digest, auth_algo);
+ if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(digest))))
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
+ ASSERT(0);
+ }
+
+ void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
+ // set ROT stucture
+ read_req->cmd_id = KEYMASTER_SET_ROT;
+ read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
+ read_req->rot_size = sizeof(digest);
+ // copy the digest
+ memcpy(cpy_ptr, (void *) &digest, sizeof(digest));
+ dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
+
+ ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(digest), (void*) &read_rsp, sizeof(read_rsp));
+ if (ret < 0 || read_rsp.status < 0)
+ {
+ dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
+ free(read_req);
+ free(rot_input);
+ return false;
+ }
+ dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
+ free(read_req);
+ free(rot_input);
+ return true;
+}
+
bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
{
bool ret = false;
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index 55f0d0a..bc61524 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -163,4 +163,6 @@
bool boot_verify_validate_keystore(unsigned char * user_addr);
/* Function to check if partition is allowed to flash in verified mode */
bool boot_verify_flash_allowed(const char * entry);
+/* Function to send root of trust to trust zone */
+bool send_rot_command();
#endif