Tidy and add trait smoke test

- Add a smoke test for the RKP trait.
- Drop some TODOs that aren't relevant
- Fix some clippy warnings.
- Convert some comments to doc comments.

Bug: 258069484
Test: libkmr_cf_test
Change-Id: Ic2f1c4db59462c8f0869332e85c1f861e5a39afb
diff --git a/common/src/crypto/ec.rs b/common/src/crypto/ec.rs
index bad05c6..ac6cae4 100644
--- a/common/src/crypto/ec.rs
+++ b/common/src/crypto/ec.rs
@@ -352,14 +352,15 @@
 /// Import an NIST EC key in SEC1 ECPrivateKey format.
 pub fn import_sec1_private_key(data: &[u8]) -> Result<KeyMaterial, Error> {
     let ec_key = sec1::EcPrivateKey::from_der(data)?;
-    let ec_parameters = ec_key.parameters.ok_or(km_err!(
-        InvalidArgument,
-        "sec1 formatted EC private key didn't have a parameters field"
-    ))?;
-    let parameters_oid = ec_parameters.named_curve().ok_or(km_err!(
-        InvalidArgument,
-        "couldn't retrieve parameters oid from sec1 ECPrivateKey formatted ec key parameters"
-    ))?;
+    let ec_parameters = ec_key.parameters.ok_or_else(|| {
+        km_err!(InvalidArgument, "sec1 formatted EC private key didn't have a parameters field")
+    })?;
+    let parameters_oid = ec_parameters.named_curve().ok_or_else(|| {
+        km_err!(
+            InvalidArgument,
+            "couldn't retrieve parameters oid from sec1 ECPrivateKey formatted ec key parameters"
+        )
+    })?;
     let algorithm =
         AlgorithmIdentifier { oid: X509_NIST_OID, parameters: Some(AnyRef::from(&parameters_oid)) };
     let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm, data);
diff --git a/ta/src/device.rs b/ta/src/device.rs
index 0e62897..410d02c 100644
--- a/ta/src/device.rs
+++ b/ta/src/device.rs
@@ -167,10 +167,9 @@
 /// implementation of IRemotelyProvisionedComponent (IRPC) HAL.
 /// Note: The devices only supporting IRPC V3+ may ignore the optional IRPC V2 specific types in
 /// the method signatures.
