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