Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7bdc955 authored by David Zeuthen's avatar David Zeuthen
Browse files

Update Identity Credential HAL docs.

This change contains no actual syntactical or semantic changes, just
clarifications on the inputs and outputs.

Test: N/A
Bug: 151082886
Merged-In: I794b8d0360c1eda37b4dbe757d7a7fadcbdda7bc
Change-Id: I5ad596ec0fa4dac7473d8fd435f538dbb5529846
parent c578a913
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -24,13 +24,15 @@ package android.hardware.identity;
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.
+45 −16
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ interface IIdentityCredential {
     * 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 @@ interface IIdentityCredential {
     * 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 @@ interface IIdentityCredential {
     * 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 @@ interface IIdentityCredential {
     *     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 @@ interface IIdentityCredential {
     *
     * 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 @@ interface IIdentityCredential {
     * @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 @@ interface IIdentityCredential {
    /**
     * 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.
     *
+17 −20
Original line number Diff line number Diff line
@@ -55,8 +55,8 @@ import android.hardware.identity.CipherSuite;
 *
 * - 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,7 +108,8 @@ import android.hardware.identity.CipherSuite;
@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;

@@ -186,16 +187,19 @@ interface IIdentityCredentialStore {
    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 @@ interface IIdentityCredentialStore {
     * 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 @@ interface IIdentityCredentialStore {
     *     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);
}
+44 −6
Original line number Diff line number Diff line
@@ -60,12 +60,50 @@ interface IWritableIdentityCredential {
     *    attestationApplicationId.
     *
     *  - The teeEnforced field in the attestation extension must include
     *    Tag::IDENTITY_CREDENTIAL_KEY. This tag indicates that the key is an Identity
     *
     *    - 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 @@ interface IWritableIdentityCredential {
     *     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 @@ interface IWritableIdentityCredential {
     * @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.
     *
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ parcelable SecureAccessControlProfile {
    /**
     * 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;