Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <sched.h>
- #include <signal.h>
- #include <setjmp.h>
- #define BLOCK_SIZE 4096
- #define RDTSC(x) \
- asm volatile ( \
- "mfence\n" \
- "lfence\n" \
- "rdtsc\n" \
- "shl $32, %%rdx\n" \
- "or %%rdx, %0" \
- : "=a" (x) \
- : \
- : "rdx")
- #define CLFLUSH(x) \
- asm volatile ( \
- "mfence\n" \
- "clflush (%0)\n" \
- :: "r" (x))
- static jmp_buf restore;
- static void signal_action(int signal, siginfo_t *si, void *u)
- {
- longjmp(restore, 1);
- }
- static uint64_t time_read(volatile char *ptr)
- {
- uint64_t msr1, msr2;
- RDTSC(msr1);
- (void)*ptr;
- RDTSC(msr2);
- return msr2 - msr1;
- }
- int main(int argc, char *argv[])
- {
- cpu_set_t mask;
- struct sigaction sa;
- int i;
- volatile char buf[256 * BLOCK_SIZE];
- unsigned char secret = argc > 1 ? atoi(argv[1]) : 0;
- /* SIGSEGV handler */
- sa.sa_sigaction = signal_action;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_NODEFER | SA_SIGINFO;
- sigaction(SIGSEGV, &sa, NULL);
- /* PIN to CPU0 */
- CPU_ZERO(&mask);
- CPU_SET(0, &mask);
- sched_setaffinity(0, sizeof(cpu_set_t), &mask);
- for (i = 0; i < sizeof(256 * BLOCK_SIZE); i++)
- CLFLUSH(buf + i);
- (void)buf[secret * BLOCK_SIZE];
- for (i = 1; i < 256; i++) {
- uint64_t t = time_read(buf + i * BLOCK_SIZE);
- printf("buf[% 3d] time: %lu\n", i, t);
- if (t < 1000) {
- printf("secret was %d (time: %lu)\n", i, t);
- return 0;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement