aws re:invent 2016: automated formal reasoning about aws systems (sec401)
TRANSCRIPT
© 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved.© 2015, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Byron Cook
November 29, 2016
SEC401
Automated Formal Reasoning About AWS Systemssecuring Customers with Mathematical Logic
Shared security model
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented and not vulnerable to side-channel attacks?”
• “How do we know that Amazon EC2’s virtualization layer protects
against memory corruption-based attacks?”
• Secure usage
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I only allowing one instance in my VPC to send outgoing
network packets?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that Amazon EC2’s virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that Amazon EC2’s virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that Amazon EC2’s virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
AWS security: Raising the bar on security
• Secure usage of AWS components
• Amazon Inspector, Amazon CloudWatch, AWS Config Rules, etc
• Tools that apply mechanized reasoning in mathematical logic to
provide additional assurance
• Securing the cloud
• Extensive penetration testing, continuous monitoring, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
AWS security: Raising the bar on security
• Helping customers be secure in the cloud
• Amazon Inspector, AWS Config Rules, etc
• Tools that apply mechanized reasoning in mathematical logic to
provide additional assurance
• Securing the cloud
• Extensive penetration testing, continuous monitoring, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
AWS security: Raising the bar on security
• Helping customers be secure in the cloud
• Amazon Inspector, AWS Config Rules, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
• Securing the cloud
• Extensive penetration testing, continuous monitoring, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
AWS security: Raising the bar on security
• Helping customers be secure in the cloud
• Amazon Inspector, AWS Config Rules, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
• Securing the cloud
• Penetration testing, continuous monitoring, compliance certification,
etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
AWS security: Raising the bar on security
• Helping customers be secure in the cloud
• Amazon Inspector, AWS Config Rules, etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
• Securing the cloud
• Penetration testing, continuous monitoring, compliance certification,
etc
• Mechanized reasoning in mathematical logic to provide additional
assurance
Questions answered in this talk
• What is “Mechanized reasoning in mathematical logic” ?
• What are some examples of what AWS doing in this space?
Mechanized reasoning in mathematical logic
• Proofs: 360 BC — 1970s AD
• Examples:
• Euclid’s Infinitude of Primes
• Godel’s incompleteness theorem
• Turing’s Halting problem undecidability
• Four-color theorem
• Odd-order theorem
• …..
• …..
• …..
Mechanized reasoning in mathematical logic
• Proofs: 360 BC — 1970s AD
• Examples:
• Euclid’s Infinitude of Primes
• Gödel’s incompleteness theorem
• Turing’s Halting problem undecidability
• Odd-order theorem
• …..
• …..
• …..
Mechanized reasoning in mathematical logic
• Proofs: 360 BC — 1970s AD
• Examples:
• Euclid’s Infinitude of Primes
• Gödel’s incompleteness theorem
• Turing’s Halting problem undecidability
• Odd-order theorem
• …..
• …..
• …..
Arguments found and
checked by humans
Mechanized reasoning in mathematical logic
• Proofs: 360 BC — 1970s AD
• Examples:
• Euclid’s Infinitude of Primes
• Gödel’s incompleteness theorem
• Turing’s Halting problem undecidability
• Odd-order theorem
• …..
• …..
• …..
• Harder: finding
the argument
• Easier: checking
the argument
Mechanized reasoning in mathematical logic
• Proofs: 1970s AD — Current
• New: human found and mechanically checked
• Examples:
• Euclid’s Infinitude of Primes
• Gödel’s Incompleteness theorem
• Turing’s Halting problem undecidability
• Odd-order theorem
• Four-color theorem
• …..
• …..
• …..
Mechanized reasoning in mathematical logic
• Proofs: 1970s AD — Current
• New: human found and mechanically checked
• Examples:
• …..
• Boeing "Little Bird" helicopter (seL4 OS-based mission computer)
• Royal Navy Ship/Helicopter Operating Limits Unit
• Lockheed Martin C130J Mission Computers
• Rolls Royce Trent Series Health Monitoring Units
• AMD K5 floating point square root microcode
• Intel CPU arithmetic and logical operations
• …..
Mechanized reasoning in mathematical logic
• Proofs: 2001 AD — Current
• Increasingly mechanically found and mechanically checked
• Examples:
• ……
• ……
• Airbus 360 primary flight control software
• Paris Metro (RATP)
• Bombardier ILLBV950L2 railway interlocking system
• Mars Rover data management subsystem
• ……
• ……
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
• P-time = polynomial time = “tractable”
• NP-complete = nondeterministic polynomial time
= “intractable”
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractible problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Just buzzwords…..
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Just buzzwords…..
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Example open source
tools: Yices, MiniSAT
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Example open source
tools: Yices, MiniSAT
Example open source
tools: Coq, Jhorn
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=4, w=3, x=1, y=10, z=5 ?
if (w<x && x<y && y<z && (w<u || u<3) && x>=z)
error();
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=4, w=3, x=1, y=10, z=5 ?
if (w<x && x<y && y<z && (w<u || u<3) && x>=z)
error();
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=4, w=3, x=1, y=10, z=5 ?
No because w>=x :
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=4, w=3, x=18, y=10, z=5 ?
No because x>=y :
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=4, w=3, x=18, y=10, z=5 ?
No because x>=y :
if (w<x && x<y && y<z && (w<u || u<3) && x>=z)
error();
Example: NP-complete in P-time
• What values of u,w,x,y,z would lead to error()?
if (w<x && x<y && y<z && (x>=z || u<3) && u>10)
error();
• u=?, w=?, x=?, y=?, z=?
• SAT: If the variables range over 32-bit integers there are 2^(32*5)
possible combinations.
• SMT: If the variables range over reals/rationals/integers there are an
infinite number of combinations (though still decidable)
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && u<3 && u>10
w<z && x<y && y<z && x>=z && u>10
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && u<3 && u>10
w<z && x<y && y<z && x>=z && u>10
w<z && x<y && y<z && u<3 && u>10
w<z && x<y && y<z && x>=z && u>10
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && u<3 && u>10
w<z && x<y && y<z && x>=z && u>10
w<z && x<y && y<z && u<3 && u>10
w<z && x<y && y<z && x>=z && u>10
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
x<y && y<z && x>=z
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
&& !(x<y && y<z && x>=z)
x<y && y<z && x>=z
Example: NP-complete in P-time
w<z && x<y && y<z && (x>=z || u<3) && u>10
&& !(x<y && y<z && x>=z)
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i--;
r=r+x;
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i--;
r=r+x;
}
assert(r==x*y);
}
Making undecidable
problems feel decidable
in practice
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i--;
r=r+x;
}
assert(r==x*y);
}
Could this
assert
ever fail?
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Inductive invariant
Inductive invariant
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
x,y,r,i
A
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i>0 condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i>0 condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
x,y,r,i
A
Now we ignore how
we got into the loop
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i>0 condition: r==(y-i)*x && i>=0
i’=i-1
r’=r+x
post condition: r’==(y-i’)*x && i’>=0
}
assert(r==x*y);
}
x,y,r,i,r’,i’
A
Now we ignore how
we got into the loop
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
i>0 condition: r==(y-i)*x && i>=0
i’=i-1
r’=r+x
post condition: r’==(y-i’)*x && i’>=0
}
assert(r==x*y);
}
x,y,r,i,r’,i’
A
Now we ignore how
we got into the loop
Inductive check
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
If you have good heuristics
for guessing the inductive
invariant, the undecidable
feels decidable
Example: Induction
if (x>=0 && y>=0) {
r=0;
i=y;
while(i>0) {
pre condition: r==(y-i)*x && i>=0
i--;
r=r+x;
post condition: r==(y-i)*x && i>=0
}
assert(r==x*y);
}
This type of bookkeeping can
be dealt with using previously
discussed techniques for NP-
complete problems
Core ideas behind the advances/buzzwords
• Making NP-complete problems feel P-time in practice
• Conflict-clause driven learning
• Back-jumping
• Random-restarts
• SAT and SAT modulo theories
• Making undecidable problems feel decidable in practice
• Abstraction to finite/tractable problems
• Counterexample-guided abstraction refinement
• Interpolation for guessing inductive invariants
Questions answered in this talk
• What is “Mechanized reasoning in mathematical logic” ?
• What are some examples of what is AWS doing in this space?
Questions answered in this talk
• What is “Mechanized reasoning in mathematical logic” ?
• What are some examples of what is AWS doing in this space?
Shared security model
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented and not vulnerable to side-channel attacks?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
• Secure usage
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I only allowing one instance in my VPC to send outgoing
network packets?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Demo: tool for reasoning
about VPCs using
techniques for NP-complete
reasoning
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Demo: tool for reasoning
about VPCs using
techniques for NP-complete
reasoning
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Demo: Proving correctness
properties of s2n using
induction and techniques
for NP-complete reasoning
Shared security model
Demo: tool for reasoning
about VPCs using
techniques for NP-complete
reasoning
Reasoning about networks
• Web service and CLI available in private beta
• Automatically answers queries about customer EC2
networking configurations
• Queries written in a simple query language
• No packets sent; network not actually used
• We can reason about networks that have not been deployed yet
Reasoning about networks
• EC2 networking semantics specified in logic
• For example, all possible subtle interactions between NAT
gateways, AZs, ACLs, VPC peering endpoints, load balancers,
etc
• Considers all possible cases/scenarios
• Can prove that there is no way for instance I to reach J
• NP-complete queries, usually answered in P-time
• Using approaches mentioned previously
Example queries
• “Which EC2 instances are accessible from the Internet?”
• “From my VPC, can non-bastion instances only SSH to
the bastions?”
• “Which EC2 instances can access an S3 endpoint?”
• “Can instances tagged Public communicate with instances
tagged Private?"
Example queries
• “Which EC2 instances are accessible from the Internet?”
• “From my VPC, can non-bastion instances only SSH to
the bastions?”
• “Which EC2 instances can access an S3 endpoint?”
• “Can instances tagged Public communicate with instances
tagged Private?"
list: internet-can-ssh-to-instance(Inst).
Example queries
• “Which EC2 instances are accessible from the Internet?”
• “From my VPC, can non-bastion instances only SSH to
the bastions?”
• “Which EC2 instances can access an S3 endpoint?”
• “Can instances tagged Public communicate with instances
tagged Private?"
all Src, Dst:
instance-has-vpc(Src,byron_vpc) &&
!atom/instance-tag(Dst, tag-key/Name, tag-value/Bastion) &&
instance-can-ssh-to-instance(Src,Dst)
=>
atom/instance-tag(Dst,tag-key/Name,tag-value/Bastion)
Example queries
• “Which EC2 instances are accessible from the Internet?”
• “From my VPC, can non-bastion instances only SSH to
the bastions?”
• “Which EC2 instances can access an S3 endpoint?”
• “Can instances tagged Public communicate with instances
tagged Private?"
list:
ex Src:
instance-can-ssh-to-instance(Src,Dst) &&
atom/instance-tag(InstDest, tag-key/Name, tag-value/S3Endpoint)
Example queries
• “Which EC2 instances are accessible from the Internet?”
• “From my VPC, can non-bastion instances only SSH to
the bastions?”
• “Which EC2 instances can access an S3 endpoint?”
• “Can instances tagged Public communicate with instances
tagged Private?"
list:
ex Src:
instance-can-ssh-to-instance(Src,Dst) &&
atom/instance-tag(InstDest, tag-key/Name, tag-value/S3Endpoint)
EC2 networking concepts supported
Availability Zones
Instances
Internet gateways
Load balancers
NAT instances
NAT gateways
Network ACLs
Network interfaces
Regions
Route tables
Security groups
Subnets
Tags
VPC endpoints
VPC peering connections
VPCs
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Demo: Proving correctness
properties of s2n using
induction and techniques
for NP-complete reasoning
Shared security model
Demo: Proving correctness
properties of s2n using
induction and techniques
for NP-complete reasoning
S2N
• Small, fast TLS library
• Rigorously engineered for security
• Open source
• Mechanical reasoning:
• Automated proving of correctness of S2N’s HMAC implementation
• Proof performed in SAW, see https://saw.galois.com
• Proof strategy: NP-complete techniques + Induction
• Continuous integration: s2n is re-proved correct at each code
checkin
HMAC
• Keyed-hash message authentication code
• Provides a signature for a message that confirms:• Authenticity: the message was signed by the expected sender
• Integrity: the message has not been modified
HMAC(K, m) = H((K0 ⊕ opad)‖H((K0 ⊕ ipad)‖m))
HMAC
• Keyed-hash message authentication code
• Provides a signature for a message that confirms:• Authenticity: the message was signed by the expected sender
• Integrity: the message has not been modified
HMAC(K, m) = H((K0 ⊕ opad)‖H((K0 ⊕ ipad)‖m))
message
HMAC
• Keyed-hash message authentication code
• Provides a signature for a message that confirms:• Authenticity: the message was signed by the expected sender
• Integrity: the message has not been modified
HMAC(K, m) = H((K0⊕ opad)‖H((K0⊕ ipad)‖m))
derived from key
HMAC
• Keyed-hash message authentication code
• Provides a signature for a message that confirms:• Authenticity: the message was signed by the expected sender
• Integrity: the message has not been modified
HMAC(K, m) = H((K0⊕ opad)‖H((K0⊕ ipad)‖m))
arbitrary hash function
HMAC
• Keyed-hash message authentication code
• Provides a signature for a message that confirms:• Authenticity: the message was signed by the expected sender
• Integrity: the message has not been modified
HMAC(K, m) = H((K0⊕ opad)‖H((K0⊕ ipad)‖m))
constants from NIST
HMAC
hmac h h2 h3 K m = h2 (okey # split (h (ikey # m)))
where
k0 = kinit h3 K
okey = [kb ^ 0x5C | kb <- k0]
ikey = [kb ^ 0x36 | kb <- k0]
HMAC(K, m) = H((K0⊕ opad)‖H((K0⊕ ipad)‖m))
Cryptol formal specification:
HMAC
hmac h h2 h3 K m = h2 (okey # split (h (ikey # m)))
where
k0 = kinit h3 K
okey = [kb ^ 0x5C | kb <- k0]
ikey = [kb ^ 0x36 | kb <- k0]
HMAC(K, m) = H((K0⊕ opad)‖H((K0⊕ ipad)‖m))
Cryptol formal specification:
hmac h h2 h3 K m =
h2 (okey # split (h (ikey # m)))
where
k0 = kinit h3 K
okey = [kb ^ 0x5C | kb <- k0]
ikey = [kb ^ 0x36 | kb <- k0]
static int s2n_sslv3_mac_init (struct s2n_hmac_state *state,
s2n_hmac_algorithm alg, const void *key,
uint32_t klen)
{
s2n_hash_algorithm hash_alg = S2N_HASH_NONE ;
if (alg == S2N_HMAC_SSLv3_MD5 ) {
hash_alg = S2N_HASH_MD5 ;
}
if (alg == S2N_HMAC_SSLv3_SHA1 ) {
hash_alg = S2N_HASH_SHA1 ;
}
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x36;
}
GUARD(s2n_hash_init (&state->inner_just_key , hash_alg));
GUARD(s2n_hash_update (&state->inner_just_key , key, klen));
GUARD(s2n_hash_update (&state->inner_just_key , state->xor_pad,
state->block_size));
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x5c;
}
GUARD(s2n_hash_init (&state->outer, hash_alg));
GUARD(s2n_hash_update (&state->outer, key, klen));
GUARD(s2n_hash_update (&state->outer, state->xor_pad, state->block_size));
/* Copy inner_just_key to inner */
return s2n_hmac_reset (state);
}
static int s2n_sslv3_mac_digest (struct s2n_hmac_state *state, void *out,
uint32_t size)
{
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x5c;
}
GUARD(s2n_hash_digest (&state->inner, state->digest_pad,
state->digest_size ));
memcpy_check (&state->inner, &state->outer, sizeof(state->inner));
GUARD(s2n_hash_update (&state->inner, state->digest_pad,
state->digest_size ));
return s2n_hash_digest (&state->inner, out, size);
}
int s2n_hmac_init (struct s2n_hmac_state *state, s2n_hmac_algorithm alg,
const void *key, uint32_t klen)
{
s2n_hash_algorithm hash_alg = S2N_HASH_NONE ;
state->currently_in_hash_block = 0;
state->digest_size = 0;
state->block_size = 64;
state->hash_block_size = 64;
switch (alg) {
case S2N_HMAC_NONE :
break;
case S2N_HMAC_SSLv3_MD5 :
state->block_size = 48;
/* Fall through ... */
case S2N_HMAC_MD5 :
hash_alg = S2N_HASH_MD5 ;
state->digest_size = MD5_DIGEST_LENGTH ;
break;
case S2N_HMAC_SSLv3_SHA1 :
state->block_size = 40;
/* Fall through ... */
case S2N_HMAC_SHA1 :
hash_alg = S2N_HASH_SHA1 ;
state->digest_size = SHA_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA224 :
hash_alg = S2N_HASH_SHA224 ;
state->digest_size = SHA224_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA256 :
hash_alg = S2N_HASH_SHA256 ;
state->digest_size = SHA256_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA384 :
hash_alg = S2N_HASH_SHA384 ;
state->digest_size = SHA384_DIGEST_LENGTH ;
state->block_size = 128;
state->hash_block_size = 128;
break;
case S2N_HMAC_SHA512 :
hash_alg = S2N_HASH_SHA512 ;
state->digest_size = SHA512_DIGEST_LENGTH ;
state->block_size = 128;
state->hash_block_size = 128;
break;
default:
S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM );
}
gte_check(sizeof(state->xor_pad), state->block_size);
gte_check(sizeof(state->digest_pad), state->digest_size );
state->alg = alg;
if (alg == S2N_HMAC_SSLv3_SHA1 || alg == S2N_HMAC_SSLv3_MD5 ) {
return s2n_sslv3_mac_init (state, alg, key, klen);
}
GUARD(s2n_hash_init (&state->inner_just_key , hash_alg));
GUARD(s2n_hash_init (&state->outer, hash_alg));
uint32_t copied = klen;
if (klen > state->block_size) {
GUARD(s2n_hash_update (&state->outer, key, klen));
GUARD(s2n_hash_digest (&state->outer, state->digest_pad,
state->digest_size));
memcpy_check(state->xor_pad, state->digest_pad, state->digest_size);
copied = state->digest_size;
} else {
memcpy_check(state->xor_pad, key, klen);
}
for (int i = 0; i < copied; i++) {
state->xor_pad[i] ^= 0x36;
}
for (int i = copied; i < state->block_size; i++) {
state->xor_pad[i] = 0x36;
}
GUARD(s2n_hash_update (&state->inner_just_key , state->xor_pad,
state->block_size));
/* 0x36 xor 0x5c == 0x6a */
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] ^= 0x6a;
}
return s2n_hmac_reset (state);
}
int s2n_hmac_update (struct s2n_hmac_state *state, const void *in, uint32_t size)
{
/* Keep track of how much of the current hash block is full
*
* Why the 4294949760 constant in this code? 4294949760 is the
* highest 32-bit value that is congruent to 0 modulo all of our
* HMAC block sizes, that is also at least 16k smaller than 2^32. It
* therefore has no effect on the mathematical result, and no valid
* record size can cause it to overflow.
*
* The value was found with the following python code;
*
* x = (2 ** 32) - (2 ** 14)
* while True:
* if x % 40 | x % 48 | x % 64 | x % 128 == 0:
* break
* x -= 1
* print x
*
* What it does do however is ensure that the mod operation takes a
* constant number of instruction cycles, regardless of the size of
* the input. On some platforms, including Intel, the operation can
* take a smaller number of cycles if the input is "small".
*/
state->currently_in_hash_block += (4294949760 + size) % state->hash_block_size ;
state->currently_in_hash_block %= state->block_size;
return s2n_hash_update (&state->inner, in, size);
}
int s2n_hmac_digest (struct s2n_hmac_state *state, void *out, uint32_t size)
{
if (state->alg == S2N_HMAC_SSLv3_SHA1 || state->alg == S2N_HMAC_SSLv3_MD5 ) {
return s2n_sslv3_mac_digest (state, out, size);
}
GUARD(s2n_hash_digest (&state->inner, state->digest_pad,
state->digest_size ));
GUARD(s2n_hash_reset (&state->outer));
GUARD(s2n_hash_update (&state->outer, state->xor_pad, state->block_size));
GUARD(s2n_hash_update (&state->outer, state->digest_pad,
state->digest_size ));
return s2n_hash_digest (&state->outer, out, size);
}
int s2n_hmac_reset (struct s2n_hmac_state *state)
{
state->currently_in_hash_block = 0;
memcpy_check (&state->inner, &state->inner_just_key , sizeof(state->inner));
return 0;
}
static int s2n_sslv3_mac_init (struct s2n_hmac_state *state,
s2n_hmac_algorithm alg, const void *key,
uint32_t klen)
{
s2n_hash_algorithm hash_alg = S2N_HASH_NONE ;
if (alg == S2N_HMAC_SSLv3_MD5 ) {
hash_alg = S2N_HASH_MD5 ;
}
if (alg == S2N_HMAC_SSLv3_SHA1 ) {
hash_alg = S2N_HASH_SHA1 ;
}
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x36;
}
GUARD(s2n_hash_init (&state->inner_just_key , hash_alg));
GUARD(s2n_hash_update (&state->inner_just_key , key, klen));
GUARD(s2n_hash_update (&state->inner_just_key , state->xor_pad,
state->block_size));
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x5c;
}
GUARD(s2n_hash_init (&state->outer, hash_alg));
GUARD(s2n_hash_update (&state->outer, key, klen));
GUARD(s2n_hash_update (&state->outer, state->xor_pad, state->block_size));
/* Copy inner_just_key to inner */
return s2n_hmac_reset (state);
}
static int s2n_sslv3_mac_digest (struct s2n_hmac_state *state, void *out,
uint32_t size)
{
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] = 0x5c;
}
GUARD(s2n_hash_digest (&state->inner, state->digest_pad,
state->digest_size ));
memcpy_check (&state->inner, &state->outer, sizeof(state->inner));
GUARD(s2n_hash_update (&state->inner, state->digest_pad,
state->digest_size ));
return s2n_hash_digest (&state->inner, out, size);
}
int s2n_hmac_init (struct s2n_hmac_state *state, s2n_hmac_algorithm alg,
const void *key, uint32_t klen)
{
s2n_hash_algorithm hash_alg = S2N_HASH_NONE ;
state->currently_in_hash_block = 0;
state->digest_size = 0;
state->block_size = 64;
state->hash_block_size = 64;
switch (alg) {
case S2N_HMAC_NONE :
break;
case S2N_HMAC_SSLv3_MD5 :
state->block_size = 48;
/* Fall through ... */
case S2N_HMAC_MD5 :
hash_alg = S2N_HASH_MD5 ;
state->digest_size = MD5_DIGEST_LENGTH ;
break;
case S2N_HMAC_SSLv3_SHA1 :
state->block_size = 40;
/* Fall through ... */
case S2N_HMAC_SHA1 :
hash_alg = S2N_HASH_SHA1 ;
state->digest_size = SHA_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA224 :
hash_alg = S2N_HASH_SHA224 ;
state->digest_size = SHA224_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA256 :
hash_alg = S2N_HASH_SHA256 ;
state->digest_size = SHA256_DIGEST_LENGTH ;
break;
case S2N_HMAC_SHA384 :
hash_alg = S2N_HASH_SHA384 ;
state->digest_size = SHA384_DIGEST_LENGTH ;
state->block_size = 128;
state->hash_block_size = 128;
break;
case S2N_HMAC_SHA512 :
hash_alg = S2N_HASH_SHA512 ;
state->digest_size = SHA512_DIGEST_LENGTH ;
state->block_size = 128;
state->hash_block_size = 128;
break;
default:
S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM );
}
gte_check(sizeof(state->xor_pad), state->block_size);
gte_check(sizeof(state->digest_pad), state->digest_size );
state->alg = alg;
if (alg == S2N_HMAC_SSLv3_SHA1 || alg == S2N_HMAC_SSLv3_MD5 ) {
return s2n_sslv3_mac_init (state, alg, key, klen);
}
GUARD(s2n_hash_init (&state->inner_just_key , hash_alg));
GUARD(s2n_hash_init (&state->outer, hash_alg));
uint32_t copied = klen;
if (klen > state->block_size) {
GUARD(s2n_hash_update (&state->outer, key, klen));
GUARD(s2n_hash_digest (&state->outer, state->digest_pad,
state->digest_size));
memcpy_check(state->xor_pad, state->digest_pad, state->digest_size);
copied = state->digest_size;
} else {
memcpy_check(state->xor_pad, key, klen);
}
for (int i = 0; i < copied; i++) {
state->xor_pad[i] ^= 0x36;
}
for (int i = copied; i < state->block_size; i++) {
state->xor_pad[i] = 0x36;
}
GUARD(s2n_hash_update (&state->inner_just_key , state->xor_pad,
state->block_size));
/* 0x36 xor 0x5c == 0x6a */
for (int i = 0; i < state->block_size; i++) {
state->xor_pad[i] ^= 0x6a;
}
return s2n_hmac_reset (state);
}
int s2n_hmac_update (struct s2n_hmac_state *state, const void *in, uint32_t size)
{
/* Keep track of how much of the current hash block is full
*
* Why the 4294949760 constant in this code? 4294949760 is the
* highest 32-bit value that is congruent to 0 modulo all of our
* HMAC block sizes, that is also at least 16k smaller than 2^32. It
* therefore has no effect on the mathematical result, and no valid
* record size can cause it to overflow.
*
* The value was found with the following python code;
*
* x = (2 ** 32) - (2 ** 14)
* while True:
* if x % 40 | x % 48 | x % 64 | x % 128 == 0:
* break
* x -= 1
* print x
*
* What it does do however is ensure that the mod operation takes a
* constant number of instruction cycles, regardless of the size of
* the input. On some platforms, including Intel, the operation can
* take a smaller number of cycles if the input is "small".
*/
state->currently_in_hash_block += (4294949760 + size) % state->hash_block_size ;
state->currently_in_hash_block %= state->block_size;
return s2n_hash_update (&state->inner, in, size);
}
int s2n_hmac_digest (struct s2n_hmac_state *state, void *out, uint32_t size)
{
if (state->alg == S2N_HMAC_SSLv3_SHA1 || state->alg == S2N_HMAC_SSLv3_MD5 ) {
return s2n_sslv3_mac_digest (state, out, size);
}
GUARD(s2n_hash_digest (&state->inner, state->digest_pad,
state->digest_size ));
GUARD(s2n_hash_reset (&state->outer));
GUARD(s2n_hash_update (&state->outer, state->xor_pad, state->block_size));
GUARD(s2n_hash_update (&state->outer, state->digest_pad,
state->digest_size ));
return s2n_hash_digest (&state->outer, out, size);
}
int s2n_hmac_reset (struct s2n_hmac_state *state)
{
state->currently_in_hash_block = 0;
memcpy_check (&state->inner, &state->inner_just_key , sizeof(state->inner));
return 0;
}
C HMACCryptol HMAC
Proof bridges this gap
Intermediate model
High-level
Cryptol
Code
Lower-level
Cryptol
Code
Production
s2n
codeproof proof
”Proof plumbing”: hand-crafted
proof artifact written in Galois
language
Intermediate model
High-level
Cryptol
code
Lower-level
Cryptol
code
Production
s2n
codeproof proof
Incorporates s2n data
structures and APIs
Intermediate model
High-level
Cryptol
Code
Lower-level
Cryptol
Code
Production
s2n
codeproof proof
Omits pointer/memory and low-
level performance optimizations
Comparing for all message sizes and splittings
• Key inductive lemmas:• hmac_update(hmac_update(s,m1),m2)) =
hmac_update(s,m1#m2)
• hmac_update(s, ””) = s
• Proved:
• Any sequence of hmac_update calls equivalent to a single call
• Single call of specification hmac_update equivalent to
implementation hmac_update
Continuous integration
• Proofs replayed automatically in Travis CI• Proof failure is a build failure
• Average runtime: 15mins
• Proof is agnostic to structure of C code, depends on:• Interfaces (arguments and struct layouts)
• Function call structure
• Easily adapted:• Function body changes → no proof changes likely needed
• Interface changes → similarly sized proof changes
• Call structure changes → tiny proof changes
Demo
Questions answered in this talk
• What is “Mechanized reasoning in mathematical logic” ?
• What are some examples of what is AWS doing in this space?
Questions answered in this talk
• What is “Mechanized reasoning in mathematical logic” ?
• What are some examples of what is AWS doing in this space?
Shared security model
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented and not vulnerable to side-channel attacks?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
• Secure usage
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I only allowing one instance in my VPC to send outgoing
network packets?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Shared security model
• Helping customers be secure in the cloud
• “Could my IAM policy allow unintended users access to my Amazon
S3 bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Project addressing this topic
too
Shared security model
• Helping customers be secure in the cloud
• “Could my AWS IAM policy allow unintended users access to my S3
bucket?”
• “Am I allowing only one instance in my VPC to send outgoing
network packets?”
• Securing the cloud
• “How do we know that the AWS crypto primitives are correctly
implemented?”
• “How do we know that the Amazon EC2 virtualization layer protects
against memory corruption-based attacks?”
Project addressing this topic
too
Thank you!