Cryptographic 1972 Parnas On the criteria software engineering, to - - PowerPoint PPT Presentation

cryptographic 1972 parnas on the criteria software
SMART_READER_LITE
LIVE PREVIEW

Cryptographic 1972 Parnas On the criteria software engineering, to - - PowerPoint PPT Presentation

1 2 Cryptographic 1972 Parnas On the criteria software engineering, to be used in decomposing part 1 systems into modules: Daniel J. Bernstein We propose instead that one begins with a list of difficult design decisions or This


slide-1
SLIDE 1

1

Cryptographic software engineering, part 1 Daniel J. Bernstein This is easy, right?

  • 1. Take general principles
  • f software engineering.
  • 2. Apply principles to crypto.

Let’s try some examples : : :

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change.

slide-2
SLIDE 2

1

Cryptographic re engineering,

  • J. Bernstein

easy, right? e general principles software engineering. Apply principles to crypto. try some examples : : :

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change. Another

  • f softwa

Make the and the

slide-3
SLIDE 3

1

engineering, Bernstein right? principles engineering. rinciples to crypto. examples : : :

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change. Another general principle

  • f software engineering:

Make the right thing and the wrong thing

slide-4
SLIDE 4

1

engineering. crypto. : :

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change. Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex.

slide-5
SLIDE 5

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change.

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex.

slide-6
SLIDE 6

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change.

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators.

slide-7
SLIDE 7

2

1972 Parnas “On the criteria to be used in decomposing systems into modules”: “We propose instead that

  • ne begins with a list of

difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.” e.g. If number of cipher rounds is properly modularized as

#define ROUNDS 20

then it is easy to change.

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ”

slide-8
SLIDE 8

2

arnas “On the criteria used in decomposing systems into modules”: ropose instead that egins with a list of difficult design decisions or decisions which are to change. Each module designed to hide such decision from the others.” number of cipher rounds erly modularized as

ROUNDS 20

is easy to change.

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ” Not so easy: 1970s: TENEX compares against secret

  • ne chara

stopping

  • AAAAAA
  • FAAAAA
  • FRAAAA
slide-9
SLIDE 9

2

“On the criteria decomposing dules”: instead that a list of decisions or which are Each module to hide such the others.”

  • f cipher rounds

dularized as

20

change.

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ” Not so easy: Timing 1970s: TENEX op compares user-supplied against secret passw

  • ne character at a

stopping at first difference:

  • AAAAAA vs. FRIEND
  • FAAAAA vs. FRIEND
  • FRAAAA vs. FRIEND
slide-10
SLIDE 10

2

criteria r dule such

  • thers.”

rounds

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ” Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at
  • FAAAAA vs. FRIEND: stop at
  • FRAAAA vs. FRIEND: stop at
slide-11
SLIDE 11

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ”

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.
slide-12
SLIDE 12

3

Another general principle

  • f software engineering:

Make the right thing simple and the wrong thing complex. e.g. Make it difficult to ignore invalid authenticators. Do not design APIs like this: “The sample code used in this manual omits the checking

  • f status values for clarity, but

when using cryptlib you should check return values, particularly for critical functions : : : ”

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password.

slide-13
SLIDE 13

3

Another general principle ware engineering: the right thing simple the wrong thing complex. Make it difficult to invalid authenticators. not design APIs like this: sample code used in manual omits the checking status values for clarity, but using cryptlib you should return values, particularly tical functions : : : ”

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password. How typical 16-byte authenticato

