keystore2: transfer RootOfTrust from TEE to SB

Bug: 219076736
Test: manual, RoT between locally modified KeyMints
Change-Id: Iad3f14afc9d853e91cc7f7810fd6e592b48cab2d
diff --git a/keystore2/src/shared_secret_negotiation.rs b/keystore2/src/shared_secret_negotiation.rs
index 1862f73..42d38d2 100644
--- a/keystore2/src/shared_secret_negotiation.rs
+++ b/keystore2/src/shared_secret_negotiation.rs
@@ -15,6 +15,7 @@
 //! This module implements the shared secret negotiation.
 
 use crate::error::{map_binder_status, map_binder_status_code, Error};
+use crate::globals::get_keymint_device;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
 use android_hardware_security_keymint::binder::Strong;
 use android_hardware_security_sharedsecret::aidl::android::hardware::security::sharedsecret::{
@@ -43,6 +44,10 @@
         let connected = connect_participants(participants);
         negotiate_shared_secret(connected);
         log::info!("Shared secret negotiation concluded successfully.");
+
+        // Once shared secret negotiation is done, the StrongBox and TEE have a common key that
+        // can be used to authenticate a possible RootOfTrust transfer.
+        transfer_root_of_trust();
     });
 }
 
@@ -278,3 +283,48 @@
         }
     }
 }
+
+/// Perform RootOfTrust transfer from TEE to StrongBox (if available).
+pub fn transfer_root_of_trust() {
+    let strongbox = match get_keymint_device(&SecurityLevel::STRONGBOX) {
+        Ok((s, _, _)) => s,
+        Err(_e) => {
+            log::info!("No StrongBox Keymint available, so no RoT transfer");
+            return;
+        }
+    };
+    // Ask the StrongBox KeyMint for a challenge.
+    let challenge = match strongbox.getRootOfTrustChallenge() {
+        Ok(data) => data,
+        Err(e) => {
+            // If StrongBox doesn't provide a challenge, it might be because:
+            // - it already has RootOfTrust information
+            // - it's a KeyMint v1 implementation that doesn't understand the method.
+            // In either case, we're done.
+            log::info!("StrongBox does not provide a challenge, so no RoT transfer: {:?}", e);
+            return;
+        }
+    };
+    // Get the RoT info from the TEE
+    let tee = match get_keymint_device(&SecurityLevel::TRUSTED_ENVIRONMENT) {
+        Ok((s, _, _)) => s,
+        Err(e) => {
+            log::error!("No TEE KeyMint implementation found! {:?}", e);
+            return;
+        }
+    };
+    let root_of_trust = match tee.getRootOfTrust(&challenge) {
+        Ok(rot) => rot,
+        Err(e) => {
+            log::error!("TEE KeyMint failed to return RootOfTrust info: {:?}", e);
+            return;
+        }
+    };
+    // The RootOfTrust information is CBOR-serialized data, but we don't need to parse it.
+    // Just pass it on to the StrongBox KeyMint instance.
+    let result = strongbox.sendRootOfTrust(&root_of_trust);
+    if let Err(e) = result {
+        log::error!("Failed to send RootOfTrust to StrongBox: {:?}", e);
+    }
+    log::info!("RootOfTrust transfer process complete");
+}