From b01282c7c714163d4e615d4a17f620e2f0c8caf3 Mon Sep 17 00:00:00 2001 From: Patrick Fallberg Date: Mon, 30 May 2016 18:53:29 +0200 Subject: [PATCH] Improve nonce generation in signing backends For atsha204, update seed every time and only extract the full 32-byte random value once. For both atsha204 and soft backends, XOR all random bytes with hwMillis() in order to "whiten" the random value a bit. --- .../MySensors/core/MySigningAtsha204.cpp | 20 +++++++++---------- .../MySensors/core/MySigningAtsha204Soft.cpp | 12 +++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/MySensors/core/MySigningAtsha204.cpp b/libraries/MySensors/core/MySigningAtsha204.cpp index c920539..a056770 100644 --- a/libraries/MySensors/core/MySigningAtsha204.cpp +++ b/libraries/MySensors/core/MySigningAtsha204.cpp @@ -91,7 +91,7 @@ void signerAtsha204Init(void) { bool signerAtsha204CheckTimer(void) { if (_signing_verification_ongoing) { - if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { + if (hwMillis() < _signing_timestamp || hwMillis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { DEBUG_SIGNING_PRINTBUF(F("Verification timeout"), NULL, 0); // Purge nonce memset(_signing_current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH); @@ -105,15 +105,15 @@ bool signerAtsha204CheckTimer(void) { bool signerAtsha204GetNonce(MyMessage &msg) { DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204"), NULL, 0); // Generate random number for use as nonce - // We used a basic whitening technique that takes the first byte of a new random value and builds up a 32-byte random value + // 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 + if (atsha204.sha204m_execute(SHA204_RANDOM, RANDOM_SEED_UPDATE, 0, 0, NULL, + RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) { + DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0); + return false; + } for (int i = 0; i < 32; i++) { - if (atsha204.sha204m_execute(SHA204_RANDOM, RANDOM_NO_SEED_UPDATE, 0, 0, NULL, - RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) { - DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0); - return false; - } - _signing_current_nonce[i] = _singning_rx_buffer[SHA204_BUFFER_POS_DATA]; + _signing_current_nonce[i] = _singning_rx_buffer[SHA204_BUFFER_POS_DATA+i] ^ (hwMillis()&0xFF); } memcpy(_signing_current_nonce, signerSha256(_signing_current_nonce, 32), MAX_PAYLOAD); @@ -123,11 +123,11 @@ bool signerAtsha204GetNonce(MyMessage &msg) { // Transfer the first part of the nonce to the message msg.set(_signing_current_nonce, MAX_PAYLOAD); _signing_verification_ongoing = true; - _signing_timestamp = millis(); // Set timestamp to determine when to purge nonce + _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) // Note that if message is "too" quick, and arrives before turnover, it will be rejected // but this is consider such a rare case that it is accepted and rejects are 'safe' - if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) _signing_timestamp = 0; + if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0; return true; } diff --git a/libraries/MySensors/core/MySigningAtsha204Soft.cpp b/libraries/MySensors/core/MySigningAtsha204Soft.cpp index a326b0d..b6037e4 100644 --- a/libraries/MySensors/core/MySigningAtsha204Soft.cpp +++ b/libraries/MySensors/core/MySigningAtsha204Soft.cpp @@ -99,7 +99,7 @@ void signerAtsha204SoftInit(void) { bool signerAtsha204SoftCheckTimer(void) { if (_signing_verification_ongoing) { - if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { + if (hwMillis() < _signing_timestamp || hwMillis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { DEBUG_SIGNING_PRINTBUF(F("Verification timeout"), NULL, 0); // Purge nonce memset(_signing_current_nonce, 0xAA, 32); @@ -113,11 +113,11 @@ bool signerAtsha204SoftCheckTimer(void) { bool signerAtsha204SoftGetNonce(MyMessage &msg) { DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204Soft"), NULL, 0); - // We used a basic whitening technique that takes the first byte of a new random value and builds up a 32-byte random value - // This 32-byte random value is then hashed (SHA256) to produce the resulting nonce + // We used a basic whitening technique that XORs a random byte with the current hwMillis() counter and then the byte is + // hashed (SHA256) to produce the resulting nonce _signing_sha256.init(); for (int i = 0; i < 32; i++) { - _signing_sha256.write(random(256)); + _signing_sha256.write(random(256) ^ (hwMillis()&0xFF)); } memcpy(_signing_current_nonce, _signing_sha256.result(), MAX_PAYLOAD); DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_current_nonce, 32); @@ -128,11 +128,11 @@ bool signerAtsha204SoftGetNonce(MyMessage &msg) { // Transfer the first part of the nonce to the message msg.set(_signing_current_nonce, MAX_PAYLOAD); _signing_verification_ongoing = true; - _signing_timestamp = millis(); // Set timestamp to determine when to purge nonce + _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) // Note that if message is "too" quick, and arrives before turnover, it will be rejected // but this is consider such a rare case that it is accepted and rejects are 'safe' - if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) _signing_timestamp = 0; + if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0; return true; }