Skip to content

Commit

Permalink
Signing support with MAX_PAYLOAD>32
Browse files Browse the repository at this point in the history
Support in the signing backends to handle configurations
where MAX_PAYLOAD is more than 32 bytes.

Fixes mysensors#748
  • Loading branch information
fallberg committed Jan 18, 2017
1 parent c90ff65 commit 86e6216
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 36 deletions.
50 changes: 28 additions & 22 deletions core/MySigningAtsha204.cpp
Expand Up @@ -125,15 +125,17 @@ bool signerAtsha204GetNonce(MyMessage &msg)
for (int i = 0; i < 32; i++) {
_signing_verifying_nonce[i] = _signing_rx_buffer[SHA204_BUFFER_POS_DATA+i] ^ (hwMillis()&0xFF);
}
memcpy(_signing_verifying_nonce, signerSha256(_signing_verifying_nonce, 32), MAX_PAYLOAD);
memcpy(_signing_verifying_nonce, signerSha256(_signing_verifying_nonce, 32), min(MAX_PAYLOAD, 32));

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
memset(&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_verifying_nonce)-MAX_PAYLOAD);
if (MAX_PAYLOAD < NONCE_NUMIN_SIZE_PASSTHROUGH) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, NONCE_NUMIN_SIZE_PASSTHROUGH-MAX_PAYLOAD);
}

// Transfer the first part of the nonce to the message
msg.set(_signing_verifying_nonce, MAX_PAYLOAD);
msg.set(_signing_verifying_nonce, min(MAX_PAYLOAD, NONCE_NUMIN_SIZE_PASSTHROUGH));
_signing_verification_ongoing = true;
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
Expand All @@ -149,9 +151,12 @@ void signerAtsha204PutNonce(MyMessage &msg)
{
DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204"), NULL, 0);

memcpy(_signing_signing_nonce, (uint8_t*)msg.getCustom(), MAX_PAYLOAD);
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_signing_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_signing_nonce)-MAX_PAYLOAD);
memcpy(_signing_signing_nonce, (uint8_t*)msg.getCustom(),
min(MAX_PAYLOAD, NONCE_NUMIN_SIZE_PASSTHROUGH));
if (MAX_PAYLOAD < NONCE_NUMIN_SIZE_PASSTHROUGH) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_signing_nonce[MAX_PAYLOAD], 0xAA, NONCE_NUMIN_SIZE_PASSTHROUGH-MAX_PAYLOAD);
}
}

bool signerAtsha204SignMsg(MyMessage &msg)
Expand All @@ -168,12 +173,12 @@ bool signerAtsha204SignMsg(MyMessage &msg)

if (DO_WHITELIST(msg.destination)) {
// Salt the signature with the senders nodeId and the unique serial of the ATSHA device
memcpy(_signing_signing_nonce, &_signing_rx_buffer[SHA204_BUFFER_POS_DATA],
32); // We can reuse the nonce buffer now since it is no longer needed
// We can reuse the nonce buffer now since it is no longer needed
memcpy(_signing_signing_nonce, &_signing_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
_signing_signing_nonce[32] = msg.sender;
atsha204_getSerialNumber(&_signing_signing_nonce[33]);
(void)signerSha256(_signing_signing_nonce,
32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
// We can 'void' sha256 because the hash is already put in the correct place
(void)signerSha256(_signing_signing_nonce, 32+1+SHA204_SERIAL_SZ);
DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0);
}

Expand All @@ -185,9 +190,9 @@ bool signerAtsha204SignMsg(MyMessage &msg)

// Transfer as much signature data as the remaining space in the message permits
memcpy(&msg.data[mGetLength(msg)], &_signing_rx_buffer[SHA204_BUFFER_POS_DATA],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));
DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));

return true;
}
Expand All @@ -211,7 +216,7 @@ bool signerAtsha204VerifyMsg(MyMessage &msg)
}

DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));
signerCalculateSignature(msg, false); // Get signature of message

#ifdef MY_SIGNING_NODE_WHITELISTING
Expand All @@ -220,12 +225,12 @@ bool signerAtsha204VerifyMsg(MyMessage &msg)
for (j=0; j < NUM_OF(_signing_whitelist); j++) {
if (_signing_whitelist[j].nodeId == msg.sender) {
DEBUG_SIGNING_PRINTBUF(F("Sender found in whitelist"), NULL, 0);
memcpy(_signing_verifying_nonce, &_signing_rx_buffer[SHA204_BUFFER_POS_DATA],
32); // We can reuse the nonce buffer now since it is no longer needed
// We can reuse the nonce buffer now since it is no longer needed
memcpy(_signing_verifying_nonce, &_signing_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
_signing_verifying_nonce[32] = msg.sender;
memcpy(&_signing_verifying_nonce[33], _signing_whitelist[j].serial, SHA204_SERIAL_SZ);
(void)signerSha256(_signing_verifying_nonce,
32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
// We can 'void' sha256 because the hash is already put in the correct place
(void)signerSha256(_signing_verifying_nonce, 32+1+SHA204_SERIAL_SZ);
break;
}
}
Expand All @@ -245,9 +250,9 @@ bool signerAtsha204VerifyMsg(MyMessage &msg)

// Compare the caluclated signature with the provided signature
if (signerMemcmp(&msg.data[mGetLength(msg)], &_signing_rx_buffer[SHA204_BUFFER_POS_DATA],
MAX_PAYLOAD-mGetLength(msg))) {
min(MAX_PAYLOAD-mGetLength(msg), 32))) {
DEBUG_SIGNING_PRINTBUF(F("Signature bad: "), &_signing_rx_buffer[SHA204_BUFFER_POS_DATA],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));
#ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
#endif
Expand All @@ -263,13 +268,14 @@ bool signerAtsha204VerifyMsg(MyMessage &msg)
static void signerCalculateSignature(MyMessage &msg, bool signing)
{
(void)atsha204_wakeup(_signing_temp_message);
//TODO: Rewrite this to support > 32 byte messages
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)));
min(MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)), 32));

