Debugging faulty(?) Cubecell I2C connection to Cryptographic Authentication Chip - ATECC508A

I am having trouble getting my ATECC508A to work with the Heltec CubeCell (HTCC-AB01) using SparkFun’s Example (1) .

Here is the output and code:

(1) https://github.com/sparkfun/SparkFun_ATECCX08a_Arduino_Library/tree/master/examples/Example1_Configuration

Accompanying literature:
https://learn.sparkfun.com/tutorials/cryptographic-co-processor-atecc508a-qwiic-hookup-guide

I ran an I2C scanner and found the Chip at 0x60. Unfortunately, when I ran the code I got, “Failure to generate This device’s Public Key”. This string is in SparkFun’s code.

I do know that the BH1750 sketch works with the Heltec Cubcell so I can receive data from I2C connections.

I also do know that SparkFun’s Example works with the Heltec ESP32. There is a public key on the device, and it is shown by the SparkFun’s test.

Is the issue with the Wire library (2) for the CubeCell? Can I set debugging? I may have done it incorrectly, and got an 8 which by the enum is I2C_ERROR_NO_BEGIN .

(2) https://github.com/HelTecAutomation/ASR650x-Arduino/blob/master/cores/asr650x/Wire/Wire.h

The SparkFun Example also runs on an Ardunio Uno Clone.

Specs:
Uno Clone (16MHz, 32kB flash)
Cubecell (48MHz Arm, 128kB Flash, 16kB SRAM)
Heltec ESP32 (240MHz, 4M flash, 520kB SRAM)

I was able to look at the inputBuffer and found that I could get a connection to the CryptoChip with a Heltec ESP32 but not a Heltec Cubcell. I tried using a 64 byte public key and a 32 byte random number.
I am unsure why the data get scrambled. The CRC always seems to fail on the CubeCell even though I am getting some data across the i2c connection. I updated the gist.

My latest tests are below:

Try:

boolean ATECCX08A::updateRandom32Bytes(boolean debug)

(on cubecell)

Beginning of update random 32 bytes
inputBuffer: 23,21,3E,38,1B,B7,7B,B3,C,10,DE,E3,E5,2,5C,32,80,6F,61,C1,D0,74,8,F4,D1,83,18,CA,EA,57,0,F5,26,64,FF,
countGlobal: 0x23
count heard from IC (inpuBuffer[0]): 0x23
CRC[0] Calc: 0x13
CRC[1] Calc: 0xE7
Message CRC Error
End of update random 32 bytes

(on heltec esp32)

Beginning of update random 32 bytes
inputBuffer: 23,98,C4,29,3B,71,71,1,19,FB,95,3E,13,84,97,C1,6A,3B,AA,1B,F8,D3,24,11,D6,63,F7,51,14,D9,FB,6A,9,2C,CB,
countGlobal: 0x23
count heard from IC (inpuBuffer[0]): 0x23
CRC[0] Calc: 0x2C
CRC[1] Calc: 0xCB
random32Bytes: 98,C4,29,3B,71,71,1,19,FB,95,3E,13,84,97,C1,6A,3B,AA,1B,F8,D3,24,11,D6,63,F7,51,14,D9,FB,6A,9,
End of update random 32 bytes

(running the heltec esp32)

Serial Number: 01238B933F8B73D0EE
Rev Number: 00005000
Config Zone: Locked
Data/OTP Zone: Locked
Data Slot 0: Locked

Print this before recieving the response data
inputBuffer: 43,F9,C3,6F,89,64,62,33,78,BD,C0,68,D4,BC,E0,7E,D1,7C,8F,A4,86,F9,AC,C,26,13,CA,3C,8C,30,6D,7B,B6,1C,D3,67,17,B8,AC,5E,4F,EA,8A,D2,3D,C8,D0,78,3C,23,18,EE,4A,D7,A8,D,B6,E0,2,6A,D0,B0,72,A2,4F,D8,64,
Print this if I get past response Data
print this for checking the CRC count
countGlobal: 0x43
count heard from IC (inpuBuffer[0]): 0x43
CRC[0] Calc: 0xD8
CRC[1] Calc: 0x64
This device’s Public Key:

