1 // Copyright 2023, 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 //! IRemotelyProvisionedComponent HAL implementation.
16
17 use crate::rkpvm;
18 use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
19 DeviceInfo::DeviceInfo,
20 IRemotelyProvisionedComponent::{
21 BnRemotelyProvisionedComponent, IRemotelyProvisionedComponent, STATUS_FAILED,
22 STATUS_INVALID_MAC, STATUS_REMOVED,
23 },
24 MacedPublicKey::MacedPublicKey,
25 ProtectedData::ProtectedData,
26 RpcHardwareInfo::{RpcHardwareInfo, CURVE_NONE, MIN_SUPPORTED_NUM_KEYS_IN_CSR},
27 };
28 use anyhow::Context;
29 use avflog::LogResult;
30 use binder::{
31 BinderFeatures, ExceptionCode, Interface, IntoBinderResult, Result as BinderResult, Status,
32 Strong,
33 };
34 use hypervisor_props::is_protected_vm_supported;
35 use rustutils::system_properties;
36 use service_vm_comm::{RequestProcessingError, Response};
37
38 /// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
new_binder() -> Strong<dyn IRemotelyProvisionedComponent>39 pub(crate) fn new_binder() -> Strong<dyn IRemotelyProvisionedComponent> {
40 BnRemotelyProvisionedComponent::new_binder(
41 AvfRemotelyProvisionedComponent {},
42 BinderFeatures::default(),
43 )
44 }
45
46 struct AvfRemotelyProvisionedComponent {}
47
48 impl Interface for AvfRemotelyProvisionedComponent {}
49
50 #[allow(non_snake_case)]
51 impl IRemotelyProvisionedComponent for AvfRemotelyProvisionedComponent {
getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo>52 fn getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo> {
53 check_remote_attestation_is_supported()?;
54
55 Ok(RpcHardwareInfo {
56 versionNumber: 3,
57 rpcAuthorName: String::from("Android Virtualization Framework"),
58 supportedEekCurve: CURVE_NONE,
59 uniqueId: Some(String::from("AVF Remote Provisioning 1")),
60 supportedNumKeysInCsr: MIN_SUPPORTED_NUM_KEYS_IN_CSR,
61 })
62 }
63
generateEcdsaP256KeyPair( &self, testMode: bool, macedPublicKey: &mut MacedPublicKey, ) -> BinderResult<Vec<u8>>64 fn generateEcdsaP256KeyPair(
65 &self,
66 testMode: bool,
67 macedPublicKey: &mut MacedPublicKey,
68 ) -> BinderResult<Vec<u8>> {
69 check_remote_attestation_is_supported()?;
70
71 if testMode {
72 return Err(Status::new_service_specific_error_str(
73 STATUS_REMOVED,
74 Some("generateEcdsaP256KeyPair does not support test mode in IRPC v3+ HAL."),
75 ))
76 .with_log();
77 }
78 let res = rkpvm::generate_ecdsa_p256_key_pair()
79 .context("Failed to generate ECDSA P-256 key pair")
80 .with_log()
81 .or_service_specific_exception(STATUS_FAILED)?;
82 match res {
83 Response::GenerateEcdsaP256KeyPair(key_pair) => {
84 macedPublicKey.macedKey = key_pair.maced_public_key;
85 Ok(key_pair.key_blob)
86 }
87 _ => Err(to_service_specific_error(res)),
88 }
89 .with_log()
90 }
91
generateCertificateRequest( &self, _testMode: bool, _keysToSign: &[MacedPublicKey], _endpointEncryptionCertChain: &[u8], _challenge: &[u8], _deviceInfo: &mut DeviceInfo, _protectedData: &mut ProtectedData, ) -> BinderResult<Vec<u8>>92 fn generateCertificateRequest(
93 &self,
94 _testMode: bool,
95 _keysToSign: &[MacedPublicKey],
96 _endpointEncryptionCertChain: &[u8],
97 _challenge: &[u8],
98 _deviceInfo: &mut DeviceInfo,
99 _protectedData: &mut ProtectedData,
100 ) -> BinderResult<Vec<u8>> {
101 Err(Status::new_service_specific_error_str(
102 STATUS_REMOVED,
103 Some("This method was deprecated in v3 of the interface."),
104 ))
105 .with_log()
106 }
107
generateCertificateRequestV2( &self, keysToSign: &[MacedPublicKey], challenge: &[u8], ) -> BinderResult<Vec<u8>>108 fn generateCertificateRequestV2(
109 &self,
110 keysToSign: &[MacedPublicKey],
111 challenge: &[u8],
112 ) -> BinderResult<Vec<u8>> {
113 check_remote_attestation_is_supported()?;
114
115 const MAX_CHALLENGE_SIZE: usize = 64;
116 if challenge.len() > MAX_CHALLENGE_SIZE {
117 let message = format!(
118 "Challenge is too big. Actual: {:?}. Maximum: {:?}.",
119 challenge.len(),
120 MAX_CHALLENGE_SIZE
121 );
122 return Err(Status::new_service_specific_error_str(STATUS_FAILED, Some(message)))
123 .with_log();
124 }
125 let res = rkpvm::generate_certificate_request(keysToSign, challenge)
126 .context("Failed to generate certificate request")
127 .with_log()
128 .or_service_specific_exception(STATUS_FAILED)?;
129 match res {
130 Response::GenerateCertificateRequest(res) => Ok(res),
131 _ => Err(to_service_specific_error(res)),
132 }
133 .with_log()
134 }
135 }
136
check_remote_attestation_is_supported() -> BinderResult<()>137 pub(crate) fn check_remote_attestation_is_supported() -> BinderResult<()> {
138 if !is_protected_vm_supported().unwrap_or(false) {
139 return Err(Status::new_exception_str(
140 ExceptionCode::UNSUPPORTED_OPERATION,
141 Some("Protected VM support is missing for this operation"),
142 ))
143 .with_log();
144 }
145 if !is_remote_attestation_supported() {
146 return Err(Status::new_exception_str(
147 ExceptionCode::UNSUPPORTED_OPERATION,
148 Some("Remote attestation is disabled"),
149 ))
150 .with_log();
151 }
152 Ok(())
153 }
154
is_remote_attestation_supported() -> bool155 pub(crate) fn is_remote_attestation_supported() -> bool {
156 // Remote attestation is enabled by default.
157 system_properties::read_bool("avf.remote_attestation.enabled", true).unwrap_or(true)
158 }
159
to_service_specific_error(response: Response) -> Status160 pub(crate) fn to_service_specific_error(response: Response) -> Status {
161 match response {
162 Response::Err(e) => match e {
163 RequestProcessingError::InvalidMac => {
164 Status::new_service_specific_error_str(STATUS_INVALID_MAC, Some(format!("{e}")))
165 }
166 _ => Status::new_service_specific_error_str(
167 STATUS_FAILED,
168 Some(format!("Failed to process request: {e}.")),
169 ),
170 },
171 other => Status::new_service_specific_error_str(
172 STATUS_FAILED,
173 Some(format!("Incorrect response type: {other:?}")),
174 ),
175 }
176 }
177