Embedded SDK
Embedded SDK
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 "bip32.h"
26 
27 bool buffer_can_read(const buffer_t *buffer, size_t n)
28 {
29  return buffer->size - buffer->offset >= n;
30 }
31 
32 bool buffer_seek_set(buffer_t *buffer, size_t offset)
33 {
34  if (offset > buffer->size) {
35  return false;
36  }
37 
38  buffer->offset = offset;
39 
40  return true;
41 }
42 
43 bool buffer_seek_cur(buffer_t *buffer, size_t offset)
44 {
45  if (buffer->offset + offset < buffer->offset || // overflow
46  buffer->offset + offset > buffer->size) { // exceed buffer size
47  return false;
48  }
49 
50  buffer->offset += offset;
51 
52  return true;
53 }
54 
55 bool buffer_seek_end(buffer_t *buffer, size_t offset)
56 {
57  if (offset > buffer->size) {
58  return false;
59  }
60 
61  buffer->offset = buffer->size - offset;
62 
63  return true;
64 }
65 
66 bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
67 {
68  if (!buffer_can_read(buffer, 1)) {
69  *value = 0;
70 
71  return false;
72  }
73 
74  *value = buffer->ptr[buffer->offset];
75  buffer_seek_cur(buffer, 1);
76 
77  return true;
78 }
79 
80 bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
81 {
82  if (!buffer_can_read(buffer, 2)) {
83  *value = 0;
84 
85  return false;
86  }
87 
88  *value = ((endianness == BE) ? read_u16_be(buffer->ptr, buffer->offset)
89  : read_u16_le(buffer->ptr, buffer->offset));
90 
91  buffer_seek_cur(buffer, 2);
92 
93  return true;
94 }
95 
96 bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
97 {
98  if (!buffer_can_read(buffer, 4)) {
99  *value = 0;
100 
101  return false;
102  }
103 
104  *value = ((endianness == BE) ? read_u32_be(buffer->ptr, buffer->offset)
105  : read_u32_le(buffer->ptr, buffer->offset));
106 
107  buffer_seek_cur(buffer, 4);
108 
109  return true;
110 }
111 
112 bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
113 {
114  if (!buffer_can_read(buffer, 8)) {
115  *value = 0;
116 
117  return false;
118  }
119 
120  *value = ((endianness == BE) ? read_u64_be(buffer->ptr, buffer->offset)
121  : read_u64_le(buffer->ptr, buffer->offset));
122 
123  buffer_seek_cur(buffer, 8);
124 
125  return true;
126 }
127 
128 bool buffer_read_varint(buffer_t *buffer, uint64_t *value)
129 {
130  int length = varint_read(buffer->ptr + buffer->offset, buffer->size - buffer->offset, value);
131 
132  if (length < 0) {
133  *value = 0;
134 
135  return false;
136  }
137 
138  return buffer_seek_cur(buffer, (size_t) length);
139 }
140 
141 bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
142 {
143  if (!bip32_path_read(
144  buffer->ptr + buffer->offset, buffer->size - buffer->offset, out, out_len)) {
145  return false;
146  }
147 
148  buffer_seek_cur(buffer, sizeof(*out) * out_len);
149 
150  return true;
151 }
152 
153 bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
154 {
155  if (buffer->size - buffer->offset > out_len) {
156  return false;
157  }
158 
159  memmove(out, buffer->ptr + buffer->offset, buffer->size - buffer->offset);
160 
161  return true;
162 }
163 
164 bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
165 {
166  if (!buffer_copy(buffer, out, out_len)) {
167  return false;
168  }
169 
170  buffer_seek_cur(buffer, out_len);
171 
172  return true;
173 }
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:128
bool buffer_seek_end(buffer_t *buffer, size_t offset)
Definition: buffer.c:55
bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
Definition: buffer.c:80
bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
Definition: buffer.c:153
bool buffer_seek_cur(buffer_t *buffer, size_t offset)
Definition: buffer.c:43
bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
Definition: buffer.c:141
bool buffer_seek_set(buffer_t *buffer, size_t offset)
Definition: buffer.c:32
bool buffer_can_read(const buffer_t *buffer, size_t n)
Definition: buffer.c:27
bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
Definition: buffer.c:112
bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
Definition: buffer.c:164
bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
Definition: buffer.c:96
bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
Definition: buffer.c:66
endianness_t
Definition: buffer.h:10
@ BE
Definition: buffer.h:11
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
const uint8_t * ptr
Definition: buffer.h:19
size_t size
Pointer to byte buffer.
Definition: buffer.h:20
size_t offset
Size of byte buffer.
Definition: buffer.h:21
unsigned short uint16_t
Definition: usbd_conf.h:54
unsigned char uint8_t
Definition: usbd_conf.h:53
int varint_read(const uint8_t *in, size_t in_len, uint64_t *value)
Definition: varint.c:42