Merge "memtrack: Update AIDL memtrack hal documentation" into sc-dev
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
index d7f3175..c960933 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -19,6 +19,15 @@
 @VintfStability
 @Backing(type="byte")
 enum EnrollmentType {
+    /**
+     * Default enrollment type.
+     */
     DEFAULT,
+
+    /**
+     * Enrollment type for people with limited vision or mobility. For example,
+     * enrollment of this type will not ask the user to move their head or
+     * look directly at the device.
+     */
     ACCESSIBILITY,
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index 57f39d4..a5ed2e8 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -16,4 +16,23 @@
 
 package android.hardware.biometrics.face;
 
-@VintfStability @Backing(type="byte") enum FaceSensorType { UNKNOWN, RGB, IR }
+@VintfStability
+@Backing(type="byte")
+enum FaceSensorType {
+    /**
+     * Placeholder value used for default initialization of FaceSensorType.
+     * This value means FaceSensorType wasn't explicitly initialized and must
+     * be discarded by the recipient.
+     */
+    UNKNOWN,
+
+    /**
+     * The face sensor is an RGB camera.
+     */
+    RGB,
+
+    /**
+     * The face sensor is an infrared camera.
+     */
+    IR,
+}
diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp
index 0fd453b..e80de0b 100644
--- a/neuralnetworks/aidl/utils/src/Device.cpp
+++ b/neuralnetworks/aidl/utils/src/Device.cpp
@@ -119,7 +119,7 @@
                           << numberOfCacheFiles.numDataCache << " vs " << nn::kMaxNumberOfCacheFiles
                           << ")";
     }
-    return std::make_pair(numberOfCacheFiles.numDataCache, numberOfCacheFiles.numModelCache);
+    return std::make_pair(numberOfCacheFiles.numModelCache, numberOfCacheFiles.numDataCache);
 }
 
 }  // namespace
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index e53b0a8..f121aca 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -58,7 +58,7 @@
 const std::shared_ptr<BnDevice> kInvalidDevice;
 constexpr PerformanceInfo kNoPerformanceInfo = {.execTime = std::numeric_limits<float>::max(),
                                                 .powerUsage = std::numeric_limits<float>::max()};
-constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles,
+constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles - 1,
                                                     .numDataCache = nn::kMaxNumberOfCacheFiles};
 
 constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