uint8_t publicKey[64] = {
0xF9, 0xC3, 0x6F, 0x89, 0x64, 0x62, 0x33, 0x78, 0xBD, 0xC0, 0x68, 0xD4, 0xBC, 0xE0, 0x7E, 0xD1,
0x7C, 0x8F, 0xA4, 0x86, 0xF9, 0xAC, 0x0C, 0x26, 0x13, 0xCA, 0x3C, 0x8C, 0x30, 0x6D, 0x7B, 0xB6,
0x1C, 0xD3, 0x67, 0x17, 0xB8, 0xAC, 0x5E, 0x4F, 0xEA, 0x8A, 0xD2, 0x3D, 0xC8, 0xD0, 0x78, 0x3C,
0x23, 0x18, 0xEE, 0x4A, 0xD7, 0xA8, 0x0D, 0xB6, 0xE0, 0x02, 0x6A, 0xD0, 0xB0, 0x72, 0xA2, 0x4F
};

(CubeCell)

Serial Number: 01238B933F8B73D0EE
Rev Number: 00005000
Config Zone: Locked
Data/OTP Zone: Locked
Data Slot 0: Locked

Print this before recieving the response data
inputBuffer: 43,F9,C3,6F,89,64,62,33,78,BD,C0,68,D4,BC,E0,7E,D1,7C,8F,A4,86,F9,AC,C,26,13,CA,3C,8C,30,6D,7B,1C,D3,67,17,B8,AC,5E,4F,EA,8A,D2,3D,C8,D0,78,3C,23,18,EE,4A,D7,A8,D,B6,E0,2,6A,D0,B0,72,A2,4F,64,FF,FF,
Print this if I get past response Data
print this for checking the CRC count
countGlobal: 0x43
count heard from IC (inpuBuffer[0]): 0x43
CRC[0] Calc: 0x6E
CRC[1] Calc: 0xCC
Message CRC Error
Failure to generate This device’s Public Key

Can you post your sketch?

I ran:


in

[SparkFun ATECCX08A Arduino Library]

with the SparkFun (MicroChipTech) ATECC508A breakout:


[SparkFun Cryptographic Co-Processor Breakout - ATECC508A (Qwiic)]

The Examples are described here:
https://learn.sparkfun.com/tutorials/cryptographic-co-processor-atecc508a-qwiic-hookup-guide
[Cryptographic Co-Processor ATECC508A (Qwiic) Hookup Guide]

actually, I threw in some debugging, so the modified code is here:

/*
Using the SparkFun Cryptographic Co-processor Breakout ATECC508a (Qwiic)
By: Pete Lewis
SparkFun Electronics
Date: August 5th, 2019
License: This code is public domain but you can buy me a beer if you use this and we meet someday (Beerware license).

Feel like supporting our work? Please buy a board from SparkFun!
https://www.sparkfun.com/products/15573

This example shows how to setup your Cryptographic Co-processor with SparkFun’s standard settings.
Configurations settings are PERMENANT
We highly encourage advanced users to do their own configuration settings.

Hardware Connections and initial setup:
Install artemis in boards manager: http://boardsmanager/All#Sparkfun_artemis
Plug in your controller board (e.g. Artemis Redboard, Nano, ATP) into your computer with USB cable.
Connect your Cryptographic Co-processor to your controller board via a qwiic cable.
Select TOOLS>>BOARD>>“SparkFun Redboard Artemis”
Select TOOLS>>PORT>> “COM 3” (note, yours may be different)
Click upload, and follow configuration prompt on serial monitor at 115200.

*/

#include <SparkFun_ATECCX08a_Arduino_Library-itwocdefault.h> //Click here to get the library: http://librarymanager/All#SparkFun_ATECCX08a
#include <Wire.h>

ATECCX08A atecc;

