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_OPS_H
18 #define ANDROID_HARDWARE_IDENTITY_EIC_OPS_H
19 
20 #include <stdarg.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 
25 // Uncomment or define if debug messages are needed.
26 //
27 //#define EIC_DEBUG
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 // The following defines must be set to something appropriate
34 //
35 //   EIC_SHA256_CONTEXT_SIZE - the size of EicSha256Ctx
36 //   EIC_HMAC_SHA256_CONTEXT_SIZE - the size of EicHmacSha256Ctx
37 //
38 // For example, if EicSha256Ctx is implemented using BoringSSL this would be
39 // defined as sizeof(SHA256_CTX).
40 //
41 // We expect the implementation to provide a header file with the name
42 // EicOpsImpl.h to do all this.
43 //
44 #include "EicOpsImpl.h"
45 
46 #define EIC_SHA256_DIGEST_SIZE 32
47 
48 // The size of a P-256 private key.
49 //
50 #define EIC_P256_PRIV_KEY_SIZE 32
51 
52 // The size of a P-256 public key in uncompressed form.
53 //
54 // The public key is stored in uncompressed form, first the X coordinate, then
55 // the Y coordinate.
56 //
57 #define EIC_P256_PUB_KEY_SIZE 64
58 
59 // Size of one of the coordinates in a curve-point.
60 //
61 #define EIC_P256_COORDINATE_SIZE 32
62 
63 // The size of an ECSDA signature using P-256.
64 //
65 // The R and S values are stored here, first R then S.
66 //
67 #define EIC_ECDSA_P256_SIGNATURE_SIZE 64
68 
69 #define EIC_AES_128_KEY_SIZE 16
70 
71 // The following are definitions of implementation functions the
72 // underlying platform must provide.
73 //
74 
75 struct EicSha256Ctx {
76   uint8_t reserved[EIC_SHA256_CONTEXT_SIZE];
77 };
78 typedef struct EicSha256Ctx EicSha256Ctx;
79 
80 struct EicHmacSha256Ctx {
81   uint8_t reserved[EIC_HMAC_SHA256_CONTEXT_SIZE];
82 };
83 typedef struct EicHmacSha256Ctx EicHmacSha256Ctx;
84 
85 #ifdef EIC_DEBUG
86 // Debug macro. Don't include a new-line in message.
87 //
88 #define eicDebug(...)                        \
89   do {                                       \
90     eicPrint("%s:%d: ", __FILE__, __LINE__); \
91     eicPrint(__VA_ARGS__);                   \
92     eicPrint("\n");                          \
93   } while (0)
94 #else
95 #define eicDebug(...) \
96   do {                \
97   } while (0)
98 #endif
99 
100 // Prints message which should include new-line character. Can be no-op.
101 //
102 // Don't use this from code, use eicDebug() instead.
103 //
104 #ifdef EIC_DEBUG
105 void eicPrint(const char* format, ...);
106 #else
eicPrint(const char *,...)107 inline void eicPrint(const char*, ...) {}
108 #endif
109 
110 // Dumps data as pretty-printed hex. Can be no-op.
111 //
112 #ifdef EIC_DEBUG
113 void eicHexdump(const char* message, const uint8_t* data, size_t dataSize);
114 #else
eicHexdump(const char *,const uint8_t *,size_t)115 inline void eicHexdump(const char*, const uint8_t*, size_t) {}
116 #endif
117 
118 // Pretty-prints encoded CBOR. Can be no-op.
119 //
120 // If a byte-string is larger than |maxBStrSize| its contents will not be
121 // printed, instead the value of the form "<bstr size=1099016
122 // sha1=ef549cca331f73dfae2090e6a37c04c23f84b07b>" will be printed. Pass zero
123 // for |maxBStrSize| to disable this.
124 //
125 #ifdef EIC_DEBUG
126 void eicCborPrettyPrint(const uint8_t* cborData, size_t cborDataSize,
127                         size_t maxBStrSize);
128 #else
eicCborPrettyPrint(const uint8_t *,size_t,size_t)129 inline void eicCborPrettyPrint(const uint8_t*, size_t, size_t) {}
130 #endif
131 
132 // Memory setting, see memset(3).
133 void* eicMemSet(void* s, int c, size_t n);
134 
135 // Memory copying, see memcpy(3).
136 void* eicMemCpy(void* dest, const void* src, size_t n);
137 
138 // String length, see strlen(3).
139 size_t eicStrLen(const char* s);
140 
141 // Memory compare, see CRYPTO_memcmp(3SSL)
142 //
143 // It takes an amount of time dependent on len, but independent of the contents
144 // of the memory regions pointed to by s1 and s2.
145 //
146 int eicCryptoMemCmp(const void* s1, const void* s2, size_t n);
147 
148 // Random number generation.
149 bool eicOpsRandom(uint8_t* buf, size_t numBytes);
150 
151 // If |testCredential| is true, returns the 128-bit AES Hardware-Bound Key (16
152 // bytes).
153 //
154 // Otherwise returns all zeroes (16 bytes).
155 //
156 const uint8_t* eicOpsGetHardwareBoundKey(bool testCredential);
157 
158 // Encrypts |data| with |key| and |additionalAuthenticatedData| using |nonce|,
159 // returns the resulting (nonce || ciphertext || tag) in |encryptedData| which
160 // must be of size |dataSize| + 28.
161 bool eicOpsEncryptAes128Gcm(
162     const uint8_t* key,    // Must be 16 bytes
163     const uint8_t* nonce,  // Must be 12 bytes
164     const uint8_t* data,   // May be NULL if size is 0
165     size_t dataSize,
166     const uint8_t* additionalAuthenticationData,  // May be NULL if size is 0
167     size_t additionalAuthenticationDataSize, uint8_t* encryptedData);
168 
169 // Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
170 // returns resulting plaintext in |data| must be of size |encryptedDataSize|
171 // - 28.
172 //
173 // The format of |encryptedData| must be as specified in the
174 // encryptAes128Gcm() function.
175 bool eicOpsDecryptAes128Gcm(const uint8_t* key,  // Must be 16 bytes
176                             const uint8_t* encryptedData,
177                             size_t encryptedDataSize,
178                             const uint8_t* additionalAuthenticationData,
179                             size_t additionalAuthenticationDataSize,
180                             uint8_t* data);
181 
182 // Creates an EC key using the P-256 curve. The private key is written to
183 // |privateKey|. The public key is written to |publicKey|.
184 //
185 bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
186                        uint8_t publicKey[EIC_P256_PUB_KEY_SIZE]);
187 
188 // Generates CredentialKey plus an attestation certificate.
189 //
190 // The attestation certificate will be signed by the attestation keys the secure
191 // area has been provisioned with. The given |challenge| and |applicationId|
192 // will be used as will |testCredential|.
193 //
194 // The generated certificate will be in X.509 format and returned in |cert|
195 // and |certSize| must be set to the size of this array and this function will
196 // set it to the size of the certification chain on successfully return.
197 //
198 // This may return either a single certificate or an entire certificate
199 // chain. If it returns only a single certificate, the implementation of
200 // SecureHardwareProvisioningProxy::createCredentialKey() should amend the
201 // remainder of the certificate chain on the HAL side.
202 //
203 bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
204                                const uint8_t* challenge, size_t challengeSize,
205                                const uint8_t* applicationId,
206                                size_t applicationIdSize, bool testCredential,
207                                uint8_t* cert,
208                                size_t* certSize);  // in out
209 
210 // Generate an X.509 certificate for the key identified by |publicKey| which
211 // must be of the form returned by eicOpsCreateEcKey().
212 //
213 // If proofOfBinding is not NULL, it will be included as an OCTET_STRING
214 // X.509 extension at OID 1.3.6.1.4.1.11129.2.1.26.
215 //
216 // The certificate will be signed by the key identified by |signingKey| which
217 // must be of the form returned by eicOpsCreateEcKey().
218 //
219 bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
220                      const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE],
221                      unsigned int serial, const char* issuerName,
222                      const char* subjectName, time_t validityNotBefore,
223                      time_t validityNotAfter, const uint8_t* proofOfBinding,
224                      size_t proofOfBindingSize, uint8_t* cert,
225                      size_t* certSize);  // in out
226 
227 // Uses |privateKey| to create an ECDSA signature of some data (the SHA-256 must
228 // be given by |digestOfData|). Returns the signature in |signature|.
229 //
230 bool eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
231                  const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],
232                  uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE]);
233 
234 // Performs Elliptic Curve Diffie-Helman.
235 //
236 bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
237                 const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
238                 uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]);
239 
240 // Performs HKDF.
241 //
242 bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize,
243                 const uint8_t* salt, size_t saltSize, const uint8_t* info,
244                 size_t infoSize, uint8_t* output, size_t outputSize);
245 
246 // SHA-256 functions.
247 void eicOpsSha256Init(EicSha256Ctx* ctx);
248 void eicOpsSha256Update(EicSha256Ctx* ctx, const uint8_t* data, size_t len);
249 void eicOpsSha256Final(EicSha256Ctx* ctx,
250                        uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
251 
252 // HMAC SHA-256 functions.
253 void eicOpsHmacSha256Init(EicHmacSha256Ctx* ctx, const uint8_t* key,
254                           size_t keySize);
255 void eicOpsHmacSha256Update(EicHmacSha256Ctx* ctx, const uint8_t* data,
256                             size_t len);
257 void eicOpsHmacSha256Final(EicHmacSha256Ctx* ctx,
258                            uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
259 
260 // Extracts the public key in the given X.509 certificate.
261 //
262 // If the key is not an EC key, this function fails.
263 //
264 // Otherwise the public key is stored in uncompressed form in |publicKey| which
265 // size should be set in |publicKeySize|. On successful return |publicKeySize|
266 // is set to the length of the key. If there is not enough space, the function
267 // fails.
268 //
269 // (The public key returned is not necessarily a P-256 key, even if it is note
270 // that its size is not EIC_P256_PUBLIC_KEY_SIZE because of the leading 0x04.)
271 //
272 bool eicOpsX509GetPublicKey(const uint8_t* x509Cert, size_t x509CertSize,
273                             uint8_t* publicKey, size_t* publicKeySize);
274 
275 // Checks that the X.509 certificate given by |x509Cert| is signed by the public
276 // key given by |publicKey| which must be an EC key in uncompressed form (e.g.
277 // same formatt as returned by eicOpsX509GetPublicKey()).
278 //
279 bool eicOpsX509CertSignedByPublicKey(const uint8_t* x509Cert,
280                                      size_t x509CertSize,
281                                      const uint8_t* publicKey,
282                                      size_t publicKeySize);
283 
284 // Checks that |signature| is a signature of some data (given by |digest|),
285 // signed by the public key given by |publicKey|.
286 //
287 // The key must be an EC key in uncompressed form (e.g.  same format as returned
288 // by eicOpsX509GetPublicKey()).
289 //
290 // The format of the signature is the same encoding as the 'signature' field of
291 // COSE_Sign1 - that is, it's the R and S integers both with the same length as
292 // the key-size.
293 //
294 // The size of digest must match the size of the key.
295 //
296 bool eicOpsEcDsaVerifyWithPublicKey(const uint8_t* digest, size_t digestSize,
297                                     const uint8_t* signature,
298                                     size_t signatureSize,
299                                     const uint8_t* publicKey,
300                                     size_t publicKeySize);
301 
302 // Validates that the passed in data constitutes a valid auth- and verification
303 // tokens.
304 //
305 bool eicOpsValidateAuthToken(
306     uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId,
307     int hardwareAuthenticatorType, uint64_t timeStamp, const uint8_t* mac,
308     size_t macSize, uint64_t verificationTokenChallenge,
309     uint64_t verificationTokenTimeStamp, int verificationTokenSecurityLevel,
310     const uint8_t* verificationTokenMac, size_t verificationTokenMacSize);
311 
312 #ifdef __cplusplus
313 }
314 #endif
315 
316 #endif  // ANDROID_HARDWARE_IDENTITY_EIC_OPS_H
317