@@ -300,6 +300,21 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
+TEST(DeviceTest, getNumberOfCacheFilesNeeded) {
+    // setup call
+    const auto mockDevice = createMockDevice();
+    EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1);
+
+    // run test
+    const auto result = Device::create(kName, mockDevice);
+
+    // verify result
+    ASSERT_TRUE(result.has_value());
+    constexpr auto kNumberOfCacheFilesPair = std::make_pair<uint32_t, uint32_t>(
+            kNumberOfCacheFiles.numModelCache, kNumberOfCacheFiles.numDataCache);
+    EXPECT_EQ(result.value()->getNumberOfCacheFilesNeeded(), kNumberOfCacheFilesPair);
+}
+
 TEST(DeviceTest, getNumberOfCacheFilesNeededError) {
     // setup call
     const auto mockDevice = createMockDevice();
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 9cc795d..4cecff7 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -277,6 +277,10 @@
      *   must return ErrorCode::INVALID_ARGUMENT.  The values 3 and 65537 must be supported.  It is
      *   recommended to support all prime values up to 2^64.
      *
+     * o Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER specify the valid date range for
+     *   the returned X.509 certificate holding the public key. If omitted, generateKey must return
+     *   ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER.
+     *
      * The following parameters are not necessary to generate a usable RSA key, but generateKey must
      * not return an error if they are omitted:
      *
@@ -297,6 +301,10 @@
      * Tag::EC_CURVE must be provided to generate an ECDSA key.  If it is not provided, generateKey
      * must return ErrorCode::UNSUPPORTED_KEY_SIZE. TEE IKeyMintDevice implementations must support
      * all curves.  StrongBox implementations must support P_256.
+
+     * Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER must be provided to specify the
+     * valid date range for the returned X.509 certificate holding the public key. If omitted,
+     * generateKey must return ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER.
      *
      * == AES Keys ==
      *
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 58e02b3..270574b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -483,12 +483,12 @@
 
     /**
      * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
-     *  specifies that this key must not be usable unless the user provides confirmation of the data
-     *  to be signed.  Confirmation is proven to keyMint via an approval token.  See
-     *  CONFIRMATION_TOKEN, as well as the ConfirmationUI HAL.
+     * specifies that this key must not be usable unless the user provides confirmation of the data
+     * to be signed.  Confirmation is proven to keyMint via an approval token.  See the authToken
+     * parameter of begin(), as well as the ConfirmationUI HAL.
      *
      * If an attempt to use a key with this tag does not have a cryptographically valid
-     * CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not
+     * token provided to finish() or if the data provided to update()/finish() does not
      * match the data described in the token, keyMint must return NO_USER_CONFIRMATION.
      *
      * Must be hardware-enforced.
@@ -497,9 +497,11 @@
 
     /**
      * Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is
-     * unlocked.
+     * unlocked, as reported to KeyMint via authToken operation parameter and the
+     * IKeyMintDevice::deviceLocked() method
      *
-     * Must be software-enforced.
+     * Must be hardware-enforced (but is also keystore-enforced on a per-user basis: see the
+     * deviceLocked() documentation).
      */
     UNLOCKED_DEVICE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 509,
 
@@ -870,8 +872,9 @@
      *
      * STORAGE_KEY is used to denote that a key generated or imported is a key used for storage
      * encryption. Keys of this type can either be generated or imported or secure imported using
-     * keyMint. exportKey() can be used to re-wrap storage key with a per-boot ephemeral key
-     * wrapped key once the key characteristics are enforced.
+     * keyMint. The convertStorageKeyToEphemeral() method of IKeyMintDevice can be used to re-wrap
+     * storage key with a per-boot ephemeral key wrapped key once the key characteristics are
+     * enforced.
      *
      * Keys with this tag cannot be used for any operation within keyMint.
      * ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to
@@ -919,11 +922,10 @@
     RESET_SINCE_ID_ROTATION = (7 << 28) /* TagType:BOOL */ | 1004,
 
     /**
-     * Tag::CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user
-     * confirmed a signing request.  The content is a full-length HMAC-SHA256 value.  See the
-     * ConfirmationUI HAL for details of token computation.
+     * OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for
+     * IKeyMintOperation methods instead.
      *
-     * Must never appear in KeyCharacteristics.
+     * TODO(b/191738660): Delete when keystore1 is deleted.
      */
     CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005,
 
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index ff08ce6..386029f 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -23,16 +23,11 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_test {
-    name: "VtsAidlKeyMintTargetTest",
+cc_defaults {
+    name: "keymint_vts_defaults",
     defaults: [
-        "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
-    ],
-    srcs: [
-        "AttestKeyTest.cpp",
-        "DeviceUniqueAttestationTest.cpp",
-        "KeyMintTest.cpp",
+        "VtsHalTargetTestDefaults",
     ],
     shared_libs: [
         "libbinder_ndk",
@@ -43,9 +38,24 @@
         "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
         "libcppcose_rkp",
+        "libjsoncpp",
         "libkeymint",
         "libkeymint_remote_prov_support",
         "libkeymint_support",
+    ],
+}
+
+cc_test {
+    name: "VtsAidlKeyMintTargetTest",
+    defaults: [
+        "keymint_vts_defaults",
+    ],
+    srcs: [
+        "AttestKeyTest.cpp",
+        "DeviceUniqueAttestationTest.cpp",
+        "KeyMintTest.cpp",
+    ],
+    static_libs: [
         "libkeymint_vts_test_utils",
     ],
     test_suites: [
@@ -57,8 +67,7 @@
 cc_test_library {
     name: "libkeymint_vts_test_utils",
     defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
+        "keymint_vts_defaults",
     ],
     srcs: [
         "KeyMintAidlTestBase.cpp",
@@ -66,45 +75,22 @@
     export_include_dirs: [
         ".",
     ],
-    shared_libs: [
-        "libbinder_ndk",
-        "libcrypto",
-    ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppbor_external",
-        "libcppcose_rkp",
         "libgmock_ndk",
-        "libkeymint",
-        "libkeymint_remote_prov_support",
-        "libkeymint_support",
     ],
 }
 
 cc_test {
     name: "VtsHalRemotelyProvisionedComponentTargetTest",
     defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
+        "keymint_vts_defaults",
     ],
     srcs: [
         "VtsRemotelyProvisionedComponentTests.cpp",
     ],
-    shared_libs: [
-        "libbinder_ndk",
-        "libcrypto",
-    ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppbor_external",
-        "libcppcose_rkp",
         "libgmock_ndk",
         "libkeymaster_portable",
-        "libkeymint",
-        "libkeymint_support",
-        "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
         "libpuresoftkeymasterdevice",
     ],
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index c2dba04..9e218b6 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -57,9 +57,11 @@
         "include",
     ],
     shared_libs: [
+        "libbase",
         "libcppbor_external",
         "libcppcose_rkp",
         "libcrypto",
+        "libjsoncpp",
     ],
 }
 
@@ -71,9 +73,11 @@
         "libgtest_main",
     ],
     shared_libs: [
+        "libbase",
         "libcppbor_external",
         "libcppcose_rkp",
         "libcrypto",
+        "libjsoncpp",
         "libkeymaster_portable",
         "libkeymint_remote_prov_support",
     ],
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index b02d273..406b7a9 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -87,4 +87,26 @@
  */
 ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
 
+struct JsonOutput {
+    static JsonOutput Ok(std::string json) { return {std::move(json), ""}; }
+    static JsonOutput Error(std::string error) { return {"", std::move(error)}; }
+
+    std::string output;
+    std::string error;  // if non-empty, this describes what went wrong
+};
+
+/**
+ * Take a given certificate request and output a JSON blob containing both the
+ * build fingerprint and certificate request. This data may be serialized, then
+ * later uploaded to the remote provisioning service. The input csr is not
+ * validated, only encoded.
+ *
+ * Output format:
+ *   {
+ *     "build_fingerprint": <string>
+ *     "csr": <base64 CBOR CSR>
+ *   }
+ */
+JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr);
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 982a1eb..0cbee51 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
+#include <iterator>
 #include <tuple>
 
