Symbolic Verification of Cache Side-Channel Freedom
Total Page:16
File Type:pdf, Size:1020Kb
1 Symbolic Verification of Cache Side-channel Freedom Sudipta Chattopadhyay, Abhik Roychoudhury Abstract—Cache timing attacks allow third-party observers reasoning over multiple execution traces. To this end, we pro- to retrieve sensitive information from program executions. But, pose a symbolic verification technique within our CACHEFIX is it possible to automatically check the vulnerability of a framework. Concretely, we capture the cache behaviour of a program against cache timing attacks and then, automatically shield program executions against these attacks? For a given program via symbolic constraints over program inputs. Then, program, a cache configuration and an attack model, our we leverage recent advances on satisfiability modulo theory CACHEFIX framework either verifies the cache side-channel (SMT) and constraint solving to (dis)prove the cache side- freedom of the program or synthesizes a series of patches to channel freedom of a program. ensure cache side-channel freedom during program execution. An appealing feature of our CACHEFIX approach is to At the core of our framework is a novel symbolic verification technique based on automated abstraction refinement of cache employ symbolic reasoning over the real counterexample semantics. The power of such a framework is to allow symbolic traces. To this end, we systematically explore real counterex- reasoning over counterexample traces and to combine it with ample traces and apply such symbolic reasoning to synthesize runtime monitoring for eliminating cache side channels during patches. Each synthesized patch captures a symbolic condition program execution. Our evaluation with routines from OpenSSL, ν on input variables and a sequence of actions that needs libfixedtimefixedpoint, GDK and FourQlib libraries to be applied when the program is processed with inputs reveals that our CACHEFIX approach (dis)proves cache side- channel freedom within an average of 75 seconds. Besides, in satisfying ν. The application of a patch is guaranteed to all except one case, CACHEFIX synthesizes all patches within 20 reduce the channel capacity of the program under inspection. minutes to ensure cache side-channel freedom of the respective Moreover, if our checker terminates, then our CACHEFIX routines during execution. approach guarantees to synthesize all patches that completely shields the program against cache timing attacks [13], [7]. I. INTRODUCTION Intuitively, our CACHEFIX approach can start with a program P vulnerable to cache timing attack. Then, it leverages a Cache timing attacks [24], [23] are among the most critical systematic combination of symbolic verification and runtime side-channel attacks [25] that retrieve sensitive information monitoring to execute P with cache side-channel freedom. from program executions. Recent cache attacks [31] further It is the precision and the novel mechanism implemented show that cache side-channel attacks are practical even in within CACHEFIX that set us apart from the state of the commodity embedded processors, such as in ARM-based art. Existing works on analyzing cache side channels [22], embedded platforms [31]. The basic idea of a cache timing [14], [30] are incapable to automatically build and refine attack is to observe the timing of cache hits and misses for a abstractions for cache semantics. Besides, these works are program execution. Subsequently, the attacker use such timing not directly applicable when the underlying program does to guess the sensitive input via which the respective program not satisfy cache side-channel freedom. Given an arbitrary was activated. program, our CACHEFIX approach generates proofs of its Given the practical relevance, it is crucial to verify whether a cache side-channel freedom or generates input(s) that manifest given program (e.g. an encryption routine) satisfies cache side- the violation of cache side-channel freedom. Moreover, our channel freedom, meaning the program is not vulnerable to symbolic reasoning framework provides capabilities to sys- cache timing attacks. However, verification of such a property tematically synthesize patches and completely eliminate cache is challenging for several reasons. Firstly, the verification of side channels during program execution. cache side-channel freedom requires a systematic integration We organize the remainder of the paper as follows. After of cache semantics within the program semantics. This, in turn, providing an overview of CACHEFIX (Section II), we make is based on the derivation of a suitable abstraction of cache the following contributions: semantics. Our proposed CACHEFIX approach automatically 1) We present CACHEFIX, a novel symbolic verification builds such an abstraction and systematically refines it until framework to check the cache side-channel freedom of a proof of cache side-channel freedom is obtained or a an arbitrary program. To the best of our knowledge, real (i.e. non-spurious) counterexample is produced. Secondly, this is the first application of automated abstraction proving cache side-channel freedom of a program requires refinement and symbolic verification to check the cache S. Chattopadhyay is with the Information Systems Technology and De- behaviour of a program. sign, Singapore University of Technology and Design, Singapore. e-mail: 2) We instantiate our CACHEFIX approach with direct- (sudipta [email protected]). A. Roychoudhury is with the School of Computing, National University of mapped caches, as well as with set-associative caches Singapore, Singapore. e-mail: ([email protected]). with least recently used (LRU) and first-in-first-out 2 (FIFO) policy (Section IV-C). In Section IV-D, we show The style of encoding, as shown in Equation 2, facilitates the generalization of our CACHEFIX approach over the usage of state-of-the-art solvers for verifying cache side- timing-based attacks [13] and trace-based attacks [7]. channel freedom. 3) We discuss a systematic exploration of counterexamples In general, we note that the cache behaviour of the program to synthesize patches and to shield program executions in Figure 1(a), i.e., the cache behaviours of r1; : : : ; r4; can against cache timing attacks (Section V). We provide be formulated accurately via the following set of predicates theoretical guarantees that such patch synthesis con- related to cache semantics: verges towards completely eliminating cache side chan- tag Pred = fρset [ ρ j 1 ≤ j < i ≤ 4g (3) nels during execution. cache ji ji 4) We provide an implementation of CACHEFIX and The size of Pred cache depends on the number of memory- evaluate it with 25 routines from OpenSSL, GDK, related instructions. However, jPred cachej does not vary with FourQlib and libfixedtimefixedpoint li- the cache size. braries. Our evaluation reveals that CACHEFIX can es- Key insight in abstraction refinement: If the attacker tablish proof or generate non-spurious counterexamples observes the number of cache misses, then the cache side- within 75 seconds on average. Besides, in most cases, channel freedom holds for the program in Figure 1(a) when CACHEFIX generated all patches within 20 minutes to all feasible traces exhibit the same number of cache misses. ensure cache side-channel freedom during execution. Hence, such a property ' can be formulated as the non- Our implementation and all experimental data are pub- existence of two traces tr1 and tr2 as follows: licly available. 4 4 ! X (tr1) X (tr2) ' ≡6 9tr1; 6 9tr2 s:t: missi 6= missi (4) i=1 i=1 II. OVERVIEW where miss(tr) captures the valuation of miss in trace tr. In this section, we demonstrate the general insight behind i i Our key insight is that to establish a proof of ' (or its lack our approach through examples. We consider the simple code thereof), it is not necessary to accurately track the values of fragments in Figure 1(a)-(b) where key is a sensitive input. In all predicates in Pred (cf. Equation 3). In other words, this example, we will assume a direct-mapped cache having cache even if some predicates in Pred have unknown values, it a size of 512 bytes. For the sake of brevity, we also assume cache might be possible to (dis)prove '. This phenomenon occurs that key is stored in a register and accessing key does not due to the inherent design principle of caches and we exploit involve the cache. The mapping of different program variables this in our abstraction refinement process. into the cache appears in Figure 1(c). Finally, we assume the To realize our hypothesis, we first start with an ini- presence of an attacker who observes the number of cache tial set of predicates (possibly empty) whose values are misses in the victim program. For such an attacker, examples accurately tracked during verification. In this example, let in Figure 1(a)-(b) satisfy cache side-channel freedom if and us assume that we start with an initial set of predicates only if the number of cache misses suffered is independent of Pred = fρset; ρtag; ρset; ρtagg. The rest of the predicates key. init 13 13 23 23 in Pred n Pred are set to unknown value. With Why symbolic verification?: Cache side-channel freedom cache init this configuration at hand, CACHEFIX returns counterexample of a program critically depends on how it interacts with the traces tr and tr (cf. Equation 4) to reflect that ' does not cache. We make an observation that the program cache be- 1 2 hold for the program in Figure 1(a). In particular, the following haviour can be formulated via a well-defined set of predicates. traces are returned: To this end, let us assume set(ri) captures the cache set tr1 ≡ hmiss1 = miss3 = 1; miss2 = miss4 = 0i accessed by instruction ri and tag(ri) captures the accessed cache tag by the same instruction. Consider the instruction tr2 ≡ hmiss1 = 0; miss2 = miss3 = miss4 = 1i r in Figure 1(a). We introduce a symbolic variable miss , 3 3 Given tr1 and tr2, we check whether any of them are which we intend to set to one if r3 suffers a cache miss and spurious.