-/// TODO (b/258069484): Add smoke tests to this device trait.
 pub trait RetrieveRpcArtifacts {
-    // Retrieve secret bytes (of the given output length) derived from a hardware backed key.
-    // For a given context, the output is deterministic.
+    /// Retrieve secret bytes (of the given output length) derived from a hardware backed key.
+    /// For a given context, the output is deterministic.
     fn derive_bytes_from_hbk(
         &self,
         hkdf: &dyn crypto::Hkdf,
@@ -178,7 +177,7 @@
         output_len: usize,
     ) -> Result<Vec<u8>, Error>;
 
-    // Compute HMAC_SHA256 over the given input using a key derived from hardware.
+    /// Compute HMAC_SHA256 over the given input using a key derived from hardware.
     fn compute_hmac_sha256(
         &self,
         hmac: &dyn crypto::Hmac,
@@ -189,16 +188,16 @@
         crypto::hmac_sha256(hmac, &secret, input)
     }
 
-    // Retrieve the information about the DICE chain belonging to the IRPC HAL implementation.
+    /// Retrieve the information about the DICE chain belonging to the IRPC HAL implementation.
     fn get_dice_info(&self, test_mode: rpc::TestMode) -> Result<DiceInfo, Error>;
 
-    // Sign the input data with the CDI leaf private key of the IRPC HAL implementation. In IRPC V2,
-    // the `data` to be signed is the [`SignedMac_structure`] in ProtectedData.aidl, when signing
-    // the ephemeral MAC key used to authenticate the public keys. In IRPC V3, the `data` to be
-    // signed is the [`SignedDataSigStruct`].
-    // If a particular implementation would like to return the signature in a COSE_Sign1 message,
-    // they can mark this unimplemented and override the default implementation in the
-    // `sign_data_in_cose_sign1` method below.
+    /// Sign the input data with the CDI leaf private key of the IRPC HAL implementation. In IRPC V2,
+    /// the `data` to be signed is the [`SignedMac_structure`] in ProtectedData.aidl, when signing
+    /// the ephemeral MAC key used to authenticate the public keys. In IRPC V3, the `data` to be
+    /// signed is the [`SignedDataSigStruct`].
+    /// If a particular implementation would like to return the signature in a COSE_Sign1 message,
+    /// they can mark this unimplemented and override the default implementation in the
+    /// `sign_data_in_cose_sign1` method below.
     fn sign_data(
         &self,
         ec: &dyn crypto::Ec,
@@ -206,9 +205,9 @@
         rpc_v2: Option<RpcV2Req>,
     ) -> Result<Vec<u8>, Error>;
 
-    // Sign the payload and return a COSE_Sign1 message. In IRPC V2, the `payload` is the MAC Key.
-    // In IRPC V3, the `payload` is the `Data` that the `SignedData` is parameterized with (i.e. a
-    // CBOR array containing `challenge` and `CsrPayload`).
+    /// Sign the payload and return a COSE_Sign1 message. In IRPC V2, the `payload` is the MAC Key.
+    /// In IRPC V3, the `payload` is the `Data` that the `SignedData` is parameterized with (i.e. a
+    /// CBOR array containing `challenge` and `CsrPayload`).
     fn sign_data_in_cose_sign1(
         &self,
         ec: &dyn crypto::Ec,
diff --git a/ta/src/keys.rs b/ta/src/keys.rs
index e7bcef6..50418f7 100644
--- a/ta/src/keys.rs
+++ b/ta/src/keys.rs
@@ -501,7 +501,8 @@
             return Err(km_err!(InvalidArgument, "invalid version in Secure Key Wrapper."));
         }
 
-        // Decrypt the masked transport key.
+        // Decrypt the masked transport key, using an RSA key. (Only RSA wrapping keys are supported
+        // by the spec, as RSA is the only algorithm supporting asymmetric decryption.)
         let masked_transport_key = match key_material {
             KeyMaterial::Rsa(key) => {
                 // Check the requirements on the wrapping key characterisitcs
@@ -515,7 +516,6 @@
                 crypto_op.as_mut().update(secure_key_wrapper.encrypted_transport_key)?;
                 crypto_op.finish()?
             }
-            // TODO: For now, we consider wrapping keys to be RSA keys only.
             _ => {
                 return Err(km_err!(InvalidArgument, "invalid key algorithm for transport key"));
             }
diff --git a/ta/src/lib.rs b/ta/src/lib.rs
index c0a6f62..de047c7 100644
--- a/ta/src/lib.rs
+++ b/ta/src/lib.rs
@@ -106,12 +106,12 @@
     /// Attestation ID information, fixed forever for a device, but retrieved on first use.
     attestation_id_info: RefCell<Option<Rc<AttestationIdInfo>>>,
 
-    // Public DICE artifacts (UDS certs and the DICE chain) included in the certificate signing
-    // requests (CSR) and the algorithm used to sign the CSR for IRemotelyProvisionedComponent
-    // (IRPC) HAL. Fixed for a device. Retrieved on first use.
-    //
-    // Note: This information is cached only in the implementations of IRPC HAL V3 and
-    // IRPC HAL V2 in production mode.
+    /// Public DICE artifacts (UDS certs and the DICE chain) included in the certificate signing
+    /// requests (CSR) and the algorithm used to sign the CSR for IRemotelyProvisionedComponent
+    /// (IRPC) HAL. Fixed for a device. Retrieved on first use.
+    ///
+    /// Note: This information is cached only in the implementations of IRPC HAL V3 and
+    /// IRPC HAL V2 in production mode.
     dice_info: RefCell<Option<Rc<DiceInfo>>>,
 
     /// Whether the device is still in early-boot.
diff --git a/ta/src/rkp.rs b/ta/src/rkp.rs
index 5424463..cfb0b7d 100644
--- a/ta/src/rkp.rs
+++ b/ta/src/rkp.rs
@@ -186,7 +186,7 @@
             return Err(rpc_err!(Removed, "generate_cert_req is not supported in IRPC V3+ HAL."));
         }
         let _device_info = self.rpc_device_info()?;
-        Err(km_err!(Unimplemented, "TODO: GenerateCertificateRequest"))
+        Err(km_err!(Unimplemented, "GenerateCertificateRequest is only required for RKP before v3"))
     }
 
     pub(crate) fn generate_cert_req_v2(
diff --git a/tests/src/lib.rs b/tests/src/lib.rs
index acad50a..032fab9 100644
--- a/tests/src/lib.rs
+++ b/tests/src/lib.rs
@@ -7,7 +7,7 @@
 };
 use kmr_common::{keyblob, keyblob::SlotPurpose};
 use kmr_ta::device::{SigningAlgorithm, SigningKey, SigningKeyType};
-use kmr_wire::keymint::Digest;
+use kmr_wire::{keymint::Digest, rpc};
 use std::collections::HashMap;
 use x509_cert::der::{Decode, Encode};
 
@@ -576,3 +576,21 @@
         }
     }
 }
+
+/// Simple smoke test for an `RetrieveRpcArtifacts` trait implementation.
+pub fn test_retrieve_rpc_artifacts<T: kmr_ta::device::RetrieveRpcArtifacts>(
+    rpc: T,
+    hmac: &dyn Hmac,
+    hkdf: &dyn Hkdf,
+) {
+    assert!(rpc.get_dice_info(rpc::TestMode(false)).is_ok());
+
+    let context = b"abcdef";
+    let data1 = rpc.derive_bytes_from_hbk(hkdf, context, 16).expect("failed to derive from HBK");
+    let data2 = rpc.derive_bytes_from_hbk(hkdf, context, 16).expect("failed to derive from HBK");
+    assert_eq!(data1, data2, "derive_bytes_from_hbk() method should be deterministic");
+
+    let data1 = rpc.compute_hmac_sha256(hmac, hkdf, context).expect("failed to perform HMAC");
+    let data2 = rpc.compute_hmac_sha256(hmac, hkdf, context).expect("failed to perform HMAC");
+    assert_eq!(data1, data2, "compute_hmac_sha256() method should be deterministic");
+}