Constant-time programming in FaCT Sunjay Cauligi , UC San Diego - - PowerPoint PPT Presentation

constant time programming in fact
SMART_READER_LITE
LIVE PREVIEW

Constant-time programming in FaCT Sunjay Cauligi , UC San Diego - - PowerPoint PPT Presentation

Constant-time programming in FaCT Sunjay Cauligi , UC San Diego Fraser Brown, Ranjit Jhala, Brian Johannesmeyer, John Renner, Gary Soeller, Deian Stefan, Riad Wahby Timing side channels Crypto Constant-time programming with FaCT Strange Loop


slide-1
SLIDE 1

Constant-time programming in FaCT

Sunjay Cauligi, UC San Diego

Fraser Brown, Ranjit Jhala, Brian Johannesmeyer, John Renner, Gary Soeller, Deian Stefan, Riad Wahby

slide-2
SLIDE 2

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

slide-3
SLIDE 3

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key

slide-4
SLIDE 4

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key Plaintext

slide-5
SLIDE 5

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key Encrypted Plaintext

slide-6
SLIDE 6

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key Encrypted Plaintext

slide-7
SLIDE 7

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key Encrypted Plaintext Timing differences

slide-8
SLIDE 8

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Timing side channels

Crypto

Secret key Encrypted Plaintext Timing differences Leaked via timing

slide-9
SLIDE 9

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Cryptographic padding

53 74 4c 6f 6f 70 ... message

slide-10
SLIDE 10

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Cryptographic padding

52 c7 be 95 59 88 dd 68 69 f9 21 ... encrypt 53 74 4c 6f 6f 70 ... message

slide-11
SLIDE 11

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Cryptographic padding

52 c7 be 95 59 88 dd 68 69 f9 21 ... encrypt decrypt 53 74 4c 6f 6f 70 ... message 53 74 4c 6f 6f 70 05 05 05 05 05 ... padding

slide-12
SLIDE 12

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Constant-time coding example

53 74 4c 6f 6f 70 05 05 05 05 05 ... 5 bytes of padding

  • Check for valid padding

○ PKCS #7 padding ○ Each padding byte holds length of padding

slide-13
SLIDE 13

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

00 00 00 00 00

Constant-time coding example

5 bytes of padding

  • Check for valid padding

○ PKCS #7 padding ○ Each padding byte holds length of padding

  • Replace padding with null bytes
  • Return padding length, or error

53 74 4c 6f 6f 70 ...

slide-14
SLIDE 14

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Constant-time coding example

5 bytes of padding

  • Check for valid padding

○ PKCS #7 padding ○ Each padding byte holds length of padding

  • Replace padding with null bytes
  • Return padding length, or error
  • Must be careful: buffer contents are secret

○ That includes padding!

00 00 00 00 00 53 74 4c 6f 6f 70 ...

slide-15
SLIDE 15

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 05 05 05

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-16
SLIDE 16

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 05 05 05

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-17
SLIDE 17

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 05 05 05

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-18
SLIDE 18

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

05 05 05 05 05

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-19
SLIDE 19

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 05 05 00

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-20
SLIDE 20

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

05 05 05 00 00

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-21
SLIDE 21

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

05 05 00 00 00

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-22
SLIDE 22

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

05 00 00 00 00

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-23
SLIDE 23

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

00 00 00 00 00

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-24
SLIDE 24

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

00 00 00 00 00

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-25
SLIDE 25

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

00 00 00 00 00

10μs 10μs 10μs 10μs 10μs

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-26
SLIDE 26

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 05 05

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-27
SLIDE 27

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 00 00

10μs 10μs

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-28
SLIDE 28

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 00 00

10μs 10μs

Padding oracle!

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-29
SLIDE 29

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 00 00

10μs 10μs

Padding oracle!

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-30
SLIDE 30

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 00 00

10μs 10μs

It’s dangerous to return early! Use this instead.

Padding oracle!

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-31
SLIDE 31

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; } int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

05 05 07 00 00

10μs 10μs

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-32
SLIDE 32

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; } int32_t remove_padding( uint8_t* buf, uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) return -1; buf[buflen-i-1] = 0; } return padlen; }

00 00 00 00 00

10μs 10μs 10μs 10μs 10μs

Padding removal: 1st try

53 74 4c 6f 6f 70 ...

slide-33
SLIDE 33

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

05 05 05 05 05

Padding removal: 2nd try

53 74 4c 6f 6f 70 ...

slide-34
SLIDE 34

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

05 05 05 05 05

Padding removal: 2nd try

53 74 4c 6f 6f 70 ...

slide-35
SLIDE 35

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

31 03 03 03

Padding removal: 2nd try

53 74 4c 6f 6f 70 ... 38

slide-36
SLIDE 36

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

31 00 00 00

10μs 10μs 10μs

