Optimize ATSHA204 respose times
Instead of shutting down the ATSHA between calls in a session, it is put in idle state. This removes the need for a full resync when the device is woken and that saves time which translate to a quicker turnaround time for signed messages with HW signing. To save power, it is still shut down when not in use.
This commit is contained in:
@@ -107,6 +107,7 @@ bool signerAtsha204GetNonce(MyMessage &msg) {
|
|||||||
// Generate random number for use as nonce
|
// Generate random number for use as nonce
|
||||||
// We used a basic whitening technique that XORs each byte in a 32byte random value with current hwMillis() counter
|
// We used a basic whitening technique that XORs each byte in a 32byte random value with current hwMillis() counter
|
||||||
// This 32-byte random value is then hashed (SHA256) to produce the resulting nonce
|
// This 32-byte random value is then hashed (SHA256) to produce the resulting nonce
|
||||||
|
(void)atsha204_wakeup(_signing_temp_message);
|
||||||
if (atsha204_execute(SHA204_RANDOM, RANDOM_SEED_UPDATE, 0, 0, NULL,
|
if (atsha204_execute(SHA204_RANDOM, RANDOM_SEED_UPDATE, 0, 0, NULL,
|
||||||
RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) {
|
RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) {
|
||||||
DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0);
|
DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0);
|
||||||
@@ -117,6 +118,8 @@ bool signerAtsha204GetNonce(MyMessage &msg) {
|
|||||||
}
|
}
|
||||||
memcpy(_signing_current_nonce, signerSha256(_signing_current_nonce, 32), MAX_PAYLOAD);
|
memcpy(_signing_current_nonce, signerSha256(_signing_current_nonce, 32), MAX_PAYLOAD);
|
||||||
|
|
||||||
|
atsha204_idle(); // We just idle the chip now since we expect to use it soon when the signed message arrives
|
||||||
|
|
||||||
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
|
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
|
||||||
memset(&_signing_current_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_current_nonce)-MAX_PAYLOAD);
|
memset(&_signing_current_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_current_nonce)-MAX_PAYLOAD);
|
||||||
|
|
||||||
@@ -159,6 +162,9 @@ bool signerAtsha204SignMsg(MyMessage &msg) {
|
|||||||
DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0);
|
DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put device back to sleep
|
||||||
|
atsha204_sleep();
|
||||||
|
|
||||||
// Overwrite the first byte in the signature with the signing identifier
|
// Overwrite the first byte in the signature with the signing identifier
|
||||||
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
|
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
|
||||||
|
|
||||||
@@ -204,10 +210,15 @@ bool signerAtsha204VerifyMsg(MyMessage &msg) {
|
|||||||
}
|
}
|
||||||
if (j == NUM_OF(_signing_whitelist)) {
|
if (j == NUM_OF(_signing_whitelist)) {
|
||||||
DEBUG_SIGNING_PRINTBUF(F("Sender not found in whitelist, message rejected!"), NULL, 0);
|
DEBUG_SIGNING_PRINTBUF(F("Sender not found in whitelist, message rejected!"), NULL, 0);
|
||||||
|
// Put device back to sleep
|
||||||
|
atsha204_sleep();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Put device back to sleep
|
||||||
|
atsha204_sleep();
|
||||||
|
|
||||||
// Overwrite the first byte in the signature with the signing identifier
|
// Overwrite the first byte in the signature with the signing identifier
|
||||||
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
|
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
|
||||||
|
|
||||||
@@ -227,6 +238,7 @@ bool signerAtsha204VerifyMsg(MyMessage &msg) {
|
|||||||
|
|
||||||
// Helper to calculate signature of msg (returned in _singning_rx_buffer[SHA204_BUFFER_POS_DATA])
|
// Helper to calculate signature of msg (returned in _singning_rx_buffer[SHA204_BUFFER_POS_DATA])
|
||||||
static void signerCalculateSignature(MyMessage &msg) {
|
static void signerCalculateSignature(MyMessage &msg) {
|
||||||
|
(void)atsha204_wakeup(_signing_temp_message);
|
||||||
memset(_signing_temp_message, 0, 32);
|
memset(_signing_temp_message, 0, 32);
|
||||||
memcpy(_signing_temp_message, (uint8_t*)&msg.data[1-HEADER_SIZE], MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
|
memcpy(_signing_temp_message, (uint8_t*)&msg.data[1-HEADER_SIZE], MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
|
||||||
|
|
||||||
@@ -251,9 +263,6 @@ static void signerCalculateSignature(MyMessage &msg) {
|
|||||||
(void)atsha204_execute(SHA204_HMAC, HMAC_MODE_SOURCE_FLAG_MATCH, 0, 0, NULL,
|
(void)atsha204_execute(SHA204_HMAC, HMAC_MODE_SOURCE_FLAG_MATCH, 0, 0, NULL,
|
||||||
HMAC_COUNT, _singning_tx_buffer, HMAC_RSP_SIZE, _singning_rx_buffer);
|
HMAC_COUNT, _singning_tx_buffer, HMAC_RSP_SIZE, _singning_rx_buffer);
|
||||||
|
|
||||||
// Put device back to sleep
|
|
||||||
atsha204_sleep();
|
|
||||||
|
|
||||||
DEBUG_SIGNING_PRINTBUF(F("HMAC: "), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
|
DEBUG_SIGNING_PRINTBUF(F("HMAC: "), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,9 +283,6 @@ static uint8_t* signerSha256(const uint8_t* data, size_t sz) {
|
|||||||
(void)atsha204_execute(SHA204_SHA, SHA_CALC, 0, SHA_MSG_SIZE, _signing_temp_message,
|
(void)atsha204_execute(SHA204_SHA, SHA_CALC, 0, SHA_MSG_SIZE, _signing_temp_message,
|
||||||
SHA_COUNT_LONG, _singning_tx_buffer, SHA_RSP_SIZE_LONG, _singning_rx_buffer);
|
SHA_COUNT_LONG, _singning_tx_buffer, SHA_RSP_SIZE_LONG, _singning_rx_buffer);
|
||||||
|
|
||||||
// Put device back to sleep
|
|
||||||
atsha204_sleep();
|
|
||||||
|
|
||||||
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
|
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
|
||||||
return &_singning_rx_buffer[SHA204_BUFFER_POS_DATA];
|
return &_singning_rx_buffer[SHA204_BUFFER_POS_DATA];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer);
|
|||||||
static uint8_t swi_send_byte(uint8_t value);
|
static uint8_t swi_send_byte(uint8_t value);
|
||||||
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
|
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
|
||||||
static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address);
|
static uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address);
|
||||||
static uint8_t sha204c_wakeup(uint8_t *response);
|
|
||||||
static uint8_t sha204c_resync(uint8_t size, uint8_t *response);
|
static uint8_t sha204c_resync(uint8_t size, uint8_t *response);
|
||||||
static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, uint8_t execution_delay, uint8_t execution_timeout);
|
static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, uint8_t execution_delay, uint8_t execution_timeout);
|
||||||
|
|
||||||
@@ -218,34 +217,6 @@ static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
|
|||||||
|
|
||||||
/* Communication functions */
|
/* Communication functions */
|
||||||
|
|
||||||
static uint8_t sha204c_wakeup(uint8_t *response)
|
|
||||||
{
|
|
||||||
swi_set_signal_pin(0);
|
|
||||||
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
|
|
||||||
swi_set_signal_pin(1);
|
|
||||||
delay(SHA204_WAKEUP_DELAY);
|
|
||||||
|
|
||||||
uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
|
|
||||||
if (ret_code != SHA204_SUCCESS)
|
|
||||||
return ret_code;
|
|
||||||
|
|
||||||
// Verify status response.
|
|
||||||
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN)
|
|
||||||
ret_code = SHA204_INVALID_SIZE;
|
|
||||||
else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP)
|
|
||||||
ret_code = SHA204_COMM_FAIL;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|
|
||||||
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43))
|
|
||||||
ret_code = SHA204_BAD_CRC;
|
|
||||||
}
|
|
||||||
if (ret_code != SHA204_SUCCESS)
|
|
||||||
delay(SHA204_COMMAND_EXEC_MAX);
|
|
||||||
|
|
||||||
return ret_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
|
static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
|
||||||
{
|
{
|
||||||
// Try to re-synchronize without sending a Wake token
|
// Try to re-synchronize without sending a Wake token
|
||||||
@@ -259,7 +230,7 @@ static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
|
|||||||
// to receive a response (steps 2 and 3 of the
|
// to receive a response (steps 2 and 3 of the
|
||||||
// re-synchronization process).
|
// re-synchronization process).
|
||||||
atsha204_sleep();
|
atsha204_sleep();
|
||||||
ret_code = sha204c_wakeup(response);
|
ret_code = atsha204_wakeup(response);
|
||||||
|
|
||||||
// Translate a return value of success into one
|
// Translate a return value of success into one
|
||||||
// that indicates that the device had to be woken up
|
// that indicates that the device had to be woken up
|
||||||
@@ -486,11 +457,44 @@ void atsha204_init(uint8_t pin)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void atsha204_idle(void)
|
||||||
|
{
|
||||||
|
swi_send_byte(SHA204_SWI_FLAG_IDLE);
|
||||||
|
}
|
||||||
|
|
||||||
void atsha204_sleep(void)
|
void atsha204_sleep(void)
|
||||||
{
|
{
|
||||||
swi_send_byte(SHA204_SWI_FLAG_SLEEP);
|
swi_send_byte(SHA204_SWI_FLAG_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t atsha204_wakeup(uint8_t *response)
|
||||||
|
{
|
||||||
|
swi_set_signal_pin(0);
|
||||||
|
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
|
||||||
|
swi_set_signal_pin(1);
|
||||||
|
delay(SHA204_WAKEUP_DELAY);
|
||||||
|
|
||||||
|
uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
|
||||||
|
if (ret_code != SHA204_SUCCESS)
|
||||||
|
return ret_code;
|
||||||
|
|
||||||
|
// Verify status response.
|
||||||
|
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN)
|
||||||
|
ret_code = SHA204_INVALID_SIZE;
|
||||||
|
else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP)
|
||||||
|
ret_code = SHA204_COMM_FAIL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|
||||||
|
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43))
|
||||||
|
ret_code = SHA204_BAD_CRC;
|
||||||
|
}
|
||||||
|
if (ret_code != SHA204_SUCCESS)
|
||||||
|
delay(SHA204_COMMAND_EXEC_MAX);
|
||||||
|
|
||||||
|
return ret_code;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||||
uint8_t datalen1, uint8_t *data1, uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
|
uint8_t datalen1, uint8_t *data1, uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#if !DOXYGEN
|
#if !DOXYGEN
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
/* This is a scaled down variant of the ATSHA204 library, tweaked to meet the specific needs of MySensors. */
|
/* This is a scaled down variant of the ATSHA204 library, tweaked to meet the specific needs of the MySensors library. */
|
||||||
|
|
||||||
/* Library return codes */
|
/* Library return codes */
|
||||||
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
|
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
|
||||||
@@ -240,7 +240,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void atsha204_init(uint8_t pin);
|
void atsha204_init(uint8_t pin);
|
||||||
|
void atsha204_idle(void);
|
||||||
void atsha204_sleep(void);
|
void atsha204_sleep(void);
|
||||||
|
uint8_t atsha204_wakeup(uint8_t *response);
|
||||||
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
uint8_t atsha204_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
|
||||||
uint8_t datalen1, uint8_t *data1, uint8_t tx_size,
|
uint8_t datalen1, uint8_t *data1, uint8_t tx_size,
|
||||||
uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
|
uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
|
||||||
|
|||||||
Reference in New Issue
Block a user