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