7

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
Rob Olmos
  • 123
  • 6

1 Answers1

8

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.

<?php
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).

Scott Arciszewski
  • 835
  • 11
  • 28
  • You should add Libsodium's [constant time bin2hex/hex2bin](https://download.libsodium.org/libsodium/content/helpers/#hexadecimal-encodingdecoding) 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