cloud9_root/src/cloud9/lib/Core/CacheDriver.cpp
// check for byte-level information leak through a (sequence) of cache misses
check for byte-level information leak through a (sequence) of cache misses
check for byte - level information leak through a ( sequence ) of cache misses
void CacheDriver::checkForByteLeakFromSequence(ExecutionState& state, TimingSolver* solver, logT& cnstrLog) {
	if (state.symbolicAddrNum == 0) {
	}
	ExecutionState cState(state);
	ref<Expr> allCnstr = NULL;
	ref<Expr> allCnstrNeg = NULL;
	int wlength = 0;
	for (unsigned II = 1; II < state.memAddrs.size(); II++) {
		ref<Expr> checkCnstr = NULL;
		ref<Expr> checkCnstrNeg = NULL;
		if (cnstrLog.count(II)) {
				checkCnstr = cnstrLog[II].first;
				checkCnstrNeg = cnstrLog[II].second;
		}
		if (coldSeqConstraintLog.count(II) && nassoc == 1) {
			if (checkCnstr.isNull()) {
				checkCnstr = coldSeqConstraintLog[II].first;
				checkCnstrNeg = coldSeqConstraintLog[II].second;
			}
			else {
				checkCnstr = OrExpr::create(checkCnstr, coldSeqConstraintLog[II].first);
				checkCnstrNeg = AndExpr::create(checkCnstrNeg, coldSeqConstraintLog[II].second);
			}
		}
		if (checkCnstr.isNull()) {
			bool nmisses = false;
			if (missConstraintLog.count(II) && missConstraintLog[II].first.isNull())
				nmisses = true;
			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 _NDEBUG
				pathCnstr->dump();
#endif
				std::pair<unsigned long, bool> missI(II, nmisses);
				if (missSeqToState.count(missI)) {
					missSeqToState[missI] = OrExpr::create(missSeqToState[missI], pathCnstr);
				} else {
					missSeqToState[missI] = pathCnstr;
				}
			}
			continue;
		}
		if (setAssocConflictCnstrLog.count(II) && nassoc > 1) {
			fprintf(stdout, "logging %lu intermediate conflicts for access %u\n", setAssocConflictCnstrLog.size(), II);
			for (unsigned JJ = 0; JJ < setAssocConflictCnstrLog[II].size(); JJ++) {
				checkCnstr = AndExpr::create(checkCnstr, setAssocConflictCnstrLog[II][JJ].first);
				checkCnstr = AndExpr::create(checkCnstr, setAssocConflictCnstrLog[II][JJ].second);
				checkCnstrNeg = AndExpr::create(checkCnstrNeg, setAssocConflictCnstrLog[II][JJ].first);
				checkCnstrNeg = AndExpr::create(checkCnstrNeg, setAssocConflictCnstrLog[II][JJ].second);
			}
		}
		allCnstr = (allCnstr.isNull()) ? checkCnstr : AndExpr::create(allCnstr, checkCnstr);
		allCnstrNeg = (allCnstrNeg.isNull()) ? checkCnstrNeg : AndExpr::create(allCnstrNeg, checkCnstrNeg);
		if (wlength < WINDOW_SIZE) {
			wlength++;
			continue;
		}
		wlength = 0;
	  int nsolution = CacheChannel::solveAllConstraints(cState, solver, allCnstr, 1);
	  int nsolutionNeg = CacheChannel::solveAllConstraints(cState, solver, allCnstrNeg, 1);
		if ((nsolution + nsolutionNeg) == 0) continue;
		for (int nbyte = 1; nbyte < SIZE_OF_SECRET; nbyte++) {
			fprintf(stdout, "\n\n###### checking potential information leak via byte %d, access %u\n\n", nbyte, II);
			bool leak = false;
			for (int value = 0x00; value <= 0xFF; value++) {
				ref<Expr> byteCnstr = constrainOneByte(state, nbyte, value);
				ref<Expr> byteLeak = AndExpr::create(byteCnstr, allCnstr);
				ref<Expr> byteLeakNeg = AndExpr::create(byteCnstr, allCnstrNeg);
				int nsolutionD = CacheChannel::solveAllConstraints(cState, solver, byteLeak, 1);
				int nsolutionDN = CacheChannel::solveAllConstraints(cState, solver, byteLeakNeg, 1);
#if 0
				if ((nsolution != nsolutionD) || (nsolutionNeg != nsolutionDN)) {
					fprintf(stdout, "\n\n##### (**) information leak detected in byte %d, access %u\n", nbyte, II);
					leak = true;
				}
#endif
				if (nsolution != nsolutionD) {
					fprintf(stdout, "\n\n##### (**)[++] information leak detected in byte %d, access %u\n", nbyte, II);
					leak = true;
				}
				if (nsolutionNeg != nsolutionDN) {
					fprintf(stdout, "\n\n##### (**)[--] information leak detected in byte %d, access %u\n", nbyte, II);
					leak = true;
				}
			}
			if (leak == false)
				fprintf(stdout, "\n\n##### NO information leak found via byte %d, access %u\n", nbyte, II);
		}
		allCnstr = NULL;
		allCnstrNeg = NULL;
	}
}
void CacheDriver :: checkForByteLeakFromSequence ( ExecutionState & state , TimingSolver * solver , logT & cnstrLog ) { if ( state . symbolicAddrNum == 0 ) { } ExecutionState cState ( state ) ; ref < Expr > allCnstr = NULL ; ref < Expr > allCnstrNeg = NULL ; int wlength = 0 ; for ( unsigned II = 1 ; II < state . memAddrs . size ( ) ; II ++ ) { ref < Expr > checkCnstr = NULL ; ref < Expr > checkCnstrNeg = NULL ; if ( cnstrLog . count ( II ) ) { checkCnstr = cnstrLog [ II ] . first ; checkCnstrNeg = cnstrLog [ II ] . second ; } if ( coldSeqConstraintLog . count ( II ) && nassoc == 1 ) { if ( checkCnstr . isNull ( ) ) { checkCnstr = coldSeqConstraintLog [ II ] . first ; checkCnstrNeg = coldSeqConstraintLog [ II ] . second ; } else { checkCnstr = OrExpr :: create ( checkCnstr , coldSeqConstraintLog [ II ] . first ) ; checkCnstrNeg = AndExpr :: create ( checkCnstrNeg , coldSeqConstraintLog [ II ] . second ) ; } } if ( checkCnstr . isNull ( ) ) { bool nmisses = false ; if ( missConstraintLog . count ( II ) && missConstraintLog [ II ] . first . isNull ( ) ) nmisses = true ; 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 _NDEBUG pathCnstr -> dump ( ) ; #endif std :: pair < unsigned long , bool > missI ( II , nmisses ) ; if ( missSeqToState . count ( missI ) ) { missSeqToState [ missI ] = OrExpr :: create ( missSeqToState [ missI ] , pathCnstr ) ; } else { missSeqToState [ missI ] = pathCnstr ; } } continue ; } if ( setAssocConflictCnstrLog . count ( II ) && nassoc > 1 ) { fprintf ( stdout , " \n " , setAssocConflictCnstrLog . size ( ) , II ) ; for ( unsigned JJ = 0 ; JJ < setAssocConflictCnstrLog [ II ] . size ( ) ; JJ ++ ) { checkCnstr = AndExpr :: create ( checkCnstr , setAssocConflictCnstrLog [ II ] [ JJ ] . first ) ; checkCnstr = AndExpr :: create ( checkCnstr , setAssocConflictCnstrLog [ II ] [ JJ ] . second ) ; checkCnstrNeg = AndExpr :: create ( checkCnstrNeg , setAssocConflictCnstrLog [ II ] [ JJ ] . first ) ; checkCnstrNeg = AndExpr :: create ( checkCnstrNeg , setAssocConflictCnstrLog [ II ] [ JJ ] . second ) ; } } allCnstr = ( allCnstr . isNull ( ) ) ? checkCnstr : AndExpr :: create ( allCnstr , checkCnstr ) ; allCnstrNeg = ( allCnstrNeg . isNull ( ) ) ? checkCnstrNeg : AndExpr :: create ( allCnstrNeg , checkCnstrNeg ) ; if ( wlength < WINDOW_SIZE ) { wlength ++ ; continue ; } wlength = 0 ; int nsolution = CacheChannel :: solveAllConstraints ( cState , solver , allCnstr , 1 ) ; int nsolutionNeg = CacheChannel :: solveAllConstraints ( cState , solver , allCnstrNeg , 1 ) ; if ( ( nsolution + nsolutionNeg ) == 0 ) continue ; for ( int nbyte = 1 ; nbyte < SIZE_OF_SECRET ; nbyte ++ ) { fprintf ( stdout , " \n \n \n \n " , nbyte , II ) ; bool leak = false ; for ( int value = 0x00 ; value <= 0xFF ; value ++ ) { ref < Expr > byteCnstr = constrainOneByte ( state , nbyte , value ) ; ref < Expr > byteLeak = AndExpr :: create ( byteCnstr , allCnstr ) ; ref < Expr > byteLeakNeg = AndExpr :: create ( byteCnstr , allCnstrNeg ) ; int nsolutionD = CacheChannel :: solveAllConstraints ( cState , solver , byteLeak , 1 ) ; int nsolutionDN = CacheChannel :: solveAllConstraints ( cState , solver , byteLeakNeg , 1 ) ; #if 0 if ( ( nsolution != nsolutionD ) || ( nsolutionNeg != nsolutionDN ) ) { fprintf ( stdout , " \n \n \n " , nbyte , II ) ; leak = true ; } #endif if ( nsolution != nsolutionD ) { fprintf ( stdout , " \n \n \n " , nbyte , II ) ; leak = true ; } if ( nsolutionNeg != nsolutionDN ) { fprintf ( stdout , " \n \n \n " , nbyte , II ) ; leak = true ; } } if ( leak == false ) fprintf ( stdout , " \n \n \n " , nbyte , II ) ; } allCnstr = NULL ; allCnstrNeg = NULL ; } }
check for byte-level information leak through a (sequence) of cache misses
check for byte - level information leak through a ( sequence ) of cache misses
/* fast path: when all addresses are constant */ /* return; */ /* sudiptac: changed due to check multiple paths */ /* check for every memory access and possible information leaks through each of them */ //for (unsigned II = 1; II < 50; II++) { /* do this optimization  only for direct-mapped caches */ /* cache hit/miss statistics is independent of data flow, so skip this access, but
		 * but record path constraints */ /* perform the following step only for set-associative caches */ /* add intermediary conflict constraints for set-associative caches */ /* end specialized computations for set-associative caches */ /* accumulate constraints in the current sliding window */ /* continue if the length of sliding window has not expired */ /* no solution exists, not an observational constraint */ /* check whether the solution is different for different value of each byte (total 256*16 calls) */ //	CacheChannel::printCacheCnstr(cState);