@@ -38,25 +38,29 @@ private function __construct()
3838 */
3939 public static function equals ($ knownString , $ userInput )
4040 {
41- $ knownString = (string ) $ knownString ;
42- $ userInput = (string ) $ userInput ;
43-
4441 if (function_exists ('hash_equals ' )) {
4542 return hash_equals ($ knownString , $ userInput );
4643 }
4744
45+ // Avoid making unnecessary duplications of secret data
46+ if (!is_string ($ knownString )) {
47+ $ knownString = (string ) $ knownString ;
48+ }
49+
50+ if (!is_string ($ userInput )) {
51+ $ userInput = (string ) $ userInput ;
52+ }
53+
4854 $ knownLen = self ::safeStrlen ($ knownString );
4955 $ userLen = self ::safeStrlen ($ userInput );
5056
51- // Extend the known string to avoid uninitialized string offsets
52- $ knownString .= $ userInput ;
53-
5457 // Set the result to the difference between the lengths
5558 $ result = $ knownLen - $ userLen ;
5659
57- // Note that we ALWAYS iterate over the user-supplied length
58- // This is to mitigate leaking length information
59- for ($ i = 0 ; $ i < $ userLen ; $ i ++) {
60+ // Always iterate over the minimum length possible.
61+ $ iterationLen = min ($ knownLen , $ userLen );
62+
63+ for ($ i = 0 ; $ i < $ iterationLen ; $ i ++) {
6064 $ result |= (ord ($ knownString [$ i ]) ^ ord ($ userInput [$ i ]));
6165 }
6266
0 commit comments