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