• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..15-Oct-2021-

bin/H15-Oct-2021-272219

include/H15-Oct-2021-5526

lib/H15-Oct-2021-7357

working/H15-Oct-2021-2,9501,810

.gitignoreH A D15-Oct-202117 43

DEBUGGING.mdH A D15-Oct-20219.7 KiB258203

MakefileH A D15-Oct-2021734 3023

README.mdH A D15-Oct-20219.6 KiB221158

count_success.plH A D15-Oct-20212.2 KiB7041

README.md

1
2
3# Constant Time Verification Tests for s2n
4
5This repository contains tests which ensure that key s2n functions
6are not susceptible to timing attacks.
7For more details, see https://github.com/awslabs/s2n/issues/463
8
9<!-- START doctoc generated TOC please keep comment here to allow auto update -->
10<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
11**Table of Contents**
12
13- [What are timing side channels](#what-are-timing-side-channels)
14- [s2n countermeasures against timing side channels](#s2n-countermeasures-against-timing-side-channels)
15- [Why use formal methods to prove the correctness of s2n's countermeasures?](#why-use-formal-methods-to-prove-the-correctness-of-s2ns-countermeasures)
16- [How does SideTrail prove the correctness of code blinding countermeasures](#how-does-sidetrail-prove-the-correctness-of-code-blinding-countermeasures)
17  - [High level overview](#high-level-overview)
18  - [User annotations](#user-annotations)
19  - [The gory details](#the-gory-details)
20- [How to execute the tests](#how-to-execute-the-tests)
21  - [Get Docker](#get-docker)
22  - [Building the image](#building-the-image)
23  - [Starting docker](#starting-docker)
24  - [Running a proof inside docker](#running-a-proof-inside-docker)
25- [Debugging SideTrail failures](#debugging-sidetrail-failures)
26- [Questions?](#questions)
27
28<!-- END doctoc generated TOC please keep comment here to allow auto update -->
29
30
31## What are timing side channels
32
33Cryptographic protocols such as TLS are supposed to keep secret information secret.
34They do this by ensuring that WHICH bytes go over the wire is hidden using encryption.
35However, if the code is not carefully written, WHEN bytes go over the wire may depend
36on values that were supposed to remain secret.
37
38For example, if code checks a password as follows
39
40```C
41for (i = 0; i < length; ++i) {
42  if password[i] != input[i] {
43    send("bad password");
44  }
45}
46```
47
48then the amount of time until the reply message is received will depend on which byte in the password is incorrect.
49An attacker can simply guess
50
51  * a*******
52  * b*******
53  * c*******
54
55until the time to receive the error message changes, and then they know the first letter in the password.
56Repeating for the remaining characters turns an exponential guessing challenge into a linear one.
57
58A variant of this attack, called LUCKY13, has been demonstrated against some implementations the Cipher Block Chaining (CBC) mode of SSL/TLS.
59In this attack, the TLS server is tricked into treating a (secret) encrypted byte as a padding length field.
60A naive TLS implementation will remove the specified amount of padding, then calculate a hash on the remaining bytes in the packet.
61If the value in the secret byte was large, a small number of bytes will be hashed; if it was small, a larger number of bytes will be hashed, creating a timing difference, which in theory can reveal the value in the secret byte.
62
63For a detailed discussion of the LUCKY13 attack and how s2n mitigates against it, see [this blog post](https://aws.amazon.com/blogs/security/s2n-and-lucky-13/).
64
65## s2n countermeasures against timing side channels
66
67s2n takes a belt and suspenders approach to preventing side-channel attacks.
681. First of all, it uses code-balancing to ensure that the same number of hash compression rounds are processed, no matter the value in the secret byte.
692. Second, it adds a delay of up to 10 seconds whenever any error is triggered, which increases by orders of magnitude the number of timing samples an attacker would need, even if they found a way around countermeasure 1.
70
71## Why use formal methods to prove the correctness of s2n's countermeasures?
72Side channels are notoriously difficult to defend against, since code with a side-channel has the same functional behaviour as code that is side-channel free.
73Testing can find bugs, but it cannot prove their absence.
74In order to prove the absence of a timing side-channel (up to a timing model of system execution), you need a formal proof.
75
76Formal proofs are also useful because they help prevent regressions.
77If a code change causes a timing side-channel to be introduced, the proof will fail, and the developer will be notified before the bug goes to production.
78
79## How does SideTrail prove the correctness of code blinding countermeasures
80
81### High level overview
82A program has a timing side channel if the amount of time needed to execute it depends on the value of a secret input to the program.
83SideTrail take a program, annotates every instruction with its runtime cost, and then generates a mathematical formula which symbolically represents the cost of executing the program given an input.
84SideTrail then asks an automated theorem prover, called a Satisfiability Modulo Theories (SMT) solver, if there is a pair of secret inputs to the program that would take different amounts of time to process.
85The SMT solver, using clever heuristics, exhaustively searches the state of all possible program inputs, and either returns a proof that there is no timing side-channel, or an example of a pair of inputs that lead to a timing channel, along with the estimated leakage.
86
87### User annotations
88In addition to the standard `assert()/assume()/` annotations supported through SMACK, there are several annotations supported by SideTrail, which allow the user to pass information to the SideTrail proof:
89
901. `__VERIFIER_ASSUME_LEAKAGE(arg)`: When the timing-modeling transformation encounters this call, it increments the leakage tracking variables by "arg"
912. `S2N_PUBLIC_INPUT(arg)`: the argument given here is taken to be public.
92   All other variables are assumed private by default.
933. `S2N_INVARIANT(arg)`: asserts that the given argument is an invariant of the loop, and as such holds on each execution of the loop, and at loop exit.
944. `__VERIFIER_ASSERT_MAX_LEAKAGE(arg)`: asserts that the given function is time-balanced, with a leakage of less than "arg" time units.
95
96### The gory details
97
98Mathematically, a program `P(secret, public)` has runtime `Time(P(secret,public))`.
99A program has a timing side-channel of delta if `|Time(P(secret_1,public)) - Time(P(secret_2,public))| = delta`.
100If we can represent `Time(P(secret,public))` as a mathematical formula, we can use a theorem prover to mathematically prove that the timing leakage of the program, for all choices of `secret_1, secret_2`, is less than `delta`.
101
102SideTrail proceeds in several steps:
103
1041. Compile the code to llvm bitcode - this allows SideTrail to accurately represent the effect of compiler optimizations on runtime
1052. Use LLVM's timing model to associate every bitcode operation with a timing cost
1063. Use SMACK to compile the annotated LLVM code to BoogiePL (this represents `(P(secret,public))` in the above formula
1074. Use bam-bam-boogieman to
108  * Add a timing cost variable to the program, generating `Time(P(secret,public))`
109  * Make two copies of the resulting program, one which has inputs `(secret_1, public)`, the other of which has inputs `(secret_2, public)`
110  * Assert that the difference in time between the two programs is less than `delta`
1115. Use boogie to prove (via the z3 theorem prover) that either
112  * The time is indeed less than `delta`
113  * or, the time is greater than `delta`, in which case the prover can emit a trace leading to the error
114
115
116## How to execute the tests
117
118### Get Docker
119
120We assume you have docker installed and running on your machine.
121If not, follow the instructions to install it https://docs.docker.com/get-docker/
122
123We will assume that you have a variable `$S2N` which encodes the path to s2n on your machine
124
125```shell
126export S2N=<path_to_s2n>
127```
128
129### Building the image
130
131To build the image, start with `s2n/codebuild/spec/sidetrail/Dockerfile`
132
133```shell
134cd $S2N
135docker build -f codebuild/spec/sidetrail/Dockerfile --tag sidetrail .
136```
137
138This step takes about 25 minutes on my laptop.
139
140### Starting docker
141
142```shell
143cd $S2N
144docker run -u `id -u` \
145           -v `pwd`:/home/s2n \
146           -w /home/s2n/tests/sidetrail/working \
147           --entrypoint /bin/bash \
148           -it sidetrail
149```
150
151You will now be presented with a docker shell.
152Inside this shell, run:
153
154```shell
155source /sidetrail-install-dir/smack.environment
156```
157
158This step is important.
159If you do not source this file when you begin working, SideTrail may appear to run, but not actually analyze the code.
160
161### Running a proof inside docker
162
163```shell
164cd <testname>
165./clean.sh && ./run.sh
166```
167
168You should see output that looks something like this
169
170```
171...
172...
173warning: memory intrinsic length exceeds threshold (0); adding quantifiers.
174SMACK generated s2n_record_parse_wrapper@s2n_record_read_wrapper.c.compiled.bpl
175warning: module contains undefined functions: malloc, __CONTRACT_invariant, nondet
176
177 ____                _            _
178|  _ \ _ __ ___   __| |_   _  ___| |_
179| |_) | '__/ _ \ / _` | | | |/ __| __|
180|  __/| | | (_) | (_| | |_| | (__| |_
181|_|   |_|  \___/ \__,_|\__,_|\___|\__|
182
183s2n_record_parse_wrapper@s2n_record_read_wrapper.c
184
185
186
187__     __        _  __
188\ \   / /__ _ __(_)/ _|_   _
189 \ \ / / _ \ '__| | |_| | | |
190  \ V /  __/ |  | |  _| |_| |
191   \_/ \___|_|  |_|_|  \__, |
192                       |___/
193s2n_record_parse_wrapper@s2n_record_read_wrapper.c
194
195+  boogie /printModel 4 /doModSetAnalysis s2n_record_parse_wrapper@s2n_record_read_wrapper.c.product.bpl
196Boogie program verifier version 2.3.0.61016, Copyright (c) 2003-2014, Microsoft.
197
198Boogie program verifier finished with 1 verified, 0 errors
199
200real	0m23.334s
201user	0m20.983s
202sys	0m2.395s
203```
204
205If you do not see the line,
206
207```
208Boogie program verifier finished with 1 verified, 0 errors
209```
210
211then you probably forgot to source `smack.environment`.
212Go back and do so.
213
214## Debugging SideTrail failures
215
216Consult [the debugging guide](DEBUGGING.md).
217
218## Questions?
219
220contact aws-arg-platforms-support@amazon.com
221