-#include <remote_prov/remote_prov_utils.h>
-
-#include <openssl/rand.h>
-
+#include <android-base/properties.h>
 #include <cppbor.h>
+#include <json/json.h>
+#include <openssl/base64.h>
+#include <openssl/rand.h>
+#include <remote_prov/remote_prov_utils.h>
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
 
@@ -180,4 +182,36 @@
     return result;
 }
 
+JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr) {
+    const std::string kFingerprintProp = "ro.build.fingerprint";
+
+    if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
+        return JsonOutput::Error("Unable to read build fingerprint");
+    }
+
+    bytevec csrCbor = csr.encode();
+    size_t base64Length;
+    int rc = EVP_EncodedLength(&base64Length, csrCbor.size());
+    if (!rc) {
+        return JsonOutput::Error("Error getting base64 length. Size overflow?");
+    }
+
+    std::vector<char> base64(base64Length);
+    rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), csrCbor.data(), csrCbor.size());
+    ++rc;  // Account for NUL, which BoringSSL does not for some reason.
+    if (rc != base64Length) {
+        return JsonOutput::Error("Error writing base64. Expected " + std::to_string(base64Length) +
+                                 " bytes to be written, but " + std::to_string(rc) +
+                                 " bytes were actually written.");
+    }
+
+    Json::Value json(Json::objectValue);
+    json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
+    json["csr"] = base64.data();  // Boring writes a NUL-terminated c-string
+
+    Json::StreamWriterBuilder factory;
+    factory["indentation"] = "";  // disable pretty formatting
+    return JsonOutput::Ok(Json::writeString(factory, json));
+}
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index c360c06..8697c51 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <android-base/properties.h>
 #include <cppbor_parse.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -23,6 +24,7 @@
 #include <openssl/curve25519.h>
 #include <remote_prov/remote_prov_utils.h>
 #include <cstdint>
+#include "cppbor.h"
 #include "keymaster/cppcose/cppcose.h"
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
@@ -80,5 +82,20 @@
     EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty)));
 }
 
+TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
+    cppbor::Array array;
+    array.add(1);
+
+    auto [json, error] = jsonEncodeCsrWithBuild(array);
+
+    ASSERT_TRUE(error.empty()) << error;
+
+    std::string expected = R"({"build_fingerprint":")" +
+                           ::android::base::GetProperty("ro.build.fingerprint", /*default=*/"") +
+                           R"(","csr":"gQE="})";
+
+    ASSERT_EQ(json, expected);
+}
+
 }  // namespace
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
index 919f882..51938ba 100644
--- a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
+++ b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
@@ -268,10 +268,16 @@
                     << "Shared secret service that provided tweaked param should fail to compute "
                        "shared secret";
         } else {
-            EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed";
-            EXPECT_NE(correct_response, responses[i].sharing_check)
-                    << "Others should calculate a different shared secret, due to the tweaked "
-                       "nonce.";
+            // Other services *may* succeed, or may notice the invalid size for the nonce.
+            // However, if another service completes the computation, it should get the 'wrong'
+            // answer.
+            if (responses[i].error == ErrorCode::OK) {
+                EXPECT_NE(correct_response, responses[i].sharing_check)
+                        << "Others should calculate a different shared secret, due to the tweaked "
+                           "nonce.";
+            } else {
+                EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error);
+            }
         }
     }
 }
@@ -348,10 +354,16 @@
                     << "Shared secret service that provided tweaked param should fail to compute "
                        "shared secret";
         } else {
-            EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed";
-            EXPECT_NE(correct_response, responses[i].sharing_check)
-                    << "Others should calculate a different shared secret, due to the tweaked "
-                       "nonce.";
+            // Other services *may* succeed, or may notice the invalid size for the seed.
+            // However, if another service completes the computation, it should get the 'wrong'
+            // answer.
+            if (responses[i].error == ErrorCode::OK) {
+                EXPECT_NE(correct_response, responses[i].sharing_check)
+                        << "Others should calculate a different shared secret, due to the tweaked "
+                           "seed.";
+            } else {
+                EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error);
+            }
         }
     }
 }