• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //! Wrapper around autogenerated ffi bindings.
17 
18 // Get the bindgen definitions
19 #[allow(non_upper_case_globals)]
20 #[allow(non_camel_case_types)]
21 #[allow(unused)]
22 #[allow(deref_nullptr)] // https://github.com/rust-lang/rust-bindgen/issues/1651
23 mod sys {
24     include!(env!("BINDGEN_INC_FILE"));
25 }
26 
27 use core::mem;
28 use kmr_common::try_to_vec;
29 use kmr_wire::legacy::InnerSerialize;
30 use log::{error, warn};
31 use tipc::{Deserialize, Handle, Serialize, Serializer, TipcError};
32 
33 /// Add entropy to Trusty's RNG.
trusty_rng_add_entropy(data: &[u8])34 pub fn trusty_rng_add_entropy(data: &[u8]) {
35     let rc = unsafe {
36         // Safety: `data` is a valid slice
37         sys::trusty_rng_add_entropy(data.as_ptr(), data.len())
38     };
39     if rc != 0 {
40         warn!("trusty_rng_add_entropy() failed, {}", rc)
41     }
42 }
43 
44 pub(crate) const KEYBOX_PORT: &[u8; 28] = sys::KEYBOX_PORT;
45 
46 type KeyboxReqHdr = sys::keybox_req;
47 type KeyboxUnwrapReqPayloadHdr = sys::keybox_unwrap_req;
48 
49 pub(crate) const KEYBOX_RESP_HDR_SIZE: usize =
50     mem::size_of::<sys::keybox_resp>() + mem::size_of::<sys::keybox_unwrap_resp>();
51 
52 const KEYBOX_RESP_MAX_SIZE: usize = KEYBOX_RESP_HDR_SIZE + (sys::KEYBOX_MAX_SIZE as usize);
53 
54 // Because KeyboxUnwrapResp deserialization doesn't use the ffi types, we add this check in case the
55 // c definitions change.
56 const _: () = assert!(
57     KEYBOX_RESP_HDR_SIZE == (mem::size_of::<u32>() + mem::size_of::<u32>() + mem::size_of::<u64>()),
58     "KEYBOX_RESP_HDR_SIZE do not match KeyboxUnwrapResp deserialization assumptions"
59 );
60 
61 // KeyboxUnwrapReq is a type created to be processed by Trusty IPC Rust serialization. This means
62 // that any data that needs to be serialized when implementing the `Serialize` trait needs to
63 // outlive its `serialize` function. A consequence of that is that the serialized values might need
64 // some memory backup space until they have been transmitted.
65 // We do not have this restriction on types we are deserializing (like `KeyboxUnwrapResp`); on which
66 // this implementation prefers to use a type that can be directly used by the Rust code. This ends
67 // up creating an asymmetry between requests and responses.
68 pub(crate) struct KeyboxUnwrapReq<'a> {
69     req_header: KeyboxReqHdr,
70     unwrap_req_header: KeyboxUnwrapReqPayloadHdr,
71     wrapped_keybox: &'a [u8],
72 }
73 
74 impl<'a> KeyboxUnwrapReq<'a> {
new(wrapped_keybox: &'a [u8]) -> Self75     pub(crate) fn new(wrapped_keybox: &'a [u8]) -> Self {
76         let req_header = KeyboxReqHdr { cmd: sys::keybox_cmd_KEYBOX_CMD_UNWRAP, reserved: 0 };
77         let unwrap_req_header =
78             KeyboxUnwrapReqPayloadHdr { wrapped_keybox_len: wrapped_keybox.len() as u64 };
79         KeyboxUnwrapReq { req_header, unwrap_req_header, wrapped_keybox }
80     }
81 }
82 
83 impl<'s> Serialize<'s> for KeyboxUnwrapReq<'s> {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>84     fn serialize<'a: 's, S: Serializer<'s>>(
85         &'a self,
86         serializer: &mut S,
87     ) -> Result<S::Ok, S::Error> {
88         // SAFETY:
89         //        - self.req_header.cmd and self.req_header.reserved are u32 and live long enough
90         //        - self.unwrap_req_header.wrapped_keybox_len is a u64 and live long enough
91         unsafe {
92             serializer.serialize_as_bytes(&self.req_header.cmd)?;
93             serializer.serialize_as_bytes(&self.req_header.reserved)?;
94             serializer.serialize_as_bytes(&self.unwrap_req_header.wrapped_keybox_len)?;
95         }
96         serializer.serialize_bytes(self.wrapped_keybox)
97     }
98 }
99 
100 pub(crate) struct KeyboxUnwrapResp {
101     unwrapped_keybox: Vec<u8>,
102 }
103 
104 impl KeyboxUnwrapResp {
get_unwrapped_keybox(self) -> Vec<u8>105     pub(crate) fn get_unwrapped_keybox(self) -> Vec<u8> {
106         self.unwrapped_keybox
107     }
108 }
109 
110 impl Deserialize for KeyboxUnwrapResp {
111     type Error = TipcError;
112     const MAX_SERIALIZED_SIZE: usize = KEYBOX_RESP_MAX_SIZE;
deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error>113     fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error> {
114         let (cmd, bytes) = <u32>::deserialize(bytes).map_err(|e| {
115             error!("received error when deserializing cmd: {:?}", e);
116             TipcError::UnknownError
117         })?;
118         if cmd != (sys::keybox_cmd_KEYBOX_CMD_UNWRAP | sys::keybox_cmd_KEYBOX_CMD_RSP_BIT) {
119             error!("Keybox unwrap deserialization received wrong cmd: {:?}", cmd);
120             return Err(TipcError::UnknownError);
121         }
122 
123         let (status, bytes) = <u32>::deserialize(bytes).map_err(|e| {
124             error!("received error when deserializing status: {:?}", e);
125             TipcError::UnknownError
126         })?;
127         if status != sys::keybox_status_KEYBOX_STATUS_SUCCESS {
128             error!(" Keybox unwrap cmd failed: {:?}", status);
129             return Err(TipcError::UnknownError);
130         }
131 
132         let (unwrapped_keybox_len, bytes) = <u64>::deserialize(bytes).map_err(|e| {
133             error!("received error when deserializing status: {:?}", e);
134             TipcError::UnknownError
135         })?;
136         if unwrapped_keybox_len as usize != bytes.len() {
137             error!(
138                 "unwrapped keybox had wrong size. Expected: {:?}, Received: {:?}",
139                 unwrapped_keybox_len,
140                 bytes.len()
141             );
142             return Err(TipcError::UnknownError);
143         }
144 
145         let unwrapped_keybox = try_to_vec(bytes).map_err(|e| {
146             error!("received error when trying to copy unwrapped keybox into vector: {:?}", e);
147             TipcError::AllocError
148         })?;
149 
150         Ok(Self { unwrapped_keybox })
151     }
152 }
153