Skip to content

Commit 71c6c3c

Browse files
authored
Merge pull request #20 from sparkfun/release_candidate
v1.3.1
2 parents 155ccbc + e937ca2 commit 71c6c3c

3 files changed

+99
-81
lines changed

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun ATECCX08a Arduino Library
2-
version=1.3.0
2+
version=1.3.1
33
author=SparkFun Electronics <techsupport@sparkfun.com>
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Library for the Microchip ATECCX08a Cryptographic Co-processors.

src/SparkFun_ATECCX08a_Arduino_Library.cpp

+62-47
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
for the same purpose.
4040
*/
4141

42-
boolean ATECCX08A::begin(uint8_t i2caddr, TwoWire &wirePort, Stream &serialPort)
42+
bool ATECCX08A::begin(uint8_t i2caddr, TwoWire &wirePort, Stream &serialPort)
4343
{
4444
//Bring in the user's choices
4545
_i2cPort = &wirePort; //Grab which port the user wants us to use
@@ -68,7 +68,7 @@ boolean ATECCX08A::begin(uint8_t i2caddr, TwoWire &wirePort, Stream &serialPort)
6868
respond with a status, we are gonna use wakeUp() for the same purpose.
6969
*/
7070

71-
boolean ATECCX08A::wakeUp()
71+
bool ATECCX08A::wakeUp()
7272
{
7373
_i2cPort->beginTransmission(0x00); // set up to write to address "0x00",
7474
// This creates a "wake condition" where SDA is held low for at least tWLO
@@ -104,11 +104,30 @@ boolean ATECCX08A::wakeUp()
104104
Note, it will automatically go into sleep mode after watchdog timer has been reached (1.3-1.7sec).
105105
*/
106106

107-
void ATECCX08A::idleMode()
107+
bool ATECCX08A::idleMode()
108108
{
109109
_i2cPort->beginTransmission(_i2caddr); // set up to write to address
110110
_i2cPort->write(WORD_ADDRESS_VALUE_IDLE); // enter idle command (aka word address - the first part of every communication to the IC)
111-
_i2cPort->endTransmission(); // actually send it
111+
return (_i2cPort->endTransmission() == 0); // actually send it
112+
}
113+
114+
/** \brief
115+
116+
sleep()
117+
118+
The ATECCX08A is forcefully put into sleep (LOW POWER) mode and ignores all subsequent I/O transitions
119+
until the next wake flag. The contents of TempKey and RNG Seed registers are NOT retained.
120+
Idle Power Supply Current: 150nA.
121+
This helps avoid waiting for watchdog timer and immidiately puts the device in sleep mode.
122+
With this sleep/wakeup cycle, RNG seed registers are updated from internal entropy.
123+
*/
124+
125+
bool ATECCX08A::sleep()
126+
{
127+
idleMode();
128+
_i2cPort->beginTransmission(_i2caddr); // set up to write to address
129+
_i2cPort->write(WORD_ADDRESS_VALUE_SLEEP); // enter sleep command (aka word address - the first part of every communication to the IC)
130+
return (_i2cPort->endTransmission() == 0); // actually send it
112131
}
113132

114133
/** \brief
@@ -122,7 +141,7 @@ void ATECCX08A::idleMode()
122141
silicon revision.
123142
*/
124143

125-
boolean ATECCX08A::getInfo()
144+
bool ATECCX08A::getInfo()
126145
{
127146
if (!sendCommand(COMMAND_OPCODE_INFO, 0x00, 0x0000)) // param1 - 0x00 (revision mode).
128147
{
@@ -156,7 +175,7 @@ boolean ATECCX08A::getInfo()
156175
and listens for success response (0x00).
157176
*/
158177

159-
boolean ATECCX08A::lockConfig()
178+
bool ATECCX08A::lockConfig()
160179
{
161180
return lock(LOCK_MODE_ZONE_CONFIG);
162181
}
@@ -172,7 +191,7 @@ boolean ATECCX08A::lockConfig()
172191
This function also updates global variables for these other things.
173192
*/
174193

175-
boolean ATECCX08A::readConfigZone(boolean debug)
194+
bool ATECCX08A::readConfigZone(bool debug)
176195
{
177196
// read block 0, the first 32 bytes of config zone into inputBuffer
178197
read(ZONE_CONFIG, ADDRESS_CONFIG_READ_BLOCK_0, CONFIG_ZONE_READ_SIZE);
@@ -236,7 +255,7 @@ boolean ATECCX08A::readConfigZone(boolean debug)
236255
and listens for success response (0x00).
237256
*/
238257

239-
boolean ATECCX08A::lockDataAndOTP()
258+
bool ATECCX08A::lockDataAndOTP()
240259
{
241260
return lock(LOCK_MODE_ZONE_DATA_AND_OTP);
242261
}
@@ -249,7 +268,7 @@ boolean ATECCX08A::lockDataAndOTP()
249268
and listens for success response (0x00).
250269
*/
251270

252-
boolean ATECCX08A::lockDataSlot0()
271+
bool ATECCX08A::lockDataSlot0()
253272
{
254273
return lock(LOCK_MODE_SLOT0);
255274
}
@@ -262,7 +281,7 @@ boolean ATECCX08A::lockDataSlot0()
262281
and listens for success response (0x00).
263282
*/
264283

265-
boolean ATECCX08A::lock(uint8_t zone)
284+
bool ATECCX08A::lock(uint8_t zone)
266285
{
267286
if (!sendCommand(COMMAND_OPCODE_LOCK, zone, 0x0000))
268287
return false;
@@ -289,7 +308,7 @@ boolean ATECCX08A::lock(uint8_t zone)
289308

290309
/** \brief
291310
292-
updateRandom32Bytes(boolean debug)
311+
updateRandom32Bytes(bool debug)
293312
294313
This function pulls a complete random number (all 32 bytes)
295314
It stores it in a global array called random32Bytes[]
@@ -300,7 +319,7 @@ boolean ATECCX08A::lock(uint8_t zone)
300319
They are getRandomByte(), getRandomInt(), and getRandomLong().
301320
*/
302321

303-
boolean ATECCX08A::updateRandom32Bytes(boolean debug)
322+
bool ATECCX08A::updateRandom32Bytes(bool debug)
304323
{
305324
if (!sendCommand(COMMAND_OPCODE_RANDOM, 0x00, 0x0000))
306325
return false;
@@ -343,28 +362,28 @@ boolean ATECCX08A::updateRandom32Bytes(boolean debug)
343362

344363
/** \brief
345364
346-
getRandomByte(boolean debug)
365+
getRandomByte(bool debug)
347366
348367
This function returns a random byte.
349368
It calls updateRandom32Bytes(), then uses the first byte in that array for a return value.
350369
*/
351370

352-
byte ATECCX08A::getRandomByte(boolean debug)
371+
byte ATECCX08A::getRandomByte(bool debug)
353372
{
354373
updateRandom32Bytes(debug);
355374
return random32Bytes[0];
356375
}
357376

358377
/** \brief
359378
360-
getRandomInt(boolean debug)
379+
getRandomInt(bool debug)
361380
362381
This function returns a random Int.
363382
It calls updateRandom32Bytes(), then uses the first 2 bytes in that array for a return value.
364383
It bitwize ORS the first two bytes of the array into the return value.
365384
*/
366385

367-
int ATECCX08A::getRandomInt(boolean debug)
386+
int ATECCX08A::getRandomInt(bool debug)
368387
{
369388
updateRandom32Bytes(debug);
370389
int return_val;
@@ -376,14 +395,14 @@ int ATECCX08A::getRandomInt(boolean debug)
376395

377396
/** \brief
378397
379-
getRandomLong(boolean debug)
398+
getRandomLong(bool debug)
380399
381400
This function returns a random Long.
382401
It calls updateRandom32Bytes(), then uses the first 4 bytes in that array for a return value.
383402
It bitwize ORS the first 4 bytes of the array into the return value.
384403
*/
385404

386-
long ATECCX08A::getRandomLong(boolean debug)
405+
long ATECCX08A::getRandomLong(bool debug)
387406
{
388407
updateRandom32Bytes(debug);
389408
long return_val;
@@ -430,7 +449,7 @@ long ATECCX08A::random(long min, long max)
430449

431450
/** \brief
432451
433-
receiveResponseData(uint8_t length, boolean debug)
452+
receiveResponseData(uint8_t length, bool debug)
434453
435454
This function receives messages from the ATECCX08a IC (up to 128 Bytes)
436455
It will return true if it receives the correct amount of data and good CRCs.
@@ -443,7 +462,7 @@ long ATECCX08A::random(long min, long max)
443462
It needs length argument:
444463
length: length of data to receive (includes count + DATA + 2 crc bytes)
445464
*/
446-
boolean ATECCX08A::receiveResponseData(uint8_t length, boolean debug)
465+
bool ATECCX08A::receiveResponseData(uint8_t length, bool debug)
447466
{
448467

449468
// pull in data 32 bytes at at time. (necessary to avoid overflow on atmega328)
@@ -470,11 +489,11 @@ boolean ATECCX08A::receiveResponseData(uint8_t length, boolean debug)
470489
requestAmount = length; // now we're ready to pull in the last chunk.
471490
}
472491

473-
uint32_t ret = _i2cPort->requestFrom(_i2caddr, requestAmount); // request bytes from slave
492+
_i2cPort->requestFrom(_i2caddr, requestAmount); // request bytes from peripheral
474493

475494
requestAttempts++;
476495

477-
while (_i2cPort->available()) // slave may send less than requested
496+
while (_i2cPort->available()) // peripheral may send less than requested
478497
{
479498
uint8_t value = _i2cPort->read();
480499

@@ -506,14 +525,14 @@ boolean ATECCX08A::receiveResponseData(uint8_t length, boolean debug)
506525

507526
/** \brief
508527
509-
checkCount(boolean debug)
528+
checkCount(bool debug)
510529
511530
This function checks that the count byte received in the most recent message equals countGlobal
512531
Call receiveResponseData, and then imeeditately call this to check the count of the complete message.
513532
Returns true if inputBuffer[0] == countGlobal.
514533
*/
515534

516-
boolean ATECCX08A::checkCount(boolean debug)
535+
bool ATECCX08A::checkCount(bool debug)
517536
{
518537
if (debug)
519538
{
@@ -535,13 +554,13 @@ boolean ATECCX08A::checkCount(boolean debug)
535554

536555
/** \brief
537556
538-
checkCrc(boolean debug)
557+
checkCrc(bool debug)
539558
540559
This function checks that the CRC bytes received in the most recent message equals a calculated CRCs
541560
Call receiveResponseData, then call immediately call this to check the CRCs of the complete message.
542561
*/
543562

544-
boolean ATECCX08A::checkCrc(boolean debug)
563+
bool ATECCX08A::checkCrc(bool debug)
545564
{
546565
// Check CRC[0] and CRC[1] are good to go.
547566
atca_calculate_crc(countGlobal - CRC_SIZE, inputBuffer); // first calculate it
@@ -622,7 +641,7 @@ void ATECCX08A::cleanInputBuffer()
622641
Sparkfun Default Configuration Sketch calls this, and then locks the data/otp zones and slot 0.
623642
*/
624643

625-
boolean ATECCX08A::createNewKeyPair(uint16_t slot)
644+
bool ATECCX08A::createNewKeyPair(uint16_t slot)
626645
{
627646
if (!sendCommand(COMMAND_OPCODE_GENKEY, GENKEY_MODE_NEW_PRIVATE, slot))
628647
return false;
@@ -651,7 +670,7 @@ boolean ATECCX08A::createNewKeyPair(uint16_t slot)
651670

652671
/** \brief
653672
654-
generatePublicKey(uint16_t slot, boolean debug)
673+
generatePublicKey(uint16_t slot, bool debug)
655674
656675
This function uses the GENKEY command in "Public Key Computation" mode.
657676
@@ -664,7 +683,7 @@ boolean ATECCX08A::createNewKeyPair(uint16_t slot)
664683
a global variable named publicKey64Bytes for later use.
665684
*/
666685

667-
boolean ATECCX08A::generatePublicKey(uint16_t slot, boolean debug)
686+
bool ATECCX08A::generatePublicKey(uint16_t slot, bool debug)
668687
{
669688
if (!sendCommand(COMMAND_OPCODE_GENKEY, GENKEY_MODE_PUBLIC, slot))
670689
return false;
@@ -711,22 +730,21 @@ boolean ATECCX08A::generatePublicKey(uint16_t slot, boolean debug)
711730

712731
/** \brief
713732
714-
read(uint8_t zone, uint16_t address, uint8_t length, boolean debug)
733+
read(uint8_t zone, uint16_t address, uint8_t length, bool debug)
715734
716735
Reads data from the IC at a specific zone and address.
717736
Your data response will be available at inputBuffer[].
718737
719738
For more info on address encoding, see datasheet pg 58.
720739
*/
721740

722-
boolean ATECCX08A::read(uint8_t zone, uint16_t address, uint8_t length, boolean debug)
741+
bool ATECCX08A::read(uint8_t zone, uint16_t address, uint8_t length, bool debug)
723742
{
724743
return read_output(zone, address, length, NULL, debug);
725744
}
726745

727-
boolean ATECCX08A::read_output(uint8_t zone, uint16_t address, uint8_t length, uint8_t * output, boolean debug)
746+
bool ATECCX08A::read_output(uint8_t zone, uint16_t address, uint8_t length, uint8_t * output, bool debug)
728747
{
729-
int i;
730748
// adjust zone as needed for whether it's 4 or 32 bytes length read
731749
// bit 7 of zone needs to be set correctly
732750
// (0 = 4 Bytes are read)
@@ -776,7 +794,7 @@ boolean ATECCX08A::read_output(uint8_t zone, uint16_t address, uint8_t length, u
776794
For more info on zone and address encoding, see datasheet pg 58.
777795
*/
778796

779-
boolean ATECCX08A::write(uint8_t zone, uint16_t address, uint8_t *data, uint8_t length_of_data)
797+
bool ATECCX08A::write(uint8_t zone, uint16_t address, uint8_t *data, uint8_t length_of_data)
780798
{
781799
// adjust zone as needed for whether it's 4 or 32 bytes length write
782800
// bit 7 of param1 needs to be set correctly
@@ -833,7 +851,7 @@ boolean ATECCX08A::write(uint8_t zone, uint16_t address, uint8_t *data, uint8_t
833851
receives the signature and copies it to signature[].
834852
*/
835853

836-
boolean ATECCX08A::createSignature(uint8_t *data, uint16_t slot)
854+
bool ATECCX08A::createSignature(uint8_t *data, uint16_t slot)
837855
{
838856
if (!loadTempKey(data) || !signTempKey(slot))
839857
return false;
@@ -855,7 +873,7 @@ boolean ATECCX08A::createSignature(uint8_t *data, uint16_t slot)
855873
when it requests data, and this will allow us to create a unique data + signature for every communication.
856874
*/
857875

858-
boolean ATECCX08A::loadTempKey(uint8_t *data)
876+
bool ATECCX08A::loadTempKey(uint8_t *data)
859877
{
860878
if (!sendCommand(COMMAND_OPCODE_NONCE, NONCE_MODE_PASSTHROUGH, 0x0000, data, 32))
861879
return false;
@@ -891,7 +909,7 @@ boolean ATECCX08A::loadTempKey(uint8_t *data)
891909
The response from this command (the signature) is stored in global varaible signature[].
892910
*/
893911

894-
boolean ATECCX08A::signTempKey(uint16_t slot)
912+
bool ATECCX08A::signTempKey(uint16_t slot)
895913
{
896914
if (!sendCommand(COMMAND_OPCODE_SIGN, SIGN_MODE_TEMPKEY, slot))
897915
return false;
@@ -939,7 +957,7 @@ boolean ATECCX08A::signTempKey(uint16_t slot)
939957
Note, it acutally uses loadTempKey, then uses the verify command in "external public key" mode.
940958
*/
941959

942-
boolean ATECCX08A::verifySignature(uint8_t *message, uint8_t *signature, uint8_t *publicKey)
960+
bool ATECCX08A::verifySignature(uint8_t *message, uint8_t *signature, uint8_t *publicKey)
943961
{
944962
uint8_t data_sigAndPub[128];
945963

@@ -975,7 +993,7 @@ boolean ATECCX08A::verifySignature(uint8_t *message, uint8_t *signature, uint8_t
975993
return true;
976994
}
977995

978-
boolean ATECCX08A::sha256(uint8_t * plain, size_t len, uint8_t * hash)
996+
bool ATECCX08A::sha256(uint8_t * plain, size_t len, uint8_t * hash)
979997
{
980998
int i;
981999
size_t chunks = len / SHA_BLOCK_SIZE + !!(len % SHA_BLOCK_SIZE);
@@ -991,7 +1009,6 @@ boolean ATECCX08A::sha256(uint8_t * plain, size_t len, uint8_t * hash)
9911009
for (i = 0; i < chunks; ++i)
9921010
{
9931011
size_t data_size = SHA_BLOCK_SIZE;
994-
uint8_t chunk[SHA_BLOCK_SIZE];
9951012

9961013
delay(9);
9971014

@@ -1051,11 +1068,11 @@ boolean ATECCX08A::sha256(uint8_t * plain, size_t len, uint8_t * hash)
10511068
Returns true if write commands were successful.
10521069
*/
10531070

1054-
boolean ATECCX08A::writeConfigSparkFun()
1071+
bool ATECCX08A::writeConfigSparkFun()
10551072
{
10561073
// keep track of our write command results.
1057-
boolean result1;
1058-
boolean result2;
1074+
bool result1;
1075+
bool result2;
10591076

10601077
// set keytype on slot 0 and 1 to 0x3300
10611078
// Lockable, ECC, PuInfo set (public key always allowed to be generated), contains a private Key
@@ -1084,7 +1101,7 @@ boolean ATECCX08A::writeConfigSparkFun()
10841101
So those specific transmissions are handled in unique functions.
10851102
*/
10861103

1087-
boolean ATECCX08A::sendCommand(uint8_t command_opcode, uint8_t param1, uint16_t param2, uint8_t *data, size_t length_of_data)
1104+
bool ATECCX08A::sendCommand(uint8_t command_opcode, uint8_t param1, uint16_t param2, uint8_t *data, size_t length_of_data)
10881105
{
10891106
// build packet array (total_transmission) to send a communication to IC, with opcode COMMAND
10901107
// It expects to see: word address, count, command opcode, param1, param2, data (optional), CRC[0], CRC[1]
@@ -1129,7 +1146,5 @@ boolean ATECCX08A::sendCommand(uint8_t command_opcode, uint8_t param1, uint16_t
11291146

11301147
_i2cPort->beginTransmission(_i2caddr);
11311148
_i2cPort->write(total_transmission, total_transmission_length);
1132-
_i2cPort->endTransmission();
1133-
1134-
return true;
1149+
return (_i2cPort->endTransmission() == 0);
11351150
}

0 commit comments

Comments
 (0)