xref: /aosp_15_r20/system/keymint/common/src/crypto/hmac.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker 
15*9860b763SAndroid Build Coastguard Worker //! Functionality related to HMAC signing/verification.
16*9860b763SAndroid Build Coastguard Worker 
17*9860b763SAndroid Build Coastguard Worker use crate::{km_err, try_to_vec, Error};
18*9860b763SAndroid Build Coastguard Worker use alloc::vec::Vec;
19*9860b763SAndroid Build Coastguard Worker use kmr_wire::KeySizeInBits;
20*9860b763SAndroid Build Coastguard Worker use zeroize::ZeroizeOnDrop;
21*9860b763SAndroid Build Coastguard Worker 
22*9860b763SAndroid Build Coastguard Worker /// Minimum size of an HMAC key in bits.
23*9860b763SAndroid Build Coastguard Worker pub const MIN_KEY_SIZE_BITS: usize = 64;
24*9860b763SAndroid Build Coastguard Worker 
25*9860b763SAndroid Build Coastguard Worker /// Maximum size of a StrongBox HMAC key in bits.
26*9860b763SAndroid Build Coastguard Worker pub const MAX_STRONGBOX_KEY_SIZE_BITS: usize = 512;
27*9860b763SAndroid Build Coastguard Worker 
28*9860b763SAndroid Build Coastguard Worker /// Maximum size of a HMAC key in bits.
29*9860b763SAndroid Build Coastguard Worker pub const MAX_KEY_SIZE_BITS: usize = 1024;
30*9860b763SAndroid Build Coastguard Worker 
31*9860b763SAndroid Build Coastguard Worker /// An HMAC key.
32*9860b763SAndroid Build Coastguard Worker #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
33*9860b763SAndroid Build Coastguard Worker pub struct Key(pub Vec<u8>);
34*9860b763SAndroid Build Coastguard Worker 
valid_size(key_size: KeySizeInBits, max_size_bits: usize) -> Result<(), Error>35*9860b763SAndroid Build Coastguard Worker fn valid_size(key_size: KeySizeInBits, max_size_bits: usize) -> Result<(), Error> {
36*9860b763SAndroid Build Coastguard Worker     if key_size.0 % 8 != 0 {
37*9860b763SAndroid Build Coastguard Worker         Err(km_err!(UnsupportedKeySize, "key size {} bits not a multiple of 8", key_size.0))
38*9860b763SAndroid Build Coastguard Worker     } else if !(MIN_KEY_SIZE_BITS..=max_size_bits).contains(&(key_size.0 as usize)) {
39*9860b763SAndroid Build Coastguard Worker         Err(km_err!(UnsupportedKeySize, "unsupported KEY_SIZE {} bits for HMAC", key_size.0))
40*9860b763SAndroid Build Coastguard Worker     } else {
41*9860b763SAndroid Build Coastguard Worker         Ok(())
42*9860b763SAndroid Build Coastguard Worker     }
43*9860b763SAndroid Build Coastguard Worker }
44*9860b763SAndroid Build Coastguard Worker 
45*9860b763SAndroid Build Coastguard Worker /// Check that the size of an HMAC key is within the allowed size for the KeyMint HAL.
valid_hal_size(key_size: KeySizeInBits) -> Result<(), Error>46*9860b763SAndroid Build Coastguard Worker pub fn valid_hal_size(key_size: KeySizeInBits) -> Result<(), Error> {
47*9860b763SAndroid Build Coastguard Worker     valid_size(key_size, MAX_KEY_SIZE_BITS)
48*9860b763SAndroid Build Coastguard Worker }
49*9860b763SAndroid Build Coastguard Worker 
50*9860b763SAndroid Build Coastguard Worker /// Check that the size of an HMAC key is within the allowed size for a StrongBox implementation.
valid_strongbox_hal_size(key_size: KeySizeInBits) -> Result<(), Error>51*9860b763SAndroid Build Coastguard Worker pub fn valid_strongbox_hal_size(key_size: KeySizeInBits) -> Result<(), Error> {
52*9860b763SAndroid Build Coastguard Worker     valid_size(key_size, MAX_STRONGBOX_KEY_SIZE_BITS)
53*9860b763SAndroid Build Coastguard Worker }
54*9860b763SAndroid Build Coastguard Worker 
55*9860b763SAndroid Build Coastguard Worker impl Key {
56*9860b763SAndroid Build Coastguard Worker     /// Create a new HMAC key from data.
new(data: Vec<u8>) -> Key57*9860b763SAndroid Build Coastguard Worker     pub fn new(data: Vec<u8>) -> Key {
58*9860b763SAndroid Build Coastguard Worker         Key(data)
59*9860b763SAndroid Build Coastguard Worker     }
60*9860b763SAndroid Build Coastguard Worker 
61*9860b763SAndroid Build Coastguard Worker     /// Create a new HMAC key from data.
new_from(data: &[u8]) -> Result<Key, Error>62*9860b763SAndroid Build Coastguard Worker     pub fn new_from(data: &[u8]) -> Result<Key, Error> {
63*9860b763SAndroid Build Coastguard Worker         Ok(Key::new(try_to_vec(data)?))
64*9860b763SAndroid Build Coastguard Worker     }
65*9860b763SAndroid Build Coastguard Worker 
66*9860b763SAndroid Build Coastguard Worker     /// Indicate the size of the key in bits.
size(&self) -> KeySizeInBits67*9860b763SAndroid Build Coastguard Worker     pub fn size(&self) -> KeySizeInBits {
68*9860b763SAndroid Build Coastguard Worker         KeySizeInBits((self.0.len() * 8) as u32)
69*9860b763SAndroid Build Coastguard Worker     }
70*9860b763SAndroid Build Coastguard Worker }
71