ot_certs/
cbor.rs

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
5use serde::{Deserialize, Serialize};
6
7// For CBOR specification, it's defined in Concise Binary Object Representation (CBOR)
8// (https://datatracker.ietf.org/doc/html/rfc8949).
9
10// Section 3.1 Major Types
11#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
12#[repr(u8)]
13enum MajorType {
14    Uint = 0,
15    Sint = 1,
16    Bstr = 2,
17    Tstr = 3,
18    Array = 4,
19    Map = 5,
20}
21
22// Section 3 Specification of the CBOR Encoding
23// The value of additionial information, describing the type of the argument.
24#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
25#[repr(u8)]
26enum ArgType {
27    U8 = 24,
28    U16 = 25,
29    U32 = 26,
30    U64 = 27,
31}
32
33/// Given a CBOR argument, it returns:
34///   1. how many additional bytes to encode them
35///   2. the value to be filled in the header's additional information
36pub fn arg_size(arg: u64) -> (u64, u8) {
37    if arg <= ArgType::U8 as u64 {
38        (0, arg as u8)
39    } else if arg <= u8::MAX.into() {
40        (1, ArgType::U8 as u8)
41    } else if arg <= u16::MAX.into() {
42        (2, ArgType::U16 as u8)
43    } else if arg <= u32::MAX.into() {
44        (4, ArgType::U32 as u8)
45    } else {
46        (8, ArgType::U64 as u8)
47    }
48}
49
50// The first few bytes of each data item,
51// consisting of major type, additional information and argument.
52fn header(kind: MajorType, arg: u64) -> Vec<u8> {
53    let (size, info) = arg_size(arg);
54    // big-endian
55    let bytes = (0..size).map(|i| ((arg >> (i * 8)) & 0xff) as u8).rev();
56    let mut res = vec![((kind as u8) << 5) | info];
57    res.extend(bytes);
58    res
59}
60
61pub fn int(value: i64) -> Vec<u8> {
62    if value >= 0 {
63        header(MajorType::Uint, value as u64)
64    } else {
65        header(MajorType::Sint, -(value + 1) as u64)
66    }
67}
68
69pub fn byte_array_header(len: u64) -> Vec<u8> {
70    header(MajorType::Bstr, len)
71}
72
73pub fn string_header(len: u64) -> Vec<u8> {
74    header(MajorType::Tstr, len)
75}
76
77pub fn array_header(len: u64) -> Vec<u8> {
78    header(MajorType::Array, len)
79}
80
81pub fn map_header(len: u64) -> Vec<u8> {
82    header(MajorType::Map, len)
83}