1use 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
35const 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
48const 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
56const 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; #[allow(dead_code)]
72const ADDRESS_CONFIG_READ_BLOCK_1: u16 = 0x0008; const ADDRESS_CONFIG_READ_BLOCK_2: u16 = 0x0010; #[allow(dead_code)]
75const ADDRESS_CONFIG_READ_BLOCK_3: u16 = 0x0018; const 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#[allow(dead_code)]
90const COMMAND_OPCODE_INFO: u8 = 0x30; const COMMAND_OPCODE_LOCK: u8 = 0x17; const COMMAND_OPCODE_RANDOM: u8 = 0x1B; const COMMAND_OPCODE_READ: u8 = 0x02; #[allow(dead_code)]
95const COMMAND_OPCODE_WRITE: u8 = 0x12; const COMMAND_OPCODE_SHA: u8 = 0x47; #[allow(dead_code)]
98const COMMAND_OPCODE_GENKEY: u8 = 0x40; #[allow(dead_code)]
100const COMMAND_OPCODE_NONCE: u8 = 0x16; #[allow(dead_code)]
102const COMMAND_OPCODE_SIGN: u8 = 0x41; #[allow(dead_code)]
104const COMMAND_OPCODE_VERIFY: u8 = 0x45; const VERIFY_MODE_EXTERNAL: u8 = 0x02; #[allow(dead_code)]
108const VERIFY_MODE_STORED: u8 = 0b00000000; const VERIFY_PARAM2_KEYTYPE_ECC: u8 = 0x0004; #[allow(dead_code)]
111const VERIFY_PARAM2_KEYTYPE_NONECC: u8 = 0x0007; const NONCE_MODE_PASSTHROUGH: u8 = 0b00000011; const 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 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 pub fn setup_tock_config(&self) -> Result<(), ErrorCode> {
397 self.op.set(Operation::SetupConfigOne);
398
399 (self.wakeup_device)();
400
401 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}