constant time programming in fact
play

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


  1. Padding removal: 1st try int32_t remove_padding( int32_t remove_padding2( uint8_t* buf, uint8_t* buf, uint32_t buflen) { uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint8_t padlen = buf[buflen-1]; uint32_t i; uint32_t i; for (i = 0; i < padlen; i++) { for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) if (buf[buflen-i-1] != padlen) return -1; ok = 0; buf[buflen-i-1] = 0; buf[buflen-i-1] = 0; } } return padlen; return ok ? padlen : -1; } } 10μs 10μs 53 74 ... 4c 6f 6f 70 05 05 07 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  2. Padding removal: 1st try int32_t remove_padding( int32_t remove_padding2( uint8_t* buf, uint8_t* buf, uint32_t buflen) { uint32_t buflen) { uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint8_t padlen = buf[buflen-1]; uint32_t i; uint32_t i; for (i = 0; i < padlen; i++) { for (i = 0; i < padlen; i++) { if (buf[buflen-i-1] != padlen) if (buf[buflen-i-1] != padlen) return -1; ok = 0; buf[buflen-i-1] = 0; buf[buflen-i-1] = 0; } } return padlen; return ok ? padlen : -1; } } 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 00 00 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  3. Padding removal: 2nd try 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) ok = 0; buf[buflen-i-1] = 0; } return ok ? padlen : -1; } 53 74 ... 4c 6f 6f 70 05 05 05 05 05 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  4. Padding removal: 2nd try 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) ok = 0; buf[buflen-i-1] = 0; } return ok ? padlen : -1; } 53 74 ... 4c 6f 6f 70 05 05 05 05 05 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  5. Padding removal: 2nd try 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) ok = 0; buf[buflen-i-1] = 0; } return ok ? padlen : -1; } 53 74 ... 4c 6f 6f 70 31 38 03 03 03 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  6. Padding removal: 2nd try 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) ok = 0; buf[buflen-i-1] = 0; } return ok ? padlen : -1; } 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  7. Padding removal: 2nd try int32_t remove_padding2( uint8_t* buf, It’s dangerous to uint32_t buflen) { bound loops with secrets! 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) ok = 0; buf[buflen-i-1] = 0; Use this instead. } return ok ? padlen : -1; } 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  8. Padding removal: 2nd try int32_t remove_padding3( uint8_t* buf, int32_t remove_padding2( uint32_t buflen) { uint8_t* buf, uint8_t ok = 1; uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint8_t ok = 1; uint32_t i; for ( i = buflen-255; i < buflen; i++) { uint8_t padlen = buf[buflen-1]; uint8_t b = buf[i]; uint32_t i; if (i >= buflen - padlen) { for (i = 0; i < padlen; i++) { if (b != padlen) if (buf[buflen-i-1] != padlen) ok = 0; ok = 0; b = 0; buf[buflen-i-1] = 0; } } buf[i] = b; return ok ? padlen : -1; } } return ok ? padlen : -1; } 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  9. Padding removal: 2nd try int32_t remove_padding3( uint8_t* buf, int32_t remove_padding2( uint32_t buflen) { uint8_t* buf, uint8_t ok = 1; uint32_t buflen) { uint8_t padlen = buf[buflen-1]; uint8_t ok = 1; uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t padlen = buf[buflen-1]; uint8_t b = buf[i]; uint32_t i; if (i >= buflen - padlen) { for (i = 0; i < padlen; i++) { if (b != padlen) if (buf[buflen-i-1] != padlen) ok = 0; ok = 0; b = 0; buf[buflen-i-1] = 0; } } buf[i] = b; return ok ? padlen : -1; } } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  10. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  11. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  12. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  13. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  14. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 10μs 10μs 10μs 10μs 10μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  15. Padding removal: 3rd try 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) ok = 0; b = 0; } buf[i] = b; } return ok ? padlen : -1; } 9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  16. Padding removal: 3rd try int32_t remove_padding3( uint8_t* buf, uint32_t buflen) { It’s dangerous to uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; have branching code! uint32_t i; for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; if (i >= buflen - padlen) { if (b != padlen) ok = 0; b = 0; } Use this instead. buf[i] = b; } return ok ? padlen : -1; } 9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  17. Padding removal: 3rd try int32_t remove_padding4( int32_t remove_padding3( uint8_t* buf, uint8_t* buf, uint32_t buflen) { uint32_t buflen) { uint32_t ok = -1; uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint8_t padlen = buf[buflen-1]; uint32_t i; uint32_t i; for (i = buflen-255; i < buflen; i++) { for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint8_t b = buf[i]; uint32_t improper_index = if (i >= buflen - padlen) { -(i - (buflen - padlen) >> 31); if (b != padlen) uint32_t matches_pad = -((b ^ padlen) - 1 >> 31); ok = 0; ok &= matches_pad | improper_index; b = 0; b = improper_index & b; } buf[i] = b; buf[i] = b; } } return (ok & padlen) | ~ok; return ok ? padlen : -1; } } 9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  18. Padding removal: 3rd try int32_t remove_padding4( int32_t remove_padding3( uint8_t* buf, uint8_t* buf, uint32_t buflen) { uint32_t buflen) { uint32_t ok = -1; uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint8_t padlen = buf[buflen-1]; uint32_t i; Ugly! Do not read! uint32_t i; for (i = buflen-255; i < buflen; i++) { for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint8_t b = buf[i]; uint32_t improper_index = if (i >= buflen - padlen) { -(i - (buflen - padlen) >> 31); if (b != padlen) uint32_t matches_pad = -((b ^ padlen) - 1 >> 31); ok = 0; ok &= matches_pad | improper_index; b = 0; b = improper_index & b; } buf[i] = b; buf[i] = b; } } return (ok & padlen) | ~ok; return ok ? padlen : -1; } } 9μs 9μs 9μs 9μs 9μs 10μs 10μs 10μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  19. Padding removal: 3rd try int32_t remove_padding4( int32_t remove_padding3( uint8_t* buf, uint8_t* buf, uint32_t buflen) { uint32_t buflen) { uint32_t ok = -1; uint8_t ok = 1; uint8_t padlen = buf[buflen-1]; uint8_t padlen = buf[buflen-1]; uint32_t i; Ugly! Do not read! uint32_t i; for (i = buflen-255; i < buflen; i++) { for (i = buflen-255; i < buflen; i++) { uint8_t b = buf[i]; uint8_t b = buf[i]; uint32_t improper_index = if (i >= buflen - padlen) { -(i - (buflen - padlen) >> 31); if (b != padlen) uint32_t matches_pad = -((b ^ padlen) - 1 >> 31); ok = 0; ok &= matches_pad | improper_index; b = 0; b = improper_index & b; } buf[i] = b; buf[i] = b; } } return (ok & padlen) | ~ok; return ok ? padlen : -1; } } 12μs 12μs 12μs 12μs 12μs 12μs 12μs 12μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  20. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  21. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  22. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  23. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); random_sleep(); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  24. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); random_sleep(); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  25. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); sleep_til_max(); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  26. Padding removal: 4th try int32_t remove_padding4( uint8_t* buf, uint32_t buflen) { uint32_t ok = -1; ! d a uint8_t padlen = buf[buflen-1]; e r t o n o uint32_t i; D ! y l g U 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); sleep_til_max(); ok &= 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 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  27. 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 ○ Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  28. 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 ○ Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  29. Error-prone in practice OpenSSL padding oracle attack Canvel, et al. “Password Interception in a SSL/TLS Channel.” Crypto, Vol. 2729. 2003. Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  30. Error-prone in practice Lucky 13 timing attack Al Fardan and Paterson. “Lucky thirteen: Breaking the TLS and DTLS record protocols.” Oakland 2013. Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  31. Error-prone in practice Further refinements Decryption path has no more measurable timing differences Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  32. Error-prone in practice Further refinements Decryption path has no more measurable timing differences Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  33. Error-prone in practice CVE-2016-2107 Somorovsky. “Curious padding oracle in OpenSSL.” Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  34. 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 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  35. FaCT .c cc -c ld Final binary .o .h Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  36. FaCT .fact .c cc -c ld Final binary .o .h Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  37. FaCT FaCT .fact .c cc -c ld Final binary .o .h Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  38. FaCT FaCT .fact .h .o .c cc -c ld Final binary .o .h Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  39. FaCT FaCT .fact .h .o .c .c cc -c ld Final binary .o .h .h Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  40. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  41. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  42. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  43. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  44. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  45. What does FaCT look like? 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); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  46. What does FaCT look like? 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) { uint8_t b = buf[i]; if (buf[i] != padlen) { uint32_t improper_index = return -1; -(i - (buflen - padlen) >> 31); } uint32_t matches_pad = buf[i] = 0; -((b ^ padlen) - 1 >> 31); } ok &= matches_pad | improper_index; } b = improper_index & b; return int32(padlen); buf[i] = b; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  47. What does FaCT look like? 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) { uint8_t b = buf[i]; if (buf[i] != padlen) { uint32_t improper_index = return -1; -(i - (buflen - padlen) >> 31); } uint32_t matches_pad = buf[i] = 0; -((b ^ padlen) - 1 >> 31); } ok &= matches_pad | improper_index; } b = improper_index & b; return int32(padlen); buf[i] = b; } 11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  48. What does FaCT look like? 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); } 11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  49. What does FaCT look like? 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); } 11μs 11μs 11μs 11μs 11μs 11μs 11μs 11μs 53 74 ... 4c 6f 6f 70 31 38 00 00 00 Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  50. 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: Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  51. 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(); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  52. 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 public_value ) { if (i < secret_value ) { do_operation(); } } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  53. 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 ○ Array indices ○ Cache lines x = sensitive_buffer[ secret_value ]; Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  54. 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 ○ Array indices ○ Cache lines for (uint32 i from public_lo to public_hi ) { if (i == secret_value ) { x = sensitive_buffer[ i ]; } } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  55. 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 ○ Array indices ○ Variable-time instructions ○ x = public_value / secret_value2 ; Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  56. 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 ○ Array indices ○ Variable-time instructions ○ x = public_value / public_value2 ; OR x = ct_div( public_value, secret_value2 ) ; Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  57. 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 ○ Array indices ○ Variable-time instructions ○ Recursive calls ○ secret uint32 fact(secret uint32 n) { if (n > 1) { return n * fact(n - 1); } return 1; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  58. 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 ○ Array indices ○ Variable-time instructions ○ Recursive calls ○ secret uint32 fact(secret uint32 n) { if (n > 1) { return n * fact(n - 1); } return 1; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  59. Automatically transform code Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  60. Automatically transform code FaCT Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  61. Automatically transform code ● Transform secret branches ● Keep track of static control flow if (s) { if (s2) { x = 42; } else { x = 17; } y = x + 2; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  62. Automatically transform code ● Transform secret branches ● Keep track of static control flow if (s) { if (s2) { x = 42; x = ct_select(s & s2, 42, x); } else { x = ct_select(s & ~s2, 17, x); x = 17; y = ct_select(s, x + 2, y); } y = x + 2; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  63. Automatically transform code ● Transform away early returns ● Keep track of current return state if (s) { return 42; } return 17; Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  64. Automatically transform code ● Transform away early returns ● Keep track of current return state rval = ct_select(s & ~returned, 42, rval); if (s) { returned |= s; return 42; } rval = ct_select(~returned, 17, rval); return 17; returned |= true; ... return rval; Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  65. Automatically transform code ● 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; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  66. Automatically transform code ● 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); foo(ref x, s); } void foo(mut x) { void foo(mut x, bool state) { x = 42; x = ct_select(state, 42, x); } } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  67. Transformations are tricky if (i < secret_index) { buf[i] = 0; } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  68. Transformations are tricky if (i < secret_index) { m = (i < secret_index); buf[i] = 0; buf[i] = ct_select(m, 0, buf[i]); } Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  69. Transformations are tricky if (i < secret_index) { m = (i < secret_index); buf[i] = 0; 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 ○ Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

  70. Transformations are tricky if (i < secret_index) { m = (i < secret_index); buf[i] = 0; 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 ○ ● Solution: disallow these programs! FaCT Z3 .fact Constant-time programming with FaCT Strange Loop 2018 Sunjay Cauligi

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend