Merge changes I4fae6a46,I60506ae1,I0c6fc14e

* changes:
  Implement authorize_update_or_finish.
  Definition and initialization of data structures for enforcements.
  Implement AuthTokenHandler enum.
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 4dd60bc..f9b320f 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -44,9 +44,9 @@
 //! from the database module these functions take permission check
 //! callbacks.
 
-use crate::db_utils;
+use crate::db_utils::{self, SqlField};
 use crate::error::{Error as KsError, ResponseCode};
-use crate::key_parameter::{KeyParameter, SqlField, Tag};
+use crate::key_parameter::{KeyParameter, Tag};
 use crate::permission::KeyPermSet;
 use anyhow::{anyhow, Context, Result};
 
diff --git a/keystore2/src/db_utils.rs b/keystore2/src/db_utils.rs
index 615005f..90f5616 100644
--- a/keystore2/src/db_utils.rs
+++ b/keystore2/src/db_utils.rs
@@ -14,7 +14,7 @@
 
 use crate::error::Error as KsError;
 use anyhow::{Context, Result};
-use rusqlite::{Row, Rows};
+use rusqlite::{types::FromSql, Row, Rows};
 
 // Takes Rows as returned by a query call on prepared statement.
 // Extracts exactly one row with the `row_extractor` and fails if more
@@ -50,3 +50,192 @@
         }
     }
 }
