A Language for Probabilistically Oblivious Computation David Darais - - PowerPoint PPT Presentation

a language for probabilistically oblivious computation
SMART_READER_LITE
LIVE PREVIEW

A Language for Probabilistically Oblivious Computation David Darais - - PowerPoint PPT Presentation

A Language for Probabilistically Oblivious Computation David Darais , Ian Sweet, Chang Liu, Michael Hicks Secure Storage S[42] secret Cloud You s = S[42] Storage S[s] secret Implementation = encrypt the data Read/write indices


slide-1
SLIDE 1

A Language for Probabilistically Oblivious Computation


 David Darais, Ian Sweet, Chang Liu, Michael Hicks

slide-2
SLIDE 2

Secure Storage

You Cloud Storage

Read/write indices in the clear, cannot depend on secrets

S[42] ← secret s = S[42] S[s] ← secret

Implementation = encrypt the data

2

slide-3
SLIDE 3

Oblivious RAM

You Cloud Storage

S[42] ← secret s = S[42] S[s] ← secret

Read/write indices can depend on secrets Implementation = encrypt the data and garble indices

3

slide-4
SLIDE 4

λ-obliv

4

slide-5
SLIDE 5

…is for implementing oblivious algorithm Secure databases and secure multiparty computation Types, semantics, and proofs for probabilistic programs Publicly available implementation

λ-obliv

Oblivious
 RAM

S[secret] (read) S[secret] ← secret (write)

5

slide-6
SLIDE 6

λ-obliv

…is for implementing oblivious algorithm Secure databases and secure multiparty computation Types, semantics, and proofs for probabilistic programs Publicly available implementation

6

slide-7
SLIDE 7

ORAM basics λ-obliv design λ-obliv proof

7

slide-8
SLIDE 8

Memory Trace Obliviousness (MTO)

Adversary can see: Public values Program counter Memory (and array) access patterns Adversary can’t see: Secret values MTO if you can’t infer secret values from observations

8

slide-9
SLIDE 9

Baby Not-secure ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r = S[s] -- NOT OK

9

Adversary Observations

slide-10
SLIDE 10

Baby Not-secure ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r = S[s] -- NOT OK

10

Adversary Observations

1

slide-11
SLIDE 11

Baby Not-secure ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r = S[s] -- NOT OK Violates Memory Trace Obliviousness (MTO)

11

Adversary Observations

1 s

slide-12
SLIDE 12

Baby Trivial ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r₀ = S[0] -- read secret 0 r₁ = S[1] -- read secret 1 r, _ = mux(s, r₀, r₁) -- MTO

12

Adversary Observations

slide-13
SLIDE 13

Baby Trivial ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r₀ = S[0] -- read secret 0 r₁ = S[1] -- read secret 1 r, _ = mux(s, r₀, r₁) -- MTO

13

Adversary Observations

1

slide-14
SLIDE 14

Baby Trivial ORAM

  • - upload secrets

S[0] ← s₀ -- write secret 0 S[1] ← s₁ -- write secret 1

  • - read secret index s

r₀ = S[0] -- read secret 0 r₁ = S[1] -- read secret 1 r, _ = mux(s, r₀, r₁) -- MTO Satisfies MTO, but inefficient

14

Adversary Observations

1 1

slide-15
SLIDE 15

Probabilistic Memory Trace Obliviousness (PMTO)

15

Adversary can see: Public values Program counter Memory (and array) access patterns Adversary can’t see: Secret values AND random samples (coin flips) PMTO if you can’t infer secret values from observations

slide-16
SLIDE 16

Baby Tree ORAM

  • - upload secrets

b = flip-coin() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s]

Violates secure data/information flow
 Satisfies Probabilistic Memory Trace Obliviousness (PMTO)

16

slide-17
SLIDE 17

Baby Tree ORAM

b S b⊕s 1 1 1 1 1 1

  • - upload secrets

b = flip-coin() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s]

17

Truth table for b⊕s

slide-18
SLIDE 18

Baby Tree ORAM

b S b⊕s 1 1 1 1 1 1

  • - upload secrets

b = flip-coin() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s]

18

Truth table for b⊕s Observation: b⊕s=1

slide-19
SLIDE 19

Baby Tree ORAM

b S b⊕s 1 1 1 1 1 1

  • - upload secrets

b = flip-coin() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s]

19

Truth table for b⊕s Observation: b⊕s=1

slide-20
SLIDE 20

Baby Tree ORAM

b S b⊕s 1 1 1 1 1 1

  • - upload secrets

b = flip-coin() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s]

20

Truth table for b⊕s

  • utput(b) after S[b⊕s] would be problematic!

Observation: b⊕s=0

slide-21
SLIDE 21

ORAM basics λ-obliv design λ-obliv proof

21

slide-22
SLIDE 22

λ-obliv design challenge

How to: Allow direct flows from uniform secrets to public values Prevent revealing any value correlated with a secret

22

slide-23
SLIDE 23

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

λ-obliv features

23

