A platform agnostic I2C driver for Microchip's crypto-authentication device i.e. ATECC608a, written entirely in Rust. This library implements APIs required to communicate with Microchip Security device - ATECC608a.
The ATECC608A device is a member of the Microchip CryptoAuthenticationâ„¢ family of crypto engine authentication devices with highly secure hardware-based key storage.
The ATECC608A device has a flexible command set that allows use in many applications, including the following: * Network/IoT Node Protection - Authenticates node IDs, ensures the integrity of messages, and supports key agreement to create session keys for message encryption. * Anti-Counterfeiting - Validates that a removable, replaceable, or consumable client is authentic. Examples of clients could be system accessories, electronic daughter cards, or other spare parts. It can also be used to validate a software/firmware module or memory storage element. * Protecting Firmware or Media - Validates code stored in flash memory at boot to prevent unauthorized modifications, encrypt downloaded program files as a common broadcast, or uniquely encrypt code images to be usable on a single system only. * Storing Secure Data - Stores secret keys for use by crypto accelerators in standard microprocessors. Programmable protection is available using encrypted/authenticated reads and writes. * Checking User Password - Validates user-entered passwords without letting the expected value become known, maps memorable passwords to a random number, and securely exchanges password values with remote systems.
The device includes an EEPROM array which can be used for storage of up to 16 keys, certificates, miscellaneous read/write, read-only or secret data, consumption logging, and security configurations. Access to the various sections of memory can be restricted in a variety of ways and then the configuration can be locked to prevent changes. Access to the device is made through a standard I2C Interface at speeds of up to 1 Mb/s(see Section I2C Interface). The interface is compatible with standard Serial EEPROM I2C interface specifications.
The ATECC608A is a command-based device which receives commands from the system, executes those commands, and then returns a result or error code. * Security Commands: This group of commands generally access the EEPROM space and/or perform cryptographic computation. * Cryptographic Commands: This subset of the security commands includes all the ECC commands which access the hardware ECC accelerator (GenKey, Sign, ECDH, and Verify) and the SHA commands which access the hardware SHA accelerator (CheckMac, DeriveKey, GenDig, HMAC, MAC, SHA, and Nonce).
```Rust
// #![allow(warnings)]
extern crate nrf52840hal as hal; extern crate panichalt; use cortexmrt::{entry, exception};
use hal::gpio::{p0, p1, Floating, Input}; use hal::target::Peripherals; use hal::timer::Timer; use hal::twim::{self, Twim}; // use cortexmsemihosting::hprintln; use Rusty_CryptoAuthLib::ATECC608A;
// Test Enum
pub enum TestEnum { ShaTestData1, ShaTestData2, }
impl<'a> TestEnum { pub fn get_value(self) -> &'a [u8] { match self { TestEnum::ShaTestData1 => &[0x01, 0x02, 0x03, 0x04, 0x05], TestEnum::ShaTestData2 => &[ 0x1f, 0xe6, 0x54, 0xc1, 0x80, 0x88, 0xe7, 0xfe, 0xf0, 0x84, 0xf9, 0x8a, 0x1a, 0x12, 0xdb, 0x84, 0x69, 0x54, 0x34, 0x25, 0x06, 0xf5, 0x17, 0x69, 0x18, 0x9e, 0x3a, 0x90, 0x79, 0x2f, 0xd3, 0x28, 0xcf, 0x51, 0x5d, 0x1e, 0x44, 0xbb, 0xa4, 0x9d, 0x34, 0xde, 0x3b, 0x99, 0xca, 0x4c, 0x5e, 0x7e, 0xf4, 0x3a, 0xf6, 0xda, 0x41, 0x3c, 0x91, 0xc7, 0x98, 0x70, 0xd4, 0x87, 0x68, 0xac, 0x74, 0x5b, 0x1f, 0xe6, 0x54, 0xc1, 0x80, 0x88, 0xe7, 0xfe, 0xf0, 0x84, 0xf9, 0x8a, 0x1a, 0x12, 0xdb, 0x84, 0x69, 0x54, 0x34, 0x25, 0x06, 0xf5, 0x17, 0x69, 0x18, 0x9e, 0x3a, 0x90, 0x79, 0x2f, 0xd3, 0x28, ], } } }
fn main() -> ! { let p = Peripherals::take().unwrap(); let pins = Pins::new(p0::Parts::new(p.P0), p1::Parts::new(p.P1)); let scl = pins.p27.intofloatinginput().degrade(); let sda = pins.p26.intofloatinginput().degrade();
let i2c_pins = twim::Pins { scl, sda };
let i2c = Twim::new(p.TWIM1, i2c_pins, twim::Frequency::K100);
let delay = Timer::new(p.TIMER0);
let timer = Timer::new(p.TIMER1);
let mut atecc608a = ATECC608A::new(i2c, delay, timer).unwrap();
#[doc = "##########################################"]
#[doc = "# INFO COMMAND EXAMPLE #"]
#[doc = "##########################################"]
let _info = match atecc608a.atcab_info() {
Ok(v) => v,
Err(e) => panic!("ERROR: {:?}", e),
};
#[doc = "##########################################"]
#[doc = "# SHA COMMAND EXAMPLE #"]
#[doc = "##########################################"]
let selection = TestEnum::ShaTestData1; // or TestEnum::ShaTestData2
let sha = match atecc608a.atcab_sha(selection.get_value()) {
Ok(v) => v,
Err(e) => panic!("ERROR: {:?}", e),
};
match selection {
TestEnum::ShaTestData1 => assert_eq!(
[
0x74, 0xf8, 0x1f, 0xe1, 0x67, 0xd9, 0x9b, 0x4c, 0xb4, 0x1d, 0x6d, 0x0c, 0xcd, 0xa8,
0x22, 0x78, 0xca, 0xee, 0x9f, 0x3e, 0x2f, 0x25, 0xd5, 0xe5, 0xa3, 0x93, 0x6f, 0xf3,
0xdc, 0xec, 0x60, 0xd0
],
&sha[..32]
),
TestEnum::ShaTestData2 => assert_eq!(
[
0x6e, 0x68, 0x88, 0x97, 0xd4, 0x70, 0xe7, 0x74, 0x27, 0x44, 0xcf, 0x2b, 0xcd, 0xe9,
0x3c, 0x9b, 0xe6, 0x94, 0xf3, 0x36, 0x34, 0x54, 0x46, 0x48, 0x27, 0x04, 0x19, 0xe7,
0xce, 0xe3, 0x40, 0xdd
],
&sha[..32]
),
}
#[doc = "##########################################"]
#[doc = "# READ COMMAND EXAMPLE #"]
#[doc = "##########################################"]
let _dump_config_zone = atecc608a.atcab_read_config_zone();
loop {}
}
fn HardFault(ef: &cortexmrt::ExceptionFrame) -> ! { panic!("HardFault at {:#?}", ef); }
fn DefaultHandler(irqn: i16) { panic!("Unhandled exception (IRQn = {})", irqn); }
// // edited for brevity's sake. See atecc608a.rs examples for complete code. ```
(1) Not all features are implemented, see follow list for details
For questions, issues, feature requests, and other changes, please file an issue in the github project.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.