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