| /* |
| * 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.Certificate; |
| import android.hardware.identity.SecureAccessControlProfile; |
| |
| /** |
| * IWritableIdentityCredential is used to personalize a new identity credential. Credentials cannot |
| * be updated or modified after creation; any changes require deletion and re-creation. |
| */ |
| @VintfStability |
| interface IWritableIdentityCredential { |
| /** |
| * Gets the certificate chain for credentialKey which can be used to prove the hardware |
| * characteristics to an issuing authority. Must not be called more than once. |
| * |
| * 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 Key". (fixed value: |
| * same on all certs) |
| * |
| * - issuer: Same as the subject field of the batch attestation key. |
| * |
| * - validity: Should be set to current time and expire at the same time as the |
| * attestation batch certificate used. |
| * |
| * - subjectPublicKeyInfo: must contain attested public key. |
| * |
| * The certificate chain must be generated using Keymaster Attestation |
| * (see https://source.android.com/security/keystore/attestation) with the |
| * following additional requirements on the data in the attestation extension: |
| * |
| * - The attestationVersion field in the attestation extension must be at least 3. |
| * |
| * - The attestationSecurityLevel field must be set to either Software (0), |
| * TrustedEnvironment (1), or StrongBox (2) depending on how attestation is |
| * implemented. |
| * |
| * - The keymasterVersion field in the attestation extension must be set to the. |
| * same value as used for Android Keystore keys. |
| * |
| * - The keymasterSecurityLevel field in the attestation extension must be set to |
| * either Software (0), TrustedEnvironment (1), or StrongBox (2) depending on how |
| * the Trusted Application backing the HAL implementation is implemented. |
| * |
| * - The attestationChallenge field must be set to the passed-in challenge. |
| * |
| * - The uniqueId field must be empty. |
| * |
| * - The softwareEnforced field in the attestation extension must include |
| * Tag::ATTESTATION_APPLICATION_ID which must be set to the bytes of the passed-in |
| * attestationApplicationId. |
| * |
| * - The teeEnforced field in the attestation extension must include |
| * |
| * - 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). This must not be set |
| * for test credentials. |
| * |
| * - 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 |
| * |
| * - Tag::ROOT_OF_TRUST must be set |
| * |
| * - Tag::OS_VERSION and Tag::OS_PATCHLEVEL must be set |
| * |
| * Additional authorizations may be appear in the softwareEnforced and teeEnforced |
| * fields. For example if the device has a boot or vendor partitions, then BOOT_PATCHLEVEL |
| * and VENDOR_PATCHLEVEL should be set. |
| * |
| * 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 (which include verified boot state), patch level, |
| * attestation 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 |
| * https://developer.android.com/training/articles/security-key-attestation#certificate_schema_attestationid |
| * |
| * @param attestationChallenge a challenge set by the issuer to ensure freshness. If |
| * this is empty, the call fails with STATUS_INVALID_DATA. Implementations must |
| * support challenges of at least 32 bytes. |
| * |
| * @return the X.509 certificate chain for the credentialKey |
| */ |
| Certificate[] getAttestationCertificate( |
| in byte[] attestationApplicationId, in byte[] attestationChallenge); |
| |
| /** |
| * Start the personalization process. |
| * |
| * startPersonalization must not be called more than once. |
| * |
| * The setExpectedProofOfProvisioningSize() method will be called before this method. |
| * |
| * @param accessControlProfileCount specifies the number of access control profiles that will |
| * be provisioned with addAccessControlProfile(). |
| * |
| * @param entryCounts specifies the number of data entries that will be provisioned with |
| * beginAddEntry() and addEntry(). Each item in the array specifies how many entries |
| * will be added for each name space. |
| */ |
| void startPersonalization(in int accessControlProfileCount, in int[] entryCounts); |
| |
| /** |
| * Add an access control profile, which defines the requirements or retrieval of one or more |
| * entries. If both readerCertificate and userAuthenticationRequired are empty/false, |
| * associated entries are open access, requiring no authentication to read (though the caller |
| * is free to require other authentication above this HAL). |
| * |
| * This method must be called exactly as many times as specified in the startPersonalization() |
| * accessControlProfileCount parameter. If this is requirement is not met, the method fails |
| * with STATUS_INVALID_DATA. |
| * |
| * @param id a numeric identifier that must be unique within the context of a Credential and may |
| * be used to reference the profile. This id must be non-negative and less than 32 (allowing |
| * for a total of 32 profiles). If this is not satisfied the call fails with |
| * STATUS_INVALID_DATA. |
| * |
| * @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). |
| * |
| * @param userAuthenticationRequired if true, specifies that the user is required to |
| * authenticate to allow requests. Required authentication freshness is specified by |
| * timeout below. |
| * |
| * @param timeoutMillis specifies the amount of time, in milliseconds, for which a user |
| * authentication (see userAuthenticationRequired above) is valid, if |
| * userAuthenticationRequired is true. If the timout is zero then authentication is |
| * required for each reader session. If userAuthenticationRequired is false, the timeout |
| * must be zero. If this requirement is not met the call fails with STATUS_INVALID_DATA. |
| * |
| * @param secureUserId must be non-zero if userAuthenticationRequired is true. It is not |
| * related to any Android user ID or UID, but is created in the Gatekeeper application |
| * in the secure environment. If this requirement is not met the call fails with |
| * STATUS_INVALID_DATA. |
| * |
| * @return a structure with the passed-in data and MAC created with storageKey for |
| * authenticating the data at a later point in time. |
| */ |
| SecureAccessControlProfile addAccessControlProfile(in int id, in Certificate readerCertificate, |
| in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId); |
| |
| /** |
| * Begins the process of adding an entry to the credential. All access control profiles must be |
| * added before calling this method. Entries must be added in namespace "groups", meaning all |
| * entries of one namespace must be added before adding entries from another namespace. |
| * |
| * This method must be called exactly as many times as the sum of the items in the entryCounts |
| * parameter specified in the startPersonalization(), and must be followed by one or more calls |
| * to addEntryValue(). If this requirement is not met the method fails with STATUS_INVALID_DATA. |
| * |
| * @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.5.1" |
| * |
| * @param name is the name of the element. |
| * |
| * @param entrySize is the size of the entry value. If this requirement |
| * is not met this method fails with STATUS_INVALID_DATA. |
| */ |
| void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace, |
| in @utf8InCpp String name, in int entrySize); |
| |
| /** |
| * Continues the process of adding an entry, providing a value or part of a value. |
| * |
| * In the common case, this method will be called only once per entry added. In the case of |
| * values that are larger than the secure environment's GCM chunk size |
| * (see IIdentityCredentialStore.getHardwareInformation()), the caller must provide the |
| * value in chunks. All chunks must be exactly gcmChunkSize except the last and the sum of all |
| * chunk sizes must equal the value of the beginAddEntry() entrySize argument. If this |
| * requirement is not met the call fails with STATUS_INVALID_DATA. |
| * |
| * @param content is the entry value, encoded as CBOR. In the case the content exceeds |
| * gcmChunkSize, this may be partial content up to gcmChunkSize bytes long. |
| * |
| * @return the encrypted and MACed content. For directly-available credentials the contents are |
| * implementation-defined. For other credentials, the result contains |
| * |
| * AES-GCM-ENC(storageKey, R, Data, AdditionalData) |
| * |
| * where: |
| * |
| * Data = any ; value |
| * |
| * AdditionalData = { |
| * "Namespace" : tstr, |
| * "Name" : tstr, |
| * "AccessControlProfileIds" : [ + uint ], |
| * } |
| */ |
| byte[] addEntryValue(in byte[] content); |
| |
| /** |
| * Finishes adding entries and returns a signature that an issuing authority may use to |
| * validate that all data was provisioned correctly. |
| * |
| * After this method is called, the IWritableIdentityCredential is no longer usable. |
| * |
| * @param out credentialData is a CBOR-encoded structure (in CDDL notation): |
| * |
| * CredentialData = [ |
| * tstr, ; docType, an optional name that identifies the type of credential |
| * bool, ; testCredential, indicates if this is a test credential |
| * bstr ; an opaque byte vector with encrypted data, see below |
| * ] |
| * |
| * The last element is an opaque byte vector which contains encrypted copies of the |
| * secrets used to secure the new credential's data and to authenticate the credential to |
| * the issuing authority. It contains: |
| * |
| * AES-GCM-ENC(HBK, R, CredentialKeys, docType) |
| * |
| * where HBK is a unique hardware-bound key that has never existed outside of the secure |
| * environment (except it's all zeroes if testCredential is True) and CredentialKeys is |
| * the CBOR-encoded structure (in CDDL notation) given below. |
| * |
| * In API versions 1 and 2 it was the following |
| * |
| * CredentialKeys = [ |
| * bstr, ; storageKey, a 128-bit AES key |
| * bstr ; credentialPrivKey, the private key for credentialKey |
| * ; in uncompressed form |
| * ] |
| * |
| * In API version 3 or later it must be the following |
| * |
| * CredentialKeys = [ |
| * bstr, ; storageKey, a 128-bit AES key |
| * bstr ; credentialPrivKey, the private key for credentialKey |
| * ; in uncompressed form |
| * bstr ; SHA-256(ProofOfProvisioning) |
| * ] |
| * |
| * Additional elements may be added to the CredentialKeys array in future versions. |
| * |
| * @param out proofOfProvisioningSignature proves to the IA that the credential was imported |
| * into the secure hardware without alteration or error. When the final addEntry() call is |
| * made (when the number of provisioned entries equals the sum of the items in |
| * startPersonalization() entryCounts parameter), a COSE_Sign1 structure |
| * signed by CredentialKey with payload set to the ProofOfProvisioning CBOR below: |
| * |
| * ProofOfProvisioning = [ |
| * "ProofOfProvisioning", |
| * tstr, ; DocType |
| * [ * AccessControlProfile ], |
| * ProvisionedData, |
| * bool ; true if this is a test credential, should |
| * ; always be false. |
| * ] |
| * |
| * AccessControlProfile = { |
| * "id" : uint, |
| * ? "readerCertificate" : bstr, |
| * ? ( |
| * "userAuthenticationRequired" : bool, |
| * "timeoutMillis" : uint, |
| * ) |
| * } |
| * |
| * ProvisionedData = { |
| * * Namespace => [ + Entry ] |
| * }, |
| * |
| * Namespace = tstr |
| * |
| * Entry = { |
| * "name" : tstr, |
| * "value" : any, |
| * "accessControlProfiles" : [ * uint ], |
| * } |
| */ |
| @SuppressWarnings(value={"out-array"}) |
| void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature); |
| |
| /** |
| * Sets the expected size of the ProofOfProvisioning returned by finishAddingEntries(). This |
| * method must be called before startPersonalization() is called. |
| * |
| * This information is provided to make it possible for a HAL implementation to |
| * incrementally build up cryptographically authenticated data which includes the |
| * ProofOfProvisioning CBOR. |
| * |
| * @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning. |
| */ |
| void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize); |
| |
| /** |
| * Sets the attestation key used to sign the credentialKey certificate. This method is used to |
| * support remotely provisioned attestation keys, removing the credential's dependency on any |
| * factory-provisioned attestation key. |
| * |
| * This method must be called before getAttestationCertificate. After this method is called, |
| * the certificate chain returned by getAttestationCertificate will contain a leaf certificate |
| * signed by attestationKeyBlob and the chain in attestationCertificate will make up the rest |
| * of the returned chain. |
| * |
| * Returns EX_UNSUPPORTED_FUNCTION if remote provisioning is not supported |
| * (see IIdentityCredentialStore.getHardwareInformation()). |
| * |
| * This method was added in API version 4. |
| * |
| * @param attestationKeyBlob is a key blob generated by the IRemotelyProvisionedComponent that |
| * is returned by ICredentialStore.getRemotelyProvisionedComponent. The format is vendor- |
| * specified, and matches the key blob returned by IKeyMintDevice.generateKey. |
| * |
| * @param attestationCertificate contains the X.509 certificate chain that certifies the |
| * attestationKeyBlob. This certificate is expected to have been remotely provisioned |
| * by a trusted authority. This parameter must contain a concatenated chain of DER-encoded |
| * X.509 certificates. The certificates must be ordered such that the attestation key |
| * certificate is first (starting at byte 0). The issuer certificate for the attestation |
| * certificate immediately follows, continuing this chain to the final, root certificate. |
| * |
| * @see getAttestationCertificate |
| * @see android.hardware.identity.ICredentialStore#getRemotelyProvisionedComponent |
| */ |
| void setRemotelyProvisionedAttestationKey( |
| in byte[] attestationKeyBlob, in byte[] attestationCertificate); |
| } |