xref: /aosp_15_r20/system/secretkeeper/comm/src/data_types/mod.rs (revision 3f8e9d82f4020c68ad19a99fc5fdc1fc90b79379)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Implements the data structures specified by SecretManagement.cddl in Secretkeeper HAL.
18 //!  Data structures specified by SecretManagement.cddl in Secretkeeper HAL.
19 //!  Note this library must stay in sync with:
20 //!      platform/hardware/interfaces/security/\
21 //!      secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
22 
23 pub mod error;
24 pub mod packet;
25 pub mod request;
26 pub mod request_response_impl;
27 pub mod response;
28 use crate::data_types::error::Error;
29 use alloc::vec::Vec;
30 use ciborium::Value;
31 use coset::{AsCborValue, CborSerializable, CoseError};
32 use zeroize::ZeroizeOnDrop;
33 use CoseError::UnexpectedItem;
34 
35 /// Size of the `id` bstr in SecretManagement.cddl
36 pub const ID_SIZE: usize = 64;
37 /// Size of the `secret` bstr in SecretManagement.cddl
38 pub const SECRET_SIZE: usize = 32;
39 
40 /// Identifier of Secret. See `id` in SecretManagement.cddl
41 #[derive(Clone, Eq, PartialEq)]
42 pub struct Id(pub [u8; ID_SIZE]);
43 
44 impl AsCborValue for Id {
from_cbor_value(value: Value) -> Result<Self, CoseError>45     fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
46         Ok(Self(
47             value
48                 .into_bytes()
49                 .map_err(|_| UnexpectedItem("-", "Bytes"))?
50                 .try_into()
51                 .map_err(|_| UnexpectedItem("Bytes", "64 Bytes"))?,
52         ))
53     }
54 
to_cbor_value(self) -> Result<Value, CoseError>55     fn to_cbor_value(self) -> Result<Value, CoseError> {
56         Ok(Value::Bytes(self.0.to_vec()))
57     }
58 }
59 
60 impl CborSerializable for Id {}
61 
62 impl core::fmt::Debug for Id {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result63     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
64         // Output only first 8 bytes of Id, which is sufficient for debugging
65         write!(f, "{:02x?}", &self.0[..8])
66     }
67 }
68 
69 /// Secret - corresponds to `secret` in SecretManagement.cddl
70 #[derive(Clone, Eq, PartialEq, ZeroizeOnDrop)]
71 pub struct Secret(pub [u8; SECRET_SIZE]);
72 impl AsCborValue for Secret {
from_cbor_value(value: Value) -> Result<Self, CoseError>73     fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
74         Ok(Self(
75             value
76                 .into_bytes()
77                 .map_err(|_| UnexpectedItem("-", "Bytes"))?
78                 .try_into()
79                 .map_err(|_| UnexpectedItem("Bytes", "32 Bytes"))?,
80         ))
81     }
82 
to_cbor_value(self) -> Result<Value, CoseError>83     fn to_cbor_value(self) -> Result<Value, CoseError> {
84         Ok(Value::Bytes(self.0.to_vec()))
85     }
86 }
87 
88 impl CborSerializable for Secret {}
89 
90 impl core::fmt::Debug for Secret {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result91     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
92         write!(f, "Sensitive information omitted")
93     }
94 }
95 
96 /// Used to represent `RequestSeqNum` & `ResponseSeqNum` in SecretManagement.cddl
97 #[derive(Default)]
98 pub struct SeqNum(u64);
99 
100 impl SeqNum {
101     /// Construct a new SeqNum. All new instances start with 0
new() -> Self102     pub fn new() -> Self {
103         Self(0)
104     }
105 
106     /// Get the encoded SeqNum & increment the underlying integer by +1. This method uses
107     /// `u64::checked_add`, thereby preventing wrapping around of SeqNum.
get_then_increment(&mut self) -> Result<Vec<u8>, Error>108     pub fn get_then_increment(&mut self) -> Result<Vec<u8>, Error> {
109         let enc = Value::Integer(self.0.into()).to_vec().map_err(|_| Error::ConversionError)?;
110         self.0 = self.0.checked_add(1).ok_or(Error::SequenceNumberExhausted)?;
111         Ok(enc)
112     }
113 }
114