/* * 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_PROVISIONING_H #define ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H #ifdef __cplusplus extern "C" { #endif #include "EicCbor.h" #define EIC_MAX_NUM_NAMESPACES 32 #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32 typedef struct { // A non-zero number unique for this EicProvisioning instance uint32_t id; // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate() uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; int numEntryCounts; uint8_t entryCounts[EIC_MAX_NUM_NAMESPACES]; int curNamespace; int curNamespaceNumProcessed; size_t curEntrySize; size_t curEntryNumBytesReceived; // Set by eicProvisioningInit() OR eicProvisioningInitForUpdate() uint8_t storageKey[EIC_AES_128_KEY_SIZE]; size_t expectedCborSizeAtEnd; // SHA-256 for AdditionalData, updated for each entry. uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]; // Digester just for ProofOfProvisioning (without Sig_structure). EicSha256Ctx proofOfProvisioningDigester; EicCbor cbor; bool testCredential; // Set to true if this is an update. bool isUpdate; } EicProvisioning; bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential); bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, size_t docTypeLength, const uint8_t* encryptedCredentialKeys, size_t encryptedCredentialKeysSize); bool eicProvisioningShutdown(EicProvisioning* ctx); bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId); bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, size_t challengeSize, const uint8_t* applicationId, size_t applicationIdSize, const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize, const uint8_t* attestationKeyCert, size_t attestationKeyCertSize, uint8_t* publicKeyCert, size_t* publicKeyCertSize); bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount, const int* entryCounts, size_t numEntryCounts, 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], 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 uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, 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. // // 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 uint8_t* accessControlProfileIds, size_t numAccessControlProfileIds, const char* nameSpace, 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); // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process" // where content is set to the ProofOfProvisioninging CBOR. // bool eicProvisioningFinishAddingEntries( EicProvisioning* ctx, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); // // // The |encryptedCredentialKeys| array is set to AES-GCM-ENC(HBK, R, CredentialKeys, docType) // where // // CredentialKeys = [ // bstr, ; storageKey, a 128-bit AES key // bstr ; credentialPrivKey, the private key for credentialKey // bstr ; SHA-256(ProofOfProvisioning) // ] // // for feature version 202101. For feature version 202009 the third field was not present. // // Since |storageKey| is 16 bytes and |credentialPrivKey| is 32 bytes, the // encoded CBOR for CredentialKeys is 86 bytes and consequently // |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); #ifdef __cplusplus } #endif #endif // ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H