1 /* Copyright 2015 OpenMarket Ltd
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://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,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "olm/pickle.hh"
16 #include "olm/pickle.h"
17 
pickle(std::uint8_t * pos,std::uint32_t value)18 std::uint8_t * olm::pickle(
19     std::uint8_t * pos,
20     std::uint32_t value
21 ) {
22     pos += 4;
23     for (unsigned i = 4; i--;) { *(--pos) = value; value >>= 8; }
24     return pos + 4;
25 }
26 
27 
unpickle(std::uint8_t const * pos,std::uint8_t const * end,std::uint32_t & value)28 std::uint8_t const * olm::unpickle(
29     std::uint8_t const * pos, std::uint8_t const * end,
30     std::uint32_t & value
31 ) {
32     value = 0;
33     if (!pos || end < pos + 4) return nullptr;
34     for (unsigned i = 4; i--;) { value <<= 8; value |= *(pos++); }
35     return pos;
36 }
37 
pickle(std::uint8_t * pos,bool value)38 std::uint8_t * olm::pickle(
39     std::uint8_t * pos,
40     bool value
41 ) {
42     *(pos++) = value ? 1 : 0;
43     return pos;
44 }
45 
unpickle(std::uint8_t const * pos,std::uint8_t const * end,bool & value)46 std::uint8_t const * olm::unpickle(
47     std::uint8_t const * pos, std::uint8_t const * end,
48     bool & value
49 ) {
50     if (!pos || pos == end) return nullptr;
51     value = *(pos++);
52     return pos;
53 }
54 
pickle_bytes(std::uint8_t * pos,std::uint8_t const * bytes,std::size_t bytes_length)55 std::uint8_t * olm::pickle_bytes(
56     std::uint8_t * pos,
57     std::uint8_t const * bytes, std::size_t bytes_length
58 ) {
59     std::memcpy(pos, bytes, bytes_length);
60     return pos + bytes_length;
61 }
62 
unpickle_bytes(std::uint8_t const * pos,std::uint8_t const * end,std::uint8_t * bytes,std::size_t bytes_length)63 std::uint8_t const * olm::unpickle_bytes(
64     std::uint8_t const * pos, std::uint8_t const * end,
65     std::uint8_t * bytes, std::size_t bytes_length
66 ) {
67     if (!pos || end < pos + bytes_length) return nullptr;
68     std::memcpy(bytes, pos, bytes_length);
69     return pos + bytes_length;
70 }
71 
72 
pickle_length(const _olm_curve25519_public_key & value)73 std::size_t olm::pickle_length(
74     const _olm_curve25519_public_key & value
75 ) {
76     return sizeof(value.public_key);
77 }
78 
79 
pickle(std::uint8_t * pos,const _olm_curve25519_public_key & value)80 std::uint8_t * olm::pickle(
81     std::uint8_t * pos,
82     const _olm_curve25519_public_key & value
83 ) {
84     pos = olm::pickle_bytes(
85         pos, value.public_key, sizeof(value.public_key)
86     );
87     return pos;
88 }
89 
90 
unpickle(std::uint8_t const * pos,std::uint8_t const * end,_olm_curve25519_public_key & value)91 std::uint8_t const * olm::unpickle(
92     std::uint8_t const * pos, std::uint8_t const * end,
93     _olm_curve25519_public_key & value
94 ) {
95     return olm::unpickle_bytes(
96         pos, end, value.public_key, sizeof(value.public_key)
97     );
98 }
99 
100 
pickle_length(const _olm_curve25519_key_pair & value)101 std::size_t olm::pickle_length(
102     const _olm_curve25519_key_pair & value
103 ) {
104     return sizeof(value.public_key.public_key)
105         + sizeof(value.private_key.private_key);
106 }
107 
108 
pickle(std::uint8_t * pos,const _olm_curve25519_key_pair & value)109 std::uint8_t * olm::pickle(
110     std::uint8_t * pos,
111     const _olm_curve25519_key_pair & value
112 ) {
113     pos = olm::pickle_bytes(
114         pos, value.public_key.public_key,
115         sizeof(value.public_key.public_key)
116     );
117     pos = olm::pickle_bytes(
118         pos, value.private_key.private_key,
119         sizeof(value.private_key.private_key)
120     );
121     return pos;
122 }
123 
124 
unpickle(std::uint8_t const * pos,std::uint8_t const * end,_olm_curve25519_key_pair & value)125 std::uint8_t const * olm::unpickle(
126     std::uint8_t const * pos, std::uint8_t const * end,
127     _olm_curve25519_key_pair & value
128 ) {
129     pos = olm::unpickle_bytes(
130         pos, end, value.public_key.public_key,
131         sizeof(value.public_key.public_key)
132     );
133     if (!pos) return nullptr;
134 
135     pos = olm::unpickle_bytes(
136         pos, end, value.private_key.private_key,
137         sizeof(value.private_key.private_key)
138     );
139     if (!pos) return nullptr;
140 
141     return pos;
142 }
143 
144 ////// pickle.h implementations
145 
_olm_pickle_ed25519_public_key_length(const _olm_ed25519_public_key * value)146 std::size_t _olm_pickle_ed25519_public_key_length(
147     const _olm_ed25519_public_key * value
148 ) {
149     return sizeof(value->public_key);
150 }
151 
152 
_olm_pickle_ed25519_public_key(std::uint8_t * pos,const _olm_ed25519_public_key * value)153 std::uint8_t * _olm_pickle_ed25519_public_key(
154     std::uint8_t * pos,
155     const _olm_ed25519_public_key *value
156 ) {
157     return olm::pickle_bytes(
158         pos, value->public_key, sizeof(value->public_key)
159     );
160 }
161 
162 
_olm_unpickle_ed25519_public_key(std::uint8_t const * pos,std::uint8_t const * end,_olm_ed25519_public_key * value)163 std::uint8_t const * _olm_unpickle_ed25519_public_key(
164     std::uint8_t const * pos, std::uint8_t const * end,
165     _olm_ed25519_public_key * value
166 ) {
167     return olm::unpickle_bytes(
168         pos, end, value->public_key, sizeof(value->public_key)
169     );
170 }
171 
172 
_olm_pickle_ed25519_key_pair_length(const _olm_ed25519_key_pair * value)173 std::size_t _olm_pickle_ed25519_key_pair_length(
174     const _olm_ed25519_key_pair *value
175 ) {
176     return sizeof(value->public_key.public_key)
177         + sizeof(value->private_key.private_key);
178 }
179 
180 
_olm_pickle_ed25519_key_pair(std::uint8_t * pos,const _olm_ed25519_key_pair * value)181 std::uint8_t * _olm_pickle_ed25519_key_pair(
182     std::uint8_t * pos,
183     const _olm_ed25519_key_pair *value
184 ) {
185     pos = olm::pickle_bytes(
186         pos, value->public_key.public_key,
187         sizeof(value->public_key.public_key)
188     );
189     pos = olm::pickle_bytes(
190         pos, value->private_key.private_key,
191         sizeof(value->private_key.private_key)
192     );
193     return pos;
194 }
195 
196 
_olm_unpickle_ed25519_key_pair(std::uint8_t const * pos,std::uint8_t const * end,_olm_ed25519_key_pair * value)197 std::uint8_t const * _olm_unpickle_ed25519_key_pair(
198     std::uint8_t const * pos, std::uint8_t const * end,
199     _olm_ed25519_key_pair *value
200 ) {
201     pos = olm::unpickle_bytes(
202         pos, end, value->public_key.public_key,
203         sizeof(value->public_key.public_key)
204     );
205     if (!pos) return nullptr;
206 
207     pos = olm::unpickle_bytes(
208         pos, end, value->private_key.private_key,
209         sizeof(value->private_key.private_key)
210     );
211     if (!pos) return nullptr;
212 
213     return pos;
214 }
215 
_olm_pickle_uint32(uint8_t * pos,uint32_t value)216 uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value) {
217     return olm::pickle(pos, value);
218 }
219 
_olm_unpickle_uint32(uint8_t const * pos,uint8_t const * end,uint32_t * value)220 uint8_t const * _olm_unpickle_uint32(
221     uint8_t const * pos, uint8_t const * end,
222     uint32_t *value
223 ) {
224     return olm::unpickle(pos, end, *value);
225 }
226 
_olm_pickle_bool(uint8_t * pos,int value)227 uint8_t * _olm_pickle_bool(uint8_t * pos, int value) {
228     return olm::pickle(pos, (bool)value);
229 }
230 
_olm_unpickle_bool(uint8_t const * pos,uint8_t const * end,int * value)231 uint8_t const * _olm_unpickle_bool(
232     uint8_t const * pos, uint8_t const * end,
233     int *value
234 ) {
235     return olm::unpickle(pos, end, *reinterpret_cast<bool *>(value));
236 }
237 
_olm_pickle_bytes(uint8_t * pos,uint8_t const * bytes,size_t bytes_length)238 uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
239                            size_t bytes_length) {
240     return olm::pickle_bytes(pos, bytes, bytes_length);
241 }
242 
_olm_unpickle_bytes(uint8_t const * pos,uint8_t const * end,uint8_t * bytes,size_t bytes_length)243 uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
244                                    uint8_t * bytes, size_t bytes_length) {
245     return olm::unpickle_bytes(pos, end, bytes, bytes_length);
246 }
247