Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
buffer.c
Go to the documentation of this file.
1/*****************************************************************************
2 * (c) 2020 Ledger SAS.
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#include <stdint.h> // uint*_t
18#include <stddef.h> // size_t
19#include <stdbool.h> // bool
20#include <string.h> // memmove
21
22#include "buffer.h"
23#include "read.h"
24#include "varint.h"
25#include "write.h"
26
27bool buffer_can_read(const buffer_t *buffer, size_t n)
28{
29 return buffer->size - buffer->offset >= n;
30}
31
32#define buffer_has_space buffer_can_read
33
34bool buffer_seek_set(buffer_t *buffer, size_t offset)
35{
36 if (offset > buffer->size) {
37 return false;
38 }
39
40 buffer->offset = offset;
41
42 return true;
43}
44
45bool buffer_seek_cur(buffer_t *buffer, size_t offset)
46{
47 if (buffer->offset + offset < buffer->offset || // overflow
48 buffer->offset + offset > buffer->size) { // exceed buffer size
49 return false;
50 }
51
52 buffer->offset += offset;
53
54 return true;
55}
56
57bool buffer_seek_end(buffer_t *buffer, size_t offset)
58{
59 if (offset > buffer->size) {
60 return false;
61 }
62
63 buffer->offset = buffer->size - offset;
64
65 return true;
66}
67
68bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
69{
70 if (!buffer_can_read(buffer, 1)) {
71 *value = 0;
72
73 return false;
74 }
75
76 *value = buffer->ptr[buffer->offset];
77 buffer_seek_cur(buffer, 1);
78
79 return true;
80}
81
82bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
83{
84 if (!buffer_can_read(buffer, 2)) {
85 *value = 0;
86
87 return false;
88 }
89
90 *value = ((endianness == BE) ? read_u16_be(buffer->ptr, buffer->offset)
91 : read_u16_le(buffer->ptr, buffer->offset));
92
93 buffer_seek_cur(buffer, 2);
94
95 return true;
96}
97
98bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
99{
100 if (!buffer_can_read(buffer, 4)) {
101 *value = 0;
102
103 return false;
104 }
105
106 *value = ((endianness == BE) ? read_u32_be(buffer->ptr, buffer->offset)
107 : read_u32_le(buffer->ptr, buffer->offset));
108
109 buffer_seek_cur(buffer, 4);
110
111 return true;
112}
113
114bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
115{
116 if (!buffer_can_read(buffer, 8)) {
117 *value = 0;
118
119 return false;
120 }
121
122 *value = ((endianness == BE) ? read_u64_be(buffer->ptr, buffer->offset)
123 : read_u64_le(buffer->ptr, buffer->offset));
124
125 buffer_seek_cur(buffer, 8);
126
127 return true;
128}
129
130bool buffer_read_varint(buffer_t *buffer, uint64_t *value)
131{
132 int length = varint_read(buffer->ptr + buffer->offset, buffer->size - buffer->offset, value);
133
134 if (length < 0) {
135 *value = 0;
136
137 return false;
138 }
139
140 return buffer_seek_cur(buffer, (size_t) length);
141}
142
143bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
144{
145 if (!bip32_path_read(
146 buffer->ptr + buffer->offset, buffer->size - buffer->offset, out, out_len)) {
147 return false;
148 }
149
150 buffer_seek_cur(buffer, sizeof(*out) * out_len);
151
152 return true;
153}
154
156{
157 if ((buffer == NULL) || (bip32 == NULL) || !buffer_can_read(buffer, 1)) {
158 return false;
159 }
160
161 bip32->length = buffer->ptr[buffer->offset];
162 buffer->offset++;
163
164 if (!buffer_can_read(buffer, sizeof(uint32_t) * bip32->length)) {
165 return false;
166 }
167
168 if (!bip32_path_read(buffer->ptr + buffer->offset,
169 buffer->size - buffer->offset,
170 bip32->path,
171 bip32->length)) {
172 return false;
173 }
174
175 buffer_seek_cur(buffer, sizeof(*bip32->path) * bip32->length);
176
177 return true;
178}
179
180bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
181{
182 if (buffer->size - buffer->offset > out_len) {
183 return false;
184 }
185
186 memmove(out, buffer->ptr + buffer->offset, buffer->size - buffer->offset);
187
188 return true;
189}
190
191bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
192{
193 if (!buffer_copy(buffer, out, out_len)) {
194 return false;
195 }
196
197 buffer_seek_cur(buffer, out_len);
198
199 return true;
200}
201
202bool buffer_peek(const buffer_t *buffer, uint8_t *value)
203{
204 return buffer_peek_n(buffer, 0, value);
205}
206
207bool buffer_peek_n(const buffer_t *buffer, size_t n, uint8_t *value)
208{
209 if (buffer->size - buffer->offset < n + 1) {
210 return false;
211 }
212
213 *value = buffer->ptr[buffer->offset + n];
214
215 return true;
216}
217
218WEAK bool buffer_read_bytes(buffer_t *buffer, uint8_t *out, size_t n)
219{
220 if (buffer->size - buffer->offset < n) {
221 return false;
222 }
223
224 memmove(out, buffer->ptr + buffer->offset, n);
225 buffer_seek_cur(buffer, n);
226
227 return true;
228}
229
230bool buffer_write_u8(buffer_t *buffer, uint8_t value)
231{
232 if (!buffer_has_space(buffer, 1)) {
233 return false;
234 }
235
236 (buffer->ptr)[buffer->offset] = value;
237 buffer_seek_cur(buffer, 1);
238
239 return true;
240}
241
242bool buffer_write_u16(buffer_t *buffer, uint16_t value, endianness_t endianness)
243{
244 if (!buffer_has_space(buffer, 2)) {
245 return false;
246 }
247
248 if (endianness == BE) {
249 write_u16_be(buffer->ptr, buffer->offset, value);
250 }
251 else {
252 write_u16_le(buffer->ptr, buffer->offset, value);
253 }
254 buffer_seek_cur(buffer, 2);
255
256 return true;
257}
258
259bool buffer_write_u32(buffer_t *buffer, uint32_t value, endianness_t endianness)
260{
261 if (!buffer_has_space(buffer, 4)) {
262 return false;
263 }
264
265 if (endianness == BE) {
266 write_u32_be(buffer->ptr, buffer->offset, value);
267 }
268 else {
269 write_u32_le(buffer->ptr, buffer->offset, value);
270 }
271 buffer_seek_cur(buffer, 4);
272
273 return true;
274}
275
276bool buffer_write_u64(buffer_t *buffer, uint64_t value, endianness_t endianness)
277{
278 if (!buffer_has_space(buffer, 8)) {
279 return false;
280 }
281
282 if (endianness == BE) {
283 write_u64_be(buffer->ptr, buffer->offset, value);
284 }
285 else {
286 write_u64_le(buffer->ptr, buffer->offset, value);
287 }
288
289 buffer_seek_cur(buffer, 8);
290
291 return true;
292}
293
294bool buffer_write_bytes(buffer_t *buffer, const uint8_t *data, size_t n)
295{
296 if (!buffer_has_space(buffer, n)) {
297 return false;
298 }
299
300 memmove(buffer->ptr + buffer->offset, data, n);
301 buffer_seek_cur(buffer, n);
302 return true;
303}
bool bip32_path_read(const uint8_t *in, size_t in_len, uint32_t *out, size_t out_len)
Definition bip32.c:26
bool buffer_read_varint(buffer_t *buffer, uint64_t *value)
Definition buffer.c:130
bool buffer_seek_end(buffer_t *buffer, size_t offset)
Definition buffer.c:57
bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
Definition buffer.c:82
bool buffer_write_u16(buffer_t *buffer, uint16_t value, endianness_t endianness)
Definition buffer.c:242
bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
Definition buffer.c:180
bool buffer_seek_cur(buffer_t *buffer, size_t offset)
Definition buffer.c:45
bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
Definition buffer.c:143
bool buffer_write_bytes(buffer_t *buffer, const uint8_t *data, size_t n)
Definition buffer.c:294
bool buffer_get_path_bip32(buffer_t *buffer, path_bip32_t *bip32)
Definition buffer.c:155
bool buffer_seek_set(buffer_t *buffer, size_t offset)
Definition buffer.c:34
bool buffer_can_read(const buffer_t *buffer, size_t n)
Definition buffer.c:27
bool buffer_write_u64(buffer_t *buffer, uint64_t value, endianness_t endianness)
Definition buffer.c:276
bool buffer_peek(const buffer_t *buffer, uint8_t *value)
Definition buffer.c:202
bool buffer_write_u32(buffer_t *buffer, uint32_t value, endianness_t endianness)
Definition buffer.c:259
#define buffer_has_space
Definition buffer.c:32
bool buffer_write_u8(buffer_t *buffer, uint8_t value)
Definition buffer.c:230
bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
Definition buffer.c:114
WEAK bool buffer_read_bytes(buffer_t *buffer, uint8_t *out, size_t n)
Definition buffer.c:218
bool buffer_peek_n(const buffer_t *buffer, size_t n, uint8_t *value)
Definition buffer.c:207
bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
Definition buffer.c:191
bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
Definition buffer.c:98
bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
Definition buffer.c:68
endianness_t
Definition buffer.h:13
@ BE
Definition buffer.h:14
#define WEAK
Definition macros.h:8
uint32_t read_u32_le(const uint8_t *ptr, size_t offset)
Definition read.c:52
uint64_t read_u64_le(const uint8_t *ptr, size_t offset)
Definition read.c:60
uint16_t read_u16_le(const uint8_t *ptr, size_t offset)
Definition read.c:46
uint32_t read_u32_be(const uint8_t *ptr, size_t offset)
Definition read.c:26
uint64_t read_u64_be(const uint8_t *ptr, size_t offset)
Definition read.c:34
uint16_t read_u16_be(const uint8_t *ptr, size_t offset)
Definition read.c:20
uint8_t * ptr
Definition buffer.h:22
size_t size
Pointer to byte buffer.
Definition buffer.h:23
size_t offset
Size of byte buffer.
Definition buffer.h:24
uint32_t path[MAX_BIP32_PATH]
Definition bip32.h:19
uint8_t length
Definition bip32.h:18
int varint_read(const uint8_t *in, size_t in_len, uint64_t *value)
Definition varint.c:42
void write_u16_le(uint8_t *ptr, size_t offset, uint16_t value)
Definition write.c:46
void write_u32_be(uint8_t *ptr, size_t offset, uint32_t value)
Definition write.c:26
void write_u16_be(uint8_t *ptr, size_t offset, uint16_t value)
Definition write.c:20
void write_u64_be(uint8_t *ptr, size_t offset, uint64_t value)
Definition write.c:34
void write_u64_le(uint8_t *ptr, size_t offset, uint64_t value)
Definition write.c:60
void write_u32_le(uint8_t *ptr, size_t offset, uint32_t value)
Definition write.c:52