for (i if (x[i] return

slide-14
SLIDE 14

3

principle engineering: thing simple thing complex. difficult to authenticators. APIs like this: de used in

  • mits the checking

for clarity, but cryptlib you should values, particularly functions : : : ”

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password. How typical softwa 16-byte authenticato

for (i = 0;i < if (x[i] != y[i]) return 1;

slide-15
SLIDE 15

3

simple complex. rs. this: checking but should rticularly

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password. How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return return 1;

slide-16
SLIDE 16

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password.

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

slide-17
SLIDE 17

4

Not so easy: Timing attacks 1970s: TENEX operating system compares user-supplied string against secret password

  • ne character at a time,

stopping at first difference:

  • AAAAAA vs. FRIEND: stop at 1.
  • FAAAAA vs. FRIEND: stop at 2.
  • FRAAAA vs. FRIEND: stop at 3.

Attacker sees comparison time, deduces position of difference. A few hundred tries reveal secret password.

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex.

slide-18
SLIDE 18

4

easy: Timing attacks TENEX operating system res user-supplied string against secret password character at a time, stopping at first difference: AAAAAA vs. FRIEND: stop at 1. FAAAAA vs. FRIEND: stop at 2. FRAAAA vs. FRIEND: stop at 3. er sees comparison time, deduces position of difference. hundred tries secret password.

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex. Language “right” is So mistak

slide-19
SLIDE 19

4

Timing attacks

  • perating system

user-supplied string password a time, difference: FRIEND: stop at 1. FRIEND: stop at 2. FRIEND: stop at 3. comparison time,

  • f difference.

tries password.

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex. Language designer’s “right” is too weak So mistakes continue

slide-20
SLIDE 20

4

attacks system string difference: stop at 1. stop at 2. stop at 3. time, difference.

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex. Language designer’s notion of “right” is too weak for securit So mistakes continue to happ

slide-21
SLIDE 21

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex.

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen.

slide-22
SLIDE 22

5

How typical software checks 16-byte authenticator:

for (i = 0;i < 16;++i) if (x[i] != y[i]) return 0; return 1;

Fix, eliminating information flow from secrets to timings:

diff = 0; for (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

Notice that the language makes the wrong thing simple and the right thing complex.

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

slide-23
SLIDE 23

5

ypical software checks yte authenticator:

(i = 0;i < 16;++i) (x[i] != y[i]) return 0; return 1;

eliminating information flow secrets to timings:

= 0; (i = 0;i < 16;++i) diff |= x[i] ^ y[i]; return 1 & ((diff-1) >> 8);

that the language the wrong thing simple the right thing complex.

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

Do timing Objection:

slide-24
SLIDE 24

5

ware checks authenticator:

16;++i) y[i]) return 0;

information flow timings:

16;++i) ^ y[i]; ((diff-1) >> 8);

language wrong thing simple thing complex.

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

Do timing attacks Objection: “Timings

slide-25
SLIDE 25

5

checks

return 0;

rmation flow

>> 8);

imple complex.

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

Do timing attacks really work? Objection: “Timings are noisy!

slide-26
SLIDE 26

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!”

slide-27
SLIDE 27

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow.

slide-28
SLIDE 28

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise.

slide-29
SLIDE 29

6

Language designer’s notion of “right” is too weak for security. So mistakes continue to happen. One of many examples, part of the reference software for

  • ne of the CAESAR candidates:

/* compare the tag */ int i; for(i = 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; } return RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise. Answer #3, what the 1970s attackers actually did: Cross page boundary, inducing page faults, to amplify timing signal.

slide-30
SLIDE 30

6

Language designer’s notion of “right” is too weak for security. mistakes continue to happen.

  • f many examples,
  • f the reference software for

the CAESAR candidates:

