From 86e6216c6c8c98192a6845a2823a380a0bb8f676 Mon Sep 17 00:00:00 2001 From: Patrick Fallberg Date: Wed, 18 Jan 2017 17:11:48 +0100 Subject: [PATCH] Signing support with MAX_PAYLOAD>32 Support in the signing backends to handle configurations where MAX_PAYLOAD is more than 32 bytes. Fixes #748 --- core/MySigningAtsha204.cpp | 50 +++++++++++++++++++--------------- core/MySigningAtsha204Soft.cpp | 33 ++++++++++++---------- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/core/MySigningAtsha204.cpp b/core/MySigningAtsha204.cpp index 88078a9bc..d3f8ab9a5 100644 --- a/core/MySigningAtsha204.cpp +++ b/core/MySigningAtsha204.cpp @@ -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) @@ -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) @@ -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); } @@ -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; } @@ -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 @@ -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; } } @@ -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 @@ -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, diff --git a/core/MySigningAtsha204Soft.cpp b/core/MySigningAtsha204Soft.cpp index 62490f0ca..d592d8ee3 100644 --- a/core/MySigningAtsha204Soft.cpp +++ b/core/MySigningAtsha204Soft.cpp @@ -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) @@ -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) @@ -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; } @@ -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 @@ -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 @@ -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);