Implement a back-level KeyMint compatibility wrapper

 - Implement a general back-level KeyMint wrapper, which forwards
   requests to either a back-level real device, or an up-level
   software device. Keyblobs from the latter are given a marker
   prefix and an authentication suffix.
 - Add an FFI wrapper function to allow calculation of HMAC-SHA256,
   so this can be used to give an authenticated suffix to wrapped
   keyblobs.
 - Abstract out the decision process for whether emulation is required
   to a EmulationDetector trait, and provide implementations for
   KeyMint V1 and for a km_compat-wrapped Keymaster.
 - Impose the KeyMint V1 wrapper whenever the real device is detected to
   be a V1 implementation.
 - Add support to the IKeystoreCompatService for returning a device for
   SecurityLevel::SOFTWARE. This device will always be the most recent
   KeyMint version.
 - Clarify what level of IKeyMint implementation gets returned from
   the IKeystoreCompatService for the other security levels.
 - Add an inner function to the km_compat code to allow unit tests
   to still work.

Co-authored-by: Janis Danisevskis <jdanis@google.com>
Bug: 194358913
Test: CtsKeystoreTestCases on oriole/bramble/cuttlefish
Change-Id: I297e8ad1cf00fd15cd5358b2760cd2ca88f53abb
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
index 92da965..14bdf04 100644
--- a/keystore2/src/crypto/lib.rs
+++ b/keystore2/src/crypto/lib.rs
@@ -19,8 +19,8 @@
 pub mod zvec;
 pub use error::Error;
 use keystore2_crypto_bindgen::{
-    extractSubjectFromCertificate, generateKeyFromPassword, randomBytes, AES_gcm_decrypt,
-    AES_gcm_encrypt, ECDHComputeKey, ECKEYGenerateKey, ECKEYMarshalPrivateKey,
+    extractSubjectFromCertificate, generateKeyFromPassword, hmacSha256, randomBytes,
+    AES_gcm_decrypt, AES_gcm_encrypt, ECDHComputeKey, ECKEYGenerateKey, ECKEYMarshalPrivateKey,
     ECKEYParsePrivateKey, ECPOINTOct2Point, ECPOINTPoint2Oct, EC_KEY_free, EC_KEY_get0_public_key,
     EC_POINT_free, HKDFExpand, HKDFExtract, EC_KEY, EC_MAX_BYTES, EC_POINT, EVP_MAX_MD_SIZE,
 };
@@ -39,6 +39,8 @@
 pub const AES_128_KEY_LENGTH: usize = 16;
 /// Length of the expected salt for key from password generation.
 pub const SALT_LENGTH: usize = 16;
+/// Length of an HMAC-SHA256 tag in bytes.
+pub const HMAC_SHA256_LEN: usize = 32;
 
 /// Older versions of keystore produced IVs with four extra
 /// ignored zero bytes at the end; recognise and trim those.
@@ -72,6 +74,21 @@
     }
 }
 
+/// Perform HMAC-SHA256.
+pub fn hmac_sha256(key: &[u8], msg: &[u8]) -> Result<Vec<u8>, Error> {
+    let mut tag = vec![0; HMAC_SHA256_LEN];
+    // Safety: The first two pairs of arguments must point to const buffers with
+    // size given by the second arg of the pair.  The final pair of arguments
+    // must point to an output buffer with size given by the second arg of the
+    // pair.
+    match unsafe {
+        hmacSha256(key.as_ptr(), key.len(), msg.as_ptr(), msg.len(), tag.as_mut_ptr(), tag.len())
+    } {
+        true => Ok(tag),
+        false => Err(Error::HmacSha256Failed),
+    }
+}
+
 /// Uses AES GCM to decipher a message given an initialization vector, aead tag, and key.
 /// This function accepts 128 and 256-bit keys and uses AES128 and AES256 respectively based
 /// on the key length.
@@ -565,4 +582,18 @@
         assert_eq!(left_key, right_key);
         Ok(())
     }
+
+    #[test]
+    fn test_hmac_sha256() {
+        let key = b"This is the key";
+        let msg1 = b"This is a message";
+        let msg2 = b"This is another message";
+        let tag1a = hmac_sha256(key, msg1).unwrap();
+        assert_eq!(tag1a.len(), HMAC_SHA256_LEN);
+        let tag1b = hmac_sha256(key, msg1).unwrap();
+        assert_eq!(tag1a, tag1b);
+        let tag2 = hmac_sha256(key, msg2).unwrap();
+        assert_eq!(tag2.len(), HMAC_SHA256_LEN);
+        assert_ne!(tag1a, tag2);
+    }
 }