-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Added constant time string comparison to avoid possible time-based attacks. #3836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
4f6f4d6
0a684dd
fe324cc
1aad21f
2ec42df
aca2832
b378b65
f5df475
0322c95
ba70b48
02d2e18
f581f15
9e764da
1373fee
c349b43
fd9f6e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -229,7 +229,7 @@ void ArduinoOTAClass::_onRx(){ | |
String result = _challengemd5.toString(); | ||
|
||
ota_ip.addr = (uint32_t)_ota_ip; | ||
if(result.equals(response)){ | ||
if(constantTimeEquals(result, response)){ | ||
_state = OTA_RUNUPDATE; | ||
} else { | ||
_udp_ota->append("Authentication Failed", 21); | ||
|
@@ -358,6 +358,27 @@ int ArduinoOTAClass::getCommand() { | |
return _cmd; | ||
} | ||
|
||
// To avoid possible time-based attacks present function compares given | ||
// strings in a constant time. | ||
bool ArduinoOTAClass::constantTimeEquals(const String & string1, | ||
const String & string2) { | ||
|
||
// Preliminary check | ||
if(string1.length() != string2.length()) { | ||
return false; | ||
} | ||
|
||
// Evaluates every character | ||
bool equals = true; | ||
unsigned int len = string1.length(); | ||
for(unsigned int i = 0; i < len; i++){ | ||
equals &= (string1.charAt(i) == string2.charAt(i)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be interesting to see the generated code for this loop at -O2 optimization level... I wonder whether the compiler is smart enough to convert this 'and' into 'branch-if-zero'. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. Maybe better to write not so easily optimizable code. Ill think about that |
||
} | ||
|
||
// Return result | ||
return equals; | ||
} | ||
|
||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA) | ||
ArduinoOTAClass ArduinoOTA; | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,6 +93,7 @@ class ArduinoOTAClass | |
void _onRx(void); | ||
int parseInt(void); | ||
String readStringUntil(char end); | ||
bool constantTimeEquals(const String &string1, const String &string2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: can this method be moved into String class, so reuse in other places is possible? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I'll do that |
||
}; | ||
|
||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed