1 /* 2 * Copyright 2019, 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 IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_ 18 #define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_ 19 20 #include <cstdint> 21 #include <map> 22 #include <optional> 23 #include <string> 24 #include <tuple> 25 #include <utility> 26 #include <vector> 27 28 namespace android { 29 namespace hardware { 30 namespace identity { 31 namespace support { 32 33 using ::std::map; 34 using ::std::optional; 35 using ::std::pair; 36 using ::std::string; 37 using ::std::tuple; 38 using ::std::vector; 39 40 // The semantic tag for a bstr which includes Encoded CBOR (RFC 7049, section 2.4) 41 const int kSemanticTagEncodedCbor = 24; 42 43 // --------------------------------------------------------------------------- 44 // Miscellaneous utilities. 45 // --------------------------------------------------------------------------- 46 47 // Dumps the data in |data| to stderr. The written data will be of the following 48 // form for the call hexdump("signature", data) where |data| is of size 71: 49 // 50 // signature: dumping 71 bytes 51 // 0000 30 45 02 21 00 ac c6 12 60 56 a2 e9 ee 16 be 14 0E.!....`V...... 52 // 0010 69 7f c4 00 95 8c e8 55 1f 22 de 34 0b 08 8a 3b i......U.".4...; 53 // 0020 a0 56 54 05 07 02 20 58 77 d9 8c f9 eb 41 df fd .VT... Xw....A.. 54 // 0030 c1 a3 14 e0 bf b0 a2 c5 0c b6 85 8c 4a 0d f9 2b ............J..+ 55 // 0040 b7 8f d2 1d 9b 11 ac ....... 56 // 57 // This should only be used for debugging. 58 void hexdump(const string& name, const vector<uint8_t>& data); 59 60 string encodeHex(const string& str); 61 62 string encodeHex(const vector<uint8_t>& data); 63 64 string encodeHex(const uint8_t* data, size_t dataLen); 65 66 optional<vector<uint8_t>> decodeHex(const string& hexEncoded); 67 68 // --------------------------------------------------------------------------- 69 // CBOR utilities. 70 // --------------------------------------------------------------------------- 71 72 // Returns pretty-printed CBOR for |value|. 73 // 74 // Only valid CBOR should be passed to this function. 75 // 76 // If a byte-string is larger than |maxBStrSize| its contents will not be 77 // printed, instead the value of the form "<bstr size=1099016 78 // sha1=ef549cca331f73dfae2090e6a37c04c23f84b07b>" will be printed. Pass zero 79 // for |maxBStrSize| to disable this. 80 // 81 // The |mapKeysToNotPrint| parameter specifies the name of map values 82 // to not print. This is useful for unit tests. 83 string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize = 32, 84 const vector<string>& mapKeysToNotPrint = {}); 85 86 // --------------------------------------------------------------------------- 87 // Crypto functionality / abstraction. 88 // --------------------------------------------------------------------------- 89 90 constexpr size_t kAesGcmIvSize = 12; 91 constexpr size_t kAesGcmTagSize = 16; 92 constexpr size_t kAes128GcmKeySize = 16; 93 94 // Returns |numBytes| bytes of random data. 95 optional<vector<uint8_t>> getRandom(size_t numBytes); 96 97 // Calculates the SHA-256 of |data|. 98 vector<uint8_t> sha256(const vector<uint8_t>& data); 99 100 // Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|, 101 // returns resulting plaintext. The format of |encryptedData| must 102 // be as specified in the encryptAes128Gcm() function. 103 optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key, 104 const vector<uint8_t>& encryptedData, 105 const vector<uint8_t>& additionalAuthenticatedData); 106 107 // Encrypts |data| with |key| and |additionalAuthenticatedData| using |nonce|, 108 // returns the resulting (nonce || ciphertext || tag). 109 optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce, 110 const vector<uint8_t>& data, 111 const vector<uint8_t>& additionalAuthenticatedData); 112 113 // --------------------------------------------------------------------------- 114 // EC crypto functionality / abstraction (only supports P-256). 115 // --------------------------------------------------------------------------- 116 117 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the 118 // DER encoded private key. Also generates an attestation using the |challenge| 119 // and |applicationId|, and returns the generated certificate chain. 120 // 121 // The notBeffore field will be the current time and the notAfter will be the same 122 // same time as the batch certificate. 123 // 124 // The first parameter of the return value is the keyPair generated, second return in 125 // the pair is the attestation certificate generated. 126 // 127 optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation( 128 const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId, 129 bool isTestCredential); 130 131 // (TODO: remove when no longer used by 3rd party.) 132 optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey( 133 const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge, 134 const vector<uint8_t>& applicationId); 135 136 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the 137 // private key in DER format (as specified in RFC 5915). 138 // 139 optional<vector<uint8_t>> createEcKeyPair(); 140 141 // For an EC key |keyPair| encoded in DER format, extracts the public key in 142 // uncompressed point form. 143 // 144 optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair); 145 146 // For an EC key |keyPair| encoded in DER format, extracts the private key as 147 // an EC uncompressed key. 148 // 149 optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair); 150 151 // Creates a DER encoded representation from a private key (which must be uncompressed, 152 // e.g. 32 bytes). 153 // 154 optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey); 155 156 // For an EC key |keyPair| encoded in DER format, creates a PKCS#12 structure 157 // with the key-pair (not using a password to encrypt the data). The public key 158 // in the created structure is included as a certificate, using the given fields 159 // |serialDecimal|, |issuer|, |subject|, |validityNotBefore|, and 160 // |validityNotAfter|. 161 // 162 optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name, 163 const string& serialDecimal, const string& issuer, 164 const string& subject, time_t validityNotBefore, 165 time_t validityNotAfter); 166 167 // Signs |data| with |key| (which must be in the format returned by 168 // ecKeyPairGetPrivateKey()). Signature is returned and will be in DER format. 169 // 170 optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data); 171 172 // Like signEcDsa() but instead of taking the data to be signed, takes a digest 173 // of it instead. 174 // 175 optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key, 176 const vector<uint8_t>& dataDigest); 177 178 // Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC 179 // is returned and will be 32 bytes. 180 // 181 optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data); 182 183 // Checks that |signature| (in DER format) is a valid signature of |digest|, 184 // made with |publicKey| (which must be in the format returned by 185 // ecKeyPairGetPublicKey()). 186 // 187 bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature, 188 const vector<uint8_t>& publicKey); 189 190 // Extracts the public-key from the top-most certificate in |certificateChain| 191 // (which should be a concatenated chain of DER-encoded X.509 certificates). 192 // 193 // The returned public key will be in the same format as returned by 194 // ecKeyPairGetPublicKey(). 195 // 196 optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain); 197 198 // Extracts the public-key from the top-most certificate in |certificateChain| 199 // (which should be a concatenated chain of DER-encoded X.509 certificates). 200 // 201 // Return offset and size of the public-key 202 // 203 optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate); 204 205 // Extracts the TbsCertificate from the top-most certificate in |certificateChain| 206 // (which should be a concatenated chain of DER-encoded X.509 certificates). 207 // 208 // Return offset and size of the TbsCertificate 209 // 210 optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate); 211 212 // Extracts the Signature from the top-most certificate in |certificateChain| 213 // (which should be a concatenated chain of DER-encoded X.509 certificates). 214 // 215 // Return offset and size of the Signature 216 // 217 optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate); 218 219 // Extracts notBefore and notAfter from the top-most certificate in |certificateChain 220 // (which should be a concatenated chain of DER-encoded X.509 certificates). 221 // 222 // Returns notBefore and notAfter in that order. 223 // 224 optional<pair<time_t, time_t>> certificateGetValidity(const vector<uint8_t>& x509Certificate); 225 226 // Looks for an extension with OID in |oidStr| which must be an stored as an OCTET STRING. 227 // 228 optional<vector<uint8_t>> certificateGetExtension(const vector<uint8_t>& x509Certificate, 229 const string& oidStr); 230 231 // Generates a X.509 certificate for |publicKey| (which must be in the format 232 // returned by ecKeyPairGetPublicKey()). 233 // 234 // The certificate is signed by |signingKey| (which must be in the format 235 // returned by ecKeyPairGetPrivateKey()) 236 // 237 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate( 238 const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey, 239 const string& serialDecimal, const string& issuer, const string& subject, 240 time_t validityNotBefore, time_t validityNotAfter, 241 const map<string, vector<uint8_t>>& extensions); 242 243 // Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the 244 // format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be 245 // in the format returned by ecKeyPairGetPrivateKey()). 246 // 247 // On success, the computed shared secret is returned. 248 // 249 optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey, const vector<uint8_t>& privateKey); 250 251 // Key derivation function using SHA-256, conforming to RFC 5869. 252 // 253 // On success, the derived key is returned. 254 // 255 optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt, 256 const vector<uint8_t>& info, size_t size); 257 258 // Returns the X and Y coordinates from |publicKey| (which must be in the format 259 // returned by ecKeyPairGetPublicKey()). 260 // 261 // Success is indicated by the first value in the returned tuple. If successful, 262 // the returned coordinates will be in uncompressed form. 263 // 264 tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(const vector<uint8_t>& publicKey); 265 266 // Concatenates all certificates into |certificateChain| together into a 267 // single bytestring. 268 // 269 // This is the reverse operation of certificateChainSplit(). 270 vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain); 271 272 // Splits all the certificates in a single bytestring into individual 273 // certificates. 274 // 275 // Returns nothing if |certificateChain| contains invalid data. 276 // 277 // This is the reverse operation of certificateChainJoin(). 278 optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain); 279 280 // Validates that the certificate chain is valid. In particular, checks that each 281 // certificate in the chain is signed by the public key in the following certificate. 282 // 283 // Returns false if |certificateChain| failed validation or if each certificate 284 // is not signed by its successor. 285 // 286 bool certificateChainValidate(const vector<uint8_t>& certificateChain); 287 288 // Returns true if |certificate| is signed by |publicKey|. 289 // 290 bool certificateSignedByPublicKey(const vector<uint8_t>& certificate, 291 const vector<uint8_t>& publicKey); 292 293 // Signs |data| and |detachedContent| with |key| (which must be in the format 294 // returned by ecKeyPairGetPrivateKey()). 295 // 296 // On success, the Signature is returned and will be in COSE_Sign1 format. 297 // 298 // If |certificateChain| is non-empty it's included in the 'x5chain' 299 // protected header element (as as described in'draft-ietf-cose-x509-04'). 300 // 301 optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data, 302 const vector<uint8_t>& detachedContent, 303 const vector<uint8_t>& certificateChain); 304 305 // Creates a COSE_Signature1 where |signatureToBeSigned| is the ECDSA signature 306 // of the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process". 307 // 308 // The |signatureToBeSigned| is expected to be 64 bytes and contain the R value, 309 // then the S value. 310 // 311 // The |data| parameter will be included in the COSE_Sign1 CBOR. 312 // 313 // If |certificateChain| is non-empty it's included in the 'x5chain' 314 // protected header element (as as described in'draft-ietf-cose-x509-04'). 315 // 316 optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned, 317 const vector<uint8_t>& data, 318 const vector<uint8_t>& certificateChain); 319 320 // Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature 321 // made with |public_key| (which must be in the format returned by 322 // ecKeyPairGetPublicKey()) where |detachedContent| is the detached content. 323 // 324 bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1, 325 const vector<uint8_t>& detachedContent, 326 const vector<uint8_t>& publicKey); 327 328 // Converts a DER-encoded signature to the format used in 'signature' bstr in COSE_Sign1. 329 bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature, 330 vector<uint8_t>& ecdsaCoseSignature); 331 332 // Converts from the format in in 'signature' bstr in COSE_Sign1 to DER encoding. 333 bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature, 334 vector<uint8_t>& ecdsaDerSignature); 335 336 // Extracts the payload from a COSE_Sign1. 337 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1); 338 339 // Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1. 340 optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1); 341 342 // Extracts the signature algorithm from a COSE_Sign1. 343 optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1); 344 345 // Extracts the X.509 certificate chain, if present. Returns the data as a 346 // concatenated chain of DER-encoded X.509 certificates 347 // 348 // Returns nothing if there is no 'x5chain' element or an error occurs. 349 // 350 optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1); 351 352 // MACs |data| and |detachedContent| with |key| (which can be any sequence of 353 // bytes). 354 // 355 // If successful, the MAC is returned and will be in COSE_Mac0 format. 356 // 357 optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data, 358 const vector<uint8_t>& detachedContent); 359 360 // Creates a COSE_Mac0 where |digestToBeMaced| is the HMAC-SHA256 361 // of the ToBeMaced CBOR from RFC 8051 "6.3. How to Compute and Verify a MAC". 362 // 363 // The |digestToBeMaced| is expected to be 32 bytes. 364 // 365 // The |data| parameter will be included in the COSE_Mac0 CBOR. 366 // 367 optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced, 368 const vector<uint8_t>& data); 369 370 // --------------------------------------------------------------------------- 371 // Utility functions specific to IdentityCredential. 372 // --------------------------------------------------------------------------- 373 374 optional<vector<uint8_t>> calcMac(const vector<uint8_t>& sessionTranscriptEncoded, 375 const string& docType, 376 const vector<uint8_t>& deviceNameSpacesEncoded, 377 const vector<uint8_t>& eMacKey); 378 379 optional<vector<uint8_t>> calcEMacKey(const vector<uint8_t>& privateKey, 380 const vector<uint8_t>& publicKey, 381 const vector<uint8_t>& sessionTranscriptBytes); 382 383 // Returns the testing AES-128 key where all bits are set to 0. 384 const vector<uint8_t>& getTestHardwareBoundKey(); 385 386 // Splits the given bytestring into chunks. If the given vector is smaller or equal to 387 // |maxChunkSize| a vector with |content| as the only element is returned. Otherwise 388 // |content| is split into N vectors each of size |maxChunkSize| except the final element 389 // may be smaller than |maxChunkSize|. 390 vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize); 391 392 } // namespace support 393 } // namespace identity 394 } // namespace hardware 395 } // namespace android 396 397 #endif // IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_ 398