| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| use alloc::vec::Vec; |
| use core::cell::RefCell; |
| use kmr_common::crypto; |
| use kmr_crypto_boring::{ |
| aes::BoringAes, aes_cmac::BoringAesCmac, des::BoringDes, ec::BoringEc, eq::BoringEq, |
| hmac::BoringHmac, rng::BoringRng, rsa::BoringRsa, |
| }; |
| use kmr_ta::{HardwareInfo, KeyMintTa}; |
| use log::{debug, info}; |
| use tipc::{ |
| Deserialize, Handle, Manager, PortCfg, Serialize, Serializer, Service, TipcError, Uuid, |
| }; |
| use trusty_std::alloc::TryAllocFrom; |
| |
| const KEYMINT_MAX_BUFFER_LENGTH: usize = 4096; |
| |
| struct Context { |
| _uuid: Uuid, |
| } |
| |
| struct KMMessage(Vec<u8>); |
| |
| impl Deserialize for KMMessage { |
| type Error = TipcError; |
| const MAX_SERIALIZED_SIZE: usize = KEYMINT_MAX_BUFFER_LENGTH; |
| |
| fn deserialize(bytes: &[u8], _handles: &[Handle]) -> Result<Self, TipcError> { |
| Ok(KMMessage(Vec::try_alloc_from(bytes)?)) |
| } |
| } |
| |
| impl<'s> Serialize<'s> for KMMessage { |
| fn serialize<'a: 's, S: Serializer<'s>>( |
| &'a self, |
| serializer: &mut S, |
| ) -> Result<S::Ok, S::Error> { |
| serializer.serialize_bytes(&self.0.as_slice()) |
| } |
| } |
| |
| struct KMService<'a> { |
| km_ta: RefCell<KeyMintTa<'a>>, |
| } |
| |
| impl<'a> KMService<'a> { |
| fn new( |
| hw_info: HardwareInfo, |
| imp: crypto::Implementation<'a>, |
| dev: kmr_ta::device::Implementation<'a>, |
| ) -> Self { |
| KMService { km_ta: RefCell::new(KeyMintTa::new(hw_info, imp, dev)) } |
| } |
| |
| fn process_message(&self, req_data: &[u8]) -> Vec<u8> { |
| self.km_ta.borrow_mut().process(req_data) |
| } |
| } |
| |
| impl<'a> Service for KMService<'a> { |
| type Connection = Context; |
| type Message = KMMessage; |
| |
| fn on_connect( |
| &self, |
| _port: &PortCfg, |
| _handle: &Handle, |
| peer: &Uuid, |
| ) -> Result<Option<Self::Connection>, TipcError> { |
| debug!("In keymint: on_connect. Client Uuid: {:?}.", peer); |
| Ok(Some(Context { _uuid: peer.clone() })) |
| } |
| |
| fn on_message( |
| &self, |
| _connection: &Self::Connection, |
| handle: &Handle, |
| msg: Self::Message, |
| ) -> Result<bool, TipcError> { |
| debug!("In keymint: on_message."); |
| let resp = self.process_message(&msg.0); |
| handle.send(&KMMessage(resp))?; |
| Ok(true) |
| } |
| } |
| |
| fn main() { |
| trusty_log::init(); |
| |
| info!("Hello from Keymint Rust!"); |
| |
| let hw_info = HardwareInfo { |
| version_number: 3, |
| security_level: kmr_common::wire::keymint::SecurityLevel::TrustedEnvironment, |
| impl_name: "TEE KeyMint in Rust", |
| author_name: "Google", |
| unique_id: "TEE KeyMint TA", |
| fused: false, |
| }; |
| |
| let mut rng = BoringRng::default(); |
| let clock = crypto::NoOpClock {}; |
| let imp = crypto::Implementation { |
| rng: &mut rng, |
| clock: Some(&clock), |
| compare: &BoringEq, |
| aes: &BoringAes, |
| des: &BoringDes, |
| hmac: &BoringHmac, |
| rsa: &BoringRsa, |
| ec: &BoringEc, |
| ckdf: &BoringAesCmac, |
| hkdf: &BoringHmac, |
| }; |
| |
| // TODO: replace no-ops with actual implementations |
| let dev = kmr_ta::device::Implementation { |
| keys: &kmr_ta::device::NoOpRetrieveKeyMaterial, |
| sign_info: &kmr_ta::device::NoOpRetrieveCertSigningInfo, |
| attest_ids: None, |
| sdd_mgr: None, |
| bootloader: &kmr_ta::device::BootloaderDone, |
| sk_wrapper: None, |
| //TODO: Implement TrustedUserPresence for Trusty |
| tup: &kmr_ta::device::TrustedPresenceUnsupported, |
| }; |
| |
| let service = KMService::new(hw_info, imp, dev); |
| |
| let port = PortCfg::new("com.android.trusty.keymint") |
| .expect("In keymint: could not create port config.") |
| .allow_ta_connect() |
| .allow_ns_connect(); |
| let buffer = [0u8; 4096]; |
| let manager = Manager::<_, _, 1, 1>::new(service, port, buffer) |
| .expect("In keymint: could not create service manager."); |
| manager.run_event_loop().expect("In keymint: service manager encountered an error"); |
| } |