Merge "Remove per-file CompOS signature support"
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 3097bae..520237a 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -39,7 +39,7 @@
         "android.security.maintenance-rust",
         "android.security.metrics-rust",
         "android.security.remoteprovisioning-rust",
-        "android.system.keystore2-V1-rust",
+        "android.system.keystore2-V2-rust",
         "libanyhow",
         "libbinder_rs",
         "libkeystore2_aaid-rust",
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 35006be..7eb2b83 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -24,7 +24,7 @@
 aidl_interface {
     name: "android.security.attestationmanager",
     srcs: [ "android/security/attestationmanager/*.aidl", ],
-    imports: [ "android.hardware.security.keymint-V1" ],
+    imports: [ "android.hardware.security.keymint-V2" ],
     unstable: true,
     backend: {
         java: {
@@ -45,7 +45,7 @@
     name: "android.security.authorization",
     srcs: [ "android/security/authorization/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint-V1",
+        "android.hardware.security.keymint-V2",
         "android.hardware.security.secureclock-V1",
     ],
     unstable: true,
@@ -86,7 +86,7 @@
     name: "android.security.compat",
     srcs: [ "android/security/compat/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint-V1",
+        "android.hardware.security.keymint-V2",
         "android.hardware.security.secureclock-V1",
         "android.hardware.security.sharedsecret-V1",
     ],
@@ -110,7 +110,7 @@
     name: "android.security.remoteprovisioning",
     srcs: [ "android/security/remoteprovisioning/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint-V1",
+        "android.hardware.security.keymint-V2",
     ],
     unstable: true,
     backend: {
@@ -132,7 +132,7 @@
     name: "android.security.maintenance",
     srcs: [ "android/security/maintenance/*.aidl" ],
     imports: [
-        "android.system.keystore2-V1",
+        "android.system.keystore2-V2",
     ],
     unstable: true,
     backend: {
@@ -173,7 +173,7 @@
     name: "android.security.metrics",
     srcs: [ "android/security/metrics/*.aidl" ],
     imports: [
-        "android.system.keystore2-V1",
+        "android.system.keystore2-V2",
     ],
     unstable: true,
     backend: {
@@ -197,13 +197,13 @@
 cc_defaults {
     name: "keystore2_use_latest_aidl_ndk_static",
     static_libs: [
-        "android.system.keystore2-V1-ndk",
+        "android.system.keystore2-V2-ndk",
     ],
 }
 
 cc_defaults {
     name: "keystore2_use_latest_aidl_ndk_shared",
     shared_libs: [
-        "android.system.keystore2-V1-ndk",
+        "android.system.keystore2-V2-ndk",
     ],
 }
diff --git a/keystore2/aidl/android/security/metrics/EcCurve.aidl b/keystore2/aidl/android/security/metrics/EcCurve.aidl
index b190d83..7b1a5a2 100644
--- a/keystore2/aidl/android/security/metrics/EcCurve.aidl
+++ b/keystore2/aidl/android/security/metrics/EcCurve.aidl
@@ -29,4 +29,5 @@
     P_256 = 2,
     P_384 = 3,
     P_521 = 4,
+    CURVE_25519 = 5,
 }
\ No newline at end of file
diff --git a/keystore2/android.system.keystore2-service.xml b/keystore2/android.system.keystore2-service.xml
index 6b8d0cb..20c2fba 100644
--- a/keystore2/android.system.keystore2-service.xml
+++ b/keystore2/android.system.keystore2-service.xml
@@ -1,6 +1,7 @@
 <manifest version="1.0" type="framework">
     <hal format="aidl">
         <name>android.system.keystore2</name>
+        <version>2</version>
         <interface>
             <name>IKeystoreService</name>
             <instance>default</instance>
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index 40ca554..bb60047 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -762,7 +762,21 @@
     return convertErrorCode(errorCode);
 }
 
-ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input,
+void KeyMintOperation::setUpdateBuffer(std::vector<uint8_t> data) {
+    mUpdateBuffer = std::move(data);
+}
+
+const std::vector<uint8_t>&
+KeyMintOperation::getExtendedUpdateBuffer(const std::vector<uint8_t>& suffix) {
+    if (mUpdateBuffer.empty()) {
+        return suffix;
+    } else {
+        mUpdateBuffer.insert(mUpdateBuffer.end(), suffix.begin(), suffix.end());
+        return mUpdateBuffer;
+    }
+}
+
+ScopedAStatus KeyMintOperation::update(const std::vector<uint8_t>& input_raw,
                                        const std::optional<HardwareAuthToken>& optAuthToken,
                                        const std::optional<TimeStampToken>& optTimeStampToken,
                                        std::vector<uint8_t>* out_output) {
@@ -772,8 +786,10 @@
     size_t inputPos = 0;
     *out_output = {};
     KMV1::ErrorCode errorCode = KMV1::ErrorCode::OK;
+    auto input = getExtendedUpdateBuffer(input_raw);
 
     while (inputPos < input.size() && errorCode == KMV1::ErrorCode::OK) {
+        uint32_t consumed = 0;
         auto result =
             mDevice->update(mOperationHandle, {} /* inParams */,
                             {input.begin() + inputPos, input.end()}, authToken, verificationToken,
@@ -781,13 +797,22 @@
                                 const hidl_vec<uint8_t>& output) {
                                 errorCode = convert(error);
                                 out_output->insert(out_output->end(), output.begin(), output.end());
-                                inputPos += inputConsumed;
+                                consumed = inputConsumed;
                             });
 
         if (!result.isOk()) {
             LOG(ERROR) << __func__ << " transaction failed. " << result.description();
             errorCode = KMV1::ErrorCode::UNKNOWN_ERROR;
         }
+
+        if (errorCode == KMV1::ErrorCode::OK && consumed == 0) {
+            // Some very old KM implementations do not buffer sub blocks in certain block modes,
+            // instead, the simply return consumed == 0. So we buffer the input here in the
+            // hope that we complete the bock in a future call to update.
+            setUpdateBuffer({input.begin() + inputPos, input.end()});
+            return convertErrorCode(errorCode);
+        }
+        inputPos += consumed;
     }
 
     if (errorCode != KMV1::ErrorCode::OK) mOperationSlot.freeSlot();
@@ -802,7 +827,8 @@
                          const std::optional<TimeStampToken>& in_timeStampToken,
                          const std::optional<std::vector<uint8_t>>& in_confirmationToken,
                          std::vector<uint8_t>* out_output) {
-    auto input = in_input.value_or(std::vector<uint8_t>());
+    auto input_raw = in_input.value_or(std::vector<uint8_t>());
+    auto input = getExtendedUpdateBuffer(input_raw);
     auto signature = in_signature.value_or(std::vector<uint8_t>());
     V4_0_HardwareAuthToken authToken = convertAuthTokenToLegacy(in_authToken);
     V4_0_VerificationToken verificationToken = convertTimestampTokenToLegacy(in_timeStampToken);
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 2d892da..70c7b86 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -140,11 +140,6 @@
 };
 
 class KeyMintOperation : public aidl::android::hardware::security::keymint::BnKeyMintOperation {
-  private:
-    ::android::sp<Keymaster> mDevice;
-    uint64_t mOperationHandle;
-    OperationSlot mOperationSlot;
-
   public:
     KeyMintOperation(::android::sp<Keymaster> device, uint64_t operationHandle,
                      OperationSlots* slots, bool isActive)
@@ -168,6 +163,25 @@
                          std::vector<uint8_t>* output) override;
 
     ScopedAStatus abort();
+
+  private:
+    /**
+     * Sets mUpdateBuffer to the given value.
+     * @param data
+     */
+    void setUpdateBuffer(std::vector<uint8_t> data);
+    /**
+     * If mUpdateBuffer is not empty, suffix is appended to mUpdateBuffer, and a reference to
+     * mUpdateBuffer is returned. Otherwise a reference to suffix is returned.
+     * @param suffix
+     * @return
+     */
+    const std::vector<uint8_t>& getExtendedUpdateBuffer(const std::vector<uint8_t>& suffix);
+
+    std::vector<uint8_t> mUpdateBuffer;
+    ::android::sp<Keymaster> mDevice;
+    uint64_t mOperationHandle;
+    OperationSlot mOperationSlot;
 };
 
 class SharedSecret : public aidl::android::hardware::security::sharedsecret::BnSharedSecret {
diff --git a/keystore2/src/km_compat/km_compat_type_conversion.h b/keystore2/src/km_compat/km_compat_type_conversion.h
index de09477..33248a4 100644
--- a/keystore2/src/km_compat/km_compat_type_conversion.h
+++ b/keystore2/src/km_compat/km_compat_type_conversion.h
@@ -16,6 +16,9 @@
 
 #pragma once
 
+#include <optional>
+
+#include <aidl/android/hardware/security/keymint/EcCurve.h>
 #include <aidl/android/hardware/security/keymint/ErrorCode.h>
 #include <keymasterV4_1/keymaster_tags.h>
 #include <keymint_support/keymint_tags.h>
@@ -278,7 +281,7 @@
     }
 }
 
-static V4_0::EcCurve convert(KMV1::EcCurve e) {
+static std::optional<V4_0::EcCurve> convert(KMV1::EcCurve e) {
     switch (e) {
     case KMV1::EcCurve::P_224:
         return V4_0::EcCurve::P_224;
@@ -288,7 +291,11 @@
         return V4_0::EcCurve::P_384;
     case KMV1::EcCurve::P_521:
         return V4_0::EcCurve::P_521;
+    case KMV1::EcCurve::CURVE_25519:
+        // KeyMaster did not support curve 25519
+        return std::nullopt;
     }
+    return std::nullopt;
 }
 
 static KMV1::EcCurve convert(V4_0::EcCurve e) {
@@ -490,7 +497,9 @@
         break;
     case KMV1::Tag::EC_CURVE:
         if (auto v = KMV1::authorizationValue(KMV1::TAG_EC_CURVE, kp)) {
-            return V4_0::makeKeyParameter(V4_0::TAG_EC_CURVE, convert(v->get()));
+            if (auto curve = convert(v->get())) {
+                return V4_0::makeKeyParameter(V4_0::TAG_EC_CURVE, curve.value());
+            }
         }
         break;
     case KMV1::Tag::RSA_PUBLIC_EXPONENT:
diff --git a/keystore2/src/metrics_store.rs b/keystore2/src/metrics_store.rs
index 741d65e..b18d84c 100644
--- a/keystore2/src/metrics_store.rs
+++ b/keystore2/src/metrics_store.rs
@@ -17,7 +17,7 @@
 //!    stores them in an in-memory store.
 //! 2. Returns the collected metrics when requested by the statsd proxy.
 
-use crate::error::get_error_code;
+use crate::error::{get_error_code, Error};
 use crate::globals::DB;
 use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
 use crate::operation::Outcome;
@@ -44,6 +44,7 @@
     RkpPoolStats::RkpPoolStats, SecurityLevel::SecurityLevel as MetricsSecurityLevel,
     Storage::Storage as MetricsStorage,
 };
+use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
 use anyhow::{Context, Result};
 use lazy_static::lazy_static;
 use rustutils::system_properties::PropertyWatcherError;
@@ -287,6 +288,7 @@
                     EcCurve::P_256 => MetricsEcCurve::P_256,
                     EcCurve::P_384 => MetricsEcCurve::P_384,
                     EcCurve::P_521 => MetricsEcCurve::P_521,
+                    EcCurve::CURVE_25519 => MetricsEcCurve::CURVE_25519,
                     _ => MetricsEcCurve::EC_CURVE_UNSPECIFIED,
                 }
             }
