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