1 /*
2  * This file has been copied from the cddl-gen submodule.
3  * Commit 9f77837f9950da1633d22abf6181a830521a6688
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 "cbor_decode.h"
17 #include "cbor_common.h"
18 
19 
20 /** Return value length from additional value.
21  */
additional_len(uint8_t additional)22 static uint32_t additional_len(uint8_t additional)
23 {
24 	if (24 <= additional && additional <= 27) {
25 		/* 24 => 1
26 		 * 25 => 2
27 		 * 26 => 4
28 		 * 27 => 8
29 		 */
30 		return 1 << (additional - 24);
31 	}
32 	return 0;
33 }
34 
35 /** Extract the major type, i.e. the first 3 bits of the header byte. */
36 #define MAJOR_TYPE(header_byte) (((header_byte) >> 5) & 0x7)
37 
38 /** Extract the additional info, i.e. the last 5 bits of the header byte. */
39 #define ADDITIONAL(header_byte) ((header_byte) & 0x1F)
40 
41 
42 #define FAIL_AND_DECR_IF(expr) \
43 do {\
44 	if (expr) { \
45 		(state->payload)--; \
46 		FAIL(); \
47 	} \
48 } while(0)
49 
50 #define FAIL_IF(expr) \
51 do {\
52 	if (expr) { \
53 		FAIL(); \
54 	} \
55 } while(0)
56 
57 
58 #define FAIL_RESTORE() \
59 	state->payload = state->payload_bak; \
60 	state->elem_count++; \
61 	FAIL()
62 
63 /** Get a single value.
64  *
65  * @details @p ppayload must point to the header byte. This function will
66  *          retrieve the value (either from within the additional info, or from
67  *          the subsequent bytes) and return it in the result. The result can
68  *          have arbitrary length.
69  *
70  *          The function will also validate
71  *           - Min/max constraints on the value.
72  *           - That @p payload doesn't overrun past @p payload_end.
73  *           - That @p elem_count has not been exhausted.
74  *
75  *          @p ppayload and @p elem_count are updated if the function
76  *          succeeds. If not, they are left unchanged.
77  *
78  *          CBOR values are always big-endian, so this function converts from
79  *          big to little-endian if necessary (@ref CONFIG_BIG_ENDIAN).
80  */
value_extract(cbor_state_t * state,void * const result,uint32_t result_len)81 static bool value_extract(cbor_state_t *state,
82 		void *const result, uint32_t result_len)
83 {
84 	cbor_trace();
85 	cbor_assert(result_len != 0, "0-length result not supported.\n");
86 	cbor_assert(result != NULL, NULL);
87 
88 	FAIL_IF((state->elem_count == 0) \
89 		|| (state->payload >= state->payload_end));
90 
91 	uint8_t *u8_result  = (uint8_t *)result;
92 	uint8_t additional = ADDITIONAL(*state->payload);
93 
94 	state->payload_bak = state->payload;
95 	(state->payload)++;
96 
97 	memset(result, 0, result_len);
98 	if (additional <= VALUE_IN_HEADER) {
99 #ifdef CONFIG_BIG_ENDIAN
100 		u8_result[result_len - 1] = additional;
101 #else
102 		u8_result[0] = additional;
103 #endif /* CONFIG_BIG_ENDIAN */
104 	} else {
105 		uint32_t len = additional_len(additional);
106 
107 		FAIL_AND_DECR_IF(len > result_len);
108 		FAIL_AND_DECR_IF((state->payload + len)
109 				> state->payload_end);
110 
111 #ifdef CONFIG_BIG_ENDIAN
112 		memcpy(&u8_result[result_len - len], state->payload, len);
113 #else
114 		for (uint32_t i = 0; i < len; i++) {
115 			u8_result[i] = (state->payload)[len - i - 1];
116 		}
117 #endif /* CONFIG_BIG_ENDIAN */
118 
119 		(state->payload) += len;
120 	}
121 
122 	(state->elem_count)--;
123 	return true;
124 }
125 
126 
int32_decode(cbor_state_t * state,int32_t * result)127 static bool int32_decode(cbor_state_t *state, int32_t *result)
128 {
129 	FAIL_IF(state->payload >= state->payload_end);
130 	uint8_t major_type = MAJOR_TYPE(*state->payload);
131 	uint32_t uint_result;
132 	int32_t int_result;
133 
134 	if (!value_extract(state, &uint_result, 4)) {
135 		FAIL();
136 	}
137 
138 	cbor_print("uintval: %u\r\n", uint_result);
139 	if (uint_result >= (1 << (8*sizeof(uint_result)-1))) {
140 		/* Value is too large to fit in a signed integer. */
141 		FAIL_RESTORE();
142 	}
143 
144 	if (major_type == CBOR_MAJOR_TYPE_NINT) {
145 		/* Convert from CBOR's representation. */
146 		int_result = -1 - uint_result;
147 	} else {
148 		int_result = uint_result;
149 	}
150 
151 	cbor_print("val: %d\r\n", int_result);
152 	*result = int_result;
153 	return true;
154 }
155 
156 
intx32_decode(cbor_state_t * state,int32_t * result)157 bool intx32_decode(cbor_state_t *state, int32_t *result)
158 {
159 	FAIL_IF(state->payload >= state->payload_end);
160 	uint8_t major_type = MAJOR_TYPE(*state->payload);
161 
162 	if (major_type != CBOR_MAJOR_TYPE_PINT
163 		&& major_type != CBOR_MAJOR_TYPE_NINT) {
164 		/* Value to be read doesn't have the right type. */
165 		FAIL();
166 	}
167 
168 	if (!int32_decode(state, result)) {
169 		FAIL();
170 	}
171 	return true;
172 }
173 
intx32_expect(cbor_state_t * state,int32_t result)174 bool intx32_expect(cbor_state_t *state, int32_t result)
175 {
176 	int32_t value;
177 
178 	if (!intx32_decode(state, &value)) {
179 		FAIL();
180 	}
181 
182 	if (value != result) {
183 		cbor_print("%d != %d\r\n", value, result);
184 		FAIL_RESTORE();
185 	}
186 	return true;
187 }
188 
189 
uint32_decode(cbor_state_t * state,uint32_t * result)190 static bool uint32_decode(cbor_state_t *state, uint32_t *result)
191 {
192 	if (!value_extract(state, result, 4)) {
193 		FAIL();
194 	}
195 
196 	return true;
197 }
198 
199 
uintx32_decode(cbor_state_t * state,uint32_t * result)200 bool uintx32_decode(cbor_state_t *state, uint32_t *result)
201 {
202 	FAIL_IF(state->payload >= state->payload_end);
203 	uint8_t major_type = MAJOR_TYPE(*state->payload);
204 
205 	if (major_type != CBOR_MAJOR_TYPE_PINT) {
206 		/* Value to be read doesn't have the right type. */
207 		FAIL();
208 	}
209 	if (!uint32_decode(state, result)) {
210 		FAIL();
211 	}
212 	return true;
213 }
214 
uintx32_expect(cbor_state_t * state,uint32_t result)215 bool uintx32_expect(cbor_state_t *state, uint32_t result)
216 {
217 	uint32_t value;
218 
219 	if (!uintx32_decode(state, &value)) {
220 		FAIL();
221 	}
222 	if (value != result) {
223 		cbor_print("%u != %u\r\n", value, result);
224 		FAIL_RESTORE();
225 	}
226 	return true;
227 }
228 
uintx32_expect_union(cbor_state_t * state,uint32_t result)229 bool uintx32_expect_union(cbor_state_t *state, uint32_t result)
230 {
231 	union_elem_code(state);
232 	return uintx32_expect(state, result);
233 }
234 
235 
strx_start_decode(cbor_state_t * state,cbor_string_type_t * result,cbor_major_type_t exp_major_type)236 static bool strx_start_decode(cbor_state_t *state,
237 		cbor_string_type_t *result, cbor_major_type_t exp_major_type)
238 {
239 	FAIL_IF(state->payload >= state->payload_end);
240 	uint8_t major_type = MAJOR_TYPE(*state->payload);
241 
242 	if (major_type != exp_major_type) {
243 		FAIL();
244 	}
245 
246 	if (!uint32_decode(state, &result->len)) {
247 		FAIL();
248 	}
249 
250 	if (result->len > (state->payload_end - state->payload)) {
251 		cbor_print("error: 0x%x > 0x%x\r\n",
252 		(uint32_t)result->len,
253 		(uint32_t)(state->payload_end - state->payload));
254 		FAIL_RESTORE();
255 	}
256 
257 	result->value = state->payload;
258 	return true;
259 }
260 
bstrx_cbor_start_decode(cbor_state_t * state,cbor_string_type_t * result)261 bool bstrx_cbor_start_decode(cbor_state_t *state, cbor_string_type_t *result)
262 {
263 	if(!strx_start_decode(state, result, CBOR_MAJOR_TYPE_BSTR)) {
264 		FAIL();
265 	}
266 
267 	if (!new_backup(state, 0xFFFFFFFF)) {
268 		FAIL_RESTORE();
269 	}
270 
271 	/* Overflow is checked in strx_start_decode() */
272 	state->payload_end = result->value + result->len;
273 	return true;
274 }
275 
bstrx_cbor_end_decode(cbor_state_t * state)276 bool bstrx_cbor_end_decode(cbor_state_t *state)
277 {
278 	if (state->payload != state->payload_end) {
279 		FAIL();
280 	}
281 	if (!restore_backup(state,
282 			FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
283 			0xFFFFFFFF)) {
284 		FAIL();
285 	}
286 
287 	return true;
288 }
289 
290 
strx_decode(cbor_state_t * state,cbor_string_type_t * result,cbor_major_type_t exp_major_type)291 bool strx_decode(cbor_state_t *state, cbor_string_type_t *result,
292 		cbor_major_type_t exp_major_type)
293 {
294 	if (!strx_start_decode(state, result, exp_major_type)) {
295 		FAIL();
296 	}
297 
298 	/* Overflow is checked in strx_start_decode() */
299 	(state->payload) += result->len;
300 	return true;
301 }
302 
303 
strx_expect(cbor_state_t * state,cbor_string_type_t * result,cbor_major_type_t exp_major_type)304 bool strx_expect(cbor_state_t *state, cbor_string_type_t *result,
305 		cbor_major_type_t exp_major_type)
306 {
307 	cbor_string_type_t tmp_result;
308 
309 	if (!strx_decode(state, &tmp_result, exp_major_type)) {
310 		FAIL();
311 	}
312 	if ((tmp_result.len != result->len)
313 			|| memcmp(result->value, tmp_result.value, tmp_result.len)) {
314 		FAIL_RESTORE();
315 	}
316 	return true;
317 }
318 
319 
bstrx_decode(cbor_state_t * state,cbor_string_type_t * result)320 bool bstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
321 {
322 	return strx_decode(state, result, CBOR_MAJOR_TYPE_BSTR);
323 }
324 
325 
bstrx_expect(cbor_state_t * state,cbor_string_type_t * result)326 bool bstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
327 {
328 	return strx_expect(state, result, CBOR_MAJOR_TYPE_BSTR);
329 }
330 
331 
tstrx_decode(cbor_state_t * state,cbor_string_type_t * result)332 bool tstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
333 {
334 	return strx_decode(state, result, CBOR_MAJOR_TYPE_TSTR);
335 }
336 
337 
tstrx_expect(cbor_state_t * state,cbor_string_type_t * result)338 bool tstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
339 {
340 	return strx_expect(state, result, CBOR_MAJOR_TYPE_TSTR);
341 }
342 
343 
list_map_start_decode(cbor_state_t * state,cbor_major_type_t exp_major_type)344 static bool list_map_start_decode(cbor_state_t *state,
345 		cbor_major_type_t exp_major_type)
346 {
347 	FAIL_IF(state->payload >= state->payload_end);
348 	uint8_t major_type = MAJOR_TYPE(*state->payload);
349 	uint32_t new_elem_count;
350 
351 	if (major_type != exp_major_type) {
352 		FAIL();
353 	}
354 
355 	if (!uint32_decode(state, &new_elem_count)) {
356 		FAIL();
357 	}
358 
359 	if (!new_backup(state, new_elem_count)) {
360 		FAIL_RESTORE();
361 	}
362 
363 	return true;
364 }
365 
366 
list_start_decode(cbor_state_t * state)367 bool list_start_decode(cbor_state_t *state)
368 {
369 	return list_map_start_decode(state, CBOR_MAJOR_TYPE_LIST);
370 }
371 
372 
map_start_decode(cbor_state_t * state)373 bool map_start_decode(cbor_state_t *state)
374 {
375 	bool ret = list_map_start_decode(state, CBOR_MAJOR_TYPE_MAP);
376 
377 	if (ret) {
378 		state->elem_count *= 2;
379 	}
380 	return ret;
381 }
382 
383 
list_map_end_decode(cbor_state_t * state)384 bool list_map_end_decode(cbor_state_t *state)
385 {
386 	if (!restore_backup(state,
387 			FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
388 			0)) {
389 		FAIL();
390 	}
391 
392 	return true;
393 }
394 
395 
list_end_decode(cbor_state_t * state)396 bool list_end_decode(cbor_state_t *state)
397 {
398 	return list_map_end_decode(state);
399 }
400 
401 
map_end_decode(cbor_state_t * state)402 bool map_end_decode(cbor_state_t *state)
403 {
404 	return list_map_end_decode(state);
405 }
406 
407 
primx_decode(cbor_state_t * state,uint32_t * result)408 static bool primx_decode(cbor_state_t *state, uint32_t *result)
409 {
410 	FAIL_IF(state->payload >= state->payload_end);
411 	uint8_t major_type = MAJOR_TYPE(*state->payload);
412 
413 	if (major_type != CBOR_MAJOR_TYPE_PRIM) {
414 		/* Value to be read doesn't have the right type. */
415 		FAIL();
416 	}
417 	if (!uint32_decode(state, result)) {
418 		FAIL();
419 	}
420 	if (*result > 0xFF) {
421 		FAIL_RESTORE();
422 	}
423 	return true;
424 }
425 
primx_expect(cbor_state_t * state,uint32_t result)426 static bool primx_expect(cbor_state_t *state, uint32_t result)
427 {
428 	uint32_t value;
429 
430 	if (!primx_decode(state, &value)) {
431 		FAIL();
432 	}
433 	if (value != result) {
434 		FAIL_RESTORE();
435 	}
436 	return true;
437 }
438 
439 
nilx_expect(cbor_state_t * state,void * result)440 bool nilx_expect(cbor_state_t *state, void *result)
441 {
442 	if (!primx_expect(state, 22)) {
443 		FAIL();
444 	}
445 	return true;
446 }
447 
448 
boolx_decode(cbor_state_t * state,bool * result)449 bool boolx_decode(cbor_state_t *state, bool *result)
450 {
451 	uint32_t tmp_result;
452 
453 	if (!primx_decode(state, &tmp_result)) {
454 		FAIL();
455 	}
456 	(*result) = tmp_result - BOOL_TO_PRIM;
457 
458 	cbor_print("boolval: %u\r\n", *result);
459 	return true;
460 }
461 
462 
boolx_expect(cbor_state_t * state,bool result)463 bool boolx_expect(cbor_state_t *state, bool result)
464 {
465 	bool value;
466 
467 	if (!boolx_decode(state, &value)) {
468 		FAIL();
469 	}
470 	if (value != result) {
471 		FAIL_RESTORE();
472 	}
473 	return true;
474 }
475 
476 
double_decode(cbor_state_t * state,double * result)477 bool double_decode(cbor_state_t *state, double *result)
478 {
479 	FAIL_IF(state->payload >= state->payload_end);
480 	uint8_t major_type = MAJOR_TYPE(*state->payload);
481 
482 	if (major_type != CBOR_MAJOR_TYPE_PRIM) {
483 		/* Value to be read doesn't have the right type. */
484 		FAIL();
485 	}
486 	if (!value_extract(state, result,
487 			sizeof(*result))) {
488 		FAIL();
489 	}
490 	return true;
491 }
492 
493 
double_expect(cbor_state_t * state,double * result)494 bool double_expect(cbor_state_t *state, double *result)
495 {
496 	double value;
497 
498 	if (!double_decode(state, &value)) {
499 		FAIL();
500 	}
501 	if (value != *result) {
502 		FAIL_RESTORE();
503 	}
504 	return true;
505 }
506 
507 
any_decode(cbor_state_t * state,void * result)508 bool any_decode(cbor_state_t *state, void *result)
509 {
510 	cbor_assert(result == NULL,
511 			"'any' type cannot be returned, only skipped.\n");
512 
513 	FAIL_IF(state->payload >= state->payload_end);
514 	uint8_t major_type = MAJOR_TYPE(*state->payload);
515 	uint32_t value;
516 	uint32_t num_decode;
517 	void *null_result = NULL;
518 	uint32_t temp_elem_count;
519 	uint8_t const *payload_bak;
520 
521 	if (!value_extract(state, &value, sizeof(value))) {
522 		/* Can happen because of elem_count (or payload_end) */
523 		FAIL();
524 	}
525 
526 	switch (major_type) {
527 		case CBOR_MAJOR_TYPE_BSTR:
528 		case CBOR_MAJOR_TYPE_TSTR:
529 			(state->payload) += value;
530 			break;
531 		case CBOR_MAJOR_TYPE_MAP:
532 			value *= 2; /* Because all members have a key. */
533 			/* Fallthrough */
534 		case CBOR_MAJOR_TYPE_LIST:
535 			temp_elem_count = state->elem_count;
536 			payload_bak = state->payload;
537 			state->elem_count = value;
538 			if (!multi_decode(value, value, &num_decode,
539 					(void *)any_decode, state,
540 					&null_result, 0)) {
541 				state->elem_count = temp_elem_count;
542 				state->payload = payload_bak;
543 				FAIL();
544 			}
545 			state->elem_count = temp_elem_count;
546 			break;
547 		default:
548 			/* Do nothing */
549 			break;
550 	}
551 
552 	return true;
553 }
554 
555 
tag_decode(cbor_state_t * state,uint32_t * result)556 bool tag_decode(cbor_state_t *state, uint32_t *result)
557 {
558 	FAIL_IF(state->payload >= state->payload_end);
559 	uint8_t major_type = MAJOR_TYPE(*state->payload);
560 
561 	if (major_type != CBOR_MAJOR_TYPE_TAG) {
562 		/* Value to be read doesn't have the right type. */
563 		FAIL();
564 	}
565 	if (!uint32_decode(state, result)) {
566 		FAIL();
567 	}
568 	state->elem_count++;
569 	return true;
570 }
571 
572 
tag_expect(cbor_state_t * state,uint32_t result)573 bool tag_expect(cbor_state_t *state, uint32_t result)
574 {
575 	uint32_t tag_val;
576 
577 	if (!tag_decode(state, &tag_val)) {
578 		FAIL();
579 	}
580 	if (tag_val != result) {
581 		FAIL_RESTORE();
582 	}
583 	return true;
584 }
585 
586 
multi_decode(uint32_t min_decode,uint32_t max_decode,uint32_t * num_decode,cbor_decoder_t decoder,cbor_state_t * state,void * result,uint32_t result_len)587 bool multi_decode(uint32_t min_decode,
588 		uint32_t max_decode,
589 		uint32_t *num_decode,
590 		cbor_decoder_t decoder,
591 		cbor_state_t *state,
592 		void *result,
593 		uint32_t result_len)
594 {
595 	for (uint32_t i = 0; i < max_decode; i++) {
596 		uint8_t const *payload_bak = state->payload;
597 		uint32_t elem_count_bak = state->elem_count;
598 
599 		if (!decoder(state,
600 				(uint8_t *)result + i*result_len)) {
601 			*num_decode = i;
602 			state->payload = payload_bak;
603 			state->elem_count = elem_count_bak;
604 			if (i < min_decode) {
605 				FAIL();
606 			} else {
607 				cbor_print("Found %zu elements.\n", i);
608 			}
609 			return true;
610 		}
611 	}
612 	cbor_print("Found %zu elements.\n", max_decode);
613 	*num_decode = max_decode;
614 	return true;
615 }
616 
617 
present_decode(uint32_t * present,cbor_decoder_t decoder,cbor_state_t * state,void * result)618 bool present_decode(uint32_t *present,
619 		cbor_decoder_t decoder,
620 		cbor_state_t *state,
621 		void *result)
622 {
623 	uint32_t num_decode;
624 	bool retval = multi_decode(0, 1, &num_decode, decoder, state, result, 0);
625 	if (retval) {
626 		*present = num_decode;
627 	}
628 	return retval;
629 }
630