I'm looking for a code and battery efficient way of generating a SHA256 signature of a string. I figured the ECC508 on the NB 1500 must either perform or use a SHA256 function for some of its functionality. Looking in the code on Gihub I do see ECCX08Class::beginSHA256(), updateSHA256 and endSHA256 functions in the ECCX08.cpp file of the ArduinoECCX08 library.
Is it possible to access these functions from my sketch? If possible, would someone be able to provide some sample code?
After some trial and error, I came up with this code to generate a SHA256 has of a string using the onboard ECC508 or ECC608 crypto chips on the MKR boards. It's working pretty well.
/*
ECCX08 SHA256 example
This sketch uses the ECC508 or ECC608 to generate a SHA256
hash of a string
Circuit:
- MKR board with ECC508 or ECC608 on board
created Dec 5 2020
by Daniel Koffler
*/
#include <ArduinoECCX08.h>
void setup() {
Serial.begin(9600);
while (!Serial);
if (!ECCX08.begin()) {
Serial.println("Failed to communicate with ECC508/ECC608!");
while (1);
}
if (!ECCX08.locked()) {
Serial.println("The ECC508/ECC608 is not locked!");
while (1);
}
//String to be hashed
String myData = "Hello=Clevland!=";
//Create a byte array of the string
byte myBytes[myData.length()];
myData.getBytes(myBytes, myData.length()+1);
Serial.print("String length: ");
Serial.println(myData.length());
Serial.print("My bytes: ");
for(int i=0; i<sizeof(myBytes); i++){
printHex(myBytes[i]);
Serial.print(" ");
}
Serial.println();
//Do Sha265
byte mySHA[32];
ECCX08.beginSHA256();
ECCX08.endSHA256(myBytes, sizeof(myBytes), mySHA);
Serial.print("SHA result: ");
for(int i=0; i<sizeof(mySHA); i++){
printHex(mySHA[i]);
//Serial.print(" ");
}
Serial.println();
}
void loop() {
}
void printHex(uint8_t num) {
char hexCar[2];
sprintf(hexCar, "%02X", num);
Serial.print(hexCar);
}
Edit: Note it only works for strings up to 63 bytes long. If the string is larger, it will return something that is not the SHA256 hash of the string
After a bit of try-and-error and having a look at the ECCX08 library I have figured out how to even Hash large Strings. You have to use the ECCX08.updateSHA256 function per each block of 64 bytes and then ECCX08.endSHA256 for the remaining bytes. The modified example is able to correctly hash a 142-character-string (The String is converted to a byte-array and then a pointer is used to send the blocks of 64 bytes to the ECCX08):
/*
ECCX08 SHA256 example
This sketch uses the ECC508 or ECC608 to generate a SHA256
hash of a string
Circuit:
- MKR board with ECC508 or ECC608 on board
created Dec 5 2020
by Daniel Koffler modified by Erich Buholzer
*/
#include <ArduinoECCX08.h>
void setup() {
Serial.begin(9600);
while (!Serial);
if (!ECCX08.begin()) {
Serial.println("Failed to communicate with ECC508/ECC608!");
while (1);
}
if (!ECCX08.locked()) {
Serial.println("The ECC508/ECC608 is not locked!");
while (1);
}
//String to be hashed
String data_str = "ThisIsATextWithAround142LettersToTestSHA256CalculationWithMyArduinoMKR1010WhichIsNowEvenExtendedToASizeOfLargerThan128CharactersForLongTesting";
//Convert the string to a byte array
int data_len = data_str.length();
Serial.print("Length: ");
Serial.println(data_len);
byte data_bytes[data_len + 1];
data_str.getBytes(data_bytes, data_len + 1);
for(int i=0; i < data_len; i++){
Serial.print((char) data_bytes[i]);
}
Serial.println();
for(int i=0; i < data_len; i++){
printHex(data_bytes[i]);
Serial.print(" ");
}
Serial.println();
byte *data_ptr = data_bytes;
int nbr_blocks = data_len / 64;
byte mySHA[32];
ECCX08.beginSHA256();
for(int i=0; i < nbr_blocks; i++){
ECCX08.updateSHA256(data_ptr);
data_ptr += 64;
}
ECCX08.endSHA256(data_ptr, data_len - nbr_blocks * 64, mySHA);
Serial.print("SHA result: ");
for(int i=0; i<sizeof(mySHA); i++){
printHex(mySHA[i]);
//Serial.print(" ");
}
Serial.println();
}
void loop() {
}
void printHex(uint8_t num) {
char hexCar[2];
sprintf(hexCar, "%02X", num);
Serial.print(hexCar);
}