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