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