blob: a9a07a5a5e6bc5deeeac1090a0826328b943dbab [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;
Alan Stokes2bffe572023-11-14 01:40:45 +000030use binder::{BinderFeatures, Interface, IntoBinderResult, Result as BinderResult, Status, Strong};
Alice Wangd80e99e2023-09-15 13:26:01 +000031use service_vm_comm::{RequestProcessingError, Response};
Alice Wang15f6d082023-08-25 09:11:07 +000032
33/// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
34pub(crate) fn new_binder() -> Strong<dyn IRemotelyProvisionedComponent> {
35 BnRemotelyProvisionedComponent::new_binder(
36 AvfRemotelyProvisionedComponent {},
37 BinderFeatures::default(),
38 )
39}
40
41struct AvfRemotelyProvisionedComponent {}
42
43impl Interface for AvfRemotelyProvisionedComponent {}
44
45#[allow(non_snake_case)]
46impl IRemotelyProvisionedComponent for AvfRemotelyProvisionedComponent {
47 fn getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo> {
48 Ok(RpcHardwareInfo {
49 versionNumber: 3,
50 rpcAuthorName: String::from("Android Virtualization Framework"),
51 supportedEekCurve: CURVE_NONE,
Alan Stokes2bffe572023-11-14 01:40:45 +000052 uniqueId: Some(String::from("Android Virtualization Framework 1")),
Alice Wang15f6d082023-08-25 09:11:07 +000053 supportedNumKeysInCsr: MIN_SUPPORTED_NUM_KEYS_IN_CSR,
54 })
55 }
56
57 fn generateEcdsaP256KeyPair(
58 &self,
Alice Wanga723fe62023-09-06 12:38:59 +000059 testMode: bool,
Alice Wangf3482602023-09-08 11:51:29 +000060 macedPublicKey: &mut MacedPublicKey,
Alice Wang15f6d082023-08-25 09:11:07 +000061 ) -> BinderResult<Vec<u8>> {
Alice Wanga723fe62023-09-06 12:38:59 +000062 if testMode {
63 return Err(Status::new_service_specific_error_str(
64 STATUS_REMOVED,
65 Some("generateEcdsaP256KeyPair does not support test mode in IRPC v3+ HAL."),
66 ))
67 .with_log();
68 }
Alice Wangd80e99e2023-09-15 13:26:01 +000069 let res = rkpvm::generate_ecdsa_p256_key_pair()
Alice Wangf3482602023-09-08 11:51:29 +000070 .context("Failed to generate ECDSA P-256 key pair")
71 .with_log()
72 .or_service_specific_exception(STATUS_FAILED)?;
Alice Wangd80e99e2023-09-15 13:26:01 +000073 match res {
74 Response::GenerateEcdsaP256KeyPair(key_pair) => {
75 macedPublicKey.macedKey = key_pair.maced_public_key;
76 Ok(key_pair.key_blob)
77 }
78 _ => Err(to_service_specific_error(res)),
79 }
80 .with_log()
Alice Wang15f6d082023-08-25 09:11:07 +000081 }
82
83 fn generateCertificateRequest(
84 &self,
85 _testMode: bool,
86 _keysToSign: &[MacedPublicKey],
87 _endpointEncryptionCertChain: &[u8],
88 _challenge: &[u8],
89 _deviceInfo: &mut DeviceInfo,
90 _protectedData: &mut ProtectedData,
91 ) -> BinderResult<Vec<u8>> {
92 Err(Status::new_service_specific_error_str(
93 STATUS_REMOVED,
94 Some("This method was deprecated in v3 of the interface."),
95 ))
96 .with_log()
97 }
98
99 fn generateCertificateRequestV2(
100 &self,
Alice Wangf3482602023-09-08 11:51:29 +0000101 keysToSign: &[MacedPublicKey],
102 challenge: &[u8],
Alice Wang15f6d082023-08-25 09:11:07 +0000103 ) -> BinderResult<Vec<u8>> {
Alice Wang2628d332023-09-13 14:48:37 +0000104 const MAX_CHALLENGE_SIZE: usize = 64;
105 if challenge.len() > MAX_CHALLENGE_SIZE {
106 let message = format!(
107 "Challenge is too big. Actual: {:?}. Maximum: {:?}.",
108 challenge.len(),
109 MAX_CHALLENGE_SIZE
110 );
111 return Err(Status::new_service_specific_error_str(STATUS_FAILED, Some(message)))
112 .with_log();
113 }
Alice Wangd80e99e2023-09-15 13:26:01 +0000114 let res = rkpvm::generate_certificate_request(keysToSign, challenge)
Alice Wangf3482602023-09-08 11:51:29 +0000115 .context("Failed to generate certificate request")
116 .with_log()
Alice Wangd80e99e2023-09-15 13:26:01 +0000117 .or_service_specific_exception(STATUS_FAILED)?;
118 match res {
119 Response::GenerateCertificateRequest(res) => Ok(res),
120 _ => Err(to_service_specific_error(res)),
121 }
122 .with_log()
123 }
124}
125
126fn to_service_specific_error(response: Response) -> Status {
127 match response {
128 Response::Err(e) => match e {
129 RequestProcessingError::InvalidMac => {
130 Status::new_service_specific_error_str(STATUS_INVALID_MAC, Some(format!("{e}")))
131 }
132 _ => Status::new_service_specific_error_str(
133 STATUS_FAILED,
134 Some(format!("Failed to process request: {e}.")),
135 ),
136 },
137 other => Status::new_service_specific_error_str(
138 STATUS_FAILED,
139 Some(format!("Incorrect response type: {other:?}")),
140 ),
Alice Wang15f6d082023-08-25 09:11:07 +0000141 }
142}