Max Bires | 148c08e | 2020-10-13 13:41:41 -0700 | [diff] [blame] | 1 | // Copyright 2020, 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 | //! This is the implementation for the remote provisioning AIDL interface between |
| 16 | //! the network providers for remote provisioning and the system. This interface |
| 17 | //! allows the caller to prompt the Remote Provisioning HAL to generate keys and |
| 18 | //! CBOR blobs that can be ferried to a provisioning server that will return |
| 19 | //! certificate chains signed by some root authority and stored in a keystore SQLite |
| 20 | //! DB. |
| 21 | |
Max Bires | b2e1d03 | 2021-02-08 21:35:05 -0800 | [diff] [blame] | 22 | use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{ |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 23 | Algorithm::Algorithm, AttestationKey::AttestationKey, Certificate::Certificate, |
Seth Moore | cd6e918 | 2022-11-04 17:39:05 +0000 | [diff] [blame] | 24 | KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue, SecurityLevel::SecurityLevel, |
Max Bires | 834dd36 | 2021-03-23 13:01:57 -0700 | [diff] [blame] | 25 | Tag::Tag, |
Max Bires | b2e1d03 | 2021-02-08 21:35:05 -0800 | [diff] [blame] | 26 | }; |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 27 | use android_system_keystore2::aidl::android::system::keystore2::{ |
Tri Vo | a1634bb | 2022-12-01 15:54:19 -0800 | [diff] [blame] | 28 | Domain::Domain, KeyDescriptor::KeyDescriptor, |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 29 | }; |
Max Bires | b2e1d03 | 2021-02-08 21:35:05 -0800 | [diff] [blame] | 30 | use anyhow::{Context, Result}; |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 31 | use keystore2_crypto::parse_subject_from_certificate; |
Max Bires | 148c08e | 2020-10-13 13:41:41 -0700 | [diff] [blame] | 32 | |
Tri Vo | a1634bb | 2022-12-01 15:54:19 -0800 | [diff] [blame] | 33 | use crate::database::Uuid; |
Alice Wang | bf6a693 | 2023-11-07 11:47:12 +0000 | [diff] [blame] | 34 | use crate::globals::get_remotely_provisioned_component_name; |
Shaquille Johnson | 9da2e1c | 2022-09-19 12:39:01 +0000 | [diff] [blame] | 35 | use crate::ks_err; |
Hasini Gunasinghe | 8a1a224 | 2021-08-02 22:28:39 +0000 | [diff] [blame] | 36 | use crate::metrics_store::log_rkp_error_stats; |
Tri Vo | b5e43d1 | 2022-12-21 08:54:14 -0800 | [diff] [blame] | 37 | use crate::rkpd_client::get_rkpd_attestation_key; |
Hasini Gunasinghe | 8a1a224 | 2021-08-02 22:28:39 +0000 | [diff] [blame] | 38 | use android_security_metrics::aidl::android::security::metrics::RkpError::RkpError as MetricsRkpError; |
Max Bires | 148c08e | 2020-10-13 13:41:41 -0700 | [diff] [blame] | 39 | |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 40 | /// Contains helper functions to check if remote provisioning is enabled on the system and, if so, |
| 41 | /// to assign and retrieve attestation keys and certificate chains. |
| 42 | #[derive(Default)] |
| 43 | pub struct RemProvState { |
| 44 | security_level: SecurityLevel, |
| 45 | km_uuid: Uuid, |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 46 | } |
| 47 | |
| 48 | impl RemProvState { |
| 49 | /// Creates a RemProvState struct. |
| 50 | pub fn new(security_level: SecurityLevel, km_uuid: Uuid) -> Self { |
Tri Vo | a1634bb | 2022-12-01 15:54:19 -0800 | [diff] [blame] | 51 | Self { security_level, km_uuid } |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 52 | } |
| 53 | |
Max Bires | 55620ff | 2022-02-11 13:34:15 -0800 | [diff] [blame] | 54 | /// Returns the uuid for the KM instance attached to this RemProvState struct. |
| 55 | pub fn get_uuid(&self) -> Uuid { |
| 56 | self.km_uuid |
| 57 | } |
| 58 | |
Seth Moore | dfdcb87 | 2022-04-20 14:33:19 -0700 | [diff] [blame] | 59 | fn is_rkp_only(&self) -> bool { |
Max Bires | 65207b5 | 2022-03-29 23:58:08 -0700 | [diff] [blame] | 60 | let default_value = false; |
| 61 | |
Seth Moore | dfdcb87 | 2022-04-20 14:33:19 -0700 | [diff] [blame] | 62 | let property_name = match self.security_level { |
| 63 | SecurityLevel::STRONGBOX => "remote_provisioning.strongbox.rkp_only", |
| 64 | SecurityLevel::TRUSTED_ENVIRONMENT => "remote_provisioning.tee.rkp_only", |
Max Bires | 65207b5 | 2022-03-29 23:58:08 -0700 | [diff] [blame] | 65 | _ => return default_value, |
| 66 | }; |
| 67 | |
| 68 | rustutils::system_properties::read_bool(property_name, default_value) |
| 69 | .unwrap_or(default_value) |
| 70 | } |
| 71 | |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 72 | fn is_asymmetric_key(&self, params: &[KeyParameter]) -> bool { |
| 73 | params.iter().any(|kp| { |
| 74 | matches!( |
| 75 | kp, |
| 76 | KeyParameter { |
| 77 | tag: Tag::ALGORITHM, |
| 78 | value: KeyParameterValue::Algorithm(Algorithm::RSA) |
| 79 | } | KeyParameter { |
| 80 | tag: Tag::ALGORITHM, |
| 81 | value: KeyParameterValue::Algorithm(Algorithm::EC) |
| 82 | } |
| 83 | ) |
| 84 | }) |
| 85 | } |
| 86 | |
Tri Vo | b5e43d1 | 2022-12-21 08:54:14 -0800 | [diff] [blame] | 87 | /// Fetches attestation key and corresponding certificates from RKPD. |
| 88 | pub fn get_rkpd_attestation_key_and_certs( |
| 89 | &self, |
| 90 | key: &KeyDescriptor, |
| 91 | caller_uid: u32, |
| 92 | params: &[KeyParameter], |
| 93 | ) -> Result<Option<(AttestationKey, Certificate)>> { |
| 94 | if !self.is_asymmetric_key(params) || key.domain != Domain::APP { |
| 95 | Ok(None) |
| 96 | } else { |
Alice Wang | bf6a693 | 2023-11-07 11:47:12 +0000 | [diff] [blame] | 97 | let rpc_name = get_remotely_provisioned_component_name(&self.security_level) |
| 98 | .context(ks_err!("Trying to get IRPC name."))?; |
| 99 | match get_rkpd_attestation_key(&rpc_name, caller_uid) { |
Tri Vo | b5e43d1 | 2022-12-21 08:54:14 -0800 | [diff] [blame] | 100 | Err(e) => { |
| 101 | if self.is_rkp_only() { |
| 102 | log::error!("Error occurred: {:?}", e); |
| 103 | return Err(e); |
| 104 | } |
| 105 | log::warn!("Error occurred: {:?}", e); |
| 106 | log_rkp_error_stats( |
| 107 | MetricsRkpError::FALL_BACK_DURING_HYBRID, |
| 108 | &self.security_level, |
| 109 | ); |
| 110 | Ok(None) |
| 111 | } |
| 112 | Ok(rkpd_key) => Ok(Some(( |
| 113 | AttestationKey { |
| 114 | keyBlob: rkpd_key.keyBlob, |
| 115 | attestKeyParams: vec![], |
| 116 | // Batch certificate is at the beginning of the certificate chain. |
| 117 | issuerSubjectName: parse_subject_from_certificate( |
| 118 | &rkpd_key.encodedCertChain, |
| 119 | ) |
| 120 | .context(ks_err!("Failed to parse subject."))?, |
| 121 | }, |
| 122 | Certificate { encodedCertificate: rkpd_key.encodedCertChain }, |
| 123 | ))), |
| 124 | } |
| 125 | } |
| 126 | } |
Max Bires | 97f9681 | 2021-02-23 23:44:57 -0800 | [diff] [blame] | 127 | } |