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