1*60b67249SAndroid Build Coastguard Worker // Copyright 2021 Google LLC
2*60b67249SAndroid Build Coastguard Worker //
3*60b67249SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker // the License at
6*60b67249SAndroid Build Coastguard Worker //
7*60b67249SAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker //
9*60b67249SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker // the License.
14*60b67249SAndroid Build Coastguard Worker
15*60b67249SAndroid Build Coastguard Worker #ifndef DICE_CBOR_READER_H_
16*60b67249SAndroid Build Coastguard Worker #define DICE_CBOR_READER_H_
17*60b67249SAndroid Build Coastguard Worker
18*60b67249SAndroid Build Coastguard Worker #include <stdbool.h>
19*60b67249SAndroid Build Coastguard Worker #include <stddef.h>
20*60b67249SAndroid Build Coastguard Worker #include <stdint.h>
21*60b67249SAndroid Build Coastguard Worker
22*60b67249SAndroid Build Coastguard Worker #ifdef __cplusplus
23*60b67249SAndroid Build Coastguard Worker extern "C" {
24*60b67249SAndroid Build Coastguard Worker #endif
25*60b67249SAndroid Build Coastguard Worker
26*60b67249SAndroid Build Coastguard Worker struct CborIn {
27*60b67249SAndroid Build Coastguard Worker const uint8_t* buffer;
28*60b67249SAndroid Build Coastguard Worker size_t buffer_size;
29*60b67249SAndroid Build Coastguard Worker size_t cursor;
30*60b67249SAndroid Build Coastguard Worker };
31*60b67249SAndroid Build Coastguard Worker
32*60b67249SAndroid Build Coastguard Worker enum CborReadResult {
33*60b67249SAndroid Build Coastguard Worker CBOR_READ_RESULT_OK,
34*60b67249SAndroid Build Coastguard Worker // The end of the input was reached before the token was fully read.
35*60b67249SAndroid Build Coastguard Worker CBOR_READ_RESULT_END,
36*60b67249SAndroid Build Coastguard Worker // A malformed or unsupported token was found.
37*60b67249SAndroid Build Coastguard Worker CBOR_READ_RESULT_MALFORMED,
38*60b67249SAndroid Build Coastguard Worker // The requested token was not found.
39*60b67249SAndroid Build Coastguard Worker CBOR_READ_RESULT_NOT_FOUND,
40*60b67249SAndroid Build Coastguard Worker };
41*60b67249SAndroid Build Coastguard Worker
42*60b67249SAndroid Build Coastguard Worker // Initializes an input stream for reading CBOR tokens.
CborInInit(const uint8_t * buffer,size_t buffer_size,struct CborIn * in)43*60b67249SAndroid Build Coastguard Worker static inline void CborInInit(const uint8_t* buffer, size_t buffer_size,
44*60b67249SAndroid Build Coastguard Worker struct CborIn* in) {
45*60b67249SAndroid Build Coastguard Worker in->buffer = buffer;
46*60b67249SAndroid Build Coastguard Worker in->buffer_size = buffer_size;
47*60b67249SAndroid Build Coastguard Worker in->cursor = 0;
48*60b67249SAndroid Build Coastguard Worker }
49*60b67249SAndroid Build Coastguard Worker
50*60b67249SAndroid Build Coastguard Worker // Returns the number of bytes that have been read from the input.
CborInOffset(const struct CborIn * in)51*60b67249SAndroid Build Coastguard Worker static inline size_t CborInOffset(const struct CborIn* in) {
52*60b67249SAndroid Build Coastguard Worker return in->cursor;
53*60b67249SAndroid Build Coastguard Worker }
54*60b67249SAndroid Build Coastguard Worker
55*60b67249SAndroid Build Coastguard Worker // Returns whether the input stream has been fully consumed.
CborInAtEnd(const struct CborIn * in)56*60b67249SAndroid Build Coastguard Worker static inline bool CborInAtEnd(const struct CborIn* in) {
57*60b67249SAndroid Build Coastguard Worker return in->cursor == in->buffer_size;
58*60b67249SAndroid Build Coastguard Worker }
59*60b67249SAndroid Build Coastguard Worker
60*60b67249SAndroid Build Coastguard Worker // These functions read simple CBOR tokens from the input stream. Interpreting
61*60b67249SAndroid Build Coastguard Worker // the greater structure of the data left to the caller and it is expected that
62*60b67249SAndroid Build Coastguard Worker // these functions are just being used to validate and extract data from a known
63*60b67249SAndroid Build Coastguard Worker // structure.
64*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadInt(struct CborIn* in, int64_t* val);
65*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadUint(struct CborIn* in, uint64_t* val);
66*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadBstr(struct CborIn* in, size_t* data_size,
67*60b67249SAndroid Build Coastguard Worker const uint8_t** data);
68*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTstr(struct CborIn* in, size_t* size,
69*60b67249SAndroid Build Coastguard Worker const char** str);
70*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadArray(struct CborIn* in, size_t* num_elements);
71*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadMap(struct CborIn* in, size_t* num_pairs);
72*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadFalse(struct CborIn* in);
73*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTrue(struct CborIn* in);
74*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadNull(struct CborIn* in);
75*60b67249SAndroid Build Coastguard Worker // Returns CBOR_READ_RESULT_OK even if the value read does not correspond to
76*60b67249SAndroid Build Coastguard Worker // a valid tag. See https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
77*60b67249SAndroid Build Coastguard Worker // for a registry of reserved and invalid tag values.
78*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadTag(struct CborIn* in, uint64_t* tag);
79*60b67249SAndroid Build Coastguard Worker
80*60b67249SAndroid Build Coastguard Worker // Skips over the next CBOR item in the input. The item may contain nested
81*60b67249SAndroid Build Coastguard Worker // items, in the case of an array, map, or tag, and this function will attempt
82*60b67249SAndroid Build Coastguard Worker // to descend and skip all nested items in order to skip the parent item. There
83*60b67249SAndroid Build Coastguard Worker // is a limit on the level of nesting, after which this function will fail with
84*60b67249SAndroid Build Coastguard Worker // CBOR_READ_RESULT_MALFORMED.
85*60b67249SAndroid Build Coastguard Worker #define CBOR_READ_SKIP_STACK_SIZE 10
86*60b67249SAndroid Build Coastguard Worker enum CborReadResult CborReadSkip(struct CborIn* in);
87*60b67249SAndroid Build Coastguard Worker
88*60b67249SAndroid Build Coastguard Worker #ifdef __cplusplus
89*60b67249SAndroid Build Coastguard Worker } // extern "C"
90*60b67249SAndroid Build Coastguard Worker #endif
91*60b67249SAndroid Build Coastguard Worker
92*60b67249SAndroid Build Coastguard Worker #endif // DICE_CBOR_READER_H_
93