blob: 40f54db82e766632c69114756841f9c2c017d054 [file] [log] [blame]
Alice Wang15f6d082023-08-25 09:11:07 +00001// 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
Alice Wangf3482602023-09-08 11:51:29 +000017use crate::rkpvm;
Alice Wang15f6d082023-08-25 09:11:07 +000018use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
19 DeviceInfo::DeviceInfo,
20 IRemotelyProvisionedComponent::{
Alice Wangf3482602023-09-08 11:51:29 +000021 BnRemotelyProvisionedComponent, IRemotelyProvisionedComponent, STATUS_FAILED,
Alice Wangd80e99e2023-09-15 13:26:01 +000022 STATUS_INVALID_MAC, STATUS_REMOVED,
Alice Wang15f6d082023-08-25 09:11:07 +000023 },
24 MacedPublicKey::MacedPublicKey,
25 ProtectedData::ProtectedData,
26 RpcHardwareInfo::{RpcHardwareInfo, CURVE_NONE, MIN_SUPPORTED_NUM_KEYS_IN_CSR},
27};
Alice Wangf3482602023-09-08 11:51:29 +000028use anyhow::Context;
Alice Wang15f6d082023-08-25 09:11:07 +000029use avflog::LogResult;
Alice Wangb5b90322023-11-14 07:38:18 +000030use binder::{
31 BinderFeatures, ExceptionCode, Interface, IntoBinderResult, Result as BinderResult, Status,
32 Strong,
33};
34use hypervisor_props::is_protected_vm_supported;
Alice Wangd80e99e2023-09-15 13:26:01 +000035use service_vm_comm::{RequestProcessingError, Response};
Alice Wang15f6d082023-08-25 09:11:07 +000036
37/// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
38pub(crate) fn new_binder() -> Strong<dyn IRemotelyProvisionedComponent> {
39 BnRemotelyProvisionedComponent::new_binder(
40 AvfRemotelyProvisionedComponent {},
41 BinderFeatures::default(),
42 )
43}
44
45struct AvfRemotelyProvisionedComponent {}
46
47impl Interface for AvfRemotelyProvisionedComponent {}
48
49#[allow(non_snake_case)]
50impl IRemotelyProvisionedComponent for AvfRemotelyProvisionedComponent {
51 fn getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo> {
Alice Wangb5b90322023-11-14 07:38:18 +000052 check_protected_vm_is_supported()?;
53
Alice Wang15f6d082023-08-25 09:11:07 +000054 Ok(RpcHardwareInfo {
55 versionNumber: 3,
56 rpcAuthorName: String::from("Android Virtualization Framework"),
57 supportedEekCurve: CURVE_NONE,
Alice Wangb5b90322023-11-14 07:38:18 +000058 uniqueId: Some(String::from("AVF Remote Provisioning 1")),
Alice Wang15f6d082023-08-25 09:11:07 +000059 supportedNumKeysInCsr: MIN_SUPPORTED_NUM_KEYS_IN_CSR,
60 })
61 }
62
63 fn generateEcdsaP256KeyPair(
64 &self,
Alice Wanga723fe62023-09-06 12:38:59 +000065 testMode: bool,
Alice Wangf3482602023-09-08 11:51:29 +000066 macedPublicKey: &mut MacedPublicKey,
Alice Wang15f6d082023-08-25 09:11:07 +000067 ) -> BinderResult<Vec<u8>> {
Alice Wangb5b90322023-11-14 07:38:18 +000068 check_protected_vm_is_supported()?;
69
Alice Wanga723fe62023-09-06 12:38:59 +000070 if testMode {
71 return Err(Status::new_service_specific_error_str(
72 STATUS_REMOVED,
73 Some("generateEcdsaP256KeyPair does not support test mode in IRPC v3+ HAL."),
74 ))
75 .with_log();
76 }
Alice Wangd80e99e2023-09-15 13:26:01 +000077 let res = rkpvm::generate_ecdsa_p256_key_pair()
Alice Wangf3482602023-09-08 11:51:29 +000078 .context("Failed to generate ECDSA P-256 key pair")
79 .with_log()
80 .or_service_specific_exception(STATUS_FAILED)?;
Alice Wangd80e99e2023-09-15 13:26:01 +000081 match res {
82 Response::GenerateEcdsaP256KeyPair(key_pair) => {
83 macedPublicKey.macedKey = key_pair.maced_public_key;
84 Ok(key_pair.key_blob)
85 }
86 _ => Err(to_service_specific_error(res)),
87 }
88 .with_log()
Alice Wang15f6d082023-08-25 09:11:07 +000089 }
90
91 fn generateCertificateRequest(
92 &self,
93 _testMode: bool,
94 _keysToSign: &[MacedPublicKey],
95 _endpointEncryptionCertChain: &[u8],
96 _challenge: &[u8],
97 _deviceInfo: &mut DeviceInfo,
98 _protectedData: &mut ProtectedData,
99 ) -> BinderResult<Vec<u8>> {
100 Err(Status::new_service_specific_error_str(
101 STATUS_REMOVED,
102 Some("This method was deprecated in v3 of the interface."),
103 ))
104 .with_log()
105 }
106
107 fn generateCertificateRequestV2(
108 &self,
Alice Wangf3482602023-09-08 11:51:29 +0000109 keysToSign: &[MacedPublicKey],
110 challenge: &[u8],
Alice Wang15f6d082023-08-25 09:11:07 +0000111 ) -> BinderResult<Vec<u8>> {
Alice Wangb5b90322023-11-14 07:38:18 +0000112 check_protected_vm_is_supported()?;
113
Alice Wang2628d332023-09-13 14:48:37 +0000114 const MAX_CHALLENGE_SIZE: usize = 64;
115 if challenge.len() > MAX_CHALLENGE_SIZE {
116 let message = format!(
117 "Challenge is too big. Actual: {:?}. Maximum: {:?}.",
118 challenge.len(),
119 MAX_CHALLENGE_SIZE
120 );
121 return Err(Status::new_service_specific_error_str(STATUS_FAILED, Some(message)))
122 .with_log();
123 }
Alice Wangd80e99e2023-09-15 13:26:01 +0000124 let res = rkpvm::generate_certificate_request(keysToSign, challenge)
Alice Wangf3482602023-09-08 11:51:29 +0000125 .context("Failed to generate certificate request")
126 .with_log()
Alice Wangd80e99e2023-09-15 13:26:01 +0000127 .or_service_specific_exception(STATUS_FAILED)?;
128 match res {
129 Response::GenerateCertificateRequest(res) => Ok(res),
130 _ => Err(to_service_specific_error(res)),
131 }
132 .with_log()
133 }
134}
135
Alice Wangb5b90322023-11-14 07:38:18 +0000136fn check_protected_vm_is_supported() -> BinderResult<()> {
137 if is_protected_vm_supported().unwrap_or(false) {
138 Ok(())
139 } else {
140 Err(Status::new_exception_str(
141 ExceptionCode::UNSUPPORTED_OPERATION,
142 Some("Protected VM support is missing for this operation"),
143 ))
144 .with_log()
145 }
146}
147
Alice Wangd80e99e2023-09-15 13:26:01 +0000148fn to_service_specific_error(response: Response) -> Status {
149 match response {
150 Response::Err(e) => match e {
151 RequestProcessingError::InvalidMac => {
152 Status::new_service_specific_error_str(STATUS_INVALID_MAC, Some(format!("{e}")))
153 }
154 _ => Status::new_service_specific_error_str(
155 STATUS_FAILED,
156 Some(format!("Failed to process request: {e}.")),
157 ),
158 },
159 other => Status::new_service_specific_error_str(
160 STATUS_FAILED,
161 Some(format!("Incorrect response type: {other:?}")),
162 ),
Alice Wang15f6d082023-08-25 09:11:07 +0000163 }
164}