Identity: Update for changes to ISO 18013-5.
Key derivation for session encryption and MACing now involves mixing
in SessionTranscriptBytes. Update docs, default implementation, and
VTS tests to reflect this.
Also, the standard changed such that instead of DeviceAuthentication
being MACed or signed, it's instead DeviceAuthenticationBytes which is
defined as #6.24(bstr .cbor DeviceAuthentication). The same also for
ReaderAuthentication, now ReaderAuthenticationBytes is the CBOR which
is signed by the reader.
Also update the URL for CDDL since it's now a published RFC.
Bug: 159482543
Test: atest VtsHalIdentityTargetTest
Test: atest android.security.identity.cts
Change-Id: I73fc7eb48ffb71e00a8b54849266ed814295fa39
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp
index 4e9e0e6..87d9a93 100644
--- a/identity/aidl/default/IdentityCredential.cpp
+++ b/identity/aidl/default/IdentityCredential.cpp
@@ -39,6 +39,10 @@
using namespace ::android::hardware::identity;
int IdentityCredential::initialize() {
+ if (credentialData_.size() == 0) {
+ LOG(ERROR) << "CredentialData is empty";
+ return IIdentityCredentialStore::STATUS_INVALID_DATA;
+ }
auto [item, _, message] = cppbor::parse(credentialData_);
if (item == nullptr) {
LOG(ERROR) << "CredentialData is not valid CBOR: " << message;
@@ -312,13 +316,16 @@
}
const vector<uint8_t>& itemsRequestBytes = itemsRequest;
- vector<uint8_t> dataThatWasSigned = cppbor::Array()
- .add("ReaderAuthentication")
- .add(sessionTranscriptItem_->clone())
- .add(cppbor::Semantic(24, itemsRequestBytes))
- .encode();
+ vector<uint8_t> encodedReaderAuthentication =
+ cppbor::Array()
+ .add("ReaderAuthentication")
+ .add(sessionTranscriptItem_->clone())
+ .add(cppbor::Semantic(24, itemsRequestBytes))
+ .encode();
+ vector<uint8_t> encodedReaderAuthenticationBytes =
+ cppbor::Semantic(24, encodedReaderAuthentication).encode();
if (!support::coseCheckEcDsaSignature(readerSignature,
- dataThatWasSigned, // detached content
+ encodedReaderAuthenticationBytes, // detached content
readerPublicKey.value())) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
@@ -774,7 +781,7 @@
array.add(sessionTranscriptItem_->clone());
array.add(docType_);
array.add(cppbor::Semantic(24, encodedDeviceNameSpaces));
- vector<uint8_t> encodedDeviceAuthentication = array.encode();
+ vector<uint8_t> deviceAuthenticationBytes = cppbor::Semantic(24, array.encode()).encode();
vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
optional<vector<uint8_t>> signingKey =
@@ -792,17 +799,24 @@
IIdentityCredentialStore::STATUS_FAILED, "Error doing ECDH"));
}
+ // Mix-in SessionTranscriptBytes
+ vector<uint8_t> sessionTranscriptBytes = cppbor::Semantic(24, sessionTranscript_).encode();
+ vector<uint8_t> sharedSecretWithSessionTranscriptBytes = sharedSecret.value();
+ std::copy(sessionTranscriptBytes.begin(), sessionTranscriptBytes.end(),
+ std::back_inserter(sharedSecretWithSessionTranscriptBytes));
+
vector<uint8_t> salt = {0x00};
vector<uint8_t> info = {};
- optional<vector<uint8_t>> derivedKey = support::hkdf(sharedSecret.value(), salt, info, 32);
+ optional<vector<uint8_t>> derivedKey =
+ support::hkdf(sharedSecretWithSessionTranscriptBytes, salt, info, 32);
if (!derivedKey) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED,
"Error deriving key from shared secret"));
}
- mac = support::coseMac0(derivedKey.value(), {}, // payload
- encodedDeviceAuthentication); // additionalData
+ mac = support::coseMac0(derivedKey.value(), {}, // payload
+ deviceAuthenticationBytes); // detached content
if (!mac) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
IIdentityCredentialStore::STATUS_FAILED, "Error MACing data"));