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