Padding removal: 2nd try

53 74 4c 6f 6f 70 ... 38

slide-37
SLIDE 37

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

31 00 00 00

10μs 10μs 10μs

It’s dangerous to bound loops with secrets! Use this instead.

Padding removal: 2nd try

53 74 4c 6f 6f 70 ... 38

slide-38
SLIDE 38

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

10μs 10μs 10μs

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

Padding removal: 2nd try

53 74 4c 6f 6f 70 ... 38

slide-39
SLIDE 39

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

31 00 00 00

10μs 10μs 10μs

int32_t remove_padding2( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen)

  • k = 0;

buf[buflen-i-1] = 0; } return ok ? padlen : -1; }

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; }

10μs 10μs 10μs 10μs 10μs

Padding removal: 2nd try

53 74 4c 6f 6f 70 ... 38

slide-40
SLIDE 40

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-41
SLIDE 41

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-42
SLIDE 42

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

31 00 00 00

10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; }

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-43
SLIDE 43

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

31 00 00 00

10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; }

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-44
SLIDE 44

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

31 00 00 00

10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; }

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-45
SLIDE 45

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

31 00 00 00

10μs 10μs 10μs

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; }

9μs 9μs 9μs 9μs 9μs

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-46
SLIDE 46

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs

It’s dangerous to have branching code! Use this instead.

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-47
SLIDE 47

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index =

  • (i - (buflen - padlen) >> 31);

uint32_t matches_pad =

  • ((b ^ padlen) - 1 >> 31);
  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; }

9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-48
SLIDE 48

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index =

  • (i - (buflen - padlen) >> 31);

uint32_t matches_pad =

  • ((b ^ padlen) - 1 >> 31);
  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; }

9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs

Ugly! Do not read!

Padding removal: 3rd try

53 74 4c 6f 6f 70 ... 38

slide-49
SLIDE 49

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen)

  • k = 0;

b = 0; } buf[i] = b; } return ok ? padlen : -1; } 31 00 00 00

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index =

  • (i - (buflen - padlen) >> 31);

uint32_t matches_pad =

  • ((b ^ padlen) - 1 >> 31);
  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; }

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 3rd try

Ugly! Do not read!

53 74 4c 6f 6f 70 ... 38

slide-50
SLIDE 50

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

53 74 4c 6f 6f 70 ... 38

slide-51
SLIDE 51

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

???

53 74 4c 6f 6f 70 ... 38

slide-52
SLIDE 52

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

53 74 4c 6f 6f 70 ... 38

slide-53
SLIDE 53

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

random_sleep();

53 74 4c 6f 6f 70 ... 38

slide-54
SLIDE 54

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

random_sleep();

53 74 4c 6f 6f 70 ... 38

slide-55
SLIDE 55

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

sleep_til_max();

53 74 4c 6f 6f 70 ... 38

slide-56
SLIDE 56

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; uint8_t padlen = buf[buflen-1]; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint32_t improper_index = -(i - (buflen - padlen) >> 31); uint32_t matches_pad = -((b ^ padlen) - 1 >> 31);

  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; } return (ok & padlen) | ~ok; } 31 00 00 00

12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs

Padding removal: 4th try

U g l y ! D

  • n
  • t

r e a d !

sleep_til_max();

53 74 4c 6f 6f 70 ... 38

slide-57
SLIDE 57

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Writing constant-time code is hard

  • Challenge: manually ensuring code is CT

○ Manually keep track of secret vs. public ○ Standard programming constructs introduce timing leaks ○ Can’t simply pad/randomize

slide-58
SLIDE 58

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Writing constant-time code is hard

  • Challenge: manually ensuring code is CT

○ Manually keep track of secret vs. public ○ Standard programming constructs introduce timing leaks ○ Can’t simply pad/randomize

  • Consequence: vulnerabilities!

○ Difficult to write correct code ○ Hard to understand what CT code is doing ○ Hard to maintain CT code

slide-59
SLIDE 59

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Error-prone in practice

OpenSSL padding oracle attack

Canvel, et al. “Password Interception in a SSL/TLS Channel.” Crypto, Vol. 2729. 2003.

slide-60
SLIDE 60

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Error-prone in practice

Lucky 13 timing attack

Al Fardan and Paterson. “Lucky thirteen: Breaking the TLS and DTLS record protocols.” Oakland 2013.

slide-61
SLIDE 61

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Error-prone in practice

Further refinements

Decryption path has no more measurable timing differences

slide-62
SLIDE 62

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Error-prone in practice

Further refinements

Decryption path has no more measurable timing differences

slide-63
SLIDE 63

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Error-prone in practice

CVE-2016-2107

  • Somorovsky. “Curious padding
  • racle in OpenSSL.”
slide-64
SLIDE 64

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

