1use crate::crypto::{self, CanonAeadKey, CanonAeadKeyRef, Crypto, Kdf};
19use crate::error::{Error, ErrorCode};
20use crate::tlv::{FromTLV, ToTLV};
21use crate::utils::init::{init, Init};
22#[cfg(feature = "groups")]
23use crate::utils::storage::Vec;
24
25#[cfg(feature = "groups")]
26pub const GROUP_MAX_EPOCH_KEYS: usize = 3;
27
28#[cfg(feature = "groups")]
30#[derive(Debug, Clone, Default, FromTLV, ToTLV)]
31#[cfg_attr(feature = "defmt", derive(defmt::Format))]
32pub struct GroupEpochKeyEntry {
33 pub epoch_key: CanonAeadKey,
34 pub epoch_start_time: u64,
35}
36
37#[cfg(feature = "groups")]
39#[derive(Debug, Clone, Default, FromTLV, ToTLV)]
40#[cfg_attr(feature = "defmt", derive(defmt::Format))]
41pub struct GroupKeySet {
42 pub group_key_set_id: u16,
43 pub group_key_security_policy: u8,
44 pub epoch_keys: Vec<GroupEpochKeyEntry, GROUP_MAX_EPOCH_KEYS>,
45}
46
47#[derive(Debug, Default, FromTLV, ToTLV)]
48#[cfg_attr(feature = "defmt", derive(defmt::Format))]
49pub struct KeySet {
50 pub epoch_key: CanonAeadKey,
51 pub op_key: CanonAeadKey,
52}
53
54impl KeySet {
55 pub const fn new() -> Self {
56 Self {
57 epoch_key: crypto::AEAD_KEY_ZEROED,
58 op_key: crypto::AEAD_KEY_ZEROED,
59 }
60 }
61
62 pub fn init() -> impl Init<Self> {
63 init!(Self {
64 epoch_key <- CanonAeadKey::init(),
65 op_key <- CanonAeadKey::init(),
66 })
67 }
68
69 pub fn update<C: Crypto>(
70 &mut self,
71 crypto: C,
72 epoch_key: CanonAeadKeyRef<'_>,
73 compressed_fabric_id: &u64,
74 ) -> Result<(), Error> {
75 const GRP_KEY_INFO: &[u8] = &[
76 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x20, 0x76, 0x31, 0x2e, 0x30,
77 ];
78
79 crypto
80 .kdf()?
81 .expand(
82 &compressed_fabric_id.to_be_bytes(),
83 epoch_key,
84 GRP_KEY_INFO,
85 &mut self.op_key,
86 )
87 .map_err(|_| ErrorCode::InvalidData)?;
88
89 self.epoch_key.load(epoch_key);
90
91 Ok(())
92 }
93
94 pub fn op_key(&self) -> CanonAeadKeyRef<'_> {
95 self.op_key.reference()
96 }
97
98 pub fn epoch_key(&self) -> CanonAeadKeyRef<'_> {
99 self.epoch_key.reference()
100 }
101}