components/
aes.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 various AES utilities.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let aes_driver_device = components::aes::AesVirtualComponent::new(aes_mux).finalize(
11//!     components::aes_virtual_component_static!(nrf52840::aes::AesECB<'static>),
12//! );
13//!
14//! let aes = components::aes::AesDriverComponent::new(
15//!     board_kernel,
16//!     capsules_extra::symmetric_encryption::aes::DRIVER_NUM,
17//!     aes_driver_device,
18//! )
19//! .finalize(components::aes_driver_component_static!(
20//!     capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<
21//!         'static,
22//!         nrf52840::aes::AesECB<'static>,
23//!     >
24//! ));
25//! ```
26
27use core::mem::MaybeUninit;
28use kernel::capabilities;
29use kernel::component::Component;
30use kernel::create_capability;
31use kernel::hil;
32use kernel::hil::symmetric_encryption::{
33    AES128Ctr, AES128, AES128CBC, AES128CCM, AES128ECB, AES128GCM,
34};
35
36const CRYPT_SIZE: usize = 7 * hil::symmetric_encryption::AES128_BLOCK_SIZE;
37
38#[macro_export]
39macro_rules! aes_virtual_component_static {
40    ($A:ty $(,)?) => {{
41        const CRYPT_SIZE: usize = 7 * kernel::hil::symmetric_encryption::AES128_BLOCK_SIZE;
42        let virtual_aes = kernel::static_buf!(
43            capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<'static, $A>
44        );
45        let crypt_buf = kernel::static_buf!([u8; CRYPT_SIZE]);
46
47        (virtual_aes, crypt_buf)
48    };};
49}
50
51#[macro_export]
52macro_rules! aes_driver_component_static {
53    ($A:ty $(,)?) => {{
54        const CRYPT_SIZE: usize = 7 * kernel::hil::symmetric_encryption::AES128_BLOCK_SIZE;
55        let aes_src_buffer = kernel::static_buf!([u8; 16]);
56        let aes_dst_buffer = kernel::static_buf!([u8; CRYPT_SIZE]);
57        let aes_driver =
58            kernel::static_buf!(capsules_extra::symmetric_encryption::aes::AesDriver<'static, $A>);
59
60        (aes_driver, aes_src_buffer, aes_dst_buffer)
61    };};
62}
63
64pub struct AesVirtualComponent<A: 'static + AES128<'static> + AES128Ctr + AES128CBC + AES128ECB> {
65    aes_mux: &'static capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM<'static, A>,
66}
67
68impl<A: 'static + AES128<'static> + AES128Ctr + AES128CBC + AES128ECB> AesVirtualComponent<A> {
69    pub fn new(
70        aes_mux: &'static capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM<'static, A>,
71    ) -> Self {
72        Self { aes_mux }
73    }
74}
75
76impl<A: 'static + AES128<'static> + AES128Ctr + AES128CBC + AES128ECB> Component
77    for AesVirtualComponent<A>
78{
79    type StaticInput = (
80        &'static mut MaybeUninit<
81            capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<'static, A>,
82        >,
83        &'static mut MaybeUninit<[u8; CRYPT_SIZE]>,
84    );
85    type Output =
86        &'static capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM<'static, A>;
87
88    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
89        let crypt_buf = static_buffer.1.write([0; CRYPT_SIZE]);
90        let aes_ccm = static_buffer.0.write(
91            capsules_core::virtualizers::virtual_aes_ccm::VirtualAES128CCM::new(
92                self.aes_mux,
93                crypt_buf,
94            ),
95        );
96        aes_ccm.setup();
97
98        aes_ccm
99    }
100}
101
102pub struct AesDriverComponent<A: AES128<'static> + AES128CCM<'static> + 'static> {
103    board_kernel: &'static kernel::Kernel,
104    driver_num: usize,
105    aes: &'static A,
106}
107
108impl<A: AES128<'static> + AES128Ctr + AES128CBC + AES128ECB + AES128CCM<'static>>
109    AesDriverComponent<A>
110{
111    pub fn new(
112        board_kernel: &'static kernel::Kernel,
113        driver_num: usize,
114        aes: &'static A,
115    ) -> AesDriverComponent<A> {
116        AesDriverComponent {
117            board_kernel,
118            driver_num,
119            aes,
120        }
121    }
122}
123
124impl<
125        A: AES128<'static>
126            + AES128Ctr
127            + AES128CBC
128            + AES128ECB
129            + AES128CCM<'static>
130            + AES128GCM<'static>,
131    > Component for AesDriverComponent<A>
132{
133    type StaticInput = (
134        &'static mut MaybeUninit<capsules_extra::symmetric_encryption::aes::AesDriver<'static, A>>,
135        &'static mut MaybeUninit<[u8; 16]>,
136        &'static mut MaybeUninit<[u8; CRYPT_SIZE]>,
137    );
138    type Output = &'static capsules_extra::symmetric_encryption::aes::AesDriver<'static, A>;
139
140    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
141        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
142        let aes_src_buf = static_buffer.1.write([0; 16]);
143        let aes_dst_buf = static_buffer.2.write([0; CRYPT_SIZE]);
144
145        let aes_driver =
146            static_buffer
147                .0
148                .write(capsules_extra::symmetric_encryption::aes::AesDriver::new(
149                    self.aes,
150                    aes_src_buf,
151                    aes_dst_buf,
152                    self.board_kernel.create_grant(self.driver_num, &grant_cap),
153                ));
154
155        hil::symmetric_encryption::AES128CCM::set_client(self.aes, aes_driver);
156        hil::symmetric_encryption::AES128::set_client(self.aes, aes_driver);
157
158        aes_driver
159    }
160}