@@ -560,10 +562,14 @@
 fn pull_attestation_pool_stats() -> Result<Vec<KeystoreAtom>> {
     let mut atoms = Vec::<KeystoreAtom>::new();
     for sec_level in &[SecurityLevel::TRUSTED_ENVIRONMENT, SecurityLevel::STRONGBOX] {
+        // set the expired_by date to be three days from now
         let expired_by = SystemTime::now()
+            .checked_add(Duration::from_secs(60 * 60 * 24 * 3))
+            .ok_or(Error::Rc(ResponseCode::SYSTEM_ERROR))
+            .context("In pull_attestation_pool_stats: Failed to compute expired by system time.")?
             .duration_since(UNIX_EPOCH)
-            .unwrap_or_else(|_| Duration::new(0, 0))
-            .as_secs() as i64;
+            .context("In pull_attestation_pool_stats: Failed to compute expired by duration.")?
+            .as_millis() as i64;
 
         let result = get_pool_status(expired_by, *sec_level);
 
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index ee725eb..da1ff16 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -54,9 +54,11 @@
     Domain::Domain, EphemeralStorageKeyResponse::EphemeralStorageKeyResponse,
     IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
     IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
-    KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
+    KeyMetadata::KeyMetadata, KeyParameters::KeyParameters, ResponseCode::ResponseCode,
 };
 use anyhow::{anyhow, Context, Result};
+use std::convert::TryInto;
+use std::time::SystemTime;
 
 /// Implementation of the IKeystoreSecurityLevel Interface.
 pub struct KeystoreSecurityLevel {
@@ -386,25 +388,50 @@
         })
     }
 
