xref: /aosp_15_r20/system/keymint/hal/src/keymint.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1 // Copyright 2022, 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 //! KeyMint HAL device implementation.
16 
17 use crate::binder;
18 use crate::hal::{
19     failed_conversion, keymint, keymint::IKeyMintOperation::IKeyMintOperation,
20     secureclock::TimeStampToken::TimeStampToken, Innto, TryInnto,
21 };
22 use crate::{ChannelHalService, SerializedChannel};
23 use kmr_wire::{keymint::KeyParam, AsCborValue, *};
24 use log::warn;
25 use std::ffi::CString;
26 use std::{
27     ops::DerefMut,
28     sync::{Arc, Mutex, MutexGuard, RwLock},
29 };
30 
31 /// Maximum overhead size from CBOR serialization of operation messages.
32 ///
33 /// A serialized `FinishRequest` includes the following additional bytes over and
34 /// above the size of the input (at most):
35 /// -    1: array wrapper (0x86)
36 ///   -  9: int (0x1b + u64) [op_handle]
37 ///   -  1: array wrapper (0x81) [input]
38 ///      -  9: input data length
39 ///      - XX:  input data
40 ///   -  1: array wrapper (0x81) [signature]
41 ///      - 5: signature data length
42 ///      - 132: signature data (P-521 point)
43 ///   -  1: array wrapper (0x81) [auth_token]
44 ///      -  9: int (0x1b + u64) [challenge]
45 ///      -  9: int (0x1b + u64) [user_id]
46 ///      -  9: int (0x1b + u64) [authenticator_id]
47 ///      -  9: int (0x1b + u64) [authenticator_type]
48 ///      -  1: array wrapper (0x81)[timestamp]
49 ///         -  9: int (0x1b + u64) [user_id]
50 ///      -  2: bstr header [mac]
51 ///      - 32: bstr [mac]
52 ///   -  1: array wrapper (0x81) [timestamp_token]
53 ///      -  1: array wrapper [TimeStampToken]
54 ///         -  9: int (0x1b + u64) [challenge]
55 ///         -  1: array wrapper (0x81)[timestamp]
56 ///            -  9: int (0x1b + u64) [user_id]
57 ///         -  2: bstr header [mac]
58 ///         - 32: bstr [mac]
59 ///   -  1: array wrapper (0x81) [confirmation_token]
60 ///      -  2: bstr header [confirmation token]
61 ///      - 32: bstr [confirmation token (HMAC-SHA256)]
62 ///
63 /// Add some leeway in case encodings change.
64 pub const MAX_CBOR_OVERHEAD: usize = 350;
65 
66 /// IKeyMintDevice implementation which converts all method invocations to serialized
67 /// requests that are sent down the associated channel.
68 pub struct Device<T: SerializedChannel + 'static> {
69     channel: Arc<Mutex<T>>,
70 }
71 
72 impl<T: SerializedChannel + 'static> Device<T> {
73     /// Construct a new instance that uses the provided channel.
new(channel: Arc<Mutex<T>>) -> Self74     pub fn new(channel: Arc<Mutex<T>>) -> Self {
75         Self { channel }
76     }
77 
78     /// Create a new instance wrapped in a proxy object.
new_as_binder( channel: Arc<Mutex<T>>, ) -> binder::Strong<dyn keymint::IKeyMintDevice::IKeyMintDevice>79     pub fn new_as_binder(
80         channel: Arc<Mutex<T>>,
81     ) -> binder::Strong<dyn keymint::IKeyMintDevice::IKeyMintDevice> {
82         keymint::IKeyMintDevice::BnKeyMintDevice::new_binder(
83             Self::new(channel),
84             binder::BinderFeatures::default(),
85         )
86     }
87 }
88 
89 impl<T: SerializedChannel> ChannelHalService<T> for Device<T> {
channel(&self) -> MutexGuard<T>90     fn channel(&self) -> MutexGuard<T> {
91         self.channel.lock().unwrap()
92     }
93 }
94 
95 impl<T: SerializedChannel> binder::Interface for Device<T> {}
96 
97 impl<T: SerializedChannel> keymint::IKeyMintDevice::IKeyMintDevice for Device<T> {
getHardwareInfo(&self) -> binder::Result<keymint::KeyMintHardwareInfo::KeyMintHardwareInfo>98     fn getHardwareInfo(&self) -> binder::Result<keymint::KeyMintHardwareInfo::KeyMintHardwareInfo> {
99         let rsp: GetHardwareInfoResponse = self.execute(GetHardwareInfoRequest {})?;
100         Ok(rsp.ret.innto())
101     }
addRngEntropy(&self, data: &[u8]) -> binder::Result<()>102     fn addRngEntropy(&self, data: &[u8]) -> binder::Result<()> {
103         let _rsp: AddRngEntropyResponse =
104             self.execute(AddRngEntropyRequest { data: data.to_vec() })?;
105         Ok(())
106     }
generateKey( &self, keyParams: &[keymint::KeyParameter::KeyParameter], attestationKey: Option<&keymint::AttestationKey::AttestationKey>, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>107     fn generateKey(
108         &self,
109         keyParams: &[keymint::KeyParameter::KeyParameter],
110         attestationKey: Option<&keymint::AttestationKey::AttestationKey>,
111     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
112         let rsp: GenerateKeyResponse = self.execute(GenerateKeyRequest {
113             key_params: keyParams
114                 .iter()
115                 .filter_map(|p| p.try_innto().transpose())
116                 .collect::<Result<Vec<KeyParam>, _>>()
117                 .map_err(failed_conversion)?,
118             attestation_key: match attestationKey {
119                 None => None,
120                 Some(k) => Some(k.clone().try_innto().map_err(failed_conversion)?),
121             },
122         })?;
123         Ok(rsp.ret.innto())
124     }
importKey( &self, keyParams: &[keymint::KeyParameter::KeyParameter], keyFormat: keymint::KeyFormat::KeyFormat, keyData: &[u8], attestationKey: Option<&keymint::AttestationKey::AttestationKey>, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>125     fn importKey(
126         &self,
127         keyParams: &[keymint::KeyParameter::KeyParameter],
128         keyFormat: keymint::KeyFormat::KeyFormat,
129         keyData: &[u8],
130         attestationKey: Option<&keymint::AttestationKey::AttestationKey>,
131     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
132         let rsp: ImportKeyResponse = self.execute(ImportKeyRequest {
133             key_params: keyParams
134                 .iter()
135                 .filter_map(|p| p.try_innto().transpose())
136                 .collect::<Result<Vec<KeyParam>, _>>()
137                 .map_err(failed_conversion)?,
138             key_format: keyFormat.try_innto().map_err(failed_conversion)?,
139             key_data: keyData.to_vec(),
140             attestation_key: match attestationKey {
141                 None => None,
142                 Some(k) => Some(k.clone().try_innto().map_err(failed_conversion)?),
143             },
144         })?;
145         Ok(rsp.ret.innto())
146     }
importWrappedKey( &self, wrappedKeyData: &[u8], wrappingKeyBlob: &[u8], maskingKey: &[u8], unwrappingParams: &[keymint::KeyParameter::KeyParameter], passwordSid: i64, biometricSid: i64, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>147     fn importWrappedKey(
148         &self,
149         wrappedKeyData: &[u8],
150         wrappingKeyBlob: &[u8],
151         maskingKey: &[u8],
152         unwrappingParams: &[keymint::KeyParameter::KeyParameter],
153         passwordSid: i64,
154         biometricSid: i64,
155     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
156         let rsp: ImportWrappedKeyResponse = self.execute(ImportWrappedKeyRequest {
157             wrapped_key_data: wrappedKeyData.to_vec(),
158             wrapping_key_blob: wrappingKeyBlob.to_vec(),
159             masking_key: maskingKey.to_vec(),
160             unwrapping_params: unwrappingParams
161                 .iter()
162                 .filter_map(|p| p.try_innto().transpose())
163                 .collect::<Result<Vec<KeyParam>, _>>()
164                 .map_err(failed_conversion)?,
165             password_sid: passwordSid,
166             biometric_sid: biometricSid,
167         })?;
168         Ok(rsp.ret.innto())
169     }
upgradeKey( &self, keyBlobToUpgrade: &[u8], upgradeParams: &[keymint::KeyParameter::KeyParameter], ) -> binder::Result<Vec<u8>>170     fn upgradeKey(
171         &self,
172         keyBlobToUpgrade: &[u8],
173         upgradeParams: &[keymint::KeyParameter::KeyParameter],
174     ) -> binder::Result<Vec<u8>> {
175         let rsp: UpgradeKeyResponse = self.execute(UpgradeKeyRequest {
176             key_blob_to_upgrade: keyBlobToUpgrade.to_vec(),
177             upgrade_params: upgradeParams
178                 .iter()
179                 .filter_map(|p| p.try_innto().transpose())
180                 .collect::<Result<Vec<KeyParam>, _>>()
181                 .map_err(failed_conversion)?,
182         })?;
183         Ok(rsp.ret)
184     }
deleteKey(&self, keyBlob: &[u8]) -> binder::Result<()>185     fn deleteKey(&self, keyBlob: &[u8]) -> binder::Result<()> {
186         let _rsp: DeleteKeyResponse =
187             self.execute(DeleteKeyRequest { key_blob: keyBlob.to_vec() })?;
188         Ok(())
189     }
deleteAllKeys(&self) -> binder::Result<()>190     fn deleteAllKeys(&self) -> binder::Result<()> {
191         let _rsp: DeleteAllKeysResponse = self.execute(DeleteAllKeysRequest {})?;
192         Ok(())
193     }
destroyAttestationIds(&self) -> binder::Result<()>194     fn destroyAttestationIds(&self) -> binder::Result<()> {
195         let _rsp: DestroyAttestationIdsResponse = self.execute(DestroyAttestationIdsRequest {})?;
196         Ok(())
197     }
begin( &self, purpose: keymint::KeyPurpose::KeyPurpose, keyBlob: &[u8], params: &[keymint::KeyParameter::KeyParameter], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, ) -> binder::Result<keymint::BeginResult::BeginResult>198     fn begin(
199         &self,
200         purpose: keymint::KeyPurpose::KeyPurpose,
201         keyBlob: &[u8],
202         params: &[keymint::KeyParameter::KeyParameter],
203         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
204     ) -> binder::Result<keymint::BeginResult::BeginResult> {
205         let rsp: BeginResponse = self.execute(BeginRequest {
206             purpose: purpose.try_innto().map_err(failed_conversion)?,
207             key_blob: keyBlob.to_vec(),
208             params: params
209                 .iter()
210                 .filter_map(|p| p.try_innto().transpose())
211                 .collect::<Result<Vec<KeyParam>, _>>()
212                 .map_err(failed_conversion)?,
213             auth_token: match authToken {
214                 None => None,
215                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
216             },
217         })?;
218         // The `begin()` method is a special case.
219         // - Internally, the in-progress operation is identified by an opaque handle value.
220         // - Externally, the in-progress operation is represented as an `IKeyMintOperation` Binder
221         //   object.
222         // The `WireOperation` struct contains the former, and acts as the latter.
223         let op = Operation::new_as_binder(self.channel.clone(), rsp.ret.op_handle);
224         Ok(keymint::BeginResult::BeginResult {
225             challenge: rsp.ret.challenge,
226             params: rsp.ret.params.innto(),
227             operation: Some(op),
228         })
229     }
deviceLocked( &self, _passwordOnly: bool, _timestampToken: Option<&TimeStampToken>, ) -> binder::Result<()>230     fn deviceLocked(
231         &self,
232         _passwordOnly: bool,
233         _timestampToken: Option<&TimeStampToken>,
234     ) -> binder::Result<()> {
235         // This method is deprecated and unused, so just fail with error UNIMPLEMENTED.
236         warn!("Deprecated method devicedLocked() was called");
237         Err(binder::Status::new_service_specific_error(
238             keymint::ErrorCode::ErrorCode::UNIMPLEMENTED.0,
239             Some(&CString::new("Deprecated method deviceLocked() is not implemented").unwrap()),
240         ))
241     }
earlyBootEnded(&self) -> binder::Result<()>242     fn earlyBootEnded(&self) -> binder::Result<()> {
243         let _rsp: EarlyBootEndedResponse = self.execute(EarlyBootEndedRequest {})?;
244         Ok(())
245     }
convertStorageKeyToEphemeral(&self, storageKeyBlob: &[u8]) -> binder::Result<Vec<u8>>246     fn convertStorageKeyToEphemeral(&self, storageKeyBlob: &[u8]) -> binder::Result<Vec<u8>> {
247         let rsp: ConvertStorageKeyToEphemeralResponse =
248             self.execute(ConvertStorageKeyToEphemeralRequest {
249                 storage_key_blob: storageKeyBlob.to_vec(),
250             })?;
251         Ok(rsp.ret)
252     }
getKeyCharacteristics( &self, keyBlob: &[u8], appId: &[u8], appData: &[u8], ) -> binder::Result<Vec<keymint::KeyCharacteristics::KeyCharacteristics>>253     fn getKeyCharacteristics(
254         &self,
255         keyBlob: &[u8],
256         appId: &[u8],
257         appData: &[u8],
258     ) -> binder::Result<Vec<keymint::KeyCharacteristics::KeyCharacteristics>> {
259         let rsp: GetKeyCharacteristicsResponse = self.execute(GetKeyCharacteristicsRequest {
260             key_blob: keyBlob.to_vec(),
261             app_id: appId.to_vec(),
262             app_data: appData.to_vec(),
263         })?;
264         Ok(rsp.ret.innto())
265     }
266     #[cfg(feature = "hal_v2")]
getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]>267     fn getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]> {
268         let rsp: GetRootOfTrustChallengeResponse =
269             self.execute(GetRootOfTrustChallengeRequest {})?;
270         Ok(rsp.ret)
271     }
272     #[cfg(feature = "hal_v2")]
getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>>273     fn getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>> {
274         let rsp: GetRootOfTrustResponse =
275             self.execute(GetRootOfTrustRequest { challenge: *challenge })?;
276         Ok(rsp.ret)
277     }
278     #[cfg(feature = "hal_v2")]
sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()>279     fn sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()> {
280         let _rsp: SendRootOfTrustResponse =
281             self.execute(SendRootOfTrustRequest { root_of_trust: root_of_trust.to_vec() })?;
282         Ok(())
283     }
284     #[cfg(feature = "hal_v4")]
setAdditionalAttestationInfo( &self, info: &[keymint::KeyParameter::KeyParameter], ) -> binder::Result<()>285     fn setAdditionalAttestationInfo(
286         &self,
287         info: &[keymint::KeyParameter::KeyParameter],
288     ) -> binder::Result<()> {
289         let _rsp: SetAdditionalAttestationInfoResponse =
290             self.execute(SetAdditionalAttestationInfoRequest {
291                 info: info
292                     .iter()
293                     .filter_map(|p| p.try_innto().transpose())
294                     .collect::<Result<Vec<KeyParam>, _>>()
295                     .map_err(failed_conversion)?,
296             })?;
297         Ok(())
298     }
299 }
300 
301 /// Representation of an in-progress KeyMint operation on a `SerializedChannel`.
302 #[derive(Debug)]
303 struct Operation<T: SerializedChannel + 'static> {
304     channel: Arc<Mutex<T>>,
305     op_handle: RwLock<Option<i64>>,
306 }
307 
308 impl<T: SerializedChannel + 'static> Drop for Operation<T> {
drop(&mut self)309     fn drop(&mut self) {
310         // Ensure that the TA is kept up-to-date by calling `abort()`, but ignore the result.
311         let _ = self.abort();
312     }
313 }
314 
315 impl<T: SerializedChannel> ChannelHalService<T> for Operation<T> {
channel(&self) -> MutexGuard<T>316     fn channel(&self) -> MutexGuard<T> {
317         self.channel.lock().unwrap()
318     }
319 
320     /// Execute the given request as part of the operation.  If the request fails, the operation is
321     /// invalidated (and any future requests for the operation will fail).
execute<R, S>(&self, req: R) -> binder::Result<S> where R: AsCborValue + Code<KeyMintOperation>, S: AsCborValue + Code<KeyMintOperation>,322     fn execute<R, S>(&self, req: R) -> binder::Result<S>
323     where
324         R: AsCborValue + Code<KeyMintOperation>,
325         S: AsCborValue + Code<KeyMintOperation>,
326     {
327         let result = super::channel_execute(self.channel().deref_mut(), req);
328         if result.is_err() {
329             // Any failed method on an operation terminates the operation.
330             self.invalidate();
331         }
332         result
333     }
334 }
335 
336 impl<T: SerializedChannel> binder::Interface for Operation<T> {}
337 
338 impl<T: SerializedChannel + 'static> Operation<T> {
339     /// Create a new `Operation` wrapped in a proxy object.
new_as_binder( channel: Arc<Mutex<T>>, op_handle: i64, ) -> binder::Strong<dyn keymint::IKeyMintOperation::IKeyMintOperation>340     fn new_as_binder(
341         channel: Arc<Mutex<T>>,
342         op_handle: i64,
343     ) -> binder::Strong<dyn keymint::IKeyMintOperation::IKeyMintOperation> {
344         let op = Self { channel, op_handle: RwLock::new(Some(op_handle)) };
345         keymint::IKeyMintOperation::BnKeyMintOperation::new_binder(
346             op,
347             binder::BinderFeatures::default(),
348         )
349     }
350 }
351 
352 impl<T: SerializedChannel> Operation<T> {
353     // Maximum size allowed for the operation data.
354     const MAX_DATA_SIZE: usize = T::MAX_SIZE - MAX_CBOR_OVERHEAD;
355 
356     /// Invalidate the operation.
invalidate(&self)357     fn invalidate(&self) {
358         *self.op_handle.write().unwrap() = None;
359     }
360 
361     /// Retrieve the operation handle, if not already failed.
validate_handle(&self) -> binder::Result<i64>362     fn validate_handle(&self) -> binder::Result<i64> {
363         self.op_handle.read().unwrap().ok_or_else(|| {
364             binder::Status::new_service_specific_error(
365                 keymint::ErrorCode::ErrorCode::INVALID_OPERATION_HANDLE.0,
366                 Some(&CString::new("Operation handle not valid").unwrap()),
367             )
368         })
369     }
370 }
371 
372 /// Implement the `IKeyMintOperation` interface for a [`Operation`].  Each method invocation is
373 /// serialized into a request message that is sent over the `Operation`'s channel, and a
374 /// corresponding response message is read.  This response message is deserialized back into the
375 /// method's output value(s).
376 impl<T: SerializedChannel + 'static> keymint::IKeyMintOperation::IKeyMintOperation
377     for Operation<T>
378 {
updateAad( &self, mut input: &[u8], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timeStampToken: Option<&TimeStampToken>, ) -> binder::Result<()>379     fn updateAad(
380         &self,
381         mut input: &[u8],
382         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
383         timeStampToken: Option<&TimeStampToken>,
384     ) -> binder::Result<()> {
385         let req_template = UpdateAadRequest {
386             op_handle: self.validate_handle()?,
387             input: vec![],
388             auth_token: match authToken {
389                 None => None,
390                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
391             },
392             timestamp_token: timeStampToken.map(|t| t.clone().innto()),
393         };
394         while !input.is_empty() {
395             let mut req = req_template.clone();
396             let batch_len = core::cmp::min(Self::MAX_DATA_SIZE, input.len());
397             req.input = input[..batch_len].to_vec();
398             input = &input[batch_len..];
399             let _rsp: UpdateAadResponse = self.execute(req).inspect_err(|_| {
400                 // Any failure invalidates the operation
401                 self.invalidate();
402             })?;
403         }
404         Ok(())
405     }
update( &self, mut input: &[u8], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timeStampToken: Option<&TimeStampToken>, ) -> binder::Result<Vec<u8>>406     fn update(
407         &self,
408         mut input: &[u8],
409         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
410         timeStampToken: Option<&TimeStampToken>,
411     ) -> binder::Result<Vec<u8>> {
412         let req_template = UpdateRequest {
413             op_handle: self.validate_handle()?,
414             input: input.to_vec(),
415             auth_token: match authToken {
416                 None => None,
417                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
418             },
419             timestamp_token: timeStampToken.map(|t| t.clone().innto()),
420         };
421         let mut output = vec![];
422         while !input.is_empty() {
423             let mut req = req_template.clone();
424             let batch_len = core::cmp::min(Self::MAX_DATA_SIZE, input.len());
425             req.input = input[..batch_len].to_vec();
426             input = &input[batch_len..];
427             let rsp: UpdateResponse = self.execute(req).inspect_err(|_| {
428                 self.invalidate();
429             })?;
430             output.extend_from_slice(&rsp.ret);
431         }
432         Ok(output)
433     }
finish( &self, input: Option<&[u8]>, signature: Option<&[u8]>, authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timestampToken: Option<&TimeStampToken>, confirmationToken: Option<&[u8]>, ) -> binder::Result<Vec<u8>>434     fn finish(
435         &self,
436         input: Option<&[u8]>,
437         signature: Option<&[u8]>,
438         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
439         timestampToken: Option<&TimeStampToken>,
440         confirmationToken: Option<&[u8]>,
441     ) -> binder::Result<Vec<u8>> {
442         let op_handle = self.validate_handle()?;
443         let auth_token = match authToken {
444             None => None,
445             Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
446         };
447         let timestamp_token = timestampToken.map(|t| t.clone().innto());
448         let confirmation_token = confirmationToken.map(|v| v.to_vec());
449 
450         let mut output = vec![];
451         let result: binder::Result<FinishResponse> = if let Some(mut input) = input {
452             let MAX_DATA_SIZE = Self::MAX_DATA_SIZE;
453             while input.len() > MAX_DATA_SIZE {
454                 let req = UpdateRequest {
455                     op_handle,
456                     input: input[..MAX_DATA_SIZE].to_vec(),
457                     auth_token: auth_token.clone(),
458                     timestamp_token: timestamp_token.clone(),
459                 };
460                 input = &input[MAX_DATA_SIZE..];
461                 let rsp: UpdateResponse = self.execute(req).inspect_err(|_| {
462                     self.invalidate();
463                 })?;
464                 output.extend_from_slice(&rsp.ret);
465             }
466 
467             self.execute(FinishRequest {
468                 op_handle,
469                 input: Some(input.to_vec()),
470                 signature: signature.map(|v| v.to_vec()),
471                 auth_token,
472                 timestamp_token,
473                 confirmation_token,
474             })
475         } else {
476             self.execute(FinishRequest {
477                 op_handle,
478                 input: None,
479                 signature: signature.map(|v| v.to_vec()),
480                 auth_token,
481                 timestamp_token,
482                 confirmation_token,
483             })
484         };
485         // Finish always invalidates the operation.
486         self.invalidate();
487         result.map(|rsp| {
488             output.extend_from_slice(&rsp.ret);
489             output
490         })
491     }
abort(&self) -> binder::Result<()>492     fn abort(&self) -> binder::Result<()> {
493         let result: binder::Result<AbortResponse> =
494             self.execute(AbortRequest { op_handle: self.validate_handle()? });
495         // Abort always invalidates the operation.
496         self.invalidate();
497         let _ = result?;
498         Ok(())
499     }
500 }
501