Identity Credential changes for Android 12
- Add IIdentityCredential.deleteCredentialWithChallenge()
- Deprecate IIdentityCredential.deleteCredential()
- Add IIdentityCredential.proveOwership()
- Add IIdentityCredential.updateCredential()
- Add ProofOfBinding CBOR to AuthenticationKey X.509 certificate
- Document which API versions new methods/features appeared in.
- Mention need to declare android.hardware.identity_credential system
feature (w/ feature version number) and do this for the default
implementation.
Bug: 170146643
Test: atest VtsHalIdentityTargetTest
Change-Id: Ib47c7caa5f3d6fff6919f019eee44a735dba9cf8
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 702334d..d23f88c 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -19,6 +19,7 @@
import android.hardware.identity.Certificate;
import android.hardware.identity.RequestNamespace;
import android.hardware.identity.SecureAccessControlProfile;
+import android.hardware.identity.IWritableIdentityCredential;
import android.hardware.keymaster.HardwareAuthToken;
import android.hardware.keymaster.VerificationToken;
@@ -40,7 +41,11 @@
* After this method has been called, the persistent storage used for credentialData should
* be deleted.
*
- * @return a COSE_Sign1 signature described above.
+ * This method was deprecated in API version 3 because there's no challenge so freshness
+ * can't be checked. Use deleteCredentalWithChallenge() instead.
+ *
+ * @return a COSE_Sign1 signature described above
+ * @deprecated use deleteCredentalWithChallenge() instead.
*/
byte[] deleteCredential();
@@ -353,6 +358,18 @@
*
* - subjectPublicKeyInfo: must contain attested public key.
*
+ * As of API version 3, the certificate shall also have an X.509 extension at
+ * OID 1.3.6.1.4.1.11129.2.1.26 which shall contain an OCTET STRING with the
+ * bytes of the CBOR with the following CDDL:
+ *
+ * ProofOfBinding = [
+ * "ProofOfBinding",
+ * bstr, // Contains SHA-256(ProofOfProvisioning)
+ * ]
+ *
+ * This CBOR enables an issuer to determine the exact state of the credential it
+ * returns issuer-signed data for.
+ *
* @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType)
* where signingKey is an EC private key in uncompressed form. That is, the returned
* blob is an encrypted copy of the newly-generated private signing key.
@@ -381,4 +398,63 @@
* The verification token. This token is only valid if the timestamp field is non-zero.
*/
void setVerificationToken(in VerificationToken verificationToken);
+
+ /**
+ * 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
+ * bstr, ; Challenge
+ * 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.
+ *
+ * This method was introduced in API version 3.
+ *
+ * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
+ * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+ * @return a COSE_Sign1 signature described above.
+ */
+ byte[] deleteCredentialWithChallenge(in byte[] challenge);
+
+ /**
+ * Prove ownership of credential.
+ *
+ * This method returns a COSE_Sign1 data structure signed by CredentialKey with payload
+ * set to the ProofOfOwnership CBOR below.
+ *
+ * ProofOfOwnership = [
+ * "ProofOfOwnership", ; tstr
+ * tstr, ; DocType
+ * bstr, ; Challenge
+ * bool ; true if this is a test credential, should
+ * ; always be false.
+ * ]
+ *
+ * This method was introduced in API version 3.
+ *
+ * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
+ * and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
+ * @return a COSE_Sign1 signature described above.
+ */
+ byte[] proveOwnership(in byte[] challenge);
+
+ /**
+ * Called to start updating the credential with new data items.
+ *
+ * If the getAttestationCertificate() method is called on the returned object
+ * it fails with the error STATUS_FAILED.
+ *
+ * This method was introduced in API version 3.
+ *
+ * @return an IWritableIdentityCredential
+ */
+ IWritableIdentityCredential updateCredential();
}
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 33e25b1..638be79 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -104,6 +104,11 @@
* 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 3 which corresponds to feature version 202101
+ * 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 {
@@ -230,6 +235,9 @@
* 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);
diff --git a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
index c48cb66..5f878ee 100644
--- a/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -263,7 +263,9 @@
*
* 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):
+ * 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
@@ -271,6 +273,17 @@
* ; 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
@@ -321,4 +334,5 @@
* @param expectedProofOfProvisioningSize the expected size of ProofOfProvisioning.
*/
void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+
}