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