diff options
author | Joseph Jang <josephjang@google.com> | 2021-09-01 16:50:09 +0800 |
---|---|---|
committer | Joseph Jang <josephjang@google.com> | 2021-09-06 18:27:08 +0800 |
commit | dabb3c515fc17e358a19ff78cd3d7a6fccd0a15c (patch) | |
tree | 783ae8bc42632fa0f9dbf1ecbe2079531c784670 /identity/aidl/default | |
parent | 334a6134deb33e3ebdb1c5b5e1989a5e049ed3b2 (diff) |
identity: Make NoS libeic and AOSP libeic align
1. Add input parameter buffer size for CBOR data encoding
because Nugget OS protobuf buffer is not null terminated.
2. Modify some libeic APIs to align with NoS libeic.
Bug: 198403263
Test: atest VtsHalIdentityTargetTest
atest android.security.identity.cts
Change-Id: I9bc3689da2571c0925972f33b7314cbaaad0e28d
Diffstat (limited to 'identity/aidl/default')
-rw-r--r-- | identity/aidl/default/FakeSecureHardwareProxy.cpp | 82 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicCbor.c | 44 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicCbor.h | 24 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicCommon.h | 44 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicPresentation.c | 105 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicPresentation.h | 36 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicProvisioning.c | 69 | ||||
-rw-r--r-- | identity/aidl/default/libeic/EicProvisioning.h | 24 | ||||
-rw-r--r-- | identity/aidl/default/libeic/libeic.h | 1 |
9 files changed, 268 insertions, 161 deletions
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp index 287ffb82e1..f0307dc324 100644 --- a/identity/aidl/default/FakeSecureHardwareProxy.cpp +++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp @@ -70,6 +70,7 @@ bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) { bool FakeSecureHardwareProvisioningProxy::initializeForUpdate( bool testCredential, string docType, vector<uint8_t> encryptedCredentialKeys) { return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(), + docType.size(), encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); } @@ -92,8 +93,11 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialK bool FakeSecureHardwareProvisioningProxy::startPersonalization( int accessControlProfileCount, vector<int> entryCounts, const string& docType, size_t expectedProofOfProvisioningSize) { - if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount, entryCounts.data(), - entryCounts.size(), docType.c_str(), + + if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount, + entryCounts.data(), + entryCounts.size(), + docType.c_str(), docType.size(), expectedProofOfProvisioningSize)) { return false; } @@ -105,9 +109,11 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlP int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired, uint64_t timeoutMillis, uint64_t secureUserId) { vector<uint8_t> mac(28); + uint8_t scratchSpace[512]; if (!eicProvisioningAddAccessControlProfile( &ctx_, id, readerCertificate.data(), readerCertificate.size(), - userAuthenticationRequired, timeoutMillis, secureUserId, mac.data())) { + userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(), + scratchSpace, sizeof(scratchSpace))) { return {}; } return mac; @@ -117,9 +123,15 @@ bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& acces const string& nameSpace, const string& name, uint64_t entrySize) { uint8_t scratchSpace[512]; - return eicProvisioningBeginAddEntry(&ctx_, accessControlProfileIds.data(), - accessControlProfileIds.size(), nameSpace.c_str(), - name.c_str(), entrySize, scratchSpace, sizeof scratchSpace); + vector<uint8_t> uint8AccessControlProfileIds; + for (size_t i = 0; i < accessControlProfileIds.size(); i++) { + uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF); + } + + return eicProvisioningBeginAddEntry(&ctx_, uint8AccessControlProfileIds.data(), + uint8AccessControlProfileIds.size(), nameSpace.c_str(), + nameSpace.size(), name.c_str(), name.size(), entrySize, + scratchSpace, sizeof(scratchSpace)); } // Returns encryptedContent. @@ -128,11 +140,16 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue( const vector<uint8_t>& content) { vector<uint8_t> eicEncryptedContent; uint8_t scratchSpace[512]; + vector<uint8_t> uint8AccessControlProfileIds; + for (size_t i = 0; i < accessControlProfileIds.size(); i++) { + uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF); + } + eicEncryptedContent.resize(content.size() + 28); if (!eicProvisioningAddEntryValue( - &ctx_, accessControlProfileIds.data(), accessControlProfileIds.size(), - nameSpace.c_str(), name.c_str(), content.data(), content.size(), - eicEncryptedContent.data(), scratchSpace, sizeof scratchSpace)) { + &ctx_, uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), + nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), content.data(), + content.size(), eicEncryptedContent.data(), scratchSpace, sizeof(scratchSpace))) { return {}; } return eicEncryptedContent; @@ -152,7 +169,7 @@ optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredenti const string& docType) { vector<uint8_t> encryptedCredentialKeys(116); size_t size = encryptedCredentialKeys.size(); - if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), + if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(), encryptedCredentialKeys.data(), &size)) { return {}; } @@ -170,7 +187,7 @@ bool FakeSecureHardwarePresentationProxy::initialize(bool testCredential, string vector<uint8_t> encryptedCredentialKeys) { LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): " << sizeof(EicPresentation); - return eicPresentationInit(&ctx_, testCredential, docType.c_str(), + return eicPresentationInit(&ctx_, testCredential, docType.c_str(), docType.size(), encryptedCredentialKeys.data(), encryptedCredentialKeys.size()); } @@ -181,8 +198,9 @@ FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time size_t publicKeyCertSize = sizeof(publicKeyCert); vector<uint8_t> signingKeyBlob(60); - if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), now, publicKeyCert, - &publicKeyCertSize, signingKeyBlob.data())) { + if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now, + publicKeyCert, &publicKeyCertSize, + signingKeyBlob.data())) { return {}; } @@ -244,10 +262,12 @@ optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired, int timeoutMillis, uint64_t secureUserId, const vector<uint8_t>& mac) { bool accessGranted = false; + uint8_t scratchSpace[512]; if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(), readerCertificate.size(), userAuthenticationRequired, timeoutMillis, - secureUserId, mac.data(), &accessGranted)) { + secureUserId, mac.data(), &accessGranted, + scratchSpace, sizeof(scratchSpace))) { return {}; } return accessGranted; @@ -267,7 +287,7 @@ bool FakeSecureHardwarePresentationProxy::calcMacKey( } return eicPresentationCalcMacKey(&ctx_, sessionTranscript.data(), sessionTranscript.size(), readerEphemeralPublicKey.data(), signingKeyBlob.data(), - docType.c_str(), numNamespacesWithValues, + docType.c_str(), docType.size(), numNamespacesWithValues, expectedProofOfProvisioningSize); } @@ -275,10 +295,16 @@ AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue( const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries, int32_t entrySize, const vector<int32_t>& accessControlProfileIds) { uint8_t scratchSpace[512]; + vector<uint8_t> uint8AccessControlProfileIds; + for (size_t i = 0; i < accessControlProfileIds.size(); i++) { + uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF); + } + EicAccessCheckResult result = eicPresentationStartRetrieveEntryValue( - &ctx_, nameSpace.c_str(), name.c_str(), newNamespaceNumEntries, entrySize, - accessControlProfileIds.data(), accessControlProfileIds.size(), scratchSpace, - sizeof scratchSpace); + &ctx_, nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), + newNamespaceNumEntries, entrySize, uint8AccessControlProfileIds.data(), + uint8AccessControlProfileIds.size(), scratchSpace, + sizeof(scratchSpace)); switch (result) { case EIC_ACCESS_CHECK_RESULT_OK: return AccessCheckResult::kOk; @@ -299,12 +325,18 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValu const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name, const vector<int32_t>& accessControlProfileIds) { uint8_t scratchSpace[512]; + vector<uint8_t> uint8AccessControlProfileIds; + for (size_t i = 0; i < accessControlProfileIds.size(); i++) { + uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF); + } + vector<uint8_t> content; content.resize(encryptedContent.size() - 28); if (!eicPresentationRetrieveEntryValue( &ctx_, encryptedContent.data(), encryptedContent.size(), content.data(), - nameSpace.c_str(), name.c_str(), accessControlProfileIds.data(), - accessControlProfileIds.size(), scratchSpace, sizeof scratchSpace)) { + nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), + uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(), + scratchSpace, sizeof(scratchSpace))) { return {}; } return content; @@ -324,9 +356,9 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential( const string& docType, const vector<uint8_t>& challenge, bool includeChallenge, size_t proofOfDeletionCborSize) { vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); - if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), challenge.data(), challenge.size(), - includeChallenge, proofOfDeletionCborSize, - signatureOfToBeSigned.data())) { + if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(), + challenge.size(), includeChallenge, + proofOfDeletionCborSize, signatureOfToBeSigned.data())) { return {}; } return signatureOfToBeSigned; @@ -336,8 +368,8 @@ optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership( const string& docType, bool testCredential, const vector<uint8_t>& challenge, size_t proofOfOwnershipCborSize) { vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE); - if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), testCredential, challenge.data(), - challenge.size(), proofOfOwnershipCborSize, + if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential, + challenge.data(), challenge.size(), proofOfOwnershipCborSize, signatureOfToBeSigned.data())) { return {}; } diff --git a/identity/aidl/default/libeic/EicCbor.c b/identity/aidl/default/libeic/EicCbor.c index 0e2684fec4..b9304bcacb 100644 --- a/identity/aidl/default/libeic/EicCbor.c +++ b/identity/aidl/default/libeic/EicCbor.c @@ -91,7 +91,7 @@ size_t eicCborAdditionalLengthBytesFor(size_t size) { return 8; } -void eicCborBegin(EicCbor* cbor, int majorType, size_t size) { +void eicCborBegin(EicCbor* cbor, int majorType, uint64_t size) { uint8_t data[9]; if (size < 24) { @@ -132,10 +132,13 @@ void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize eicCborAppend(cbor, data, dataSize); } -void eicCborAppendString(EicCbor* cbor, const char* str) { - size_t length = eicStrLen(str); - eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_STRING, length); - eicCborAppend(cbor, (const uint8_t*)str, length); +void eicCborAppendString(EicCbor* cbor, const char* str, size_t strLength) { + eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_STRING, strLength); + eicCborAppend(cbor, (const uint8_t*)str, strLength); +} + +void eicCborAppendStringZ(EicCbor* cbor, const char* str) { + eicCborAppendString(cbor, str, eicStrLen(str)); } void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue) { @@ -153,13 +156,13 @@ void eicCborAppendSemantic(EicCbor* cbor, uint64_t value) { } void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value) { - size_t encoded = value; + uint64_t encoded = value; eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_UNSIGNED, encoded); } void eicCborAppendNumber(EicCbor* cbor, int64_t value) { if (value < 0) { - size_t encoded = -1 - value; + uint64_t encoded = -1 - value; eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_NEGATIVE, encoded); } else { eicCborAppendUnsigned(cbor, value); @@ -188,19 +191,19 @@ bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* reade } } eicCborAppendMap(cborBuilder, numPairs); - eicCborAppendString(cborBuilder, "id"); + eicCborAppendStringZ(cborBuilder, "id"); eicCborAppendUnsigned(cborBuilder, id); if (readerCertificateSize > 0) { - eicCborAppendString(cborBuilder, "readerCertificate"); + eicCborAppendStringZ(cborBuilder, "readerCertificate"); eicCborAppendByteString(cborBuilder, readerCertificate, readerCertificateSize); } if (userAuthenticationRequired) { - eicCborAppendString(cborBuilder, "userAuthenticationRequired"); + eicCborAppendStringZ(cborBuilder, "userAuthenticationRequired"); eicCborAppendBool(cborBuilder, userAuthenticationRequired); - eicCborAppendString(cborBuilder, "timeoutMillis"); + eicCborAppendStringZ(cborBuilder, "timeoutMillis"); eicCborAppendUnsigned(cborBuilder, timeoutMillis); if (secureUserId > 0) { - eicCborAppendString(cborBuilder, "secureUserId"); + eicCborAppendStringZ(cborBuilder, "secureUserId"); eicCborAppendUnsigned(cborBuilder, secureUserId); } } @@ -214,20 +217,21 @@ bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* reade return true; } -bool eicCborCalcEntryAdditionalData(const int* accessControlProfileIds, +bool eicCborCalcEntryAdditionalData(const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, uint8_t* cborBuffer, size_t cborBufferSize, - size_t* outAdditionalDataCborSize, + size_t nameSpaceLength, const char* name, + size_t nameLength, uint8_t* cborBuffer, + size_t cborBufferSize, size_t* outAdditionalDataCborSize, uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]) { EicCbor cborBuilder; eicCborInit(&cborBuilder, cborBuffer, cborBufferSize); eicCborAppendMap(&cborBuilder, 3); - eicCborAppendString(&cborBuilder, "Namespace"); - eicCborAppendString(&cborBuilder, nameSpace); - eicCborAppendString(&cborBuilder, "Name"); - eicCborAppendString(&cborBuilder, name); - eicCborAppendString(&cborBuilder, "AccessControlProfileIds"); + eicCborAppendStringZ(&cborBuilder, "Namespace"); + eicCborAppendString(&cborBuilder, nameSpace, nameSpaceLength); + eicCborAppendStringZ(&cborBuilder, "Name"); + eicCborAppendString(&cborBuilder, name, nameLength); + eicCborAppendStringZ(&cborBuilder, "AccessControlProfileIds"); eicCborAppendArray(&cborBuilder, numAccessControlProfileIds); for (size_t n = 0; n < numAccessControlProfileIds; n++) { eicCborAppendNumber(&cborBuilder, accessControlProfileIds[n]); diff --git a/identity/aidl/default/libeic/EicCbor.h b/identity/aidl/default/libeic/EicCbor.h index 9c0f531e4a..16f7ab6619 100644 --- a/identity/aidl/default/libeic/EicCbor.h +++ b/identity/aidl/default/libeic/EicCbor.h @@ -102,13 +102,16 @@ void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size); #define EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR 24 /* Begins a new CBOR value. */ -void eicCborBegin(EicCbor* cbor, int majorType, size_t size); +void eicCborBegin(EicCbor* cbor, int majorType, uint64_t size); /* Appends a bytestring. */ void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize); +/* Appends a UTF-8 string. */ +void eicCborAppendString(EicCbor* cbor, const char* str, size_t strLength); + /* Appends a NUL-terminated UTF-8 string. */ -void eicCborAppendString(EicCbor* cbor, const char* str); +void eicCborAppendStringZ(EicCbor* cbor, const char* str); /* Appends a simple value. */ void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue); @@ -144,22 +147,13 @@ bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* reade size_t readerCertificateSize, bool userAuthenticationRequired, uint64_t timeoutMillis, uint64_t secureUserId); -bool eicCborCalcEntryAdditionalData(const int* accessControlProfileIds, +bool eicCborCalcEntryAdditionalData(const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, uint8_t* cborBuffer, size_t cborBufferSize, - size_t* outAdditionalDataCborSize, + size_t nameSpaceLength, const char* name, + size_t nameLength, uint8_t* cborBuffer, + size_t cborBufferSize, size_t* outAdditionalDataCborSize, uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]); -// The maximum size of an encoded Secure Access Control Profile that we -// support. Since the SACP may contain a reader certificate chain these can get -// pretty big. -// -// Currently we allocate space on the stack for this structure which is why we -// have a maximum size. We can get rid of the maximum size by incrementally -// building/verifying the SACP. TODO: actually do this. -// -#define EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE 512 - #ifdef __cplusplus } #endif diff --git a/identity/aidl/default/libeic/EicCommon.h b/identity/aidl/default/libeic/EicCommon.h new file mode 100644 index 0000000000..476276ebcf --- /dev/null +++ b/identity/aidl/default/libeic/EicCommon.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) +#error "Never include this file directly, include libeic.h instead." +#endif + +#ifndef ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H +#define ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H + +// Feature version 202009: +// +// CredentialKeys = [ +// bstr, ; storageKey, a 128-bit AES key +// bstr, ; credentialPrivKey, the private key for credentialKey +// ] +// +// Feature version 202101: +// +// CredentialKeys = [ +// bstr, ; storageKey, a 128-bit AES key +// bstr, ; credentialPrivKey, the private key for credentialKey +// bstr ; proofOfProvisioning SHA-256 +// ] +// +// where storageKey is 16 bytes, credentialPrivateKey is 32 bytes, and proofOfProvisioning +// SHA-256 is 32 bytes. +#define EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202009 52 +#define EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101 86 + +#endif // ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c index 3d13766f1e..0d03ae9620 100644 --- a/identity/aidl/default/libeic/EicPresentation.c +++ b/identity/aidl/default/libeic/EicPresentation.c @@ -15,22 +15,23 @@ */ #include "EicPresentation.h" +#include "EicCommon.h" #include <inttypes.h> bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - const uint8_t* encryptedCredentialKeys, + size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize) { - uint8_t credentialKeys[86]; + uint8_t credentialKeys[EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101]; bool expectPopSha256 = false; // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86 // bytes (the additional data is the ProofOfProvisioning SHA-256). We need // to support loading all feature versions. // - if (encryptedCredentialKeysSize == 52 + 28) { + if (encryptedCredentialKeysSize == EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202009 + 28) { /* do nothing */ - } else if (encryptedCredentialKeysSize == 86 + 28) { + } else if (encryptedCredentialKeysSize == EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101 + 28) { expectPopSha256 = true; } else { eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize); @@ -42,7 +43,7 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, encryptedCredentialKeysSize, // DocType is the additionalAuthenticatedData - (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) { + (const uint8_t*)docType, docTypeLength, credentialKeys)) { eicDebug("Error decrypting CredentialKeys"); return false; } @@ -88,7 +89,8 @@ bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* return true; } -bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, time_t now, +bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, + size_t docTypeLength, time_t now, uint8_t* publicKeyCert, size_t* publicKeyCertSize, uint8_t signingKeyBlob[60]) { uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE]; @@ -114,7 +116,7 @@ bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* doc EicCbor cbor; eicCborInit(&cbor, cborBuf, sizeof cborBuf); eicCborAppendArray(&cbor, 2); - eicCborAppendString(&cbor, "ProofOfBinding"); + eicCborAppendStringZ(&cbor, "ProofOfBinding"); eicCborAppendByteString(&cbor, ctx->proofOfProvisioningSha256, EIC_SHA256_DIGEST_SIZE); if (cbor.size > sizeof(cborBuf)) { eicDebug("Exceeded buffer size"); @@ -147,7 +149,7 @@ bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* doc } if (!eicOpsEncryptAes128Gcm(ctx->storageKey, nonce, signingKeyPriv, sizeof(signingKeyPriv), // DocType is the additionalAuthenticatedData - (const uint8_t*)docType, eicStrLen(docType), signingKeyBlob)) { + (const uint8_t*)docType, docTypeLength, signingKeyBlob)) { eicDebug("Error encrypting signing key"); return false; } @@ -219,7 +221,7 @@ bool eicPresentationValidateRequestMessage(EicPresentation* ctx, const uint8_t* EicCbor cbor; eicCborInit(&cbor, NULL, 0); eicCborAppendArray(&cbor, 4); - eicCborAppendString(&cbor, "Signature1"); + eicCborAppendStringZ(&cbor, "Signature1"); // The COSE Encoded protected headers is just a single field with // COSE_LABEL_ALG (1) -> coseSignAlg (e.g. -7). For simplicitly we just @@ -277,7 +279,7 @@ bool eicPresentationValidateRequestMessage(EicPresentation* ctx, const uint8_t* // size_t payloadOffset = cbor.size; eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_ARRAY, 3); - eicCborAppendString(&cbor, "ReaderAuthentication"); + eicCborAppendStringZ(&cbor, "ReaderAuthentication"); eicCborAppend(&cbor, sessionTranscript, sessionTranscriptSize); eicCborAppendSemantic(&cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR); eicCborBegin(&cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, requestMessageSize); @@ -438,18 +440,18 @@ bool eicPresentationValidateAccessControlProfile(EicPresentation* ctx, int id, size_t readerCertificateSize, bool userAuthenticationRequired, int timeoutMillis, uint64_t secureUserId, const uint8_t mac[28], - bool* accessGranted) { + bool* accessGranted, + uint8_t* scratchSpace, + size_t scratchSpaceSize) { *accessGranted = false; - if (id < 0 || id >= 32) { eicDebug("id value of %d is out of allowed range [0, 32[", id); return false; } // Validate the MAC - uint8_t cborBuffer[EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE]; EicCbor cborBuilder; - eicCborInit(&cborBuilder, cborBuffer, EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE); + eicCborInit(&cborBuilder, scratchSpace, scratchSpaceSize); if (!eicCborCalcAccessControl(&cborBuilder, id, readerCertificate, readerCertificateSize, userAuthenticationRequired, timeoutMillis, secureUserId)) { return false; @@ -464,15 +466,15 @@ bool eicPresentationValidateAccessControlProfile(EicPresentation* ctx, int id, checkUserAuth(ctx, userAuthenticationRequired, timeoutMillis, secureUserId); bool passedReaderAuth = checkReaderAuth(ctx, readerCertificate, readerCertificateSize); - ctx->accessControlProfileMaskValidated |= (1 << id); + ctx->accessControlProfileMaskValidated |= (1U << id); if (readerCertificateSize > 0) { - ctx->accessControlProfileMaskUsesReaderAuth |= (1 << id); + ctx->accessControlProfileMaskUsesReaderAuth |= (1U << id); } if (!passedReaderAuth) { - ctx->accessControlProfileMaskFailedReaderAuth |= (1 << id); + ctx->accessControlProfileMaskFailedReaderAuth |= (1U << id); } if (!passedUserAuth) { - ctx->accessControlProfileMaskFailedUserAuth |= (1 << id); + ctx->accessControlProfileMaskFailedUserAuth |= (1U << id); } if (passedUserAuth && passedReaderAuth) { @@ -486,11 +488,11 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans size_t sessionTranscriptSize, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE], const uint8_t signingKeyBlob[60], const char* docType, - unsigned int numNamespacesWithValues, + size_t docTypeLength, unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) { uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE]; if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType, - eicStrLen(docType), signingKeyPriv)) { + docTypeLength, signingKeyPriv)) { eicDebug("Error decrypting signingKeyBlob"); return false; } @@ -530,7 +532,7 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans // ] // eicCborAppendArray(&ctx->cbor, 4); - eicCborAppendString(&ctx->cbor, "MAC0"); + eicCborAppendStringZ(&ctx->cbor, "MAC0"); // The COSE Encoded protected headers is just a single field with // COSE_LABEL_ALG (1) -> COSE_ALG_HMAC_256_256 (5). For simplicitly we just @@ -566,8 +568,7 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans calculatedSize += 1; // "DeviceAuthentication" less than 24 bytes calculatedSize += sizeof("DeviceAuthentication") - 1; // Don't include trailing NUL calculatedSize += sessionTranscriptSize; // Already CBOR encoded - size_t docTypeLen = eicStrLen(docType); - calculatedSize += 1 + eicCborAdditionalLengthBytesFor(docTypeLen) + docTypeLen; + calculatedSize += 1 + eicCborAdditionalLengthBytesFor(docTypeLength) + docTypeLength; calculatedSize += 2; // Semantic tag EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR (24) calculatedSize += 1 + eicCborAdditionalLengthBytesFor(expectedDeviceNamespacesSize); calculatedSize += expectedDeviceNamespacesSize; @@ -589,9 +590,9 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, calculatedSize); eicCborAppendArray(&ctx->cbor, 4); - eicCborAppendString(&ctx->cbor, "DeviceAuthentication"); + eicCborAppendStringZ(&ctx->cbor, "DeviceAuthentication"); eicCborAppend(&ctx->cbor, sessionTranscript, sessionTranscriptSize); - eicCborAppendString(&ctx->cbor, docType); + eicCborAppendString(&ctx->cbor, docType, docTypeLength); // For the payload, the _encoded_ form follows here. We handle this by simply // opening a bstr, and then writing the CBOR. This requires us to know the @@ -618,16 +619,18 @@ bool eicPresentationStartRetrieveEntries(EicPresentation* ctx) { } EicAccessCheckResult eicPresentationStartRetrieveEntryValue( - EicPresentation* ctx, const char* nameSpace, const char* name, - unsigned int newNamespaceNumEntries, int32_t /* entrySize */, - const int* accessControlProfileIds, size_t numAccessControlProfileIds, + EicPresentation* ctx, const char* nameSpace, size_t nameSpaceLength, + const char* name, size_t nameLength, + unsigned int newNamespaceNumEntries, int32_t entrySize, + const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, uint8_t* scratchSpace, size_t scratchSpaceSize) { + (void)entrySize; uint8_t* additionalDataCbor = scratchSpace; - const size_t additionalDataCborBufSize = scratchSpaceSize; + size_t additionalDataCborBufferSize = scratchSpaceSize; size_t additionalDataCborSize; if (newNamespaceNumEntries > 0) { - eicCborAppendString(&ctx->cbor, nameSpace); + eicCborAppendString(&ctx->cbor, nameSpace, nameSpaceLength); eicCborAppendMap(&ctx->cbor, newNamespaceNumEntries); } @@ -636,8 +639,9 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( // ctx->accessCheckOk = false; if (!eicCborCalcEntryAdditionalData(accessControlProfileIds, numAccessControlProfileIds, - nameSpace, name, additionalDataCbor, - additionalDataCborBufSize, &additionalDataCborSize, + nameSpace, nameSpaceLength, name, nameLength, + additionalDataCbor, additionalDataCborBufferSize, + &additionalDataCborSize, ctx->additionalDataSha256)) { return EIC_ACCESS_CHECK_RESULT_FAILED; } @@ -681,7 +685,7 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( eicDebug("Result %d for name %s", result, name); if (result == EIC_ACCESS_CHECK_RESULT_OK) { - eicCborAppendString(&ctx->cbor, name); + eicCborAppendString(&ctx->cbor, name, nameLength); ctx->accessCheckOk = true; } return result; @@ -690,18 +694,21 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( // Note: |content| must be big enough to hold |encryptedContentSize| - 28 bytes. bool eicPresentationRetrieveEntryValue(EicPresentation* ctx, const uint8_t* encryptedContent, size_t encryptedContentSize, uint8_t* content, - const char* nameSpace, const char* name, - const int* accessControlProfileIds, - size_t numAccessControlProfileIds, uint8_t* scratchSpace, + const char* nameSpace, size_t nameSpaceLength, + const char* name, size_t nameLength, + const uint8_t* accessControlProfileIds, + size_t numAccessControlProfileIds, + uint8_t* scratchSpace, size_t scratchSpaceSize) { uint8_t* additionalDataCbor = scratchSpace; - const size_t additionalDataCborBufSize = scratchSpaceSize; + size_t additionalDataCborBufferSize = scratchSpaceSize; size_t additionalDataCborSize; uint8_t calculatedSha256[EIC_SHA256_DIGEST_SIZE]; if (!eicCborCalcEntryAdditionalData(accessControlProfileIds, numAccessControlProfileIds, - nameSpace, name, additionalDataCbor, - additionalDataCborBufSize, &additionalDataCborSize, + nameSpace, nameSpaceLength, name, nameLength, + additionalDataCbor, additionalDataCborBufferSize, + &additionalDataCborSize, calculatedSha256)) { return false; } @@ -746,9 +753,10 @@ bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMac return true; } -bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, +bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, size_t docTypeLength, const uint8_t* challenge, size_t challengeSize, - bool includeChallenge, size_t proofOfDeletionCborSize, + bool includeChallenge, + size_t proofOfDeletionCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) { EicCbor cbor; @@ -766,7 +774,7 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, // ] // eicCborAppendArray(&cbor, 4); - eicCborAppendString(&cbor, "Signature1"); + eicCborAppendStringZ(&cbor, "Signature1"); // The COSE Encoded protected headers is just a single field with // COSE_LABEL_ALG (1) -> COSE_ALG_ECSDA_256 (-7). For simplicitly we just @@ -787,8 +795,8 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, // Finally, the CBOR that we're actually signing. eicCborAppendArray(&cbor, includeChallenge ? 4 : 3); - eicCborAppendString(&cbor, "ProofOfDeletion"); - eicCborAppendString(&cbor, docType); + eicCborAppendStringZ(&cbor, "ProofOfDeletion"); + eicCborAppendString(&cbor, docType, docTypeLength); if (includeChallenge) { eicCborAppendByteString(&cbor, challenge, challengeSize); } @@ -804,7 +812,8 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, return true; } -bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential, +bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, + size_t docTypeLength, bool testCredential, const uint8_t* challenge, size_t challengeSize, size_t proofOfOwnershipCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]) { @@ -824,7 +833,7 @@ bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bo // ] // eicCborAppendArray(&cbor, 4); - eicCborAppendString(&cbor, "Signature1"); + eicCborAppendStringZ(&cbor, "Signature1"); // The COSE Encoded protected headers is just a single field with // COSE_LABEL_ALG (1) -> COSE_ALG_ECSDA_256 (-7). For simplicitly we just @@ -845,8 +854,8 @@ bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bo // Finally, the CBOR that we're actually signing. eicCborAppendArray(&cbor, 4); - eicCborAppendString(&cbor, "ProofOfOwnership"); - eicCborAppendString(&cbor, docType); + eicCborAppendStringZ(&cbor, "ProofOfOwnership"); + eicCborAppendString(&cbor, docType, docTypeLength); eicCborAppendByteString(&cbor, challenge, challengeSize); eicCborAppendBool(&cbor, testCredential); diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h index c888049dbe..6f7f432960 100644 --- a/identity/aidl/default/libeic/EicPresentation.h +++ b/identity/aidl/default/libeic/EicPresentation.h @@ -94,10 +94,11 @@ typedef struct { } EicPresentation; bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType, - const uint8_t* encryptedCredentialKeys, + size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); -bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, time_t now, +bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, + size_t docTypeLength, time_t now, uint8_t* publicKeyCert, size_t* publicKeyCertSize, uint8_t signingKeyBlob[60]); @@ -148,12 +149,17 @@ bool eicPresentationPushReaderCert(EicPresentation* ctx, const uint8_t* certX509 // be called after pushing that certificate using // eicPresentationPushReaderCert(). // +// The scratchSpace should be set to a buffer at least 512 bytes. It's done +// this way to avoid allocating stack space. +// bool eicPresentationValidateAccessControlProfile(EicPresentation* ctx, int id, const uint8_t* readerCertificate, size_t readerCertificateSize, bool userAuthenticationRequired, int timeoutMillis, uint64_t secureUserId, const uint8_t mac[28], - bool* accessGranted); + bool* accessGranted, + uint8_t* scratchSpace, + size_t scratchSpaceSize); // Validates that the given requestMessage is signed by the public key in the // certificate last set with eicPresentationPushReaderCert(). @@ -196,7 +202,7 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans size_t sessionTranscriptSize, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE], const uint8_t signingKeyBlob[60], const char* docType, - unsigned int numNamespacesWithValues, + size_t docTypeLength, unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize); // The scratchSpace should be set to a buffer at least 512 bytes (ideally 1024 @@ -204,9 +210,11 @@ bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTrans // space. // EicAccessCheckResult eicPresentationStartRetrieveEntryValue( - EicPresentation* ctx, const char* nameSpace, const char* name, - unsigned int newNamespaceNumEntries, int32_t entrySize, const int* accessControlProfileIds, - size_t numAccessControlProfileIds, uint8_t* scratchSpace, size_t scratchSpaceSize); + EicPresentation* ctx, const char* nameSpace, size_t nameSpaceLength, + const char* name, size_t nameLength, + unsigned int newNamespaceNumEntries, int32_t entrySize, + const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, + uint8_t* scratchSpace, size_t scratchSpaceSize); // Note: |content| must be big enough to hold |encryptedContentSize| - 28 bytes. // @@ -215,9 +223,11 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( // bool eicPresentationRetrieveEntryValue(EicPresentation* ctx, const uint8_t* encryptedContent, size_t encryptedContentSize, uint8_t* content, - const char* nameSpace, const char* name, - const int* accessControlProfileIds, - size_t numAccessControlProfileIds, uint8_t* scratchSpace, + const char* nameSpace, size_t nameSpaceLength, + const char* name, size_t nameLength, + const uint8_t* accessControlProfileIds, + size_t numAccessControlProfileIds, + uint8_t* scratchSpace, size_t scratchSpaceSize); // Returns the HMAC-SHA256 of |ToBeMaced| as per RFC 8051 "6.3. How to Compute @@ -229,7 +239,7 @@ bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMac // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process" // where content is set to the ProofOfDeletion CBOR. // -bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, +bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, size_t docTypeLength, const uint8_t* challenge, size_t challengeSize, bool includeChallenge, size_t proofOfDeletionCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); @@ -238,8 +248,8 @@ bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType, // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process" // where content is set to the ProofOfOwnership CBOR. // -bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential, - const uint8_t* challenge, size_t challengeSize, +bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, size_t docTypeLength, + bool testCredential, const uint8_t* challenge, size_t challengeSize, size_t proofOfOwnershipCborSize, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c index 3b4148e571..c9df4fd74f 100644 --- a/identity/aidl/default/libeic/EicProvisioning.c +++ b/identity/aidl/default/libeic/EicProvisioning.c @@ -15,6 +15,7 @@ */ #include "EicProvisioning.h" +#include "EicCommon.h" bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) { eicMemSet(ctx, '\0', sizeof(EicProvisioning)); @@ -27,18 +28,18 @@ bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) { } bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, - const uint8_t* encryptedCredentialKeys, + size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize) { - uint8_t credentialKeys[86]; + uint8_t credentialKeys[EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101]; // For feature version 202009 it's 52 bytes long and for feature version 202101 it's 86 // bytes (the additional data is the ProofOfProvisioning SHA-256). We need // to support loading all feature versions. // bool expectPopSha256 = false; - if (encryptedCredentialKeysSize == 52 + 28) { + if (encryptedCredentialKeysSize == EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202009 + 28) { /* do nothing */ - } else if (encryptedCredentialKeysSize == 86 + 28) { + } else if (encryptedCredentialKeysSize == EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101 + 28) { expectPopSha256 = true; } else { eicDebug("Unexpected size %zd for encryptedCredentialKeys", encryptedCredentialKeysSize); @@ -51,7 +52,7 @@ bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, con if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys, encryptedCredentialKeysSize, // DocType is the additionalAuthenticatedData - (const uint8_t*)docType, eicStrLen(docType), credentialKeys)) { + (const uint8_t*)docType, docTypeLength, credentialKeys)) { eicDebug("Error decrypting CredentialKeys"); return false; } @@ -114,7 +115,7 @@ bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* cha bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount, const int* entryCounts, size_t numEntryCounts, - const char* docType, + const char* docType, size_t docTypeLength, size_t expectedProofOfProvisioningSize) { if (numEntryCounts >= EIC_MAX_NUM_NAMESPACES) { return false; @@ -150,7 +151,7 @@ bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControl // ] // eicCborAppendArray(&ctx->cbor, 4); - eicCborAppendString(&ctx->cbor, "Signature1"); + eicCborAppendStringZ(&ctx->cbor, "Signature1"); // The COSE Encoded protected headers is just a single field with // COSE_LABEL_ALG (1) -> COSE_ALG_ECSDA_256 (-7). For simplicitly we just @@ -174,8 +175,8 @@ bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControl eicCborEnableSecondaryDigesterSha256(&ctx->cbor, &ctx->proofOfProvisioningDigester); eicCborAppendArray(&ctx->cbor, 5); - eicCborAppendString(&ctx->cbor, "ProofOfProvisioning"); - eicCborAppendString(&ctx->cbor, docType); + eicCborAppendStringZ(&ctx->cbor, "ProofOfProvisioning"); + eicCborAppendString(&ctx->cbor, docType, docTypeLength); eicCborAppendArray(&ctx->cbor, accessControlProfileCount); @@ -185,12 +186,12 @@ bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControl bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id, const uint8_t* readerCertificate, size_t readerCertificateSize, - bool userAuthenticationRequired, uint64_t timeoutMillis, - uint64_t secureUserId, uint8_t outMac[28]) { - uint8_t cborBuffer[EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE]; + bool userAuthenticationRequired, + uint64_t timeoutMillis, uint64_t secureUserId, + uint8_t outMac[28], uint8_t* scratchSpace, + size_t scratchSpaceSize) { EicCbor cborBuilder; - - eicCborInit(&cborBuilder, cborBuffer, EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE); + eicCborInit(&cborBuilder, scratchSpace, scratchSpaceSize); if (!eicCborCalcAccessControl(&cborBuilder, id, readerCertificate, readerCertificateSize, userAuthenticationRequired, timeoutMillis, secureUserId)) { @@ -209,7 +210,7 @@ bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id, // The ACP CBOR in the provisioning receipt doesn't include secureUserId so build // it again. - eicCborInit(&cborBuilder, cborBuffer, EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE); + eicCborInit(&cborBuilder, scratchSpace, scratchSpaceSize); if (!eicCborCalcAccessControl(&cborBuilder, id, readerCertificate, readerCertificateSize, userAuthenticationRequired, timeoutMillis, 0 /* secureUserId */)) { @@ -222,9 +223,10 @@ bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id, return true; } -bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControlProfileIds, +bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, uint64_t entrySize, uint8_t* scratchSpace, + size_t nameSpaceLength, const char* name, size_t nameLength, + uint64_t entrySize, uint8_t* scratchSpace, size_t scratchSpaceSize) { uint8_t* additionalDataCbor = scratchSpace; const size_t additionalDataCborBufSize = scratchSpaceSize; @@ -233,9 +235,9 @@ bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControl // We'll need to calc and store a digest of additionalData to check that it's the same // additionalData being passed in for every eicProvisioningAddEntryValue() call... if (!eicCborCalcEntryAdditionalData(accessControlProfileIds, numAccessControlProfileIds, - nameSpace, name, additionalDataCbor, - additionalDataCborBufSize, &additionalDataCborSize, - ctx->additionalDataSha256)) { + nameSpace, nameSpaceLength, name, nameLength, + additionalDataCbor, additionalDataCborBufSize, + &additionalDataCborSize, ctx->additionalDataSha256)) { return false; } @@ -244,7 +246,7 @@ bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControl ctx->curNamespaceNumProcessed = 0; // Opens the main map: { * Namespace => [ + Entry ] } eicCborAppendMap(&ctx->cbor, ctx->numEntryCounts); - eicCborAppendString(&ctx->cbor, nameSpace); + eicCborAppendString(&ctx->cbor, nameSpace, nameSpaceLength); // Opens the per-namespace array: [ + Entry ] eicCborAppendArray(&ctx->cbor, ctx->entryCounts[ctx->curNamespace]); } @@ -252,37 +254,39 @@ bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControl if (ctx->curNamespaceNumProcessed == ctx->entryCounts[ctx->curNamespace]) { ctx->curNamespace += 1; ctx->curNamespaceNumProcessed = 0; - eicCborAppendString(&ctx->cbor, nameSpace); + eicCborAppendString(&ctx->cbor, nameSpace, nameSpaceLength); // Opens the per-namespace array: [ + Entry ] eicCborAppendArray(&ctx->cbor, ctx->entryCounts[ctx->curNamespace]); } eicCborAppendMap(&ctx->cbor, 3); - eicCborAppendString(&ctx->cbor, "name"); - eicCborAppendString(&ctx->cbor, name); + eicCborAppendStringZ(&ctx->cbor, "name"); + eicCborAppendString(&ctx->cbor, name, nameLength); ctx->curEntrySize = entrySize; ctx->curEntryNumBytesReceived = 0; - eicCborAppendString(&ctx->cbor, "value"); + eicCborAppendStringZ(&ctx->cbor, "value"); ctx->curNamespaceNumProcessed += 1; return true; } -bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const int* accessControlProfileIds, +bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, const uint8_t* content, size_t contentSize, + size_t nameSpaceLength, const char* name, size_t nameLength, + const uint8_t* content, size_t contentSize, uint8_t* outEncryptedContent, uint8_t* scratchSpace, size_t scratchSpaceSize) { uint8_t* additionalDataCbor = scratchSpace; const size_t additionalDataCborBufSize = scratchSpaceSize; size_t additionalDataCborSize; - uint8_t calculatedSha256[EIC_SHA256_DIGEST_SIZE]; + if (!eicCborCalcEntryAdditionalData(accessControlProfileIds, numAccessControlProfileIds, - nameSpace, name, additionalDataCbor, - additionalDataCborBufSize, &additionalDataCborSize, + nameSpace, nameSpaceLength, name, nameLength, + additionalDataCbor, additionalDataCborBufSize, + &additionalDataCborSize, calculatedSha256)) { return false; } @@ -305,7 +309,7 @@ bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const int* accessControl // If done with this entry, close the map ctx->curEntryNumBytesReceived += contentSize; if (ctx->curEntryNumBytesReceived == ctx->curEntrySize) { - eicCborAppendString(&ctx->cbor, "accessControlProfiles"); + eicCborAppendStringZ(&ctx->cbor, "accessControlProfiles"); eicCborAppendArray(&ctx->cbor, numAccessControlProfileIds); for (size_t n = 0; n < numAccessControlProfileIds; n++) { eicCborAppendNumber(&ctx->cbor, accessControlProfileIds[n]); @@ -337,6 +341,7 @@ bool eicProvisioningFinishAddingEntries( } bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType, + size_t docTypeLength, uint8_t* encryptedCredentialKeys, size_t* encryptedCredentialKeysSize) { EicCbor cbor; @@ -367,7 +372,7 @@ bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* do if (!eicOpsEncryptAes128Gcm( eicOpsGetHardwareBoundKey(ctx->testCredential), nonce, cborBuf, cbor.size, // DocType is the additionalAuthenticatedData - (const uint8_t*)docType, eicStrLen(docType), encryptedCredentialKeys)) { + (const uint8_t*)docType, docTypeLength, encryptedCredentialKeys)) { eicDebug("Error encrypting CredentialKeys"); return false; } diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h index f064787b1b..92f1e4a2a0 100644 --- a/identity/aidl/default/libeic/EicProvisioning.h +++ b/identity/aidl/default/libeic/EicProvisioning.h @@ -65,7 +65,7 @@ typedef struct { bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential); bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, - const uint8_t* encryptedCredentialKeys, + size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, @@ -75,21 +75,27 @@ bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* cha bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount, const int* entryCounts, size_t numEntryCounts, - const char* docType, + const char* docType, size_t docTypeLength, size_t expectedProofOfProvisioningingSize); +// The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to +// avoid allocating stack space. +// bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id, const uint8_t* readerCertificate, size_t readerCertificateSize, - bool userAuthenticationRequired, uint64_t timeoutMillis, - uint64_t secureUserId, uint8_t outMac[28]); + bool userAuthenticationRequired, + uint64_t timeoutMillis, uint64_t secureUserId, + uint8_t outMac[28], uint8_t* scratchSpace, + size_t scratchSpaceSize); // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to // avoid allocating stack space. // -bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControlProfileIds, +bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, uint64_t entrySize, uint8_t* scratchSpace, + size_t nameSpaceLength, const char* name, size_t nameLength, + uint64_t entrySize, uint8_t* scratchSpace, size_t scratchSpaceSize); // The outEncryptedContent array must be contentSize + 28 bytes long. @@ -97,9 +103,10 @@ bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControl // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to // avoid allocating stack space. // -bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const int* accessControlProfileIds, +bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, - const char* name, const uint8_t* content, size_t contentSize, + size_t nameSpaceLength, const char* name, size_t nameLength, + const uint8_t* content, size_t contentSize, uint8_t* outEncryptedContent, uint8_t* scratchSpace, size_t scratchSpaceSize); @@ -128,6 +135,7 @@ bool eicProvisioningFinishAddingEntries( // |encryptedCredentialKeys| will be no longer than 86 + 28 = 114 bytes. // bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType, + size_t docTypeLength, uint8_t* encryptedCredentialKeys, size_t* encryptedCredentialKeysSize); diff --git a/identity/aidl/default/libeic/libeic.h b/identity/aidl/default/libeic/libeic.h index 88abef808f..20c889660f 100644 --- a/identity/aidl/default/libeic/libeic.h +++ b/identity/aidl/default/libeic/libeic.h @@ -30,6 +30,7 @@ extern "C" { #include "EicOps.h" #include "EicPresentation.h" #include "EicProvisioning.h" +#include "EicCommon.h" #undef EIC_INSIDE_LIBEIC_H #ifdef __cplusplus |