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     // A non-zero number unique for this EicProvisioning instance
35     uint32_t id;
36 
37     // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate()
38     uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE];
39 
40     int numEntryCounts;
41     uint8_t entryCounts[EIC_MAX_NUM_NAMESPACES];
42 
43     int curNamespace;
44     int curNamespaceNumProcessed;
45 
46     size_t curEntrySize;
47     size_t curEntryNumBytesReceived;
48 
49     // Set by eicProvisioningInit() OR eicProvisioningInitForUpdate()
50     uint8_t storageKey[EIC_AES_128_KEY_SIZE];
51 
52     size_t expectedCborSizeAtEnd;
53 
54     // SHA-256 for AdditionalData, updated for each entry.
55     uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE];
56 
57     // Digester just for ProofOfProvisioning (without Sig_structure).
58     EicSha256Ctx proofOfProvisioningDigester;
59 
60     EicCbor cbor;
61 
62     bool testCredential;
63 
64     // Set to true if this is an update.
65     bool isUpdate;
66 } EicProvisioning;
67 
68 bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential);
69 
70 bool eicProvisioningInitForUpdate(EicProvisioning* ctx, bool testCredential, const char* docType,
71                                   size_t docTypeLength, const uint8_t* encryptedCredentialKeys,
72                                   size_t encryptedCredentialKeysSize);
73 
74 bool eicProvisioningShutdown(EicProvisioning* ctx);
75 
76 bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId);
77 
78 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
79                                         size_t challengeSize, const uint8_t* applicationId,
80                                         size_t applicationIdSize, const uint8_t* attestationKeyBlob,
81                                         size_t attestationKeyBlobSize,
82                                         const uint8_t* attestationKeyCert,
83                                         size_t attestationKeyCertSize, uint8_t* publicKeyCert,
84                                         size_t* publicKeyCertSize);
85 
86 bool eicProvisioningStartPersonalization(EicProvisioning* ctx, int accessControlProfileCount,
87                                          const int* entryCounts, size_t numEntryCounts,
88                                          const char* docType, size_t docTypeLength,
89                                          size_t expectedProofOfProvisioningingSize);
90 
91 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to
92 // avoid allocating stack space.
93 //
94 bool eicProvisioningAddAccessControlProfile(EicProvisioning* ctx, int id,
95                                             const uint8_t* readerCertificate,
96                                             size_t readerCertificateSize,
97                                             bool userAuthenticationRequired,
98                                             uint64_t timeoutMillis, uint64_t secureUserId,
99                                             uint8_t outMac[28], uint8_t* scratchSpace,
100                                             size_t scratchSpaceSize);
101 
102 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to
103 // avoid allocating stack space.
104 //
105 bool eicProvisioningBeginAddEntry(EicProvisioning* ctx, const uint8_t* accessControlProfileIds,
106                                   size_t numAccessControlProfileIds, const char* nameSpace,
107                                   size_t nameSpaceLength, const char* name, size_t nameLength,
108                                   uint64_t entrySize, uint8_t* scratchSpace,
109                                   size_t scratchSpaceSize);
110 
111 // The outEncryptedContent array must be contentSize + 28 bytes long.
112 //
113 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to
114 // avoid allocating stack space.
115 //
116 bool eicProvisioningAddEntryValue(EicProvisioning* ctx, const uint8_t* accessControlProfileIds,
117                                   size_t numAccessControlProfileIds, const char* nameSpace,
118                                   size_t nameSpaceLength, const char* name, size_t nameLength,
119                                   const uint8_t* content, size_t contentSize,
120                                   uint8_t* outEncryptedContent, uint8_t* scratchSpace,
121                                   size_t scratchSpaceSize);
122 
123 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
124 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
125 // where content is set to the ProofOfProvisioninging CBOR.
126 //
127 bool eicProvisioningFinishAddingEntries(
128         EicProvisioning* ctx, uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]);
129 
130 //
131 //
132 // The |encryptedCredentialKeys| array is set to AES-GCM-ENC(HBK, R, CredentialKeys, docType)
133 // where
134 //
135 //   CredentialKeys = [
136 //     bstr,   ; storageKey, a 128-bit AES key
137 //     bstr    ; credentialPrivKey, the private key for credentialKey
138 //     bstr    ; SHA-256(ProofOfProvisioning)
139 //   ]
140 //
141 // for feature version 202101. For feature version 202009 the third field was not present.
142 //
143 // Since |storageKey| is 16 bytes and |credentialPrivKey| is 32 bytes, the
144 // encoded CBOR for CredentialKeys is 86 bytes and consequently
145 // |encryptedCredentialKeys| will be no longer than 86 + 28 = 114 bytes.
146 //
147 bool eicProvisioningFinishGetCredentialData(EicProvisioning* ctx, const char* docType,
148                                             size_t docTypeLength,
149                                             uint8_t* encryptedCredentialKeys,
150                                             size_t* encryptedCredentialKeysSize);
151 
152 #ifdef __cplusplus
153 }
154 #endif
155 
156 #endif  // ANDROID_HARDWARE_IDENTITY_EIC_PROVISIONING_H
157