Skip to content

Commit 82ec8c1

Browse files
Adding HMAC and nonce functionality for ATECC608 (#45)
Co-authored-by: Dane Walton <[email protected]>
1 parent e30e8f0 commit 82ec8c1

File tree

3 files changed

+193
-0
lines changed

3 files changed

+193
-0
lines changed

examples/ECCX08HMAC/ECCX08HMAC.ino

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
ECCX08 HMAC functionality example
3+
4+
This sketch uses the ECC608 to generate an hmac on some data.
5+
Stores key using nonce.
6+
7+
Tested on the Arduino Nano RP2040.
8+
9+
created 10 October 2022
10+
by Raul Leclair
11+
*/
12+
13+
#include <ArduinoECCX08.h>
14+
15+
#define TEMPKEY_SLOT 0xFFFF
16+
17+
byte nonceKey[] = {
18+
0x10, 0x10, 0x10, 0x10
19+
};
20+
21+
byte data[] = {
22+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
23+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
24+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
25+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
26+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
27+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
28+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
29+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
30+
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
31+
};
32+
33+
int dataLength = sizeof(data);
34+
35+
void setup() {
36+
Serial.begin(115200);
37+
while (!Serial);
38+
39+
if (!ECCX08.begin()) {
40+
Serial.println("Failed to initialize ECCX08 board.");
41+
while (1);
42+
}
43+
44+
// Perform nonce
45+
if (!ECCX08.nonce(nonceKey))
46+
{
47+
Serial.println("Failed to perform nonce.");
48+
while (1);
49+
}
50+
51+
// Starting HMAC operation on tempkey slot
52+
if (!ECCX08.beginHMAC(TEMPKEY_SLOT)) {
53+
Serial.println("Failed to start HMAC operation.");
54+
while (1);
55+
}
56+
57+
if (!ECCX08.updateHMAC(data, dataLength)) {
58+
Serial.println("Failed to update HMAC operation.");
59+
while (1);
60+
}
61+
62+
byte resultHMAC[32];
63+
if (!ECCX08.endHMAC(resultHMAC)) {
64+
Serial.println("Failed to end HMAC operation");
65+
while (1);
66+
}
67+
68+
Serial.println("HMAC Result: ");
69+
for (int i = 0; i < sizeof(resultHMAC); i++) {
70+
char hexChar[2];
71+
sprintf(hexChar, "%02X", resultHMAC[i]);
72+
Serial.print(hexChar);
73+
Serial.print(" ");
74+
}
75+
}
76+
77+
void loop() {
78+
}

src/ECCX08.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,114 @@ int ECCX08Class::lock()
440440
return 1;
441441
}
442442

443+
444+
int ECCX08Class::beginHMAC(uint16_t keySlot)
445+
{
446+
// HMAC implementation is only for ATECC608
447+
uint8_t status;
448+
long ecc608ver = 0x0600000;
449+
long eccCurrVer = version() & 0x0F00000;
450+
451+
if (eccCurrVer != ecc608ver) {
452+
return 0;
453+
}
454+
455+
if (!wakeup()) {
456+
return 0;
457+
}
458+
459+
if (!sendCommand(0x47, 0x04, keySlot)) {
460+
return 0;
461+
}
462+
463+
delay(9);
464+
465+
if (!receiveResponse(&status, sizeof(status))) {
466+
return 0;
467+
}
468+
469+
delay(1);
470+
idle();
471+
472+
if (status != 0) {
473+
return 0;
474+
}
475+
476+
return 1;
477+
}
478+
479+
int ECCX08Class::updateHMAC(const byte data[], int length) {
480+
uint8_t status;
481+
482+
if (!wakeup()) {
483+
return 0;
484+
}
485+
486+
// Processing message
487+
int currLength = 0;
488+
while (length) {
489+
data += currLength;
490+
491+
if (length > 64) {
492+
currLength = 64;
493+
} else {
494+
currLength = length;
495+
}
496+
length -= currLength;
497+
498+
if (!sendCommand(0x47, 0x01, currLength, data, currLength)) {
499+
return 0;
500+
}
501+
502+
delay(9);
503+
504+
if (!receiveResponse(&status, sizeof(status))) {
505+
return 0;
506+
}
507+
508+
delay(1);
509+
}
510+
idle();
511+
512+
if (status != 0) {
513+
return 0;
514+
}
515+
516+
return 1;
517+
}
518+
519+
int ECCX08Class::endHMAC(byte result[])
520+
{
521+
return endHMAC(NULL, 0, result);
522+
}
523+
524+
int ECCX08Class::endHMAC(const byte data[], int length, byte result[])
525+
{
526+
if (!wakeup()) {
527+
return 0;
528+
}
529+
530+
if (!sendCommand(0x47, 0x02, length, data, length)) {
531+
return 0;
532+
}
533+
534+
delay(9);
535+
536+
if (!receiveResponse(result, 32)) {
537+
return 0;
538+
}
539+
540+
delay(1);
541+
idle();
542+
543+
return 1;
544+
}
545+
546+
int ECCX08Class::nonce(const byte data[])
547+
{
548+
return challenge(data);
549+
}
550+
443551
int ECCX08Class::wakeup()
444552
{
445553
_wire->setClock(_wakeupFrequency);

src/ECCX08.h

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ class ECCX08Class
5959
int readConfiguration(byte data[]);
6060
int lock();
6161

62+
int beginHMAC(uint16_t keySlot);
63+
int updateHMAC(const byte data[], int length);
64+
int endHMAC(byte result[]);
65+
int endHMAC(const byte data[], int length, byte result[]);
66+
67+
int nonce(const byte data[]);
68+
6269
private:
6370
int wakeup();
6471
int sleep();

0 commit comments

Comments
 (0)