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