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