c++timing-attack

Function to count time with precision less than a millisecond


I have a function here that can make program count, wait etc with least count of 1 millisecond. But i was wondering if i can do same will lower precision. I have read other answers but they are mostly about changing to linux or sleep is guesstimate and whats more is those answers were around a decade old so maybe there might have come new function to do it.

Here's function-

void sleep(unsigned int mseconds)
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}

Actually, i was trying to make a function similar to secure_compare but i dont think it is wise idea to waste 1 millisecond(current least count) on just comparing two strings.

Here is function i made for the same -

bool secure_compare(string a,string b){
    clock_t limit=wait + clock();  //limit of time program can take to compare
    bool x = (a==b);

    if(clock()>limit){             //if time taken to compare is more increase wait so it takes this new max time for other comparisons too 
        wait = clock()-limit;
        cout<<"Error";
        secure_compare(a,b);
    }

    while(clock()<limit);         //finishing time left to make it constant time function
        return x;
}

Solution

  • You're trying to make a comparison function time-independent. There are basically two ways to do this:

    Instead of using the normal string comparison, you could implement your own comparison that compares all characters and not just up until the first mismatch, like this:

    bool match = true;
    size_t min_length = min(a.size(), b.size());
    for (size_t i = 0; i < min_length; ++i) {
        match &= (a[i] == b[i]);
    }
    return match;
    

    Here, no branching (conditional operations) takes place, so every call of this method with strings of the same length should take roughly the same time. So the only side-channel information you leak is the length of the strings you compare, but that would be difficult to hide anyways, if they are of arbitrary length.

    EDIT: Incorporating Passer By's comment:

    If we want to reduce the size leakage, we could try to round the size up and clamp the index values.

    bool match = true;
    size_t min_length = min(a.size(), b.size());
    size_t rounded_length = (min_length + 1023) / 1024 * 1024;
    for (size_t i = 0; i < rounded_length; ++i) {
        size_t clamped_i = min(i, min_length - 1);
        match &= (a[clamped_i] == b[clamped_i]);
    }
    return match;
    

    There might be a tiny cache timing sidechannel present (because we don't get any more cache misses if i > clamped_i), but since a and b should be in the cache hierarchy anyways, I doubt the difference is usable in any way.