summaryrefslogtreecommitdiff
path: root/identity/aidl/default/libeic/EicCbor.h
blob: 16f7ab66190c0322c762d9cf5f745adf14c53675 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright 2020, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION)
#error "Never include this file directly, include libeic.h instead."
#endif

#ifndef ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H
#define ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H

#ifdef __cplusplus
extern "C" {
#endif

#include "EicOps.h"

typedef enum {
    EIC_CBOR_DIGEST_TYPE_SHA256,
    EIC_CBOR_DIGEST_TYPE_HMAC_SHA256,
} EicCborDigestType;

/* EicCbor is a utility class to build CBOR data structures and calculate
 * digests on the fly.
 */
typedef struct {
    // Contains the size of the built CBOR, even if it exceeds bufferSize (will
    // never write to buffer beyond bufferSize though)
    size_t size;

    // The size of the buffer. Is zero if no data is recorded in which case
    // only digesting is performed.
    size_t bufferSize;

    // Whether we're producing a SHA-256 or HMAC-SHA256 digest.
    EicCborDigestType digestType;

    // The SHA-256 digester object.
    union {
        EicSha256Ctx sha256;
        EicHmacSha256Ctx hmacSha256;
    } digester;

    // The secondary digester, may be unset.
    EicSha256Ctx* secondaryDigesterSha256;

    // The buffer used for building up CBOR or NULL if bufferSize is 0.
    uint8_t* buffer;
} EicCbor;

/* Initializes an EicCbor.
 *
 * The given buffer will be used, up to bufferSize.
 *
 * If bufferSize is 0, buffer may be NULL.
 */
void eicCborInit(EicCbor* cbor, uint8_t* buffer, size_t bufferSize);

/* Like eicCborInit() but uses HMAC-SHA256 instead of SHA-256.
 */
void eicCborInitHmacSha256(EicCbor* cbor, uint8_t* buffer, size_t bufferSize,
                           const uint8_t* hmacKey, size_t hmacKeySize);

/* Enables a secondary digester.
 *
 * May be enabled midway through processing, this can be used to e.g. calculate
 * a digest of Sig_structure (for COSE_Sign1) and a separate digest of its
 * payload.
 */
void eicCborEnableSecondaryDigesterSha256(EicCbor* cbor, EicSha256Ctx* sha256);

/* Finishes building CBOR and returns the digest. */
void eicCborFinal(EicCbor* cbor, uint8_t digest[EIC_SHA256_DIGEST_SIZE]);

/* Appends CBOR data to the EicCbor. */
void eicCborAppend(EicCbor* cbor, const uint8_t* data, size_t size);

#define EIC_CBOR_MAJOR_TYPE_UNSIGNED 0
#define EIC_CBOR_MAJOR_TYPE_NEGATIVE 1
#define EIC_CBOR_MAJOR_TYPE_BYTE_STRING 2
#define EIC_CBOR_MAJOR_TYPE_STRING 3
#define EIC_CBOR_MAJOR_TYPE_ARRAY 4
#define EIC_CBOR_MAJOR_TYPE_MAP 5
#define EIC_CBOR_MAJOR_TYPE_SEMANTIC 6
#define EIC_CBOR_MAJOR_TYPE_SIMPLE 7

#define EIC_CBOR_SIMPLE_VALUE_FALSE 20
#define EIC_CBOR_SIMPLE_VALUE_TRUE 21

#define EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR 24

/* Begins a new CBOR value. */
void eicCborBegin(EicCbor* cbor, int majorType, uint64_t size);

/* Appends a bytestring. */
void eicCborAppendByteString(EicCbor* cbor, const uint8_t* data, size_t dataSize);

/* Appends a UTF-8 string. */
void eicCborAppendString(EicCbor* cbor, const char* str, size_t strLength);

/* Appends a NUL-terminated UTF-8 string. */
void eicCborAppendStringZ(EicCbor* cbor, const char* str);

/* Appends a simple value. */
void eicCborAppendSimple(EicCbor* cbor, uint8_t simpleValue);

/* Appends a boolean. */
void eicCborAppendBool(EicCbor* cbor, bool value);

/* Appends a semantic */
void eicCborAppendSemantic(EicCbor* cbor, uint64_t value);

/* Appends an unsigned number. */
void eicCborAppendUnsigned(EicCbor* cbor, uint64_t value);

/* Appends a number. */
void eicCborAppendNumber(EicCbor* cbor, int64_t value);

/* Starts appending an array.
 *
 * After this numElements CBOR elements must follow.
 */
void eicCborAppendArray(EicCbor* cbor, size_t numElements);

/* Starts appending a map.
 *
 * After this numPairs pairs of CBOR elements must follow.
 */
void eicCborAppendMap(EicCbor* cbor, size_t numPairs);

/* Calculates how many bytes are needed to store a size. */
size_t eicCborAdditionalLengthBytesFor(size_t size);

bool eicCborCalcAccessControl(EicCbor* cborBuilder, int id, const uint8_t* readerCertificate,
                              size_t readerCertificateSize, bool userAuthenticationRequired,
                              uint64_t timeoutMillis, uint64_t secureUserId);

bool eicCborCalcEntryAdditionalData(const uint8_t* accessControlProfileIds,
                                    size_t numAccessControlProfileIds, const char* nameSpace,
                                    size_t nameSpaceLength, const char* name,
                                    size_t nameLength, uint8_t* cborBuffer,
                                    size_t cborBufferSize, size_t* outAdditionalDataCborSize,
                                    uint8_t additionalDataSha256[EIC_SHA256_DIGEST_SIZE]);

#ifdef __cplusplus
}
#endif

#endif  // ANDROID_HARDWARE_IDENTITY_EIC_CBOR_H