cloud9_root/src/cloud9/lib/Core/CacheDriver.cpp
// check for bit-level information leak through a (sequence) of cache misses
check for bit-level information leak through a (sequence) of cache misses
check for bit - level information leak through a ( sequence ) of cache misses
void CacheDriver::checkForBitLeakFromSequence(ExecutionState& state, TimingSolver* solver, logT& cnstrLog) {
	if (state.symbolicAddrNum == 0) {
		return;
	}
	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()) continue;
		if (setAssocConflictCnstrLog.count(II) && nassoc > 1) {
			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;
		for (int nbit = 0; nbit < SIZE_OF_SECRET * SIZE_OF_BYTE; nbit++) {
			ref<Expr> bitTrueCnstr = constrainOneBit(state, nbit, true);
			ref<Expr> bitFalseCnstr = constrainOneBit(state, nbit, false);
			ref<Expr> trueLeak = AndExpr::create(bitTrueCnstr, allCnstr);
			ref<Expr> falseLeak = AndExpr::create(bitFalseCnstr, allCnstr);
			fprintf(stdout, "\n\n###### (++) checking potential information leak via bit %d, access %u\n\n", nbit, II);
			int nsolutionTrue = CacheChannel::solveAllConstraints(cState, solver, trueLeak, 1);
			int nsolutionFalse = CacheChannel::solveAllConstraints(cState, solver, falseLeak, 1);
			if (nsolutionTrue != nsolutionFalse) {
				fprintf(stdout, "\n\n######## (**) potential information leak via bit %d, access %u\n", nbit, II);
				continue;
			}
			ref<Expr> trueLeakNeg = AndExpr::create(bitTrueCnstr, allCnstrNeg);
			ref<Expr> falseLeakNeg = AndExpr::create(bitFalseCnstr, allCnstrNeg);
			fprintf(stdout, "\n\n###### (--) checking potential information leak via bit %d, access %u\n\n", nbit, II);
			int nsolutionTrueNeg = CacheChannel::solveAllConstraints(cState, solver, trueLeakNeg, 1);
			int nsolutionFalseNeg = CacheChannel::solveAllConstraints(cState, solver, falseLeakNeg, 1);
			if (nsolutionTrueNeg != nsolutionFalseNeg) {
				fprintf(stdout, "\n\n######## (**) potential information leak via bit %d, access %u\n", nbit, II);
				continue;
			} else {
				fprintf(stdout, "\n\n######## NO potential information leak via bit %d, access %u\n", nbit, II);
			}
		}
	}
}
void CacheDriver :: checkForBitLeakFromSequence ( ExecutionState & state , TimingSolver * solver , logT & cnstrLog ) { if ( state . symbolicAddrNum == 0 ) { return ; } 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 ( ) ) continue ; if ( setAssocConflictCnstrLog . count ( II ) && nassoc > 1 ) { 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 ; for ( int nbit = 0 ; nbit < SIZE_OF_SECRET * SIZE_OF_BYTE ; nbit ++ ) { ref < Expr > bitTrueCnstr = constrainOneBit ( state , nbit , true ) ; ref < Expr > bitFalseCnstr = constrainOneBit ( state , nbit , false ) ; ref < Expr > trueLeak = AndExpr :: create ( bitTrueCnstr , allCnstr ) ; ref < Expr > falseLeak = AndExpr :: create ( bitFalseCnstr , allCnstr ) ; fprintf ( stdout , " \n \n \n \n " , nbit , II ) ; int nsolutionTrue = CacheChannel :: solveAllConstraints ( cState , solver , trueLeak , 1 ) ; int nsolutionFalse = CacheChannel :: solveAllConstraints ( cState , solver , falseLeak , 1 ) ; if ( nsolutionTrue != nsolutionFalse ) { fprintf ( stdout , " \n \n \n " , nbit , II ) ; continue ; } ref < Expr > trueLeakNeg = AndExpr :: create ( bitTrueCnstr , allCnstrNeg ) ; ref < Expr > falseLeakNeg = AndExpr :: create ( bitFalseCnstr , allCnstrNeg ) ; fprintf ( stdout , " \n \n \n \n " , nbit , II ) ; int nsolutionTrueNeg = CacheChannel :: solveAllConstraints ( cState , solver , trueLeakNeg , 1 ) ; int nsolutionFalseNeg = CacheChannel :: solveAllConstraints ( cState , solver , falseLeakNeg , 1 ) ; if ( nsolutionTrueNeg != nsolutionFalseNeg ) { fprintf ( stdout , " \n \n \n " , nbit , II ) ; continue ; } else { fprintf ( stdout , " \n \n \n " , nbit , II ) ; } } } }
check for bit-level information leak through a (sequence) of cache misses
check for bit - level information leak through a ( sequence ) of cache misses
/* fast path: when all addresses are constant */ /* check for every memory access and possible information leaks through each of them */ /* do this optimization only for direct-mapped caches */ /* cache hit/miss statistics is independent of data flow, so skip this access */ /* 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 */ /* otherwise, check whether any information leak (bit-level) happen through this access */ /* check satisfiability when the bit is true */ /* check satisfiability when the bit is false */ /* potential leak situation */ /* check satisfiability when the bit is true */ /* check satisfiability when the bit is false */ /* potential leak situation */