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

Commit c1e8c375 authored by David Zeuthen's avatar David Zeuthen Committed by android-build-merger
Browse files

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

am: ba60e1fa

Change-Id: Ic404209ca7e0b6439f7050e794fe637402c64571
parents bebc590e ba60e1fa
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -615,6 +615,10 @@ dd377f404a8e71f6191d295e10067db629b0f0c28e594af906f2bea5d87fe2cc 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