blob: aa26e6202aa217f39b6ef1e506b083678fc0a90b [file] [log] [blame]
David Zeuthen630de2a2020-05-11 14:04:54 -04001/*
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
34extern "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
79struct EicSha256Ctx {
80 uint8_t reserved[EIC_SHA256_CONTEXT_SIZE];
81};
82typedef struct EicSha256Ctx EicSha256Ctx;
83
84struct EicHmacSha256Ctx {
85 uint8_t reserved[EIC_HMAC_SHA256_CONTEXT_SIZE];
86};
87typedef 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
109void eicPrint(const char* format, ...);
110#else
111inline void eicPrint(const char*, ...) {}
112#endif
113
114// Dumps data as pretty-printed hex. Can be no-op.
115//
116#ifdef EIC_DEBUG
117void eicHexdump(const char* message, const uint8_t* data, size_t dataSize);
118#else
119inline 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
130void eicCborPrettyPrint(const uint8_t* cborData, size_t cborDataSize, size_t maxBStrSize);
131#else
132inline void eicCborPrettyPrint(const uint8_t*, size_t, size_t) {}
133#endif
134
135// Memory setting, see memset(3).
136void* eicMemSet(void* s, int c, size_t n);
137
138// Memory copying, see memcpy(3).
139void* eicMemCpy(void* dest, const void* src, size_t n);
140
141// String length, see strlen(3).
142size_t eicStrLen(const char* s);
143
David Zeuthen1eb12b22021-09-11 13:59:43 -0400144// Locate a substring, see memmem(3)
145void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle,
146 size_t needleLen);
147
David Zeuthen630de2a2020-05-11 14:04:54 -0400148// 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//
153int eicCryptoMemCmp(const void* s1, const void* s2, size_t n);
154
155// Random number generation.
156bool eicOpsRandom(uint8_t* buf, size_t numBytes);
157
David Zeuthen1eb12b22021-09-11 13:59:43 -0400158// 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//
162bool eicNextId(uint32_t* id);
163
David Zeuthen630de2a2020-05-11 14:04:54 -0400164// If |testCredential| is true, returns the 128-bit AES Hardware-Bound Key (16 bytes).
165//
166// Otherwise returns all zeroes (16 bytes).
167//
168const 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.
173bool 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.
186bool 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//
194bool 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// The attestation certificate will be signed by the attestation keys the secure
200// area has been provisioned with. The given |challenge| and |applicationId|
201// will be used as will |testCredential|.
202//
203// The generated certificate will be in X.509 format and returned in |cert|
204// and |certSize| must be set to the size of this array and this function will
205// set it to the size of the certification chain on successfully return.
206//
207// This may return either a single certificate or an entire certificate
208// chain. If it returns only a single certificate, the implementation of
209// SecureHardwareProvisioningProxy::createCredentialKey() should amend the
210// remainder of the certificate chain on the HAL side.
211//
212bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
213 size_t challengeSize, const uint8_t* applicationId,
214 size_t applicationIdSize, bool testCredential, uint8_t* cert,
215 size_t* certSize); // inout
216
217// Generate an X.509 certificate for the key identified by |publicKey| which
218// must be of the form returned by eicOpsCreateEcKey().
219//
David Zeuthen49f2d252020-10-16 11:27:24 -0400220// If proofOfBinding is not NULL, it will be included as an OCTET_STRING
221// X.509 extension at OID 1.3.6.1.4.1.11129.2.1.26.
222//
David Zeuthen630de2a2020-05-11 14:04:54 -0400223// The certificate will be signed by the key identified by |signingKey| which
224// must be of the form returned by eicOpsCreateEcKey().
225//
226bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
227 const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial,
228 const char* issuerName, const char* subjectName, time_t validityNotBefore,
David Zeuthen49f2d252020-10-16 11:27:24 -0400229 time_t validityNotAfter, const uint8_t* proofOfBinding,
230 size_t proofOfBindingSize, uint8_t* cert, size_t* certSize); // inout
David Zeuthen630de2a2020-05-11 14:04:54 -0400231
232// Uses |privateKey| to create an ECDSA signature of some data (the SHA-256 must
233// be given by |digestOfData|). Returns the signature in |signature|.
234//
235bool eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
236 const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],
237 uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE]);
238
239// Performs Elliptic Curve Diffie-Helman.
240//
241bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
242 const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
243 uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]);
244
245// Performs HKDF.
246//
247bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize, const uint8_t* salt,
248 size_t saltSize, const uint8_t* info, size_t infoSize, uint8_t* output,
249 size_t outputSize);
250
251// SHA-256 functions.
252void eicOpsSha256Init(EicSha256Ctx* ctx);
253void eicOpsSha256Update(EicSha256Ctx* ctx, const uint8_t* data, size_t len);
254void eicOpsSha256Final(EicSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
255
256// HMAC SHA-256 functions.
257void eicOpsHmacSha256Init(EicHmacSha256Ctx* ctx, const uint8_t* key, size_t keySize);
258void eicOpsHmacSha256Update(EicHmacSha256Ctx* ctx, const uint8_t* data, size_t len);
259void eicOpsHmacSha256Final(EicHmacSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
260
261// Extracts the public key in the given X.509 certificate.
262//
263// If the key is not an EC key, this function fails.
264//
265// Otherwise the public key is stored in uncompressed form in |publicKey| which
266// size should be set in |publicKeySize|. On successful return |publicKeySize|
267// is set to the length of the key. If there is not enough space, the function
268// fails.
269//
270// (The public key returned is not necessarily a P-256 key, even if it is note
271// that its size is not EIC_P256_PUBLIC_KEY_SIZE because of the leading 0x04.)
272//
273bool eicOpsX509GetPublicKey(const uint8_t* x509Cert, size_t x509CertSize, uint8_t* publicKey,
274 size_t* publicKeySize);
275
276// Checks that the X.509 certificate given by |x509Cert| is signed by the public
277// key given by |publicKey| which must be an EC key in uncompressed form (e.g.
278// same formatt as returned by eicOpsX509GetPublicKey()).
279//
280bool eicOpsX509CertSignedByPublicKey(const uint8_t* x509Cert, size_t x509CertSize,
281 const uint8_t* publicKey, size_t publicKeySize);
282
283// Checks that |signature| is a signature of some data (given by |digest|),
284// signed by the public key given by |publicKey|.
285//
286// The key must be an EC key in uncompressed form (e.g. same format as returned
287// by eicOpsX509GetPublicKey()).
288//
289// The format of the signature is the same encoding as the 'signature' field of
290// COSE_Sign1 - that is, it's the R and S integers both with the same length as
291// the key-size.
292//
293// The size of digest must match the size of the key.
294//
295bool eicOpsEcDsaVerifyWithPublicKey(const uint8_t* digest, size_t digestSize,
296 const uint8_t* signature, size_t signatureSize,
297 const uint8_t* publicKey, size_t publicKeySize);
298
299// Validates that the passed in data constitutes a valid auth- and verification tokens.
300//
301bool eicOpsValidateAuthToken(uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId,
302 int hardwareAuthenticatorType, uint64_t timeStamp, const uint8_t* mac,
303 size_t macSize, uint64_t verificationTokenChallenge,
304 uint64_t verificationTokenTimeStamp,
305 int verificationTokenSecurityLevel,
306 const uint8_t* verificationTokenMac, size_t verificationTokenMacSize);
307
David Zeuthen1eb12b22021-09-11 13:59:43 -0400308// Also see eicOpsLookupActiveSessionFromId() defined in EicSession.h
309
David Zeuthen630de2a2020-05-11 14:04:54 -0400310#ifdef __cplusplus
311}
312#endif
313
314#endif // ANDROID_HARDWARE_IDENTITY_EIC_OPS_H