void setup() {
Wire.begin(); /// I think that I need to send more information to the wire library in Wire.begin()
// Wire.setTimeout(200); /// possibly I need the change the setTimeout, but changing the default timeout in the cubecell library #define I2CTIMEOUT = 10 does not seem to do much…
Serial.begin(115200);
if (atecc.begin() == true)
{
Serial.println(“Successful wakeUp(). I2C connections are good.”);
}
else
{
Serial.println(“Device not found. Check wiring.”);
while (1); // stall out forever
}

Serial.println(“Try cleaning the input buffer”);
atecc.cleanInputBuffer();
Serial.println(“End of cleaning the input buffer”);
Serial.println(“Beginning of update random 32 bytes”);
atecc.cleanInputBuffer();
atecc.updateRandom32Bytes(true);
Serial.println(“End of update random 32 bytes”);
Serial.println(“Beginning of get random int”);
atecc.cleanInputBuffer();
atecc.getRandomInt(true);
Serial.println(“End of get random int”);
printInfo(); // see function below for library calls and data handling

// Serial.printf(Wire.getErrorText(Wire.lastError()));

/* uint8_t err= Wire.endTransmission(); /
/

if (err != I2C_ERROR_OK){ // problem
Serial.printf(“Problem sending Activate command endTransmission returned %d(%s).”,Wire.lastError(), Wire.getErrorText(Wire.lastError()));
}

/
/
Serial.println(err);
*Serial.println(“test”);
*/

/* Wire.begin(); */

Serial.println(“Would you like to configure your Cryptographic Co-processor with SparkFun Standard settings? (y/n)”);
Serial.println(“Note, this is PERMANENT and cannot be changed later”);
Serial.println("***If you do not want to do this, type an ‘n’ or unplug now.***");

while (Serial.available() == 0); // wait for user input

if (Serial.read() == ‘y’)
{
Serial.println();
Serial.println(“Configuration beginning.”);

Serial.print("Write Config: \t");
if (atecc.writeConfigSparkFun() == true) Serial.println("Success!");
else Serial.println("Failure.");

Serial.print("Lock Config: \t");
if (atecc.lockConfig() == true) Serial.println("Success!");
else Serial.println("Failure.");

Serial.print("Key Creation: \t");
if (atecc.createNewKeyPair() == true) Serial.println("Success!");
else Serial.println("Failure.");

Serial.print("Lock Data-OTP: \t");
if (atecc.lockDataAndOTP() == true) Serial.println("Success!");
else Serial.println("Failure.");

Serial.print("Lock Slot 0: \t");
if (atecc.lockDataSlot0() == true) Serial.println("Success!");
else Serial.println("Failure.");

Serial.println("Configuration done.");
Serial.println();

}
else
{
Serial.println(“Unfortunately, you cannot use any features of the ATECCX08A without configuration and locking.”);
}

printInfo(); // Print info again to see lock statuses. And if all is good, print the generated public key!

}

void loop()
{
// do nothing.
}

void printInfo()
{
// Read all 128 bytes of Configuration Zone
// These will be stored in an array within the instance named: atecc.configZone[128]
atecc.readConfigZone(true); // Debug argument false (OFF)

// Print useful information from configuration zone data
Serial.println();

Serial.print(“Serial Number: \t”);
for (int i = 0 ; i < 9 ; i++)
{
if ((atecc.serialNumber[i] >> 4) == 0) Serial.print(“0”); // print preceeding high nibble if it’s zero
Serial.print(atecc.serialNumber[i], HEX);
}
Serial.println();

Serial.print(“Rev Number: \t”);
for (int i = 0 ; i < 4 ; i++)
{
if ((atecc.revisionNumber[i] >> 4) == 0) Serial.print(“0”); // print preceeding high nibble if it’s zero
Serial.print(atecc.revisionNumber[i], HEX);
}
Serial.println();

Serial.print(“Config Zone: \t”);
if (atecc.configLockStatus) Serial.println(“Locked”);
else Serial.println(“NOT Locked”);

Serial.print(“Data/OTP Zone: \t”);
if (atecc.dataOTPLockStatus) Serial.println(“Locked”);
else Serial.println(“NOT Locked”);

Serial.print(“Data Slot 0: \t”);
if (atecc.slot0LockStatus) Serial.println(“Locked”);
else Serial.println(“NOT Locked”);

Serial.println();

// if everything is locked up, then configuration is complete, so let’s print the public key
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus)
{
if(atecc.generatePublicKey() == false)
{
Serial.println(“Failure to generate This device’s Public Key”);
Serial.println();
// Serial.printf(Wire.getErrorText(Wire.lastError()));
// Serial.printf(Wire.lastError());
}
}
}

I do not quite understand. I know that the Wire.h library is slightly different for the ESP32 and the Heltec CubCell. I can plug the ATECC508A CryptoChip into the ESP32 and have it just work with the 1st SparkFun Example, however this does not happen with the CubeCell. An I2C connection is established, and I can return things like the chip serial number, the config, etc, except I get CRC errors (parts of the data is missing or out of order) for returning things like the public key and random 32 bit numbers.

I know there are a number of sensor implementations for the CubeCell. I suppose an implementation like this needs to be followed. I need to study I2C communication more. Maybe the buffer size or timing is not right for the cryptochip to CubeCell communication.

I got the CubeCell working with SparkFun Examples 1 and 2 [1]. Changing the constant ATRCC508A_MAX_REQUEST_SIZE from 32 to 96 [2] fixed the problem.

[1] https://github.com/sparkfun/SparkFun_ATECCX08a_Arduino_Library
[2] https://github.com/sparkfun/SparkFun_ATECCX08a_Arduino_Library/blob/master/src/SparkFun_ATECCX08a_Arduino_Library.h#L99