xref: /aosp_15_r20/system/authgraph/hal/src/lib.rs (revision 4185b0660fbe514985fdcf75410317caad8afad1)
1*4185b066SAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*4185b066SAndroid Build Coastguard Worker //
3*4185b066SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*4185b066SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*4185b066SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*4185b066SAndroid Build Coastguard Worker //
7*4185b066SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
8*4185b066SAndroid Build Coastguard Worker //
9*4185b066SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*4185b066SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*4185b066SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*4185b066SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*4185b066SAndroid Build Coastguard Worker // limitations under the License.
14*4185b066SAndroid Build Coastguard Worker //
15*4185b066SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
16*4185b066SAndroid Build Coastguard Worker 
17*4185b066SAndroid Build Coastguard Worker //! Crate that holds common code for an AuthGraph HAL service.
18*4185b066SAndroid Build Coastguard Worker 
19*4185b066SAndroid Build Coastguard Worker use android_hardware_security_authgraph::aidl::android::hardware::security::authgraph::{
20*4185b066SAndroid Build Coastguard Worker     Arc::Arc, Identity::Identity, KeInitResult::KeInitResult, Key::Key, PlainPubKey::PlainPubKey,
21*4185b066SAndroid Build Coastguard Worker     PubKey::PubKey, SessionIdSignature::SessionIdSignature, SessionInfo::SessionInfo,
22*4185b066SAndroid Build Coastguard Worker     SessionInitiationInfo::SessionInitiationInfo,
23*4185b066SAndroid Build Coastguard Worker };
24*4185b066SAndroid Build Coastguard Worker use authgraph_wire as wire;
25*4185b066SAndroid Build Coastguard Worker use log::warn;
26*4185b066SAndroid Build Coastguard Worker 
27*4185b066SAndroid Build Coastguard Worker pub mod channel;
28*4185b066SAndroid Build Coastguard Worker pub mod service;
29*4185b066SAndroid Build Coastguard Worker 
30*4185b066SAndroid Build Coastguard Worker // Neither the AIDL types nor the `authgraph_core` types are local to this crate, which means that
31*4185b066SAndroid Build Coastguard Worker // Rust's orphan rule means we cannot implement the standard conversion traits.  So instead define
32*4185b066SAndroid Build Coastguard Worker // our own equivalent conversion traits that are local, and for which we're allowed to provide
33*4185b066SAndroid Build Coastguard Worker // implementations.  Give them an odd name to avoid confusion with the standard traits.
34*4185b066SAndroid Build Coastguard Worker 
35*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `From` trait, with a different name to avoid clashes.
36*4185b066SAndroid Build Coastguard Worker pub trait Fromm<T>: Sized {
37*4185b066SAndroid Build Coastguard Worker     /// Convert `val` into type `Self`.
fromm(val: T) -> Self38*4185b066SAndroid Build Coastguard Worker     fn fromm(val: T) -> Self;
39*4185b066SAndroid Build Coastguard Worker }
40*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `TryFrom` trait, with a different name to avoid clashes.
41*4185b066SAndroid Build Coastguard Worker pub trait TryFromm<T>: Sized {
42*4185b066SAndroid Build Coastguard Worker     /// Error type emitted on conversion failure.
43*4185b066SAndroid Build Coastguard Worker     type Error;
44*4185b066SAndroid Build Coastguard Worker     /// Try to convert `val` into type `Self`.
try_fromm(val: T) -> Result<Self, Self::Error>45*4185b066SAndroid Build Coastguard Worker     fn try_fromm(val: T) -> Result<Self, Self::Error>;
46*4185b066SAndroid Build Coastguard Worker }
47*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `Into` trait, with a different name to avoid clashes.
48*4185b066SAndroid Build Coastguard Worker pub trait Innto<T> {
49*4185b066SAndroid Build Coastguard Worker     /// Convert `self` into type `T`.
innto(self) -> T50*4185b066SAndroid Build Coastguard Worker     fn innto(self) -> T;
51*4185b066SAndroid Build Coastguard Worker }
52*4185b066SAndroid Build Coastguard Worker /// Local equivalent of `TryInto` trait, with a different name to avoid clashes.
53*4185b066SAndroid Build Coastguard Worker pub trait TryInnto<T> {
54*4185b066SAndroid Build Coastguard Worker     /// Error type emitted on conversion failure.
55*4185b066SAndroid Build Coastguard Worker     type Error;
56*4185b066SAndroid Build Coastguard Worker     /// Try to convert `self` into type `T`.
try_innto(self) -> Result<T, Self::Error>57*4185b066SAndroid Build Coastguard Worker     fn try_innto(self) -> Result<T, Self::Error>;
58*4185b066SAndroid Build Coastguard Worker }
59*4185b066SAndroid Build Coastguard Worker /// Blanket implementation of `Innto` from `Fromm`
60*4185b066SAndroid Build Coastguard Worker impl<T, U> Innto<U> for T
61*4185b066SAndroid Build Coastguard Worker where
62*4185b066SAndroid Build Coastguard Worker     U: Fromm<T>,
63*4185b066SAndroid Build Coastguard Worker {
innto(self) -> U64*4185b066SAndroid Build Coastguard Worker     fn innto(self) -> U {
65*4185b066SAndroid Build Coastguard Worker         U::fromm(self)
66*4185b066SAndroid Build Coastguard Worker     }
67*4185b066SAndroid Build Coastguard Worker }
68*4185b066SAndroid Build Coastguard Worker /// Blanket implementation of `TryInnto` from `TryFromm`
69*4185b066SAndroid Build Coastguard Worker impl<T, U> TryInnto<U> for T
70*4185b066SAndroid Build Coastguard Worker where
71*4185b066SAndroid Build Coastguard Worker     U: TryFromm<T>,
72*4185b066SAndroid Build Coastguard Worker {
73*4185b066SAndroid Build Coastguard Worker     type Error = U::Error;
try_innto(self) -> Result<U, Self::Error>74*4185b066SAndroid Build Coastguard Worker     fn try_innto(self) -> Result<U, Self::Error> {
75*4185b066SAndroid Build Coastguard Worker         U::try_fromm(self)
76*4185b066SAndroid Build Coastguard Worker     }
77*4185b066SAndroid Build Coastguard Worker }
78*4185b066SAndroid Build Coastguard Worker 
79*4185b066SAndroid Build Coastguard Worker // Conversions from internal types to HAL-defined types.
80*4185b066SAndroid Build Coastguard Worker 
81*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::SessionInitiationInfo> for SessionInitiationInfo {
fromm(val: wire::SessionInitiationInfo) -> Self82*4185b066SAndroid Build Coastguard Worker     fn fromm(val: wire::SessionInitiationInfo) -> Self {
83*4185b066SAndroid Build Coastguard Worker         Self {
84*4185b066SAndroid Build Coastguard Worker             key: val.ke_key.innto(),
85*4185b066SAndroid Build Coastguard Worker             identity: Identity { identity: val.identity },
86*4185b066SAndroid Build Coastguard Worker             nonce: val.nonce,
87*4185b066SAndroid Build Coastguard Worker             version: val.version,
88*4185b066SAndroid Build Coastguard Worker         }
89*4185b066SAndroid Build Coastguard Worker     }
90*4185b066SAndroid Build Coastguard Worker }
91*4185b066SAndroid Build Coastguard Worker 
92*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::Key> for Key {
fromm(val: wire::Key) -> Self93*4185b066SAndroid Build Coastguard Worker     fn fromm(val: wire::Key) -> Self {
94*4185b066SAndroid Build Coastguard Worker         Self {
95*4185b066SAndroid Build Coastguard Worker             pubKey: val
96*4185b066SAndroid Build Coastguard Worker                 .pub_key
97*4185b066SAndroid Build Coastguard Worker                 .map(|pub_key| PubKey::PlainKey(PlainPubKey { plainPubKey: pub_key })),
98*4185b066SAndroid Build Coastguard Worker             arcFromPBK: val.arc_from_pbk.map(|arc| Arc { arc }),
99*4185b066SAndroid Build Coastguard Worker         }
100*4185b066SAndroid Build Coastguard Worker     }
101*4185b066SAndroid Build Coastguard Worker }
102*4185b066SAndroid Build Coastguard Worker 
103*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::KeInitResult> for KeInitResult {
fromm(val: wire::KeInitResult) -> Self104*4185b066SAndroid Build Coastguard Worker     fn fromm(val: wire::KeInitResult) -> Self {
105*4185b066SAndroid Build Coastguard Worker         Self {
106*4185b066SAndroid Build Coastguard Worker             sessionInitiationInfo: val.session_init_info.innto(),
107*4185b066SAndroid Build Coastguard Worker             sessionInfo: val.session_info.innto(),
108*4185b066SAndroid Build Coastguard Worker         }
109*4185b066SAndroid Build Coastguard Worker     }
110*4185b066SAndroid Build Coastguard Worker }
111*4185b066SAndroid Build Coastguard Worker 
112*4185b066SAndroid Build Coastguard Worker impl Fromm<wire::SessionInfo> for SessionInfo {
fromm(val: wire::SessionInfo) -> Self113*4185b066SAndroid Build Coastguard Worker     fn fromm(val: wire::SessionInfo) -> Self {
114*4185b066SAndroid Build Coastguard Worker         Self {
115*4185b066SAndroid Build Coastguard Worker             sharedKeys: val.shared_keys.map(|arc| Arc { arc }),
116*4185b066SAndroid Build Coastguard Worker             sessionId: val.session_id,
117*4185b066SAndroid Build Coastguard Worker             signature: SessionIdSignature { signature: val.session_id_signature },
118*4185b066SAndroid Build Coastguard Worker         }
119*4185b066SAndroid Build Coastguard Worker     }
120*4185b066SAndroid Build Coastguard Worker }
121*4185b066SAndroid Build Coastguard Worker 
122*4185b066SAndroid Build Coastguard Worker // Conversions from HAL-defined types to internal types.
123*4185b066SAndroid Build Coastguard Worker 
124*4185b066SAndroid Build Coastguard Worker impl TryFromm<Key> for wire::Key {
125*4185b066SAndroid Build Coastguard Worker     type Error = binder::Status;
try_fromm(aidl: Key) -> Result<Self, Self::Error>126*4185b066SAndroid Build Coastguard Worker     fn try_fromm(aidl: Key) -> Result<Self, Self::Error> {
127*4185b066SAndroid Build Coastguard Worker         let pub_key = match aidl.pubKey {
128*4185b066SAndroid Build Coastguard Worker             None => None,
129*4185b066SAndroid Build Coastguard Worker             Some(PubKey::PlainKey(k)) => Some(k.plainPubKey),
130*4185b066SAndroid Build Coastguard Worker             Some(PubKey::SignedKey(_)) => return Err(arg_err("expect plain pubkey")),
131*4185b066SAndroid Build Coastguard Worker         };
132*4185b066SAndroid Build Coastguard Worker         Ok(Self { pub_key, arc_from_pbk: aidl.arcFromPBK.map(|a| a.arc) })
133*4185b066SAndroid Build Coastguard Worker     }
134*4185b066SAndroid Build Coastguard Worker }
135*4185b066SAndroid Build Coastguard Worker 
136*4185b066SAndroid Build Coastguard Worker /// Generate a binder illegal argument error with the given message.
arg_err(msg: &str) -> binder::Status137*4185b066SAndroid Build Coastguard Worker fn arg_err(msg: &str) -> binder::Status {
138*4185b066SAndroid Build Coastguard Worker     binder::Status::new_exception(
139*4185b066SAndroid Build Coastguard Worker         binder::ExceptionCode::ILLEGAL_ARGUMENT,
140*4185b066SAndroid Build Coastguard Worker         Some(&std::ffi::CString::new(msg).unwrap()),
141*4185b066SAndroid Build Coastguard Worker     )
142*4185b066SAndroid Build Coastguard Worker }
143*4185b066SAndroid Build Coastguard Worker 
144*4185b066SAndroid Build Coastguard Worker /// Convert a [`wire::ErrorCore`] into a binder error.
errcode_to_binder(err: wire::ErrorCode) -> binder::Status145*4185b066SAndroid Build Coastguard Worker pub fn errcode_to_binder(err: wire::ErrorCode) -> binder::Status {
146*4185b066SAndroid Build Coastguard Worker     warn!("operation failed: {err:?}");
147*4185b066SAndroid Build Coastguard Worker     // Translate the internal errors for `Unimplemented` and `InternalError` to their counterparts
148*4185b066SAndroid Build Coastguard Worker     // in binder errors to have uniformity in the Android HAL layer
149*4185b066SAndroid Build Coastguard Worker     match err {
150*4185b066SAndroid Build Coastguard Worker         wire::ErrorCode::Unimplemented => {
151*4185b066SAndroid Build Coastguard Worker             binder::Status::new_exception(binder::ExceptionCode::UNSUPPORTED_OPERATION, None)
152*4185b066SAndroid Build Coastguard Worker         }
153*4185b066SAndroid Build Coastguard Worker         wire::ErrorCode::InternalError => {
154*4185b066SAndroid Build Coastguard Worker             binder::Status::new_exception(binder::ExceptionCode::SERVICE_SPECIFIC, None)
155*4185b066SAndroid Build Coastguard Worker         }
156*4185b066SAndroid Build Coastguard Worker         _ => binder::Status::new_service_specific_error(err as i32, None),
157*4185b066SAndroid Build Coastguard Worker     }
158*4185b066SAndroid Build Coastguard Worker }
159