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_PRESENTATION_H
22 #define ANDROID_HARDWARE_IDENTITY_EIC_PRESENTATION_H
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #include "EicCbor.h"
29 
30 // The maximum size we support for public keys in reader certificates.
31 #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65
32 
33 typedef struct {
34     int featureLevel;
35 
36     uint8_t storageKey[EIC_AES_128_KEY_SIZE];
37     uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE];
38 
39     uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE];
40 
41     // The challenge generated with eicPresentationCreateAuthChallenge()
42     uint64_t authChallenge;
43 
44     // Set by eicPresentationSetAuthToken() and contains the fields
45     // from the passed in authToken and verificationToken.
46     //
47     uint64_t authTokenChallenge;
48     uint64_t authTokenSecureUserId;
49     uint64_t authTokenTimestamp;
50     uint64_t verificationTokenTimestamp;
51 
52     // The public key for the reader.
53     //
54     // (During the process of pushing reader certificates, this is also used to store
55     // the public key of the previously pushed certificate.)
56     //
57     uint8_t readerPublicKey[EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE];
58     size_t readerPublicKeySize;
59 
60     // This is set to true only if eicPresentationValidateRequestMessage() successfully
61     // validated the requestMessage.
62     //
63     // Why even record this? Because there's no requirement the HAL actually calls that
64     // function and we validate ACPs before it's called... so it's possible that a
65     // compromised HAL could trick us into marking ACPs as authorized while they in fact
66     // aren't.
67     bool requestMessageValidated;
68     bool buildCbor;
69 
70     // Set to true initialized as a test credential.
71     bool testCredential;
72 
73     // Set to true if the evaluation of access control checks in
74     // eicPresentationStartRetrieveEntryValue() resulted EIC_ACCESS_CHECK_RESULT_OK
75     bool accessCheckOk;
76 
77     // These are bitmasks indicating which of the possible 32 access control profiles are
78     // authorized. They are built up by eicPresentationValidateAccessControlProfile().
79     //
80     uint32_t accessControlProfileMaskValidated;         // True if the profile was validated.
81     uint32_t accessControlProfileMaskUsesReaderAuth;    // True if the ACP is using reader auth
82     uint32_t accessControlProfileMaskFailedReaderAuth;  // True if failed reader auth
83     uint32_t accessControlProfileMaskFailedUserAuth;    // True if failed user auth
84 
85     // SHA-256 for AdditionalData, updated for each entry.
86     uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE];
87 
88     // SHA-256 of ProofOfProvisioning. Set to NUL-bytes or initialized from CredentialKeys data
89     // if credential was created with feature version 202101 or later.
90     uint8_t proofOfProvisioningSha256[EIC_SHA256_DIGEST_SIZE];
91 
92     size_t expectedCborSizeAtEnd;
93     EicCbor cbor;
94 } EicPresentation;
95 
96 bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType,
97                          const uint8_t* encryptedCredentialKeys,
98                          size_t encryptedCredentialKeysSize);
99 
100 bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType, time_t now,
101                                            uint8_t* publicKeyCert, size_t* publicKeyCertSize,
102                                            uint8_t signingKeyBlob[60]);
103 
104 // Create an ephemeral key-pair.
105 //
106 // The private key is stored in |ctx->ephemeralPrivateKey| and also returned in
107 // |ephemeralPrivateKey|.
108 //
109 bool eicPresentationCreateEphemeralKeyPair(EicPresentation* ctx,
110                                            uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]);
111 
112 // Returns a non-zero challenge in |authChallenge|.
113 bool eicPresentationCreateAuthChallenge(EicPresentation* ctx, uint64_t* authChallenge);
114 
115 // Starts retrieveing entries.
116 //
117 bool eicPresentationStartRetrieveEntries(EicPresentation* ctx);
118 
119 // Sets the auth-token.
120 bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint64_t secureUserId,
121                                  uint64_t authenticatorId, int hardwareAuthenticatorType,
122                                  uint64_t timeStamp, const uint8_t* mac, size_t macSize,
123                                  uint64_t verificationTokenChallenge,
124                                  uint64_t verificationTokenTimeStamp,
125                                  int verificationTokenSecurityLevel,
126                                  const uint8_t* verificationTokenMac,
127                                  size_t verificationTokenMacSize);
128 
129 // Function to push certificates in the reader certificate chain.
130 //
131 // This should start with the root certificate (e.g. the last in the chain) and
132 // continue up the chain, ending with the certificate for the reader.
133 //
134 // Calls to this function should be interleaved with calls to the
135 // eicPresentationValidateAccessControlProfile() function, see below.
136 //
137 bool eicPresentationPushReaderCert(EicPresentation* ctx, const uint8_t* certX509,
138                                    size_t certX509Size);
139 
140 // Checks an access control profile.
141 //
142 // Returns false if an error occurred while checking the profile (e.g. MAC doesn't check out).
143 //
144 // Returns in |accessGranted| whether access is granted.
145 //
146 // If |readerCertificate| is non-empty and the public key of one of those
147 // certificates appear in the chain presented by the reader, this function must
148 // be called after pushing that certificate using
149 // eicPresentationPushReaderCert().
150 //
151 bool eicPresentationValidateAccessControlProfile(EicPresentation* ctx, int id,
152                                                  const uint8_t* readerCertificate,
153                                                  size_t readerCertificateSize,
154                                                  bool userAuthenticationRequired, int timeoutMillis,
155                                                  uint64_t secureUserId, const uint8_t mac[28],
156                                                  bool* accessGranted);
157 
158 // Validates that the given requestMessage is signed by the public key in the
159 // certificate last set with eicPresentationPushReaderCert().
160 //
161 // The format of the signature is the same encoding as the 'signature' field of
162 // COSE_Sign1 - that is, it's the R and S integers both with the same length as
163 // the key-size.
164 //
165 // Must be called after eicPresentationPushReaderCert() have been used to push
166 // the final certificate. Which is the certificate of the reader itself.
167 //
168 bool eicPresentationValidateRequestMessage(EicPresentation* ctx, const uint8_t* sessionTranscript,
169                                            size_t sessionTranscriptSize,
170                                            const uint8_t* requestMessage, size_t requestMessageSize,
171                                            int coseSignAlg,
172                                            const uint8_t* readerSignatureOfToBeSigned,
173                                            size_t readerSignatureOfToBeSignedSize);
174 
175 typedef enum {
176     // Returned if access is granted.
177     EIC_ACCESS_CHECK_RESULT_OK,
178 
179     // Returned if an error occurred checking for access.
180     EIC_ACCESS_CHECK_RESULT_FAILED,
181 
182     // Returned if access was denied because item is configured without any
183     // access control profiles.
184     EIC_ACCESS_CHECK_RESULT_NO_ACCESS_CONTROL_PROFILES,
185 
186     // Returned if access was denied because of user authentication.
187     EIC_ACCESS_CHECK_RESULT_USER_AUTHENTICATION_FAILED,
188 
189     // Returned if access was denied because of reader authentication.
190     EIC_ACCESS_CHECK_RESULT_READER_AUTHENTICATION_FAILED,
191 } EicAccessCheckResult;
192 
193 // Passes enough information to calculate the MACing key
194 //
195 bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTranscript,
196                                size_t sessionTranscriptSize,
197                                const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE],
198                                const uint8_t signingKeyBlob[60], const char* docType,
199                                unsigned int numNamespacesWithValues,
200                                size_t expectedDeviceNamespacesSize);
201 
202 // The scratchSpace should be set to a buffer at least 512 bytes (ideally 1024
203 // bytes, the bigger the better). It's done this way to avoid allocating stack
204 // space.
205 //
206 EicAccessCheckResult eicPresentationStartRetrieveEntryValue(
207         EicPresentation* ctx, const char* nameSpace, const char* name,
208         unsigned int newNamespaceNumEntries, int32_t entrySize, const int* accessControlProfileIds,
209         size_t numAccessControlProfileIds, uint8_t* scratchSpace, size_t scratchSpaceSize);
210 
211 // Note: |content| must be big enough to hold |encryptedContentSize| - 28 bytes.
212 //
213 // The scratchSpace should be set to a buffer at least 512 bytes. It's done this way to
214 // avoid allocating stack space.
215 //
216 bool eicPresentationRetrieveEntryValue(EicPresentation* ctx, const uint8_t* encryptedContent,
217                                        size_t encryptedContentSize, uint8_t* content,
218                                        const char* nameSpace, const char* name,
219                                        const int* accessControlProfileIds,
220                                        size_t numAccessControlProfileIds, uint8_t* scratchSpace,
221                                        size_t scratchSpaceSize);
222 
223 // Returns the HMAC-SHA256 of |ToBeMaced| as per RFC 8051 "6.3. How to Compute
224 // and Verify a MAC".
225 bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMaced,
226                                     size_t* digestToBeMacedSize);
227 
228 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
229 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
230 // where content is set to the ProofOfDeletion CBOR.
231 //
232 bool eicPresentationDeleteCredential(EicPresentation* ctx, const char* docType,
233                                      const uint8_t* challenge, size_t challengeSize,
234                                      bool includeChallenge, size_t proofOfDeletionCborSize,
235                                      uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]);
236 
237 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
238 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
239 // where content is set to the ProofOfOwnership CBOR.
240 //
241 bool eicPresentationProveOwnership(EicPresentation* ctx, const char* docType, bool testCredential,
242                                    const uint8_t* challenge, size_t challengeSize,
243                                    size_t proofOfOwnershipCborSize,
244                                    uint8_t signatureOfToBeSigned[EIC_ECDSA_P256_SIGNATURE_SIZE]);
245 
246 #ifdef __cplusplus
247 }
248 #endif
249 
250 #endif  // ANDROID_HARDWARE_IDENTITY_EIC_PRESENTATION_H
251