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