Skip to content

Commit

Permalink
Adding HMAC and nonce functionality for ATECC608 (#45)
Browse files Browse the repository at this point in the history
Co-authored-by: Dane Walton <[email protected]>
  • Loading branch information
RLeclair and danewalton authored Dec 1, 2022
1 parent e30e8f0 commit 82ec8c1
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
78 changes: 78 additions & 0 deletions examples/ECCX08HMAC/ECCX08HMAC.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
ECCX08 HMAC functionality example
This sketch uses the ECC608 to generate an hmac on some data.
Stores key using nonce.
Tested on the Arduino Nano RP2040.
created 10 October 2022
by Raul Leclair
*/

#include <ArduinoECCX08.h>

#define TEMPKEY_SLOT 0xFFFF

byte nonceKey[] = {
0x10, 0x10, 0x10, 0x10
};

byte data[] = {
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
};

int dataLength = sizeof(data);

void setup() {
Serial.begin(115200);
while (!Serial);

if (!ECCX08.begin()) {
Serial.println("Failed to initialize ECCX08 board.");
while (1);
}

// Perform nonce
if (!ECCX08.nonce(nonceKey))
{
Serial.println("Failed to perform nonce.");
while (1);
}

// Starting HMAC operation on tempkey slot
if (!ECCX08.beginHMAC(TEMPKEY_SLOT)) {
Serial.println("Failed to start HMAC operation.");
while (1);
}

if (!ECCX08.updateHMAC(data, dataLength)) {
Serial.println("Failed to update HMAC operation.");
while (1);
}

byte resultHMAC[32];
if (!ECCX08.endHMAC(resultHMAC)) {
Serial.println("Failed to end HMAC operation");
while (1);
}

Serial.println("HMAC Result: ");
for (int i = 0; i < sizeof(resultHMAC); i++) {
char hexChar[2];
sprintf(hexChar, "%02X", resultHMAC[i]);
Serial.print(hexChar);
Serial.print(" ");
}
}

void loop() {
}
108 changes: 108 additions & 0 deletions src/ECCX08.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,114 @@ int ECCX08Class::lock()
return 1;
}


int ECCX08Class::beginHMAC(uint16_t keySlot)
{
// HMAC implementation is only for ATECC608
uint8_t status;
long ecc608ver = 0x0600000;
long eccCurrVer = version() & 0x0F00000;

if (eccCurrVer != ecc608ver) {
return 0;
}

if (!wakeup()) {
return 0;
}

if (!sendCommand(0x47, 0x04, keySlot)) {
return 0;
}

delay(9);

if (!receiveResponse(&status, sizeof(status))) {
return 0;
}

delay(1);
idle();

if (status != 0) {
return 0;
}

return 1;
}

int ECCX08Class::updateHMAC(const byte data[], int length) {
uint8_t status;

if (!wakeup()) {
return 0;
}

// Processing message
int currLength = 0;
while (length) {
data += currLength;

if (length > 64) {
currLength = 64;
} else {
currLength = length;
}
length -= currLength;

if (!sendCommand(0x47, 0x01, currLength, data, currLength)) {
return 0;
}

delay(9);

if (!receiveResponse(&status, sizeof(status))) {
return 0;
}

delay(1);
}
idle();

if (status != 0) {
return 0;
}

return 1;
}

int ECCX08Class::endHMAC(byte result[])
{
return endHMAC(NULL, 0, result);
}

int ECCX08Class::endHMAC(const byte data[], int length, byte result[])
{
if (!wakeup()) {
return 0;
}

if (!sendCommand(0x47, 0x02, length, data, length)) {
return 0;
}

delay(9);

if (!receiveResponse(result, 32)) {
return 0;
}

delay(1);
idle();

return 1;
}

int ECCX08Class::nonce(const byte data[])
{
return challenge(data);
}

int ECCX08Class::wakeup()
{
_wire->setClock(_wakeupFrequency);
Expand Down
7 changes: 7 additions & 0 deletions src/ECCX08.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ class ECCX08Class
int readConfiguration(byte data[]);
int lock();

int beginHMAC(uint16_t keySlot);
int updateHMAC(const byte data[], int length);
int endHMAC(byte result[]);
int endHMAC(const byte data[], int length, byte result[]);

int nonce(const byte data[]);

private:
int wakeup();
int sleep();
Expand Down

0 comments on commit 82ec8c1

Please sign in to comment.