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, uint64_t size);
106 
107 /* Appends a bytestring. */
108 void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize);
109 
110 /* Appends a UTF-8 string. */
111 void eicCborAppendString(EicCbor* cbor, const char* str, size_t strLength);
112 
113 /* Appends a NUL-terminated UTF-8 string. */
114 void eicCborAppendStringZ(EicCbor* cbor, const char* str);
115 
116 /* Appends a simple value. */
117 void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue);
118 
119 /* Appends a boolean. */
120 void eicCborAppendBool(EicCbor* cbor, bool value);
121 
122 /* Appends a semantic */
123 void eicCborAppendSemantic(EicCbor* cbor, uint64_t value);
124 
125 /* Appends an unsigned number. */
126 void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value);
127 
128 /* Appends a number. */
129 void eicCborAppendNumber(EicCbor* cbor, int64_t value);
130 
131 /* Starts appending an array.
132  *
133  * After this numElements CBOR elements must follow.
134  */
135 void eicCborAppendArray(EicCbor* cbor, size_t numElements);
136 
137 /* Starts appending a map.
138  *
139  * After this numPairs pairs of CBOR elements must follow.
140  */
141 void eicCborAppendMap(EicCbor* cbor, size_t numPairs);
142 
143 /* Calculates how many bytes are needed to store a size. */
144 size_t eicCborAdditionalLengthBytesFor(size_t size);
145 
146 bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate,
147                               size_t readerCertificateSize, bool userAuthenticationRequired,
148                               uint64_t timeoutMillis, uint64_t secureUserId);
149 
150 bool eicCborCalcEntryAdditionalData(const uint8_t* accessControlProfileIds,
151                                     size_t numAccessControlProfileIds, const char* nameSpace,
152                                     size_t nameSpaceLength, const char* name,
153                                     size_t nameLength, uint8_t* cborBuffer,
154                                     size_t cborBufferSize, size_t* outAdditionalDataCborSize,
155                                     uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]);
156 
157 #ifdef __cplusplus
158 }
159 #endif
160 
161 #endif  // ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H
162