This is what DSLs are for!

  • Explicitly distinguish secret vs. public values
  • Type system to prevent writing leaky code
  • Compiler to transform high-level constructs to CT
slide-65
SLIDE 65

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT

.c .h .o cc -c ld Final binary

slide-66
SLIDE 66

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

.fact

FaCT

.c .h .o cc -c ld Final binary

slide-67
SLIDE 67

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

.fact FaCT

FaCT

.c .h .o cc -c ld Final binary

slide-68
SLIDE 68

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

.fact .h .o FaCT

FaCT

.c .h .o cc -c ld Final binary

slide-69
SLIDE 69

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

.fact .c .h .o .h FaCT

FaCT

.c .h .o cc -c ld Final binary

slide-70
SLIDE 70

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-71
SLIDE 71

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-72
SLIDE 72

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-73
SLIDE 73

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-74
SLIDE 74

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-75
SLIDE 75

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

slide-76
SLIDE 76

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

uint8_t b = buf[i]; uint32_t improper_index =

  • (i - (buflen - padlen) >> 31);

uint32_t matches_pad =

  • ((b ^ padlen) - 1 >> 31);
  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b;

slide-77
SLIDE 77

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

uint8_t b = buf[i]; uint32_t improper_index =

  • (i - (buflen - padlen) >> 31);

uint32_t matches_pad =

  • ((b ^ padlen) - 1 >> 31);
  • k &= matches_pad | improper_index;

b = improper_index & b; buf[i] = b; secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

31 00 00 00

11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs

53 74 4c 6f 6f 70 ... 38

slide-78
SLIDE 78

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

31 00 00 00

11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs

53 74 4c 6f 6f 70 ... 38

slide-79
SLIDE 79

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

secret int32 remove_padding(secret mut uint8[] buf) { assume(len buf >= 255); secret uint8 padlen = buf[len buf - 1]; for (uint64 i from len buf - 255 to len buf) { if (i >= len buf - padlen) { if (buf[i] != padlen) { return -1; } buf[i] = 0; } } return int32(padlen); }

What does FaCT look like?

31 38 00 00 00

11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs

53 74 4c 6f 6f 70 ...

slide-80
SLIDE 80

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Labels ensure no leakage

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:
slide-81
SLIDE 81

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Labels ensure no leakage

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds

for (uint32 i from 0 to secret_value) { do_operation(); }

slide-82
SLIDE 82

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds

for (uint32 i from 0 to public_value) { if (i < secret_value) { do_operation(); } }

Labels ensure no leakage

slide-83
SLIDE 83

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices

x = sensitive_buffer[secret_value];

Labels ensure no leakage

Cache lines

slide-84
SLIDE 84

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices

for (uint32 i from public_lo to public_hi) { if (i == secret_value) { x = sensitive_buffer[i]; } }

Labels ensure no leakage

Cache lines

slide-85
SLIDE 85

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices ○ Variable-time instructions

Labels ensure no leakage

x = public_value / secret_value2;

slide-86
SLIDE 86

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices ○ Variable-time instructions

Labels ensure no leakage

x = public_value / public_value2; x = ct_div(public_value, secret_value2); OR

slide-87
SLIDE 87

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices ○ Variable-time instructions ○ Recursive calls

Labels ensure no leakage

secret uint32 fact(secret uint32 n) { if (n > 1) { return n * fact(n - 1); } return 1; }

slide-88
SLIDE 88

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • No assignment from secret to public
  • Type system tracks control flow label

○ Only transform secret control flow

  • Prevent secret expressions that leak:

○ Loop bounds ○ Array indices ○ Variable-time instructions ○ Recursive calls

Labels ensure no leakage

secret uint32 fact(secret uint32 n) { if (n > 1) { return n * fact(n - 1); } return 1; }

slide-89
SLIDE 89

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Automatically transform code

slide-90
SLIDE 90

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT

Automatically transform code

slide-91
SLIDE 91

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Transform secret branches
  • Keep track of static control flow

if (s) { if (s2) { x = 42; } else { x = 17; } y = x + 2; }

Automatically transform code

slide-92
SLIDE 92

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Automatically transform code

  • Transform secret branches
  • Keep track of static control flow

if (s) { if (s2) { x = 42; } else { x = 17; } y = x + 2; } x = ct_select(s & s2, 42, x); x = ct_select(s & ~s2, 17, x); y = ct_select(s, x + 2, y);

slide-93
SLIDE 93

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Transform away early returns
  • Keep track of current return state

Automatically transform code

if (s) { return 42; } return 17;

slide-94
SLIDE 94

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Transform away early returns
  • Keep track of current return state

Automatically transform code

if (s) { return 42; } return 17; rval = ct_select(s & ~returned, 42, rval); returned |= s; rval = ct_select(~returned, 17, rval); returned |= true; return rval; ...

