Advertisement
teknoraver

time_attack.c

Jan 16th, 2018
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.48 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <sched.h>
  6. #include <signal.h>
  7. #include <setjmp.h>
  8.  
  9. #define BLOCK_SIZE  4096
  10.  
  11. #define RDTSC(x)            \
  12.     asm volatile (          \
  13.         "mfence\n"      \
  14.         "lfence\n"      \
  15.         "rdtsc\n"       \
  16.         "shl $32, %%rdx\n"  \
  17.         "or %%rdx, %0"      \
  18.         : "=a" (x)      \
  19.         :           \
  20.         : "rdx")
  21.  
  22. #define CLFLUSH(x)          \
  23.     asm volatile (          \
  24.         "mfence\n"      \
  25.         "clflush (%0)\n"    \
  26.         :: "r" (x))
  27.  
  28. static jmp_buf restore;
  29. static void signal_action(int signal, siginfo_t *si, void *u)
  30. {
  31.     longjmp(restore, 1);
  32. }
  33.  
  34. static uint64_t time_read(volatile char *ptr)
  35. {
  36.     uint64_t msr1, msr2;
  37.  
  38.     RDTSC(msr1);
  39.     (void)*ptr;
  40.     RDTSC(msr2);
  41.  
  42.     return msr2 - msr1;
  43. }
  44.  
  45. int main(int argc, char *argv[])
  46. {
  47.     cpu_set_t mask;
  48.     struct sigaction sa;
  49.     int i;
  50.     volatile char buf[256 * BLOCK_SIZE];
  51.     unsigned char secret = argc > 1 ? atoi(argv[1]) : 0;
  52.  
  53.     /* SIGSEGV handler */
  54.     sa.sa_sigaction = signal_action;
  55.     sigemptyset(&sa.sa_mask);
  56.     sa.sa_flags = SA_NODEFER | SA_SIGINFO;
  57.     sigaction(SIGSEGV, &sa, NULL);
  58.  
  59.     /* PIN to CPU0 */
  60.     CPU_ZERO(&mask);
  61.     CPU_SET(0, &mask);
  62.     sched_setaffinity(0, sizeof(cpu_set_t), &mask);
  63.  
  64.     for (i = 0; i < sizeof(256 * BLOCK_SIZE); i++)
  65.         CLFLUSH(buf + i);
  66.  
  67.     (void)buf[secret * BLOCK_SIZE];
  68.     for (i = 1; i < 256; i++) {
  69.         uint64_t t = time_read(buf + i * BLOCK_SIZE);
  70.             printf("buf[% 3d] time: %lu\n", i, t);
  71.  
  72.         if (t < 1000) {
  73.             printf("secret was %d (time: %lu)\n", i, t);
  74.             return 0;
  75.         }
  76.     }
  77.  
  78.     return 0;
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement