>>> On 28 May 2015, at 17:03, William A Rowe Jr <wr...@rowe-clan.net 
>>> <mailto:wr...@rowe-clan.net>> wrote:
….
>>> > > On 26 May 2015, at 17:22, Dirk-Willem van Gulik <di...@webweaving.org 
>>> > > <mailto:di...@webweaving.org>> wrote:
>>> > ..
>>> > > So I think that what is needed are two (or three) functions
>>> > ...
>>> > > -     A string comparison function; where at least one string is is 
>>> > > under control of the attacker.
>>> 
Thanks for all the feedback. With a bit of help from Martijn Boekhorst and Andy 
Armstrong I got as far as:

        https://gist.github.com/dirkx/37c29dc5a82b6deb0bf0 
<https://gist.github.com/dirkx/37c29dc5a82b6deb0bf0>

which I am now testing against a wide range of settings & compilers (in essence 
running a side channel attack on it and see how far I get with the various 
variations).

However I could use some help & manual inspection ?

So if you have the time & can read assembler well - can you compile this at a 
reasonable optimizer setting and look at the assembler to confirm that key 
elements are not somehow optimized away; i.e. the innner loop is running in 
constant time. I am fairly sure about what happens on ARM and x386 — but modern 
x86 is largely voodoo to me.

Secondly - when we get to the end of the shorter string; we can either keep 
comparing to the last char or \0; or we go ‘modulo’ to the start of the string. 
Now modulo is perhaps not ideal; and seems to affect the pipeline on the XEON 
cpu (something I confess not to quite understand; and I cannot see/replicate on 
ARM).

So I would also love to have feedback on the two strategies in the code w.r.t. 
to that - and not getting hit by pipeline length; L3 caches or odd things like 
page boundaries.

Above GIST has the full code - the simpliefied version below (which does not 
have the 1024 min length).

Dw.



// MODULO version

AP_DECLARE(int) ap_timingsafe_strcmp(const char * hostile, const char * 
toProtect) {
        const unsigned char *p1 = (const unsigned char *)hostile;
        const unsigned char *p2 = (const unsigned char *) toProtect;

        size_t i1 = 1 ,i2 = 1;
        unsigned int d1 = 1, d2 = 1, res = 0;
        do {
                res |= (p1[i % i1] - p2[i % i2]);
 
                d1 &= !!p1[i % i1];
                d2 &= !!p2[i % i2];

                i1 += d1;
                i2 += d2;
                i++; 
        } while (d1); // we reveal the length of the hostile string.

        res |= (i1 - i2);
 
        return (int) res;
}
 

// Cycle at last char version

AP_DECLARE(int) ap_timingsafe_strcmp(const char * hostile, const char * 
toProtect) {
        const unsigned char *p1 = (const unsigned char *)hostile;
        const unsigned char *p2 = (const unsigned char *)toProtect;

        size_t i1 = 0 ,i2 = 0;
        unsigned int d1 = 1, d2 = 1, res = 0;
 
        do {
                res |= (p1[i1] - p2[i2]);

                d1 &= !!p1[i1];
                d2 &= !!p2[i2];

                i1 += d1;
                i2 += d2;
                i++;
        } while (d1); // we reveal the length of the hostile string. Use 
(d1|d2) and a min run-length to hide both.

        res |= (i1 - i2);
 
        return (int) res;
}



Reply via email to