Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 1 | // Copyright 2023 The Android Open Source Project |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 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 | // |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 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 | |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 15 | use crate::dice_driver::DiceDriver; |
| 16 | use crate::{is_debuggable, MicrodroidData}; |
| 17 | use anyhow::{bail, Context, Result}; |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 18 | use ciborium::{cbor, ser}; |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 19 | use diced_open_dice::OwnedDiceArtifacts; |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 20 | use microdroid_metadata::PayloadMetadata; |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 21 | use openssl::sha::Sha512; |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 22 | |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 23 | /// Perform an open DICE derivation for the payload. |
| 24 | pub fn dice_derivation( |
| 25 | dice: DiceDriver, |
| 26 | verified_data: &MicrodroidData, |
| 27 | payload_metadata: &PayloadMetadata, |
| 28 | ) -> Result<OwnedDiceArtifacts> { |
| 29 | // Calculate compound digests of code and authorities |
| 30 | let mut code_hash_ctx = Sha512::new(); |
| 31 | let mut authority_hash_ctx = Sha512::new(); |
| 32 | code_hash_ctx.update(verified_data.apk_data.root_hash.as_ref()); |
| 33 | authority_hash_ctx.update(verified_data.apk_data.pubkey.as_ref()); |
| 34 | for extra_apk in &verified_data.extra_apks_data { |
| 35 | code_hash_ctx.update(extra_apk.root_hash.as_ref()); |
| 36 | authority_hash_ctx.update(extra_apk.pubkey.as_ref()); |
Alice Wang | 7e6c935 | 2023-02-15 15:44:13 +0000 | [diff] [blame] | 37 | } |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 38 | for apex in &verified_data.apex_data { |
| 39 | code_hash_ctx.update(apex.root_digest.as_ref()); |
| 40 | authority_hash_ctx.update(apex.public_key.as_ref()); |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 41 | } |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 42 | let code_hash = code_hash_ctx.finish(); |
| 43 | let authority_hash = authority_hash_ctx.finish(); |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 44 | |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 45 | let config_descriptor = format_payload_config_descriptor(payload_metadata)?; |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 46 | |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 47 | // Check debuggability, conservatively assuming it is debuggable |
| 48 | let debuggable = is_debuggable()?; |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 49 | |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 50 | // Send the details to diced |
| 51 | let hidden = verified_data.salt.clone().try_into().unwrap(); |
| 52 | dice.derive(code_hash, &config_descriptor, authority_hash, debuggable, hidden) |
Andrew Scull | d64ae7d | 2022-10-05 17:41:43 +0000 | [diff] [blame] | 53 | } |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 54 | |
| 55 | /// Returns a configuration descriptor of the given payload following the BCC's specification: |
| 56 | /// https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl |
| 57 | /// { |
| 58 | /// -70002: "Microdroid payload", |
Alan Stokes | 331a3a1 | 2023-08-04 11:31:51 +0100 | [diff] [blame] | 59 | /// ? -71000: tstr ; payload_config_path |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 60 | /// ? -71001: PayloadConfig |
| 61 | /// } |
| 62 | /// PayloadConfig = { |
Alan Stokes | 331a3a1 | 2023-08-04 11:31:51 +0100 | [diff] [blame] | 63 | /// 1: tstr ; payload_binary_name |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 64 | /// } |
Alan Stokes | 1125e01 | 2023-10-13 12:31:10 +0100 | [diff] [blame^] | 65 | fn format_payload_config_descriptor(payload: &PayloadMetadata) -> Result<Vec<u8>> { |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 66 | const MICRODROID_PAYLOAD_COMPONENT_NAME: &str = "Microdroid payload"; |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 67 | |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 68 | let config_descriptor_cbor_value = match payload { |
| 69 | PayloadMetadata::ConfigPath(payload_config_path) => cbor!({ |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 70 | -70002 => MICRODROID_PAYLOAD_COMPONENT_NAME, |
| 71 | -71000 => payload_config_path |
| 72 | }), |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 73 | PayloadMetadata::Config(payload_config) => cbor!({ |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 74 | -70002 => MICRODROID_PAYLOAD_COMPONENT_NAME, |
| 75 | -71001 => {1 => payload_config.payload_binary_name} |
| 76 | }), |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 77 | _ => bail!("Failed to match the payload against a config type: {:?}", payload), |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 78 | } |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 79 | .context("Failed to build a CBOR Value from payload metadata")?; |
| 80 | let mut config_descriptor = Vec::new(); |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 81 | |
Alice Wang | a04890b | 2023-03-01 11:45:09 +0000 | [diff] [blame] | 82 | ser::into_writer(&config_descriptor_cbor_value, &mut config_descriptor)?; |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 83 | Ok(config_descriptor) |
| 84 | } |
| 85 | |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 86 | #[cfg(test)] |
| 87 | mod tests { |
| 88 | use super::*; |
| 89 | use microdroid_metadata::PayloadConfig; |
| 90 | |
| 91 | #[test] |
| 92 | fn payload_metadata_with_path_formats_correctly() -> Result<()> { |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 93 | let payload_metadata = PayloadMetadata::ConfigPath("/config_path".to_string()); |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 94 | let config_descriptor = format_payload_config_descriptor(&payload_metadata)?; |
| 95 | static EXPECTED_CONFIG_DESCRIPTOR: &[u8] = &[ |
| 96 | 0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72, |
| 97 | 0x6f, 0x69, 0x64, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x00, 0x01, |
| 98 | 0x15, 0x57, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, |
| 99 | 0x68, |
| 100 | ]; |
| 101 | assert_eq!(EXPECTED_CONFIG_DESCRIPTOR, &config_descriptor); |
| 102 | Ok(()) |
| 103 | } |
| 104 | |
| 105 | #[test] |
| 106 | fn payload_metadata_with_config_formats_correctly() -> Result<()> { |
| 107 | let payload_config = PayloadConfig { |
| 108 | payload_binary_name: "payload_binary".to_string(), |
| 109 | ..Default::default() |
| 110 | }; |
Ludovic Barman | 93ee308 | 2023-06-20 12:18:43 +0000 | [diff] [blame] | 111 | let payload_metadata = PayloadMetadata::Config(payload_config); |
Alice Wang | 285a3d2 | 2023-03-01 11:36:29 +0000 | [diff] [blame] | 112 | let config_descriptor = format_payload_config_descriptor(&payload_metadata)?; |
| 113 | static EXPECTED_CONFIG_DESCRIPTOR: &[u8] = &[ |
| 114 | 0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72, |
| 115 | 0x6f, 0x69, 0x64, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x00, 0x01, |
| 116 | 0x15, 0x58, 0xa1, 0x01, 0x6e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, |
| 117 | 0x69, 0x6e, 0x61, 0x72, 0x79, |
| 118 | ]; |
| 119 | assert_eq!(EXPECTED_CONFIG_DESCRIPTOR, &config_descriptor); |
| 120 | Ok(()) |
| 121 | } |
| 122 | } |