Merge "Keystore 2.0: Minor update to pregenerated keymint rust bindings."
diff --git a/keystore/include/keystore/keystore.h b/keystore/include/keystore/keystore.h
index f840eb7..ab6c682 100644
--- a/keystore/include/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -59,7 +59,6 @@
     ABORT_CALLED = 18,
     PRUNED = 19,
     BINDER_DIED = 20,
-
 };
 
 /*
diff --git a/keystore/key_attestation_log_handler.h b/keystore/key_attestation_log_handler.h
index e69e667..a418bfa 100644
--- a/keystore/key_attestation_log_handler.h
+++ b/keystore/key_attestation_log_handler.h
@@ -23,4 +23,4 @@
 
 }
 
-#endif  //_KEY_ATTESTATION_LOG_HANDLER_H_
\ No newline at end of file
+#endif  //_KEY_ATTESTATION_LOG_HANDLER_H_
diff --git a/keystore/key_operation_log_handler.cpp b/keystore/key_operation_log_handler.cpp
index 140d5a7..e7f4345 100644
--- a/keystore/key_operation_log_handler.cpp
+++ b/keystore/key_operation_log_handler.cpp
@@ -133,4 +133,4 @@
         responseCode);
 }
 
-}  // namespace keystore
+}  // namespace keystore
\ No newline at end of file
diff --git a/keystore/key_operation_log_handler.h b/keystore/key_operation_log_handler.h
index efd3f00..ba27747 100644
--- a/keystore/key_operation_log_handler.h
+++ b/keystore/key_operation_log_handler.h
@@ -25,4 +25,4 @@
 
 }  // namespace keystore
 
-#endif  // KEY_OPERATION_LOG_HANDLER_H_
+#endif  // KEY_OPERATION_LOG_HANDLER_H_
\ No newline at end of file
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 75f2027..37adf04 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -42,10 +42,11 @@
 //! callbacks.
 
 use crate::error::Error as KsError;
+use crate::key_parameter::{KeyParameter, SqlField, TagType};
 use crate::{error, permission::KeyPermSet};
 use anyhow::{anyhow, Context, Result};
 
-use android_hardware_keymint::aidl::android::hardware::keymint::SecurityLevel::SecurityLevel;
+use android_hardware_keymint::aidl::android::hardware::keymint::SecurityLevel::SecurityLevel as SecurityLevelType;
 use android_security_keystore2::aidl::android::security::keystore2::{
     Domain, Domain::Domain as DomainType, KeyDescriptor::KeyDescriptor,
 };
@@ -98,8 +99,8 @@
     km_blob: Option<Vec<u8>>,
     cert: Option<Vec<u8>>,
     cert_chain: Option<Vec<u8>>,
-    sec_level: SecurityLevel,
-    //    parameters: Vec<KeyParameters>,
+    sec_level: SecurityLevelType,
+    parameters: Vec<KeyParameter>,
 }
 
 impl KeyEntry {
@@ -132,7 +133,7 @@
         self.cert_chain.take()
     }
     /// Returns the security level of the key entry.
-    pub fn sec_level(&self) -> SecurityLevel {
+    pub fn sec_level(&self) -> SecurityLevelType {
         self.sec_level
     }
 }
@@ -302,7 +303,7 @@
         key_id: i64,
         sc_type: SubComponentType,
         blob: &[u8],
-        sec_level: SecurityLevel,
+        sec_level: SecurityLevelType,
     ) -> Result<()> {
         self.conn
             .execute(
@@ -314,6 +315,29 @@
         Ok(())
     }
 
+    /// Inserts a collection of key parameters into the `persistent.keyparameter` table
+    /// and associates them with the given `key_id`.
+    pub fn insert_keyparameter<'a>(
+        &mut self,
+        key_id: i64,
+        params: impl IntoIterator<Item = &'a KeyParameter>,
+    ) -> Result<()> {
+        let mut stmt = self
+            .conn
+            .prepare(
+                "INSERT into persistent.keyparameter (keyentryid, tag, data, security_level)
+                    VALUES (?, ?, ?, ?);",
+            )
+            .context("In insert_keyparameter: Failed to prepare statement.")?;
+
+        let iter = params.into_iter();
+        for p in iter {
+            stmt.insert(params![key_id, p.get_tag(), p.key_parameter_value(), p.security_level()])
+                .with_context(|| format!("In insert_keyparameter: Failed to insert {:?}", p))?;
+        }
+        Ok(())
+    }
+
     /// Updates the alias column of the given key id `newid` with the given alias,
     /// and atomically, removes the alias, domain, and namespace from another row
     /// with the same alias-domain-namespace tuple if such row exits.
@@ -486,6 +510,79 @@
         }
     }
 
+    fn load_blob_components(
+        key_id: i64,
+        load_bits: KeyEntryLoadBits,
+        tx: &Transaction,
+    ) -> Result<(SecurityLevelType, Option<Vec<u8>>, Option<Vec<u8>>, Option<Vec<u8>>)> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT MAX(id), sec_level, subcomponent_type, blob FROM persistent.blobentry
+                    WHERE keyentryid = ? GROUP BY subcomponent_type;",
+            )
+            .context("In load_blob_components: prepare statement failed.")?;
+
+        let mut rows =
+            stmt.query(params![key_id]).context("In load_blob_components: query failed.")?;
+
+        let mut sec_level: SecurityLevelType = Default::default();
+        let mut km_blob: Option<Vec<u8>> = None;
+        let mut cert_blob: Option<Vec<u8>> = None;
+        let mut cert_chain_blob: Option<Vec<u8>> = None;
+        Self::with_rows_extract_all(&mut rows, |row| {
+            let sub_type: SubComponentType =
+                row.get(2).context("Failed to extract subcomponent_type.")?;
+            match (sub_type, load_bits.load_public()) {
+                (SubComponentType::KM_BLOB, _) => {
+                    sec_level = row.get(1).context("Failed to extract security level.")?;
+                    if load_bits.load_km() {
+                        km_blob = Some(row.get(3).context("Failed to extract KM blob.")?);
+                    }
+                }
+                (SubComponentType::CERT, true) => {
+                    cert_blob =
+                        Some(row.get(3).context("Failed to extract public certificate blob.")?);
+                }
+                (SubComponentType::CERT_CHAIN, true) => {
+                    cert_chain_blob =
+                        Some(row.get(3).context("Failed to extract certificate chain blob.")?);
+                }
+                (SubComponentType::CERT, _) | (SubComponentType::CERT_CHAIN, _) => {}
+                _ => Err(KsError::sys()).context("Unknown subcomponent type.")?,
+            }
+            Ok(())
+        })
+        .context("In load_blob_components.")?;
+
+        Ok((sec_level, km_blob, cert_blob, cert_chain_blob))
+    }
+
+    fn load_key_parameters(key_id: i64, tx: &Transaction) -> Result<Vec<KeyParameter>> {
+        let mut stmt = tx
+            .prepare(
+                "SELECT tag, data, security_level from persistent.keyparameter
+                    WHERE keyentryid = ?;",
+            )
+            .context("In load_key_parameters: prepare statement failed.")?;
+
+        let mut parameters: Vec<KeyParameter> = Vec::new();
+
+        let mut rows =
+            stmt.query(params![key_id]).context("In load_key_parameters: query failed.")?;
+        Self::with_rows_extract_all(&mut rows, |row| {
+            let tag: TagType = row.get(0).context("Failed to read tag.")?;
+            let sec_level: SecurityLevelType = row.get(2).context("Failed to read sec_level.")?;
+            parameters.push(
+                KeyParameter::new_from_sql(tag, &SqlField::new(1, &row), sec_level)
+                    .context("Failed to read KeyParameter.")?,
+            );
+            Ok(())
+        })
+        .context("In load_key_parameters.")?;
+
+        Ok(parameters)
+    }
+
     /// Load a key entry by the given key descriptor.
     /// It uses the `check_permission` callback to verify if the access is allowed
     /// given the key access tuple read from the database using `load_access_tuple`.
@@ -505,52 +602,27 @@
 
         // Load the key_id and complete the access control tuple.
         let (key_id, access_key_descriptor, access_vector) =
-            Self::load_access_tuple(&tx, key, caller_uid).context("In load_key_entry:")?;
+            Self::load_access_tuple(&tx, key, caller_uid).context("In load_key_entry.")?;
 
         // Perform access control. It is vital that we return here if the permission is denied.
         // So do not touch that '?' at the end.
-        check_permission(&access_key_descriptor, access_vector).context("In load_key_entry")?;
+        check_permission(&access_key_descriptor, access_vector).context("In load_key_entry.")?;
 
-        let mut result =
-            KeyEntry { id: key_id, km_blob: None, cert: None, cert_chain: None, sec_level: 0 };
+        let (sec_level, km_blob, cert_blob, cert_chain_blob) =
+            Self::load_blob_components(key_id, load_bits, &tx).context("In load_key_entry.")?;
 
-        let mut stmt = tx
-            .prepare(
-                "SELECT MAX(id), sec_level, subcomponent_type, blob FROM persistent.blobentry
-                    WHERE keyentryid = ? GROUP BY subcomponent_type;",
-            )
-            .context("In load_key_entry: blobentry: prepare statement failed.")?;
+        let parameters = Self::load_key_parameters(key_id, &tx).context("In load_key_entry.")?;
 
-        let mut rows =
-            stmt.query(params![key_id]).context("In load_key_entry: blobentry: query failed.")?;
-        Self::with_rows_extract_all(&mut rows, |row| {
-            let sub_type: SubComponentType =
-                row.get(2).context("Failed to extract subcomponent_type.")?;
-            match (sub_type, load_bits.load_public()) {
-                (SubComponentType::KM_BLOB, _) => {
-                    result.sec_level = row.get(1).context("Failed to extract security level.")?;
-                    if load_bits.load_km() {
-                        result.km_blob = Some(row.get(3).context("Failed to extract KM blob.")?);
-                    }
-                }
-                (SubComponentType::CERT, true) => {
-                    result.cert =
-                        Some(row.get(3).context("Failed to extract public certificate blob.")?);
-                }
-                (SubComponentType::CERT_CHAIN, true) => {
-                    result.cert_chain =
-                        Some(row.get(3).context("Failed to extract certificate chain blob.")?);
-                }
-                (SubComponentType::CERT, _) | (SubComponentType::CERT_CHAIN, _) => {}
-                _ => Err(KsError::sys()).context("Unknown subcomponent type.")?,
-            }
-            Ok(())
+        tx.commit().context("In load_key_entry: Failed to commit transaction.")?;
+
+        Ok(KeyEntry {
+            id: key_id,
+            km_blob,
+            cert: cert_blob,
+            cert_chain: cert_chain_blob,
+            sec_level,
+            parameters,
         })
-        .context("In load_key_entry")?;
-
-        // TODO load key parameters.
-
-        Ok(result)
     }
 
     /// Adds a grant to the grant table.
@@ -712,6 +784,10 @@
 mod tests {
 
     use super::*;
+    use crate::key_parameter::{
+        Algorithm, BlockMode, Digest, EcCurve, HardwareAuthenticatorType, KeyOrigin, KeyParameter,
+        KeyParameterValue, KeyPurpose, PaddingMode, SecurityLevel,
+    };
     use crate::key_perm_set;
     use crate::permission::{KeyPerm, KeyPermSet};
     use rusqlite::NO_PARAMS;
@@ -1088,6 +1164,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: 1,
+                parameters: make_test_params()
             }
         );
         Ok(())
@@ -1117,6 +1194,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: 1,
+                parameters: make_test_params()
             }
         );
         Ok(())
@@ -1141,6 +1219,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: 1,
+                parameters: make_test_params()
             }
         );
 
@@ -1182,6 +1261,7 @@
                 cert: Some(TEST_CERT_BLOB.to_vec()),
                 cert_chain: Some(TEST_CERT_CHAIN_BLOB.to_vec()),
                 sec_level: 1,
+                parameters: make_test_params()
             }
         );
         Ok(())
@@ -1229,6 +1309,228 @@
             .collect::<Result<Vec<_>>>()
     }
 
+    // Note: The parameters and SecurityLevel associations are nonsensical. This
+    // collection is only used to check if the parameters are preserved as expected by the
+    // database.
+    fn make_test_params() -> Vec<KeyParameter> {
+        vec![
+            KeyParameter::new(KeyParameterValue::Invalid, SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(
+                KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Algorithm(Algorithm::RSA),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::KeySize(1024), SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(
+                KeyParameterValue::BlockMode(BlockMode::ECB),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::BlockMode(BlockMode::GCM),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::Digest(Digest::NONE), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::MD5),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::SHA_2_224),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Digest(Digest::SHA_2_256),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::NONE),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_OAEP),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::PaddingMode(PaddingMode::RSA_PKCS1_1_5_SIGN),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(KeyParameterValue::MinMacLength(256), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_224),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::EcCurve(EcCurve::P_256), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_384),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::EcCurve(EcCurve::P_521),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::RSAPublicExponent(3),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::IncludeUniqueID,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::BootLoaderOnly, SecurityLevel::STRONGBOX),
+            KeyParameter::new(KeyParameterValue::RollbackResistance, SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::ActiveDateTime(1234567890),
+                SecurityLevel::STRONGBOX,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::OriginationExpireDateTime(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::UsageExpireDateTime(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MinSecondsBetweenOps(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MaxUsesPerBoot(1234567890),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::UserID(1), SecurityLevel::STRONGBOX),
+            KeyParameter::new(KeyParameterValue::UserSecureID(42), SecurityLevel::STRONGBOX),
+            KeyParameter::new(
+                KeyParameterValue::NoAuthRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType::PASSWORD),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::AuthTimeout(1234567890), SecurityLevel::SOFTWARE),
+            KeyParameter::new(KeyParameterValue::AllowWhileOnBody, SecurityLevel::SOFTWARE),
+            KeyParameter::new(
+                KeyParameterValue::TrustedUserPresenceRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::TrustedConfirmationRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::UnlockedDeviceRequired,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ApplicationID(vec![1u8, 2u8, 3u8, 4u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ApplicationData(vec![4u8, 3u8, 2u8, 1u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::CreationDateTime(12345677890),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::KeyOrigin(KeyOrigin::GENERATED),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::RootOfTrust(vec![3u8, 2u8, 1u8, 4u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(KeyParameterValue::OSVersion(1), SecurityLevel::TRUSTED_ENVIRONMENT),
+            KeyParameter::new(KeyParameterValue::OSPatchLevel(2), SecurityLevel::SOFTWARE),
+            KeyParameter::new(
+                KeyParameterValue::UniqueID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::SOFTWARE,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationChallenge(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationApplicationID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdBrand(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdDevice(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdProduct(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdSerial(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdIMEI(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdMEID(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdManufacturer(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AttestationIdModel(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::VendorPatchLevel(3),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::BootPatchLevel(4),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::AssociatedData(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::Nonce(vec![4u8, 3u8, 1u8, 2u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::MacLength(256),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ResetSinceIdRotation,
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+            KeyParameter::new(
+                KeyParameterValue::ConfirmationToken(vec![5u8, 5u8, 5u8, 5u8]),
+                SecurityLevel::TRUSTED_ENVIRONMENT,
+            ),
+        ]
+    }
+
     fn make_test_key_entry(
         db: &mut KeystoreDB,
         domain: DomainType,
@@ -1239,6 +1541,7 @@
         db.insert_blob(key_id, SubComponentType::KM_BLOB, TEST_KM_BLOB, 1)?;
         db.insert_blob(key_id, SubComponentType::CERT, TEST_CERT_BLOB, 1)?;
         db.insert_blob(key_id, SubComponentType::CERT_CHAIN, TEST_CERT_CHAIN_BLOB, 1)?;
+        db.insert_keyparameter(key_id, &make_test_params())?;
         db.rebind_alias(key_id, alias, domain, namespace)?;
         Ok(key_id)
     }
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
index 5266c28..ae3d774 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -33,6 +33,7 @@
 use rusqlite::{Result as SqlResult, Row};
 
 /// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
+#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub struct KeyParameter {
     key_parameter_value: KeyParameterValue,
     security_level: SecurityLevelType,
@@ -40,7 +41,7 @@
 
 /// KeyParameterValue holds a value corresponding to one of the Tags defined in
 /// the AIDL spec at hardware/interfaces/keymint
-#[derive(PartialEq, Debug)]
+#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum KeyParameterValue {
     /// Associated with Tag:INVALID
     Invalid,
@@ -238,7 +239,7 @@
 
 #[cfg(test)]
 mod basic_tests {
-    use crate::key_parameter::*;
+    use super::*;
 
     // Test basic functionality of KeyParameter.
     #[test]
@@ -265,6 +266,10 @@
 pub struct SqlField<'a>(usize, &'a Row<'a>);
 
 impl<'a> SqlField<'a> {
+    /// Creates a new SqlField with the given index and row.
+    pub fn new(index: usize, row: &'a Row<'a>) -> Self {
+        Self(index, row)
+    }
     /// Returns the column value from the row, when we know the expected type.
     pub fn get<T: FromSql>(&self) -> SqlResult<T> {
         self.1.get(self.0)