Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dabb3c51 authored by Joseph Jang's avatar Joseph Jang
Browse files

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
parent 334a6134
Loading
Loading
Loading
Loading
+57 −25
Original line number Diff line number Diff line
@@ -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 {};
    }
+24 −20
Original line number Diff line number Diff line
@@ -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]);
+9 −15
Original line number Diff line number Diff line
@@ -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
+44 −0
Original line number Diff line number Diff line
/*
 * 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
+57 −48

File changed.

Preview size limit exceeded, changes collapsed.

Loading