slide-95
SLIDE 95

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Transform function side effects

○ Depends on control flow state of caller

  • Pass the current control flow as an extra parameter

if (s) { foo(ref x); } void foo(mut x) { x = 42; }

Automatically transform code

slide-96
SLIDE 96

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Transform function side effects

○ Depends on control flow state of caller

  • Pass the current control flow as an extra parameter

foo(ref x, s); void foo(mut x, bool state) { x = ct_select(state, 42, x); } if (s) { foo(ref x); } void foo(mut x) { x = 42; }

Automatically transform code

slide-97
SLIDE 97

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Transformations are tricky

if (i < secret_index) { buf[i] = 0; }

slide-98
SLIDE 98

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Transformations are tricky

if (i < secret_index) { buf[i] = 0; } m = (i < secret_index); buf[i] = ct_select(m, 0, buf[i]);

slide-99
SLIDE 99

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Transformations are tricky

if (i < secret_index) { buf[i] = 0; } m = (i < secret_index); buf[i] = ct_select(m, 0, buf[i]);

  • Problem: secret if-statements always perform branches

○ Does not guard execution ○ Similar problem for secret early return

slide-100
SLIDE 100

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Transformations are tricky

  • Problem: secret if-statements always perform branches

○ Does not guard execution ○ Similar problem for secret early return

  • Solution: disallow these programs!

if (i < secret_index) { buf[i] = 0; } m = (i < secret_index); buf[i] = ct_select(m, 0, buf[i]); .fact FaCT Z3

slide-101
SLIDE 101

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Verifying constant-time code

  • FaCT is memory safe and has no undefined behavior

○ Generate constraints while type checking ○ Aware of secret-if semantics

.fact FaCT Z3

slide-102
SLIDE 102

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Verifying constant-time code

  • FaCT is memory safe and has no undefined behavior

○ Generate constraints while type checking ○ Aware of secret-if semantics

  • FaCT generates constant-time code

○ Verified with external tool

.fact FaCT Z3 ct-verif

slide-103
SLIDE 103

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Interoperate with external code

  • Generate function prototypes

/*public*/ uint8_t crypto_secretbox( /*secret*/ uint8_t c[], /*public*/ uint64_t c_len, const /*public*/ uint8_t n[24], const /*secret*/ uint8_t k[32]);

slide-104
SLIDE 104

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Interoperate with external code

  • Generate function prototypes
  • Call external functions from FaCT

extern void aesni_cbc_encrypt( secret mut uint8[] buf, public uint64 buf_len, AES_KEY key, public int32 enc);

slide-105
SLIDE 105

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Interoperate with external code

  • Generate function prototypes
  • Call external functions from FaCT
  • Pass complex data structures

struct EVP_AES_HMAC_SHA1 { AES_KEY ks; SHA_CTX md; public uint64 payload_length; secret uint8[16] tls_aad; }

slide-106
SLIDE 106

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Interoperate with external code

  • Generate function prototypes
  • Call external functions from FaCT
  • Pass complex data structures
  • Embed in other languages

import Language.FaCT.Inline [fact| secret uint32 choose( secret bool b, secret uint32 x, secret uint32 y) { return b ? x : y; } |]

slide-107
SLIDE 107

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT in practice

  • Must be fast
  • Must be usable
slide-108
SLIDE 108

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT in practice

  • Must be fast
  • Must be usable
  • Case studies:

○ libsodium ○ OpenSSL ○ mbedTLS ○ donna curve-25519

slide-109
SLIDE 109

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT in practice

  • Must be fast
  • Must be usable
  • Case studies:

○ libsodium ○ OpenSSL ○ mbedTLS ○ donna curve-25519

  • User study
slide-110
SLIDE 110

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Performance numbers

OpenSSL decryption throughput

(higher is better) Chunk size

slide-111
SLIDE 111

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Performance numbers

libsodium secretbox benchmarks

(lower is better) Encryption Decryption

slide-112
SLIDE 112

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

  • Conducted user study on undergrad PL class

○ Understanding constant-time code (C vs. FaCT) ○ Writing constant-time code (C + ct-verif vs. FaCT)

User study results

  • Results:

○ Students understood FaCT code better than C ○ More students successfully wrote FaCT code ○ Fewer security errors when writing FaCT ○ FaCT syntax tripped people up

slide-113
SLIDE 113

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

Future directions

  • Add useful language features
  • Add other backends (ARM, CT-WASM, ...)
  • Verify the FaCT compiler
slide-114
SLIDE 114

Constant-time programming with FaCT Sunjay Cauligi Strange Loop 2018

FaCT

  • DSL for cryptographic code
  • Automatic transformation to constant-time
  • Easily fits into your existing toolchain
  • Usable and fast

.fact .h .h .o .c .o cc -c ld FaCT Final binary https://github.com/PLSysSec/FaCT