components/
atecc508a.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 the ATECC508A CryptoAuthentication Device.
6//!
7//! Usage
8//! -----
9//! ```rust
10//!     let atecc508a =
11//!         Atecc508aComponent::new(mux_i2c, 0x60).finalize(components::atecc508a_component_static!());
12//! ```
13
14use capsules_core::virtualizers::virtual_i2c::{I2CDevice, MuxI2C};
15use capsules_extra::atecc508a::Atecc508a;
16use core::mem::MaybeUninit;
17use kernel::component::Component;
18use kernel::hil::i2c;
19
20// Setup static space for the objects.
21#[macro_export]
22macro_rules! atecc508a_component_static {
23    ($I:ty $(,)?) => {{
24        let i2c_device =
25            kernel::static_buf!(capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>);
26        let i2c_buffer = kernel::static_buf!([u8; 140]);
27        let entropy_buffer = kernel::static_buf!([u8; 32]);
28        let digest_buffer = kernel::static_buf!([u8; 64]);
29        let verify_key_buffer = kernel::static_buf!([u8; 64]);
30        let atecc508a = kernel::static_buf!(capsules_extra::atecc508a::Atecc508a<'static>);
31
32        (
33            i2c_device,
34            i2c_buffer,
35            entropy_buffer,
36            digest_buffer,
37            verify_key_buffer,
38            atecc508a,
39        )
40    };};
41}
42
43pub struct Atecc508aComponent<I: 'static + i2c::I2CMaster<'static>> {
44    i2c_mux: &'static MuxI2C<'static, I>,
45    i2c_address: u8,
46    wakeup_device: fn(),
47}
48
49impl<I: 'static + i2c::I2CMaster<'static>> Atecc508aComponent<I> {
50    pub fn new(i2c: &'static MuxI2C<'static, I>, i2c_address: u8, wakeup_device: fn()) -> Self {
51        Atecc508aComponent {
52            i2c_mux: i2c,
53            i2c_address,
54            wakeup_device,
55        }
56    }
57}
58
59impl<I: 'static + i2c::I2CMaster<'static>> Component for Atecc508aComponent<I> {
60    type StaticInput = (
61        &'static mut MaybeUninit<I2CDevice<'static, I>>,
62        &'static mut MaybeUninit<[u8; 140]>,
63        &'static mut MaybeUninit<[u8; 32]>,
64        &'static mut MaybeUninit<[u8; 64]>,
65        &'static mut MaybeUninit<[u8; 64]>,
66        &'static mut MaybeUninit<Atecc508a<'static>>,
67    );
68    type Output = &'static Atecc508a<'static>;
69
70    fn finalize(self, s: Self::StaticInput) -> Self::Output {
71        let atecc508a_i2c = s.0.write(I2CDevice::new(self.i2c_mux, self.i2c_address));
72
73        let i2c_buffer = s.1.write([0; 140]);
74        let entropy_buffer = s.2.write([0; 32]);
75        let digest_buffer = s.3.write([0; 64]);
76        let verify_key_buffer = s.4.write([0; 64]);
77
78        let atecc508a = s.5.write(Atecc508a::new(
79            atecc508a_i2c,
80            i2c_buffer,
81            entropy_buffer,
82            digest_buffer,
83            self.wakeup_device,
84        ));
85        atecc508a.set_public_key(Some(verify_key_buffer));
86
87        atecc508a_i2c.set_client(atecc508a);
88        atecc508a
89    }
90}