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

Commit 3e4cf14b authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Add Identity Credential HAL, default implementation, and VTS tests."...

Merge "Add Identity Credential HAL, default implementation, and VTS tests." am: ba60e1fa am: c1e8c375 am: 851142d6

Change-Id: Icc36d5e615a5e17c23fe665d6d2d2121f540764d
parents 586f08ac 851142d6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -640,6 +640,10 @@ ccdf3c0fb2c02a6d4dc57afb276c3497ae8172b80b00ebc0bf8a0238dd38b01d android.hardwar
ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
0589e410f519e36514e7ece18f283f022df0f70efd2c12821d822f67f74aba98 android.hardware.identity@1.0::types
bbeee9604128ede83ee755b67e73b5ad29e6e1dbac9ec41fea6ffe2745b0c50a android.hardware.identity@1.0::IIdentityCredential
96ce8aad80f4c476f25261f790d357c117e79e18474c7dadd850dac704bbe65e android.hardware.identity@1.0::IIdentityCredentialStore
6e1e28a96c90ba78d47257faea3f3bb4e6360affbbfa5822f0dc31211f9266ff android.hardware.identity@1.0::IWritableIdentityCredential
c228aaa27f66c48e147159a4f4996c5273191fece1b08de31bd171c61334855e android.hardware.keymaster@4.1::IKeymasterDevice
adb0efdf1462e9b2e742c0dcadd598666aac551f178be06e755bfcdf5797abd0 android.hardware.keymaster@4.1::IOperation
7a04ea5595ed418ca3e91c28b8bd7353dd988be9be7b0c8c9e64fb4b77bd4523 android.hardware.keymaster@4.1::types
+25 −0
Original line number Diff line number Diff line
// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {
    name: "android.hardware.identity@1.0",
    root: "android.hardware",
    vndk: {
        enabled: true,
    },
    srcs: [
        "types.hal",
        "IIdentityCredential.hal",
        "IIdentityCredentialStore.hal",
        "IWritableIdentityCredential.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
        "android.hardware.keymaster@4.0",
    ],
    types: [
        "AuditLogEntry",
        "ResultCode",
        "SecureAccessControlProfile",
    ],
    gen_java: false,
}
+343 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.identity@1.0;

import android.hardware.keymaster@4.0::HardwareAuthToken;

interface IIdentityCredential {
    /**
     * Delete a credential.
     *
     * This method returns a COSE_Sign1 data structure signed by CredentialKey
     * with payload set to the ProofOfDeletion CBOR below:
     *
     *     ProofOfDeletion = [
     *          "ProofOfDeletion",            ; tstr
     *          tstr,                         ; DocType
     *          bool                          ; true if this is a test credential, should
     *                                        ; always be false.
     *     ]
     *
     * After this method has been called, the persistent storage used for credentialData should
     * be deleted.
     *
     * @return proofOfDeletionSignature is a COSE_Sign1 signature described above.
     */
    deleteCredential()
        generates(Result result, vec<uint8_t> proofOfDeletionSignature);

    /**
     * Creates an ephemeral EC key pair, for use in establishing a seceure session with a reader.
     * This method returns the private key so the caller can perform an ECDH key agreement operation
     * 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.
     *
     * This method may only be called once per instance. If called more than once, FAILED
     * will be returned.
     *
     * @return result is OK on success or FAILED if an error occurred.
     *
     * @return keyPair contains the unencrypted key-pair in PKCS#8 format.
     */
    createEphemeralKeyPair() generates (Result result, vec<uint8_t> keyPair);

    /**
     * Sets the public part of the reader's ephemeral key pair.
     *
     * This method may only be called once per instance. If called more than once, FAILED
     * will be returned.
     *
     * @param publicKey contains the reader's ephemeral public key, in uncompressed form.
     *
     * @return result is OK on success or FAILED if an error occurred.
     */
    setReaderEphemeralPublicKey(vec<uint8_t> publicKey) generates (Result result);

    /**
     * Creates a challenge value to be used for proving successful user authentication. This
     * is included in the authToken passed to the startRetrieval() method.
     *
     * This method may only be called once per instance. If called more than once, FAILED
     * will be returned.
     *
     * @return result is OK on success or FAILED if an error occurred.
     *
     * @return challenge on success, is a non-zero number.
     */
    createAuthChallenge() generates (Result result, uint64_t challenge);

