I've read in a few places[1][2][3] of the desire to make PHP's bin2hex constant time.

In what scenarios would bin2hex be vulnerable to a timing attack?

Is this below code for handling a CSRF token vulnerable to a timing attack?

// generate a CSRF token, n is some large number
$token = bin2hex(openssl_random_pseudo_bytes(n));
// ... store $token on in the PHP session and render form with CSRF token
// ... on form submission compare the form's CSRF token to the session token
hash_equals($sessionToken, $formToken);
  1. http://blog.ircmaxell.com/2014/11/its-all-about-time.html
  2. https://github.com/php/php-src/pull/909
  3. http://grokbase.com/t/php/php-internals/14bs5tmqbr/php-src-constant-time-bin2hex-implementation-909

In what scenarios would bin2hex be vulnerable to a timing attack?

The timing attack discussed in the mailing list and blog post is a cache-timing attack, which was famously demonstrated by Daniel J. Bernstein against OpenSSL's implementation of AES here (PDF).

In order for bin2hex() to be vulnerable to a timing attack, the following conditions must be met:

  1. Internally, it either indexes or branches based on the secret we are trying to protect (e.g. HMAC key). The PHP implementation does index based on what could potentially be a secret.
  2. The attacker has to be able to alter the state of the processor cache somehow. (e.g. Renting a neighbor VM on the same baremetal machine with your cloud provider and executing a strategy similar to FLUSH+RELOAD.)
  3. The attacker can rapidly issue many valid requests from a privileged network position with minimal network jitter (surprisingly trivial these days).
  4. The key we want to protect is reused. (General case; some CSRF tokens are not reused.)

The feasibility of such an attack is still an unknown, but patching this potential side-channel is actually not that difficult. The previously linked methods were derived from libsodium's bin2hex implementation, which was provided by CodesInChaos.

Is this below code for handling a CSRF token vulnerable to a timing attack?

I don't know. The bin2hex() might be a very minor concern, but not one that I can demonstrate a practical exploit for. Maybe someone in Crypto Stack Exchange can?

Update: There's a Lib for That

If you use paragonie/constant_time_encoding (which didn't exist when you asked this question), you shouldn't leak any information via cache timing.

use \ParagonIE\ConstantTime\Hex;

$rawBinary = random_bytes(32);
$data = Hex::encode($rawBinary);
$decoded = Hex::decode($data);

This library cover all of the RFC 4648 encoding schemes:

  • Hex
  • Base32
  • Base32Hex
  • Base64
  • Base64UrlSafe
  • Base64DotSlash
  • Base64DotSlashOrdered

The latter two are compatible with crypt(3).

  • You should add Libsodium's constant time bin2hex/hex2bin algorithms. – rugk Sep 19 '16 at 13:37
  • Ah just saw you already mentioned it. A bit hidden though. – rugk Sep 19 '16 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.