1 //! Functionality related to HMAC signing/verification.
2
3 use crate::{km_err, try_to_vec, Error};
4 use alloc::vec::Vec;
5 use kmr_wire::KeySizeInBits;
6 use zeroize::ZeroizeOnDrop;
7
8 /// Minimum size of an HMAC key in bits.
9 pub const MIN_KEY_SIZE_BITS: usize = 64;
10
11 /// Maximum size of a StrongBox HMAC key in bits.
12 pub const MAX_STRONGBOX_KEY_SIZE_BITS: usize = 512;
13
14 /// Maximum size of a HMAC key in bits.
15 pub const MAX_KEY_SIZE_BITS: usize = 1024;
16
17 /// An HMAC key.
18 #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
19 pub struct Key(pub Vec<u8>);
20
valid_size(key_size: KeySizeInBits, max_size_bits: usize) -> Result<(), Error>21 fn valid_size(key_size: KeySizeInBits, max_size_bits: usize) -> Result<(), Error> {
22 if key_size.0 % 8 != 0 {
23 Err(km_err!(UnsupportedKeySize, "key size {} bits not a multiple of 8", key_size.0))
24 } else if !(MIN_KEY_SIZE_BITS..=max_size_bits).contains(&(key_size.0 as usize)) {
25 Err(km_err!(UnsupportedKeySize, "unsupported KEY_SIZE {} bits for HMAC", key_size.0))
26 } else {
27 Ok(())
28 }
29 }
30
31 /// 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>32 pub fn valid_hal_size(key_size: KeySizeInBits) -> Result<(), Error> {
33 valid_size(key_size, MAX_KEY_SIZE_BITS)
34 }
35
36 /// 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>37 pub fn valid_strongbox_hal_size(key_size: KeySizeInBits) -> Result<(), Error> {
38 valid_size(key_size, MAX_STRONGBOX_KEY_SIZE_BITS)
39 }
40
41 impl Key {
42 /// Create a new HMAC key from data.
new(data: Vec<u8>) -> Key43 pub fn new(data: Vec<u8>) -> Key {
44 Key(data)
45 }
46
47 /// Create a new HMAC key from data.
new_from(data: &[u8]) -> Result<Key, Error>48 pub fn new_from(data: &[u8]) -> Result<Key, Error> {
49 Ok(Key::new(try_to_vec(data)?))
50 }
51
52 /// Indicate the size of the key in bits.
size(&self) -> KeySizeInBits53 pub fn size(&self) -> KeySizeInBits {
54 KeySizeInBits((self.0.len() * 8) as u32)
55 }
56 }
57