-    fn add_certificate_parameters(
+    fn add_required_parameters(
         &self,
         uid: u32,
         params: &[KeyParameter],
         key: &KeyDescriptor,
     ) -> Result<Vec<KeyParameter>> {
         let mut result = params.to_vec();
+
+        // Unconditionally add the CREATION_DATETIME tag and prevent callers from
+        // specifying it.
+        if params.iter().any(|kp| kp.tag == Tag::CREATION_DATETIME) {
+            return Err(Error::Rc(ResponseCode::INVALID_ARGUMENT)).context(
+                "In KeystoreSecurityLevel::add_required_parameters: \
+                Specifying Tag::CREATION_DATETIME is not allowed.",
+            );
+        }
+
+        result.push(KeyParameter {
+            tag: Tag::CREATION_DATETIME,
+            value: KeyParameterValue::DateTime(
+                SystemTime::now()
+                    .duration_since(SystemTime::UNIX_EPOCH)
+                    .context(
+                        "In KeystoreSecurityLevel::add_required_parameters: \
+                        Failed to get epoch time.",
+                    )?
+                    .as_millis()
+                    .try_into()
+                    .context(
+                        "In KeystoreSecurityLevel::add_required_parameters: \
+                        Failed to convert epoch time.",
+                    )?,
+            ),
+        });
+
         // If there is an attestation challenge we need to get an application id.
         if params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
             let aaid = {
                 let _wp = self.watch_millis(
-                    "In KeystoreSecurityLevel::add_certificate_parameters calling: get_aaid",
+                    "In KeystoreSecurityLevel::add_required_parameters calling: get_aaid",
                     500,
                 );
                 keystore2_aaid::get_aaid(uid).map_err(|e| {
-                    anyhow!(format!(
-                        "In add_certificate_parameters: get_aaid returned status {}.",
-                        e
-                    ))
+                    anyhow!(format!("In add_required_parameters: get_aaid returned status {}.", e))
                 })
             }?;
 
@@ -416,13 +443,13 @@
 
         if params.iter().any(|kp| kp.tag == Tag::INCLUDE_UNIQUE_ID) {
             check_key_permission(KeyPerm::GenUniqueId, key, &None).context(concat!(
-                "In add_certificate_parameters: ",
+                "In add_required_parameters: ",
                 "Caller does not have the permission to generate a unique ID"
             ))?;
             if self.id_rotation_state.had_factory_reset_since_id_rotation().context(
-                "In add_certificate_parameters: Call to had_factory_reset_since_id_rotation failed."
+                "In add_required_parameters: Call to had_factory_reset_since_id_rotation failed.",
             )? {
-                result.push(KeyParameter{
+                result.push(KeyParameter {
                     tag: Tag::RESET_SINCE_ID_ROTATION,
                     value: KeyParameterValue::BoolValue(true),
                 })
@@ -433,7 +460,7 @@
         // correct Android permission.
         if params.iter().any(|kp| is_device_id_attestation_tag(kp.tag)) {
             check_device_attestation_permissions().context(concat!(
-                "In add_certificate_parameters: ",
+                "In add_required_parameters: ",
                 "Caller does not have the permission to attest device identifiers."
             ))?;
         }
@@ -505,7 +532,7 @@
                 .context("In generate_key: Trying to get an attestation key")?,
         };
         let params = self
-            .add_certificate_parameters(caller_uid, params, &key)
+            .add_required_parameters(caller_uid, params, &key)
             .context("In generate_key: Trying to get aaid.")?;
 
         let creation_result = match attestation_key_info {
@@ -604,7 +631,7 @@
         check_key_permission(KeyPerm::Rebind, &key, &None).context("In import_key.")?;
 
         let params = self
-            .add_certificate_parameters(caller_uid, params, &key)
+            .add_required_parameters(caller_uid, params, &key)
             .context("In import_key: Trying to get aaid.")?;
 
         let format = params