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