1 /* 2 * Copyright 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION) 18 #error "Never include this file directly, include libeic.h instead." 19 #endif 20 21 #ifndef ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H 22 #define ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #include "EicCbor.h" 29 30 #define EIC_MAX_NUM_NAMESPACES 32 31 #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32 32 33 typedef struct { 34 // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate() 35 uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE]; 36 37 int numEntryCounts; 38 uint8_t entryCounts[EIC_MAX_NUM_NAMESPACES]; 39 40 int curNamespace; 41 int curNamespaceNumProcessed; 42 43 size_t curEntrySize; 44 size_t curEntryNumBytesReceived; 45 46 // Set by eicProvisioningInit() OR eicProvisioningInitForUpdate() 47 uint8_t storageKey[EIC_AES_128_KEY_SIZE]; 48 49 size_t expectedCborSizeAtEnd; 50 51 // SHA-256 for AdditionalData, updated for each entry. 52 uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]; 53 54 // Digester just for ProofOfProvisioning (without Sig_structure). 55 EicSha256Ctx proofOfProvisioningDigester; 56 57 EicCbor cbor; 58 59 bool testCredential; 60 61 // Set to true if this is an update. 62 bool isUpdate; 63 } EicProvisioning; 64 65 bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential); 66 67 bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType, 68 const uint8_t* encryptedCredentialKeys, 69 size_t encryptedCredentialKeysSize); 70 71 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge, 72 size_t challengeSize, const uint8_t* applicationId, 73 size_t applicationIdSize, uint8_t* publicKeyCert, 74 size_t* publicKeyCertSize); 75 76 bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount, 77 const int* entryCounts, size_t numEntryCounts, 78 const char* docType, 79 size_t expectedProofOfProvisioningingSize); 80 81 bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id, 82 const uint8_t* readerCertificate, 83 size_t readerCertificateSize, 84 bool userAuthenticationRequired, uint64_t timeoutMillis, 85 uint64_t secureUserId, uint8_t outMac[28]); 86 87 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to 88 // avoid allocating stack space. 89 // 90 bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const int* accessControlProfileIds, 91 size_t numAccessControlProfileIds, const char* nameSpace, 92 const char* name, uint64_t entrySize, uint8_t* scratchSpace, 93 size_t scratchSpaceSize); 94 95 // The outEncryptedContent array must be contentSize + 28 bytes long. 96 // 97 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to 98 // avoid allocating stack space. 99 // 100 bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const int* accessControlProfileIds, 101 size_t numAccessControlProfileIds, const char* nameSpace, 102 const char* name, const uint8_t* content, size_t contentSize, 103 uint8_t* outEncryptedContent, uint8_t* scratchSpace, 104 size_t scratchSpaceSize); 105 106 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of 107 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process" 108 // where content is set to the ProofOfProvisioninging CBOR. 109 // 110 bool eicProvisioningFinishAddingEntries( 111 EicProvisioning* ctx, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]); 112 113 // 114 // 115 // The |encryptedCredentialKeys| array is set to AES-GCM-ENC(HBK, R, CredentialKeys, docType) 116 // where 117 // 118 // CredentialKeys = [ 119 // bstr, ; storageKey, a 128-bit AES key 120 // bstr ; credentialPrivKey, the private key for credentialKey 121 // bstr ; SHA-256(ProofOfProvisioning) 122 // ] 123 // 124 // for feature version 202101. For feature version 202009 the third field was not present. 125 // 126 // Since |storageKey| is 16 bytes and |credentialPrivKey| is 32 bytes, the 127 // encoded CBOR for CredentialKeys is 86 bytes and consequently 128 // |encryptedCredentialKeys| will be no longer than 86 + 28 = 114 bytes. 129 // 130 bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType, 131 uint8_t* encryptedCredentialKeys, 132 size_t* encryptedCredentialKeysSize); 133 134 #ifdef __cplusplus 135 } 136 #endif 137 138 #endif // ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H 139