a design and verification methodology for secure isolated...
Post on 24-Apr-2018
217 Views
Preview:
TRANSCRIPT
A Design and Verification Methodology for Secure Isolated Regions
Rohit Sinha1, Manuel Costa2, Akash Lal2, Nuno P. Lopes2,Sriram Rajamani2, Sanjit A. Seshia1, Kapil Vaswani2
21
PLDI 2016
Secure Isolated Regions (SIR)
2
App
Operating System
Hypervisor
Secure Hardware
IntelSGX
ARMTrustZone
Secure Isolated Regions (SIR)
SIR memory is protected: only SIR code can access it
2
App
Operating System
Hypervisor
Secure Hardware
IntelSGX
ARMTrustZone
SIR
Secure Isolated Regions (SIR)
SIR memory is protected: only SIR code can access it
Trusted Computing Base includes the SIR and CPU hardware
2
App
Operating System
Hypervisor
Secure Hardware
IntelSGX
ARMTrustZone
SIR
Secure Isolated Regions (SIR)
SIR memory is protected: only SIR code can access it
Trusted Computing Base includes the SIR and CPU hardware
2
AppHadoopSIR
Operating System
Hypervisor
Secure Hardware
IntelSGX
ARMTrustZone
VC3: Trustworthy Data Analytics in the Cloud [Schuster et. al., S&P’15]
void map(...) { /* compute on sensitive data */ }
void reduce(...) { /* compute on sensitive data */ }
SIR
Bugs in SIRs can be Exploited
SIR accesses untrusted Hadoop’s memory to perform I/O
3
HadoopSIR
Secure Hardware
IntelSGX
Bugs in SIRs can be Exploited
SIR accesses untrusted Hadoop’s memory to perform I/O
3
HadoopSIR
Secure Hardware
IntelSGX
MapperSIRHadoop
MapperSIRHadoop
Reducer SIR
encrypted (k,v)
//decrypt; compute
Bugs in SIRs can be Exploited
SIR accesses untrusted Hadoop’s memory to perform I/O
Adversary can exploit SIRs using I/O interactions
3
HadoopSIR
Secure Hardware
IntelSGX
MapperSIRHadoop
MapperSIRHadoop
e.g. Heartbleed, unsafe gcc
optimizations
Reducer SIR
encrypted (k,v)
//decrypt; compute
Bugs in SIRs can be Exploited
SIR accesses untrusted Hadoop’s memory to perform I/O
Adversary can exploit SIRs using I/O interactions
Our goal: ensure that secrets are not leaked (confidentiality) in the presence of programming errors and compiler bugs
3
HadoopSIR
Secure Hardware
IntelSGX
MapperSIRHadoop
MapperSIRHadoop
e.g. Heartbleed, unsafe gcc
optimizations
Reducer SIR
encrypted (k,v)
//decrypt; compute
void Reduce(byte *kEnc, byte *vEnc) {
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v);
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum);
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
void Reduce(byte *kEnc, byte *vEnc) { KeyAesGcm *aesKey = ProvisionKey();
char k[..]; aesKey->Decrypt(kEnc, k); char v[..]; aesKey->Decrypt(vEnc, v); long sum = compute_sum(v);
char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); aesKey->Encrypt(cleartext, untrusted_memory, BUF_SIZE);}
Challenges in Proving Confidentiality
4
HadoopSIR
Secure Hardware
IntelSGX
compiler
Information Release Confinement
5
HadoopSIRUser Code(U)
Runtime Library
(L)
L implements send, recv, malloc, free
Information Release Confinement
5
HadoopSIRUser Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
void Reduce(byte *kEnc, byte *vEnc) { char *k = recv(..); char *v = recv(..);
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
void Reduce(byte *kEnc, byte *vEnc) { char *k = recv(..); char *v = recv(..); long sum = compute_sum(v);
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
void Reduce(byte *kEnc, byte *vEnc) { char *k = recv(..); char *v = recv(..); long sum = compute_sum(v); char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); send(cleartext, ..);}
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
5
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
void Reduce(byte *kEnc, byte *vEnc) { char *k = recv(..); char *v = recv(..); long sum = compute_sum(v); char cleartext[..]; sprintf(cleartext, “%s %lld”, k, sum); send(cleartext, ..);}
IRC: All updates to non-SIR memory via L’s send API
Separation of concerns:U does not
manage crypto keys or write to
untrusted memory
Information Release Confinement
6
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
Information Release Confinement
6
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
send(secret)
L implements send, recv, malloc, free
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
6
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
✓ Prevents explicit information leaks: side channels outside scope
send(secret)
L implements send, recv, malloc, free
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
6
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
✓ Prevents explicit information leaks: side channels outside scope
✓ Even if U is buggy, an adversary only sees encrypted values in an exploit
send(secret)
L implements send, recv, malloc, free
IRC: All updates to non-SIR memory via L’s send API
Information Release Confinement
6
HadoopSIR...f12e6dafa9d3b
...c96a8ebbd4a7e
ciphertext messages
User Code(U)
Runtime Library
(L)
✓ Prevents explicit information leaks: side channels outside scope
✓ Even if U is buggy, an adversary only sees encrypted values in an exploit
send(secret)
L implements send, recv, malloc, free
✓ Avoids fine-grained tracking of secrets in U’s memory: all of U is secret
IRC: All updates to non-SIR memory via L’s send API
Proving Information Release Confinementsatisfies IRC
Correctness of L Correctness of U
implement a cryptographically secure channel
send, recv
SIR
7
Proving Information Release Confinementsatisfies IRC
Correctness of L Correctness of U
implement a cryptographically secure channel
send, recv U calls into L at API entrypoints
SIR
7
Proving Information Release Confinementsatisfies IRC
Correctness of L Correctness of U
implement a cryptographically secure channel
send, recv U does not write to non-SIR
memory
U calls into L at API entrypoints
SIR
7
Proving Information Release Confinementsatisfies IRC
Correctness of L Correctness of U
implement a cryptographically secure channel
send, recv U does not write to non-SIR
memory
U calls into L at API entrypoints
SIR
7
✓ We don’t require full functional correctness of U
Proving Information Release Confinementsatisfies IRC
Correctness of L Correctness of U
implement a cryptographically secure channel
send, recv U does not write to non-SIR
memory
U calls into L at API entrypoints
✓ Proof strategy requires no annotations from the developer
SIR
7
✓ We don’t require full functional correctness of U
Contributions
8
Sound Decomposition of IRC proof into Contracts on U and L
Formal Specification of IRC
IRC as a design methodology for programming SIRs
Contributions
8
Sound Decomposition of IRC proof into Contracts on U and L
Automatic, Modular Verifier for proving IRC on U’s binary
Verifier checks against a privileged OS-level adversary
Formal Specification of IRC
IRC as a design methodology for programming SIRs
Contributions
8
Sound Decomposition of IRC proof into Contracts on U and L
Automatic, Modular Verifier for proving IRC on U’s binary
Verifier checks against a privileged OS-level adversary
Evaluation on several SIRs
Map-Reduce benchmarks from VC3
SPEC benchmarks
Formal Specification of IRC
IRC as a design methodology for programming SIRs
This Talk: Automatically Proving IRC
Verifying that U calls into L at API entrypointsVerifying Calls in U
9
This Talk: Automatically Proving IRC
Verifying that U calls into L at API entrypoints
Verifying that U does not modify non-SIR memory
Verifying Calls in U
Verifying Writes in U
9
This Talk: Automatically Proving IRC
Verifying that U calls into L at API entrypoints
Verifying that U does not modify non-SIR memory
Correctness properties of L
Verifying Calls in U
Verifying Writes in U
Verifying L
9
This Talk: Automatically Proving IRC
Verifying that U calls into L at API entrypoints
Verifying that U does not modify non-SIR memory
Correctness properties of L
Evaluation on VC3 and SPEC
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
9
Verifying U: Calls to L via API Entrypoints
10
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
buf
Verifying U: Calls to L via API Entrypoints
10
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
bufq
Verifying U: Calls to L via API Entrypoints
10
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
buf
q
Verifying U: Calls to L via API Entrypoints
10
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
buf
q
Verifying U: Calls to L via API Entrypoints
10
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
✓ A call instruction targets the starting address of a procedure in U or API of L
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
✓ A call instruction targets the starting address of a procedure in U or API of L
✓ A ret instruction returns back to the caller
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
✓ A call instruction targets the starting address of a procedure in U or API of L
✓ A ret instruction returns back to the caller
✓ A jmp instruction targets a legal instruction within the procedure
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
✓ A call instruction targets the starting address of a procedure in U or API of L
✓ A ret instruction returns back to the caller
✓ A jmp instruction targets a legal instruction within the procedure
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
EvaluationWeak (WCFI)
SIR memory
*q = buf + input; *q = input2;... return;
return addr
arbitrary code
buf
q
Verifying U: Calls to L via API Entrypoints
10
✓ A call instruction targets the starting address of a procedure in U or API of L
✓ A ret instruction returns back to the caller
✓ A jmp instruction targets a legal instruction within the procedure
Control Flow Integrity
arbitrary code- middle of x86 instructions- arbitrary instructions in L
Potential Code in U
Verifying Calls in U
Verifying Writes in U
Verifying L
EvaluationWCFI ⇒
U calls into L via APIs
Weak (WCFI)
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
not-writablereturn addresses
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
not-writablereturn addresses
writablelocal varsheap objects
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
bufq
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
not-writablereturn addresses
writablelocal varsheap objects
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
q
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
not-writablereturn addresses
writablelocal varsheap objects
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
q
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
bitmap
not-writablereturn addresses
writablelocal varsheap objects
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
SIR memory
*q = buf + input;*q = input2;...return;
return addr
buf
q
Runtime check using VC3 compiler:is address of q marked writable in bitmap?
Software TRAP
bitmap
not-writablereturn addresses
writablelocal varsheap objects
Verifying U: Runtime Checks for WCFI
11
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Potential Code in U
Verifying U: Modeling U’s Binary
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modeling U’s Binary
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugs
Verifying U: Modeling U’s Binary
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugsCompiler optimizes away many runtime checks
Verifying U: Modeling U’s Binary
...mov rcx, [rax+rbx]bt rcx, rbxjb $L2int 3$L2: mov [rbx],rdx ... ret
x64 code produced by compiler
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugsCompiler optimizes away many runtime checks
Verifying U: Modeling U’s Binary
Binary Analysis Platform
...mov rcx, [rax+rbx]bt rcx, rbxjb $L2int 3$L2: mov [rbx],rdx ... ret
x64 code produced by compiler
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugsCompiler optimizes away many runtime checks
Verifying U: Modeling U’s Binary
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; mem := store(mem, rbx, rdx); ... return;
Binary Analysis Platform
...mov rcx, [rax+rbx]bt rcx, rbxjb $L2int 3$L2: mov [rbx],rdx ... ret
x64 code produced by compiler
Boogie model
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugsCompiler optimizes away many runtime checks
Verifying U: Modeling U’s Binary
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; mem := store(mem, rbx, rdx); ... return;
Binary Analysis Platform
...mov rcx, [rax+rbx]bt rcx, rbxjb $L2int 3$L2: mov [rbx],rdx ... ret
x64 code produced by compiler
Boogie model
12
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Avoid trusting the compiler: Long history of bugsCompiler optimizes away many runtime checks
Verifying U: Modeling the Adversary
13
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modeling the Adversary
SIR memory
a
13
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
load from untrusted memory returns arbitrary value *load(mem,a) = ITE(SIR(a), mem[a], *);
Verifying U: Modeling the Adversary
SIR memory
a
13
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation[Moat CCS’15]: models all operations by a malicious OS e.g. generate interrupts, modify page tables, launch other SIRs, etc.
load from untrusted memory returns arbitrary value *load(mem,a) = ITE(SIR(a), mem[a], *);
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Proof Obligations guarantee WCFI ⇒
U calls into L via APIs
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
VC-gen+
SMT Solving
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Proof Obligations guarantee WCFI ⇒
U calls into L via APIs
Verifying U: Proof Obligations
...rcx := load(mem, rax +64 rbx);CF := (rcx >>64 rbx)[1:0];goto $L1, $L2;$L1: assume CF == 0; assume false;$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
VC-gen+
SMT Solving
14
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Presence of runtime checks helps SMT solver
to prove assert Ψ
Proof Obligations guarantee WCFI ⇒
U calls into L via APIs
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ... sprintf(cleartext, “%s %lld”,...); ...}
void sprintf(char *cleartext,...) { /* write to cleartext */}
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ... sprintf(cleartext, “%s %lld”,...); ...}
void sprintf(char *cleartext,...) { /* write to cleartext */}
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ... sprintf(cleartext, “%s %lld”,...); ...}
void sprintf(char *cleartext,...) { /* write to cleartext */}
verifier asserts writable(bitmap, addr) for each store
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ... sprintf(cleartext, “%s %lld”,...); ...}
void sprintf(char *cleartext,...) { /* write to cleartext */}
verifier asserts writable(bitmap, addr) for each store
addr
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
15
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ... sprintf(cleartext, “%s %lld”,...); ...}
void sprintf(char *cleartext,...) { /* write to cleartext */}
verifier asserts writable(bitmap, addr) for each store
addr
addr
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
16
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
16
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ...
sprintf(cleartext, “%s %lld”, ...); ...}
void sprintf(char *cleartext, ...) { /* write to cleartext */}
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
16
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ...
sprintf(cleartext, “%s %lld”, ...); ...}
void sprintf(char *cleartext, ...) { /* write to cleartext */}
store<compiler makes cleartext writable>
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
16
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ...
sprintf(cleartext, “%s %lld”, ...); ...}
void sprintf(char *cleartext, ...) { /* write to cleartext */}
verifier asserts that bitmap is updated safely
store<compiler makes cleartext writable>
Verifying U: Proof Obligations on store
SIR memory
stack
bitmap
return address
sprintf localvariables
cleartext
16
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
void Reduce(...) { ...
sprintf(cleartext, “%s %lld”, ...); ...}
void sprintf(char *cleartext, ...) { /* write to cleartext */}
verifier asserts that bitmap is updated safely
store<compiler makes cleartext writable>
Verifying U: Soundness
17
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
call:
ret:
jmp:
Verifying U: Soundness
17
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
call:
ret:
jmp:
Proof obligations imply WCFI ⇒
U calls into L via APIs
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input;*q = secret;...
buf
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input;*q = secret;...
bufq
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input;*q = secret;...
buf
q
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input;*q = secret;...
buf
q
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
SIR memory
*q = buf + input;*q = secret;...
buf
q
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Runtime check using VC3 compiler:is q within SIR range?
SIR memory
*q = buf + input;*q = secret;...
buf
q
Software TRAP
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Runtime check using VC3 compiler:is q within SIR range?
SIR memory
*q = buf + input;*q = secret;...
buf
q
Software TRAP
Verifying U: Preventing Writes Outside SIR
18
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Since we don’t trust the compiler:verifier asserts addrInSIR(addr) for each store
Runtime check using VC3 compiler:is q within SIR range?
Verifying U: Soundness
...$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
19
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Soundness
...$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
19
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation Proof Obligations for WCFI
Verifying U: Soundness
...$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
19
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation Proof Obligations for WCFI
Proof Obligations for writes within SIR
Verifying U: Soundness
...$L2: assume CF == 1; assert Ψ; mem := store(mem, rbx, rdx); ...assert φ;return;
19
Boogie modelVerifying Calls in U
Verifying Writes in U
Verifying L
Evaluation Proof Obligations for WCFI + = IRCProof Obligations
for writes within SIR
Verifying U: Modular Verification
20
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modular Verification
We perform modular reasoning of U’s binary without false positives.
20
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modular Verification
We perform modular reasoning of U’s binary without false positives.
The VC3 compiler generates enough runtime checks to allow this.
20
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modular Verification
We perform modular reasoning of U’s binary without false positives.
The VC3 compiler generates enough runtime checks to allow this.
void Reduce(...) { ... sprintf(cleartext, “%s %lld”, …); ...}void sprintf(char *cleartext, …) { //write to cleartext, which is stack-allocated}
20
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verifying U: Modular Verification
We perform modular reasoning of U’s binary without false positives.
The VC3 compiler generates enough runtime checks to allow this.
void Reduce(...) { ... sprintf(cleartext, “%s %lld”, …); ...}void sprintf(char *cleartext, …) { //write to cleartext, which is stack-allocated}
20
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
<runtime check that buf is in SIR memory>
Verification Optimizations
21
assertret:Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verification Optimizations
21
assertret:
sound strategy for quantifier instantiation
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verification Optimizations
21
assertret:
split into disjoint arrays for bitmap and stack
sound strategy for quantifier instantiation
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Verification Optimizations
21
Removed hundreds of Z3 timeouts in our experiments
assertret:
split into disjoint arrays for bitmap and stack
sound strategy for quantifier instantiation
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
void *malloc(size_t size)void free(void *buf)
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
void *malloc(size_t size)void free(void *buf)// ensures ...
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
void *malloc(size_t size)void free(void *buf)// ensures ...
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Manual, One-time Verification of L
void send(void *buf, size_t size)void recv(void *buf, size_t size)// ensures no unsafe modification to U// ensures channel key is not modified// ensures ...
void *malloc(size_t size)void free(void *buf)// ensures ...
No requires clauseon U
22
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
EvaluationRuntime checks incur 15% performance hit [Schuster et al.: VC3]
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Evaluation
timeout: 30 mins
Runtime checks incur 15% performance hit [Schuster et al.: VC3]
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Evaluation
timeout: 30 mins
Runtime checks incur 15% performance hit [Schuster et al.: VC3]
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
Evaluation
timeout: 30 mins
Runtime checks incur 15% performance hit [Schuster et al.: VC3]
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
verified in 4 hours
Evaluation
timeout: 30 mins
Runtime checks incur 15% performance hit [Schuster et al.: VC3]
Verifying Calls in U
Verifying Writes in U
Verifying L
Evaluation
verified in 4 hours
Related WorkWork Application Technique Comparison
Sinha et al: Moat CCS’15
Verifying Confidentiality of SGX Programs
Refinement type system for
non-interference
Requires global, precise tracking of secrets in machine
code
Related WorkWork Application Technique Comparison
Sinha et al: Moat CCS’15
Verifying Confidentiality of SGX Programs
Refinement type system for
non-interference
Requires global, precise tracking of secrets in machine
code
Myers et al:JIF
SOSP’97
Information Flow for Java
applicationsType system for non-interference
Requires annotations, and trust in language
runtime
Related WorkWork Application Technique Comparison
Sinha et al: Moat CCS’15
Verifying Confidentiality of SGX Programs
Refinement type system for
non-interference
Requires global, precise tracking of secrets in machine
code
Myers et al:JIF
SOSP’97
Information Flow for Java
applicationsType system for non-interference
Requires annotations, and trust in language
runtime
Hawblitzel et al:IronClad Apps
OSDI’14Functional
correctnessDeductive verification
Requires manual effort in writing invariants
Related WorkWork Application Technique Comparison
Sinha et al: Moat CCS’15
Verifying Confidentiality of SGX Programs
Refinement type system for
non-interference
Requires global, precise tracking of secrets in machine
code
Myers et al:JIF
SOSP’97
Information Flow for Java
applicationsType system for non-interference
Requires annotations, and trust in language
runtime
Hawblitzel et al:IronClad Apps
OSDI’14Functional
correctnessDeductive verification
Requires manual effort in writing invariants
Morisett et al: Rocksalt PLDI’12
Software Fault Isolation
Verified Machine Code Checker
extracted from Coq
different goal
64-bit version requires 100GB address
space
Takeaway Points
IRC as a design principle for SIRs: • easier to verify than full functional correctness
25
Takeaway Points
IRC as a design principle for SIRs: • easier to verify than full functional correctness• avoids tracking of secrets in SIR’s memory
25
Takeaway Points
IRC as a design principle for SIRs: • easier to verify than full functional correctness• avoids tracking of secrets in SIR’s memory
Automatic, modular verification of IRC on SIR binaries, with a small trusted computing base
25
Takeaway Points
IRC as a design principle for SIRs: • easier to verify than full functional correctness• avoids tracking of secrets in SIR’s memory
Automatic, modular verification of IRC on SIR binaries, with a small trusted computing base
https://github.com/TrustedCloud/slashconfidential
25
top related