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