Information Flow Control

Information flow determines Information security.

(End-to-end) Confidentiality no leakage, no insecure information flow

Integrity data only changed when authorized

Until now we used different security mechanisms.

Problem of security mechanisms:

  • None offer full security or end-to-end security
  • each have their own weaknesses
  • Software is always viewed as black box.

Solution: language-based approach

(Ideally automatic) formal methods for proof of security.

Proofs based on code semantics - security type checking (statically and dynamically)

  • controlling information flow
  • not being too restrictive (declassifying when necessary)

Side channels

Mechanisms to get sensitive information through the observable behaviour of a computing system.

Explicit flow information leakage through direct assignment.

Implicit flow control structure of the program. (Using HH as a guard)

Termination channels termination / non-termination.

Timing channels execution time of program, cache access time, \dots

Probabilistic channels different stochastic properties, observing behaviour of execution scheduler

Power channels Power consumption by computer

Resource exhaustion c. exhaustion of a finite, shared resource: memory space, \dots

Confidentiality, Integrity

Informal definition of Non-Interference

Non interference = formal definition of confidentiality.

Program is secure if high inputs do not interfere with low inputs.

Computation C\text{C} , with semantics C\llbracket \mathrm{C} \rrbracket (maps the input to the output or does not terminate \bot )

 mem, mem: mem =L memC mem LC mem \forall \text { mem, mem}':\\ \text{ mem }=_{L} \text { mem}^{\prime} \Rightarrow \llbracket C \rrbracket \text { mem } \approx_{L} \llbracket C \rrbracket \text { mem}^{\prime} 

where

=L=_Lmeans low memory equality

L\approx_Lmeans low view indistinguishability by attacker

Confidentiality vs. Integrity are dual

Confidentiality
Integrity

Security Types, Security Lattice

Multiple security types: One for confidentiality, one for integrity

High confidentiality means low integrity - vice versa.

=L1L2\ell=L_{1} L_{2} confidentiality level \cdot integrity level

Formal definition of non-interference

Program c\text{c} satisfies non-interference, if:

μ,v,μ,v:\forall \mu , v, \mu', v':

μv,\mu \sim_\ell v,

(c,μ)μ,(\text{c}, \mu) \stackrel{*}{\rightarrow} \mu',

(c,v)v(\text{c}, v) \stackrel{*}{\rarr} v'

uv\Rarr u' \sim_{\ell} v'

where(μv)(\mu \sim_\ell v)means thatμ\muandvvare equivalent at level\ellor lower.

This definition is incomplete:

  • termination, timing-insensitive
  • does not work with multi-threading, non-determinism

Considering Termination

If they do terminate, then they must have the same lower part.

mem≈Lmem′iffmem=⊥=mem′∨(mem≠⊥≠mem′∧mem=Lmem′)\begin{array}{c}\mathrm{mem} \approx_{\mathrm{L}} \text {mem}'\textcolor{grey}{ \text{ iff}} \\\mathrm{mem}=\perp=\mathrm{mem}^{\prime} ~\vee \left(\mathrm{mem} \neq \perp \neq \mathrm{mem}^{\prime} \wedge \mathrm{mem}=_L\mathrm{mem}^{\prime}\right)\end{array}mem≈L​mem′iffmem=⊥=mem′∨(mem=⊥=mem′∧mem=L​mem′)​

Security Type System

non-interference definition contains a universal quantification over all possible inputs → undecidable.

Static analysis

We type expressions and then enforce rules.

Good option but incomplete because of undecidability.

Insecure program might get accepted.


Assigned type

Type \ell of xx as assigned by Γ\Gamma

Γ(x)=ℓΓ⊢x:ℓ\frac{\Gamma(x)=\ell}{\Gamma \vdash x: \ell}Γ⊢x:ℓΓ(x)=ℓ​

program counterpcpc

always has the higher type: pc=max(,pc)\ell \sqcup p c = \max(\ell, p c )

