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;
23use kernel::component::Component;
24use kernel::create_capability;
25use kernel::hil::digest;
26
27#[macro_export]
28macro_rules! hmac_component_static {
29    ($A:ty, $L:expr $(,)?) => {{
30        let hmac = kernel::static_buf!(capsules_extra::hmac::HmacDriver<'static, $A, $L>);
31
32        let data_buffer = kernel::static_buf!([u8; 64]);
33        let dest_buffer = kernel::static_buf!([u8; $L]);
34
35        (hmac, data_buffer, dest_buffer)
36    };};
37}
38
39pub type HmacComponentType<H, const L: usize> = capsules_extra::hmac::HmacDriver<'static, H, L>;
40
41pub struct HmacComponent<A: 'static + digest::Digest<'static, L>, const L: usize> {
42    board_kernel: &'static kernel::Kernel,
43    driver_num: usize,
44    hmac: &'static A,
45}
46
47impl<A: 'static + digest::Digest<'static, L>, const L: usize> HmacComponent<A, L> {
48    pub fn new(
49        board_kernel: &'static kernel::Kernel,
50        driver_num: usize,
51        hmac: &'static A,
52    ) -> HmacComponent<A, L> {
53        HmacComponent {
54            board_kernel,
55            driver_num,
56            hmac,
57        }
58    }
59}
60
61impl<
62        A: kernel::hil::digest::HmacSha256
63            + digest::HmacSha384
64            + digest::HmacSha512
65            + 'static
66            + digest::Digest<'static, L>,
67        const L: usize,
68    > Component for HmacComponent<A, L>
69{
70    type StaticInput = (
71        &'static mut MaybeUninit<HmacDriver<'static, A, L>>,
72        &'static mut MaybeUninit<[u8; 64]>,
73        &'static mut MaybeUninit<[u8; L]>,
74    );
75    type Output = &'static HmacDriver<'static, A, L>;
76
77    fn finalize(self, s: Self::StaticInput) -> Self::Output {
78        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
79
80        let data_buffer = s.1.write([0; 64]);
81        let dest_buffer = s.2.write([0; L]);
82
83        let hmac = s.0.write(capsules_extra::hmac::HmacDriver::new(
84            self.hmac,
85            data_buffer,
86            dest_buffer,
87            self.board_kernel.create_grant(self.driver_num, &grant_cap),
88        ));
89
90        self.hmac.set_client(hmac);
91
92        hmac
93    }
94}
95
96#[macro_export]
97macro_rules! hmac_sha256_software_component_static {
98    ($S:ty $(,)?) => {{
99        let hmac_sha256 =
100            kernel::static_buf!(capsules_extra::hmac_sha256::HmacSha256Software<'static, $S>);
101
102        let data_buffer = kernel::static_buf!([u8; 64]);
103        let verify_buffer = kernel::static_buf!([u8; 32]);
104
105        (hmac_sha256, data_buffer, verify_buffer)
106    };};
107}
108
109pub type HmacSha256SoftwareComponentType<S> =
110    capsules_extra::hmac_sha256::HmacSha256Software<'static, S>;
111
112pub struct HmacSha256SoftwareComponent<
113    S: digest::Sha256 + digest::DigestDataHash<'static, 32> + digest::Digest<'static, 32> + 'static,
114> {
115    sha_256: &'static S,
116}
117
118impl<S: digest::Sha256 + digest::DigestDataHash<'static, 32> + digest::Digest<'static, 32>>
119    HmacSha256SoftwareComponent<S>
120{
121    pub fn new(sha_256: &'static S) -> HmacSha256SoftwareComponent<S> {
122        HmacSha256SoftwareComponent { sha_256 }
123    }
124}
125
126impl<
127        S: digest::Sha256
128            + digest::DigestDataHash<'static, 32>
129            + digest::Digest<'static, 32>
130            + 'static,
131    > Component for HmacSha256SoftwareComponent<S>
132{
133    type StaticInput = (
134        &'static mut MaybeUninit<capsules_extra::hmac_sha256::HmacSha256Software<'static, S>>,
135        &'static mut MaybeUninit<[u8; 64]>,
136        &'static mut MaybeUninit<[u8; 32]>,
137    );
138    type Output = &'static capsules_extra::hmac_sha256::HmacSha256Software<'static, S>;
139
140    fn finalize(self, s: Self::StaticInput) -> Self::Output {
141        let data_buffer = s.1.write([0; 64]);
142        let verify_buffer = s.2.write([0; 32]);
143
144        let hmac_sha256_sw =
145            s.0.write(capsules_extra::hmac_sha256::HmacSha256Software::new(
146                self.sha_256,
147                data_buffer,
148                verify_buffer,
149            ));
150
151        kernel::hil::digest::Digest::set_client(self.sha_256, hmac_sha256_sw);
152
153        hmac_sha256_sw
154    }
155}