Skip to main content

components/
hmac.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Components for collections of HMACs.
6//!
7//! Usage
8//! -----
9//! ```rust
10//!    let hmac = components::hmac::HmacComponent::new(
11//!        board_kernel,
12//!        chip.hmac,
13//!    )
14//!    .finalize(components::hmac_component_static!(
15//!        lowrisc::hmac::Hmac,
16//!        32
17//!    ));
18//! ```
19
20use capsules_extra::hmac::HmacDriver;
21use core::mem::MaybeUninit;
22use kernel::capabilities::MemoryAllocationCapability;
23use kernel::component::Component;
24use kernel::hil::digest;
25
26#[macro_export]
27macro_rules! hmac_component_static {
28    ($A:ty, $L:expr $(,)?) => {{
29        let hmac = kernel::static_buf!(capsules_extra::hmac::HmacDriver<'static, $A, $L>);
30
31        let data_buffer = kernel::static_buf!([u8; 64]);
32        let dest_buffer = kernel::static_buf!([u8; $L]);
33
34        (hmac, data_buffer, dest_buffer)
35    }};
36}
37
38pub type HmacComponentType<H, const L: usize> = capsules_extra::hmac::HmacDriver<'static, H, L>;
39
40pub struct HmacComponent<
41    A: 'static + digest::Digest<'static, L>,
42    const L: usize,
43    CAP: MemoryAllocationCapability + 'static,
44> {
45    board_kernel: &'static kernel::Kernel,
46    driver_num: usize,
47    hmac: &'static A,
48    mem_cap: CAP,
49}
50
51impl<
52    A: 'static + digest::Digest<'static, L>,
53    const L: usize,
54    CAP: MemoryAllocationCapability + 'static,
55> HmacComponent<A, L, CAP>
56{
57    pub fn new(
58        board_kernel: &'static kernel::Kernel,
59        driver_num: usize,
60        hmac: &'static A,
61        mem_cap: CAP,
62    ) -> HmacComponent<A, L, CAP> {
63        HmacComponent {
64            board_kernel,
65            driver_num,
66            hmac,
67            mem_cap,
68        }
69    }
70}
71
72impl<
73    A: kernel::hil::digest::HmacSha256
74        + digest::HmacSha384
75        + digest::HmacSha512
76        + digest::HmacMd5
77        + digest::HmacSha224
78        + digest::HmacSha1
79        + 'static
80        + digest::Digest<'static, L>,
81    const L: usize,
82    CAP: MemoryAllocationCapability + 'static,
83> Component for HmacComponent<A, L, CAP>
84{
85    type StaticInput = (
86        &'static mut MaybeUninit<HmacDriver<'static, A, L>>,
87        &'static mut MaybeUninit<[u8; 64]>,
88        &'static mut MaybeUninit<[u8; L]>,
89    );
90    type Output = &'static HmacDriver<'static, A, L>;
91
92    fn finalize(self, s: Self::StaticInput) -> Self::Output {
93        let data_buffer = s.1.write([0; 64]);
94        let dest_buffer = s.2.write([0; L]);
95
96        let hmac = s.0.write(capsules_extra::hmac::HmacDriver::new(
97            self.hmac,
98            data_buffer,
99            dest_buffer,
100            self.board_kernel
101                .create_grant(self.driver_num, &self.mem_cap),
102        ));
103
104        self.hmac.set_client(hmac);
105
106        hmac
107    }
108}
109
110#[macro_export]
111macro_rules! hmac_sha256_software_component_static {
112    ($S:ty $(,)?) => {{
113        let hmac_sha256 =
114            kernel::static_buf!(capsules_extra::hmac_sha256::HmacSha256Software<'static, $S>);
115
116        let data_buffer = kernel::static_buf!([u8; 64]);
117        let verify_buffer = kernel::static_buf!([u8; 32]);
118
119        (hmac_sha256, data_buffer, verify_buffer)
120    }};
121}
122
123pub type HmacSha256SoftwareComponentType<S> =
124    capsules_extra::hmac_sha256::HmacSha256Software<'static, S>;
125
126pub struct HmacSha256SoftwareComponent<
127    S: digest::Sha256 + digest::DigestDataHash<'static, 32> + digest::Digest<'static, 32> + 'static,
128> {
129    sha_256: &'static S,
130}
131
132impl<S: digest::Sha256 + digest::DigestDataHash<'static, 32> + digest::Digest<'static, 32>>
133    HmacSha256SoftwareComponent<S>
134{
135    pub fn new(sha_256: &'static S) -> HmacSha256SoftwareComponent<S> {
136        HmacSha256SoftwareComponent { sha_256 }
137    }
138}
139
140impl<
141    S: digest::Sha256 + digest::DigestDataHash<'static, 32> + digest::Digest<'static, 32> + 'static,
142> Component for HmacSha256SoftwareComponent<S>
143{
144    type StaticInput = (
145        &'static mut MaybeUninit<capsules_extra::hmac_sha256::HmacSha256Software<'static, S>>,
146        &'static mut MaybeUninit<[u8; 64]>,
147        &'static mut MaybeUninit<[u8; 32]>,
148    );
149    type Output = &'static capsules_extra::hmac_sha256::HmacSha256Software<'static, S>;
150
151    fn finalize(self, s: Self::StaticInput) -> Self::Output {
152        let data_buffer = s.1.write([0; 64]);
153        let verify_buffer = s.2.write([0; 32]);
154
155        let hmac_sha256_sw =
156            s.0.write(capsules_extra::hmac_sha256::HmacSha256Software::new(
157                self.sha_256,
158                data_buffer,
159                verify_buffer,
160            ));
161
162        kernel::hil::digest::Digest::set_client(self.sha_256, hmac_sha256_sw);
163
164        hmac_sha256_sw
165    }
166}