xref: /aosp_15_r20/system/keymint/wire/src/legacy.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker 
15*9860b763SAndroid Build Coastguard Worker //! Functionality for dealing with (a subset of) legacy C++ KeyMint internal messages.
16*9860b763SAndroid Build Coastguard Worker //!
17*9860b763SAndroid Build Coastguard Worker //! The inner messages are defined by the classes deriving from `KeymasterMessage` in
18*9860b763SAndroid Build Coastguard Worker //! `system/keymaster/include/keymaster/android_keymaster_messages.h`. Each of these classes derives
19*9860b763SAndroid Build Coastguard Worker //! from `Serializable` (in `system/keymaster/include/keymaster/serializable.h`) and implements
20*9860b763SAndroid Build Coastguard Worker //! `Serialize` and `Deserialize` methods that convert instances of the message into opaque
21*9860b763SAndroid Build Coastguard Worker //! sequences of bytes.
22*9860b763SAndroid Build Coastguard Worker //!
23*9860b763SAndroid Build Coastguard Worker //! However, these opaque sequences of bytes do not self-identify which particular message is
24*9860b763SAndroid Build Coastguard Worker //! involved.  Instead, there is device specific code to wrap the inner serialized data into some
25*9860b763SAndroid Build Coastguard Worker //! sort of envelope that identifies the message type.
26*9860b763SAndroid Build Coastguard Worker //!
27*9860b763SAndroid Build Coastguard Worker //! 1) For Trusty, this envelope is the `keymaster_message` struct from
28*9860b763SAndroid Build Coastguard Worker //!    `system/core/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h`; this struct holds
29*9860b763SAndroid Build Coastguard Worker //!    (and is serialized as):
30*9860b763SAndroid Build Coastguard Worker //!
31*9860b763SAndroid Build Coastguard Worker //!    - A u32 indicating which command is involved, together with two low bits to encode whether the
32*9860b763SAndroid Build Coastguard Worker //!      message is a response, and a stop bit.  The command code values are taken from
33*9860b763SAndroid Build Coastguard Worker //!      `keymaster_command` in
34*9860b763SAndroid Build Coastguard Worker //!      `system/core/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h`.
35*9860b763SAndroid Build Coastguard Worker //!    - The payload.
36*9860b763SAndroid Build Coastguard Worker //!
37*9860b763SAndroid Build Coastguard Worker //! 2) For Cuttlefish, this envelope is the `keymaster_message` struct from
38*9860b763SAndroid Build Coastguard Worker //!    `device/google/cuttlefish/common/libs/security/keymaster_channel.h`; this struct holds (and is
39*9860b763SAndroid Build Coastguard Worker //!    serialized as):
40*9860b763SAndroid Build Coastguard Worker //!
41*9860b763SAndroid Build Coastguard Worker //!    - A u32 indicating which command is involved, together with a bit indicating if the message is a
42*9860b763SAndroid Build Coastguard Worker //!      response.  The command code values are taken from `AndroidKeymasterCommand` in
43*9860b763SAndroid Build Coastguard Worker //!      `system/keymaster/include/keymaster/android_keymaster_messages.h`.
44*9860b763SAndroid Build Coastguard Worker //!    - A u32 indicating the size of the payload
45*9860b763SAndroid Build Coastguard Worker //!    - The payload.
46*9860b763SAndroid Build Coastguard Worker //!
47*9860b763SAndroid Build Coastguard Worker //! In addition to the common messages defined in `android_keymaster_messages.h`, Trusty includes
48*9860b763SAndroid Build Coastguard Worker //! additional messages defined in `app/keymaster/trusty_keymaster_messages.h`.
49*9860b763SAndroid Build Coastguard Worker //!
50*9860b763SAndroid Build Coastguard Worker //!
51*9860b763SAndroid Build Coastguard Worker //! Only a subset of legacy messages are of interest; specifically, messages that involve
52*9860b763SAndroid Build Coastguard Worker //! interactions with things *other* than the HAL service, such as:
53*9860b763SAndroid Build Coastguard Worker //! - The bootloader.
54*9860b763SAndroid Build Coastguard Worker //! - Other TAs (e.g. Gatekeeper, ConfirmationUI) running in the secure environment.
55*9860b763SAndroid Build Coastguard Worker //! - Provisioning tools.
56*9860b763SAndroid Build Coastguard Worker 
57*9860b763SAndroid Build Coastguard Worker use crate::{
58*9860b763SAndroid Build Coastguard Worker     keymint::{Algorithm, ErrorCode, VerifiedBootState},
59*9860b763SAndroid Build Coastguard Worker     try_from_n,
60*9860b763SAndroid Build Coastguard Worker };
61*9860b763SAndroid Build Coastguard Worker use alloc::vec::Vec;
62*9860b763SAndroid Build Coastguard Worker use enumn::N;
63*9860b763SAndroid Build Coastguard Worker use kmr_derive::LegacySerialize;
64*9860b763SAndroid Build Coastguard Worker use zeroize::ZeroizeOnDrop;
65*9860b763SAndroid Build Coastguard Worker 
66*9860b763SAndroid Build Coastguard Worker /// This bit is set in the `u32` command value for response messages.
67*9860b763SAndroid Build Coastguard Worker const TRUSTY_RESPONSE_BITMASK: u32 = 0x01;
68*9860b763SAndroid Build Coastguard Worker /// This bit is set in the `u32` command value for the final fragment of response messages; i.e. if
69*9860b763SAndroid Build Coastguard Worker /// this bit is clear on a response message, more data is expected.
70*9860b763SAndroid Build Coastguard Worker pub const TRUSTY_STOP_BITMASK: u32 = 0x02;
71*9860b763SAndroid Build Coastguard Worker /// The raw `u32` command value should be shifted right by this number of bits to get the command
72*9860b763SAndroid Build Coastguard Worker /// enum value.
73*9860b763SAndroid Build Coastguard Worker pub const TRUSTY_CMD_SHIFT: usize = 2;
74*9860b763SAndroid Build Coastguard Worker 
75*9860b763SAndroid Build Coastguard Worker /// Legacy serialized trusty messages have as a first element the desired command encoded on a `u32`
76*9860b763SAndroid Build Coastguard Worker pub const CMD_SIZE: usize = 4;
77*9860b763SAndroid Build Coastguard Worker /// After the command, non-secure port responses have an error code encoded on a `u32`
78*9860b763SAndroid Build Coastguard Worker pub const ERROR_CODE_SIZE: usize = 4;
79*9860b763SAndroid Build Coastguard Worker /// Non-secure channel response headers are comprised of a CMD and an Error code
80*9860b763SAndroid Build Coastguard Worker pub const LEGACY_NON_SEC_RSP_HEADER_SIZE: usize = CMD_SIZE + ERROR_CODE_SIZE;
81*9860b763SAndroid Build Coastguard Worker 
82*9860b763SAndroid Build Coastguard Worker /// Key{Mint,master} version identifier.
83*9860b763SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq, N)]
84*9860b763SAndroid Build Coastguard Worker #[repr(i32)]
85*9860b763SAndroid Build Coastguard Worker pub enum KmVersion {
86*9860b763SAndroid Build Coastguard Worker     Keymaster1 = 10,
87*9860b763SAndroid Build Coastguard Worker     Keymaster11 = 11,
88*9860b763SAndroid Build Coastguard Worker     Keymaster2 = 20,
89*9860b763SAndroid Build Coastguard Worker     Keymaster3 = 30,
90*9860b763SAndroid Build Coastguard Worker     Keymaster4 = 40,
91*9860b763SAndroid Build Coastguard Worker     Keymaster41 = 41,
92*9860b763SAndroid Build Coastguard Worker     KeyMint1 = 100,
93*9860b763SAndroid Build Coastguard Worker     KeyMint2 = 200,
94*9860b763SAndroid Build Coastguard Worker     KeyMint3 = 300,
95*9860b763SAndroid Build Coastguard Worker }
96*9860b763SAndroid Build Coastguard Worker try_from_n!(KmVersion);
97*9860b763SAndroid Build Coastguard Worker 
98*9860b763SAndroid Build Coastguard Worker impl KmVersion {
99*9860b763SAndroid Build Coastguard Worker     /// Indicate the message format version associated with a C++ KeyMint version.
message_version(&self) -> u32100*9860b763SAndroid Build Coastguard Worker     pub fn message_version(&self) -> u32 {
101*9860b763SAndroid Build Coastguard Worker         match self {
102*9860b763SAndroid Build Coastguard Worker             KmVersion::Keymaster1 => 1,
103*9860b763SAndroid Build Coastguard Worker             KmVersion::Keymaster11 => 2,
104*9860b763SAndroid Build Coastguard Worker             KmVersion::Keymaster2
105*9860b763SAndroid Build Coastguard Worker             | KmVersion::Keymaster3
106*9860b763SAndroid Build Coastguard Worker             | KmVersion::Keymaster4
107*9860b763SAndroid Build Coastguard Worker             | KmVersion::Keymaster41 => 3,
108*9860b763SAndroid Build Coastguard Worker             KmVersion::KeyMint1 | KmVersion::KeyMint2 | KmVersion::KeyMint3 => 4,
109*9860b763SAndroid Build Coastguard Worker         }
110*9860b763SAndroid Build Coastguard Worker     }
111*9860b763SAndroid Build Coastguard Worker }
112*9860b763SAndroid Build Coastguard Worker 
113*9860b763SAndroid Build Coastguard Worker /// Date marker used by the last version of the previous C++ code.
114*9860b763SAndroid Build Coastguard Worker pub const KM_DATE: u32 = 20201219;
115*9860b763SAndroid Build Coastguard Worker 
116*9860b763SAndroid Build Coastguard Worker /// Errors encountered when [de-]serializing legacy messages.
117*9860b763SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy)]
118*9860b763SAndroid Build Coastguard Worker pub enum Error {
119*9860b763SAndroid Build Coastguard Worker     DataTruncated,
120*9860b763SAndroid Build Coastguard Worker     ExcessData(usize),
121*9860b763SAndroid Build Coastguard Worker     AllocationFailed,
122*9860b763SAndroid Build Coastguard Worker     UnexpectedResponse,
123*9860b763SAndroid Build Coastguard Worker     UnknownCommand(u32),
124*9860b763SAndroid Build Coastguard Worker     InvalidEnumValue(u32),
125*9860b763SAndroid Build Coastguard Worker }
126*9860b763SAndroid Build Coastguard Worker 
127*9860b763SAndroid Build Coastguard Worker /// Identification of Trusty messages.
128*9860b763SAndroid Build Coastguard Worker pub trait TrustyMessageId {
129*9860b763SAndroid Build Coastguard Worker     type Code;
code(&self) -> Self::Code130*9860b763SAndroid Build Coastguard Worker     fn code(&self) -> Self::Code;
131*9860b763SAndroid Build Coastguard Worker }
132*9860b763SAndroid Build Coastguard Worker 
133*9860b763SAndroid Build Coastguard Worker /// Trait for deserialization of Trusty messages.
134*9860b763SAndroid Build Coastguard Worker trait TrustyDeserialize: TrustyMessageId + Sized {
from_code_and_data(cmd: u32, data: &[u8]) -> Result<Self, Error>135*9860b763SAndroid Build Coastguard Worker     fn from_code_and_data(cmd: u32, data: &[u8]) -> Result<Self, Error>;
136*9860b763SAndroid Build Coastguard Worker }
137*9860b763SAndroid Build Coastguard Worker 
deserialize_trusty_request_message<T: TrustyDeserialize>(data: &[u8]) -> Result<T, Error>138*9860b763SAndroid Build Coastguard Worker fn deserialize_trusty_request_message<T: TrustyDeserialize>(data: &[u8]) -> Result<T, Error> {
139*9860b763SAndroid Build Coastguard Worker     let (raw_cmd, data) = <u32>::deserialize(data)?;
140*9860b763SAndroid Build Coastguard Worker     let cmd = raw_cmd >> TRUSTY_CMD_SHIFT;
141*9860b763SAndroid Build Coastguard Worker     if (raw_cmd & TRUSTY_RESPONSE_BITMASK) == TRUSTY_RESPONSE_BITMASK {
142*9860b763SAndroid Build Coastguard Worker         return Err(Error::UnexpectedResponse);
143*9860b763SAndroid Build Coastguard Worker     }
144*9860b763SAndroid Build Coastguard Worker     let req = T::from_code_and_data(cmd, data)?;
145*9860b763SAndroid Build Coastguard Worker     Ok(req)
146*9860b763SAndroid Build Coastguard Worker }
147*9860b763SAndroid Build Coastguard Worker 
148*9860b763SAndroid Build Coastguard Worker /// Deserialize a legacy Trusty request message arriving on the non-secure port.
deserialize_trusty_req(data: &[u8]) -> Result<TrustyPerformOpReq, Error>149*9860b763SAndroid Build Coastguard Worker pub fn deserialize_trusty_req(data: &[u8]) -> Result<TrustyPerformOpReq, Error> {
150*9860b763SAndroid Build Coastguard Worker     deserialize_trusty_request_message(data)
151*9860b763SAndroid Build Coastguard Worker }
152*9860b763SAndroid Build Coastguard Worker 
153*9860b763SAndroid Build Coastguard Worker /// Deserialize a legacy Trusty request message arriving on the secure port.
deserialize_trusty_secure_req(data: &[u8]) -> Result<TrustyPerformSecureOpReq, Error>154*9860b763SAndroid Build Coastguard Worker pub fn deserialize_trusty_secure_req(data: &[u8]) -> Result<TrustyPerformSecureOpReq, Error> {
155*9860b763SAndroid Build Coastguard Worker     deserialize_trusty_request_message(data)
156*9860b763SAndroid Build Coastguard Worker }
157*9860b763SAndroid Build Coastguard Worker 
158*9860b763SAndroid Build Coastguard Worker /// Trait to allow serialization of Trusty messages.
159*9860b763SAndroid Build Coastguard Worker pub trait TrustySerialize: TrustyMessageId {
raw_code(&self) -> u32160*9860b763SAndroid Build Coastguard Worker     fn raw_code(&self) -> u32;
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>161*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>;
162*9860b763SAndroid Build Coastguard Worker }
163*9860b763SAndroid Build Coastguard Worker 
164*9860b763SAndroid Build Coastguard Worker /// The result of a legacy operation is either a response message or an error code associated with
165*9860b763SAndroid Build Coastguard Worker /// the original command.
166*9860b763SAndroid Build Coastguard Worker pub enum LegacyResult<T> {
167*9860b763SAndroid Build Coastguard Worker     Ok(T),
168*9860b763SAndroid Build Coastguard Worker     Err { cmd: u32, code: ErrorCode },
169*9860b763SAndroid Build Coastguard Worker }
170*9860b763SAndroid Build Coastguard Worker 
171*9860b763SAndroid Build Coastguard Worker impl<T: TrustySerialize> LegacyResult<T> {
172*9860b763SAndroid Build Coastguard Worker     /// Return the command code associated with the result.
cmd(&self) -> u32173*9860b763SAndroid Build Coastguard Worker     fn cmd(&self) -> u32 {
174*9860b763SAndroid Build Coastguard Worker         match self {
175*9860b763SAndroid Build Coastguard Worker             LegacyResult::Ok(rsp) => rsp.raw_code(),
176*9860b763SAndroid Build Coastguard Worker             LegacyResult::Err { cmd, code: _code } => *cmd,
177*9860b763SAndroid Build Coastguard Worker         }
178*9860b763SAndroid Build Coastguard Worker     }
179*9860b763SAndroid Build Coastguard Worker }
180*9860b763SAndroid Build Coastguard Worker 
181*9860b763SAndroid Build Coastguard Worker /// Serialize a Trusty response message in the form:
182*9860b763SAndroid Build Coastguard Worker /// - command code: 32-bit integer (native endian)
183*9860b763SAndroid Build Coastguard Worker /// - return code: 32-bit integer (native endian)
184*9860b763SAndroid Build Coastguard Worker /// - encoded response data (if return code is 0/Ok).
185*9860b763SAndroid Build Coastguard Worker ///
186*9860b763SAndroid Build Coastguard Worker /// Note that some legacy response messages (e.g. [`GetDeviceInfoResponse`],
187*9860b763SAndroid Build Coastguard Worker /// [`GetAuthTokenKeyResponse`]) do not use this encoding format.
serialize_trusty_response_message<T: TrustySerialize>( result: LegacyResult<T>, ) -> Result<Vec<u8>, Error>188*9860b763SAndroid Build Coastguard Worker fn serialize_trusty_response_message<T: TrustySerialize>(
189*9860b763SAndroid Build Coastguard Worker     result: LegacyResult<T>,
190*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<u8>, Error> {
191*9860b763SAndroid Build Coastguard Worker     let cmd = result.cmd();
192*9860b763SAndroid Build Coastguard Worker     // None of the supported response messages are large enough to require fragmentation, so always
193*9860b763SAndroid Build Coastguard Worker     // mark this as the final response.
194*9860b763SAndroid Build Coastguard Worker     let raw_cmd = cmd << TRUSTY_CMD_SHIFT | TRUSTY_RESPONSE_BITMASK | TRUSTY_STOP_BITMASK;
195*9860b763SAndroid Build Coastguard Worker     let mut buf = Vec::new();
196*9860b763SAndroid Build Coastguard Worker     buf.try_reserve(LEGACY_NON_SEC_RSP_HEADER_SIZE).map_err(|_e| Error::AllocationFailed)?;
197*9860b763SAndroid Build Coastguard Worker     buf.extend_from_slice(&raw_cmd.to_ne_bytes());
198*9860b763SAndroid Build Coastguard Worker 
199*9860b763SAndroid Build Coastguard Worker     match result {
200*9860b763SAndroid Build Coastguard Worker         LegacyResult::Ok(rsp) => {
201*9860b763SAndroid Build Coastguard Worker             buf.extend_from_slice(&(ErrorCode::Ok as u32).to_ne_bytes());
202*9860b763SAndroid Build Coastguard Worker             rsp.serialize_into(&mut buf)?;
203*9860b763SAndroid Build Coastguard Worker         }
204*9860b763SAndroid Build Coastguard Worker         LegacyResult::Err { cmd: _cmd, code } => {
205*9860b763SAndroid Build Coastguard Worker             buf.extend_from_slice(&(code as u32).to_ne_bytes());
206*9860b763SAndroid Build Coastguard Worker         }
207*9860b763SAndroid Build Coastguard Worker     }
208*9860b763SAndroid Build Coastguard Worker 
209*9860b763SAndroid Build Coastguard Worker     Ok(buf)
210*9860b763SAndroid Build Coastguard Worker }
211*9860b763SAndroid Build Coastguard Worker 
212*9860b763SAndroid Build Coastguard Worker /// Serialize a legacy Trusty response message for the non-secure port.
serialize_trusty_rsp(rsp: TrustyPerformOpRsp) -> Result<Vec<u8>, Error>213*9860b763SAndroid Build Coastguard Worker pub fn serialize_trusty_rsp(rsp: TrustyPerformOpRsp) -> Result<Vec<u8>, Error> {
214*9860b763SAndroid Build Coastguard Worker     serialize_trusty_response_message(LegacyResult::Ok(rsp))
215*9860b763SAndroid Build Coastguard Worker }
216*9860b763SAndroid Build Coastguard Worker 
217*9860b763SAndroid Build Coastguard Worker /// Serialize raw data as a Trusty response message without length prefix.
serialize_trusty_raw_rsp(cmd: u32, raw_data: &[u8]) -> Result<Vec<u8>, Error>218*9860b763SAndroid Build Coastguard Worker fn serialize_trusty_raw_rsp(cmd: u32, raw_data: &[u8]) -> Result<Vec<u8>, Error> {
219*9860b763SAndroid Build Coastguard Worker     let raw_cmd = cmd << TRUSTY_CMD_SHIFT | TRUSTY_RESPONSE_BITMASK | TRUSTY_STOP_BITMASK;
220*9860b763SAndroid Build Coastguard Worker     let mut buf = Vec::new();
221*9860b763SAndroid Build Coastguard Worker     buf.try_reserve(CMD_SIZE + raw_data.len()).map_err(|_e| Error::AllocationFailed)?;
222*9860b763SAndroid Build Coastguard Worker     buf.extend_from_slice(&raw_cmd.to_ne_bytes());
223*9860b763SAndroid Build Coastguard Worker     buf.extend_from_slice(raw_data);
224*9860b763SAndroid Build Coastguard Worker     Ok(buf)
225*9860b763SAndroid Build Coastguard Worker }
226*9860b763SAndroid Build Coastguard Worker 
227*9860b763SAndroid Build Coastguard Worker /// Serialize a legacy Trusty response message for the secure port.
serialize_trusty_secure_rsp(rsp: TrustyPerformSecureOpRsp) -> Result<Vec<u8>, Error>228*9860b763SAndroid Build Coastguard Worker pub fn serialize_trusty_secure_rsp(rsp: TrustyPerformSecureOpRsp) -> Result<Vec<u8>, Error> {
229*9860b763SAndroid Build Coastguard Worker     match &rsp {
230*9860b763SAndroid Build Coastguard Worker         TrustyPerformSecureOpRsp::GetAuthTokenKey(GetAuthTokenKeyResponse { key_material }) => {
231*9860b763SAndroid Build Coastguard Worker             // The `KM_GET_AUTH_TOKEN_KEY` response does not include the error code value.  (The
232*9860b763SAndroid Build Coastguard Worker             // recipient has to distinguish between OK and error responses by the size of the
233*9860b763SAndroid Build Coastguard Worker             // response message: 4+32 for OK, 4+4 for error).
234*9860b763SAndroid Build Coastguard Worker             serialize_trusty_raw_rsp(rsp.raw_code(), key_material)
235*9860b763SAndroid Build Coastguard Worker         }
236*9860b763SAndroid Build Coastguard Worker         TrustyPerformSecureOpRsp::GetDeviceInfo(GetDeviceInfoResponse { device_ids }) => {
237*9860b763SAndroid Build Coastguard Worker             // The `KM_GET_DEVICE_INFO` response does not include the error code value. (The
238*9860b763SAndroid Build Coastguard Worker             // recipient has to distinguish between OK and error response by attempting to parse
239*9860b763SAndroid Build Coastguard Worker             // the response data as a CBOR map, and if this fails assume that the response hold
240*9860b763SAndroid Build Coastguard Worker             // an error code instead).
241*9860b763SAndroid Build Coastguard Worker             // TODO: update this to include explicit error code information if/when the C++ code
242*9860b763SAndroid Build Coastguard Worker             // and library are updated.
243*9860b763SAndroid Build Coastguard Worker             serialize_trusty_raw_rsp(rsp.raw_code(), device_ids)
244*9860b763SAndroid Build Coastguard Worker         }
245*9860b763SAndroid Build Coastguard Worker         TrustyPerformSecureOpRsp::GetUdsCerts(GetUdsCertsResponse { uds_certs: _ }) => {
246*9860b763SAndroid Build Coastguard Worker             serialize_trusty_response_message(LegacyResult::Ok(rsp))
247*9860b763SAndroid Build Coastguard Worker         }
248*9860b763SAndroid Build Coastguard Worker         TrustyPerformSecureOpRsp::SetAttestationIds(_) => {
249*9860b763SAndroid Build Coastguard Worker             serialize_trusty_response_message(LegacyResult::Ok(rsp))
250*9860b763SAndroid Build Coastguard Worker         }
251*9860b763SAndroid Build Coastguard Worker     }
252*9860b763SAndroid Build Coastguard Worker }
253*9860b763SAndroid Build Coastguard Worker 
254*9860b763SAndroid Build Coastguard Worker /// Deserialize the header of a non-secure channel Trusty response message to know if the operation
255*9860b763SAndroid Build Coastguard Worker /// succeeded. The Result is the error code of the operation, which is roughly equivalent to the
256*9860b763SAndroid Build Coastguard Worker /// legacy keymaster error. Notice that if the keymint operation was successful the return error
257*9860b763SAndroid Build Coastguard Worker /// code will be `ErrorCode::Ok`.
deserialize_trusty_rsp_error_code(rsp: &[u8]) -> Result<ErrorCode, Error>258*9860b763SAndroid Build Coastguard Worker pub fn deserialize_trusty_rsp_error_code(rsp: &[u8]) -> Result<ErrorCode, Error> {
259*9860b763SAndroid Build Coastguard Worker     if rsp.len() < LEGACY_NON_SEC_RSP_HEADER_SIZE {
260*9860b763SAndroid Build Coastguard Worker         return Err(Error::DataTruncated);
261*9860b763SAndroid Build Coastguard Worker     }
262*9860b763SAndroid Build Coastguard Worker 
263*9860b763SAndroid Build Coastguard Worker     let (error_code, _) = u32::deserialize(&rsp[CMD_SIZE..LEGACY_NON_SEC_RSP_HEADER_SIZE])?;
264*9860b763SAndroid Build Coastguard Worker     ErrorCode::try_from(error_code as i32).map_err(|_e| Error::InvalidEnumValue(error_code))
265*9860b763SAndroid Build Coastguard Worker }
266*9860b763SAndroid Build Coastguard Worker 
267*9860b763SAndroid Build Coastguard Worker /// Serialize a legacy Trusty error response for the non-secure port.
serialize_trusty_error_rsp( op: TrustyKeymasterOperation, rc: ErrorCode, ) -> Result<Vec<u8>, Error>268*9860b763SAndroid Build Coastguard Worker pub fn serialize_trusty_error_rsp(
269*9860b763SAndroid Build Coastguard Worker     op: TrustyKeymasterOperation,
270*9860b763SAndroid Build Coastguard Worker     rc: ErrorCode,
271*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<u8>, Error> {
272*9860b763SAndroid Build Coastguard Worker     serialize_trusty_response_message(LegacyResult::<TrustyPerformOpRsp>::Err {
273*9860b763SAndroid Build Coastguard Worker         cmd: op as u32,
274*9860b763SAndroid Build Coastguard Worker         code: rc,
275*9860b763SAndroid Build Coastguard Worker     })
276*9860b763SAndroid Build Coastguard Worker }
277*9860b763SAndroid Build Coastguard Worker 
278*9860b763SAndroid Build Coastguard Worker /// Serialize a legacy Trusty error response for the secure port.
serialize_trusty_secure_error_rsp( op: TrustyKeymasterSecureOperation, rc: ErrorCode, ) -> Result<Vec<u8>, Error>279*9860b763SAndroid Build Coastguard Worker pub fn serialize_trusty_secure_error_rsp(
280*9860b763SAndroid Build Coastguard Worker     op: TrustyKeymasterSecureOperation,
281*9860b763SAndroid Build Coastguard Worker     rc: ErrorCode,
282*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<u8>, Error> {
283*9860b763SAndroid Build Coastguard Worker     serialize_trusty_response_message(LegacyResult::<TrustyPerformSecureOpRsp>::Err {
284*9860b763SAndroid Build Coastguard Worker         cmd: op as u32,
285*9860b763SAndroid Build Coastguard Worker         code: rc,
286*9860b763SAndroid Build Coastguard Worker     })
287*9860b763SAndroid Build Coastguard Worker }
288*9860b763SAndroid Build Coastguard Worker 
289*9860b763SAndroid Build Coastguard Worker /// Trait that serializes an inner message to/from the format used by the legacy C++ Keymaster code.
290*9860b763SAndroid Build Coastguard Worker pub trait InnerSerialize: Sized {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>291*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>;
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>292*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>;
293*9860b763SAndroid Build Coastguard Worker }
294*9860b763SAndroid Build Coastguard Worker 
295*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for u64 {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>296*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
297*9860b763SAndroid Build Coastguard Worker         if data.len() < 8 {
298*9860b763SAndroid Build Coastguard Worker             return Err(Error::DataTruncated);
299*9860b763SAndroid Build Coastguard Worker         }
300*9860b763SAndroid Build Coastguard Worker         let int_data: [u8; 8] = data[..8].try_into().map_err(|_e| Error::DataTruncated)?;
301*9860b763SAndroid Build Coastguard Worker         Ok((<u64>::from_ne_bytes(int_data), &data[8..]))
302*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>303*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
304*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(8).map_err(|_e| Error::AllocationFailed)?;
305*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&self.to_ne_bytes());
306*9860b763SAndroid Build Coastguard Worker         Ok(())
307*9860b763SAndroid Build Coastguard Worker     }
308*9860b763SAndroid Build Coastguard Worker }
309*9860b763SAndroid Build Coastguard Worker 
310*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for u32 {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>311*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
312*9860b763SAndroid Build Coastguard Worker         if data.len() < 4 {
313*9860b763SAndroid Build Coastguard Worker             return Err(Error::DataTruncated);
314*9860b763SAndroid Build Coastguard Worker         }
315*9860b763SAndroid Build Coastguard Worker         let int_data: [u8; 4] = data[..4].try_into().map_err(|_e| Error::DataTruncated)?;
316*9860b763SAndroid Build Coastguard Worker         Ok((<u32>::from_ne_bytes(int_data), &data[4..]))
317*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>318*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
319*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(4).map_err(|_e| Error::AllocationFailed)?;
320*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&self.to_ne_bytes());
321*9860b763SAndroid Build Coastguard Worker         Ok(())
322*9860b763SAndroid Build Coastguard Worker     }
323*9860b763SAndroid Build Coastguard Worker }
324*9860b763SAndroid Build Coastguard Worker 
325*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for u8 {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>326*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
327*9860b763SAndroid Build Coastguard Worker         if data.is_empty() {
328*9860b763SAndroid Build Coastguard Worker             return Err(Error::DataTruncated);
329*9860b763SAndroid Build Coastguard Worker         }
330*9860b763SAndroid Build Coastguard Worker         Ok((data[0], &data[1..]))
331*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>332*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
333*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(1).map_err(|_e| Error::AllocationFailed)?;
334*9860b763SAndroid Build Coastguard Worker         buf.push(*self);
335*9860b763SAndroid Build Coastguard Worker         Ok(())
336*9860b763SAndroid Build Coastguard Worker     }
337*9860b763SAndroid Build Coastguard Worker }
338*9860b763SAndroid Build Coastguard Worker 
339*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for bool {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>340*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
341*9860b763SAndroid Build Coastguard Worker         let (v, rest) = <u32>::deserialize(data)?;
342*9860b763SAndroid Build Coastguard Worker         Ok((v != 0, rest))
343*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>344*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
345*9860b763SAndroid Build Coastguard Worker         (*self as u32).serialize_into(buf)
346*9860b763SAndroid Build Coastguard Worker     }
347*9860b763SAndroid Build Coastguard Worker }
348*9860b763SAndroid Build Coastguard Worker 
349*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for Vec<u8> {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>350*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
351*9860b763SAndroid Build Coastguard Worker         let (len, rest) = <u32>::deserialize(data)?;
352*9860b763SAndroid Build Coastguard Worker         let len = len as usize;
353*9860b763SAndroid Build Coastguard Worker         if rest.len() < len {
354*9860b763SAndroid Build Coastguard Worker             return Err(Error::DataTruncated);
355*9860b763SAndroid Build Coastguard Worker         }
356*9860b763SAndroid Build Coastguard Worker         let mut buf = Vec::new();
357*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(len).map_err(|_e| Error::AllocationFailed)?;
358*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&rest[..len]);
359*9860b763SAndroid Build Coastguard Worker         Ok((buf, &rest[len..]))
360*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>361*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
362*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(4 + self.len()).map_err(|_e| Error::AllocationFailed)?;
363*9860b763SAndroid Build Coastguard Worker         let len = self.len() as u32;
364*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&len.to_ne_bytes());
365*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(self);
366*9860b763SAndroid Build Coastguard Worker         Ok(())
367*9860b763SAndroid Build Coastguard Worker     }
368*9860b763SAndroid Build Coastguard Worker }
369*9860b763SAndroid Build Coastguard Worker 
370*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for KmVersion {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>371*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
372*9860b763SAndroid Build Coastguard Worker         let (v, rest) = <u32>::deserialize(data)?;
373*9860b763SAndroid Build Coastguard Worker         Ok((Self::try_from(v as i32).map_err(|_e| Error::InvalidEnumValue(v))?, rest))
374*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>375*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
376*9860b763SAndroid Build Coastguard Worker         (*self as u32).serialize_into(buf)
377*9860b763SAndroid Build Coastguard Worker     }
378*9860b763SAndroid Build Coastguard Worker }
379*9860b763SAndroid Build Coastguard Worker 
380*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for Algorithm {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>381*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
382*9860b763SAndroid Build Coastguard Worker         let (v, rest) = <u32>::deserialize(data)?;
383*9860b763SAndroid Build Coastguard Worker         Ok((Self::try_from(v as i32).map_err(|_e| Error::InvalidEnumValue(v))?, rest))
384*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>385*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
386*9860b763SAndroid Build Coastguard Worker         (*self as u32).serialize_into(buf)
387*9860b763SAndroid Build Coastguard Worker     }
388*9860b763SAndroid Build Coastguard Worker }
389*9860b763SAndroid Build Coastguard Worker 
390*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for VerifiedBootState {
deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error>391*9860b763SAndroid Build Coastguard Worker     fn deserialize(data: &[u8]) -> Result<(Self, &[u8]), Error> {
392*9860b763SAndroid Build Coastguard Worker         let (v, rest) = <u32>::deserialize(data)?;
393*9860b763SAndroid Build Coastguard Worker         Ok((Self::try_from(v as i32).map_err(|_e| Error::InvalidEnumValue(v))?, rest))
394*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>395*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
396*9860b763SAndroid Build Coastguard Worker         (*self as u32).serialize_into(buf)
397*9860b763SAndroid Build Coastguard Worker     }
398*9860b763SAndroid Build Coastguard Worker }
399*9860b763SAndroid Build Coastguard Worker 
400*9860b763SAndroid Build Coastguard Worker // Legacy messages of interest from `android_keymaster_messages.h`.
401*9860b763SAndroid Build Coastguard Worker 
402*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
403*9860b763SAndroid Build Coastguard Worker pub struct GetVersionRequest {}
404*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
405*9860b763SAndroid Build Coastguard Worker pub struct GetVersionResponse {
406*9860b763SAndroid Build Coastguard Worker     pub major_ver: u8,
407*9860b763SAndroid Build Coastguard Worker     pub minor_ver: u8,
408*9860b763SAndroid Build Coastguard Worker     pub subminor_ver: u8,
409*9860b763SAndroid Build Coastguard Worker }
410*9860b763SAndroid Build Coastguard Worker 
411*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
412*9860b763SAndroid Build Coastguard Worker pub struct GetVersion2Request {
413*9860b763SAndroid Build Coastguard Worker     pub max_message_version: u32,
414*9860b763SAndroid Build Coastguard Worker }
415*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
416*9860b763SAndroid Build Coastguard Worker pub struct GetVersion2Response {
417*9860b763SAndroid Build Coastguard Worker     pub max_message_version: u32,
418*9860b763SAndroid Build Coastguard Worker     pub km_version: KmVersion,
419*9860b763SAndroid Build Coastguard Worker     pub km_date: u32,
420*9860b763SAndroid Build Coastguard Worker }
421*9860b763SAndroid Build Coastguard Worker 
422*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
423*9860b763SAndroid Build Coastguard Worker pub struct ConfigureBootPatchlevelRequest {
424*9860b763SAndroid Build Coastguard Worker     pub boot_patchlevel: u32, // YYYMMDD
425*9860b763SAndroid Build Coastguard Worker }
426*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
427*9860b763SAndroid Build Coastguard Worker pub struct ConfigureBootPatchlevelResponse {}
428*9860b763SAndroid Build Coastguard Worker 
429*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
430*9860b763SAndroid Build Coastguard Worker pub struct ConfigureVerifiedBootInfoRequest {
431*9860b763SAndroid Build Coastguard Worker     pub boot_state: Vec<u8>,
432*9860b763SAndroid Build Coastguard Worker     pub bootloader_state: Vec<u8>,
433*9860b763SAndroid Build Coastguard Worker     pub vbmeta_digest: Vec<u8>,
434*9860b763SAndroid Build Coastguard Worker }
435*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
436*9860b763SAndroid Build Coastguard Worker pub struct ConfigureVerifiedBootInfoResponse {}
437*9860b763SAndroid Build Coastguard Worker 
438*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
439*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationIdsRequest {
440*9860b763SAndroid Build Coastguard Worker     pub brand: Vec<u8>,
441*9860b763SAndroid Build Coastguard Worker     pub device: Vec<u8>,
442*9860b763SAndroid Build Coastguard Worker     pub product: Vec<u8>,
443*9860b763SAndroid Build Coastguard Worker     pub serial: Vec<u8>,
444*9860b763SAndroid Build Coastguard Worker     pub imei: Vec<u8>,
445*9860b763SAndroid Build Coastguard Worker     pub meid: Vec<u8>,
446*9860b763SAndroid Build Coastguard Worker     pub manufacturer: Vec<u8>,
447*9860b763SAndroid Build Coastguard Worker     pub model: Vec<u8>,
448*9860b763SAndroid Build Coastguard Worker }
449*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
450*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationIdsResponse {}
451*9860b763SAndroid Build Coastguard Worker 
452*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
453*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationIdsKM3Request {
454*9860b763SAndroid Build Coastguard Worker     pub base: SetAttestationIdsRequest,
455*9860b763SAndroid Build Coastguard Worker     pub second_imei: Vec<u8>,
456*9860b763SAndroid Build Coastguard Worker }
457*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
458*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationIdsKM3Response {}
459*9860b763SAndroid Build Coastguard Worker 
460*9860b763SAndroid Build Coastguard Worker // Legacy messages of interest from `trusty_keymaster_messages.h`.
461*9860b763SAndroid Build Coastguard Worker 
462*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
463*9860b763SAndroid Build Coastguard Worker pub struct GetAuthTokenKeyRequest {}
464*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
465*9860b763SAndroid Build Coastguard Worker pub struct GetAuthTokenKeyResponse {
466*9860b763SAndroid Build Coastguard Worker     pub key_material: Vec<u8>,
467*9860b763SAndroid Build Coastguard Worker }
468*9860b763SAndroid Build Coastguard Worker 
469*9860b763SAndroid Build Coastguard Worker /// The serialization of a `GET_AUTH_TOKEN_KEY` response does not include a length field before the
470*9860b763SAndroid Build Coastguard Worker /// contents of the key, so the auto-derive implementation can't be used. (This also means that
471*9860b763SAndroid Build Coastguard Worker /// `deserialize()` can't be implemented, because there is no length information available.)
472*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for GetAuthTokenKeyResponse {
deserialize(_data: &[u8]) -> Result<(Self, &[u8]), Error>473*9860b763SAndroid Build Coastguard Worker     fn deserialize(_data: &[u8]) -> Result<(Self, &[u8]), Error> {
474*9860b763SAndroid Build Coastguard Worker         Err(Error::UnexpectedResponse)
475*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>476*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
477*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(self.key_material.len()).map_err(|_e| Error::AllocationFailed)?;
478*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&self.key_material);
479*9860b763SAndroid Build Coastguard Worker         Ok(())
480*9860b763SAndroid Build Coastguard Worker     }
481*9860b763SAndroid Build Coastguard Worker }
482*9860b763SAndroid Build Coastguard Worker 
483*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
484*9860b763SAndroid Build Coastguard Worker pub struct GetDeviceInfoRequest {}
485*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
486*9860b763SAndroid Build Coastguard Worker pub struct GetDeviceInfoResponse {
487*9860b763SAndroid Build Coastguard Worker     // Device ID information encoded as a CBOR map.
488*9860b763SAndroid Build Coastguard Worker     pub device_ids: Vec<u8>,
489*9860b763SAndroid Build Coastguard Worker }
490*9860b763SAndroid Build Coastguard Worker 
491*9860b763SAndroid Build Coastguard Worker /// The serialization of a `GET_DEVICE_INFO` response does not include a length field before the
492*9860b763SAndroid Build Coastguard Worker /// contents, so the auto-derive implementation can't be used. (This also means that `deserialize()`
493*9860b763SAndroid Build Coastguard Worker /// can't be implemented, because there is no length information available.)
494*9860b763SAndroid Build Coastguard Worker impl InnerSerialize for GetDeviceInfoResponse {
deserialize(_data: &[u8]) -> Result<(Self, &[u8]), Error>495*9860b763SAndroid Build Coastguard Worker     fn deserialize(_data: &[u8]) -> Result<(Self, &[u8]), Error> {
496*9860b763SAndroid Build Coastguard Worker         Err(Error::UnexpectedResponse)
497*9860b763SAndroid Build Coastguard Worker     }
serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error>498*9860b763SAndroid Build Coastguard Worker     fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
499*9860b763SAndroid Build Coastguard Worker         buf.try_reserve(self.device_ids.len()).map_err(|_e| Error::AllocationFailed)?;
500*9860b763SAndroid Build Coastguard Worker         buf.extend_from_slice(&self.device_ids);
501*9860b763SAndroid Build Coastguard Worker         Ok(())
502*9860b763SAndroid Build Coastguard Worker     }
503*9860b763SAndroid Build Coastguard Worker }
504*9860b763SAndroid Build Coastguard Worker 
505*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
506*9860b763SAndroid Build Coastguard Worker pub struct GetUdsCertsRequest {}
507*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
508*9860b763SAndroid Build Coastguard Worker pub struct GetUdsCertsResponse {
509*9860b763SAndroid Build Coastguard Worker     pub uds_certs: Vec<u8>,
510*9860b763SAndroid Build Coastguard Worker }
511*9860b763SAndroid Build Coastguard Worker 
512*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
513*9860b763SAndroid Build Coastguard Worker pub struct SetBootParamsRequest {
514*9860b763SAndroid Build Coastguard Worker     pub os_version: u32,
515*9860b763SAndroid Build Coastguard Worker     pub os_patchlevel: u32, // YYYYMM
516*9860b763SAndroid Build Coastguard Worker     pub device_locked: bool,
517*9860b763SAndroid Build Coastguard Worker     pub verified_boot_state: VerifiedBootState,
518*9860b763SAndroid Build Coastguard Worker     pub verified_boot_key: Vec<u8>,
519*9860b763SAndroid Build Coastguard Worker     pub verified_boot_hash: Vec<u8>,
520*9860b763SAndroid Build Coastguard Worker }
521*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
522*9860b763SAndroid Build Coastguard Worker pub struct SetBootParamsResponse {}
523*9860b763SAndroid Build Coastguard Worker 
524*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
525*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationKeyRequest {
526*9860b763SAndroid Build Coastguard Worker     #[zeroize(skip)]
527*9860b763SAndroid Build Coastguard Worker     pub algorithm: Algorithm,
528*9860b763SAndroid Build Coastguard Worker     pub key_data: Vec<u8>,
529*9860b763SAndroid Build Coastguard Worker }
530*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
531*9860b763SAndroid Build Coastguard Worker pub struct SetAttestationKeyResponse {}
532*9860b763SAndroid Build Coastguard Worker 
533*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
534*9860b763SAndroid Build Coastguard Worker pub struct AppendAttestationCertChainRequest {
535*9860b763SAndroid Build Coastguard Worker     pub algorithm: Algorithm,
536*9860b763SAndroid Build Coastguard Worker     pub cert_data: Vec<u8>,
537*9860b763SAndroid Build Coastguard Worker }
538*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
539*9860b763SAndroid Build Coastguard Worker pub struct AppendAttestationCertChainResponse {}
540*9860b763SAndroid Build Coastguard Worker 
541*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
542*9860b763SAndroid Build Coastguard Worker pub struct ClearAttestationCertChainRequest {
543*9860b763SAndroid Build Coastguard Worker     pub algorithm: Algorithm,
544*9860b763SAndroid Build Coastguard Worker }
545*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
546*9860b763SAndroid Build Coastguard Worker pub struct ClearAttestationCertChainResponse {}
547*9860b763SAndroid Build Coastguard Worker 
548*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
549*9860b763SAndroid Build Coastguard Worker pub struct SetWrappedAttestationKeyRequest {
550*9860b763SAndroid Build Coastguard Worker     #[zeroize(skip)]
551*9860b763SAndroid Build Coastguard Worker     pub algorithm: Algorithm,
552*9860b763SAndroid Build Coastguard Worker     pub key_data: Vec<u8>,
553*9860b763SAndroid Build Coastguard Worker }
554*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
555*9860b763SAndroid Build Coastguard Worker pub struct SetWrappedAttestationKeyResponse {}
556*9860b763SAndroid Build Coastguard Worker 
557*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
558*9860b763SAndroid Build Coastguard Worker pub struct AppendUdsCertificateRequest {
559*9860b763SAndroid Build Coastguard Worker     pub cert_data: Vec<u8>,
560*9860b763SAndroid Build Coastguard Worker }
561*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
562*9860b763SAndroid Build Coastguard Worker pub struct AppendUdsCertificateResponse {}
563*9860b763SAndroid Build Coastguard Worker 
564*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, LegacySerialize, ZeroizeOnDrop)]
565*9860b763SAndroid Build Coastguard Worker pub struct ClearUdsCertificateRequest {}
566*9860b763SAndroid Build Coastguard Worker 
567*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, Debug, LegacySerialize)]
568*9860b763SAndroid Build Coastguard Worker pub struct ClearUdsCertificateResponse {}
569*9860b763SAndroid Build Coastguard Worker 
570*9860b763SAndroid Build Coastguard Worker macro_rules! declare_req_rsp_enums {
571*9860b763SAndroid Build Coastguard Worker     {
572*9860b763SAndroid Build Coastguard Worker         $cenum:ident => ($reqenum:ident, $rspenum:ident)
573*9860b763SAndroid Build Coastguard Worker         {
574*9860b763SAndroid Build Coastguard Worker             $( $cname:ident = $cvalue:expr => ($reqtyp:ty, $rsptyp:ty) , )*
575*9860b763SAndroid Build Coastguard Worker         }
576*9860b763SAndroid Build Coastguard Worker     } => {
577*9860b763SAndroid Build Coastguard Worker         #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, N)]
578*9860b763SAndroid Build Coastguard Worker         pub enum $cenum {
579*9860b763SAndroid Build Coastguard Worker             $( $cname = $cvalue, )*
580*9860b763SAndroid Build Coastguard Worker         }
581*9860b763SAndroid Build Coastguard Worker         pub enum $reqenum {
582*9860b763SAndroid Build Coastguard Worker             $( $cname($reqtyp), )*
583*9860b763SAndroid Build Coastguard Worker         }
584*9860b763SAndroid Build Coastguard Worker         pub enum $rspenum {
585*9860b763SAndroid Build Coastguard Worker             $( $cname($rsptyp), )*
586*9860b763SAndroid Build Coastguard Worker         }
587*9860b763SAndroid Build Coastguard Worker         impl TrustyMessageId for $reqenum {
588*9860b763SAndroid Build Coastguard Worker             type Code = $cenum;
589*9860b763SAndroid Build Coastguard Worker             fn code(&self) -> $cenum {
590*9860b763SAndroid Build Coastguard Worker                 match self {
591*9860b763SAndroid Build Coastguard Worker                     $( Self::$cname(_) => $cenum::$cname, )*
592*9860b763SAndroid Build Coastguard Worker                 }
593*9860b763SAndroid Build Coastguard Worker             }
594*9860b763SAndroid Build Coastguard Worker         }
595*9860b763SAndroid Build Coastguard Worker         impl TrustyDeserialize  for $reqenum {
596*9860b763SAndroid Build Coastguard Worker             fn from_code_and_data(cmd: u32, data: &[u8]) -> Result<Self, Error> {
597*9860b763SAndroid Build Coastguard Worker                 let (req, rest) = match cmd {
598*9860b763SAndroid Build Coastguard Worker                     $(
599*9860b763SAndroid Build Coastguard Worker                         $cvalue => {
600*9860b763SAndroid Build Coastguard Worker                             let (req, rest) = <$reqtyp>::deserialize(data)?;
601*9860b763SAndroid Build Coastguard Worker                             ($reqenum::$cname(req), rest)
602*9860b763SAndroid Build Coastguard Worker                         }
603*9860b763SAndroid Build Coastguard Worker                     )*
604*9860b763SAndroid Build Coastguard Worker                     _ => return Err(Error::UnknownCommand(cmd)),
605*9860b763SAndroid Build Coastguard Worker                 };
606*9860b763SAndroid Build Coastguard Worker                 if !rest.is_empty() {
607*9860b763SAndroid Build Coastguard Worker                     return Err(Error::ExcessData(rest.len()));
608*9860b763SAndroid Build Coastguard Worker                 }
609*9860b763SAndroid Build Coastguard Worker                 Ok(req)
610*9860b763SAndroid Build Coastguard Worker             }
611*9860b763SAndroid Build Coastguard Worker         }
612*9860b763SAndroid Build Coastguard Worker         impl TrustyMessageId for $rspenum {
613*9860b763SAndroid Build Coastguard Worker             type Code = $cenum;
614*9860b763SAndroid Build Coastguard Worker             fn code(&self) -> $cenum {
615*9860b763SAndroid Build Coastguard Worker                 match self {
616*9860b763SAndroid Build Coastguard Worker                     $( Self::$cname(_) => $cenum::$cname, )*
617*9860b763SAndroid Build Coastguard Worker                 }
618*9860b763SAndroid Build Coastguard Worker             }
619*9860b763SAndroid Build Coastguard Worker         }
620*9860b763SAndroid Build Coastguard Worker         impl TrustySerialize for $rspenum {
621*9860b763SAndroid Build Coastguard Worker             fn raw_code(&self) -> u32 {
622*9860b763SAndroid Build Coastguard Worker                 self.code() as u32
623*9860b763SAndroid Build Coastguard Worker             }
624*9860b763SAndroid Build Coastguard Worker             fn serialize_into(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
625*9860b763SAndroid Build Coastguard Worker                 match self {
626*9860b763SAndroid Build Coastguard Worker                     $( Self::$cname(rsp) => rsp.serialize_into(buf), )*
627*9860b763SAndroid Build Coastguard Worker                 }
628*9860b763SAndroid Build Coastguard Worker             }
629*9860b763SAndroid Build Coastguard Worker         }
630*9860b763SAndroid Build Coastguard Worker     };
631*9860b763SAndroid Build Coastguard Worker }
632*9860b763SAndroid Build Coastguard Worker 
633*9860b763SAndroid Build Coastguard Worker // Possible legacy Cuttlefish Keymaster operation requests, as:
634*9860b763SAndroid Build Coastguard Worker // - an enum value with an explicit numeric value
635*9860b763SAndroid Build Coastguard Worker // - a request enum which has an operation code associated to each variant
636*9860b763SAndroid Build Coastguard Worker // - a response enum which has the same operation code associated to each variant.
637*9860b763SAndroid Build Coastguard Worker //
638*9860b763SAndroid Build Coastguard Worker // Numerical values for discriminants match the values in
639*9860b763SAndroid Build Coastguard Worker // system/keymaster/include/keymaster/android_keymaster_messages.h
640*9860b763SAndroid Build Coastguard Worker declare_req_rsp_enums! { CuttlefishKeymasterOperation => (CuttlefishPerformOpReq, CuttlefishPerformOpRsp) {
641*9860b763SAndroid Build Coastguard Worker     ConfigureBootPatchlevel = 33 =>                      (ConfigureBootPatchlevelRequest, ConfigureBootPatchlevelResponse),
642*9860b763SAndroid Build Coastguard Worker     ConfigureVerifiedBootInfo = 34 =>                    (ConfigureVerifiedBootInfoRequest, ConfigureVerifiedBootInfoResponse),
643*9860b763SAndroid Build Coastguard Worker     SetAttestationIds = 38 =>                            (SetAttestationIdsRequest, SetAttestationIdsResponse),
644*9860b763SAndroid Build Coastguard Worker } }
645*9860b763SAndroid Build Coastguard Worker 
646*9860b763SAndroid Build Coastguard Worker // Possible legacy Trusty Keymaster operation requests for the non-secure port.
647*9860b763SAndroid Build Coastguard Worker //
648*9860b763SAndroid Build Coastguard Worker // Numerical values for discriminants match the values in
649*9860b763SAndroid Build Coastguard Worker // trusty/user/app/keymaster/ipc/keymaster_ipc.h.
650*9860b763SAndroid Build Coastguard Worker declare_req_rsp_enums! { TrustyKeymasterOperation => (TrustyPerformOpReq, TrustyPerformOpRsp) {
651*9860b763SAndroid Build Coastguard Worker     GetVersion = 7 =>                                (GetVersionRequest, GetVersionResponse),
652*9860b763SAndroid Build Coastguard Worker     GetVersion2 = 28 =>                              (GetVersion2Request, GetVersion2Response),
653*9860b763SAndroid Build Coastguard Worker     SetBootParams = 0x1000 =>                        (SetBootParamsRequest, SetBootParamsResponse),
654*9860b763SAndroid Build Coastguard Worker 
655*9860b763SAndroid Build Coastguard Worker     // Provisioning-related requests. Changes here should be reflected in `is_trusty_provisioning_{code,req}`.
656*9860b763SAndroid Build Coastguard Worker     SetAttestationKey = 0x2000 =>                    (SetAttestationKeyRequest, SetAttestationKeyResponse),
657*9860b763SAndroid Build Coastguard Worker     AppendAttestationCertChain = 0x3000 =>           (AppendAttestationCertChainRequest, AppendAttestationCertChainResponse),
658*9860b763SAndroid Build Coastguard Worker     ClearAttestationCertChain = 0xa000 =>            (ClearAttestationCertChainRequest, ClearAttestationCertChainResponse),
659*9860b763SAndroid Build Coastguard Worker     SetWrappedAttestationKey = 0xb000 =>             (SetWrappedAttestationKeyRequest, SetWrappedAttestationKeyResponse),
660*9860b763SAndroid Build Coastguard Worker     SetAttestationIds = 0xc000 =>                    (SetAttestationIdsRequest, SetAttestationIdsResponse),
661*9860b763SAndroid Build Coastguard Worker     SetAttestationIdsKM3 = 0xc001 =>                 (SetAttestationIdsKM3Request, SetAttestationIdsKM3Response),
662*9860b763SAndroid Build Coastguard Worker     ConfigureBootPatchlevel = 0xd0000 =>             (ConfigureBootPatchlevelRequest, ConfigureBootPatchlevelResponse),
663*9860b763SAndroid Build Coastguard Worker     AppendUdsCertificate = 0xe0000 =>                (AppendUdsCertificateRequest, AppendUdsCertificateResponse),
664*9860b763SAndroid Build Coastguard Worker     ClearUdsCertificate = 0xe0001 =>                 (ClearUdsCertificateRequest, ClearUdsCertificateResponse),
665*9860b763SAndroid Build Coastguard Worker } }
666*9860b763SAndroid Build Coastguard Worker 
667*9860b763SAndroid Build Coastguard Worker // Possible legacy Trusty Keymaster operation requests for the secure port.
668*9860b763SAndroid Build Coastguard Worker //
669*9860b763SAndroid Build Coastguard Worker // Numerical values for discriminants match the values in
670*9860b763SAndroid Build Coastguard Worker // trusty/user/base/interface/keymaster/include/interface/keymaster/keymaster.h
671*9860b763SAndroid Build Coastguard Worker declare_req_rsp_enums! { TrustyKeymasterSecureOperation  => (TrustyPerformSecureOpReq, TrustyPerformSecureOpRsp) {
672*9860b763SAndroid Build Coastguard Worker     GetAuthTokenKey = 0 =>                                  (GetAuthTokenKeyRequest, GetAuthTokenKeyResponse),
673*9860b763SAndroid Build Coastguard Worker     GetDeviceInfo = 1 =>                                    (GetDeviceInfoRequest, GetDeviceInfoResponse),
674*9860b763SAndroid Build Coastguard Worker     GetUdsCerts = 2 =>                                      (GetUdsCertsRequest, GetUdsCertsResponse),
675*9860b763SAndroid Build Coastguard Worker     SetAttestationIds = 0xc000 =>                           (SetAttestationIdsRequest, SetAttestationIdsResponse),
676*9860b763SAndroid Build Coastguard Worker } }
677*9860b763SAndroid Build Coastguard Worker 
678*9860b763SAndroid Build Coastguard Worker /// Indicate whether a request message is a bootloader message.
is_trusty_bootloader_code(code: u32) -> bool679*9860b763SAndroid Build Coastguard Worker pub fn is_trusty_bootloader_code(code: u32) -> bool {
680*9860b763SAndroid Build Coastguard Worker     matches!(
681*9860b763SAndroid Build Coastguard Worker         TrustyKeymasterOperation::n(code),
682*9860b763SAndroid Build Coastguard Worker         Some(TrustyKeymasterOperation::SetBootParams)
683*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::ConfigureBootPatchlevel)
684*9860b763SAndroid Build Coastguard Worker     )
685*9860b763SAndroid Build Coastguard Worker }
686*9860b763SAndroid Build Coastguard Worker 
687*9860b763SAndroid Build Coastguard Worker /// Indicate whether a request message is a bootloader message.
is_trusty_bootloader_req(req: &TrustyPerformOpReq) -> bool688*9860b763SAndroid Build Coastguard Worker pub fn is_trusty_bootloader_req(req: &TrustyPerformOpReq) -> bool {
689*9860b763SAndroid Build Coastguard Worker     matches!(
690*9860b763SAndroid Build Coastguard Worker         req,
691*9860b763SAndroid Build Coastguard Worker         TrustyPerformOpReq::SetBootParams(_) | TrustyPerformOpReq::ConfigureBootPatchlevel(_)
692*9860b763SAndroid Build Coastguard Worker     )
693*9860b763SAndroid Build Coastguard Worker }
694*9860b763SAndroid Build Coastguard Worker 
695*9860b763SAndroid Build Coastguard Worker /// Indicate whether a request message is a provisioning message.
is_trusty_provisioning_code(code: u32) -> bool696*9860b763SAndroid Build Coastguard Worker pub fn is_trusty_provisioning_code(code: u32) -> bool {
697*9860b763SAndroid Build Coastguard Worker     matches!(
698*9860b763SAndroid Build Coastguard Worker         TrustyKeymasterOperation::n(code),
699*9860b763SAndroid Build Coastguard Worker         Some(TrustyKeymasterOperation::SetAttestationKey)
700*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::AppendAttestationCertChain)
701*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::ClearAttestationCertChain)
702*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::SetWrappedAttestationKey)
703*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::SetAttestationIds)
704*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::SetAttestationIdsKM3)
705*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::AppendUdsCertificate)
706*9860b763SAndroid Build Coastguard Worker             | Some(TrustyKeymasterOperation::ClearUdsCertificate)
707*9860b763SAndroid Build Coastguard Worker     )
708*9860b763SAndroid Build Coastguard Worker }
709*9860b763SAndroid Build Coastguard Worker 
710*9860b763SAndroid Build Coastguard Worker /// Indicate whether a request message is a provisioning message.
is_trusty_provisioning_req(req: &TrustyPerformOpReq) -> bool711*9860b763SAndroid Build Coastguard Worker pub fn is_trusty_provisioning_req(req: &TrustyPerformOpReq) -> bool {
712*9860b763SAndroid Build Coastguard Worker     matches!(
713*9860b763SAndroid Build Coastguard Worker         req,
714*9860b763SAndroid Build Coastguard Worker         TrustyPerformOpReq::SetAttestationKey(_)
715*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::AppendAttestationCertChain(_)
716*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::ClearAttestationCertChain(_)
717*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::SetWrappedAttestationKey(_)
718*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::SetAttestationIds(_)
719*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::SetAttestationIdsKM3(_)
720*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::AppendUdsCertificate(_)
721*9860b763SAndroid Build Coastguard Worker             | TrustyPerformOpReq::ClearUdsCertificate(_)
722*9860b763SAndroid Build Coastguard Worker     )
723*9860b763SAndroid Build Coastguard Worker }
724*9860b763SAndroid Build Coastguard Worker 
725*9860b763SAndroid Build Coastguard Worker #[cfg(test)]
726*9860b763SAndroid Build Coastguard Worker mod tests {
727*9860b763SAndroid Build Coastguard Worker     use super::*;
728*9860b763SAndroid Build Coastguard Worker     use alloc::vec;
729*9860b763SAndroid Build Coastguard Worker     #[test]
test_inner_serialize()730*9860b763SAndroid Build Coastguard Worker     fn test_inner_serialize() {
731*9860b763SAndroid Build Coastguard Worker         let msg = SetBootParamsRequest {
732*9860b763SAndroid Build Coastguard Worker             // `u32` encoding uses native byte order so use symmetric values
733*9860b763SAndroid Build Coastguard Worker             os_version: 0x01010101,
734*9860b763SAndroid Build Coastguard Worker             os_patchlevel: 0x02020202,
735*9860b763SAndroid Build Coastguard Worker             device_locked: false,
736*9860b763SAndroid Build Coastguard Worker             verified_boot_state: VerifiedBootState::Unverified,
737*9860b763SAndroid Build Coastguard Worker             verified_boot_key: vec![1, 2, 3],
738*9860b763SAndroid Build Coastguard Worker             verified_boot_hash: vec![5, 4, 3],
739*9860b763SAndroid Build Coastguard Worker         };
740*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "little")]
741*9860b763SAndroid Build Coastguard Worker         let hex_data = concat!(
742*9860b763SAndroid Build Coastguard Worker             "01010101", // os_version
743*9860b763SAndroid Build Coastguard Worker             "02020202", // os_patchlevel
744*9860b763SAndroid Build Coastguard Worker             "00000000", // device_locked
745*9860b763SAndroid Build Coastguard Worker             "02000000", // verified_boot_state
746*9860b763SAndroid Build Coastguard Worker             "03000000", "010203", // verified_boot_key
747*9860b763SAndroid Build Coastguard Worker             "03000000", "050403", // verified_boot_key
748*9860b763SAndroid Build Coastguard Worker         );
749*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "big")]
750*9860b763SAndroid Build Coastguard Worker         let hex_data = concat!(
751*9860b763SAndroid Build Coastguard Worker             "01010101", // os_version
752*9860b763SAndroid Build Coastguard Worker             "02020202", // os_patchlevel
753*9860b763SAndroid Build Coastguard Worker             "00000000", // device_locked
754*9860b763SAndroid Build Coastguard Worker             "02000002", // verified_boot_state
755*9860b763SAndroid Build Coastguard Worker             "00000003", "010203", // verified_boot_key
756*9860b763SAndroid Build Coastguard Worker             "00000003", "050403", // verified_boot_key
757*9860b763SAndroid Build Coastguard Worker         );
758*9860b763SAndroid Build Coastguard Worker         let data = hex::decode(hex_data).unwrap();
759*9860b763SAndroid Build Coastguard Worker 
760*9860b763SAndroid Build Coastguard Worker         let mut got_data = Vec::new();
761*9860b763SAndroid Build Coastguard Worker         msg.serialize_into(&mut got_data).unwrap();
762*9860b763SAndroid Build Coastguard Worker         assert_eq!(hex::encode(got_data), hex_data);
763*9860b763SAndroid Build Coastguard Worker 
764*9860b763SAndroid Build Coastguard Worker         let (got, rest) = SetBootParamsRequest::deserialize(&data).unwrap();
765*9860b763SAndroid Build Coastguard Worker         assert!(rest.is_empty());
766*9860b763SAndroid Build Coastguard Worker         assert!(got == msg);
767*9860b763SAndroid Build Coastguard Worker     }
768*9860b763SAndroid Build Coastguard Worker     #[test]
test_get_version_serialize()769*9860b763SAndroid Build Coastguard Worker     fn test_get_version_serialize() {
770*9860b763SAndroid Build Coastguard Worker         let msg = GetVersionResponse { major_ver: 1, minor_ver: 2, subminor_ver: 3 };
771*9860b763SAndroid Build Coastguard Worker         let data = vec![1, 2, 3];
772*9860b763SAndroid Build Coastguard Worker 
773*9860b763SAndroid Build Coastguard Worker         let mut got_data = Vec::new();
774*9860b763SAndroid Build Coastguard Worker         msg.serialize_into(&mut got_data).unwrap();
775*9860b763SAndroid Build Coastguard Worker         assert_eq!(got_data, data);
776*9860b763SAndroid Build Coastguard Worker 
777*9860b763SAndroid Build Coastguard Worker         let (got, rest) = GetVersionResponse::deserialize(&data).unwrap();
778*9860b763SAndroid Build Coastguard Worker         assert!(rest.is_empty());
779*9860b763SAndroid Build Coastguard Worker         assert!(got == msg);
780*9860b763SAndroid Build Coastguard Worker     }
781*9860b763SAndroid Build Coastguard Worker     #[test]
test_inner_deserialize_fail()782*9860b763SAndroid Build Coastguard Worker     fn test_inner_deserialize_fail() {
783*9860b763SAndroid Build Coastguard Worker         let data = "010101"; // too short
784*9860b763SAndroid Build Coastguard Worker         let data = hex::decode(data).unwrap();
785*9860b763SAndroid Build Coastguard Worker         let result = ConfigureBootPatchlevelRequest::deserialize(&data);
786*9860b763SAndroid Build Coastguard Worker         assert!(result.is_err());
787*9860b763SAndroid Build Coastguard Worker     }
788*9860b763SAndroid Build Coastguard Worker     #[test]
test_trusty_serialize_rsp()789*9860b763SAndroid Build Coastguard Worker     fn test_trusty_serialize_rsp() {
790*9860b763SAndroid Build Coastguard Worker         use alloc::vec;
791*9860b763SAndroid Build Coastguard Worker         let msg = TrustyPerformSecureOpRsp::GetAuthTokenKey(GetAuthTokenKeyResponse {
792*9860b763SAndroid Build Coastguard Worker             key_material: vec![1, 2, 3],
793*9860b763SAndroid Build Coastguard Worker         });
794*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "little")]
795*9860b763SAndroid Build Coastguard Worker         let data = concat!("03000000", "010203");
796*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "big")]
797*9860b763SAndroid Build Coastguard Worker         let data = concat!("00000003", "010203");
798*9860b763SAndroid Build Coastguard Worker 
799*9860b763SAndroid Build Coastguard Worker         let got_data = serialize_trusty_secure_rsp(msg).unwrap();
800*9860b763SAndroid Build Coastguard Worker         assert_eq!(hex::encode(got_data), data);
801*9860b763SAndroid Build Coastguard Worker     }
802*9860b763SAndroid Build Coastguard Worker     #[test]
test_get_uds_certs_rsp_serialize()803*9860b763SAndroid Build Coastguard Worker     fn test_get_uds_certs_rsp_serialize() {
804*9860b763SAndroid Build Coastguard Worker         let msg =
805*9860b763SAndroid Build Coastguard Worker             TrustyPerformSecureOpRsp::GetUdsCerts(GetUdsCertsResponse { uds_certs: vec![1, 2, 3] });
806*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "little")]
807*9860b763SAndroid Build Coastguard Worker         let data = concat!(
808*9860b763SAndroid Build Coastguard Worker             /* cmd */ "0b000000", /* rc */ "00000000", /* len */ "03000000",
809*9860b763SAndroid Build Coastguard Worker             /* data */ "010203"
810*9860b763SAndroid Build Coastguard Worker         );
811*9860b763SAndroid Build Coastguard Worker         #[cfg(target_endian = "big")]
812*9860b763SAndroid Build Coastguard Worker         let data = concat!(
813*9860b763SAndroid Build Coastguard Worker             /* cmd */ "0000000b", /* rc */ "00000000", /* len */ "00000003",
814*9860b763SAndroid Build Coastguard Worker             /* data */ "010203"
815*9860b763SAndroid Build Coastguard Worker         );
816*9860b763SAndroid Build Coastguard Worker         let got_data = serialize_trusty_secure_rsp(msg).unwrap();
817*9860b763SAndroid Build Coastguard Worker         assert_eq!(hex::encode(got_data), data);
818*9860b763SAndroid Build Coastguard Worker     }
819*9860b763SAndroid Build Coastguard Worker }
820