1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #ifndef DICE_CBOR_WRITER_H_
16 #define DICE_CBOR_WRITER_H_
17
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 struct CborOut {
27 uint8_t* buffer;
28 size_t buffer_size;
29 size_t cursor;
30 };
31
32 // Initializes an output stream for writing CBOR tokens.
CborOutInit(uint8_t * buffer,size_t buffer_size,struct CborOut * out)33 static inline void CborOutInit(uint8_t* buffer, size_t buffer_size,
34 struct CborOut* out) {
35 out->buffer = buffer;
36 out->buffer_size = buffer_size;
37 out->cursor = 0;
38 }
39
40 // Returns the number of bytes of encoded data. If |CborOutOverflowed()|
41 // returns false, this number of bytes have been written, otherwise, this is the
42 // number of bytes that that would have been written had there been space.
CborOutSize(const struct CborOut * out)43 static inline size_t CborOutSize(const struct CborOut* out) {
44 return out->cursor;
45 }
46
47 // Returns whether the |out| buffer contains the encoded tokens written to it or
48 // whether the encoded tokens did not fit and the contents of the buffer should
49 // be considered invalid.
CborOutOverflowed(const struct CborOut * out)50 static inline bool CborOutOverflowed(const struct CborOut* out) {
51 return out->cursor == SIZE_MAX || out->cursor > out->buffer_size;
52 }
53
54 // These functions write simple deterministically encoded CBOR tokens to an
55 // output buffer. The offset is always increased, even if there is not enough
56 // space in the output buffer to allow for measurement of the encoded data.
57 // Use |CborOutOverflowed()| to check whether or not the buffer successfully
58 // contains all of the of the encoded data.
59 //
60 // Complex types are constructed from these simple types, see RFC 8949. The
61 // caller is responsible for correct and deterministic encoding of complex
62 // types.
63 void CborWriteInt(int64_t val, struct CborOut* out);
64 void CborWriteUint(uint64_t val, struct CborOut* out);
65 void CborWriteBstr(size_t data_size, const uint8_t* data, struct CborOut* out);
66 void CborWriteTstr(const char* str, struct CborOut* out);
67 void CborWriteArray(size_t num_elements, struct CborOut* out);
68 void CborWriteMap(size_t num_pairs, struct CborOut* out);
69 void CborWriteTag(uint64_t tag, struct CborOut* out);
70 void CborWriteFalse(struct CborOut* out);
71 void CborWriteTrue(struct CborOut* out);
72 void CborWriteNull(struct CborOut* out);
73
74 // These functions write the type header and reserve space for the caller to
75 // populate. The reserved space is left uninitialized. Returns NULL if space
76 // could not be reserved in the output buffer.
77 uint8_t* CborAllocBstr(size_t data_size, struct CborOut* out);
78 char* CborAllocTstr(size_t size, struct CborOut* out);
79
80 #ifdef __cplusplus
81 } // extern "C"
82 #endif
83
84 #endif // DICE_CBOR_WRITER_H_
85