cloud9_root/src/cloud9/lib/Core/CacheDriver.cpp
// check for byte-level information leak through observing cache-miss count
check for byte-level information leak through observing cache-miss count
check for byte - level information leak through observing cache - miss count
void CacheDriver::checkForByteLeakFromMissCount(ExecutionState& state, TimingSolver* solver) {
	fprintf(stdout, "\n\n##### Number of (input)-independent cache misses = %lu #####\n\n", fixedColdMisses + fixedConflictMisses);
	fprintf(stdout, "\n\n##### Number of (input)-independent cold misses = %d #####\n\n", fixedColdMisses);
	fprintf(stdout, "\n\n##### Number of (input)-independent conflict misses = %lu #####\n\n", fixedConflictMisses);
	fflush(stdout);
	if (state.symbolicAddrNum == 0) {
		unsigned long nmisses = fixedColdMisses+fixedConflictMisses;
		ConstraintManager cm = state.constraints();
		ref<Expr> pathCnstr = NULL;
		for (ConstraintManager::constraint_iterator ci = cm.begin(); ci != cm.end(); ci++) {
			if (pathCnstr.isNull())
				pathCnstr = *ci;
			else
				pathCnstr = AndExpr::create(pathCnstr, *ci);
		}
		if (pathCnstr.isNull() == 0) {
#ifdef _DEBUG
			pathCnstr->dump();
#endif
			if (missToState.count(nmisses)) {
				missToState[nmisses] = OrExpr::create(missToState[nmisses], pathCnstr);
			} else {
				missToState[nmisses] = pathCnstr;
			}
		}
		return;
	}
	ExecutionState cState(state);
	if (nassoc == 1)
		addConflictConstraints(cState, conflictConstraintLog);
	else {
		if (strncasecmp(policy, "l", 1) == 0) {
			fprintf(stdout, "set-associative LRU cache detected");
			addConflictConstraints(cState, conflictConstraintLogLRU);
		}
		else
			assert(0 && "fatal: replacement policy is not supported");
	}
	for (int omiss = OBS_START; omiss < OBS_END; omiss++) {
		ref<Expr> missCnstr = CacheChannel::processMissCountCnstr(omiss);
		observedCacheMiss = fixedColdMisses + fixedConflictMisses + omiss;
		bool rs = CacheChannel::sanityCheck(state, fixedColdMisses+fixedConflictMisses, observedCacheMiss);
		if (rs) continue;
		if (missCnstr.isNull()) continue;
		int nsolution = CacheChannel::solveAllConstraints(cState, solver, missCnstr, 1);
		if (nsolution == 0) continue;
		for (int nbyte = 0; nbyte < SIZE_OF_SECRET; nbyte++) {
			fprintf(stdout, "\n\n###### checking potential information leak via byte %d\n\n", nbyte);
			bool leak = false;
			for (int value = 0x00; value <= 0xFF; value++) {
				ref<Expr> byteCnstr = constrainOneByte(state, nbyte, value);
				ref<Expr> byteLeak = AndExpr::create(byteCnstr, missCnstr);
				int nsolutionD = CacheChannel::solveAllConstraints(cState, solver, byteLeak, 1);
				if (nsolution != nsolutionD) {
					fprintf(stdout, "\n\n##### (**) information leak detected in byte %d\n", nbyte);
					leak = true;
				}
			}
			if (leak == false) {
				fprintf(stdout, "\n\n##### NO information leak found via byte %d\n", nbyte);
			}
		}
    exit(0);
	}
}
void CacheDriver :: checkForByteLeakFromMissCount ( ExecutionState & state , TimingSolver * solver ) { fprintf ( stdout , " \n \n \n \n " , fixedColdMisses + fixedConflictMisses ) ; fprintf ( stdout , " \n \n \n \n " , fixedColdMisses ) ; fprintf ( stdout , " \n \n \n \n " , fixedConflictMisses ) ; fflush ( stdout ) ; if ( state . symbolicAddrNum == 0 ) { unsigned long nmisses = fixedColdMisses + fixedConflictMisses ; ConstraintManager cm = state . constraints ( ) ; ref < Expr > pathCnstr = NULL ; for ( ConstraintManager :: constraint_iterator ci = cm . begin ( ) ; ci != cm . end ( ) ; ci ++ ) { if ( pathCnstr . isNull ( ) ) pathCnstr = * ci ; else pathCnstr = AndExpr :: create ( pathCnstr , * ci ) ; } if ( pathCnstr . isNull ( ) == 0 ) { #ifdef _DEBUG pathCnstr -> dump ( ) ; #endif if ( missToState . count ( nmisses ) ) { missToState [ nmisses ] = OrExpr :: create ( missToState [ nmisses ] , pathCnstr ) ; } else { missToState [ nmisses ] = pathCnstr ; } } return ; } ExecutionState cState ( state ) ; if ( nassoc == 1 ) addConflictConstraints ( cState , conflictConstraintLog ) ; else { if ( strncasecmp ( policy , " " , 1 ) == 0 ) { fprintf ( stdout , " " ) ; addConflictConstraints ( cState , conflictConstraintLogLRU ) ; } else assert ( 0 && " " ) ; } for ( int omiss = OBS_START ; omiss < OBS_END ; omiss ++ ) { ref < Expr > missCnstr = CacheChannel :: processMissCountCnstr ( omiss ) ; observedCacheMiss = fixedColdMisses + fixedConflictMisses + omiss ; bool rs = CacheChannel :: sanityCheck ( state , fixedColdMisses + fixedConflictMisses , observedCacheMiss ) ; if ( rs ) continue ; if ( missCnstr . isNull ( ) ) continue ; int nsolution = CacheChannel :: solveAllConstraints ( cState , solver , missCnstr , 1 ) ; if ( nsolution == 0 ) continue ; for ( int nbyte = 0 ; nbyte < SIZE_OF_SECRET ; nbyte ++ ) { fprintf ( stdout , " \n \n \n \n " , nbyte ) ; bool leak = false ; for ( int value = 0x00 ; value <= 0xFF ; value ++ ) { ref < Expr > byteCnstr = constrainOneByte ( state , nbyte , value ) ; ref < Expr > byteLeak = AndExpr :: create ( byteCnstr , missCnstr ) ; int nsolutionD = CacheChannel :: solveAllConstraints ( cState , solver , byteLeak , 1 ) ; if ( nsolution != nsolutionD ) { fprintf ( stdout , " \n \n \n " , nbyte ) ; leak = true ; } } if ( leak == false ) { fprintf ( stdout , " \n \n \n " , nbyte ) ; } } exit ( 0 ) ; } }
check for byte-level information leak through observing cache-miss count
check for byte - level information leak through observing cache - miss count
/* fast path: when all addresses are constant */ /* add cache-conflict and/or cold-miss related constraints */ /* the constraint log depends on the type of cache (direct-mapped or set-associative) */ /* check for different timing constraints and possible information leaks through them */ /* no solution exists, not an observational constraint */ /* check whether the solution is different for different value of each byte (total 256*16 calls) */ /* sudiptac: remove this */