compare the tag */ 0;i < CRYPTO_ABYTES;i++) if(tag[i] != c[(*mlen) + i]){ return RETURN_TAG_NO_MATCH; RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise. Answer #3, what the 1970s attackers actually did: Cross page boundary, inducing page faults, to amplify timing signal. Defenders Some of 1996 Ko attacks on Briefly mentioned Kocher and Schneier–W secret arra affect timing 2002 Page, Suzaki–Shigeri–Miy timing attacks

slide-31
SLIDE 31

6

designer’s notion of eak for security. continue to happen. examples, reference software for CAESAR candidates:

tag */ CRYPTO_ABYTES;i++) c[(*mlen) + i]){ RETURN_TAG_NO_MATCH; RETURN_SUCCESS;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise. Answer #3, what the 1970s attackers actually did: Cross page boundary, inducing page faults, to amplify timing signal. Defenders don’t lea Some of the literature: 1996 Kocher pointed attacks on cryptographi Briefly mentioned Kocher and by 1998 Schneier–Wagner–Hall: secret array indices affect timing via cache 2002 Page, 2003 Tsuno Suzaki–Shigeri–Miy timing attacks on

slide-32
SLIDE 32

6

notion of security. happen. are for candidates:

CRYPTO_ABYTES;i++) + i]){ RETURN_TAG_NO_MATCH;

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise. Answer #3, what the 1970s attackers actually did: Cross page boundary, inducing page faults, to amplify timing signal. Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misse 2002 Page, 2003 Tsunoo–Sa Suzaki–Shigeri–Miyauchi: timing attacks on DES.

slide-33
SLIDE 33

7

Do timing attacks really work? Objection: “Timings are noisy!” Answer #1: Does noise stop all attacks? To guarantee security, defender must block all information flow. Answer #2: Attacker uses statistics to eliminate noise. Answer #3, what the 1970s attackers actually did: Cross page boundary, inducing page faults, to amplify timing signal.

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES.

slide-34
SLIDE 34

7

timing attacks really work? Objection: “Timings are noisy!” er #1: noise stop all attacks? guarantee security, defender block all information flow. er #2: Attacker uses statistics to eliminate noise. er #3, what the attackers actually did: page boundary, inducing page faults, amplify timing signal.

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES. “Guaranteed” load entire

slide-35
SLIDE 35

7

attacks really work? Timings are noisy!” all attacks? security, defender information flow. ttacker uses eliminate noise. what the actually did:

  • undary,

aults, timing signal.

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES. “Guaranteed” counterme load entire table into

slide-36
SLIDE 36

7

  • rk?

noisy!” attacks? defender flow. noise. did:

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES. “Guaranteed” countermeasur load entire table into cache.

slide-37
SLIDE 37

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES.

9

“Guaranteed” countermeasure: load entire table into cache.

slide-38
SLIDE 38

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES.

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices.

slide-39
SLIDE 39

8

Defenders don’t learn Some of the literature: 1996 Kocher pointed out timing attacks on cryptographic key bits. Briefly mentioned by Kocher and by 1998 Kelsey– Schneier–Wagner–Hall: secret array indices can affect timing via cache misses. 2002 Page, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: timing attacks on DES.

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption.

slide-40
SLIDE 40

8

Defenders don’t learn

  • f the literature:

Kocher pointed out timing attacks on cryptographic key bits. mentioned by cher and by 1998 Kelsey– Schneier–Wagner–Hall: array indices can timing via cache misses. age, 2003 Tsunoo–Saito– Suzaki–Shigeri–Miyauchi: attacks on DES.

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption. Intel recomme OpenSSL countermeasure: from kno

slide-41
SLIDE 41

8

learn literature:

  • inted out timing

cryptographic key bits. mentioned by 1998 Kelsey– agner–Hall: indices can cache misses. Tsunoo–Saito– Suzaki–Shigeri–Miyauchi:

  • n DES.

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption. Intel recommends, OpenSSL integrates, countermeasure: alw from known lines of

slide-42
SLIDE 42

8

timing ey bits. Kelsey– misses.

  • –Saito–

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption. Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache.

slide-43
SLIDE 43

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache.

slide-44
SLIDE 44

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004.

slide-45
SLIDE 45

9

“Guaranteed” countermeasure: load entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; e.g., secret array indices can affect timing via cache-bank collisions. What is safe: kill all data flow from secrets to array indices. 2005 Tromer–Osvik–Shamir: 65ms to steal Linux AES key used for hard-disk encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL.

slide-46
SLIDE 46

9

ranteed” countermeasure: entire table into cache. 2004.11/2005.04 Bernstein: Timing attacks on AES. Countermeasure isn’t safe; secret array indices can affect via cache-bank collisions. is safe: kill all data flow secrets to array indices. romer–Osvik–Shamir: to steal Linux AES key for hard-disk encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL. 2008 RF Layer Securit Version 1.2”: small timing performance extent on fragment, be large due to the existing MA

  • f the timing
slide-47
SLIDE 47

9

countermeasure: into cache. Bernstein:

  • n AES.

isn’t safe; indices can affect cache-bank collisions. kill all data flow array indices. romer–Osvik–Shamir: Linux AES key rd-disk encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL. 2008 RFC 5246 “The Layer Security (TLS) Version 1.2”: “This small timing channel, performance depends extent on the size fragment, but it is be large enough to due to the large blo existing MACs and

  • f the timing signal.”
slide-48
SLIDE 48

9

asure: cache. Bernstein: safe; can affect collisions. flow indices. romer–Osvik–Shamir: ey encryption.

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL. 2008 RFC 5246 “The Transp Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MA performance depends to some extent on the size of the data fragment, but it is not believed be large enough to be exploitable due to the large block size of existing MACs and the small

  • f the timing signal.”
slide-49
SLIDE 49

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL.

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”
slide-50
SLIDE 50

10

Intel recommends, and OpenSSL integrates, cheaper countermeasure: always loading from known lines of cache. 2013 Bernstein–Schwabe “A word of warning”: This countermeasure isn’t safe. Variable-time lab experiment. Same issues described in 2004. 2016 Yarom–Genkin–Heninger “CacheBleed” steals RSA secret key via timings of OpenSSL.

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”

2013 AlFardan–Paterson “Lucky Thirteen: breaking the TLS and DTLS record protocols”: exploit these timings; steal plaintext.

slide-51
SLIDE 51

10

recommends, and enSSL integrates, cheaper countermeasure: always loading known lines of cache. Bernstein–Schwabe rd of warning”: countermeasure isn’t safe. riable-time lab experiment. issues described in 2004. arom–Genkin–Heninger “CacheBleed” steals RSA secret timings of OpenSSL.

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”

2013 AlFardan–Paterson “Lucky Thirteen: breaking the TLS and DTLS record protocols”: exploit these timings; steal plaintext. How to write If possible, to control Look for identifying “Division when the completes, cycles re values of Measure trusting

slide-52
SLIDE 52

10

s, and integrates, cheaper always loading lines of cache. Bernstein–Schwabe rning”: countermeasure isn’t safe. lab experiment. described in 2004. rom–Genkin–Heninger steals RSA secret

  • f OpenSSL.

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”

2013 AlFardan–Paterson “Lucky Thirteen: breaking the TLS and DTLS record protocols”: exploit these timings; steal plaintext. How to write constant-time If possible, write co to control instruction Look for documentation identifying variabilit “Division operations when the divide op completes, with the cycles required dep values of the input Measure cycles rather trusting CPU documentation.

slide-53
SLIDE 53

10

cheaper loading cache. safe. eriment. 2004. rom–Genkin–Heninger secret enSSL.

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”

2013 AlFardan–Paterson “Lucky Thirteen: breaking the TLS and DTLS record protocols”: exploit these timings; steal plaintext. How to write constant-time If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number cycles required dependent on values of the input operands.” Measure cycles rather than trusting CPU documentation.

slide-54
SLIDE 54

11

2008 RFC 5246 “The Transport Layer Security (TLS) Protocol, Version 1.2”: “This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size

  • f the timing signal.”

2013 AlFardan–Paterson “Lucky Thirteen: breaking the TLS and DTLS record protocols”: exploit these timings; steal plaintext.

12

How to write constant-time code If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number of cycles required dependent on the values of the input operands.” Measure cycles rather than trusting CPU documentation.

slide-55
SLIDE 55

11

RFC 5246 “The Transport Security (TLS) Protocol, ersion 1.2”: “This leaves a timing channel, since MAC rmance depends to some

  • n the size of the data

fragment, but it is not believed to rge enough to be exploitable, the large block size of existing MACs and the small size timing signal.” AlFardan–Paterson “Lucky Thirteen: breaking the TLS and record protocols”: exploit timings; steal plaintext.

12

How to write constant-time code If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number of cycles required dependent on the values of the input operands.” Measure cycles rather than trusting CPU documentation. Cut off all secrets to Cut off all secrets to Cut off all secrets to Prefer logic Prefer vecto Watch o variable-time Cortex-M3

slide-56
SLIDE 56

11

“The Transport (TLS) Protocol, his leaves a channel, since MAC ends to some size of the data is not believed to to be exploitable, block size of and the small size signal.” rdan–Paterson “Lucky reaking the TLS and rotocols”: exploit steal plaintext.

12

How to write constant-time code If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number of cycles required dependent on the values of the input operands.” Measure cycles rather than trusting CPU documentation. Cut off all data flo secrets to branch conditions. Cut off all data flo secrets to array indices. Cut off all data flo secrets to shift/rotate Prefer logic instructions. Prefer vector instructions. Watch out for CPUs variable-time multipliers: Cortex-M3 and most

slide-57
SLIDE 57

11

ransport Protocol, a since MAC some data elieved to exploitable,

  • f

all size “Lucky TLS and exploit plaintext.

12

How to write constant-time code If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number of cycles required dependent on the values of the input operands.” Measure cycles rather than trusting CPU documentation. Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs.

slide-58
SLIDE 58

12

How to write constant-time code If possible, write code in asm to control instruction selection. Look for documentation identifying variability: e.g., “Division operations terminate when the divide operation completes, with the number of cycles required dependent on the values of the input operands.” Measure cycles rather than trusting CPU documentation.

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs.

slide-59
SLIDE 59

12

to write constant-time code

  • ssible, write code in asm

control instruction selection. for documentation identifying variability: e.g., “Division operations terminate the divide operation completes, with the number of required dependent on the

  • f the input operands.”

Measure cycles rather than trusting CPU documentation.

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs. Suppose const-time Suppose has “secret Easy for that secret by const-time Proofs of (uninitialized ctgrind,

slide-60
SLIDE 60

12

constant-time code code in asm instruction selection. cumentation riability: e.g., erations terminate

  • peration

the number of dependent on the input operands.” rather than cumentation.

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs. Suppose we know const-time machine Suppose programming has “secret” types. Easy for compiler to that secret types by const-time instructions. Proofs of concept: (uninitialized data ctgrind, ct-verif, Flo

slide-61
SLIDE 61

12

constant-time code asm selection. e.g., terminate er of

  • n the

erands.” than cumentation.

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs. Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret ctgrind, ct-verif, FlowTracker.

slide-62
SLIDE 62

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs.

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker.

slide-63
SLIDE 63

13

Cut off all data flow from secrets to branch conditions. Cut off all data flow from secrets to array indices. Cut off all data flow from secrets to shift/rotate distances. Prefer logic instructions. Prefer vector instructions. Watch out for CPUs with variable-time multipliers: e.g., Cortex-M3 and most PowerPCs.

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array?

slide-64
SLIDE 64

13

all data flow from to branch conditions. all data flow from to array indices. all data flow from to shift/rotate distances. logic instructions. vector instructions.

  • ut for CPUs with

riable-time multipliers: e.g., rtex-M3 and most PowerPCs.

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array? Eliminating Let’s try Assume

slide-65
SLIDE 65

13

flow from ranch conditions. flow from indices. flow from shift/rotate distances. instructions. instructions. CPUs with multipliers: e.g., most PowerPCs.

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array? Eliminating branches Let’s try sorting 2 Assume int32 is secret

slide-66
SLIDE 66

13

conditions. distances. e.g., erPCs.

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array? Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

slide-67
SLIDE 67

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array?

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

slide-68
SLIDE 68

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array?

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

slide-69
SLIDE 69

14

Suppose we know (some) const-time machine instructions. Suppose programming language has “secret” types. Easy for compiler to guarantee that secret types are used only by const-time instructions. Proofs of concept: Valgrind (uninitialized data as secret), ctgrind, ct-verif, FlowTracker. How can we implement, e.g., sorting of a secret array?

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

slide-70
SLIDE 70

14

  • se we know (some)

const-time machine instructions.

  • se programming language

secret” types. for compiler to guarantee secret types are used only const-time instructions.

  • f concept: Valgrind

(uninitialized data as secret), ctgrind, ct-verif, FlowTracker. can we implement, e.g.,

  • f a secret array?

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

void sort2(int32 { int32 int32 if (x1 x[0] x[1] } else x[0] x[1] } }

slide-71
SLIDE 71

14

w (some) machine instructions. rogramming language ypes. compiler to guarantee es are used only instructions. concept: Valgrind data as secret), FlowTracker. implement, e.g., secret array?

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

void sort2(int32 { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

slide-72
SLIDE 72

14

instructions. nguage rantee used only instructions. d secret), ker. e.g.,

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

slide-73
SLIDE 73

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

slide-74
SLIDE 74

15

Eliminating branches Let’s try sorting 2 integers. Assume int32 is secret.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } }

Unacceptable: not constant-time.

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

slide-75
SLIDE 75

15

Eliminating branches try sorting 2 integers. Assume int32 is secret.

sort2(int32 *x) x0 = x[0]; x1 = x[1]; (x1 < x0) { x[0] = x1; x[1] = x0;

Unacceptable: not constant-time.

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

void sort2(int32 { int32 int32 int32 x[0] = x[1] = }

slide-76
SLIDE 76

15

ranches 2 integers. is secret.

*x) x[0]; x[1];

not constant-time.

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

void sort2(int32 { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x[0] = (c ? x1 x[1] = (c ? x0 }

slide-77
SLIDE 77

15

rs. constant-time.

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

slide-78
SLIDE 78

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

slide-79
SLIDE 79

16

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; if (x1 < x0) { x[0] = x1; x[1] = x0; } else { x[0] = x0; x[1] = x1; } }

Safe compiler won’t allow this. Branch timing leaks secrets.

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1;

slide-80
SLIDE 80

16

sort2(int32 *x) x0 = x[0]; x1 = x[1]; (x1 < x0) { x[0] = x1; x[1] = x0; else { x[0] = x0; x[1] = x1;

compiler won’t allow this. Branch timing leaks secrets.

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1; void sort2(int32 { int32 int32 int32 x[c] = x[1 - }

slide-81
SLIDE 81

16

*x) x[0]; x[1];

  • n’t allow this.

leaks secrets.

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1; void sort2(int32 { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x[c] = x0; x[1 - c] = x1; }

slide-82
SLIDE 82

16

this. secrets.

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1; void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

slide-83
SLIDE 83

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1;

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

slide-84
SLIDE 84

17

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[0] = (c ? x1 : x0); x[1] = (c ? x0 : x1); }

Syntax is different but “?:” is a branch by definition:

if (x1 < x0) x[0] = x1; else x[0] = x0; if (x1 < x0) x[1] = x0; else x[1] = x1;

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

slide-85
SLIDE 85

17

sort2(int32 *x) x0 = x[0]; x1 = x[1]; c = (x1 < x0); = (c ? x1 : x0); = (c ? x0 : x1);

is different but “?:” ranch by definition:

(x1 < x0) x[0] = x1; x[0] = x0; (x1 < x0) x[1] = x0; x[1] = x1;

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

void sort2(int32 { int32 int32 int32 c *= x1 x[0] = x[1] = }

slide-86
SLIDE 86

17

*x) x[0]; x[1]; < x0); : x0); : x1);

different but “?:” efinition:

x[0] = x1; x0; x[1] = x0; x1;

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

void sort2(int32 { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

slide-87
SLIDE 87

17

x1; x0;

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

slide-88
SLIDE 88

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

slide-89
SLIDE 89

18

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); x[c] = x0; x[1 - c] = x1; }

Safe compiler won’t allow this: won’t allow secret data to be used as an array index. Cache timing is not constant: see earlier attack examples.

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

Does safe compiler allow multiplication of secrets? Recall that multiplication takes variable time on, e.g., Cortex-M3 and most PowerPCs.

slide-90
SLIDE 90

18

sort2(int32 *x) x0 = x[0]; x1 = x[1]; c = (x1 < x0); = x0; c] = x1;

compiler won’t allow this: allow secret data used as an array index. timing is not constant: rlier attack examples.

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

Does safe compiler allow multiplication of secrets? Recall that multiplication takes variable time on, e.g., Cortex-M3 and most PowerPCs. Will want for fast p but let’s for this so

void sort2(int32 { int32 int32 int32 c &= x1 x[0] = x[1] = }

slide-91
SLIDE 91

18

*x) x[0]; x[1]; < x0);

  • n’t allow this:

secret data array index. not constant: examples.

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

Does safe compiler allow multiplication of secrets? Recall that multiplication takes variable time on, e.g., Cortex-M3 and most PowerPCs. Will want to handle for fast prime-field but let’s dodge the for this sorting code:

void sort2(int32 { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

slide-92
SLIDE 92

18

this: index. constant: examples.

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

Does safe compiler allow multiplication of secrets? Recall that multiplication takes variable time on, e.g., Cortex-M3 and most PowerPCs. Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

slide-93
SLIDE 93

19

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = (x1 < x0); c *= x1 - x0; x[0] = x0 + c; x[1] = x1 - c; }

Does safe compiler allow multiplication of secrets? Recall that multiplication takes variable time on, e.g., Cortex-M3 and most PowerPCs.

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

slide-94
SLIDE 94

19

sort2(int32 *x) x0 = x[0]; x1 = x[1]; c = (x1 < x0); x1 - x0; = x0 + c; = x1 - c;

safe compiler allow multiplication of secrets? that multiplication variable time on, e.g., rtex-M3 and most PowerPCs.

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

  • 1. Possible

(also for C standa int32 as “undefined” Real CPU but C compiler

slide-95
SLIDE 95

19

*x) x[0]; x[1]; < x0);

compiler allow secrets? multiplication time on, e.g., most PowerPCs.

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

  • 1. Possible correctness

(also for previous co C standard does not int32 as twos-complement; “undefined” behavio Real CPU uses twos-complement but C compiler can

slide-96
SLIDE 96

19

e.g., erPCs.

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

  • 1. Possible correctness problem

(also for previous code): C standard does not define int32 as twos-complement; “undefined” behavior on overflo Real CPU uses twos-complement but C compiler can screw this

slide-97
SLIDE 97

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up.

slide-98
SLIDE 98

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

slide-99
SLIDE 99

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t?

slide-100
SLIDE 100

20

Will want to handle this issue for fast prime-field ECC etc., but let’s dodge the issue for this sorting code:

void sort2(int32 *x) { int32 x0 = x[0]; int32 x1 = x[1]; int32 c = -(x1 < x0); c &= x1 ^ x0; x[0] = x0 ^ c; x[1] = x1 ^ c; }

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this.

slide-101
SLIDE 101

20

ant to handle this issue fast prime-field ECC etc., let’s dodge the issue is sorting code:

sort2(int32 *x) x0 = x[0]; x1 = x[1]; c = -(x1 < x0); x1 ^ x0; = x0 ^ c; = x1 ^ c;

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this. Constant-time

int32 isnegative(int32 { return

Returns

slide-102
SLIDE 102

20

handle this issue rime-field ECC etc., the issue code:

*x) x[0]; x[1]; < x0);

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this. Constant-time com

int32 isnegative(int32 { return x >> 31;

Returns -1 if x < 0

slide-103
SLIDE 103

20

issue etc.,

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this. Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise

slide-104
SLIDE 104

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this.

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0.

slide-105
SLIDE 105

21

  • 1. Possible correctness problems

(also for previous code): C standard does not define int32 as twos-complement; says “undefined” behavior on overflow. Real CPU uses twos-complement but C compiler can screw this up. Fix: use gcc -fwrapv.

  • 2. Does safe compiler allow

“x1 < x0” for secrets? What do we do if it doesn’t? C compilers sometimes use constant-time instructions for this.

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

slide-106
SLIDE 106

21

  • ssible correctness problems

for previous code): standard does not define as twos-complement; says “undefined” behavior on overflow. CPU uses twos-complement compiler can screw this up. use gcc -fwrapv. es safe compiler allow

x0” for secrets?

do we do if it doesn’t? compilers sometimes use constant-time instructions for this.

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

int32 ispositive(int32 { return

slide-107
SLIDE 107

21

rrectness problems revious code): not define

  • s-complement; says

ehavior on overflow. wos-complement can screw this up.

  • fwrapv.

compiler allow secrets? if it doesn’t? sometimes use instructions for this.

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

int32 ispositive(int32 { return isnegative(-x);

slide-108
SLIDE 108

21

roblems define

  • s-complement; says
  • verflow.
  • s-complement

this up. w esn’t? use for this.

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

int32 ispositive(int32 x) { return isnegative(-x);

slide-109
SLIDE 109

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

23

int32 ispositive(int32 x) { return isnegative(-x); }

slide-110
SLIDE 110

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231.

slide-111
SLIDE 111

22

Constant-time comparisons

int32 isnegative(int32 x) { return x >> 31; }

Returns -1 if x < 0, otherwise 0. Why this works: the bits (b31; b30; : : : ; b2; b1; b0) represent the integer b0 + 2b1 + 4b2 + · · · + 230b30 − 231b31. “1-bit signed right shift”: (b31; b31; : : : ; b3; b2; b1). “31-bit signed right shift”: (b31; b31; : : : ; b31; b31; b31).

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

slide-112
SLIDE 112

22

Constant-time comparisons

isnegative(int32 x) return x >> 31; }

Returns -1 if x < 0, otherwise 0. this works: the bits

30; : : : ; b2; b1; b0)

resent the integer b0 + 2b1 + · · · + 230b30 − 231b31. signed right shift”:

31; : : : ; b3; b2; b1).

“31-bit signed right shift”:

31; : : : ; b31; b31; b31).

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

Side note

int32 ispositive(int32 { if (x return

slide-113
SLIDE 113

22

comparisons

isnegative(int32 x) 31; }

0, otherwise 0. the bits ; b1; b0) integer b0 + 2b1 +

30 − 231b31.

right shift”: ; b2; b1). right shift”: ; b31; b31).

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

Side note illustrating

int32 ispositive(int32 { if (x == -x) return return isnegative(-x);

slide-114
SLIDE 114

22

risons

x)

  • therwise 0.

2b1 +

31.

shift”: ).

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

Side note illustrating -fwrapv

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x);

slide-115
SLIDE 115

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

slide-116
SLIDE 116

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time.

slide-117
SLIDE 117

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code.

slide-118
SLIDE 118

23

int32 ispositive(int32 x) { return isnegative(-x); }

This code is incorrect! Fails for input −231, because “-x” produces −231. Can catch this bug by testing:

int64 x; int32 c; for (x = INT32_MIN; x <= INT32_MAX;++x) { c = ispositive(x); assert(c == -(x > 0)); }

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

slide-119
SLIDE 119

23

ispositive(int32 x) return isnegative(-x); }

code is incorrect! for input −231, ecause “-x” produces −231. catch this bug by testing:

x; int32 c; = INT32_MIN; <= INT32_MAX;++x) { ispositive(x); assert(c == -(x > 0));

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

int32 isnonzero(int32 { return || isnegative(-x);

slide-120
SLIDE 120

23

ispositive(int32 x) isnegative(-x); }

rrect! 231, roduces −231. bug by testing:

c; INT32_MIN; INT32_MAX;++x) { ispositive(x);

  • (x > 0));

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

int32 isnonzero(int32 { return isnegative(x) || isnegative(-x);

slide-121
SLIDE 121

23

x) }

231. testing:

{

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

slide-122
SLIDE 122

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

slide-123
SLIDE 123

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.
slide-124
SLIDE 124

24

Side note illustrating -fwrapv:

int32 ispositive(int32 x) { if (x == -x) return 0; return isnegative(-x); }

Not constant-time. Even worse: without -fwrapv, current gcc can remove the x == -x test, breaking this code. Incompetent gcc engineering: source of many security holes. Incompetent language standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

slide-125
SLIDE 125

24

note illustrating -fwrapv:

ispositive(int32 x) == -x) return 0; return isnegative(-x); }

