blob: 9c0f531e4aeb6a66e5a545b10e155a8f2eb09b8e [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_CBOR_H
22#define ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#include "EicOps.h"
29
30typedef enum {
31 EIC_CBOR_DIGEST_TYPE_SHA256,
32 EIC_CBOR_DIGEST_TYPE_HMAC_SHA256,
33} EicCborDigestType;
34
35/* EicCbor is a utility class to build CBOR data structures and calculate
36 * digests on the fly.
37 */
38typedef struct {
39 // Contains the size of the built CBOR, even if it exceeds bufferSize (will
40 // never write to buffer beyond bufferSize though)
41 size_t size;
42
43 // The size of the buffer. Is zero if no data is recorded in which case
44 // only digesting is performed.
45 size_t bufferSize;
46
47 // Whether we're producing a SHA-256 or HMAC-SHA256 digest.
48 EicCborDigestType digestType;
49
50 // The SHA-256 digester object.
51 union {
52 EicSha256Ctx sha256;
53 EicHmacSha256Ctx hmacSha256;
54 } digester;
55
David Zeuthen49f2d252020-10-16 11:27:24 -040056 // The secondary digester, may be unset.
57 EicSha256Ctx* secondaryDigesterSha256;
58
David Zeuthen630de2a2020-05-11 14:04:54 -040059 // The buffer used for building up CBOR or NULL if bufferSize is 0.
60 uint8_t* buffer;
61} EicCbor;
62
63/* Initializes an EicCbor.
64 *
65 * The given buffer will be used, up to bufferSize.
66 *
67 * If bufferSize is 0, buffer may be NULL.
68 */
69void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize);
70
71/* Like eicCborInit() but uses HMAC-SHA256 instead of SHA-256.
72 */
73void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize,
74 const uint8_t* hmacKey, size_t hmacKeySize);
75
David Zeuthen49f2d252020-10-16 11:27:24 -040076/* Enables a secondary digester.
77 *
78 * May be enabled midway through processing, this can be used to e.g. calculate
79 * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its
80 * payload.
81 */
82void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256);
83
David Zeuthen630de2a2020-05-11 14:04:54 -040084/* Finishes building CBOR and returns the digest. */
85void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
86
87/* Appends CBOR data to the EicCbor. */
88void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size);
89
90#define EIC_CBOR_MAJOR_TYPE_UNSIGNED 0
91#define EIC_CBOR_MAJOR_TYPE_NEGATIVE 1
92#define EIC_CBOR_MAJOR_TYPE_BYTE_STRING 2
93#define EIC_CBOR_MAJOR_TYPE_STRING 3
94#define EIC_CBOR_MAJOR_TYPE_ARRAY 4
95#define EIC_CBOR_MAJOR_TYPE_MAP 5
96#define EIC_CBOR_MAJOR_TYPE_SEMANTIC 6
97#define EIC_CBOR_MAJOR_TYPE_SIMPLE 7
98
99#define EIC_CBOR_SIMPLE_VALUE_FALSE 20
100#define EIC_CBOR_SIMPLE_VALUE_TRUE 21
101
102#define EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR 24
103
104/* Begins a new CBOR value. */
105void eicCborBegin(EicCbor* cbor, int majorType, size_t size);
106
107/* Appends a bytestring. */
108void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize);
109
110/* Appends a NUL-terminated UTF-8 string. */
111void eicCborAppendString(EicCbor* cbor, const char* str);
112
113/* Appends a simple value. */
114void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue);
115
116/* Appends a boolean. */
117void eicCborAppendBool(EicCbor* cbor, bool value);
118
119/* Appends a semantic */
120void eicCborAppendSemantic(EicCbor* cbor, uint64_t value);
121
122/* Appends an unsigned number. */
123void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value);
124
125/* Appends a number. */
126void eicCborAppendNumber(EicCbor* cbor, int64_t value);
127
128/* Starts appending an array.
129 *
130 * After this numElements CBOR elements must follow.
131 */
132void eicCborAppendArray(EicCbor* cbor, size_t numElements);
133
134/* Starts appending a map.
135 *
136 * After this numPairs pairs of CBOR elements must follow.
137 */
138void eicCborAppendMap(EicCbor* cbor, size_t numPairs);
139
140/* Calculates how many bytes are needed to store a size. */
141size_t eicCborAdditionalLengthBytesFor(size_t size);
142
143bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate,
144 size_t readerCertificateSize, bool userAuthenticationRequired,
145 uint64_t timeoutMillis, uint64_t secureUserId);
146
147bool eicCborCalcEntryAdditionalData(const int* accessControlProfileIds,
148 size_t numAccessControlProfileIds, const char* nameSpace,
149 const char* name, uint8_t* cborBuffer, size_t cborBufferSize,
150 size_t* outAdditionalDataCborSize,
151 uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]);
152
153// The maximum size of an encoded Secure Access Control Profile that we
154// support. Since the SACP may contain a reader certificate chain these can get
155// pretty big.
156//
157// Currently we allocate space on the stack for this structure which is why we
158// have a maximum size. We can get rid of the maximum size by incrementally
159// building/verifying the SACP. TODO: actually do this.
160//
161#define EIC_MAX_CBOR_SIZE_FOR_ACCESS_CONTROL_PROFILE 512
162
163#ifdef __cplusplus
164}
165#endif
166
167#endif // ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H