Software APIs
cbor.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/cert/cbor.h"
6 
8 
9 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
10  "CBOR library assumes that the system is little endian.");
11 
12 typedef enum {
13  Cbor_Type_Uint = 0,
14  Cbor_Type_Sint = 1,
15  Cbor_Type_Bstr = 2,
16  Cbor_Type_Tstr = 3,
17  Cbor_Type_Array = 4,
18  Cbor_Type_Map = 5,
19 } cbor_type_t;
20 
21 typedef enum {
22  Cbor_Arg_Type_U8 = 24,
23  Cbor_Arg_Type_U16 = 25,
24  Cbor_Arg_Type_U32 = 26,
25  Cbor_Arg_Type_U64 = 27,
26 } cbor_arg_type_t;
27 
28 size_t cbor_calc_arg_size(const uint64_t value) {
29  if (value <= 23) {
30  return 0;
31  } else if (value <= 0xff) {
32  return 1;
33  } else if (value <= 0xffff) {
34  return 2;
35  } else if (value <= 0xffffffff) {
36  return 4;
37  } else {
38  return 8;
39  };
40 }
41 
42 static uint8_t cbor_calc_additional_info(const uint64_t value) {
43  if (value <= 23) {
44  return (uint8_t)value;
45  } else if (value <= 0xff) {
46  return Cbor_Arg_Type_U8;
47  } else if (value <= 0xffff) {
48  return Cbor_Arg_Type_U16;
49  } else if (value <= 0xffffffff) {
50  return Cbor_Arg_Type_U32;
51  } else {
52  return Cbor_Arg_Type_U64;
53  };
54 }
55 
56 size_t cbor_calc_int_size(const int64_t value) {
57  if (value < 0)
58  return cbor_calc_arg_size((uint64_t)(-(value + 1)));
59  else
60  return cbor_calc_arg_size((uint64_t)value);
61 }
62 
63 size_t cbor_write_raw_bytes(cbor_out_t *p, const uint8_t *raw,
64  const size_t raw_size) {
65  if (p) {
66  memcpy(p->start + p->offset, raw, raw_size);
67  p->offset += raw_size;
68  }
69 
70  return raw_size;
71 }
72 
73 static size_t cbor_write_type(cbor_out_t *p, cbor_type_t type,
74  const uint64_t arg) {
75  const size_t sz = cbor_calc_arg_size(arg);
76 
77  if (p) {
78  const uint8_t add_info = cbor_calc_additional_info(arg);
79  const uint8_t *parg = (uint8_t *)&arg + sz;
80 
81  p->start[p->offset++] = ((uint8_t)(type << 5) | add_info);
82  for (size_t i = 0; i < sz; ++i)
83  p->start[p->offset++] = *(--parg);
84  }
85 
86  return 1 + sz;
87 }
88 
89 size_t cbor_write_int(cbor_out_t *p, const int64_t value) {
90  if (value < 0)
91  return cbor_write_type(p, Cbor_Type_Sint, (uint64_t)(-(value + 1)));
92  else
93  return cbor_write_type(p, Cbor_Type_Uint, (uint64_t)value);
94 }
95 
96 size_t cbor_write_bstr_header(cbor_out_t *p, const size_t bstr_size) {
97  return cbor_write_type(p, Cbor_Type_Bstr, bstr_size);
98 }
99 
100 size_t cbor_write_tstr_header(cbor_out_t *p, const size_t tstr_size) {
101  return cbor_write_type(p, Cbor_Type_Tstr, tstr_size);
102 }
103 
104 size_t cbor_write_array_header(cbor_out_t *p, const size_t num_elements) {
105  return cbor_write_type(p, Cbor_Type_Array, num_elements);
106 }
107 
108 size_t cbor_write_map_header(cbor_out_t *p, const size_t num_pairs) {
109  return cbor_write_type(p, Cbor_Type_Map, num_pairs);
110 }