Untrusted Hosts and Confidentiality: Secure Program Partitioning Steve Zdancewic Lantian Zheng • Nathaniel Nystrom • Andrew Myers Cornell University Protecting Confidential Data • Programs manipulate valuable data – web-based e-mail, shopping, financial planning – B2B transactions, military information systems,... • Important Features A – Confidentiality is crucial – Distribution is unavoidable – Heterogeneous trust • Challenges B C "Alice trusts A & C" "Bob trusts B & C" – Complex policies – Complex software – Correct use of access control & cryptography 2 Tools for Security • Automatic tools – Check the use of enforcement mechanisms – Increase confidence in security • Language-based tools – Raise the level of abstraction – Consider information flow through entire system (program) • Use the security policy to guide distribution 3 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 4 Secure Program Partitioning Describes the computation and the principals' security policies. Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 5 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter Verifies that the program obeys the security policies. subprograms Host 1 runtime Host 2 Host 3 6 Secure Program Partitioning Describes the trust relationships between principals and hosts. Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 7 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter Partitions the data and computation among hosts, so that policies are obeyed. subprograms Host 1 runtime Host 2 Host 3 8 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Performs dynamic access control checks and encrypts communication. Host 3 9 Security Assurance • Goal: Resulting distributed program performs the same computation as the source and also satisfies the security policies. • Guarantee: Principal P's security policy is violated only if a host that P trusts fails or is subverted. • Example: "Alice trusts A & C" "Bob trusts B & C" A B C If B fails, Alice's policy is obeyed, Bob's policy may be violated. 10 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 11 Confidentiality Policies in Jif • Confidentiality labels: int{Alice} a; "a is Alice's private int" • Integrity labels: int{?Alice} a; "Alice must trust a" • Combined labels: int{Alice, ?Alice} a; (Both constraints) int{Alice} a1, a2; int{Bob} b; // Insecure a1 = b; b = a1; // Secure a1 = a2; 12 Policy Operations in Jif • Declassification: int{Alice} a; declassify(a to Bob); "type-cast int{Alice} to int{Bob}" • Endorse: int{?Bob} b; endorse(b by Alice); • But (!) Alice must trust the integrity of decision to perform the policy operation. – Compiler guarantees the integrity 13 Example: Oblivious Transfer Alice request(n) int m1; int m2; answer(mn) Bob • Alice has two integers: m1 and m2. • Alice's Policy: "Bob gets to choose exactly one of m1 and m2." • Bob's Policy: "Alice doesn't get to know which item I request." • Classic Result: "Impossible to solve using 2 principals, with perfect security." 14 Oblivious Transfer (Java) int boolean int m1, m2; // Alice's data accessed; n, ans; // Bob's data n = choose(); // Bob's choice if (!accessed) { accessed = true; if (n == 1) ans = m1; else ans = m2; } // Transfer 15 Adding Confidentiality Labels int{Alice} boolean int{Bob} m1, m2; // Alice's data accessed; n, ans; // Bob's data n = choose(); // Bob's choice if (!accessed) { accessed = true; if (n == 1) ans = m1; else ans = m2; } // Transfer Verification Fails 16 Using Declassification int{Alice} boolean int{Bob} n = choose(); m1, m2; // Alice's data accessed; n, ans; // Bob's data Verification // Bob's choice Fails // Transfer if (!accessed) { accessed = true; if (n == 1) ans = declassify(m1 to Bob); else ans = declassify(m2 to Bob); } 17 Integrity Constraints int{Alice} boolean{?Alice} int{Bob} n = choose(); m1, m2; // Alice's data accessed; n, ans; // Bob's data // Bob's choice Verification Fails // Transfer if (!accessed) { accessed = true; if (n == 1) ans = declassify(m1 to Bob); else ans = declassify(m2 to Bob); } 18 Using Endorsement int{Alice} boolean{?Alice} int{Bob} n = choose(); m1, m2; // Alice's data accessed; n, ans; // Bob's data // Bob's choice if (!accessed) { // Transfer accessed = true; if (endorse(n by Alice) == 1) ans = declassify(m1 to Bob); else ans = declassify(m2 to Bob); } 19 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 20 Trust Configurations • Labels describe the trust relationship between principals and the available hosts. • Confidentiality: Host A:{Alice} "Alice trusts host A not to leak her confidential data." int{Alice} m1; int{Bob} n; • Integrity: m1 can be sent to A n cannot be sent to A Host A:{?Alice} "Alice trusts host A not to corrupt her high-integrity data." 21 Two-Host Configuration A B {Alice, ?Alice} {Bob, ?Bob} 22 Splitter output: No Solution! A B Can't find a host for the expression: endorse(n by Alice) It requires a host that has Alice's integrity yet can hold Bob's private data. {Alice, ?Alice} {Bob, ?Bob} 23 Splitter Output A T int m1, m2; bool accessed; int n, ans; n = choose(); B int choose() { ... return n; } if (!accessed) { ... } {Alice, ?Alice} {Alice, ?Alice, Bob} {Bob, ?Bob} 24 Splitter Output is Java A Data and all of the code except 'choose()' are located at T. {Alice, ?Alice} T int m1, m2; bool accessed; int n, ans; n = choose(); B int choose() { ... return n; } if (!accessed) { ... } {Alice, ?Alice, Bob} {Bob, ?Bob} 25 Run-time Calls A T int m1, m2; bool accessed; int n, ans; Resulting code links against the runtime. {Alice, ?Alice} n = choose(); B int choose() { ... return n; } if (!accessed) { ... } {Alice, ?Alice, Bob} {Bob, ?Bob} 26 Security Assurance A T int m1, m2; bool accessed; int n, ans; Alice's policy is enforced. n = choose(); B int choose() { ... return n; } if (!accessed) { ... } {Alice, ?Alice} {Alice, ?Alice, Bob} {Bob, ?Bob} 27 Network Overhead A T int m1, m2; bool accessed; int n, ans; n = choose(); B int choose() { ... return n; } if (!accessed) { ... } Nothing located at host A! {Alice, ?Alice} {Alice, ?Alice, Bob} {Bob, ?Bob} 28 Another Secure Solution A bool accessed; T B int m1, m2; int n, ans; goto(B); int choose() { ... return n; } goto(A); if (!accessed){ accessed=true; goto(T); } int n'= get(n,B); if (n' == 1) set(ans, m1); else ... {Alice, ?Alice} {Alice, ?Alice, Bob} n = choose(); goto(T); {Bob, ?Bob} 29 Secure Program Partitioning Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 30 Core Runtime Protocol • Data Transfer Val getField(Host h, ObjID o, Field f) Val setField(Host h, ObjID o, Field f, Val v) void forward(Host h, Frame f, Var vr, Val v) • Control Transfer void rgoto(Host h, Frame f, EntryPt e, Token t) void lgoto(Token t) void sync(Host h, Frame f, EntryPt e, Token t) • Implementation – Performs access control checks – Encrypts network communication – Capability mechanism protects control transfers 31 Control Transfer Integrity Alice's privileged code ... goto(B); ... declassify(X) ... goto(A); {?Alice} (Trusted) (Less Trusted) ... declassify(Y) {?Alice} (Trusted) 32 Control Transfer Integrity ... goto(B); ... declassify(X) ... goto(A); {?Alice} (Trusted) (Less Trusted) ... declassify(Y) {?Alice} (Trusted) 33 Control Transfer Integrity 1. sync T ... goto(B); 2. rgoto ... declassify(X) T T ... goto(A); T ... declassify(Y) 3. lgoto {?Alice} (Trusted) (Less Trusted) {?Alice} (Trusted) 34 Control Transfer Integrity T ... goto(B); ... declassify(X) T ... goto(A); {?Alice} (Trusted) T (Less Trusted) T ... declassify(Y) {?Alice} (Trusted) 35 Capabilities Protocol • Theorem: When trusted hosts follow the protocol, there is at most one valid capability available to less trusted hosts. Means that less trusted hosts have no choice about how privileges are restored to the computation. 36 Prototype: Jif/split • Jif/split: 7400 loc Runtime: 1700 loc • 4 small benchmarks: – < 300 lines of code each – 2 hand implemented in Java using RMI • Experimental results: (LAN setting) – Running time overhead vs. hand implemented: 20% to 120% – Message count overhead vs. hand implemented: -25% to 25% – Costs seem reasonable – Need to try bigger programs 37 Secure Program Partitioning • Language-based Confidentiality Policies – Compiler splits a program among heterogeneously trusted hosts. – Guided by security policies – Resulting distributed program satisfies the policies • Benefits: – End-to-end security – Decentralized – Automatic – Explicit Policies Source Code Policy Compiler Trust info Splitter subprograms Host 1 runtime Host 2 Host 3 60 38 http://www.cs.cornell.edu/jif 39 Oblivious Transfer Impossibility "It is well known (and easy to see) that in a two-player scenario with noiseless communication, OT [Oblivious Transfer] ... with information-theoretic security is not possible, even if only passive cheating is assumed, and players are allowed infinite computing power." – Damgård, Kilian, Slavail On the (Im)possibility of Basing Oblivious Transfer and Bit Commitment on Weakened Security Assumptions, EUROCRYPTO '99 40 Access Control Checks A int{Alice, ?Alice} m1; get(m1)K(S) {Alice, ?Alice} S t1 = getField(Alice, m1); {Alice, ?Alice, Bob} • Static constraints for read/write are compiled into access control checks • Host A checks that {Alice} {Alice,?Alice,Bob} – verifies signature of S – checks that S {A, S} – if so, replies with m1 • setField requires integrity checks 41 Partitioning Jif Programs • Solve a constraint system to determine possible hosts • Use dynamic programming & heuristics to find an efficient solution • Rewrite program, inserting calls to runtime system – data forwarding and control transfers • Outputs: A collection of Java code fragments with host assignments 42 Static Constraints • Consider a field: int{Alice:;?:Alice} f; • Host H : confidentiality label C integrity label I • Constraints: {Alice:} C I {?:Alice} • Read-channels: Uses(f) C • Generalize to program statements • Constraints on declassify() 43