    /**
     * Start an entry retrieval process.
     *
     * 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".
     *
     * It is permissible to perform multiple credential presentations 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
     * fails with the SESSION_TRANSCRIPT_MISMATCH error.
     *
     * If the provided authToken is not valid this method fails with INVALID_AUTH_TOKEN.
     *
     * Each of the provided accessControlProfiles is checked in this call. If they are not
     * all valid, the call fails with INVALID_DATA.
     *
     * For the itemsRequest parameter, the content can be defined in the way appropriate for
     * the credential, but there are three requirements that must be met to work with this HAL:
     *
     *  1. The content must be a CBOR-encoded structure.
     *  2. The CBOR structure must be a map.
     *  3. The map must contain a tstr key "nameSpaces" whose value contains a map, as described in
     *     the example below.
     *
     * If these requirements are not met the startRetrieval() call fails with
     * INVALID_ITEMS_REQUEST_MESSAGE.
     *
     * Here's an example of ItemsRequest CBOR which conforms to this requirement:
     *
     *   ItemsRequest = {
     *     ? "docType" : DocType,
     *       "nameSpaces" : NameSpaces,
     *     ? "requestInfo" : {* tstr => any}   ; Additional info the reader wants to provide
     *   }
     *
     *   DocType = tstr
     *
     *   NameSpaces = {
     *     + NameSpace => DataElements    ; Requested data elements for each NameSpace
     *   }
     *
     *   NameSpace = tstr
     *
     *   DataElements = {
     *     + DataElement => IntentToRetain
     *   }
     *
     *   DataElement = tstr
     *   IntentToRetain = bool
     *
     * For the readerSignature parameter, this can either be empty or if non-empty it
     * must be a COSE_Sign1 structure with an ECDSA signature over the content of the
     * CBOR conforming to the following CDDL:
     *
     *     ReaderAuthentication = [
     *       "ReaderAuthentication",
     *       SessionTranscript,
     *       ItemsRequestBytes
     *     ]
     *
     *     SessionTranscript = [
     *       DeviceEngagementBytes,
     *       EReaderKeyBytes
     *     ]
     *
     *     DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
     *     EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
     *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
     *
     * 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
     * and there may be more (and if so, each certificate must be signed by its successor).
     * This is checked and if the check fails the call fails with READER_SIGNATURE_CHECK_FAILED.
     *
     * The SessionTranscript CBOR is conveyed in the sessionTranscript parameter. It
     * is permissible for this to be empty in which case the readerSignature parameter
     * must also be empty. If this is not the case, the call fails with FAILED.
     *
     * If the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
     * part of the key-pair previously generated by createEphemeralKeyPair() must appear
     * somewhere in the bytes of DeviceEngagement structure. Both X and Y should be in
     * uncompressed form. If this is not satisfied, the call fails with
     * EPHEMERAL_PUBLIC_KEY_NOT_FOUND.
     *
     * @param accessControlProfiles
     *   Access control profiles that are required to retrieve the entries that are going to be
     *   requested with IIdentityCredential.retrieveEntryValue(). See above.
     *
     * @param authToken
     *   The authentication token that proves the user was authenticated, as required
     *   by one or more of the provided accessControlProfiles. See above.
     *
     * @param itemsRequest
     *   If non-empty, contains request data that is signed by the reader. See above.
     *
     * @param sessionTranscript
     *   Either empty or the CBOR of the SessionTranscript. See above.
     *
     * @param readerSignature
     *   readerSignature is either empty or contains a CBOR_Sign1 structure. See above.
     *
     * @param requestCounts
     *   requestCounts specifies the number of data items that are going to be requested, per
     *   namespace.  The number of elements in the vector must be the number of namespaces for which
     *   data items will be requested in retrieveEntryValue() calls, and the values of the elments
     *   must be the number of items from each namespace, in order, that will be requested in
     *   retrieveEntryValue() calls.
     *   Note that it's the caller's responsibility to ensure that the counts correspond to the
     *   retrieveEntryValue() calls that will be made, and that every retrieveEntryValue() call
     *   will succeed (i.e. that the access control profile checks will succeed).  This means that
     *   it's the responsibility of the caller to determine which access control checks will fail
     *   and remove the corresponding requests from the counts.
     *
     * @return result is OK on success. If an error occurs one of the values described above
     *   will be returned.
     */
    startRetrieval(vec<SecureAccessControlProfile> accessControlProfiles,
                   HardwareAuthToken authToken,
                   vec<uint8_t> itemsRequest,
                   vec<uint8_t> sessionTranscript,
                   vec<uint8_t> readerSignature,
                   vec<uint16_t> requestCounts) generates(Result result);

