1 use crate::rng;
2 use binder::Interface;
3 use fingerguard_api::aidl::IFingerGuard::IFingerGuard;
4 use kmr_common::crypto::Rng;
5 use log::error;
6 use storage::{OpenMode, Port, Session};
7 use tipc::TipcError;
8 use trusty_sys::Error;
9
10 #[derive(Hash, Eq, PartialEq, Debug)]
11 struct SensorStateIndex {
12 sensor_id: i32,
13 user_id: i32,
14 }
15
16 impl SensorStateIndex {
authenticator_id_file_name(&self) -> String17 fn authenticator_id_file_name(&self) -> String {
18 format!("s{}.u{}.authenticator_id", self.sensor_id, self.user_id)
19 }
20 }
21
deserialize_authenticator_id(buffer: &[u8]) -> Result<i64, TipcError>22 fn deserialize_authenticator_id(buffer: &[u8]) -> Result<i64, TipcError> {
23 if let Ok(buffer) = buffer.try_into() {
24 return Ok(i64::from_ne_bytes(buffer));
25 }
26 error!("failed to deserialize the auth id from buffer: expected size 8, got {}", buffer.len());
27 Err(TipcError::SystemError(Error::BadState))
28 }
29
30 /// Implements the `IFingerGuard` AIDL interface for other Trusty apps to call.
31 pub struct FingerGuardService {}
32
33 impl FingerGuardService {
new() -> Self34 pub fn new() -> Self {
35 Self {}
36 }
37
read_authenticator_id(&self, sensor_id: i32, user_id: i32) -> Result<i64, TipcError>38 fn read_authenticator_id(&self, sensor_id: i32, user_id: i32) -> Result<i64, TipcError> {
39 let index = SensorStateIndex { sensor_id, user_id };
40 let file_name = index.authenticator_id_file_name();
41 let mut session = Session::new(Port::TamperDetect, false).map_err(|e| {
42 error!("failed to create storage session: {:?}", e);
43 TipcError::SystemError(Error::BadState)
44 })?;
45 let secure_file = session.open_file(&file_name, OpenMode::Create).map_err(|e| {
46 error!("failed to open file {}: {:?}", file_name, e);
47 TipcError::SystemError(Error::BadState)
48 })?;
49 let file_size = session.get_size(&secure_file).map_err(|e| {
50 error!("failed to get file size for {}: {:?}", file_name, e);
51 TipcError::SystemError(Error::BadState)
52 })?;
53 let mut buffer = vec![0; file_size];
54 let content = session.read_all(&secure_file, buffer.as_mut_slice()).map_err(|e| {
55 error!("failed to read file bytes for {}: {:?}", file_name, e);
56 TipcError::SystemError(Error::BadState)
57 })?;
58 // By the HAL definition, When no authenticator id was ever generated, return 0.
59 if content.len() == 0 {
60 return Ok(0_i64);
61 }
62 deserialize_authenticator_id(&content)
63 }
64
generate_authenticator_id(&self, sensor_id: i32, user_id: i32) -> Result<i64, TipcError>65 fn generate_authenticator_id(&self, sensor_id: i32, user_id: i32) -> Result<i64, TipcError> {
66 let mut rng = rng::TrustyRng::default();
67 let mut buffer = [0u8; 8];
68 rng.fill_bytes(&mut buffer[..]);
69 let authenticator_id = deserialize_authenticator_id(&buffer)?;
70 let index = SensorStateIndex { sensor_id, user_id };
71 let file_name = index.authenticator_id_file_name();
72 let mut session = Session::new(Port::TamperDetect, true).map_err(|e| {
73 error!("failed to create storage session: {:?}", e);
74 TipcError::SystemError(Error::BadState)
75 })?;
76 let mut secure_file = session.open_file(&file_name, OpenMode::Create).map_err(|e| {
77 error!("failed to open file {}: {:?}", file_name, e);
78 TipcError::SystemError(Error::BadState)
79 })?;
80 session.write_all(&mut secure_file, &buffer).map_err(|e| {
81 error!("failed to write the serialized auth id to {}: {:?}", file_name, e);
82 TipcError::SystemError(Error::BadState)
83 })?;
84 Ok(authenticator_id)
85 }
86 }
87
88 impl Interface for FingerGuardService {}
89
90 impl IFingerGuard for FingerGuardService {
getAuthenticatorId(&self, sensor_id: i32, user_id: i32) -> binder::Result<i64>91 fn getAuthenticatorId(&self, sensor_id: i32, user_id: i32) -> binder::Result<i64> {
92 FingerGuardService::read_authenticator_id(&self, sensor_id, user_id)
93 .map_err(|_| binder::StatusCode::FAILED_TRANSACTION.into())
94 }
newAuthenticatorId(&self, sensor_id: i32, user_id: i32) -> binder::Result<i64>95 fn newAuthenticatorId(&self, sensor_id: i32, user_id: i32) -> binder::Result<i64> {
96 FingerGuardService::generate_authenticator_id(&self, sensor_id, user_id)
97 .map_err(|_| binder::StatusCode::FAILED_TRANSACTION.into())
98 }
99 }
100