xref: /aosp_15_r20/external/open-dice/dpe-rs/src/args.rs (revision 60b67249c2e226f42f35cc6cfe66c6048e0bae6b)
1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 //! Types related to command arguments.
16 
17 use crate::error::{DpeResult, ErrCode};
18 use crate::memory::SizedMessage;
19 use heapless::FnvIndexMap;
20 use log::error;
21 
22 /// Represents the numeric identifier of a command or response argument.
23 pub type ArgId = u32;
24 
25 /// Represents the type of a command or response argument.
26 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
27 pub enum ArgTypeSelector {
28     /// Indicates an argument was not recognized, so its type is unknown.
29     #[default]
30     Unknown,
31     /// Indicates an argument is encoded as a CBOR byte string.
32     Bytes,
33     /// Indicates an argument is encoded as a CBOR unsigned integer.
34     Int,
35     /// Indicates an argument is encoded as a CBOR true or false simple value.
36     Bool,
37     /// Indicates an argument needs additional custom decoding.
38     Other,
39 }
40 
41 /// Represents a command or response argument value.
42 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
43 pub enum ArgValue<'a> {
44     /// This instantiation borrows a slice of a message buffer that was decoded
45     /// as a CBOR byte string. The slice needs to live at least as long as
46     /// this.
47     BytesArg(&'a [u8]),
48     /// This instantiation contains a decoded CBOR unsigned integer.
49     IntArg(u64),
50     /// This instantiation contains a decoded CBOR boolean value.
51     BoolArg(bool),
52 }
53 
54 impl<'a> ArgValue<'a> {
55     /// Creates a new `BytesArg` from a slice, borrowing the slice.
from_slice(value: &'a [u8]) -> Self56     pub fn from_slice(value: &'a [u8]) -> Self {
57         ArgValue::BytesArg(value)
58     }
59 
60     /// Returns the borrowed slice if this is a BytesArg.
61     ///
62     /// # Errors
63     ///
64     /// Returns an InternalError error if this is not a BytesArg.
try_into_slice(&self) -> DpeResult<&'a [u8]>65     pub fn try_into_slice(&self) -> DpeResult<&'a [u8]> {
66         match self {
67             ArgValue::IntArg(_) | ArgValue::BoolArg(_) => {
68                 error!("ArgValue::try_info_slice called on {:?}", self);
69                 Err(ErrCode::InternalError)
70             }
71             ArgValue::BytesArg(value) => Ok(value),
72         }
73     }
74 
75     /// Returns the value held by an IntArg as a u32.
76     ///
77     /// # Errors
78     ///
79     /// Returns an InternalError error if this is not an IntArg.
try_into_u32(&self) -> DpeResult<u32>80     pub fn try_into_u32(&self) -> DpeResult<u32> {
81         match self {
82             ArgValue::IntArg(i) => Ok((*i).try_into()?),
83             _ => {
84                 error!("ArgValue::try_into_u32 called on {:?}", self);
85                 Err(ErrCode::InternalError)
86             }
87         }
88     }
89 
90     /// Creates a new `IntArg` holding the given u32 `value`.
from_u32(value: u32) -> Self91     pub fn from_u32(value: u32) -> Self {
92         ArgValue::IntArg(value as u64)
93     }
94 
95     /// Returns the value held by an IntArg as a u64.
96     ///
97     /// # Errors
98     ///
99     /// Returns an InternalError error if this is not an IntArg.
try_into_u64(&self) -> DpeResult<u64>100     pub fn try_into_u64(&self) -> DpeResult<u64> {
101         match self {
102             ArgValue::IntArg(i) => Ok(*i),
103             _ => {
104                 error!("ArgValue::try_into_u64 called on {:?}", self);
105                 Err(ErrCode::InternalError)
106             }
107         }
108     }
109 
110     /// Creates a new `IntArg` holding the given u64 `value`.
from_u64(value: u64) -> Self111     pub fn from_u64(value: u64) -> Self {
112         ArgValue::IntArg(value)
113     }
114 
115     /// Returns the value held by a BoolArg.
116     ///
117     /// # Errors
118     ///
119     /// Returns an InternalError error if this is not a BoolArg.
try_into_bool(&self) -> DpeResult<bool>120     pub fn try_into_bool(&self) -> DpeResult<bool> {
121         match self {
122             ArgValue::BoolArg(b) => Ok(*b),
123             _ => {
124                 error!("ArgValue::try_into_bool called on {:?}", self);
125                 Err(ErrCode::InternalError)
126             }
127         }
128     }
129 
130     /// Creates a new `BoolArg` holding the given `value`.
from_bool(value: bool) -> Self131     pub fn from_bool(value: bool) -> Self {
132         ArgValue::BoolArg(value)
133     }
134 }
135 
136 impl<'a, const S: usize> From<&'a SizedMessage<S>> for ArgValue<'a> {
from(message: &'a SizedMessage<S>) -> Self137     fn from(message: &'a SizedMessage<S>) -> Self {
138         Self::BytesArg(message.as_slice())
139     }
140 }
141 
142 /// Contains a set of command or response arguments in the form of a map from
143 /// [`ArgId`] to [`ArgValue`].
144 pub type ArgMap<'a> = FnvIndexMap<ArgId, ArgValue<'a>, 16>;
145 
146 /// Contains a set of argument types in the form of a map from ArgId to
147 /// [`ArgTypeSelector`].
148 pub type ArgTypeMap = FnvIndexMap<ArgId, ArgTypeSelector, 16>;
149