Affine, uniformly distributed secret random values
 R = probability region (elements in a join semilattice)


  • Values in same region may be prob. dependent
  • Values in strictly ordered regions guaranteed prob. independent
slide-24
SLIDE 24

λ-obliv features

24

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

Non-affine, possibly random secret values
 R = probability region, ℓ = information flow label


  • Region tracks prob. dependence on random values
slide-25
SLIDE 25

λ-obliv features

25

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

Standard features like references and functions

slide-26
SLIDE 26

λ-obliv features

26

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

New random values are allocated in static region

slide-27
SLIDE 27

λ-obliv features

27

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

castP : flip[R] → bit[⊥,P] (consuming)
 
 castS : flip[R] → bit[R,S] (non-consuming) Escape hatches needed to implement ORAM

slide-28
SLIDE 28

λ-obliv features

28

τ ⩴ … | flip[R] -- uniform secrets | bit[R,ℓ] -- bits | ref(τ) -- references | τ → τ -- functions e ⩴ … | flip[R]() -- create uniform secrets | castP(e) -- reveal uniform secrets | castS(x) -- non-affine use of x | e ⊕ e -- xor | mux(e, e, e) -- atomic mux | read(e) -- reference read | write(e, e) -- reference write | if(e){e}{e} -- conditionals | λx.e | e(e) -- functions

slide-29
SLIDE 29

Taming the escape hatches

29

Affine
 Types Probability
 Regions

e ⩴ … | castP(e) | castS(x)

slide-30
SLIDE 30

Affinity in Action

30

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-31
SLIDE 31

Affinity in Action

31

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-32
SLIDE 32

Affinity in Action

32

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-33
SLIDE 33

Affinity in Action

33

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-34
SLIDE 34

Affinity in Action

s b₁ b₂ b₃ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK

34

slide-35
SLIDE 35

Affinity in Action

s b₁ b₂ b₃ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Observation: b₃=1

35

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-36
SLIDE 36

Affinity in Action

s b₁ b₂ b₃ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Observation: b₃=1 Observation: b₁=0 Learn: s=0

36

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK
slide-37
SLIDE 37

Affinity in Action

Mux Rule: “consume” branch values

r₁, r₂ = mux(s, b₁, b₂)

37

slide-38
SLIDE 38

b₁, b₂ = flip[R1](), flip[R2]() b₃, _ = mux(s, b₁, b₂)

  • - each of b₁, b₂, b₃ uniform
  • utput(castP(b₃)) -- OK
  • - none of b₁, b₂, b₃ uniform
  • utput(castP(b₁)) -- NOT OK

Affinity in Action

38

Rejected by λ-obliv type system

slide-39
SLIDE 39

Taming the escape hatches

39

Affine
 Types Probability
 Regions

e ⩴ … | castP(e) | castS(x)

slide-40
SLIDE 40

Taming the escape hatches

40

Affine
 Types Probability
 Regions

e ⩴ … | castP(e) | castS(x)

slide-41
SLIDE 41

Probability Regions in Action

b₁, b₂ = flip[R1](), flip[R2]()

  • - each of b₁, b₂ uniform

b₃, _ = mux(castS(b₁), b₁, b₂)

  • - b₃ not uniform

b₄, _ = mux(s, b₃, flip[R3]())

  • - b₄ not uniform because b₃ isn't
  • utput(castP(b₄)) -- NOT OK

41

slide-42
SLIDE 42

Probability Regions in Action

b₁, b₂ = flip[R1](), flip[R2]()

  • - each of b₁, b₂ uniform

b₃, _ = mux(castS(b₁), b₁, b₂)

  • - b₃ not uniform

b₄, _ = mux(s, b₃, flip[R3]())

  • - b₄ not uniform because b₃ isn't
  • utput(castP(b₄)) -- NOT OK

42

b₁ ⫫ b₂

slide-43
SLIDE 43

Probability Regions in Action

43

r₁, r₂ = mux(s, b₁, b₂)

Rule: probabilistic independence from guard

slide-44
SLIDE 44

Probability Regions in Action

b₁, b₂ = flip[R1](), flip[R2]()

  • - each of b₁, b₂ uniform

b₃, _ = mux(castS(b₁), b₁, b₂)

  • - b₃ not uniform

b₄, _ = mux(s, b₃, flip[R3]())

  • - b₄ not uniform because b₃ isn't
  • utput(castP(b₄)) -- NOT OK

44

Rejected by λ-obliv type system

R₁ ⊏ R₁

slide-45
SLIDE 45

Probability Regions

45

Values Types Property

b₁ ▷ b₂ R₁ ⊑ R₂

Noninterference

slide-46
SLIDE 46

Probability Regions

46

Values Types

b₁ ⫫ b₂

Property

Probabilistic
 Independence

b₁ ▷ b₂ R₁ ⊑ R₂

Noninterference

slide-47
SLIDE 47

Probability Regions

47

Values Types

b₁ ⫫ b₂

Property

Probabilistic
 Independence

