capsules_extra/
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 2023.
4
5//! Capsule for interfacing with the ATECC508A CryptoAuthentication Device
6//! using the I2C bus.
7//!
8//! <https://ww1.microchip.com/downloads/en/DeviceDoc/20005928A.pdf>
9//!
10//! The device requires at least 60us of the SDA pin being pulled low
11//! to power on. So before any I2C commands can be issued the SDA pin
12//! must be pulled low.
13//!
14//! The ATECC508A is shipped in an unlocked state. That is, the configuration
15//! can be changed. The ATECC508A is practically useless while it's unlocked
16//! though. Even the random number generator only returns
17//! 0xFF, 0xFF, 0x00, 0x00 when the device is unlocked.
18//!
19//! Locking the device is permanent! Once the device is locked it can not be
20//! unlocked. Be very careful about locking the configurations. In saying that
21//! the device must be locked before it can be used.
22//!
23//! Look at the `setup_and_lock_tock_config()` function for an example of
24//! setting up the device.
25
26use core::cell::Cell;
27use kernel::debug;
28use kernel::hil::i2c::{self, I2CClient, I2CDevice};
29use kernel::hil::public_key_crypto::keys;
30use kernel::hil::public_key_crypto::signature::{ClientVerify, SignatureVerify};
31use kernel::hil::{digest, entropy, entropy::Entropy32};
32use kernel::utilities::cells::{MapCell, OptionalCell, TakeCell};
33use kernel::utilities::leasable_buffer::{SubSlice, SubSliceMut, SubSliceMutImmut};
34use kernel::ErrorCode;
35
36/* Protocol + Cryptographic defines */
37const RESPONSE_COUNT_SIZE: usize = 1;
38const RESPONSE_SIGNAL_SIZE: usize = 1;
39const RESPONSE_SHA_SIZE: usize = 32;
40#[allow(dead_code)]
41const RESPONSE_INFO_SIZE: usize = 4;
42const RESPONSE_RANDOM_SIZE: usize = 32;
43const CRC_SIZE: usize = 2;
44#[allow(dead_code)]
45const CONFIG_ZONE_SIZE: usize = 128;
46#[allow(dead_code)]
47const SERIAL_NUMBER_SIZE: usize = 10;
48
49/* Protocol Indices */
50const ATRCC508A_PROTOCOL_FIELD_COMMAND: usize = 0;
51const ATRCC508A_PROTOCOL_FIELD_LENGTH: usize = 1;
52const ATRCC508A_PROTOCOL_FIELD_OPCODE: usize = 2;
53const ATRCC508A_PROTOCOL_FIELD_PARAM1: usize = 3;
54const ATRCC508A_PROTOCOL_FIELD_PARAM2: usize = 4;
55const ATRCC508A_PROTOCOL_FIELD_DATA: usize = 6;
56
57/* Protocl Sizes */
58const ATRCC508A_PROTOCOL_FIELD_SIZE_COMMAND: usize = 1;
59const ATRCC508A_PROTOCOL_FIELD_SIZE_LENGTH: usize = 1;
60const ATRCC508A_PROTOCOL_FIELD_SIZE_OPCODE: usize = 1;
61const ATRCC508A_PROTOCOL_FIELD_SIZE_PARAM1: usize = 1;
62const ATRCC508A_PROTOCOL_FIELD_SIZE_PARAM2: usize = 2;
63const ATRCC508A_PROTOCOL_FIELD_SIZE_CRC: usize = CRC_SIZE;
64
65const ZONE_CONFIG: u8 = 0x00;
66#[allow(dead_code)]
67const ZONE_OTP: u8 = 0x01;
68#[allow(dead_code)]
69const ZONE_DATA: u8 = 0x02;
70
71const ADDRESS_CONFIG_READ_BLOCK_0: u16 = 0x0000; // 00000000 00000000 // param2 (byte 0), address block bits: _ _ _ 0  0 _ _ _
72#[allow(dead_code)]
73const ADDRESS_CONFIG_READ_BLOCK_1: u16 = 0x0008; // 00000000 00001000 // param2 (byte 0), address block bits: _ _ _ 0  1 _ _ _
74const ADDRESS_CONFIG_READ_BLOCK_2: u16 = 0x0010; // 00000000 00010000 // param2 (byte 0), address block bits: _ _ _ 1  0 _ _ _
75#[allow(dead_code)]
76const ADDRESS_CONFIG_READ_BLOCK_3: u16 = 0x0018; // 00000000 00011000 // param2 (byte 0), address block bits: _ _ _ 1  1 _ _ _
77
78/* configZone EEPROM mapping */
79const CONFIG_ZONE_READ_SIZE: usize = 32;
80#[allow(dead_code)]
81const CONFIG_ZONE_SLOT_CONFIG: usize = 20;
82const CONFIG_ZONE_OTP_LOCK: usize = 86;
83const CONFIG_ZONE_LOCK_STATUS: usize = 87;
84const CONFIG_ZONE_SLOTS_LOCK0: usize = 88;
85const CONFIG_ZONE_SLOTS_LOCK1: usize = 89;
86#[allow(dead_code)]
87const CONFIG_ZONE_KEY_CONFIG: usize = 96;
88
89// COMMANDS (aka "opcodes" in the datasheet)
90#[allow(dead_code)]
91const COMMAND_OPCODE_INFO: u8 = 0x30; // Return device state information.
92const COMMAND_OPCODE_LOCK: u8 = 0x17; // Lock configuration and/or Data and OTP zones
93const COMMAND_OPCODE_RANDOM: u8 = 0x1B; // Create and return a random number (32 bytes of data)
94const COMMAND_OPCODE_READ: u8 = 0x02; // Return data at a specific zone and address.
95#[allow(dead_code)]
96const COMMAND_OPCODE_WRITE: u8 = 0x12; // Return data at a specific zone and address.
97const COMMAND_OPCODE_SHA: u8 = 0x47; // Computes a SHA-256 or HMAC/SHA digest for general purpose use by the system.
98#[allow(dead_code)]
99const COMMAND_OPCODE_GENKEY: u8 = 0x40; // Creates a key (public and/or private) and stores it in a memory key slot
100#[allow(dead_code)]
101const COMMAND_OPCODE_NONCE: u8 = 0x16; //
102#[allow(dead_code)]
103const COMMAND_OPCODE_SIGN: u8 = 0x41; // Create an ECC signature with contents of TempKey and designated key slot
104#[allow(dead_code)]
105const COMMAND_OPCODE_VERIFY: u8 = 0x45; // takes an ECDSA <R,S> signature and verifies that it is correctly generated from a given message and public key
106
107const VERIFY_MODE_EXTERNAL: u8 = 0x02; // Use an external public key for verification, pass to command as data post param2, ds pg 89
108#[allow(dead_code)]
109const VERIFY_MODE_STORED: u8 = 0b00000000; // Use an internally stored public key for verification, param2 = keyID, ds pg 89
110const VERIFY_PARAM2_KEYTYPE_ECC: u8 = 0x0004; // When verify mode external, param2 should be KeyType, ds pg 89
111#[allow(dead_code)]
112const VERIFY_PARAM2_KEYTYPE_NONECC: u8 = 0x0007; // When verify mode external, param2 should be KeyType, ds pg 89
113const NONCE_MODE_PASSTHROUGH: u8 = 0b00000011; // Operate in pass-through mode and Write TempKey with NumIn. datasheet pg 79
114
115const LOCK_MODE_ZONE_CONFIG: u8 = 0b10000000;
116const LOCK_MODE_ZONE_DATA_AND_OTP: u8 = 0b10000001;
117const LOCK_MODE_SLOT0: u8 = 0b10000010;
118
119#[allow(dead_code)]
120const RANDOM_BYTES_BLOCK_SIZE: usize = 32;
121
122const SHA_START: u8 = 0;
123const SHA_UPDATE: u8 = 1;
124const SHA_END: u8 = 2;
125
126#[allow(dead_code)]
127const SHA256_SIZE: usize = 32;
128const PUBLIC_KEY_SIZE: usize = 64;
129#[allow(dead_code)]
130const SIGNATURE_SIZE: usize = 64;
131#[allow(dead_code)]
132const BUFFER_SIZE: usize = 128;
133
134const RESPONSE_SIGNAL_INDEX: usize = RESPONSE_COUNT_SIZE;
135const ATRCC508A_SUCCESSFUL_TEMPKEY: u8 = 0x00;
136const ATRCC508A_SUCCESSFUL_VERIFY: u8 = 0x00;
137const ATRCC508A_SUCCESSFUL_LOCK: u8 = 0x00;
138
139const WORD_ADDRESS_VALUE_RESET: u8 = 0x00;
140const WORD_ADDRESS_VALUE_IDLE: u8 = 0x02;
141const WORD_ADDRESS_VALUE_COMMAND: u8 = 0x03;
142
143const ATRCC508A_PROTOCOL_OVERHEAD: usize = ATRCC508A_PROTOCOL_FIELD_SIZE_COMMAND
144    + ATRCC508A_PROTOCOL_FIELD_SIZE_LENGTH
145    + ATRCC508A_PROTOCOL_FIELD_SIZE_OPCODE
146    + ATRCC508A_PROTOCOL_FIELD_SIZE_PARAM1
147    + ATRCC508A_PROTOCOL_FIELD_SIZE_PARAM2
148    + ATRCC508A_PROTOCOL_FIELD_SIZE_CRC;
149
150#[allow(dead_code)]
151const GENKEY_MODE_PUBLIC: u8 = 0b00000000;
152const GENKEY_MODE_NEW_PRIVATE: u8 = 0b00000100;
153
154#[derive(Clone, Copy, Debug, PartialEq)]
155enum Operation {
156    Reset,
157    Ready,
158    ReadConfigZeroCommand,
159    ReadConfigZeroResult(usize),
160    ReadConfigTwoCommand,
161    ReadConfigTwoResult(usize),
162    GenerateEntropyCommand(usize),
163    GenerateEntropyResult(usize),
164    SetupConfigOne,
165    SetupConfigTwo(usize),
166    LockZoneConfig(usize),
167    LockResponse(usize),
168    CreateKeyPair(usize, u16),
169    ReadKeyPair(usize),
170    LockDataOtp(usize),
171    LockSlot0(usize),
172    StartSha(usize),
173    ShaLoad(usize),
174    ShaLoadResponse(usize),
175    ReadySha,
176    ShaRun(usize),
177    ShaEnd(usize),
178    LoadTempKeyNonce(usize),
179    LoadTempKeyCheckNonce(usize),
180    VerifySubmitData(usize),
181    CompleteVerify(usize),
182}
183
184pub struct Atecc508a<'a> {
185    buffer: TakeCell<'static, [u8]>,
186    i2c: &'a dyn I2CDevice,
187    op: Cell<Operation>,
188    op_len: Cell<usize>,
189
190    entropy_buffer: TakeCell<'static, [u8; 32]>,
191    entropy_offset: Cell<usize>,
192    entropy_client: OptionalCell<&'a dyn entropy::Client32>,
193
194    digest_client: OptionalCell<&'a dyn digest::ClientDataHash<32>>,
195    digest_buffer: TakeCell<'static, [u8; 64]>,
196    write_len: Cell<usize>,
197    remain_len: Cell<usize>,
198    hash_data: MapCell<SubSliceMutImmut<'static, u8>>,
199    digest_data: TakeCell<'static, [u8; 32]>,
200
201    secure_client: OptionalCell<&'a dyn ClientVerify<32, 64>>,
202    message_data: TakeCell<'static, [u8; 32]>,
203    signature_data: TakeCell<'static, [u8; 64]>,
204    ext_public_key: TakeCell<'static, [u8; 64]>,
205    ext_public_key_temp: TakeCell<'static, [u8; 64]>,
206    key_set_client: OptionalCell<&'a dyn keys::SetKeyBySliceClient<64>>,
207    deferred_call: kernel::deferred_call::DeferredCall,
208
209    wakeup_device: fn(),
210
211    config_lock: Cell<bool>,
212    data_lock: Cell<bool>,
213    public_key: OptionalCell<[u8; PUBLIC_KEY_SIZE]>,
214}
215
216impl<'a> Atecc508a<'a> {
217    pub fn new(
218        i2c: &'a dyn I2CDevice,
219        buffer: &'static mut [u8],
220        entropy_buffer: &'static mut [u8; 32],
221        digest_buffer: &'static mut [u8; 64],
222        wakeup_device: fn(),
223    ) -> Self {
224        Atecc508a {
225            buffer: TakeCell::new(buffer),
226            i2c,
227            op: Cell::new(Operation::Ready),
228            op_len: Cell::new(0),
229            entropy_buffer: TakeCell::new(entropy_buffer),
230            entropy_offset: Cell::new(0),
231            entropy_client: OptionalCell::empty(),
232            digest_client: OptionalCell::empty(),
233            digest_buffer: TakeCell::new(digest_buffer),
234            write_len: Cell::new(0),
235            remain_len: Cell::new(0),
236            hash_data: MapCell::empty(),
237            digest_data: TakeCell::empty(),
238            secure_client: OptionalCell::empty(),
239            message_data: TakeCell::empty(),
240            signature_data: TakeCell::empty(),
241            ext_public_key: TakeCell::empty(),
242            ext_public_key_temp: TakeCell::empty(),
243            key_set_client: OptionalCell::empty(),
244            deferred_call: kernel::deferred_call::DeferredCall::new(),
245            wakeup_device,
246            config_lock: Cell::new(false),
247            data_lock: Cell::new(false),
248            public_key: OptionalCell::new([0; PUBLIC_KEY_SIZE]),
249        }
250    }
251
252    fn calculate_crc(data: &[u8]) -> u16 {
253        let mut crc_register: u16 = 0;
254
255        for counter in 0..data.len() {
256            let mut shift_register: u8 = 0x01;
257
258            while shift_register > 0x00 {
259                let data_val = data[counter] & shift_register;
260                let data_bit = u16::from(data_val > 0);
261
262                let crc_bit = crc_register >> 15;
263                crc_register <<= 1;
264
265                if data_bit != crc_bit {
266                    crc_register ^= 0x8005;
267                }
268
269                shift_register <<= 1;
270            }
271        }
272
273        crc_register
274    }
275
276    fn read(&self, zone: u8, address: u16, length: usize) -> Result<(), ErrorCode> {
277        let mut zone_calc = zone;
278
279        match length {
280            32 => zone_calc |= 1 << 7,
281            4 => zone_calc &= !(1 << 7),
282            _ => return Err(ErrorCode::SIZE),
283        }
284
285        self.op_len.set(length);
286
287        self.send_command(COMMAND_OPCODE_READ, zone_calc, address, 0);
288
289        Ok(())
290    }
291
292    fn write(&self, zone: u8, address: u16, length: usize) -> Result<(), ErrorCode> {
293        let mut zone_calc = zone;
294
295        match length {
296            32 => zone_calc |= 1 << 7,
297            4 => zone_calc &= !(1 << 7),
298            _ => return Err(ErrorCode::SIZE),
299        }
300
301        self.op_len.set(length);
302
303        self.send_command(COMMAND_OPCODE_WRITE, zone_calc, address, length);
304
305        Ok(())
306    }
307
308    fn idle(&self) {
309        self.buffer.take().map(|buffer| {
310            buffer[ATRCC508A_PROTOCOL_FIELD_COMMAND] = WORD_ADDRESS_VALUE_IDLE;
311
312            let _ = self.i2c.write(buffer, 1);
313        });
314    }
315
316    fn reset(&self) {
317        self.buffer.take().map(|buffer| {
318            self.op.set(Operation::Reset);
319
320            buffer[ATRCC508A_PROTOCOL_FIELD_COMMAND] = WORD_ADDRESS_VALUE_RESET;
321
322            let _ = self.i2c.write(buffer, 1);
323        });
324    }
325
326    fn send_command(&self, command_opcode: u8, param1: u8, param2: u16, length: usize) {
327        let i2c_length = length + ATRCC508A_PROTOCOL_OVERHEAD;
328
329        self.buffer.take().map(|buffer| {
330            buffer[ATRCC508A_PROTOCOL_FIELD_COMMAND] = WORD_ADDRESS_VALUE_COMMAND;
331            buffer[ATRCC508A_PROTOCOL_FIELD_LENGTH] =
332                (i2c_length - ATRCC508A_PROTOCOL_FIELD_SIZE_LENGTH) as u8;
333            buffer[ATRCC508A_PROTOCOL_FIELD_OPCODE] = command_opcode;
334            buffer[ATRCC508A_PROTOCOL_FIELD_PARAM1] = param1;
335            buffer[ATRCC508A_PROTOCOL_FIELD_PARAM2] = (param2 & 0xFF) as u8;
336            buffer[ATRCC508A_PROTOCOL_FIELD_PARAM2 + 1] = ((param2 >> 8) & 0xFF) as u8;
337
338            let data_crc_len = i2c_length
339                - (ATRCC508A_PROTOCOL_FIELD_SIZE_COMMAND + ATRCC508A_PROTOCOL_FIELD_SIZE_CRC);
340            let crc = Self::calculate_crc(
341                &buffer[ATRCC508A_PROTOCOL_FIELD_LENGTH
342                    ..(data_crc_len + ATRCC508A_PROTOCOL_FIELD_LENGTH)],
343            );
344
345            buffer[i2c_length - ATRCC508A_PROTOCOL_FIELD_SIZE_CRC] = (crc & 0xFF) as u8;
346            buffer[i2c_length - ATRCC508A_PROTOCOL_FIELD_SIZE_CRC + 1] = ((crc >> 8) & 0xFF) as u8;
347
348            let _ = self.i2c.write(buffer, i2c_length);
349        });
350    }
351
352    /// Read information from the configuration zone and print it
353    /// This will work while the device is either locked or unlocked
354    pub fn read_config_zone(&self) -> Result<(), ErrorCode> {
355        assert_eq!(self.op.get(), Operation::Ready);
356
357        self.op.set(Operation::ReadConfigZeroCommand);
358
359        (self.wakeup_device)();
360
361        self.read(
362            ZONE_CONFIG,
363            ADDRESS_CONFIG_READ_BLOCK_0,
364            CONFIG_ZONE_READ_SIZE,
365        )
366    }
367
368    /// Setup the device keys and config
369    ///
370    /// This will only work on an unlocked device and will lock the device!
371    ///
372    /// The slots will be configured as below
373    ///
374    ///```ignore
375    /// Slot 0: 0x2083
376    ///     - ReadKey: External signatures of arbitrary messages are enabled
377    ///                Internal signatures of messages generated by GenDig or GenKey are enabled
378    ///     - IsSecret: The contents of this slot are secret
379    ///     - WriteConfig: PubInvalid
380    ///
381    ///     Key Config: 0x33
382    ///        - Private: The key slot contains an ECC private key
383    ///        - PubInfo: The public version of this key can always be generated
384    ///        - KeyType: P256 NIST ECC key
385    ///        - Lockable: Slot can be individually locked using the Lock command
386    ///
387    /// Slot 1: 0x2083
388    ///     - ReadKey: External signatures of arbitrary messages are enabled
389    ///                Internal signatures of messages generated by GenDig or GenKey are enabled
390    ///     - IsSecret: The contents of this slot are secret
391    ///     - WriteConfig: PubInvalid
392    ///
393    ///     Key Config: 0x33
394    ///        - Private: The key slot contains an ECC private key
395    ///        - PubInfo: The public version of this key can always be generated
396    ///        - KeyType: P256 NIST ECC key
397    ///        - Lockable: Slot can be individually locked using the Lock command
398    ///
399    /// Slot 2:
400    ///     - ReadKey: Then this slot can be the source for the CheckMac/Copy operation
401    ///     - WriteConfig: Always
402    ///```
403    pub fn setup_tock_config(&self) -> Result<(), ErrorCode> {
404        self.op.set(Operation::SetupConfigOne);
405
406        (self.wakeup_device)();
407
408        // Set keytype on slot 0 and 1 to 0x3300
409        self.buffer.take().map(|buffer| {
410            buffer[ATRCC508A_PROTOCOL_FIELD_DATA..(ATRCC508A_PROTOCOL_FIELD_DATA + 4)]
411                .copy_from_slice(&[0x33, 0x00, 0x33, 0x00]);
412
413            self.buffer.replace(buffer);
414        });
415
416        self.write(ZONE_CONFIG, 96 / 4, 4)?;
417
418        Ok(())
419    }
420
421    /// Lock the zone config
422    pub fn lock_zone_config(&self) -> Result<(), ErrorCode> {
423        self.op.set(Operation::LockZoneConfig(0));
424
425        self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_ZONE_CONFIG, 0x0000, 0);
426
427        Ok(())
428    }
429
430    /// Create a key pair in the `slot`
431    pub fn create_key_pair(&self, slot: u16) -> Result<(), ErrorCode> {
432        self.op.set(Operation::CreateKeyPair(0, slot));
433
434        (self.wakeup_device)();
435
436        self.send_command(COMMAND_OPCODE_GENKEY, GENKEY_MODE_NEW_PRIVATE, slot, 0);
437
438        Ok(())
439    }
440
441    /// Retrieve the public key from the slot.
442    ///
443    /// This can be called only after `create_key_pair()` has completed
444    pub fn get_public_key(
445        &'a self,
446        _slot: u16,
447    ) -> Result<&'a OptionalCell<[u8; PUBLIC_KEY_SIZE]>, ErrorCode> {
448        if self.public_key.get().unwrap().iter().all(|&x| x == 0) {
449            return Err(ErrorCode::BUSY);
450        }
451
452        Ok(&self.public_key)
453    }
454
455    /// Set the public key to use for the `verify` command, if using an
456    /// external key.
457    ///
458    /// This will return the previous key if one was stored. Pass in
459    /// `None` to retrieve the key without providing a new one.
460    pub fn set_public_key(
461        &self,
462        public_key: Option<&'static mut [u8; 64]>,
463    ) -> Option<&'static mut [u8; 64]> {
464        let ret = self.ext_public_key.take();
465
466        if let Some(key) = public_key {
467            self.ext_public_key.replace(key);
468        }
469
470        ret
471    }
472
473    /// Lock the data and OTP
474    pub fn lock_data_and_otp(&self) -> Result<(), ErrorCode> {
475        self.op.set(Operation::LockDataOtp(0));
476
477        (self.wakeup_device)();
478
479        self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_ZONE_DATA_AND_OTP, 0x0000, 0);
480
481        Ok(())
482    }
483
484    /// Lock the slot0 config
485    pub fn lock_slot0(&self) -> Result<(), ErrorCode> {
486        self.op.set(Operation::LockSlot0(0));
487
488        (self.wakeup_device)();
489
490        self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_SLOT0, 0x0000, 0);
491
492        Ok(())
493    }
494
495    /// Check is the device configuration is locked
496    pub fn device_locked(&self) -> bool {
497        self.config_lock.get() && self.data_lock.get()
498    }
499
500    fn sha_update(&self) -> bool {
501        let op_len = (self.hash_data.map_or(0, |buf| match buf {
502            SubSliceMutImmut::Mutable(b) => {
503                let len = b.len();
504                self.remain_len.get() + len
505            }
506            SubSliceMutImmut::Immutable(b) => {
507                let len = b.len();
508                self.remain_len.get() + len
509            }
510        }))
511        .min(64);
512
513        // The SHA Update step only supports 64-bytes, so if we have less
514        // we store the data and write it when we have more data or on the
515        // End command
516        if op_len < 64 {
517            self.op.set(Operation::ReadySha);
518
519            self.hash_data.map(|buf| {
520                if op_len > 0 {
521                    self.digest_buffer.map(|digest_buffer| {
522                        digest_buffer[self.remain_len.get()..(self.remain_len.get() + op_len)]
523                            .copy_from_slice(&buf[0..op_len]);
524
525                        self.remain_len.set(self.remain_len.get() + op_len);
526
527                        buf.slice(op_len..);
528                    });
529                }
530
531                self.idle();
532            });
533
534            return false;
535        }
536
537        // At this point we have at least 64 bytes to write
538        self.buffer.take().map(|buffer| {
539            let remain_len = self.remain_len.get();
540
541            if remain_len > 0 {
542                self.digest_buffer.map(|digest_buffer| {
543                    buffer[ATRCC508A_PROTOCOL_FIELD_DATA
544                        ..(ATRCC508A_PROTOCOL_FIELD_DATA + remain_len)]
545                        .copy_from_slice(&digest_buffer[0..remain_len]);
546                });
547            }
548
549            self.hash_data.map(|hash_data| {
550                buffer[ATRCC508A_PROTOCOL_FIELD_DATA + remain_len
551                    ..(ATRCC508A_PROTOCOL_FIELD_DATA + op_len)]
552                    .copy_from_slice(&hash_data[0..(op_len - remain_len)]);
553
554                hash_data.slice((op_len - remain_len)..);
555            });
556
557            self.remain_len.set(0);
558            self.buffer.replace(buffer);
559        });
560
561        self.op.set(Operation::ShaLoadResponse(0));
562
563        true
564    }
565}
566
567impl I2CClient for Atecc508a<'_> {
568    fn command_complete(&self, buffer: &'static mut [u8], status: Result<(), i2c::Error>) {
569        match self.op.get() {
570            Operation::Ready => unreachable!(),
571            Operation::ReadySha => {
572                self.buffer.replace(buffer);
573
574                self.hash_data.take().map(|buf| {
575                    self.digest_client.map(|client| match buf {
576                        SubSliceMutImmut::Mutable(b) => client.add_mut_data_done(Ok(()), b),
577                        SubSliceMutImmut::Immutable(b) => client.add_data_done(Ok(()), b),
578                    })
579                });
580            }
581            Operation::Reset => {
582                self.buffer.replace(buffer);
583            }
584            Operation::ReadConfigZeroCommand => {
585                self.op.set(Operation::ReadConfigZeroResult(0));
586
587                let _ = self
588                    .i2c
589                    .read(buffer, self.op_len.get() + RESPONSE_COUNT_SIZE + CRC_SIZE);
590            }
591            Operation::ReadConfigZeroResult(run) => {
592                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
593                    // The device isn't ready yet, try again
594                    if run == 10 {
595                        return;
596                    }
597
598                    self.op.set(Operation::ReadConfigZeroResult(run + 1));
599
600                    let _ = self
601                        .i2c
602                        .read(buffer, self.op_len.get() + RESPONSE_COUNT_SIZE + CRC_SIZE);
603
604                    return;
605                }
606
607                self.op.set(Operation::ReadConfigTwoCommand);
608
609                assert_eq!(status, Ok(()));
610
611                let mut serial_num: [u8; 9] = [0; 9];
612                serial_num[0..3].copy_from_slice(&buffer[0..3]);
613                serial_num[4..8].copy_from_slice(&buffer[8..12]);
614
615                debug!("ATECC508A Serial Number: {serial_num:x?}");
616                debug!("ATECC508A Rev Number: {:x?}", &buffer[4..7]);
617
618                self.buffer.replace(buffer);
619
620                let _ = self.read(
621                    ZONE_CONFIG,
622                    ADDRESS_CONFIG_READ_BLOCK_2,
623                    CONFIG_ZONE_READ_SIZE,
624                );
625            }
626            Operation::ReadConfigTwoCommand => {
627                self.op.set(Operation::ReadConfigTwoResult(0));
628
629                let _ = self
630                    .i2c
631                    .read(buffer, self.op_len.get() + RESPONSE_COUNT_SIZE + CRC_SIZE);
632            }
633            Operation::ReadConfigTwoResult(run) => {
634                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
635                    // The device isn't ready yet, try again
636                    if run == 10 {
637                        return;
638                    }
639
640                    self.op.set(Operation::ReadConfigTwoResult(run + 1));
641
642                    let _ = self
643                        .i2c
644                        .read(buffer, self.op_len.get() + RESPONSE_COUNT_SIZE + CRC_SIZE);
645
646                    return;
647                }
648
649                self.op.set(Operation::Ready);
650
651                assert_eq!(status, Ok(()));
652
653                let otp_lock = buffer[CONFIG_ZONE_OTP_LOCK - 63];
654                if otp_lock == 0x55 {
655                    debug!("ATECC508A Data and OTP UnLocked");
656                } else if otp_lock == 0x00 {
657                    debug!("ATECC508A Data and OTP Locked");
658                    self.data_lock.set(true);
659                } else {
660                    debug!("ATECC508A Data and OTP Invalid Config");
661                }
662
663                let config_lock = buffer[CONFIG_ZONE_LOCK_STATUS - 63];
664                if config_lock == 0x55 {
665                    debug!("ATECC508A Config Zone UnLocked");
666                } else if config_lock == 0x00 {
667                    debug!("ATECC508A Config Zone Locked");
668                    self.config_lock.set(true);
669                } else {
670                    debug!("ATECC508A Config Zone Invalid Config");
671                }
672
673                debug!(
674                    "ATECC508A Slot Lock Status: 0x{:x} and 0x{:x}",
675                    &buffer[CONFIG_ZONE_SLOTS_LOCK0 - 63],
676                    &buffer[CONFIG_ZONE_SLOTS_LOCK1 - 63]
677                );
678
679                self.buffer.replace(buffer);
680            }
681            Operation::GenerateEntropyCommand(run) => {
682                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
683                    self.buffer.replace(buffer);
684
685                    // The device isn't ready yet, try again
686                    if run == 10 {
687                        self.entropy_client.map(move |client| {
688                            client.entropy_available(
689                                &mut Atecc508aRngIter(self),
690                                Err(ErrorCode::NOACK),
691                            );
692                        });
693
694                        return;
695                    }
696
697                    self.op.set(Operation::GenerateEntropyCommand(run + 1));
698                    self.send_command(COMMAND_OPCODE_RANDOM, 0x00, 0x0000, 0);
699
700                    return;
701                }
702
703                self.op.set(Operation::GenerateEntropyResult(0));
704
705                let _ = self.i2c.read(
706                    buffer,
707                    RESPONSE_COUNT_SIZE + RESPONSE_RANDOM_SIZE + CRC_SIZE,
708                );
709            }
710            Operation::GenerateEntropyResult(run) => {
711                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
712                    // The device isn't ready yet, try again
713
714                    if run == 1000 {
715                        self.entropy_client.map(move |client| {
716                            client.entropy_available(
717                                &mut Atecc508aRngIter(self),
718                                Err(ErrorCode::NOACK),
719                            );
720                        });
721
722                        return;
723                    }
724
725                    self.op.set(Operation::GenerateEntropyResult(run + 1));
726
727                    let _ = self.i2c.read(
728                        buffer,
729                        RESPONSE_COUNT_SIZE + RESPONSE_RANDOM_SIZE + CRC_SIZE,
730                    );
731
732                    return;
733                }
734
735                self.op.set(Operation::Ready);
736
737                self.entropy_buffer.take().map(|entropy_buffer| {
738                    entropy_buffer.copy_from_slice(
739                        &buffer[RESPONSE_COUNT_SIZE..(RESPONSE_COUNT_SIZE + RESPONSE_RANDOM_SIZE)],
740                    );
741
742                    self.entropy_buffer.replace(entropy_buffer);
743                });
744
745                self.buffer.replace(buffer);
746
747                if self.entropy_client.map(move |client| {
748                    client.entropy_available(&mut Atecc508aRngIter(self), Ok(()))
749                }) == Some(entropy::Continue::More)
750                {
751                    // We need more
752                    if let Err(e) = self.get() {
753                        self.entropy_client.map(move |client| {
754                            client.entropy_available(&mut (0..0), Err(e));
755                        });
756                    }
757                }
758            }
759            Operation::SetupConfigOne => {
760                self.op.set(Operation::SetupConfigTwo(0));
761
762                self.buffer.replace(buffer);
763
764                // Set slot config on slot 0 and 1 to 0x8320
765                self.buffer.take().map(|buffer| {
766                    buffer[ATRCC508A_PROTOCOL_FIELD_DATA..(ATRCC508A_PROTOCOL_FIELD_DATA + 4)]
767                        .copy_from_slice(&[0x83, 0x20, 0x83, 0x20]);
768
769                    self.buffer.replace(buffer);
770                });
771
772                let _ = self.write(ZONE_CONFIG, 20 / 4, 4);
773            }
774            Operation::SetupConfigTwo(run) => {
775                self.buffer.replace(buffer);
776
777                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
778                    // The device isn't ready yet, try again
779                    if run == 10 {
780                        self.op.set(Operation::Ready);
781                        return;
782                    }
783
784                    self.op.set(Operation::SetupConfigTwo(run + 1));
785                    let _ = self.write(ZONE_CONFIG, 20 / 4, 4);
786                    return;
787                }
788
789                self.op.set(Operation::Ready);
790            }
791            Operation::LockZoneConfig(run) => {
792                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
793                    self.buffer.replace(buffer);
794
795                    // The device isn't ready yet, try again
796                    if run == 30 {
797                        self.op.set(Operation::Ready);
798                        return;
799                    }
800
801                    self.op.set(Operation::LockZoneConfig(run + 1));
802                    self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_ZONE_CONFIG, 0x0000, 0);
803                    return;
804                }
805
806                self.op.set(Operation::LockResponse(0));
807
808                let _ = self.i2c.read(
809                    buffer,
810                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
811                );
812            }
813            Operation::LockResponse(run) => {
814                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
815                    // The device isn't ready yet, try again
816                    if run == 100 {
817                        self.buffer.replace(buffer);
818                        self.op.set(Operation::Ready);
819                        return;
820                    }
821
822                    self.op.set(Operation::LockResponse(run + 1));
823                    let _ = self.i2c.read(
824                        buffer,
825                        RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
826                    );
827                    return;
828                }
829
830                self.op.set(Operation::Ready);
831
832                let response = buffer[RESPONSE_SIGNAL_INDEX];
833
834                if response != ATRCC508A_SUCCESSFUL_LOCK {
835                    debug!("Failed to lock the device");
836                }
837
838                self.buffer.replace(buffer);
839            }
840            Operation::CreateKeyPair(run, slot) => {
841                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
842                    self.buffer.replace(buffer);
843
844                    // The device isn't ready yet, try again
845                    if run == 10 {
846                        self.op.set(Operation::Ready);
847                        return;
848                    }
849
850                    self.op.set(Operation::CreateKeyPair(run + 1, slot));
851                    self.send_command(COMMAND_OPCODE_GENKEY, GENKEY_MODE_NEW_PRIVATE, slot, 0);
852                    return;
853                }
854
855                self.op.set(Operation::ReadKeyPair(0));
856
857                let _ = self
858                    .i2c
859                    .read(buffer, RESPONSE_COUNT_SIZE + PUBLIC_KEY_SIZE + CRC_SIZE);
860            }
861            Operation::ReadKeyPair(run) => {
862                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
863                    // The device isn't ready yet, try again
864                    // This can take awhile to generate
865                    if run == 5000 {
866                        self.buffer.replace(buffer);
867                        self.op.set(Operation::Ready);
868                        return;
869                    }
870
871                    self.op.set(Operation::ReadKeyPair(run + 1));
872                    let _ = self
873                        .i2c
874                        .read(buffer, RESPONSE_COUNT_SIZE + PUBLIC_KEY_SIZE + CRC_SIZE);
875                    return;
876                }
877
878                self.public_key.take().map(|mut pub_key| {
879                    pub_key.copy_from_slice(
880                        &buffer[RESPONSE_COUNT_SIZE..(RESPONSE_COUNT_SIZE + PUBLIC_KEY_SIZE)],
881                    );
882                    self.public_key.set(pub_key);
883                });
884
885                self.op.set(Operation::Ready);
886                self.buffer.replace(buffer);
887            }
888            Operation::LockDataOtp(run) => {
889                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
890                    self.buffer.replace(buffer);
891
892                    // The device isn't ready yet, try again
893                    if run == 100 {
894                        self.op.set(Operation::Ready);
895                        return;
896                    }
897
898                    self.op.set(Operation::LockDataOtp(run + 1));
899                    self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_ZONE_DATA_AND_OTP, 0x0000, 0);
900                    return;
901                }
902
903                self.op.set(Operation::LockResponse(0));
904
905                let _ = self.i2c.read(
906                    buffer,
907                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
908                );
909            }
910            Operation::LockSlot0(run) => {
911                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
912                    self.buffer.replace(buffer);
913
914                    // The device isn't ready yet, try again
915                    if run == 100 {
916                        self.op.set(Operation::Ready);
917                        return;
918                    }
919
920                    self.op.set(Operation::LockSlot0(run + 1));
921                    self.send_command(COMMAND_OPCODE_LOCK, LOCK_MODE_SLOT0, 0x0000, 0);
922                    return;
923                }
924
925                self.op.set(Operation::LockResponse(0));
926
927                let _ = self.i2c.read(
928                    buffer,
929                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
930                );
931            }
932            Operation::StartSha(run) => {
933                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
934                    self.buffer.replace(buffer);
935
936                    // The device isn't ready yet, try again
937                    if run == 10 {
938                        self.op.set(Operation::Ready);
939                        return;
940                    }
941
942                    self.op.set(Operation::StartSha(run + 1));
943                    self.send_command(COMMAND_OPCODE_SHA, SHA_START, 0x0000, 0);
944                    return;
945                }
946
947                self.op.set(Operation::ShaLoad(0));
948
949                let _ = self.i2c.read(
950                    buffer,
951                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
952                );
953            }
954            Operation::ShaLoad(run) => {
955                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
956                    // The device isn't ready yet, try again
957                    if run == 50 {
958                        self.op.set(Operation::Ready);
959                        return;
960                    }
961
962                    self.op.set(Operation::ShaLoad(run + 1));
963                    let _ = self.i2c.read(
964                        buffer,
965                        RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
966                    );
967                    return;
968                }
969
970                self.buffer.replace(buffer);
971
972                if self.sha_update() {
973                    self.send_command(COMMAND_OPCODE_SHA, SHA_UPDATE, 64, 64);
974                }
975            }
976            Operation::ShaLoadResponse(run) => {
977                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
978                    // The device isn't ready yet, try again
979                    if run == 10 {
980                        self.op.set(Operation::Ready);
981                        return;
982                    }
983
984                    self.op.set(Operation::ShaLoadResponse(run + 1));
985                    self.send_command(COMMAND_OPCODE_SHA, SHA_UPDATE, 64, 64);
986
987                    return;
988                }
989
990                self.op.set(Operation::ShaLoad(0));
991                let _ = self.i2c.read(
992                    buffer,
993                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
994                );
995            }
996            Operation::ShaRun(run) => {
997                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
998                    self.buffer.replace(buffer);
999
1000                    // The device isn't ready yet, try again
1001                    if run == 10 {
1002                        self.op.set(Operation::Ready);
1003                        return;
1004                    }
1005
1006                    self.op.set(Operation::ShaRun(run + 1));
1007                    self.send_command(
1008                        COMMAND_OPCODE_SHA,
1009                        SHA_END,
1010                        self.remain_len.get() as u16,
1011                        self.remain_len.get(),
1012                    );
1013                    return;
1014                }
1015
1016                self.op.set(Operation::ShaEnd(0));
1017                self.remain_len.set(0);
1018
1019                let _ = self
1020                    .i2c
1021                    .read(buffer, RESPONSE_COUNT_SIZE + RESPONSE_SHA_SIZE + CRC_SIZE);
1022            }
1023            Operation::ShaEnd(run) => {
1024                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
1025                    // The device isn't ready yet, try again
1026                    if run == 500 {
1027                        self.op.set(Operation::Ready);
1028                        return;
1029                    }
1030
1031                    self.op.set(Operation::ShaEnd(run + 1));
1032                    let _ = self
1033                        .i2c
1034                        .read(buffer, RESPONSE_COUNT_SIZE + RESPONSE_SHA_SIZE + CRC_SIZE);
1035                    return;
1036                }
1037
1038                self.digest_data.take().map(|digest_data| {
1039                    digest_data[0..32]
1040                        .copy_from_slice(&buffer[RESPONSE_COUNT_SIZE..(RESPONSE_COUNT_SIZE + 32)]);
1041
1042                    self.buffer.replace(buffer);
1043
1044                    self.op.set(Operation::Ready);
1045
1046                    self.digest_client.map(|client| {
1047                        client.hash_done(Ok(()), digest_data);
1048                    })
1049                });
1050            }
1051            Operation::LoadTempKeyNonce(run) => {
1052                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
1053                    self.buffer.replace(buffer);
1054
1055                    // The device isn't ready yet, try again
1056                    if run == 10 {
1057                        self.op.set(Operation::Ready);
1058                        return;
1059                    }
1060
1061                    self.op.set(Operation::LoadTempKeyNonce(run + 1));
1062                    self.send_command(COMMAND_OPCODE_NONCE, NONCE_MODE_PASSTHROUGH, 0x0000, 32);
1063                    return;
1064                }
1065
1066                self.op.set(Operation::LoadTempKeyCheckNonce(0));
1067
1068                let _ = self.i2c.read(
1069                    buffer,
1070                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
1071                );
1072            }
1073            Operation::LoadTempKeyCheckNonce(run) => {
1074                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
1075                    // The device isn't ready yet, try again
1076                    if run == 10 {
1077                        self.op.set(Operation::Ready);
1078                        return;
1079                    }
1080
1081                    self.op.set(Operation::LoadTempKeyCheckNonce(run + 1));
1082                    let _ = self.i2c.read(
1083                        buffer,
1084                        RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
1085                    );
1086                    return;
1087                }
1088
1089                if buffer[RESPONSE_SIGNAL_INDEX] != ATRCC508A_SUCCESSFUL_TEMPKEY {
1090                    self.buffer.replace(buffer);
1091
1092                    self.secure_client.map(|client| {
1093                        client.verification_done(
1094                            Err(ErrorCode::FAIL),
1095                            self.message_data.take().unwrap(),
1096                            self.signature_data.take().unwrap(),
1097                        );
1098                    });
1099
1100                    return;
1101                }
1102
1103                // Append Signature
1104                self.signature_data.map(|signature_data| {
1105                    buffer[ATRCC508A_PROTOCOL_FIELD_DATA..(ATRCC508A_PROTOCOL_FIELD_DATA + 64)]
1106                        .copy_from_slice(signature_data);
1107                });
1108
1109                // Append Public Key
1110                self.ext_public_key.map(|ext_public_key| {
1111                    buffer[(ATRCC508A_PROTOCOL_FIELD_DATA + 64)
1112                        ..(ATRCC508A_PROTOCOL_FIELD_DATA + 128)]
1113                        .copy_from_slice(ext_public_key);
1114                });
1115
1116                self.buffer.replace(buffer);
1117                self.op.set(Operation::VerifySubmitData(0));
1118
1119                self.send_command(
1120                    COMMAND_OPCODE_VERIFY,
1121                    VERIFY_MODE_EXTERNAL,
1122                    VERIFY_PARAM2_KEYTYPE_ECC as u16,
1123                    128,
1124                );
1125            }
1126            Operation::VerifySubmitData(run) => {
1127                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
1128                    self.buffer.replace(buffer);
1129
1130                    // The device isn't ready yet, try again
1131                    if run == 10 {
1132                        self.op.set(Operation::Ready);
1133                        return;
1134                    }
1135
1136                    self.op.set(Operation::VerifySubmitData(run + 1));
1137                    self.send_command(
1138                        COMMAND_OPCODE_VERIFY,
1139                        VERIFY_MODE_EXTERNAL,
1140                        VERIFY_PARAM2_KEYTYPE_ECC as u16,
1141                        128,
1142                    );
1143                    return;
1144                }
1145
1146                self.op.set(Operation::CompleteVerify(0));
1147                let _ = self.i2c.read(
1148                    buffer,
1149                    RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
1150                );
1151            }
1152            Operation::CompleteVerify(run) => {
1153                if status == Err(i2c::Error::DataNak) || status == Err(i2c::Error::AddressNak) {
1154                    // The device isn't ready yet, try again
1155                    if run == 100 {
1156                        self.op.set(Operation::Ready);
1157                        return;
1158                    }
1159
1160                    self.op.set(Operation::CompleteVerify(run + 1));
1161                    let _ = self.i2c.read(
1162                        buffer,
1163                        RESPONSE_COUNT_SIZE + RESPONSE_SIGNAL_SIZE + CRC_SIZE,
1164                    );
1165                    return;
1166                }
1167
1168                let ret = buffer[RESPONSE_SIGNAL_INDEX];
1169
1170                self.op.set(Operation::Ready);
1171                self.buffer.replace(buffer);
1172
1173                self.secure_client.map(|client| {
1174                    if ret == ATRCC508A_SUCCESSFUL_VERIFY {
1175                        client.verification_done(
1176                            Ok(true),
1177                            self.message_data.take().unwrap(),
1178                            self.signature_data.take().unwrap(),
1179                        );
1180                    } else if ret == 1 {
1181                        client.verification_done(
1182                            Ok(false),
1183                            self.message_data.take().unwrap(),
1184                            self.signature_data.take().unwrap(),
1185                        );
1186                    } else {
1187                        client.verification_done(
1188                            Err(ErrorCode::FAIL),
1189                            self.message_data.take().unwrap(),
1190                            self.signature_data.take().unwrap(),
1191                        );
1192                    }
1193                });
1194            }
1195        }
1196    }
1197}
1198
1199struct Atecc508aRngIter<'a, 'b: 'a>(&'a Atecc508a<'b>);
1200
1201impl Iterator for Atecc508aRngIter<'_, '_> {
1202    type Item = u32;
1203
1204    fn next(&mut self) -> Option<u32> {
1205        self.0.entropy_buffer.take().map(|entropy_buffer| {
1206            let offset = self.0.entropy_offset.get();
1207            let entropy_bytes =
1208                <[u8; 4]>::try_from(&entropy_buffer[(offset + 0)..(offset + 4)]).unwrap();
1209            let entropy: u32 = u32::from_be_bytes(entropy_bytes);
1210
1211            if offset >= 28 {
1212                self.0.entropy_offset.set(0);
1213            } else {
1214                self.0.entropy_offset.set(offset + 4);
1215            }
1216            self.0.entropy_buffer.replace(entropy_buffer);
1217
1218            entropy
1219        })
1220    }
1221}
1222
1223impl<'a> entropy::Entropy32<'a> for Atecc508a<'a> {
1224    fn set_client(&'a self, client: &'a dyn entropy::Client32) {
1225        self.entropy_client.set(client);
1226    }
1227
1228    fn get(&self) -> Result<(), ErrorCode> {
1229        self.op.set(Operation::GenerateEntropyCommand(0));
1230
1231        (self.wakeup_device)();
1232
1233        self.send_command(COMMAND_OPCODE_RANDOM, 0x00, 0x0000, 0);
1234
1235        Ok(())
1236    }
1237
1238    fn cancel(&self) -> Result<(), ErrorCode> {
1239        Ok(())
1240    }
1241}
1242
1243impl<'a> digest::DigestData<'a, 32> for Atecc508a<'a> {
1244    fn set_data_client(&'a self, _client: &'a dyn digest::ClientData<32>) {
1245        unimplemented!()
1246    }
1247
1248    fn add_data(
1249        &self,
1250        data: SubSlice<'static, u8>,
1251    ) -> Result<(), (ErrorCode, SubSlice<'static, u8>)> {
1252        if !(self.op.get() == Operation::Ready || self.op.get() == Operation::ReadySha) {
1253            return Err((ErrorCode::BUSY, data));
1254        }
1255
1256        (self.wakeup_device)();
1257
1258        self.write_len.set(data.len());
1259        self.hash_data.replace(SubSliceMutImmut::Immutable(data));
1260
1261        if self.op.get() == Operation::Ready {
1262            self.op.set(Operation::StartSha(0));
1263
1264            self.send_command(COMMAND_OPCODE_SHA, SHA_START, 0x0000, 0);
1265        } else {
1266            self.op.set(Operation::ShaLoad(0));
1267
1268            if self.sha_update() {
1269                self.send_command(COMMAND_OPCODE_SHA, SHA_UPDATE, 64, 64);
1270            }
1271        }
1272
1273        Ok(())
1274    }
1275
1276    fn add_mut_data(
1277        &self,
1278        data: SubSliceMut<'static, u8>,
1279    ) -> Result<(), (ErrorCode, SubSliceMut<'static, u8>)> {
1280        if !(self.op.get() == Operation::Ready || self.op.get() == Operation::ReadySha) {
1281            return Err((ErrorCode::BUSY, data));
1282        }
1283
1284        self.write_len.set(data.len());
1285        self.hash_data.replace(SubSliceMutImmut::Mutable(data));
1286
1287        if self.op.get() == Operation::Ready {
1288            self.op.set(Operation::StartSha(0));
1289
1290            (self.wakeup_device)();
1291
1292            self.send_command(COMMAND_OPCODE_SHA, SHA_START, 0x0000, 0);
1293        } else {
1294            self.op.set(Operation::ShaLoad(0));
1295
1296            if self.sha_update() {
1297                (self.wakeup_device)();
1298
1299                self.send_command(COMMAND_OPCODE_SHA, SHA_UPDATE, 64, 64);
1300            }
1301        }
1302
1303        Ok(())
1304    }
1305
1306    /// This will reset the device to clear the data
1307    ///
1308    /// This is an async operation though, as it requires the I2C operation
1309    /// to complete and the I2C callback to occur, but the `clear_data()`
1310    /// definition is syncronous, so this can race.
1311    fn clear_data(&self) {
1312        (self.wakeup_device)();
1313
1314        self.reset();
1315    }
1316}
1317
1318impl<'a> digest::DigestHash<'a, 32> for Atecc508a<'a> {
1319    fn set_hash_client(&'a self, _client: &'a dyn digest::ClientHash<32>) {
1320        unimplemented!()
1321    }
1322
1323    fn run(
1324        &'a self,
1325        digest: &'static mut [u8; 32],
1326    ) -> Result<(), (ErrorCode, &'static mut [u8; 32])> {
1327        let remain_len = self.remain_len.get();
1328
1329        if self.op.get() != Operation::ReadySha {
1330            return Err((ErrorCode::BUSY, digest));
1331        }
1332
1333        (self.wakeup_device)();
1334
1335        self.op.set(Operation::ShaRun(0));
1336        self.digest_data.replace(digest);
1337
1338        if remain_len > 0 {
1339            self.buffer.take().map(|buffer| {
1340                self.digest_buffer.map(|digest_buffer| {
1341                    buffer[ATRCC508A_PROTOCOL_FIELD_DATA
1342                        ..(ATRCC508A_PROTOCOL_FIELD_DATA + remain_len)]
1343                        .copy_from_slice(&digest_buffer[0..remain_len]);
1344                });
1345
1346                self.buffer.replace(buffer);
1347            });
1348        }
1349
1350        self.send_command(
1351            COMMAND_OPCODE_SHA,
1352            SHA_END,
1353            self.remain_len.get() as u16,
1354            remain_len,
1355        );
1356
1357        Ok(())
1358    }
1359}
1360
1361impl<'a> digest::DigestDataHash<'a, 32> for Atecc508a<'a> {
1362    fn set_client(&'a self, client: &'a dyn digest::ClientDataHash<32>) {
1363        self.digest_client.set(client);
1364    }
1365}
1366
1367impl<'a> SignatureVerify<'a, 32, 64> for Atecc508a<'a> {
1368    fn set_verify_client(&self, client: &'a dyn ClientVerify<32, 64>) {
1369        self.secure_client.set(client);
1370    }
1371
1372    /// Check the signature against the external public key loaded via
1373    /// `set_public_key()`.
1374    ///
1375    /// Verifying that a message was signed by the device is not support
1376    /// yet.
1377    fn verify(
1378        &self,
1379        hash: &'static mut [u8; 32],
1380        signature: &'static mut [u8; 64],
1381    ) -> Result<(), (ErrorCode, &'static mut [u8; 32], &'static mut [u8; 64])> {
1382        if self.ext_public_key.is_none() {
1383            return Err((ErrorCode::OFF, hash, signature));
1384        }
1385
1386        (self.wakeup_device)();
1387
1388        self.op.set(Operation::LoadTempKeyNonce(0));
1389
1390        self.buffer.map(|buffer| {
1391            buffer[ATRCC508A_PROTOCOL_FIELD_DATA..(ATRCC508A_PROTOCOL_FIELD_DATA + 32)]
1392                .copy_from_slice(hash);
1393        });
1394
1395        self.message_data.replace(hash);
1396        self.signature_data.replace(signature);
1397
1398        self.send_command(COMMAND_OPCODE_NONCE, NONCE_MODE_PASSTHROUGH, 0x0000, 32);
1399
1400        Ok(())
1401    }
1402}
1403
1404impl<'a> keys::SetKeyBySlice<'a, 64> for Atecc508a<'a> {
1405    fn set_key(
1406        &self,
1407        key: &'static mut [u8; 64],
1408    ) -> Result<(), (ErrorCode, &'static mut [u8; 64])> {
1409        // Copy the key into our public key buffer.
1410        self.ext_public_key.map(|epkey| {
1411            epkey.copy_from_slice(key);
1412        });
1413
1414        // Save the key so we can return the buffer in `set_key_done()`.
1415        self.ext_public_key_temp.replace(key);
1416        self.deferred_call.set();
1417        Ok(())
1418    }
1419
1420    fn set_client(&self, client: &'a dyn keys::SetKeyBySliceClient<64>) {
1421        self.key_set_client.replace(client);
1422    }
1423}
1424
1425impl kernel::deferred_call::DeferredCallClient for Atecc508a<'_> {
1426    fn handle_deferred_call(&self) {
1427        self.key_set_client.map(|client| {
1428            self.ext_public_key_temp
1429                .take()
1430                .map(|key| client.set_key_done(key, Ok(())))
1431        });
1432    }
1433
1434    fn register(&'static self) {
1435        self.deferred_call.register(self);
1436    }
1437}