1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <string.h>
11 #include "zcbor_encode.h"
12 #include "zcbor_common.h"
13 #include "zcbor_print.h"
14
15 _Static_assert((sizeof(size_t) == sizeof(void *)),
16 "This code needs size_t to be the same length as pointers.");
17
18
log2ceil(size_t val)19 static uint8_t log2ceil(size_t val)
20 {
21 switch(val) {
22 case 1: return 0;
23 case 2: return 1;
24 case 3: return 2;
25 case 4: return 2;
26 case 5: return 3;
27 case 6: return 3;
28 case 7: return 3;
29 case 8: return 3;
30 }
31
32 zcbor_log("Should not come here.\r\n");
33 return 0;
34 }
35
36
get_additional(size_t len,uint8_t value0)37 static uint8_t get_additional(size_t len, uint8_t value0)
38 {
39 return len == 0 ? value0 : (uint8_t)(24 + log2ceil(len));
40 }
41
42
encode_header_byte(zcbor_state_t * state,zcbor_major_type_t major_type,uint8_t additional)43 static bool encode_header_byte(zcbor_state_t *state,
44 zcbor_major_type_t major_type, uint8_t additional)
45 {
46 ZCBOR_CHECK_ERROR();
47 ZCBOR_CHECK_PAYLOAD();
48
49 zcbor_assert_state(additional < 32, "Unsupported additional value: %d\r\n", additional);
50
51 *(state->payload_mut) = (uint8_t)((major_type << 5) | (additional & 0x1F));
52 zcbor_trace(state, "value_encode");
53 state->payload_mut++;
54 return true;
55 }
56
57
58 /** Encode a single value.
59 */
value_encode_len(zcbor_state_t * state,zcbor_major_type_t major_type,const void * const result,size_t result_len)60 static bool value_encode_len(zcbor_state_t *state, zcbor_major_type_t major_type,
61 const void *const result, size_t result_len)
62 {
63 uint8_t *u8_result = (uint8_t *)result;
64
65 if ((state->payload + 1 + result_len) > state->payload_end) {
66 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
67 }
68
69 if (!encode_header_byte(state, major_type,
70 get_additional(result_len, u8_result[0]))) {
71 ZCBOR_FAIL();
72 }
73
74 #ifdef ZCBOR_BIG_ENDIAN
75 memcpy(state->payload_mut, u8_result, result_len);
76 state->payload_mut += result_len;
77 #else
78 for (; result_len > 0; result_len--) {
79 *(state->payload_mut++) = u8_result[result_len - 1];
80 }
81 #endif /* ZCBOR_BIG_ENDIAN */
82
83 state->elem_count++;
84 return true;
85 }
86
87
value_encode(zcbor_state_t * state,zcbor_major_type_t major_type,const void * const input,size_t max_result_len)88 static bool value_encode(zcbor_state_t *state, zcbor_major_type_t major_type,
89 const void *const input, size_t max_result_len)
90 {
91 zcbor_assert_state(max_result_len != 0, "0-length result not supported.\r\n");
92
93 size_t result_len = zcbor_header_len_ptr(input, max_result_len) - 1;
94 const void *result = input;
95
96 #ifdef ZCBOR_BIG_ENDIAN
97 result = (uint8_t *)input + max_result_len - (result_len ? result_len : 1);
98 #endif
99
100 return value_encode_len(state, major_type, result, result_len);
101 }
102
103
zcbor_int_encode(zcbor_state_t * state,const void * input_int,size_t int_size)104 bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size)
105 {
106 zcbor_major_type_t major_type;
107 uint8_t input_buf[8];
108 const uint8_t *input_uint8 = input_int;
109 const int8_t *input_int8 = input_int;
110 const uint8_t *input = input_int;
111
112 if (int_size > sizeof(int64_t)) {
113 ZCBOR_ERR(ZCBOR_ERR_INT_SIZE);
114 }
115
116 #ifdef ZCBOR_BIG_ENDIAN
117 if (input_int8[0] < 0) {
118 #else
119 if (input_int8[int_size - 1] < 0) {
120 #endif
121 major_type = ZCBOR_MAJOR_TYPE_NINT;
122
123 /* Convert to CBOR's representation by flipping all bits. */
124 for (unsigned int i = 0; i < int_size; i++) {
125 input_buf[i] = (uint8_t)~input_uint8[i];
126 }
127 input = input_buf;
128 } else {
129 major_type = ZCBOR_MAJOR_TYPE_PINT;
130 }
131
132 if (!value_encode(state, major_type, input, int_size)) {
133 ZCBOR_FAIL();
134 }
135
136 return true;
137 }
138
139
140 bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size)
141 {
142 if (!value_encode(state, ZCBOR_MAJOR_TYPE_PINT, input_uint, uint_size)) {
143 zcbor_log("uint with size %zu failed.\r\n", uint_size);
144 ZCBOR_FAIL();
145 }
146 return true;
147 }
148
149
150 bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input)
151 {
152 return zcbor_int_encode(state, input, sizeof(*input));
153 }
154
155
156 bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input)
157 {
158 return zcbor_int_encode(state, input, sizeof(*input));
159 }
160
161
162 bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input)
163 {
164 return zcbor_uint_encode(state, input, sizeof(*input));
165 }
166
167
168 bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input)
169 {
170 return zcbor_uint_encode(state, input, sizeof(*input));
171 }
172
173
174 bool zcbor_int32_put(zcbor_state_t *state, int32_t input)
175 {
176 return zcbor_int_encode(state, &input, sizeof(input));
177 }
178
179
180 bool zcbor_int64_put(zcbor_state_t *state, int64_t input)
181 {
182 return zcbor_int_encode(state, &input, sizeof(input));
183 }
184
185
186 bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input)
187 {
188 return zcbor_uint_encode(state, &input, sizeof(input));
189 }
190
191
192 bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input)
193 {
194 return zcbor_uint_encode(state, &input, sizeof(input));
195 }
196
197
198 #ifdef ZCBOR_SUPPORTS_SIZE_T
199 bool zcbor_size_put(zcbor_state_t *state, size_t input)
200 {
201 return zcbor_uint_encode(state, &input, sizeof(input));
202 }
203
204
205 bool zcbor_size_encode(zcbor_state_t *state, const size_t *input)
206 {
207 return zcbor_uint_encode(state, input, sizeof(*input));
208 }
209 #endif
210
211 static bool str_start_encode(zcbor_state_t *state,
212 const struct zcbor_string *input, zcbor_major_type_t major_type)
213 {
214 if (input->value && ((zcbor_header_len_ptr(&input->len, sizeof(input->len))
215 + input->len + (size_t)state->payload)
216 > (size_t)state->payload_end)) {
217 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
218 }
219 if (!value_encode(state, major_type, &input->len, sizeof(input->len))) {
220 ZCBOR_FAIL();
221 }
222
223 return true;
224 }
225
226
227 bool zcbor_bstr_start_encode(zcbor_state_t *state)
228 {
229 if (!zcbor_new_backup(state, 0)) {
230 ZCBOR_FAIL();
231 }
232
233 uint64_t max_len = zcbor_remaining_str_len(state);
234
235 /* Encode a dummy header */
236 if (!value_encode(state, ZCBOR_MAJOR_TYPE_BSTR, &max_len, sizeof(max_len))) {
237 ZCBOR_FAIL();
238 }
239 return true;
240 }
241
242
243 bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result)
244 {
245 const uint8_t *payload = state->payload;
246 struct zcbor_string dummy_value;
247
248 if (result == NULL) {
249 /* Use a dummy value for the sake of the length calculation below.
250 * Will not be returned.
251 */
252 result = &dummy_value;
253 }
254
255 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
256 ZCBOR_FAIL();
257 }
258
259 result->value = state->payload + zcbor_header_len(zcbor_remaining_str_len(state));
260 result->len = (size_t)payload - (size_t)result->value;
261
262 /* Reencode header of list now that we know the number of elements. */
263 if (!zcbor_bstr_encode(state, result)) {
264 ZCBOR_FAIL();
265 }
266 return true;
267 }
268
269
270 static bool str_encode(zcbor_state_t *state,
271 const struct zcbor_string *input, zcbor_major_type_t major_type)
272 {
273 ZCBOR_CHECK_PAYLOAD(); /* To make the size_t cast below safe. */
274 if (input->len > (size_t)(state->payload_end - state->payload)) {
275 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
276 }
277 if (!str_start_encode(state, input, major_type)) {
278 ZCBOR_FAIL();
279 }
280 if (state->payload_mut != input->value) {
281 /* Use memmove since string might be encoded into the same space
282 * because of bstrx_cbor_start_encode/bstrx_cbor_end_encode. */
283 memmove(state->payload_mut, input->value, input->len);
284 }
285 state->payload += input->len;
286 return true;
287 }
288
289
290 bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
291 {
292 return str_encode(state, input, ZCBOR_MAJOR_TYPE_BSTR);
293 }
294
295
296 bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
297 {
298 return str_encode(state, input, ZCBOR_MAJOR_TYPE_TSTR);
299 }
300
301
302 bool zcbor_bstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
303 {
304 const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
305
306 return zcbor_bstr_encode(state, &zs);
307 }
308
309
310 bool zcbor_tstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
311 {
312 const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
313
314 return zcbor_tstr_encode(state, &zs);
315 }
316
317
318 bool zcbor_bstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
319 {
320 return zcbor_bstr_encode_ptr(state, str, strnlen(str, maxlen));
321 }
322
323
324 bool zcbor_tstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
325 {
326 return zcbor_tstr_encode_ptr(state, str, strnlen(str, maxlen));
327 }
328
329
330 static bool list_map_start_encode(zcbor_state_t *state, size_t max_num,
331 zcbor_major_type_t major_type)
332 {
333 #ifdef ZCBOR_CANONICAL
334 if (!zcbor_new_backup(state, 0)) {
335 ZCBOR_FAIL();
336 }
337
338 /* Encode dummy header with max number of elements. */
339 if (!value_encode(state, major_type, &max_num, sizeof(max_num))) {
340 ZCBOR_FAIL();
341 }
342 state->elem_count--; /* Because of dummy header. */
343 #else
344 (void)max_num;
345
346 if (!encode_header_byte(state, major_type, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
347 ZCBOR_FAIL();
348 }
349 #endif
350 return true;
351 }
352
353
354 bool zcbor_list_start_encode(zcbor_state_t *state, size_t max_num)
355 {
356 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
357 }
358
359
360 bool zcbor_map_start_encode(zcbor_state_t *state, size_t max_num)
361 {
362 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
363 }
364
365
366 static bool list_map_end_encode(zcbor_state_t *state, size_t max_num,
367 zcbor_major_type_t major_type)
368 {
369 #ifdef ZCBOR_CANONICAL
370 size_t list_count = ((major_type == ZCBOR_MAJOR_TYPE_LIST) ?
371 state->elem_count
372 : (state->elem_count / 2));
373
374 const uint8_t *payload = state->payload;
375
376 size_t max_header_len = zcbor_header_len_ptr(&max_num, 4) - 1;
377 size_t header_len = zcbor_header_len_ptr(&list_count, 4) - 1;
378
379 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
380 ZCBOR_FAIL();
381 }
382
383 zcbor_log("list_count: %zu\r\n", list_count);
384
385
386 /** If max_num is smaller than the actual number of encoded elements,
387 * the value_encode() below will corrupt the data if the encoded
388 * header is larger than the previously encoded header. */
389 if (header_len > max_header_len) {
390 zcbor_log("max_num too small.\r\n");
391 ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
392 }
393
394 /* Reencode header of list now that we know the number of elements. */
395 if (!(value_encode(state, major_type, &list_count, sizeof(list_count)))) {
396 ZCBOR_FAIL();
397 }
398
399 if (max_header_len != header_len) {
400 const uint8_t *start = state->payload + max_header_len - header_len;
401 size_t body_size = (size_t)payload - (size_t)start;
402
403 memmove(state->payload_mut, start, body_size);
404 /* Reset payload pointer to end of list */
405 state->payload += body_size;
406 } else {
407 /* Reset payload pointer to end of list */
408 state->payload = payload;
409 }
410 #else
411 (void)max_num;
412 (void)major_type;
413 if (!encode_header_byte(state, ZCBOR_MAJOR_TYPE_SIMPLE, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
414 ZCBOR_FAIL();
415 }
416 #endif
417 return true;
418 }
419
420
421 bool zcbor_list_end_encode(zcbor_state_t *state, size_t max_num)
422 {
423 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
424 }
425
426
427 bool zcbor_map_end_encode(zcbor_state_t *state, size_t max_num)
428 {
429 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
430 }
431
432
433 bool zcbor_list_map_end_force_encode(zcbor_state_t *state)
434 {
435 #ifdef ZCBOR_CANONICAL
436 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME,
437 ZCBOR_MAX_ELEM_COUNT)) {
438 ZCBOR_FAIL();
439 }
440 #endif
441 (void)state;
442 return true;
443 }
444
445
446 bool zcbor_simple_encode(zcbor_state_t *state, uint8_t *input)
447 {
448 /* Simple values 24 to 31 inclusive are unused. Ref: RFC8949 sec 3.3 */
449 if ((*input > ZCBOR_VALUE_IN_HEADER) && (*input < 32)) {
450 ZCBOR_ERR(ZCBOR_ERR_INVALID_VALUE_ENCODING);
451 }
452 if (!value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, input, sizeof(*input))) {
453 zcbor_log("Error encoding %u (0x%p)\r\n", *input, input);
454 ZCBOR_FAIL();
455 }
456 return true;
457 }
458
459
460 bool zcbor_simple_put(zcbor_state_t *state, uint8_t input)
461 {
462 return zcbor_simple_encode(state, &input);
463 }
464
465
466 bool zcbor_nil_put(zcbor_state_t *state, const void *unused)
467 {
468 (void)unused;
469 return zcbor_simple_put(state, 22);
470 }
471
472
473 bool zcbor_undefined_put(zcbor_state_t *state, const void *unused)
474 {
475 (void)unused;
476 return zcbor_simple_put(state, 23);
477 }
478
479
480 bool zcbor_bool_encode(zcbor_state_t *state, const bool *input)
481 {
482 return zcbor_bool_put(state, *input);
483 }
484
485
486 bool zcbor_bool_put(zcbor_state_t *state, bool input)
487 {
488 return zcbor_simple_put(state, (!!input + ZCBOR_BOOL_TO_SIMPLE));
489 }
490
491
492 bool zcbor_float64_encode(zcbor_state_t *state, const double *input)
493 {
494 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
495 sizeof(*input))) {
496 ZCBOR_FAIL();
497 }
498
499 return true;
500 }
501
502
503 bool zcbor_float64_put(zcbor_state_t *state, double input)
504 {
505 return zcbor_float64_encode(state, &input);
506 }
507
508
509 bool zcbor_float32_encode(zcbor_state_t *state, const float *input)
510 {
511 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
512 sizeof(*input))) {
513 ZCBOR_FAIL();
514 }
515
516 return true;
517 }
518
519
520 bool zcbor_float32_put(zcbor_state_t *state, float input)
521 {
522 return zcbor_float32_encode(state, &input);
523 }
524
525
526 bool zcbor_float16_encode(zcbor_state_t *state, const float *input)
527 {
528 return zcbor_float16_put(state, *input);
529 }
530
531
532 bool zcbor_float16_put(zcbor_state_t *state, float input)
533 {
534 return zcbor_float16_bytes_put(state, zcbor_float32_to_16(input));
535 }
536
537
538 bool zcbor_float16_bytes_encode(zcbor_state_t *state, const uint16_t *input)
539 {
540 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
541 sizeof(*input))) {
542 ZCBOR_FAIL();
543 }
544
545 return true;
546 }
547
548
549 bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input)
550 {
551 return zcbor_float16_bytes_encode(state, &input);
552 }
553
554
555 bool zcbor_tag_put(zcbor_state_t *state, uint32_t tag)
556 {
557 if (!value_encode(state, ZCBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
558 ZCBOR_FAIL();
559 }
560 state->elem_count--;
561
562 return true;
563 }
564
565
566 bool zcbor_tag_encode(zcbor_state_t *state, uint32_t *tag)
567 {
568 return zcbor_tag_put(state, *tag);
569 }
570
571
572 bool zcbor_multi_encode_minmax(size_t min_encode, size_t max_encode,
573 const size_t *num_encode, zcbor_encoder_t encoder,
574 zcbor_state_t *state, const void *input, size_t result_len)
575 {
576
577 if ((*num_encode >= min_encode) && (*num_encode <= max_encode)) {
578 return zcbor_multi_encode(*num_encode, encoder, state, input, result_len);
579 } else {
580 ZCBOR_ERR(ZCBOR_ERR_ITERATIONS);
581 }
582 }
583
584
585 bool zcbor_multi_encode(const size_t num_encode, zcbor_encoder_t encoder,
586 zcbor_state_t *state, const void *input, size_t result_len)
587 {
588 ZCBOR_CHECK_ERROR();
589 for (size_t i = 0; i < num_encode; i++) {
590 if (!encoder(state, (const uint8_t *)input + i*result_len)) {
591 ZCBOR_FAIL();
592 }
593 }
594 zcbor_log("Encoded %zu elements.\n", num_encode);
595 return true;
596 }
597
598
599 void zcbor_new_encode_state(zcbor_state_t *state_array, size_t n_states,
600 uint8_t *payload, size_t payload_len, size_t elem_count)
601 {
602 zcbor_new_state(state_array, n_states, payload, payload_len, elem_count, NULL, 0);
603 }
604