Merge "Allow device properties tags for attestation"
diff --git a/automotive/vehicle/2.0/manifest.vehicle.xml b/automotive/vehicle/2.0/manifest.vehicle.xml
new file mode 100644
index 0000000..832b302
--- /dev/null
+++ b/automotive/vehicle/2.0/manifest.vehicle.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device" target-level="3">
+    <hal format="hidl">
+        <name>android.hardware.automotive.vehicle</name>
+        <transport>hwbinder</transport>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/identity/aidl/android/hardware/identity/CipherSuite.aidl b/identity/aidl/android/hardware/identity/CipherSuite.aidl
index 20b02a8..f38134b 100644
--- a/identity/aidl/android/hardware/identity/CipherSuite.aidl
+++ b/identity/aidl/android/hardware/identity/CipherSuite.aidl
@@ -24,13 +24,15 @@
 enum CipherSuite {
     /**
      * Specifies that the cipher suite that will be used to secure communications between the reader
-     * is:
+     * and the prover is using the following primitives
      *
-     * - ECDHE with HKDF-SHA-256 for key agreement.
-     * - AES-256 with GCM block mode for authenticated encryption (nonces are incremented by
-     *   one for every message).
-     * - ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
-     *   man-in-the-middle attacks), signing keys are not ephemeral.
+     *  - ECKA-DH (Elliptic Curve Key Agreement Algorithm - Diffie-Hellman, see BSI TR-03111)
+     *  - HKDF-SHA-256 (see RFC 5869)
+     *  - AES-256-GCM (see NIST SP 800-38D)
+     *  - HMAC-SHA-256 (see RFC 2104)
+     *
+     * The exact way these primitives are combined to derive the session key is specified in
+     * section 9.2.1.4 of ISO/IEC 18013-5 (see description of cipher suite '1').
      *
      * At present this is the only supported cipher suite and it is mandatory for all
      * implementations to support it.
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index cc14271..7d14f03 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -48,6 +48,8 @@
      * with the reader.  The reason for generating the key pair in the secure environment is so that
      * the secure environment knows what public key to expect to find in the session transcript.
      *
+     * The generated key must be an EC key using the P-256 curve.
+     *
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
@@ -61,7 +63,8 @@
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
-     * @param publicKey contains the reader's ephemeral public key, in uncompressed form.
+     * @param publicKey contains the reader's ephemeral public key, in uncompressed
+     *        form (e.g. 0x04 || X || Y).
      */
     void setReaderEphemeralPublicKey(in byte[] publicKey);
 
@@ -82,9 +85,9 @@
      * This method be called after createEphemeralKeyPair(), setReaderEphemeralPublicKey(),
      * createAuthChallenge() and before startRetrieveEntry(). This method call is followed by
      * multiple calls of startRetrieveEntryValue(), retrieveEntryValue(), and finally
-     * finishRetrieval().This whole process is called a "credential presentation".
+     * finishRetrieval().
      *
-     * It is permissible to perform multiple credential presentations using the same instance (e.g.
+     * It is permissible to perform data retrievals multiple times using the same instance (e.g.
      * startRetrieval(), then multiple calls of startRetrieveEntryValue(), retrieveEntryValue(),
      * then finally finishRetrieval()) but if this is done, the sessionTranscript parameter
      * must be identical for each startRetrieval() invocation. If this is not the case, this call
@@ -148,6 +151,8 @@
      *     EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
      *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
      *
+     *     EReaderKey.Pub = COSE_Key    ; Ephemeral public key provided by reader
+     *
      * The public key corresponding to the key used to made signature, can be found in the
      * 'x5chain' unprotected header element of the COSE_Sign1 structure (as as described
      * in 'draft-ietf-cose-x509-04'). There will be at least one certificate in said element
@@ -220,13 +225,11 @@
      *
      * It is permissible to keep retrieving values if an access control check fails.
      *
-     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013.5.1"
      *
-     * @param name is the name of the element.
+     * @param name is the name of the element, e.g. "driving_privileges".
      *
-     * @param entrySize is the size of the entry value, if it's a text string or a byte string.
-     *     It must be zero if the entry value is an integer or boolean. If this requirement
-     *     is not met the call fails with STATUS_INVALID_DATA.
+     * @param entrySize is the size of the entry value encoded in CBOR.
      *
      * @param accessControlProfileIds specifies the set of access control profiles that can
      *     authorize access to the provisioned element. If an identifier of a profile
@@ -260,14 +263,12 @@
      * @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
      *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
      *    and the detached content is set to DeviceAuthentication as defined below.
-     *    The key used for the MAC operation is EMacKey and is derived as follows:
-     *
-     *     KDF(ECDH(SDeviceKey.Priv, EReaderKey.Pub))
-     *
-     *    where SDeviceKey.Priv is the key identified by signingKeyBlob. The KDF
-     *    and ECDH functions shall be the same as the ciphersuite selected and
-     *    passed to IIdentityStore.getCredential(). The EMacKey shall be derived
-     *    using a salt of 0x00.
+     *    This code is produced by using the key agreement and key derivation function
+     *    from the ciphersuite with the authentication private key and the reader
+     *    ephemeral public key to compute a shared message authentication code (MAC)
+     *    key, then using the MAC function from the ciphersuite to compute a MAC of
+     *    the authenticated data. See section 9.2.3.5 of ISO/IEC 18013-5 for details
+     *    of this operation.
      *
      *        DeviceAuthentication = [
      *            "DeviceAuthentication",
@@ -308,6 +309,34 @@
     /**
      * Generate a key pair to be used for signing session data and retrieved data items.
      *
+     * The generated key must be an EC key using the P-256 curve.
+     *
+     * This method shall return just a single X.509 certificate which is signed by CredentialKey.
+     * When combined with the certificate chain returned at provisioning time by
+     * getAttestationCertificate() on IWritableIdentityCredential (for the credential key), this
+     * forms a chain all the way from the root of trust to the generated key.
+     *
+     * The public part of a signing key is usually included in issuer-signed data and is
+     * used for anti-cloning purposes or as a mechanism for the issuer to attest to data
+     * generated on the device.
+     *
+     * The following non-optional fields for the X.509 certificate shall be set as follows:
+     *
+     *  - version: INTEGER 2 (means v3 certificate).
+     *
+     *  - serialNumber: INTEGER 1 (fixed value: same on all certs).
+     *
+     *  - signature: must be set to ECDSA.
+     *
+     *  - subject: CN shall be set to "Android Identity Credential Authentication Key".
+     *
+     *  - issuer: shall be set to "credentialStoreName (credentialStoreAuthorName)" using the
+     *    values returned in HardwareInformation.
+     *
+     *  - validity: should be from current time and one year in the future.
+     *
+     *  - subjectPublicKeyInfo: must contain attested public key.
+     *
      * @param out signingKeyBlob contains an encrypted copy of the newly-generated private
      *     signing key.
      *
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 23cb1b7..bd664e8 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -55,8 +55,8 @@
  *
  * - For each namespase, a set of name/value pairs, each with an associated set of access control
  *   profile IDs.  Names are UTF-8 strings of up to 256 bytes in length (most should be much
- *   shorter).  Values stored must be encoed as valid CBOR (https://tools.ietf.org/html/rfc7049) and
- *   the encoeded size is is limited to at most 512 KiB.
+ *   shorter).  Values stored must be encoded as CBOR (https://tools.ietf.org/html/rfc7049) and
+ *   the encoded size is is limited to at most 512 KiB.
  *
  * - A set of access control profiles, each with a profile ID and a specification of the
  *   conditions which satisfy the profile's requirements.
@@ -108,12 +108,13 @@
 @VintfStability
 interface IIdentityCredentialStore {
     /**
-     * Success.
+     * Success. This is never returned but included for completeness and for use by code
+     * using these statuses for internal use.
      */
     const int STATUS_OK = 0;
 
     /**
-     * The operation failed. This is used as a generic catch-all for errors that don't belong
+     * The operation failed.  This is used as a generic catch-all for errors that don't belong
      * in other categories, including memory/resource allocation failures and I/O errors.
      */
     const int STATUS_FAILED = 1;
@@ -124,7 +125,7 @@
     const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
 
     /**
-     * The passed data was invalid. This is a generic catch all for errors that don't belong
+     * The passed data was invalid.  This is a generic catch all for errors that don't belong
      * in other categories related to parameter validation.
      */
     const int STATUS_INVALID_DATA = 3;
@@ -186,16 +187,19 @@
     HardwareInformation getHardwareInformation();
 
     /**
-     * createCredential creates a new Credential.  When a Credential is created, two cryptographic
+     * createCredential creates a new credential.  When a credential is created, two cryptographic
      * keys are created: StorageKey, an AES key used to secure the externalized Credential
-     * contents, and CredentialKeyPair, an EC key pair used to authenticate the store to the IA.  In
-     * addition, all of the Credential data content is imported and a certificate for the
-     * CredentialKeyPair and a signature produced with the CredentialKeyPair are created.  These
+     * contents, and CredentialKey, an EC key pair used to authenticate the store to the IA.
+     *
+     * CredentialKey must be an EC key using the P-256 curve.
+     *
+     * In addition, all of the Credential data content is imported and a certificate for the
+     * CredentialKey and a signature produced with the CredentialKey are created.  These
      * latter values may be checked by an issuing authority to verify that the data was imported
      * into secure hardware and that it was imported unmodified.
      *
      * @param docType is an optional name (may be an empty string) that identifies the type of
-     *     credential being created, e.g. "org.iso.18013-5.2019.mdl" (the doc type of the ISO
+     *     credential being created, e.g. "org.iso.18013.5.1.mDL" (the doc type of the ISO
      *     driving license standard).
      *
      * @param testCredential indicates if this is a test store.  Test credentials must use an
@@ -213,15 +217,8 @@
      * Credential.
      *
      * The cipher suite used to communicate with the remote verifier must also be specified. Currently
-     * only a single cipher-suite is supported and the details of this are as follow:
-     *
-     *  - ECDHE with HKDF-SHA-256 for key agreement.
-     *  - AES-256 with GCM block mode for authenticated encryption (nonces are incremented by one
-     *    for every message).
-     *  - ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
-     *    man-in-the-middle attacks), signing keys are not ephemeral.
-     *
-     * Support for other cipher suites may be added in a future version of this HAL.
+     * only a single cipher-suite is supported. Support for other cipher suites may be added in a
+     * future version of this HAL.
      *
      * This method fails with STATUS_INVALID_DATA if the passed in credentialData cannot be
      * decoded or decrypted.
@@ -233,7 +230,7 @@
      *     return argument of the same name in finishAddingEntries(), in
      *     IWritableIdentityCredential.
      *
-     * @return an IIdentityCredential HIDL interface that provides operations on the Credential.
+     * @return an IIdentityCredential interface that provides operations on the Credential.
      */
     IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData);
 }
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index 483b0c7..9673821 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -60,12 +60,50 @@
      *    attestationApplicationId.
      *
      *  - The teeEnforced field in the attestation extension must include
-     *    Tag::IDENTITY_CREDENTIAL_KEY. This tag indicates that the key is an Identity
-     *    Credential key (which can only sign/MAC very specific messages) and not an Android
-     *    Keystore key (which can be used to sign/MAC anything).
+     *
+     *    - Tag::IDENTITY_CREDENTIAL_KEY which indicates that the key is an Identity
+     *      Credential key (which can only sign/MAC very specific messages) and not an Android
+     *      Keystore key (which can be used to sign/MAC anything).
+     *
+     *    - Tag::PURPOSE must be set to SIGN
+     *
+     *    - Tag::KEY_SIZE must be set to the appropriate key size, in bits (e.g. 256)
+     *
+     *    - Tag::ALGORITHM must be set to EC
+     *
+     *    - Tag::NO_AUTH_REQUIRED must be set
+     *
+     *    - Tag::DIGEST must be set to SHA_2_256
+     *
+     *    - Tag::EC_CURVE must be set to P_256
      *
      * Additional authorizations may be needed in the softwareEnforced and teeEnforced
-     * fields - the above is not an exhaustive list.
+     * fields - the above is not an exhaustive list. Specifically, authorizations containing
+     * information about the root of trust, OS version, verified boot state, and so on should
+     * be included.
+     *
+     * Since the chain is required to be generated using Keymaster Attestation, the returned
+     * certificate chain has the following properties:
+     *
+     *  - The certificate chain is of at least length three.
+     *
+     *  - The root of trust is the same as for Keymaster Attestation. This is usually
+     *    a certificate owned by Google but depending on the specific Android device it may
+     *    be another certificate.
+     *
+     * As with any user of attestation, the Issuing Authority (as a relying party) wishing
+     * to issue a credential to a device using these APIs, must carefully examine the
+     * returned certificate chain for all of the above (and more). In particular, the Issuing
+     * Authority should check the root of trust, verified boot state, patch level,
+     * application id, etc.
+     *
+     * This all depends on the needs of the Issuing Authority and the kind of credential but
+     * in general an Issuing Authority should never issue a credential to a device without
+     * verified boot enabled, to an unrecognized application, or if it appears the device
+     * hasn't been updated for a long time.
+     *
+     * See https://github.com/google/android-key-attestation for an example of how to
+     * examine attestations generated from Android devices.
      *
      * @param attestationApplicationId is the DER encoded value to be stored
      *     in Tag::ATTESTATION_APPLICATION_ID. This schema is described in
@@ -105,7 +143,7 @@
      *     be used to reference the profile. If this is not satisfied the call fails with
      *     STATUS_INVALID_DATA.
      *
-     * @param readerCertificate if non-empty, specifies a X.509 certificate (or chain of
+     * @param readerCertificate if non-empty, specifies a single X.509 certificate (not a chain of
      *     certificates) that must be used to authenticate requests (see the readerSignature
      *     parameter in IIdentityCredential.startRetrieval).
      *
@@ -142,7 +180,7 @@
      * @param accessControlProfileIds specifies the set of access control profiles that can
      *     authorize access to the provisioned element.
      *
-     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013.5.1"
      *
      * @param name is the name of the element.
      *
diff --git a/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
index 01d312d..13f0c6d 100644
--- a/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
+++ b/identity/aidl/android/hardware/identity/SecureAccessControlProfile.aidl
@@ -29,7 +29,7 @@
     /**
      * readerCertificate, if non-empty, specifies a single X.509 certificate (not a chain
      * of certificates) that must be used to authenticate requests. For details about how
-     * this is done, see the readerSignature paremter of IIdentityCredential.startRetrieval.
+     * this is done, see the readerSignature parameter of IIdentityCredential.startRetrieval.
      */
     Certificate readerCertificate;
 
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 4c0100e..e590fda 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -535,13 +535,18 @@
     removeValueAndDecrementGreaterValues(&model->main.outputIndexes, index);
 }
 
-static bool removeOperandSkip(size_t operand, const Model& model) {
+static bool removeOperandSkip(size_t operandIndex, const Model& model) {
+    const Operand& operand = model.main.operands[operandIndex];
+    if (operand.numberOfConsumers == 0) {
+        // Removing an unused operand has no effect.
+        return true;
+    }
     for (const Operation& operation : model.main.operations) {
         // Skip removeOperandTest for the following operations.
         // - SPLIT's outputs are not checked during prepareModel.
         if (operation.type == OperationType::SPLIT) {
-            for (const size_t outOprand : operation.outputs) {
-                if (operand == outOprand) {
+            for (const size_t index : operation.outputs) {
+                if (index == operandIndex) {
                     return true;
                 }
             }
@@ -556,8 +561,8 @@
             operation.type == OperationType::UNIDIRECTIONAL_SEQUENCE_RNN ||
             operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_LSTM ||
             operation.type == OperationType::BIDIRECTIONAL_SEQUENCE_RNN) {
-            for (const size_t outOprand : operation.outputs) {
-                if (operand == outOprand) {
+            for (const size_t index : operation.outputs) {
+                if (index == operandIndex) {
                     return true;
                 }
             }
diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp
index 4765fa2..7755ef5 100644
--- a/sensors/2.0/vts/functional/Android.bp
+++ b/sensors/2.0/vts/functional/Android.bp
@@ -33,5 +33,9 @@
         "libfmq",
         "VtsHalSensorsTargetTestUtils",
     ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
 
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 9236b95..1a8fd3b 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -163,6 +163,10 @@
             }
             LOG(INFO) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
                       << e.scale;
+
+            int32_t durationMs;
+            getPrimitiveDuration(e.primitive, &durationMs);
+            usleep(durationMs * 1000);
         }
 
         if (callback != nullptr) {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 411fe7a..9a1b660 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -33,6 +33,7 @@
 using android::hardware::vibrator::Effect;
 using android::hardware::vibrator::EffectStrength;
 using android::hardware::vibrator::IVibrator;
+using std::chrono::high_resolution_clock;
 
 const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
                                    android::enum_range<Effect>().end()};
@@ -381,26 +382,52 @@
 }
 
 TEST_P(VibratorAidl, ComposeCallback) {
+    constexpr std::chrono::milliseconds allowedLatency{10};
+
     if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
-        std::promise<void> completionPromise;
-        std::future<void> completionFuture{completionPromise.get_future()};
-        sp<CompletionCallback> callback =
-                new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
-        CompositePrimitive primitive = CompositePrimitive::CLICK;
-        CompositeEffect effect;
-        std::vector<CompositeEffect> composite;
-        int32_t duration;
+        std::vector<CompositePrimitive> supported;
 
-        effect.delayMs = 0;
-        effect.primitive = primitive;
-        effect.scale = 1.0f;
-        composite.emplace_back(effect);
+        ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
 
-        EXPECT_EQ(Status::EX_NONE,
-                  vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
-        EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode());
-        EXPECT_EQ(completionFuture.wait_for(std::chrono::milliseconds(duration * 2)),
-                  std::future_status::ready);
+        for (auto primitive : supported) {
+            if (primitive == CompositePrimitive::NOOP) {
+                continue;
+            }
+
+            std::promise<void> completionPromise;
+            std::future<void> completionFuture{completionPromise.get_future()};
+            sp<CompletionCallback> callback =
+                    new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+            CompositeEffect effect;
+            std::vector<CompositeEffect> composite;
+            int32_t durationMs;
+            std::chrono::milliseconds duration;
+            std::chrono::time_point<high_resolution_clock> start, end;
+            std::chrono::milliseconds elapsed;
+
+            effect.delayMs = 0;
+            effect.primitive = primitive;
+            effect.scale = 1.0f;
+            composite.emplace_back(effect);
+
+            EXPECT_EQ(Status::EX_NONE,
+                      vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
+                    << toString(primitive);
+            duration = std::chrono::milliseconds(durationMs);
+
+            EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
+                    << toString(primitive);
+            start = high_resolution_clock::now();
+
+            EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency),
+                      std::future_status::ready)
+                    << toString(primitive);
+            end = high_resolution_clock::now();
+
+            elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+            EXPECT_LE(elapsed.count(), (duration + allowedLatency).count()) << toString(primitive);
+            EXPECT_GE(elapsed.count(), (duration - allowedLatency).count()) << toString(primitive);
+        }
     }
 }