blob: 6bce53526450aeda85b0722cd7497709db145582 [file] [log] [blame]
Orlando Arbildoe6827812022-11-02 17:21:17 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16//! Trusty implementation of StorageKeyWrapper trait.
17use alloc::vec::Vec;
18use hwwsk;
19use kmr_common::{
David Drysdale7166ff62022-12-16 12:27:23 +000020 crypto,
21 crypto::{aes, Aes, KeyMaterial, OpaqueKeyMaterial, OpaqueOr},
22 get_bool_tag_value, get_opt_tag_value, get_tag_value, km_err, vec_try, vec_try_with_capacity,
23 Error,
Orlando Arbildoe6827812022-11-02 17:21:17 +000024};
David Drysdale7166ff62022-12-16 12:27:23 +000025use kmr_crypto_boring::aes::BoringAes;
Orlando Arbildoe6827812022-11-02 17:21:17 +000026use kmr_ta::device::StorageKeyWrapper;
David Drysdale7166ff62022-12-16 12:27:23 +000027use kmr_wire::{keymint, keymint::ErrorCode, KeySizeInBits};
28use log::warn;
Orlando Arbildoe6827812022-11-02 17:21:17 +000029use tipc::Handle;
30use trusty_std::ffi::CStr;
31
David Drysdale64702102022-12-14 12:23:16 +000032/// TIPC port used for communication with the `hwwsk` service.
Orlando Arbildoe6827812022-11-02 17:21:17 +000033const HWWSK_PORT: &'static [u8] = b"com.android.trusty.hwwsk\0";
34
David Drysdale7166ff62022-12-16 12:27:23 +000035/// Create a session for `hwwsk` communication.
36fn hwwsk_session() -> Result<Handle, Error> {
37 let port = CStr::from_bytes_with_nul(HWWSK_PORT).expect("HWWSK_PORT was not null terminated");
38 Handle::connect(port)
39 .map_err(|e| km_err!(SecureHwCommunicationFailed, "failed to connect to hwwsk: {:?}", e))
40}
41
42/// Storage key wrapper implementation for Trusty.
Orlando Arbildoe6827812022-11-02 17:21:17 +000043pub struct TrustyStorageKeyWrapper;
44
45impl StorageKeyWrapper for TrustyStorageKeyWrapper {
46 fn ephemeral_wrap(&self, key_material: &KeyMaterial) -> Result<Vec<u8>, Error> {
David Drysdale7166ff62022-12-16 12:27:23 +000047 let wrapped_key = match key_material {
48 KeyMaterial::Aes(OpaqueOr::Opaque(key)) => key,
49 _ => {
50 return Err(km_err!(
51 UnsupportedAlgorithm,
52 "only opaque AES storage keys are supported"
53 ))
54 }
Orlando Arbildoe6827812022-11-02 17:21:17 +000055 };
David Drysdale7166ff62022-12-16 12:27:23 +000056 let key = &wrapped_key.0;
57 let session = hwwsk_session()?;
Orlando Arbildoe6827812022-11-02 17:21:17 +000058 let buf = &mut [0u8; hwwsk::HWWSK_MAX_MSG_SIZE as usize];
David Drysdale7166ff62022-12-16 12:27:23 +000059 let wrapped_key_buffer = hwwsk::export_key(&session, buf, key).map_err(|e| {
60 km_err!(SecureHwCommunicationFailed, "hwwsk failed to wrap key: {:?}", e)
61 })?;
Orlando Arbildoe6827812022-11-02 17:21:17 +000062 let mut wrapped_key = vec_try_with_capacity!(wrapped_key_buffer.len())?;
63 wrapped_key.extend_from_slice(wrapped_key_buffer);
64 Ok(wrapped_key)
65 }
66}
67
David Drysdale7166ff62022-12-16 12:27:23 +000068/// Wrapper around `BoringAes` implementation that intercepts storage keys.
69pub struct TrustyAes(BoringAes);
70
71impl Default for TrustyAes {
72 fn default() -> Self {
73 Self(BoringAes)
74 }
75}
76impl TrustyAes {
77 fn create_storage_key(
78 &self,
79 key: Option<aes::Key>,
80 params: &[keymint::KeyParam],
81 ) -> Result<crypto::KeyMaterial, Error> {
82 // Storage keys should not work for normal operations. The TA code polices this by watching
83 // for `Tag::StorageKey`; also police here by rejecting keys that have a `Tag::BlockMode`
84 // attached.
85 if get_opt_tag_value!(params, BlockMode)?.is_some() {
86 return Err(km_err!(UnsupportedTag, "don't expect block mode on storage key"));
87 }
88 let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedTag)?;
89 let key_size = key_size.0 as usize;
90 let mut key_flags = hwwsk::KeyFlags::new();
91 let rollback_resistance = get_bool_tag_value!(params, RollbackResistance)?;
92 if rollback_resistance {
93 key_flags = key_flags.rollback_resistance();
94 };
95
96 let session = hwwsk_session()?;
97 let mut buf = vec_try![0; hwwsk::HWWSK_MAX_MSG_SIZE as usize]?;
98 let key_material: Option<&[u8]> = match key.as_ref() {
99 None => None,
100 Some(aes_key) => Some(match aes_key {
101 aes::Key::Aes128(key) => key,
102 aes::Key::Aes192(key) => key,
103 aes::Key::Aes256(key) => key,
104 }),
105 };
106 let mut result = match key_material {
107 None => hwwsk::generate_key(&session, &mut buf, key_size, key_flags),
108 Some(key) => hwwsk::import_key(&session, &mut buf, key_size, key_flags, key),
109 };
110 if result == Err(hwwsk::HwWskError::NotSupported) && rollback_resistance {
111 warn!("failed to generate rollback-resistant storage key, retrying without resistance");
112 key_flags = hwwsk::KeyFlags::new();
113 result = match key_material {
114 None => hwwsk::generate_key(&session, &mut buf, key_size, key_flags),
115 Some(key) => hwwsk::import_key(&session, &mut buf, key_size, key_flags, key),
116 };
117 }
118
119 let wrapped_key_buffer =
120 result.map_err(|e| km_err!(UnknownError, "hwwsk failed to create key: {:?}", e))?;
121
122 let mut wrapped_key = vec_try_with_capacity!(wrapped_key_buffer.len())?;
123 wrapped_key.extend_from_slice(wrapped_key_buffer);
124 Ok(crypto::KeyMaterial::Aes(OpaqueOr::Opaque(OpaqueKeyMaterial(wrapped_key))))
125 }
126}
127
128impl Aes for TrustyAes {
129 fn generate_key(
130 &self,
131 rng: &mut dyn crypto::Rng,
132 variant: aes::Variant,
133 params: &[keymint::KeyParam],
134 ) -> Result<crypto::KeyMaterial, Error> {
135 if !get_bool_tag_value!(params, StorageKey)? {
136 // For normal (non-storage) keys, pass on to BoringSSL implementation.
137 return self.0.generate_key(rng, variant, params);
138 }
139 self.create_storage_key(None, params)
140 }
141
142 fn import_key(
143 &self,
144 data: &[u8],
145 params: &[keymint::KeyParam],
146 ) -> Result<(crypto::KeyMaterial, KeySizeInBits), Error> {
147 if !get_bool_tag_value!(params, StorageKey)? {
148 // For normal (non-storage) keys, pass on to BoringSSL implementation.
149 return self.0.import_key(data, params);
150 }
151
152 let aes_key = aes::Key::new_from(data)?;
153 let key_size = aes_key.size();
154 Ok((self.create_storage_key(Some(aes_key), params)?, key_size))
155 }
156
157 fn begin(
158 &self,
159 key: OpaqueOr<aes::Key>,
160 mode: aes::CipherMode,
161 dir: crypto::SymmetricOperation,
162 ) -> Result<Box<dyn crypto::EmittingOperation>, Error> {
163 match key {
164 OpaqueOr::Explicit(_) => self.0.begin(key, mode, dir),
165 OpaqueOr::Opaque(_) => {
166 Err(km_err!(StorageKeyUnsupported, "attempt to use storage key"))
167 }
168 }
169 }
170
171 fn begin_aead(
172 &self,
173 key: OpaqueOr<aes::Key>,
174 mode: aes::GcmMode,
175 dir: crypto::SymmetricOperation,
176 ) -> Result<Box<dyn crypto::AadOperation>, Error> {
177 match key {
178 OpaqueOr::Explicit(_) => self.0.begin_aead(key, mode, dir),
179 OpaqueOr::Opaque(_) => {
180 Err(km_err!(StorageKeyUnsupported, "attempt to use storage key"))
181 }
182 }
183 }
184}
185
Orlando Arbildoe6827812022-11-02 17:21:17 +0000186// Not adding unit tests because we do not have a mock server on AOSP for hwwsk.