constant-time.

  • rse: without -fwrapv,

current gcc can remove the test, breaking this code. Incompetent gcc engineering:

  • f many security holes.

Incompetent language standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

int32 issmaller(int32 { return

slide-126
SLIDE 126

24

illustrating -fwrapv:

ispositive(int32 x) return 0; isnegative(-x); }

constant-time. without -fwrapv, remove the reaking this code. engineering: security holes. language standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

int32 issmaller(int32 { return isnegative(x

slide-127
SLIDE 127

24

  • fwrapv:

x) }

  • fwrapv,

the this code. engineering: holes. standard.

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

int32 issmaller(int32 x,int32 { return isnegative(x - y);

slide-128
SLIDE 128

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

slide-129
SLIDE 129

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231).

slide-130
SLIDE 130

25

int32 isnonzero(int32 x) { return isnegative(x) || isnegative(-x); }

Not constant-time. Second part is evaluated

  • nly if first part is zero.

int32 isnonzero(int32 x) { return isnegative(x) | isnegative(-x); }

Constant-time logic instructions. Safe compiler will allow this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); }

slide-131
SLIDE 131

25

isnonzero(int32 x) return isnegative(x) isnegative(-x); }

constant-time. Second part is evaluated first part is zero.

isnonzero(int32 x) return isnegative(x) isnegative(-x); }

