Skip to content

Commit d32226e

Browse files
committed
CXX-657 Use constant time comparison for SCRAM1 signature comparisons
Cherry-picked from server commit 618a5ef908ac5787eb80166ada3914f4db7d3c37 for SERVER-21016
1 parent f7e5d1a commit d32226e

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/mongo/crypto/mechanism_scram.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,27 @@ std::string generateClientProof(const unsigned char saltedPassword[hashSize],
181181
return base64::encode(reinterpret_cast<char*>(clientProof), hashSize);
182182
}
183183

184+
/**
185+
* Compare two arrays of bytes for equality in constant time.
186+
*
187+
* This means that the function runs for the same amount of time even if they differ. Unlike memcmp,
188+
* this function does not exit on the first difference.
189+
*
190+
* Returns true if the two arrays are equal.
191+
*
192+
* TODO: evaluate if LTO inlines or changes the code flow of this function.
193+
*/
194+
NOINLINE_DECL
195+
bool memequal(volatile const unsigned char* s1, volatile const unsigned char* s2, size_t length) {
196+
unsigned char ret = 0;
197+
198+
for (size_t i = 0; i < length; ++i) {
199+
ret |= s1[i] ^ s2[i];
200+
}
201+
202+
return ret == 0;
203+
}
204+
184205
bool verifyServerSignature(const unsigned char saltedPassword[hashSize],
185206
const std::string& authMessage,
186207
const std::string& receivedServerSignature) {
@@ -207,7 +228,14 @@ bool verifyServerSignature(const unsigned char saltedPassword[hashSize],
207228

208229
std::string encodedServerSignature =
209230
base64::encode(reinterpret_cast<char*>(serverSignature), sizeof(serverSignature));
210-
return (receivedServerSignature == encodedServerSignature);
231+
232+
if (encodedServerSignature.size() != receivedServerSignature.size()) {
233+
return false;
234+
}
235+
236+
return memequal(reinterpret_cast<const unsigned char*>(encodedServerSignature.c_str()),
237+
reinterpret_cast<const unsigned char*>(receivedServerSignature.c_str()),
238+
encodedServerSignature.size());
211239
}
212240

213241
} // namespace scram

0 commit comments

Comments
 (0)