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