Γ⊢e:ℓΓ,ℓ⊔pc⊢c1Γ,ℓ⊔pc⊢c2Γ,pc⊢ifethenc1elsec2\frac{\Gamma \vdash e: \ell \quad \Gamma, \ell \sqcup p c \vdash c_{1} \quad \Gamma, \ell \sqcup p c \vdash c_{2}}{\Gamma, p c \vdash \text { if } e \text { then } c_{1} \text { else } c_{2}}Γ,pc⊢ifethenc1​elsec2​Γ⊢e:ℓΓ,ℓ⊔pc⊢c1​Γ,ℓ⊔pc⊢c2​​
Γ⊢e:ℓΓ,ℓ⊔pc⊢cΓ,pc⊢whileedoc\frac{\Gamma \vdash e: \ell \quad \Gamma, \ell \sqcup p c \vdash c}{\Gamma, p c \vdash \text { while } e \text { do } c}Γ,pc⊢whileedocΓ⊢e:ℓΓ,ℓ⊔pc⊢c​

Explicit flow, impicit flow

If expression ee has type \ell then:

pc\ell \sqcup p c must be lower than the type of xx . (implicit flow throughpcpcand explicit flow throughΓ(x)\Gamma(x))

Γ⊢e:ℓℓ⊔pc⊑Γ(x)Γ,pc⊢x:=e\frac{\Gamma \vdash e: \ell \quad \ell \sqcup p c \sqsubseteq \Gamma(x)}{\Gamma, p c \vdash x:=e}Γ,pc⊢x:=eΓ⊢e:ℓℓ⊔pc⊑Γ(x)​

Numbernn— skip instruction — sequencing instructions

Γ⊢n:L\Gamma \vdash n: LΓ⊢n:L
Γ,pc⊢skip\Gamma, p c \vdash \text {skip }Γ,pc⊢skip
Γ,pc⊢c1Γ,pc⊢c2Γ,pc⊢c1;c2\frac{\Gamma, p c \vdash c_{1} \quad \Gamma, p c \vdash c_{2}}{\Gamma, p c \vdash c_{1} ; c_{2}}Γ,pc⊢c1​;c2​Γ,pc⊢c1​Γ,pc⊢c2​​

Declassification

Sometimes necessary to allow explicit flow ie. for checking passwords. We do not check pcΓ(x)\ell \sqcup p c \sqsubseteq \Gamma(x) anymore.

pc⊑Γ(x)Γ,pc⊢x:=declassify⁡(e)\frac{p c \sqsubseteq \Gamma(x)}{\Gamma, p c \vdash x:=\operatorname{declassify}(e)}Γ,pc⊢x:=declassify(e)pc⊑Γ(x)​

Considering Timing: hiding timing leaks

Cross-copy low slices = dummy instructions (like skip sequences) in each branch that so that both take an equal amount of time - means number of instructions per branch must be equal.

Γ⊢e:ℓΓ,ℓ⊔pc⊢c1Γ,ℓ⊔pc⊢c2c1∼c2Γ,pc⊢ifethenc1elsec2\frac{\Gamma \vdash e: \ell \quad \Gamma, \ell \sqcup p c \vdash c_{1} \quad \Gamma, \ell \sqcup p c \vdash c_{2} \quad \textcolor{pink}{c_1 \sim c_2}}{\Gamma, p c \vdash \text { if } e \text { then } c_{1} \text {else } c_{2}}Γ,pc⊢ifethenc1​elsec2​Γ⊢e:ℓΓ,ℓ⊔pc⊢c1​Γ,ℓ⊔pc⊢c2​c1​∼c2​​

The guard must be low and the entire instruction must be checked under a low pcpc . We don't want different looping times based on the guard.

Γ⊢e:LΓ,ℓ⊔pc⊢cΓ,L⊢whileedoc\frac{\Gamma \vdash e: \textcolor{pink}L \quad \Gamma, \ell \sqcup p c \vdash c}{\Gamma, \textcolor{pink}L \vdash \text { while } e \text { do } c}Γ,L⊢whileedocΓ⊢e:LΓ,ℓ⊔pc⊢c​