coap_numbers/
oscore_flag.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//! Constants for OSCORE flag bits
//!
//! Flags and fields are expressed as bit masks over their serialized memory area. This means that
//! flags in the 0..7 are expressed as u8 masks. Later bits are expressed in the smallest integer
//! they can be expressed in; applications are expected to parse the extended bytes into an integer
//! large enough to match their needs, and can cast up the flag bits easily. Note that due to the
//! arrangement of bytes in the OSCORE option and the numbering of the bits, this requires treating
//! the bytes as a little-endian representation of the full (numeric) bit set.
//!
//! No helper functions are given because it's unlikely that any application can make sense of the
//! flags by looking at the registered flag bits but not know their meaning (as every flag is
//! essentially mandatory to understand).

/// Shift for a little-endian number (where flags can be easily cast around) for a bit position.
///
/// See [test_bitshift_pos] for illustration
const fn bitpos_shift(bitpos: u8) -> u8 {
    let bit = bitpos & 0x7;
    let byte = bitpos >> 3;
    byte * 8 + (7 - bit)
}

pub const EXTENSION_1: u8 = 1 << bitpos_shift(0);
pub const GROUP: u8 = 1 << bitpos_shift(2);
pub const KID_CONTEXT_FLAG: u8 = 1 << bitpos_shift(3);
pub const KID_FLAG: u8 = 1 << bitpos_shift(4);
pub const PARTIAL_IV: u8 = 0x07;

pub const EXTENSION_2: u16 = 1 << bitpos_shift(8);
pub const NONCE: u16 = 1 << bitpos_shift(15);

#[test]
fn test_bitshift_pos() {
    assert_eq!(1 << bitpos_shift(0), 0x80);
    assert_eq!(1 << bitpos_shift(7), 1);
    assert_eq!(1 << bitpos_shift(8), 0x8000);
    assert_eq!(1 << bitpos_shift(15), 0x100);
}

#[test]
fn test_values() {
    assert_eq!(EXTENSION_1, 0x80);
    assert_eq!(EXTENSION_2, 0x8000);
    assert_eq!(NONCE, 0x100);
}