tpm2_protocol/basic/
integer.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2025 Opinsys Oy
3// Copyright (c) 2024-2025 Jarkko Sakkinen
4
5use crate::{TpmMarshal, TpmResult, TpmSized, TpmUnmarshal, TpmWriter};
6use core::{convert::TryFrom, fmt, mem::size_of};
7
8macro_rules! define_integer {
9    ($name:ident, $raw:ty, $bytes:expr) => {
10        #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11        #[repr(transparent)]
12        pub struct $name(pub $raw);
13
14        impl $name {
15            #[must_use]
16            pub const fn new(value: $raw) -> Self {
17                Self(value)
18            }
19
20            #[must_use]
21            pub const fn value(self) -> $raw {
22                self.0
23            }
24
25            #[must_use]
26            pub fn to_be_bytes(self) -> [u8; $bytes] {
27                self.0.to_be_bytes()
28            }
29
30            #[must_use]
31            pub fn from_be_bytes(bytes: [u8; $bytes]) -> Self {
32                Self(<$raw>::from_be_bytes(bytes))
33            }
34        }
35
36        impl From<$raw> for $name {
37            fn from(value: $raw) -> Self {
38                Self(value)
39            }
40        }
41
42        impl From<$name> for $raw {
43            fn from(value: $name) -> $raw {
44                value.0
45            }
46        }
47
48        impl fmt::Display for $name {
49            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50                fmt::Display::fmt(&self.0, f)
51            }
52        }
53
54        impl fmt::LowerHex for $name {
55            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56                fmt::LowerHex::fmt(&self.0, f)
57            }
58        }
59
60        impl fmt::UpperHex for $name {
61            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62                fmt::UpperHex::fmt(&self.0, f)
63            }
64        }
65
66        impl TpmSized for $name {
67            const SIZE: usize = size_of::<$raw>();
68            fn len(&self) -> usize {
69                Self::SIZE
70            }
71        }
72
73        impl TpmMarshal for $name {
74            fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
75                writer.write_bytes(&self.to_be_bytes())
76            }
77        }
78
79        impl TpmUnmarshal for $name {
80            fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
81                let size = size_of::<$raw>();
82                let bytes = buf
83                    .get(..size)
84                    .ok_or(crate::TpmProtocolError::UnexpectedEnd)?;
85                let array = bytes
86                    .try_into()
87                    .map_err(|_| crate::TpmProtocolError::UnexpectedEnd)?;
88                let val = Self::from_be_bytes(array);
89                Ok((val, &buf[size..]))
90            }
91        }
92
93        impl TryFrom<usize> for $name
94        where
95            $raw: TryFrom<usize>,
96        {
97            type Error = <$raw as TryFrom<usize>>::Error;
98            fn try_from(value: usize) -> Result<Self, Self::Error> {
99                <$raw>::try_from(value).map(Self)
100            }
101        }
102    };
103}
104
105define_integer!(Uint8, u8, 1);
106define_integer!(Int8, i8, 1);
107define_integer!(Uint16, u16, 2);
108define_integer!(Uint32, u32, 4);
109define_integer!(Uint64, u64, 8);
110define_integer!(Int32, i32, 4);
111
112/// Associates primitive integer types with their TPM wrapper counterparts.
113pub trait IntegerRepr: Copy {
114    /// The wrapper type used for marshaling and unmarshaling.
115    type Wrapper: TpmSized + TpmMarshal + TpmUnmarshal + From<Self> + Into<Self>;
116}
117
118impl IntegerRepr for u8 {
119    type Wrapper = Uint8;
120}
121
122impl IntegerRepr for i8 {
123    type Wrapper = Int8;
124}
125
126impl IntegerRepr for u16 {
127    type Wrapper = Uint16;
128}
129
130impl IntegerRepr for u32 {
131    type Wrapper = Uint32;
132}
133
134impl IntegerRepr for u64 {
135    type Wrapper = Uint64;
136}
137
138impl IntegerRepr for i32 {
139    type Wrapper = Int32;
140}