Реализация атаки по времени побочного канала

Я работаю над проектом, реализующим атаку синхронизации побочного канала в C на HMAC. Я сделал это путем вычисления шестнадцатеричного кодированного тега и побитового байтового форсирования, используя преимущества оптимизации синхронизации strcmp. Поэтому для каждой цифры в моем тестовом теге я вычисляю количество времени, которое требуется каждому шестнадцатеричному символу для проверки. Я беру шестнадцатеричный символ, который соответствует наибольшему количеству вычисленного времени, и делаю вывод, что это правильный символ в теге, и перехожу к следующему байту. Тем не менее, время strcmp очень непредсказуемо. Несмотря на то, что легко увидеть разницу во времени между сравнением двух одинаковых строк и двух совершенно разных строк, у меня возникают трудности с поиском символа, который больше всего вычисляет мою тестовую строку, когда каждая другая строка, с которой я сравниваю, очень похожа (отличается только на 1 байт).

Метод changeByte, приведенный ниже, принимает значение customTag, которое является тегом, вычисленным до этого момента времени, и пытается найти правильный байт, соответствующий индексу. changeByte вызывается n раз, где n= длина тега. hexTag - это глобальная переменная, которая является правильным тегом. timeCompleted хранит среднее время, необходимое для вычисления testTag для каждого из шестнадцатеричных символов для позиции символа. Любая помощь будет оценена, спасибо за ваше время.

// Checks if the index of the given byte is correct or not
void changeByte(unsigned char *k, unsigned char * m, unsigned char * algorithm, unsigned char * customTag, int index)
{
    long iterations=50000;
    // used for every byte sequence to test the timing
    unsigned char * tempTag = (unsigned char *)(malloc(sizeof (unsigned char)*(strlen(customTag)+1 ) ));
    sprintf(tempTag, "%s", customTag);
    int timeIndex=0;
    // stores the time completed for every respective ascii char
    double * timeCompleted = (double *)(malloc (sizeof (double) * 16));

    // iterates through hex char 0-9, a-f
    for (int i=48; i<=102;i++){
            if (i >= 58 && i <=96)continue;
            double total=0;
            for (long j=0; j<iterations; j++){
                    // calculates the time it takes to complete for every char in that position
                    tempTag[index]=(unsigned char)i;
                    struct rusage usage;
                    struct timeval start, end;
                    getrusage(RUSAGE_SELF, &usage);
                    start=usage.ru_stime;
                    for (int k=0; k<50000; k++)externalStrcmp(tempTag, hexTag); // this is just calling strcmp in another file
                    getrusage (RUSAGE_SELF, &usage);
                    end=usage.ru_stime;
}
                    double startTime=((double)start.tv_sec + (double)start.tv_usec)/10000;
                    double endTime=((double)end.tv_sec+(double)end.tv_usec)/10000;
                    total+=endTime-startTime;
            }
            double val=total/iterations;
            timeCompleted[timeIndex]=val;
            timeIndex++;                

    }
    // sets next char equal to the hex char corresponding to the index
    customTag[index]=getCorrectChar (timeCompleted);
    free(timeCompleted);
    free(tempTag);

}

// finds the highest time. The hex char corresponding with the highest time it took the
// verify function to complete is the correct one
unsigned char getCorrectChar(double * timeCompleted)
{
    double high =-1;
    int index=0;
    for (int i=0; i<16; i++){
            if (timeCompleted[i]>high){
                    high=timeCompleted[i];
                    index=i;
            }
    }
    return (index+48)<=57 ?(unsigned char) (index+48) : (unsigned char)(index+87);

}

1 ответ

Я не уверен, что это главная проблема, но вы добавляете секунды к микросекундам напрямую, как будто 1us == 1s. Это даст неверные результаты, если количество секунд в startTime и endTime различается. А коэффициент масштабирования между usec и sec составляет 1 000 000 (thx zaph). Так что это должно работать лучше:

double startTime=(double)start.tv_sec + (double)start.tv_usec/1000000;
double endTime=(double)end.tv_sec + (double)end.tv_usec/1000000;
Другие вопросы по тегам