Skip to main content

rs_matter/
group_keys.rs

1/*
2 *
3 *    Copyright (c) 2022-2026 Project CHIP Authors
4 *
5 *    Licensed under the Apache License, Version 2.0 (the "License");
6 *    you may not use this file except in compliance with the License.
7 *    You may obtain a copy of the License at
8 *
9 *        http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS,
13 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *    See the License for the specific language governing permissions and
15 *    limitations under the License.
16 */
17
18use crate::crypto::{self, CanonAeadKey, CanonAeadKeyRef, Crypto, Kdf};
19use crate::error::{Error, ErrorCode};
20use crate::tlv::{FromTLV, ToTLV};
21use crate::utils::init::{init, Init};
22use crate::utils::storage::Vec;
23
24pub const GROUP_MAX_EPOCH_KEYS: usize = 3;
25
26/// A stored group key set entry.
27#[derive(Debug, Clone, Default, FromTLV, ToTLV)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub struct GroupEpochKeyEntry {
30    pub epoch_key: CanonAeadKey,
31    pub epoch_start_time: u64,
32}
33
34/// A stored group key set entry.
35#[derive(Debug, Clone, Default, FromTLV, ToTLV)]
36#[cfg_attr(feature = "defmt", derive(defmt::Format))]
37pub struct GroupKeySet {
38    pub group_key_set_id: u16,
39    pub group_key_security_policy: u8,
40    pub epoch_keys: Vec<GroupEpochKeyEntry, GROUP_MAX_EPOCH_KEYS>,
41}
42
43#[derive(Debug, Default, FromTLV, ToTLV)]
44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
45pub struct KeySet {
46    pub epoch_key: CanonAeadKey,
47    pub op_key: CanonAeadKey,
48}
49
50impl KeySet {
51    pub const fn new() -> Self {
52        Self {
53            epoch_key: crypto::AEAD_KEY_ZEROED,
54            op_key: crypto::AEAD_KEY_ZEROED,
55        }
56    }
57
58    pub fn init() -> impl Init<Self> {
59        init!(Self {
60            epoch_key <- CanonAeadKey::init(),
61            op_key <- CanonAeadKey::init(),
62        })
63    }
64
65    pub fn update<C: Crypto>(
66        &mut self,
67        crypto: C,
68        epoch_key: CanonAeadKeyRef<'_>,
69        compressed_fabric_id: &u64,
70    ) -> Result<(), Error> {
71        const GRP_KEY_INFO: &[u8] = &[
72            0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x20, 0x76, 0x31, 0x2e, 0x30,
73        ];
74
75        crypto
76            .kdf()?
77            .expand(
78                &compressed_fabric_id.to_be_bytes(),
79                epoch_key,
80                GRP_KEY_INFO,
81                &mut self.op_key,
82            )
83            .map_err(|_| ErrorCode::InvalidData)?;
84
85        self.epoch_key.load(epoch_key);
86
87        Ok(())
88    }
89
90    pub fn op_key(&self) -> CanonAeadKeyRef<'_> {
91        self.op_key.reference()
92    }
93
94    pub fn epoch_key(&self) -> CanonAeadKeyRef<'_> {
95        self.epoch_key.reference()
96    }
97}