Constant-time logic instructions. compiler will allow this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); } int32 issmaller(int32 { int32 int32 c ^= xy return }

slide-132
SLIDE 132

25

isnonzero(int32 x) isnegative(x) isnegative(-x); }

constant-time. evaluated is zero.

isnonzero(int32 x) isnegative(x) isnegative(-x); }

logic instructions. will allow this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); } int32 issmaller(int32 { int32 xy = x ^ int32 c = x - y; c ^= xy & (c ^ return isnegative(c); }

slide-133
SLIDE 133

25

instructions. this.

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); } int32 issmaller(int32 x,int32 { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

slide-134
SLIDE 134

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); }

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

slide-135
SLIDE 135

26

int32 issmaller(int32 x,int32 y) { return isnegative(x - y); }

This code is incorrect! Generalization of ispositive. Wrong for inputs (0; −231). Wrong for many more inputs. Caught quickly by random tests:

for (j = 0;j < 10000000;++j) { x += random(); y += random(); c = issmaller(x,y); assert(c == -(x < y)); }

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

Some verification strategies:

  • Think this through.
  • Write a proof.
  • Formally verify proof.
  • Automate proof construction.
  • Test many random inputs.
  • A bit painful: test all inputs.
  • Faster: test int16 version.
slide-136
SLIDE 136

