| /* |
| * 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); |
| }; |