    /**
     * Starts retrieving an entry, subject to access control requirements.  Entries must be
     * retrieved in namespace groups as specified in the requestCounts parameter.
     *
     * If the requestData parameter as passed to startRetrieval() was non-empty
     * this method must only be called with entries specified in that field. If this
     * requirement is not met, the call fails with NOT_IN_REQUEST_MESSAGE.
     *
     * If nameSpace or name is empty this call fails with INVALID_DATA.
     *
     * Each access control profile for the entry is checked. If user authentication
     * is required and the supplied auth token doesn't provide it the call fails
     * with USER_AUTHENTICATION_FAILED. If reader authentication is required and
     * a suitable reader certificate chain isn't presented, the call fails with
     * READER_AUTHENTICATION_FAILED.
     *
     * 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 name is the name of the element.
     *
     * @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 INVALID_DATA.
     *
     * @param accessControlProfileIds specifies the set of access control profiles that can
     *     authorize access to the provisioned element. If an identifier of a profile
     *     is given and this profile wasn't passed to startRetrieval() this call fails
     *     with INVALID_DATA.
     *
     * @return result is OK on success. Otherwise one of INVALID_DATA, FAILED,
     *     USER_AUTHENTICATION_FAILED, READER_AUTHENTICATION_FAILED.
     */
    startRetrieveEntryValue(string nameSpace, string name, uint32_t entrySize,
                            vec<uint16_t> accessControlProfileIds)
        generates (Result result);


    /**
     * Retrieves an entry value, or part of one, if the entry value is larger than gcmChunkSize.
     * May only be called after startRetrieveEntry().
     *
     * If the passed in data is not authentic, can't be decrypted, is of the wrong size, or can't
     * be decoded, this call fails with INVALID_DATA.
     *
     * @param encryptedContent contains the encrypted and MACed content.
     *
     * @return result is OK on success, INVALID_DATA, or FAILED if an error occurred.
     *
     * @return content is the entry value as CBOR, or part of the entry value in the case the
     *    content exceeds gcmChunkSize in length.
     */
    retrieveEntryValue(vec<uint8_t> encryptedContent)
        generates (Result result, vec<uint8_t> content);


    /**
     * End retrieval of data, optionally returning a message authentication code over the
     * returned data.
     *
     * If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
     * empty then the returned MAC will be empty.
     *
     * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
     *    below) containing the signing key to use to sign the data retrieved. If this
     *    is not in the right format the call fails with INVALID_DATA.
     *
     * @return result is OK on success, INVALID_DATA or FAILED if an error occurred.
     *
     * @return 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.
     *
     *        DeviceAuthentication = [
     *            "DeviceAuthentication",
     *            SessionTranscript,
     *            DocType,
     *            DeviceNameSpaceBytes,
     *        ]
     *
     *        DocType = tstr
     *
     *        SessionTranscript = [
     *            DeviceEngagementBytes,
     *            EReaderKeyBytes
     *        ]
     *
     *        DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
     *        EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
     *        DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
     *
     *    where
     *
     *        DeviceNameSpaces = {
     *            * NameSpace => DeviceSignedItems
     *        }
     *        DeviceSignedItems = {
     *            + DataItemName => DataItemValue
     *        }
     *
     *        Namespace = tstr
     *        DataItemName = tstr
     *        DataItemValue = any
     *
     *
     * @return deviceNameSpaces the bytes of DeviceNameSpaces.
     */
    finishRetrieval(vec<uint8_t> signingKeyBlob)
        generates(Result result, vec<uint8_t> mac, vec<uint8_t> deviceNameSpaces);


    /**
     * Generate a key pair to be used for signing session data and retrieved data items.
     *
     * @return result is OK on success or FAILED if an error occurred.
     *
     * @return signingKeyBlob contains an encrypted copy of the newly-generated private signing key.
     *
     * @return signingKeyCertificate contains an X.509 certificate for the new signing key, signed
     *     by the credential key.
     */
    generateSigningKeyPair()
        generates(Result result, vec<uint8_t> signingKeyBlob,
                  vec<uint8_t> signingKeyCertificate);
};
+185 −0

File added.

Preview size limit exceeded, changes collapsed.

+236 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading