Skip to content

Commit b01282c

Browse files
committed
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.
1 parent 6498354 commit b01282c

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

libraries/MySensors/core/MySigningAtsha204.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ void signerAtsha204Init(void) {
9191

9292
bool signerAtsha204CheckTimer(void) {
9393
if (_signing_verification_ongoing) {
94-
if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
94+
if (hwMillis() < _signing_timestamp || hwMillis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
9595
DEBUG_SIGNING_PRINTBUF(F("Verification timeout"), NULL, 0);
9696
// Purge nonce
9797
memset(_signing_current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
@@ -105,15 +105,15 @@ bool signerAtsha204CheckTimer(void) {
105105
bool signerAtsha204GetNonce(MyMessage &msg) {
106106
DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204"), NULL, 0);
107107
// Generate random number for use as nonce
108-
// We used a basic whitening technique that takes the first byte of a new random value and builds up a 32-byte random value
108+
// We used a basic whitening technique that XORs each byte in a 32byte random value with current hwMillis() counter
109109
// This 32-byte random value is then hashed (SHA256) to produce the resulting nonce
110+
if (atsha204.sha204m_execute(SHA204_RANDOM, RANDOM_SEED_UPDATE, 0, 0, NULL,
111+
RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) {
112+
DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0);
113+
return false;
114+
}
110115
for (int i = 0; i < 32; i++) {
111-
if (atsha204.sha204m_execute(SHA204_RANDOM, RANDOM_NO_SEED_UPDATE, 0, 0, NULL,
112-
RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) {
113-
DEBUG_SIGNING_PRINTBUF(F("Failed to generate nonce"), NULL, 0);
114-
return false;
115-
}
116-
_signing_current_nonce[i] = _singning_rx_buffer[SHA204_BUFFER_POS_DATA];
116+
_signing_current_nonce[i] = _singning_rx_buffer[SHA204_BUFFER_POS_DATA+i] ^ (hwMillis()&0xFF);
117117
}
118118
memcpy(_signing_current_nonce, signerSha256(_signing_current_nonce, 32), MAX_PAYLOAD);
119119

@@ -123,11 +123,11 @@ bool signerAtsha204GetNonce(MyMessage &msg) {
123123
// Transfer the first part of the nonce to the message
124124
msg.set(_signing_current_nonce, MAX_PAYLOAD);
125125
_signing_verification_ongoing = true;
126-
_signing_timestamp = millis(); // Set timestamp to determine when to purge nonce
126+
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
127127
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
128128
// Note that if message is "too" quick, and arrives before turnover, it will be rejected
129129
// but this is consider such a rare case that it is accepted and rejects are 'safe'
130-
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) _signing_timestamp = 0;
130+
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0;
131131
return true;
132132
}
133133

libraries/MySensors/core/MySigningAtsha204Soft.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void signerAtsha204SoftInit(void) {
9999

100100
bool signerAtsha204SoftCheckTimer(void) {
101101
if (_signing_verification_ongoing) {
102-
if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
102+
if (hwMillis() < _signing_timestamp || hwMillis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
103103
DEBUG_SIGNING_PRINTBUF(F("Verification timeout"), NULL, 0);
104104
// Purge nonce
105105
memset(_signing_current_nonce, 0xAA, 32);
@@ -113,11 +113,11 @@ bool signerAtsha204SoftCheckTimer(void) {
113113
bool signerAtsha204SoftGetNonce(MyMessage &msg) {
114114
DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204Soft"), NULL, 0);
115115

116-
// We used a basic whitening technique that takes the first byte of a new random value and builds up a 32-byte random value
117-
// This 32-byte random value is then hashed (SHA256) to produce the resulting nonce
116+
// We used a basic whitening technique that XORs a random byte with the current hwMillis() counter and then the byte is
117+
// hashed (SHA256) to produce the resulting nonce
118118
_signing_sha256.init();
119119
for (int i = 0; i < 32; i++) {
120-
_signing_sha256.write(random(256));
120+
_signing_sha256.write(random(256) ^ (hwMillis()&0xFF));
121121
}
122122
memcpy(_signing_current_nonce, _signing_sha256.result(), MAX_PAYLOAD);
123123
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_current_nonce, 32);
@@ -128,11 +128,11 @@ bool signerAtsha204SoftGetNonce(MyMessage &msg) {
128128
// Transfer the first part of the nonce to the message
129129
msg.set(_signing_current_nonce, MAX_PAYLOAD);
130130
_signing_verification_ongoing = true;
131-
_signing_timestamp = millis(); // Set timestamp to determine when to purge nonce
131+
_signing_timestamp = hwMillis(); // Set timestamp to determine when to purge nonce
132132
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
133133
// Note that if message is "too" quick, and arrives before turnover, it will be rejected
134134
// but this is consider such a rare case that it is accepted and rejects are 'safe'
135-
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) _signing_timestamp = 0;
135+
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0;
136136
return true;
137137
}
138138

0 commit comments

Comments
 (0)