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