blob: d3e4da04a0554f7fdee10d78186a3268e65c72e9 [file] [log] [blame]
/*
* 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;
import android.hardware.identity.CipherSuite;
import android.hardware.identity.HardwareInformation;
import android.hardware.identity.IIdentityCredential;
import android.hardware.identity.IPresentationSession;
import android.hardware.identity.IWritableIdentityCredential;
import android.hardware.security.keymint.IRemotelyProvisionedComponent;
/**
* IIdentityCredentialStore provides an interface to a secure store for user identity documents.
* This HAL is deliberately fairly general and abstract. To the extent possible, specification of
* the message formats and semantics of communication with credential verification devices and
* issuing authorities (IAs) is out of scope for this HAL. It provides the interface with secure
* storage but a credential-specific Android application will be required to implement the
* presentation and verification protocols and processes appropriate for the specific credential
* type.
*
* The design of this HAL makes few assumptions about the underlying secure hardware. In particular
* it does not assume that the secure hardware has any storage beyond that needed for a persistent,
* hardware-bound AES-128 key. However, its design allows the use of secure hardware that does have
* storage, specifically to enable "direct access". Most often credentials will be accessed through
* this HAL and through the Android layers above it but that requires that the Android device be
* powered up and fully functional. It is desirable to allow identity credential usage when the
* Android device's battery is too low to boot the Android operating system, so direct access to the
* secure hardware via NFC may allow data retrieval, if the secure hardware chooses to implement it.
* Definition of how data is retrieved in low power mode is explicitly out of scope for this HAL
* specification; it's up to the relevant identity credential standards to define.
*
* The 'default' HAL instance is explicitly not for direct access and the 'direct_access' HAL
* instance - if available - is for direct access. Applications are expected to provision their
* credential to both instances (and the contents may differ), not just one of them.
*
* Multiple credentials can be created. Each credential comprises:
*
* - A document type, which is a UTF-8 string of at most 256 bytes.
*
* - A set of namespaces, which serve to disambiguate value names. Namespaces are UTF-8 strings of
* up to 256 bytes in length (most should be much shorter). It is recommended that namespaces be
* structured as reverse domain names so that IANA effectively serves as the namespace registrar.
*
* - 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 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.
*
* - An asymmetric key pair which is used to authenticate the credential to the IA, called the
* CredentialKey. This key is attested to by the secure hardware using Android Keystore
* attestation (https://source.android.com/security/keystore/attestation). See
* getAttestationCertificate() in the IWritableIdentityCredential for more information.
*
* - A set of zero or more named reader authentication public keys, which are used to authenticate
* an authorized reader to the credential.
*
* - A set of named signing keys, which are used to sign collections of values and session
* transcripts.
*
* Cryptographic notation:
*
* Throughout this HAL, cryptographic operations are specified in detail. To avoid repeating the
* definition of the notation, it's specified here. It is assumed that the reader is familiar with
* standard cryptographic algorithms and constructs.
*
* AES-GCM-ENC(K, N, D, A) represents AES-GCM encryption with key 'K', nonce 'N', additional
* authenticated data 'A' and data 'D'. The nonce is usually specified as 'R', meaning 12
* random bytes. The nonce is always 12 bytes and is prepended to the ciphertext. The GCM
* tag is 16 bytes, appended to the ciphertext. AES-GCM-DEC with the same argument notation
* represents the corresponding decryption operation.
*
* ECDSA(K, D) represents ECDSA signing of data 'D' with key 'K'.
*
* || represents concatenation
*
* {} represents an empty input; 0 bytes of data.
*
* HBK represents a device-unique, hardware-bound AES-128 key which exists only in secure
* hardware, except for "test" credential stores (see createCredential(), below). For test
* stores, an all-zero value is used in place of the HBK.
*
* Data encoding notation:
*
* Various fields need to be encoded as precisely-specified byte arrays. Where existing standards
* define appropriate encodings, those are used. For example, X.509 certificates. Where new
* encodings are needed, CBOR is used. CBOR maps are described in CDDL notation
* (https://tools.ietf.org/html/rfc8610).
*
* All binder calls in the HAL may return a ServiceSpecificException with statuses from the
* STATUS_* integers defined in this interface. Each method states which status can be returned
* and under which circumstances.
*
* The API described here is API version 4 which corresponds to feature version 202201
* of the android.security.identity Framework API. An XML file declaring the feature
* android.hardware.identity_credential (or android.hardware.identity_credential.direct_access
* if implementing the Direct Access HAL) should be included declaring this feature version.
*/
@VintfStability
interface IIdentityCredentialStore {
/**
* 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
* in other categories, including memory/resource allocation failures and I/O errors.
*/
const int STATUS_FAILED = 1;
/**
* Unsupported cipher suite.
*/
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
* in other categories related to parameter validation.
*/
const int STATUS_INVALID_DATA = 3;
/**
* The authToken parameter passed to IIdentityCredential.startRetrieval() is not valid.
*/
const int STATUS_INVALID_AUTH_TOKEN = 4;
/**
* The itemsRequest parameter passed to IIdentityCredential.startRetrieval() does not meet
* the requirements described in the documentation for that method.
*/
const int STATUS_INVALID_ITEMS_REQUEST_MESSAGE = 5;
/**
* The readerSignature parameter in IIdentityCredential.startRetrieval() is invalid,
* doesn't contain an embedded certificate chain, or the signature failed to
* validate.
*/
const int STATUS_READER_SIGNATURE_CHECK_FAILED = 6;
/**
* The sessionTranscript passed to startRetrieval() did not contain the ephmeral public
* key returned by createEphemeralPublicKey().
*/
const int STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND = 7;
/**
* An access condition related to user authentication was not satisfied.
*/
const int STATUS_USER_AUTHENTICATION_FAILED = 8;
/**
* An access condition related to reader authentication was not satisfied.
*/
const int STATUS_READER_AUTHENTICATION_FAILED = 9;
/**
* The request data element has no access control profiles associated so it cannot be accessed.
*/
const int STATUS_NO_ACCESS_CONTROL_PROFILES = 10;
/**
* The requested data element is not in the provided non-empty itemsRequest message.
*/
const int STATUS_NOT_IN_REQUEST_MESSAGE = 11;
/**
* The passed-in sessionTranscript doesn't match the previously passed-in sessionTranscript.
*/
const int STATUS_SESSION_TRANSCRIPT_MISMATCH = 12;
/**
* Returns information about hardware.
*
* @return a HardwareInformation with information about the hardware.
*/
HardwareInformation getHardwareInformation();
/**
* 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 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.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
* all-zeros hardware-bound key (HBK) and must set the test bit in the
* personalizationReceipt (see finishAddingEntries(), in IWritableIdentityCredential).
*
* @return an IWritableIdentityCredential interface that provides operations to
* provision a credential.
*/
IWritableIdentityCredential createCredential(
in @utf8InCpp String docType, in boolean testCredential);
/**
* getCredential retrieves an IIdentityCredential interface which allows use of a stored
* Credential.
*
* The cipher suite used to communicate with the remote verifier must also be specified.
* Currently 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.
*
* @param cipherSuite is the cipher suite to use.
*
* @param credentialData is a CBOR-encoded structure containing metadata about the credential
* and an encrypted byte array that contains data used to secure the credential. See the
* return argument of the same name in finishAddingEntries(), in
* IWritableIdentityCredential.
*
* Note that the format of credentialData may depend on the feature version.
* Implementations must support credentialData created by an earlier feature version.
*
* @return an IIdentityCredential interface that provides operations on the Credential.
*/
IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData);
/**
* createPresentationSession creates IPresentationSession interface which can be used to
* present one or more credentials to a remote verifier device.
*
* The cipher suite used to communicate with the remote verifier must be specified. Currently
* only a single cipher-suite is supported. Support for other cipher suites may be added in a
* future version of this HAL. If the requested cipher suite is not support the call fails
* with STATUS_CIPHER_SUITE_NOT_SUPPORTED.
*
* In this version of the HAL, implementations are only required to support a single session
* being active. In a future version, implementations may be required to support multiple
* presentation sessions being active at the same time.
*
* This method was introduced in API version 4.
*
* @param cipherSuite The cipher suite to use.
*
* @return an IPresentationSession interface.
*/
IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
/**
* Fetch the IRemotelyProvisionedComponent that is used to generate attestation keys for
* remote provisionining. Keys generated by this component are to be certified by a remote
* provisionined authority, then used to attest to credential keys via
* IWritableIdentityCredential.setRemotelyProvisionedAttestationKey.
*
* Support for this method is indicated by HardwareInformation. If the
* |isRemoteKeyProvisioningSupported| field is false, this method will fail with
* EX_UNSUPPORTED_OPERATION.
*
* This method was added in API version 4.
*
* @see
* android.hardware.identity.IWritableIdentityCredential#setRemotelyProvisionedAttestationKey
*
* @return an IRemotelyProvisionedComponent that is used to generate attestation keys.
*/
IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
}