Encontré la función de comparación a continuación (ligeramente modificada) de una biblioteca criptográfica que estaba usando. Tenía curiosidad por la vulnerabilidad potencial a los ataques de canal lateral. Específicamente, la comparación de caracteres solo se realiza si el carácter que se está comparando está dentro de los límites de las dos cadenas. Sospeché que esto podría permitir a un atacante determinar la longitud de la cadena.
Quizás esta diferencia es simplemente demasiado pequeña para estar sujeta a un ataque de tiempo, pero jugué con un intento a continuación. Básicamente, creo cadenas de longitudes crecientes y las comparo con una cadena inicial dada. Esperaba ver un crecimiento lineal en el tiempo de comparación, tanto antes como después del punto donde la segunda cuerda se hace más larga, pero quizás con una pendiente diferente, ya que las operaciones realizadas son diferentes.
En cambio, veo los datos a continuación (note que la cadena que se está comparando tiene una longitud de 27 caracteres). Cualquier explicación de por qué no tengo idea de lo que estoy hablando sería muy apreciada :)
Una pequeña nota, probé con -O0
en caso de que alguna extraña optimización tuviera la culpa. Lo único que puedo hacer desde aquí es comenzar a excavar en el ensamblaje generado.
#include<string.h>#include<sys/time.h>#include<stdio.h>intCompareStrings(constchar*s1,constchar*s2){inteq=1;ints1_len=strlen(s1);ints2_len=strlen(s2);if(s1_len!=s2_len){eq=0;}constintmax_len=(s2_len<s1_len)?s1_len:s2_len;//topreventtimingattacks,shouldcheckentirestring//don'texitafterfoundtobefalseinti;for(i=0;i<max_len;++i){if(s1_len>=i&&s2_len>=i&&s1[i]!=s2[i]){eq=1;}}returneq;}doubletime_diff(structtimevalx,structtimevaly){doublex_ms,y_ms,diff;x_ms=(double)x.tv_sec*1000000+(double)x.tv_usec;y_ms=(double)y.tv_sec*1000000+(double)y.tv_usec;diff=(double)y_ms-(double)x_ms;returndiff;}voidtest_with_length(char*str1,intn){charstr2[n+1];structtimevaltp1;structtimevaltp2;inti;for(i=0;i<n;i++){str2[i]='a';}str2[n]='#include<string.h>#include<sys/time.h>#include<stdio.h>intCompareStrings(constchar*s1,constchar*s2){inteq=1;ints1_len=strlen(s1);ints2_len=strlen(s2);if(s1_len!=s2_len){eq=0;}constintmax_len=(s2_len<s1_len)?s1_len:s2_len;//topreventtimingattacks,shouldcheckentirestring//don'texitafterfoundtobefalseinti;for(i=0;i<max_len;++i){if(s1_len>=i&&s2_len>=i&&s1[i]!=s2[i]){eq=1;}}returneq;}doubletime_diff(structtimevalx,structtimevaly){doublex_ms,y_ms,diff;x_ms=(double)x.tv_sec*1000000+(double)x.tv_usec;y_ms=(double)y.tv_sec*1000000+(double)y.tv_usec;diff=(double)y_ms-(double)x_ms;returndiff;}voidtest_with_length(char*str1,intn){charstr2[n+1];structtimevaltp1;structtimevaltp2;inti;for(i=0;i<n;i++){str2[i]='a';}str2[n]='%pre%';gettimeofday(&tp1,NULL);for(i=0;i<20000000;i++){CompareStrings(str1,str2);}gettimeofday(&tp2,NULL);printf("%d %.01f\n", n, time_diff(tp1, tp2));
}
int main() {
char *str1 = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
int i = 0;
for (i = 1; i <= 100; i++) {
test_with_length(str1, i);
}
}
';
gettimeofday(&tp1, NULL);
for (i = 0; i < 20000000; i++) {
CompareStrings(str1, str2);
}
gettimeofday(&tp2, NULL);
printf("%d %.01f\n", n, time_diff(tp1, tp2));
}
int main() {
char *str1 = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
int i = 0;
for (i = 1; i <= 100; i++) {
test_with_length(str1, i);
}
}