26

issmaller(int32 x,int32 y) return isnegative(x - y); }

code is incorrect! Generalization of ispositive. for inputs (0; −231). for many more inputs. Caught quickly by random tests:

= 0;j < 10000000;++j) { random(); y += random(); issmaller(x,y); assert(c == -(x < y));

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

Some verification strategies:

  • Think this through.
  • Write a proof.
  • Formally verify proof.
  • Automate proof construction.
  • Test many random inputs.
  • A bit painful: test all inputs.
  • Faster: test int16 version.

void minmax(int32 { int32 int32 int32 int32 c ^= ab c >>= c &= ab; *x = a *y = b } void sort2(int32 { minmax(x,x

slide-137
SLIDE 137

26

issmaller(int32 x,int32 y) isnegative(x - y); }

rrect!

  • f ispositive.

inputs (0; −231). more inputs. by random tests:

10000000;++j) { y += random(); issmaller(x,y);

  • (x < y));

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

Some verification strategies:

  • Think this through.
  • Write a proof.
  • Formally verify proof.
  • Automate proof construction.
  • Test many random inputs.
  • A bit painful: test all inputs.
  • Faster: test int16 version.

void minmax(int32 { int32 a = *x; int32 b = *y; int32 ab = b ^ int32 c = b - a; c ^= ab & (c ^ c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 { minmax(x,x + 1);

slide-138
SLIDE 138

26

x,int32 y) y); }

ispositive. ). inputs. tests:

10000000;++j) { random();

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

Some verification strategies:

  • Think this through.
  • Write a proof.
  • Formally verify proof.
  • Automate proof construction.
  • Test many random inputs.
  • A bit painful: test all inputs.
  • Faster: test int16 version.

void minmax(int32 *x,int32 { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); }

slide-139
SLIDE 139

27

int32 issmaller(int32 x,int32 y) { int32 xy = x ^ y; int32 c = x - y; c ^= xy & (c ^ x); return isnegative(c); }

Some verification strategies:

  • Think this through.
  • Write a proof.
  • Formally verify proof.
  • Automate proof construction.
  • Test many random inputs.
  • A bit painful: test all inputs.
  • Faster: test int16 version.

28

void minmax(int32 *x,int32 *y) { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); }

slide-140
SLIDE 140

27

issmaller(int32 x,int32 y) xy = x ^ y; c = x - y; xy & (c ^ x); return isnegative(c);

verification strategies: Think this through. rite a proof. ally verify proof. Automate proof construction. many random inputs. bit painful: test all inputs. aster: test int16 version.

28

void minmax(int32 *x,int32 *y) { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); } int32 ispositive(int32 { int32 c ^= x return } void sort(int32 { long long for (j for minmax(x }

Safe compiler if array length

slide-141
SLIDE 141

27

issmaller(int32 x,int32 y) y; y; x); isnegative(c);

verification strategies: rough. proof.

  • f construction.

random inputs. test all inputs. int16 version.

28

void minmax(int32 *x,int32 *y) { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); } int32 ispositive(int32 { int32 c = -x; c ^= x & c; return isnegative(c); } void sort(int32 *x,long { long long i,j; for (j = 0;j < for (i = j - minmax(x + }

Safe compiler will if array length n is

slide-142
SLIDE 142

27

x,int32 y)

strategies: construction. puts. inputs. version.

28

void minmax(int32 *x,int32 *y) { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); } int32 ispositive(int32 x) { int32 c = -x; c ^= x & c; return isnegative(c); } void sort(int32 *x,long long { long long i,j; for (j = 0;j < n;++j) for (i = j - 1;i >= 0;--i) minmax(x + i,x + i }

Safe compiler will allow this if array length n is not secret

slide-143
SLIDE 143

28

void minmax(int32 *x,int32 *y) { int32 a = *x; int32 b = *y; int32 ab = b ^ a; int32 c = b - a; c ^= ab & (c ^ b); c >>= 31; c &= ab; *x = a ^ c; *y = b ^ c; } void sort2(int32 *x) { minmax(x,x + 1); }

29

int32 ispositive(int32 x) { int32 c = -x; c ^= x & c; return isnegative(c); } void sort(int32 *x,long long n) { long long i,j; for (j = 0;j < n;++j) for (i = j - 1;i >= 0;--i) minmax(x + i,x + i + 1); }

Safe compiler will allow this if array length n is not secret.