+
+/// This struct is defined to postpone converting rusqlite column value to the
+/// appropriate key parameter value until we know the corresponding tag value.
+/// Wraps the column index and a rusqlite row.
+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) -> rusqlite::Result<T> {
+        self.1.get(self.0)
+    }
+}
+
+/// This macro implements two types to aid in the implementation of a type safe metadata
+/// store. The first is a collection of metadata and the second is the entry in that
+/// collection. The caller has to provide the infrastructure to load and store the
+/// the collection or individual entries in a SQLite database. The idea is that once
+/// the infrastructure for a metadata collection is in place all it takes to add another
+/// field is make a new entry in the list of variants (see details below).
+///
+/// # Usage
+/// ```
+/// impl_metadata!{
+///     /// This is the name of the collection.
+///     #[derive(Debug, Default)]
+///     pub struct CollectionName;
+///     /// This is the name of the Entry type followed by a list of variants, accessor function
+///     /// names, and types.
+///     #[derive(Debug, Eq, PartialEq)]
+///     pub enum EntryName {
+///         /// An enum variant with an accessor function name.
+///         VariantA(u32) with accessor get_variant_a,
+///         /// A second variant. `MyType` must implement rusqlite::types::ToSql and FromSql.
+///         VariantB(MyType) with accessor get_variant_b,
+///         //  --- ADD NEW META DATA FIELDS HERE ---
+///         // For backwards compatibility add new entries only to
+///         // end of this list and above this comment.
+///     };
+/// }
+/// ```
+///
+/// expands to:
+///
+/// ```
+/// pub enum EntryName {
+///     VariantA(u32),
+///     VariantB(MyType),
+/// }
+///
+/// impl EntryName {}
+///     /// Returns a numeric variant id that can be used for persistent storage.
+///     fn db_tag(&self) -> i64 {...}
+///     /// Helper function that constructs a new `EntryName` given a variant identifier
+///     /// and a to-be-extracted `SqlFiled`
+///     fn new_from_sql(db_tag: i64, data: &SqlField) -> Result<Self> {...}
+/// }
+///
+/// impl ToSql for EntryName {...}
+///
+/// pub struct CollectionName {
+///     data: std::collections::HashMap<i64, EntryName>,
+/// }
+///
+/// impl CollectionName {
+///     /// Create a new collection of meta data.
+///     pub fn new() -> Self {...}
+///     /// Add a new entry to this collection. Replaces existing entries of the
+///     /// same variant unconditionally.
+///     pub fn add(&mut self, e: EntryName) {...}
+///     /// Type safe accessor function for the defined fields.
+///     pub fn get_variant_a() -> Option<u32> {...}
+///     pub fn get_variant_b() -> Option<MyType> {...}
+/// }
+///
+/// let mut collection = CollectionName::new();
+/// collection.add(EntryName::VariantA(3));
+/// let three: u32 = collection.get_variant_a().unwrap()
+/// ```
+///
+/// The caller of this macro must implement the actual database queries to load and store
+/// either a whole collection of metadata or individual fields. For example by associating
+/// with the given type:
+/// ```
+/// impl CollectionName {
+///     fn load(tx: &Transaction) -> Result<Self> {...}
+/// }
+/// ```
+#[macro_export]
+macro_rules! impl_metadata {
+    // These two macros assign incrementing numeric ids to each field which are used as
+    // database tags.
+    (@gen_consts {} {$($n:ident $nid:tt,)*} {$($count:tt)*}) => {
+        $(
+            // This allows us to reuse the variant name for these constants. The constants
+            // are private so that this exception does not spoil the public interface.
+            #[allow(non_upper_case_globals)]
+            const $n: i64 = $nid;
+        )*
+    };
+    (@gen_consts {$first:ident $(,$tail:ident)*} {$($out:tt)*} {$($count:tt)*}) => {
+        impl_metadata!(@gen_consts {$($tail),*} {$($out)* $first ($($count)*),} {$($count)* + 1});
+    };
+    (
+        $(#[$nmeta:meta])*
+        $nvis:vis struct $name:ident;
+        $(#[$emeta:meta])*
+        $evis:vis enum $entry:ident {
+            $($(#[$imeta:meta])* $vname:ident($t:ty) with accessor $func:ident),* $(,)?
+        };
+    ) => {
+        $(#[$emeta])*
+        $evis enum $entry {
+            $(
+                $(#[$imeta])*
+                $vname($t),
+            )*
+        }
+
+        impl $entry {
+            fn db_tag(&self) -> i64 {
+                match self {
+                    $(Self::$vname(_) => $name::$vname,)*
+                }
+            }
+
+            fn new_from_sql(db_tag: i64, data: &SqlField) -> anyhow::Result<Self> {
+                match db_tag {
+                    $(
+                        $name::$vname => {
+                            Ok($entry::$vname(
+                                data.get()
+                                .with_context(|| format!(
+                                    "In {}::new_from_sql: Unable to get {}.",
+                                    stringify!($entry),
+                                    stringify!($vname)
+                                ))?
+                            ))
+                        },
+                    )*
+                    _ => Err(anyhow!(format!(
+                        "In {}::new_from_sql: unknown db tag {}.",
+                        stringify!($entry), db_tag
+                    ))),
+                }
+            }
+        }
+
+        impl rusqlite::types::ToSql for $entry {
+            fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
+                match self {
+                    $($entry::$vname(v) => v.to_sql(),)*
+                }
+            }
+        }
+
+        $(#[$nmeta])*
+        $nvis struct $name {
+            data: std::collections::HashMap<i64, $entry>,
+        }
+
+        impl $name {
+            /// Create a new instance of $name
+            pub fn new() -> Self {
+                Self{data: std::collections::HashMap::new()}
+            }
+
+            impl_metadata!{@gen_consts {$($vname),*} {} {0}}
+
+            /// Add a new instance of $entry to this collection of metadata.
+            pub fn add(&mut self, entry: $entry) {
+                self.data.insert(entry.db_tag(), entry);
+            }
+            $(
+                /// If the variant $vname is set, returns the wrapped value or None otherwise.
+                pub fn $func(&self) -> Option<&$t> {
+                    if let Some($entry::$vname(v)) = self.data.get(&Self::$vname) {
+                        Some(v)
+                    } else {
+                        None
+                    }
+                }
+            )*
+        }
+    };
+}
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
index 7f2dc56..56c03aa 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -16,19 +16,21 @@
 //! and enforced by the OEMs. This module implements the internal representation of KeyParameter
 //! and the methods to work with KeyParameter.
 
+use crate::db_utils::SqlField;
 use crate::error::Error as KeystoreError;
 use crate::error::ResponseCode;
 
 pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
     HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
-    KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
-    SecurityLevel::SecurityLevel, Tag::Tag,
+    KeyParameter::KeyParameter as KmKeyParameter,
+    KeyParameterValue::KeyParameterValue as KmKeyParameterValue, KeyPurpose::KeyPurpose,
+    PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::Authorization::Authorization;
 use anyhow::{Context, Result};
-use rusqlite::types::{FromSql, Null, ToSql, ToSqlOutput};
-use rusqlite::{Result as SqlResult, Row};
+use rusqlite::types::{Null, ToSql, ToSqlOutput};
+use rusqlite::Result as SqlResult;
 
 /// KeyParameter wraps the KeyParameterValue and the security level at which it is enforced.
 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
@@ -245,22 +247,6 @@
     }
 }
 
-/// This struct is defined to postpone converting rusqlite column value to the
-/// appropriate key parameter value until we know the corresponding tag value.
-/// Wraps the column index and a rusqlite row.
-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)
-    }
-}
-
 impl ToSql for KeyParameterValue {
     /// Converts KeyParameterValue to be stored in rusqlite database.
     /// Note that following variants of KeyParameterValue should not be stored:
@@ -705,11 +691,11 @@
     ($($variant:ident, $tag_name:ident, $field_name:ident $(,$enum_type:ident)?;)*) => {
         // pre-processes input to target the rules that generate convert_to_wire() method.
         implement_key_parameter_conversion_to_from_wire! {@to
-            [], $($variant, $tag_name, $field_name $(,$enum_type)?;)*
+            [], $($variant, $tag_name, $field_name;)*
         }
         // pre-processes input to target the rules that generate convert_from_wire() method.
         implement_key_parameter_conversion_to_from_wire! {@from
-            [], $($variant, $tag_name, $field_name $(,$enum_type)?;)*
+            [], $($variant, $tag_name, $field_name;)*
         }
     };
 
@@ -717,74 +703,52 @@
     // convert_to_wire() conversion method.
     // -----------------------------------------------------------------------
     // This rule handles Invalid variant.
-    // On an input: 'Invalid, INVALID, na;' it generates a match arm like:
+    // On an input: `Invalid, INVALID, Invalid;` it generates a match arm like:
     // KeyParameterValue::Invalid => KmKeyParameter {
-    //                                   tag: Tag::INVALID,
-    //                                   ..Default::default()
-    //                               },
-    (@to [$($out:tt)*], Invalid, INVALID, na; $($in:tt)*) => {
+    //     tag: Tag::INVALID,
+    //     value: KmKeyParameterValue::Invalid(0),
+    // },
+    (@to [$($out:tt)*], Invalid, INVALID, Invalid; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@to
             [$($out)*
                 KeyParameterValue::Invalid => KmKeyParameter {
                     tag: Tag::INVALID,
-                    ..Default::default()
+                    value: KmKeyParameterValue::Invalid(0),
                 },
             ], $($in)*
         }
     };
     // This rule handles all variants that correspond to bool values.
-    // On an input like: 'CallerNonce, CALLER_NONCE, boolValue;' it generates
+    // On an input like: `CallerNonce, CALLER_NONCE, BoolValue;` it generates
     // a match arm like:
     // KeyParameterValue::CallerNonce => KmKeyParameter {
-    //                                       tag: Tag::CALLER_NONCE,
-    //                                       boolValue: true,
-    //                                       ..Default::default()
-    //                                   },
-    (@to [$($out:tt)*], $variant:ident, $tag_val:ident, boolValue; $($in:tt)*) => {
+    //     tag: Tag::CALLER_NONCE,
+    //     value: KmKeyParameterValue::BoolValue(true),
+    // },
+    (@to [$($out:tt)*], $variant:ident, $tag_val:ident, BoolValue; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@to
             [$($out)*
                 KeyParameterValue::$variant => KmKeyParameter {
                     tag: Tag::$tag_val,
-                    boolValue: true,
-                    ..Default::default()
+                    value: KmKeyParameterValue::BoolValue(true),
                 },
             ], $($in)*
         }
     };
-    // This rule handles all enum variants.
-    // On an input like: 'KeyPurpose, PURPOSE, integer, KeyPurpose;' it generates a match arm
-    // like: KeyParameterValue::KeyPurpose(v) => KmKeyParameter {
-    //                                               tag: Tag::PURPOSE,
-    //                                               integer: v.0,
-    //                                               ..Default::default(),
-    //                                           },
-    (@to [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident, $enum_type:ident; $($in:tt)*) => {
-       implement_key_parameter_conversion_to_from_wire! {@to
-           [$($out)*
-               KeyParameterValue::$variant(v) => KmKeyParameter {
-                   tag: Tag::$tag_val,
-                   $field: v.0,
-                   ..Default::default()
-               },
-           ], $($in)*
-       }
-    };
     // This rule handles all variants that are neither invalid nor bool values nor enums
     // (i.e. all variants which correspond to integer, longInteger, and blob fields in
     // KmKeyParameter).
-    // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
+    // On an input like: `ConfirmationToken, CONFIRMATION_TOKEN, Blob;` it generates a match arm
     // like: KeyParameterValue::ConfirmationToken(v) => KmKeyParameter {
-    //                                                      tag: Tag::CONFIRMATION_TOKEN,
-    //                                                      blob: v,
-    //                                                      ..Default::default(),
-    //                                                  },
+    //     tag: Tag::CONFIRMATION_TOKEN,
+    //     value: KmKeyParameterValue::$field(v),
+    // },
     (@to [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@to
             [$($out)*
                 KeyParameterValue::$variant(v) => KmKeyParameter {
                     tag: Tag::$tag_val,
-                    $field: v,
-                    ..Default::default()
+                    value: KmKeyParameterValue::$field(v),
                 },
             ], $($in)*
         }
@@ -804,9 +768,9 @@
     // convert_from_wire() conversion method.
     // ------------------------------------------------------------------------
     // This rule handles Invalid variant.
-    // On an input: 'Invalid, INVALID, na;' it generates a match arm like:
+    // On an input: `Invalid, INVALID, Invalid;` it generates a match arm like:
     // KmKeyParameter { tag: Tag::INVALID, .. } => KeyParameterValue::Invalid,
-    (@from [$($out:tt)*], Invalid, INVALID, na; $($in:tt)*) => {
+    (@from [$($out:tt)*], Invalid, INVALID, Invalid; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@from
             [$($out)*
                 KmKeyParameter {
@@ -817,59 +781,37 @@
         }
     };
     // This rule handles all variants that correspond to bool values.
-    // On an input like: 'CallerNonce, CALLER_NONCE, boolValue;' it generates a match arm like:
+    // On an input like: `CallerNonce, CALLER_NONCE, BoolValue;` it generates a match arm like:
     // KmKeyParameter {
     //      tag: Tag::CALLER_NONCE,
     //      boolValue: true,
     //      ..
     // } => KeyParameterValue::CallerNonce,
-    (@from [$($out:tt)*], $variant:ident, $tag_val:ident, boolValue; $($in:tt)*) => {
+    (@from [$($out:tt)*], $variant:ident, $tag_val:ident, BoolValue; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@from
             [$($out)*
                 KmKeyParameter {
                     tag: Tag::$tag_val,
-                    boolValue: true,
-                    ..
+                    value: KmKeyParameterValue::BoolValue(true),
                 } => KeyParameterValue::$variant,
             ], $($in)*
         }
     };
-    // This rule handles all enum variants.
-    // On an input like: 'KeyPurpose, PURPOSE, integer, KeyPurpose;' it generates a match arm
-    // like:
-    // KmKeyParameter {
-    //         tag: Tag::PURPOSE,
-    //         integer: v,
-    //         ..,
-    // } => KeyParameterValue::KeyPurpose(KeyPurpose(v)),
-    (@from [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident, $enum_type:ident; $($in:tt)*) => {
-        implement_key_parameter_conversion_to_from_wire! {@from
-            [$($out)*
-                KmKeyParameter {
-                    tag: Tag::$tag_val,
-                    $field: v,
-                    ..
-                } => KeyParameterValue::$variant($enum_type(v)),
-            ], $($in)*
-        }
-    };
     // This rule handles all variants that are neither invalid nor bool values nor enums
     // (i.e. all variants which correspond to integer, longInteger, and blob fields in
     // KmKeyParameter).
-    // On an input like: 'ConfirmationToken, CONFIRMATION_TOKEN, blob;' it generates a match arm
+    // On an input like: `ConfirmationToken, CONFIRMATION_TOKEN, Blob;` it generates a match arm
     // like:
     // KmKeyParameter {
     //         tag: Tag::CONFIRMATION_TOKEN,
-    //         blob: v,
-    //         ..,
+    //         value: KmKeyParameterValue::Blob(v),
     // } => KeyParameterValue::ConfirmationToken(v),
     (@from [$($out:tt)*], $variant:ident, $tag_val:ident, $field:ident; $($in:tt)*) => {
         implement_key_parameter_conversion_to_from_wire! {@from
             [$($out)*
                 KmKeyParameter {
                     tag: Tag::$tag_val,
-                    $field: v,
-                    ..
+                    value: KmKeyParameterValue::$field(v),
                 } => KeyParameterValue::$variant(v),
             ], $($in)*
         }
@@ -893,59 +835,59 @@
     // contains: variant identifier, tag value, and the related field name (i.e.
     // boolValue/integer/longInteger/blob) in the KmKeyParameter.
     implement_key_parameter_conversion_to_from_wire! {
-        Invalid, INVALID, na;
-        KeyPurpose, PURPOSE, integer, KeyPurpose;
-        Algorithm, ALGORITHM, integer, Algorithm;
-        KeySize, KEY_SIZE, integer;
-        BlockMode, BLOCK_MODE, integer, BlockMode;
-        Digest, DIGEST, integer, Digest;
-        PaddingMode, PADDING, integer, PaddingMode;
-        CallerNonce, CALLER_NONCE, boolValue;
-        MinMacLength, MIN_MAC_LENGTH, integer;
-        EcCurve, EC_CURVE, integer, EcCurve;
-        RSAPublicExponent, RSA_PUBLIC_EXPONENT, longInteger;
-        IncludeUniqueID, INCLUDE_UNIQUE_ID, boolValue;
-        BootLoaderOnly, BOOTLOADER_ONLY, boolValue;
-        RollbackResistance, ROLLBACK_RESISTANCE, boolValue;
-        ActiveDateTime, ACTIVE_DATETIME, longInteger;
-        OriginationExpireDateTime, ORIGINATION_EXPIRE_DATETIME, longInteger;
-        UsageExpireDateTime, USAGE_EXPIRE_DATETIME, longInteger;
-        MinSecondsBetweenOps, MIN_SECONDS_BETWEEN_OPS, integer;
-        MaxUsesPerBoot, MAX_USES_PER_BOOT, integer;
-        UserID, USER_ID, integer;
-        UserSecureID, USER_SECURE_ID, longInteger;
-        NoAuthRequired, NO_AUTH_REQUIRED, boolValue;
-        HardwareAuthenticatorType, USER_AUTH_TYPE, integer, HardwareAuthenticatorType;
-        AuthTimeout, AUTH_TIMEOUT, integer;
-        AllowWhileOnBody, ALLOW_WHILE_ON_BODY, boolValue;
-        TrustedUserPresenceRequired, TRUSTED_USER_PRESENCE_REQUIRED, boolValue;
-        TrustedConfirmationRequired, TRUSTED_CONFIRMATION_REQUIRED, boolValue;
-        UnlockedDeviceRequired, UNLOCKED_DEVICE_REQUIRED, boolValue;
-        ApplicationID, APPLICATION_ID, blob;
-        ApplicationData, APPLICATION_DATA, blob;
-        CreationDateTime, CREATION_DATETIME, longInteger;
-        KeyOrigin, ORIGIN, integer, KeyOrigin;
-        RootOfTrust, ROOT_OF_TRUST, blob;
-        OSVersion, OS_VERSION, integer;
-        OSPatchLevel, OS_PATCHLEVEL, integer;
-        UniqueID, UNIQUE_ID, blob;
-        AttestationChallenge, ATTESTATION_CHALLENGE, blob;
-        AttestationApplicationID, ATTESTATION_APPLICATION_ID, blob;
-        AttestationIdBrand, ATTESTATION_ID_BRAND, blob;
-        AttestationIdDevice, ATTESTATION_ID_DEVICE, blob;
-        AttestationIdProduct, ATTESTATION_ID_PRODUCT, blob;
-        AttestationIdSerial, ATTESTATION_ID_SERIAL, blob;
-        AttestationIdIMEI, ATTESTATION_ID_IMEI, blob;
-        AttestationIdMEID, ATTESTATION_ID_MEID, blob;
-        AttestationIdManufacturer, ATTESTATION_ID_MANUFACTURER, blob;
-        AttestationIdModel, ATTESTATION_ID_MODEL, blob;
-        VendorPatchLevel, VENDOR_PATCHLEVEL, integer;
-        BootPatchLevel, BOOT_PATCHLEVEL, integer;
-        AssociatedData, ASSOCIATED_DATA, blob;
-        Nonce, NONCE, blob;
-        MacLength, MAC_LENGTH, integer;
-        ResetSinceIdRotation, RESET_SINCE_ID_ROTATION, boolValue;
-        ConfirmationToken, CONFIRMATION_TOKEN, blob;
+        Invalid, INVALID, Invalid;
+        KeyPurpose, PURPOSE, KeyPurpose;
+        Algorithm, ALGORITHM, Algorithm;
+        KeySize, KEY_SIZE, Integer;
+        BlockMode, BLOCK_MODE, BlockMode;
+        Digest, DIGEST, Digest;
+        PaddingMode, PADDING, PaddingMode;
+        CallerNonce, CALLER_NONCE, BoolValue;
+        MinMacLength, MIN_MAC_LENGTH, Integer;
+        EcCurve, EC_CURVE, EcCurve;
+        RSAPublicExponent, RSA_PUBLIC_EXPONENT, LongInteger;
+        IncludeUniqueID, INCLUDE_UNIQUE_ID, BoolValue;
+        BootLoaderOnly, BOOTLOADER_ONLY, BoolValue;
+        RollbackResistance, ROLLBACK_RESISTANCE, BoolValue;
+        ActiveDateTime, ACTIVE_DATETIME, DateTime;
+        OriginationExpireDateTime, ORIGINATION_EXPIRE_DATETIME, DateTime;
+        UsageExpireDateTime, USAGE_EXPIRE_DATETIME, DateTime;
+        MinSecondsBetweenOps, MIN_SECONDS_BETWEEN_OPS, Integer;
+        MaxUsesPerBoot, MAX_USES_PER_BOOT, Integer;
+        UserID, USER_ID, Integer;
+        UserSecureID, USER_SECURE_ID, LongInteger;
+        NoAuthRequired, NO_AUTH_REQUIRED, BoolValue;
+        HardwareAuthenticatorType, USER_AUTH_TYPE, HardwareAuthenticatorType;
+        AuthTimeout, AUTH_TIMEOUT, Integer;
+        AllowWhileOnBody, ALLOW_WHILE_ON_BODY, BoolValue;
+        TrustedUserPresenceRequired, TRUSTED_USER_PRESENCE_REQUIRED, BoolValue;
+        TrustedConfirmationRequired, TRUSTED_CONFIRMATION_REQUIRED, BoolValue;
+        UnlockedDeviceRequired, UNLOCKED_DEVICE_REQUIRED, BoolValue;
+        ApplicationID, APPLICATION_ID, Blob;
+        ApplicationData, APPLICATION_DATA, Blob;
+        CreationDateTime, CREATION_DATETIME, DateTime;
+        KeyOrigin, ORIGIN, Origin;
+        RootOfTrust, ROOT_OF_TRUST, Blob;
+        OSVersion, OS_VERSION, Integer;
+        OSPatchLevel, OS_PATCHLEVEL, Integer;
+        UniqueID, UNIQUE_ID, Blob;
+        AttestationChallenge, ATTESTATION_CHALLENGE, Blob;
+        AttestationApplicationID, ATTESTATION_APPLICATION_ID, Blob;
+        AttestationIdBrand, ATTESTATION_ID_BRAND, Blob;
+        AttestationIdDevice, ATTESTATION_ID_DEVICE, Blob;
+        AttestationIdProduct, ATTESTATION_ID_PRODUCT, Blob;
+        AttestationIdSerial, ATTESTATION_ID_SERIAL, Blob;
+        AttestationIdIMEI, ATTESTATION_ID_IMEI, Blob;
+        AttestationIdMEID, ATTESTATION_ID_MEID, Blob;
+        AttestationIdManufacturer, ATTESTATION_ID_MANUFACTURER, Blob;
+        AttestationIdModel, ATTESTATION_ID_MODEL, Blob;
+        VendorPatchLevel, VENDOR_PATCHLEVEL, Integer;
+        BootPatchLevel, BOOT_PATCHLEVEL, Integer;
+        AssociatedData, ASSOCIATED_DATA, Blob;
+        Nonce, NONCE, Blob;
+        MacLength, MAC_LENGTH, Integer;
+        ResetSinceIdRotation, RESET_SINCE_ID_ROTATION, BoolValue;
+        ConfirmationToken, CONFIRMATION_TOKEN, Blob;
     }
 }
 
@@ -1235,7 +1177,7 @@
         let row = rows.next()?.unwrap();
         Ok(KeyParameter::new_from_sql(
             Tag(row.get(0)?),
-            &SqlField(1, row),
+            &SqlField::new(1, row),
             SecurityLevel(row.get(2)?),
         )?)
     }
@@ -1263,7 +1205,7 @@
         let kp = KeyParameter::new(KeyParameterValue::CallerNonce, SecurityLevel::STRONGBOX);
         let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
         assert_eq!(Tag::CALLER_NONCE, actual.tag);
-        assert_eq!(true, actual.boolValue);
+        assert_eq!(KmKeyParameterValue::BoolValue(true), actual.value);
     }
     #[test]
     fn test_convert_to_wire_integer() {
@@ -1273,7 +1215,7 @@
         );
         let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
         assert_eq!(Tag::PURPOSE, actual.tag);
-        assert_eq!(KeyPurpose::ENCRYPT.0, actual.integer);
+        assert_eq!(KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), actual.value);
     }
     #[test]
     fn test_convert_to_wire_long_integer() {
@@ -1281,7 +1223,7 @@
             KeyParameter::new(KeyParameterValue::UserSecureID(i64::MAX), SecurityLevel::STRONGBOX);
         let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
         assert_eq!(Tag::USER_SECURE_ID, actual.tag);
-        assert_eq!(i64::MAX, actual.longInteger);
+        assert_eq!(KmKeyParameterValue::LongInteger(i64::MAX), actual.value);
     }
     #[test]
     fn test_convert_to_wire_blob() {
@@ -1291,7 +1233,10 @@
         );
         let actual = KeyParameterValue::convert_to_wire(kp.key_parameter_value);
         assert_eq!(Tag::CONFIRMATION_TOKEN, actual.tag);
-        assert_eq!(String::from("ConfirmationToken").into_bytes(), actual.blob);
+        assert_eq!(
+            KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()),
+            actual.value
+        );
     }
 
     /// unit tests for from conversion
@@ -1304,7 +1249,7 @@
     #[test]
     fn test_convert_from_wire_bool() {
         let aidl_kp =
-            KmKeyParameter { tag: Tag::CALLER_NONCE, boolValue: true, ..Default::default() };
+            KmKeyParameter { tag: Tag::CALLER_NONCE, value: KmKeyParameterValue::BoolValue(true) };
         let actual = KeyParameterValue::convert_from_wire(aidl_kp);
         assert_eq!(KeyParameterValue::CallerNonce, actual);
     }
@@ -1312,8 +1257,7 @@
     fn test_convert_from_wire_integer() {
         let aidl_kp = KmKeyParameter {
             tag: Tag::PURPOSE,
-            integer: KeyPurpose::ENCRYPT.0,
-            ..Default::default()
+            value: KmKeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
         };
         let actual = KeyParameterValue::convert_from_wire(aidl_kp);
         assert_eq!(KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT), actual);
@@ -1322,8 +1266,7 @@
     fn test_convert_from_wire_long_integer() {
         let aidl_kp = KmKeyParameter {
             tag: Tag::USER_SECURE_ID,
-            longInteger: i64::MAX,
-            ..Default::default()
+            value: KmKeyParameterValue::LongInteger(i64::MAX),
         };
         let actual = KeyParameterValue::convert_from_wire(aidl_kp);
         assert_eq!(KeyParameterValue::UserSecureID(i64::MAX), actual);
@@ -1332,8 +1275,7 @@
     fn test_convert_from_wire_blob() {
         let aidl_kp = KmKeyParameter {
             tag: Tag::CONFIRMATION_TOKEN,
-            blob: String::from("ConfirmationToken").into_bytes(),
-            ..Default::default()
+            value: KmKeyParameterValue::Blob(String::from("ConfirmationToken").into_bytes()),
         };
         let actual = KeyParameterValue::convert_from_wire(aidl_kp);
         assert_eq!(
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index 13a9b0c..9a35154 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -136,7 +136,8 @@
 use crate::utils::Asp;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     ByteArray::ByteArray, IKeyMintOperation::IKeyMintOperation,
-    KeyParameter::KeyParameter as KmParam, KeyParameterArray::KeyParameterArray, Tag::Tag,
+    KeyParameter::KeyParameter as KmParam, KeyParameterArray::KeyParameterArray,
+    KeyParameterValue::KeyParameterValue as KmParamValue, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
@@ -319,8 +320,7 @@
         let params = KeyParameterArray {
             params: vec![KmParam {
                 tag: Tag::ASSOCIATED_DATA,
-                blob: aad_input.into(),
-                ..Default::default()
+                value: KmParamValue::Blob(aad_input.into()),
             }],
         };
 
@@ -377,7 +377,13 @@
         .context("In update: KeyMint::update failed.")?;
 
         match output {
-            Some(blob) => Ok(Some(blob.data)),
+            Some(blob) => {
+                if blob.data.is_empty() {
+                    Ok(None)
+                } else {
+                    Ok(Some(blob.data))
+                }
+            }
             None => Ok(None),
         }
     }
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 9a8c7d9..3657a43 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -20,7 +20,7 @@
     Algorithm::Algorithm, ByteArray::ByteArray, Certificate::Certificate as KmCertificate,
     HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
     KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
-    KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel, Tag::Tag,
+    KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
@@ -234,7 +234,11 @@
         let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
             Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
                 .context("In create_operation: No operation purpose specified."),
-            |kp| Ok(KeyPurpose(kp.integer)),
+            |kp| match kp.value {
+                KeyParameterValue::KeyPurpose(p) => Ok(p),
+                _ => Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
+                    .context("In create_operation: Malformed KeyParameter."),
+            },
         )?;
 
         let km_dev: Box<dyn IKeyMintDevice> = self
@@ -365,11 +369,14 @@
             .find(|p| p.tag == Tag::ALGORITHM)
             .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
             .context("No KeyParameter 'Algorithm'.")
-            .and_then(|p| match Algorithm(p.integer) {
-                Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
-                Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
-                algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
-                    .context(format!("Unknown Algorithm {:?}.", algorithm)),
+            .and_then(|p| match &p.value {
+                KeyParameterValue::Algorithm(Algorithm::AES)
+                | KeyParameterValue::Algorithm(Algorithm::HMAC)
+                | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES) => Ok(KeyFormat::RAW),
+                KeyParameterValue::Algorithm(Algorithm::RSA)
+                | KeyParameterValue::Algorithm(Algorithm::EC) => Ok(KeyFormat::PKCS8),
+                v => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                    .context(format!("Unknown Algorithm {:?}.", v)),
             })
             .context("In import_key.")?;