R₁ ⊓ R₂ = ⊥ b₁ ▷ b₂ R₁ ⊑ R₂

Noninterference

slide-48
SLIDE 48

Probability Regions

48

Values Types

b₁ ⫫ b₂ b₁ ⫫ b₂ | Φ

Property

Probabilistic
 Independence

R₁ ⊓ R₂ = ⊥

Robust w.r.t. Revelations

b₁ ▷ b₂ R₁ ⊑ R₂

Noninterference

slide-49
SLIDE 49

Probability Regions

49

Values Types

b₁ ⫫ b₂ b₁ ⫫ b₂ | Φ

Property

Probabilistic
 Independence

R₁ ⊓ R₂ = ⊥ R₁ ⊏ R₂

Robust w.r.t. Revelations

b₁ ▷ b₂

Noninterference

R₁ ⊑ R₂

slide-50
SLIDE 50

λ-obliv Typing

50

s : secret @ R₁ R₁ ⊏ R₂ b₁ : flip @ R₂ R₁ ⊏ R₃ b₂ : flip @ R₃ R = R₁ ⊔ R₂ ⊔ R₃ ──────────────────────────────────────── mux(s, b₁, b₂) : (flip @ R) × (flip @ R)

slide-51
SLIDE 51

λ-obliv Typing

51

s : secret @ R₁ R₁ ⊏ R₂ b₁ : flip @ R₂ R₁ ⊏ R₃ b₂ : flip @ R₃ R = R₁ ⊔ R₂ ⊔ R₃ ──────────────────────────────────────── mux(s, b₁, b₂) : (flip @ R) × (flip @ R)

slide-52
SLIDE 52

λ-obliv Typing

52

s : secret @ R₁ R₁ ⊏ R₂ b₁ : flip @ R₂ R₁ ⊏ R₃ b₂ : flip @ R₃ R = R₁ ⊔ R₂ ⊔ R₃ ──────────────────────────────────────── mux(s, b₁, b₂) : (flip @ R) × (flip @ R)

slide-53
SLIDE 53

λ-obliv Typing

53

s : secret @ R₁ R₁ ⊏ R₂ b₁ : flip @ R₂ R₁ ⊏ R₃ b₂ : flip @ R₃ R = R₁ ⊔ R₂ ⊔ R₃ ──────────────────────────────────────── mux(s, b₁, b₂) : (flip @ R) × (flip @ R)

slide-54
SLIDE 54

λ-obliv Typing

54

s : secret @ R₁ R₁ ⊏ R₂ b₁ : flip @ R₂ R₁ ⊏ R₃ b₂ : flip @ R₃ R = R₁ ⊔ R₂ ⊔ R₃ ──────────────────────────────────────── mux(s, b₁, b₂) : (flip @ R) × (flip @ R)

slide-55
SLIDE 55

Case Study: Tree ORAM

λ-obliv is expressive enough to implement full ORAM ORAM security verified entirely via type checking Implemented in OCaml and publicly available (+ other case studies)

55

slide-56
SLIDE 56

ORAM basics λ-obliv design λ-obliv proof

56

slide-57
SLIDE 57

λ-obliv Enjoys PMTO

THEOREM: typing implies PMTO for small-step sampling semantics PROOF: via alternative “mixed” semantics which: Mixes operational and denotational methods Uses a new probability monad for reasoning about conditional

(in)dependence

PROOF INVARIANT: flip values are: Uniformly distributed Independent from all other flip values, conditioned on any subset

  • f secrets typed at smaller regions

57

slide-58
SLIDE 58

Related Work

Prior work [1] verifies deterministic MTO by typing.
 We push this to probabilistic (PMTO). Prior work [2] claims to solve PMTO by typing but unsound.
 (fix = probability regions; proof much more involved) Related work this POPL [3] (tomorrow 14:43) solves PMTO for ORAM via a program logic.

[1]: Chang Liu, Austin Harris, Martin Maas, Michael Hicks, Mohit Tiwari, and Elaine Shi. GhostRider: A Hardware-Software System for Memory Trace Oblivious Computation. ASPLOS 2015. [2]: Chang Liu, Xiao Shaun Wang, Kartik Nayak, Yan Huang, and Elaine Shi. ObliVM: A Programming Framework for Secure Computation. IEEE S&P 2015. [3]: Gilles Barthe, Justin Hsu, Mingsheng Ying, Nengkun Yu, Li Zhou. Relational Proofs for Quantum Programs. POPL 2020.

58

slide-59
SLIDE 59

λ-obliv

Mux Rule: affine branches

mux(s, b₁, b₂)

Mux Rule: independence from guard

mux(s, b₁, b₂)

59

  • - upload secrets

b = flip[R]() -- randomness s₀′, s₁′ = mux(b, s₀, s₁) S[0] ← s₀′ -- write secret 0 or 1 S[1] ← s₁′ -- write secret 1 or 0

  • - read secret index s

r = S[b⊕s] - PMTO

+ = PMTO e ⩴ … | castP(e) | castS(x)