Skip to content

Commit

Permalink
Merge pull request mysensors#444 from fallberg/memcmp
Browse files Browse the repository at this point in the history
Add and use timing neutral memcmp for signing
  • Loading branch information
tekka007 committed May 22, 2016
2 parents 1a11c54 + 585150c commit 347bbab
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
29 changes: 29 additions & 0 deletions libraries/MySensors/core/MySigning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,32 @@ uint8_t* signerSha256Final(void) {
memcpy(sha256_hash, _soft_sha256.result(), 32);
return sha256_hash;
}

int signerMemcmp(const void* a, const void* b, size_t sz) {
int retVal;
size_t i;
int done = 0;
const uint8_t* ptrA = (const uint8_t*)a;
const uint8_t* ptrB = (const uint8_t*)b;
for (i=0; i < sz; i++) {
if (ptrA[i] == ptrB[i]) {
if (done > 0) {
done = 1;
} else {
done = 0;
}
} else {
if (done > 0) {
done = 2;
} else {
done = 3;
}
}
}
if (done > 0) {
retVal = -1;
} else {
retVal = 0;
}
return retVal;
}
14 changes: 14 additions & 0 deletions libraries/MySensors/core/MySigning.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,5 +622,19 @@ void signerSha256Update(const uint8_t* data, size_t sz);
*/
uint8_t* signerSha256Final(void);

/**
* @brief Do a timing neutral memory comparison.
*
* The function behaves similar to memcmp with the difference that it will
* always use the same number of instructions for a given number of bytes,
* no matter how the two buffers differ and the response is either 0 or -1.
*
* @param a First buffer for comparison.
* @param b Second buffer for comparison.
* @param sz The number of bytes to compare.
* @returns 0 if buffers match, -1 if they do not.
*/
int signerMemcmp(const void* a, const void* b, size_t sz);

#endif
/** @}*/
2 changes: 1 addition & 1 deletion libraries/MySensors/core/MySigningAtsha204.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ bool signerAtsha204VerifyMsg(MyMessage &msg) {
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;

// Compare the caluclated signature with the provided signature
if (memcmp(&msg.data[mGetLength(msg)], &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg))) {
if (signerMemcmp(&msg.data[mGetLength(msg)], &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg))) {
DEBUG_SIGNING_PRINTBUF(F("Signature bad: "), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg));
#ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
Expand Down
2 changes: 1 addition & 1 deletion libraries/MySensors/core/MySigningAtsha204Soft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg) {
_signing_hmac[0] = SIGNING_IDENTIFIER;

// Compare the caluclated signature with the provided signature
if (memcmp(&msg.data[mGetLength(msg)], _signing_hmac, MAX_PAYLOAD-mGetLength(msg))) {
if (signerMemcmp(&msg.data[mGetLength(msg)], _signing_hmac, MAX_PAYLOAD-mGetLength(msg))) {
DEBUG_SIGNING_PRINTBUF(F("Signature bad: "), _signing_hmac, MAX_PAYLOAD-mGetLength(msg));
#ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
Expand Down

0 comments on commit 347bbab

Please sign in to comment.