Skip to content

Commit bf7690e

Browse files
committed
Implement generating IV using counter on chip
1 parent 83f1b7f commit bf7690e

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

examples/ECCX08AES/ECCX08AES.ino

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
ECCX08 AES-GCM
3+
4+
This sketch uses the ECC608 to compute
5+
the AES_128_GCM encryption for some data
6+
7+
*/
8+
9+
#include <ArduinoECCX08.h>
10+
11+
void setup() {
12+
Serial.begin(9600);
13+
while (!Serial);
14+
15+
if (!ECCX08.begin()) {
16+
Serial.println("Failed to communicate with ECC508/ECC608!");
17+
while (1);
18+
}
19+
20+
if (!ECCX08.locked()) {
21+
Serial.println("The ECC508/ECC608 is not locked!");
22+
while (1);
23+
}
24+
25+
byte devicePubKey[64];
26+
if (!ECCX08.generatePublicKey(0, devicePubKey)){
27+
Serial.println("Failed to generate private key.");
28+
} else {
29+
Serial.println("Device Public key:");
30+
printHex(devicePubKey, 64);
31+
}
32+
33+
byte IV[12];
34+
if (!ECCX08.AESGenIV(IV)){
35+
Serial.println("Failed to initialize IV.");
36+
} else {
37+
Serial.print("IV: ");
38+
printHex(IV, 12);
39+
}
40+
41+
}
42+
43+
void loop() {
44+
}
45+
46+
void printHex(uint8_t *data, uint8_t length) {
47+
char tmp[16];
48+
for (int i = 0; i < length; i++) {
49+
sprintf(tmp, "%.2X", data[i]);
50+
Serial.print(tmp);
51+
Serial.print(" ");
52+
}
53+
Serial.println();
54+
}

src/ECCX08.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,103 @@ int ECCX08Class::ecdh(int slot, byte mode, const byte pubKeyXandY[], byte output
354354
return 1;
355355
}
356356

357+
int ECCX08Class::AESEncrypt(byte IV[], byte ad[], byte pt[], byte ct[], byte tag[])
358+
{
359+
return 0;
360+
}
361+
362+
/** \brief Generates AES GCM initialization vector.
363+
*
364+
* \param[in,out] IV Initialization vector to be generated
365+
* (12 bytes). See
366+
* NIST Special Publication 800-38D
367+
* 8.2.1 Deterministic Construction
368+
*
369+
* \return 1 on success, otherwise 0.
370+
*/
371+
int ECCX08Class::AESGenIV(byte IV[])
372+
{
373+
// The device ID is determined by the public key in slot 0
374+
byte pubKey[64];
375+
if (!generatePublicKey(0, pubKey)){
376+
Serial.println("AESGenIV: failed to obtain device ID");
377+
return 0;
378+
}
379+
// XOR the 64 public key bytes to get 4 bytes
380+
byte deviceID[4] = {0x00};
381+
for (int i=0; i<64; i++){
382+
deviceID[i%4] ^= pubKey[i];
383+
}
384+
// First 4 bytes of IV are device ID
385+
for (int i=0; i<4; i++){
386+
IV[i] = deviceID[i];
387+
}
388+
389+
// Device only has two 4 byte counters
390+
// instead of 8 byte counter.
391+
byte counter0[4];
392+
if (!incrementCounter(0, counter0)){
393+
Serial.println("AESGenIV: failed to increment counter");
394+
// TODO: Reset counter0 and increment counter1
395+
return 0;
396+
}
397+
byte counter1[4];
398+
if (!readCounter(1, counter1)){
399+
Serial.println("AESGenIV: failed to read counter");
400+
return 0;
401+
}
402+
// Last 8 bytes of IV are counter
403+
for (int i=0; i<4; i++){
404+
// chip counter is little endian
405+
IV[11-i] = counter0[i];
406+
IV[7-i] = counter1[i];
407+
}
408+
409+
return 1;
410+
}
411+
412+
int ECCX08Class::readCounter(int slot, byte counter[])
413+
{
414+
if (!wakeup()) {
415+
return 0;
416+
}
417+
if (!sendCommand(0x24, 0x00, slot)) {
418+
return 0;
419+
}
420+
421+
delay(51);
422+
423+
if (!receiveResponse(counter, 4)) {
424+
return 0;
425+
}
426+
427+
delay(1);
428+
idle();
429+
430+
return 1;
431+
}
432+
433+
int ECCX08Class::incrementCounter(int slot, byte counter[])
434+
{
435+
if (!wakeup()) {
436+
return 0;
437+
}
438+
if (!sendCommand(0x24, 0x01, slot)) {
439+
return 0;
440+
}
441+
442+
delay(51);
443+
444+
if (!receiveResponse(counter, 4)) {
445+
return 0;
446+
}
447+
448+
delay(1);
449+
idle();
450+
451+
return 1;
452+
}
453+
357454
int ECCX08Class::readSlot(int slot, byte data[], int length)
358455
{
359456
if (slot < 0 || slot > 15) {

src/ECCX08.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ class ECCX08Class
5454
#define ECDH_MODE_TEMPKEY ((uint8_t)0x08) //!< ECDH mode: write to TempKey
5555
#define ECDH_MODE_OUTPUT ((uint8_t)0x0c) //!< ECDH mode: write to buffer
5656

57+
int AESEncrypt(byte IV[], byte ad[], byte pt[], byte ct[], byte tag[]);
58+
int AESDecrypt(byte IV[], byte ad[], byte pt[], byte ct[], byte tag[]);
59+
#define AES_MODE_ENCRYPT ((uint8_t)0x00) //!< AES mode: encrypt
60+
#define AES_MODE_GFM ((uint8_t)0x03) //!< AES mode: Galois Field Multiply
61+
int AESGenIV(byte IV[]);
62+
63+
int incrementCounter(int slot, byte counter[]);
64+
int readCounter(int slot, byte counter[]);
65+
5766
int readSlot(int slot, byte data[], int length);
5867
int writeSlot(int slot, const byte data[], int length);
5968

0 commit comments

Comments
 (0)