// Program the data to sign into the ATSHA204
DEBUG_SIGNING_PRINTBUF(F("Message to process: "), (uint8_t*)&msg.data[1-HEADER_SIZE],
MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
min(MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)), 32));
DEBUG_SIGNING_PRINTBUF(F("Current nonce: "),
signing ? _signing_signing_nonce : _signing_verifying_nonce, 32);
(void)atsha204_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 8 << 3, 32,
Expand Down
33 changes: 19 additions & 14 deletions core/MySigningAtsha204Soft.cpp
Expand Up @@ -135,14 +135,16 @@ bool signerAtsha204SoftGetNonce(MyMessage &msg)
for (int i = 0; i < 32; i++) {
_signing_sha256.write(random(256) ^ (hwMillis()&0xFF));
}
memcpy(_signing_verifying_nonce, _signing_sha256.result(), MAX_PAYLOAD);
memcpy(_signing_verifying_nonce, _signing_sha256.result(), min(MAX_PAYLOAD, 32));
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_verifying_nonce, 32);

// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_verifying_nonce)-MAX_PAYLOAD);
if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_verifying_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}

// Transfer the first part of the nonce to the message
msg.set(_signing_verifying_nonce, MAX_PAYLOAD);
msg.set(_signing_verifying_nonce, min(MAX_PAYLOAD, 32));
_signing_verification_ongoing = true;
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
Expand All @@ -158,9 +160,11 @@ void signerAtsha204SoftPutNonce(MyMessage &msg)
{
DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204Soft"), NULL, 0);

memcpy(_signing_signing_nonce, (uint8_t*)msg.getCustom(), MAX_PAYLOAD);
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_signing_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_signing_nonce)-MAX_PAYLOAD);
memcpy(_signing_signing_nonce, (uint8_t*)msg.getCustom(), min(MAX_PAYLOAD, 32));
if (MAX_PAYLOAD < 32) {
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&_signing_signing_nonce[MAX_PAYLOAD], 0xAA, 32-MAX_PAYLOAD);
}
}

bool signerAtsha204SoftSignMsg(MyMessage &msg)
Expand Down Expand Up @@ -194,9 +198,9 @@ bool signerAtsha204SoftSignMsg(MyMessage &msg)
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Transfer as much signature data as the remaining space in the message permits
memcpy(&msg.data[mGetLength(msg)], _signing_hmac, MAX_PAYLOAD-mGetLength(msg));
memcpy(&msg.data[mGetLength(msg)], _signing_hmac, min(MAX_PAYLOAD-mGetLength(msg), 32));
DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));

return true;
}
Expand All @@ -221,7 +225,7 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg)

// Get signature of message
DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)],
MAX_PAYLOAD-mGetLength(msg));
min(MAX_PAYLOAD-mGetLength(msg), 32));
signerCalculateSignature(msg, false);

#ifdef MY_SIGNING_NODE_WHITELISTING
Expand Down Expand Up @@ -253,8 +257,8 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg)
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Compare the caluclated signature with the provided signature
if (signerMemcmp(&msg.data[mGetLength(msg)], _signing_hmac, MAX_PAYLOAD-mGetLength(msg))) {
DEBUG_SIGNING_PRINTBUF(F("Signature bad: "), _signing_hmac, MAX_PAYLOAD-mGetLength(msg));
if (signerMemcmp(&msg.data[mGetLength(msg)], _signing_hmac, min(MAX_PAYLOAD-mGetLength(msg), 32))) {
DEBUG_SIGNING_PRINTBUF(F("Signature bad: "), _signing_hmac, min(MAX_PAYLOAD-mGetLength(msg), 32));
#ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
#endif
Expand All @@ -269,11 +273,12 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg)
// Helper to calculate signature of msg (returned in hmac)
static void signerCalculateSignature(MyMessage &msg, bool signing)
{
//TODO: Rewrite this to support > 32 byte messages while still retaining compatibility with ATSHA204A
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)));
min(MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)), 32));
DEBUG_SIGNING_PRINTBUF(F("Message to process: "), (uint8_t*)&msg.data[1-HEADER_SIZE],
MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
min(MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)), 32));
DEBUG_SIGNING_PRINTBUF(F("Current nonce: "),
signing ? _signing_signing_nonce : _signing_verifying_nonce, 32);

Expand Down

0 comments on commit 86e6216

Please sign in to comment.