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_CBOR_H
22 #define ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #include "EicOps.h"
29 
30 typedef 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  */
38 typedef 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 
56     // The secondary digester, may be unset.
57     EicSha256Ctx* secondaryDigesterSha256;
58 
59     // 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  */
69 void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize);
70 
71 /* Like eicCborInit() but uses HMAC-SHA256 instead of SHA-256.
72  */
73 void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize,
74                            const uint8_t* hmacKey, size_t hmacKeySize);
75 
76 /* 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  */
82 void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256);
83 
84 /* Finishes building CBOR and returns the digest. */
85 void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);
86 
87 /* Appends CBOR data to the EicCbor. */
88 void 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. */
105 void eicCborBegin(EicCbor* cbor, int majorType, size_t size);
106 
107 /* Appends a bytestring. */
108 void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize);
109 
110 /* Appends a NUL-terminated UTF-8 string. */
111 void eicCborAppendString(EicCbor* cbor, const char* str);
112 
113 /* Appends a simple value. */
114 void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue);
115 
116 /* Appends a boolean. */
117 void eicCborAppendBool(EicCbor* cbor, bool value);
118 
119 /* Appends a semantic */
120 void eicCborAppendSemantic(EicCbor* cbor, uint64_t value);
121 
122 /* Appends an unsigned number. */
123 void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value);
124 
125 /* Appends a number. */
126 void eicCborAppendNumber(EicCbor* cbor, int64_t value);
127 
128 /* Starts appending an array.
129  *
130  * After this numElements CBOR elements must follow.
131  */
132 void eicCborAppendArray(EicCbor* cbor, size_t numElements);
133 
134 /* Starts appending a map.
135  *
136  * After this numPairs pairs of CBOR elements must follow.
137  */
138 void eicCborAppendMap(EicCbor* cbor, size_t numPairs);
139 
140 /* Calculates how many bytes are needed to store a size. */
141 size_t eicCborAdditionalLengthBytesFor(size_t size);
142 
143 bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate,
144                               size_t readerCertificateSize, bool userAuthenticationRequired,
145                               uint64_t timeoutMillis, uint64_t secureUserId);
146 
147 bool 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
168