tink_mac/
aes_cmac_key_manager.rs1use tink_core::{utils::wrap_err, TinkError};
20use tink_proto::prost::Message;
21
22pub const CMAC_KEY_VERSION: u32 = 0;
24pub const CMAC_TYPE_URL: &str = "type.googleapis.com/google.crypto.tink.AesCmacKey";
26
27#[derive(Default)]
29pub(crate) struct AesCmacKeyManager;
30
31impl tink_core::registry::KeyManager for AesCmacKeyManager {
32 fn primitive(&self, serialized_key: &[u8]) -> Result<tink_core::Primitive, TinkError> {
35 if serialized_key.is_empty() {
36 return Err("AesCmacKeyManager: invalid key".into());
37 }
38
39 let key = tink_proto::AesCmacKey::decode(serialized_key)
40 .map_err(|e| wrap_err("AesCmacKeyManager: decode failed", e))?;
41 let tag_size = validate_key(&key)?;
42 match crate::subtle::AesCmac::new(&key.key_value, tag_size) {
43 Ok(p) => Ok(tink_core::Primitive::Mac(Box::new(p))),
44 Err(e) => Err(wrap_err(
45 "AesCmacKeyManager: cannot create new primitive",
46 e,
47 )),
48 }
49 }
50
51 fn new_key(&self, serialized_key_format: &[u8]) -> Result<Vec<u8>, TinkError> {
54 if serialized_key_format.is_empty() {
55 return Err("AesCmacKeyManager: invalid key format".into());
56 }
57 let key_format = tink_proto::AesCmacKeyFormat::decode(serialized_key_format)
58 .map_err(|_| "AesCmacKeyManager: invalid key format")?;
59 validate_key_format(&key_format)
60 .map_err(|e| wrap_err("AesCmacKeyManager: invalid key format", e))?;
61 let key_value = tink_core::subtle::random::get_random_bytes(key_format.key_size as usize);
62 let mut sk = Vec::new();
63 tink_proto::AesCmacKey {
64 version: CMAC_KEY_VERSION,
65 params: key_format.params,
66 key_value,
67 }
68 .encode(&mut sk)
69 .map_err(|e| wrap_err("AesCmacKeyManager: failed to encode new key", e))?;
70 Ok(sk)
71 }
72
73 fn type_url(&self) -> &'static str {
74 CMAC_TYPE_URL
75 }
76
77 fn key_material_type(&self) -> tink_proto::key_data::KeyMaterialType {
78 tink_proto::key_data::KeyMaterialType::Symmetric
79 }
80}
81
82fn validate_key(key: &tink_proto::AesCmacKey) -> Result<usize, TinkError> {
85 tink_core::keyset::validate_key_version(key.version, CMAC_KEY_VERSION)
86 .map_err(|e| wrap_err("AesCmacKeyManager: invalid version", e))?;
87 let key_size = key.key_value.len();
88 match &key.params {
89 None => Err("AesCmacKeyManager: missing AES-CMAC params".into()),
90 Some(params) => {
91 crate::subtle::validate_cmac_params(key_size, params.tag_size as usize)?;
92 Ok(params.tag_size as usize)
93 }
94 }
95}
96
97fn validate_key_format(format: &tink_proto::AesCmacKeyFormat) -> Result<(), TinkError> {
99 match &format.params {
100 None => Err("missing AES-CMAC params".into()),
101 Some(params) => {
102 crate::subtle::validate_cmac_params(format.key_size as usize, params.tag_size as usize)
103 }
104 }
105}