dragonblood analyzing the dragonfly
play

Dragonblood: Analyzing the Dragonfly Handshake of WPA3 and EAP-pwd - PowerPoint PPT Presentation

Dragonblood: Analyzing the Dragonfly Handshake of WPA3 and EAP-pwd Mathy Vanhoef and Eyal Ronen ANRW. Montreal, Canada, 22 July 2019. Background: Dragonfly in WPA3 = Password Authenticated Key Exchange (PAKE) Negotiate Provide mutual session


  1. Dragonblood: Analyzing the Dragonfly Handshake of WPA3 and EAP-pwd Mathy Vanhoef and Eyal Ronen ANRW. Montreal, Canada, 22 July 2019.

  2. Background: Dragonfly in WPA3 = Password Authenticated Key Exchange (PAKE) Negotiate Provide mutual session key authentication Forward secrecy Protect against & prevent offline server compromise dictionary attacks 2

  3. Dragonfly Convert password to Convert password to elliptic curve point P elliptic curve point P Commit phase Confirm phase 3

  4. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P 4

  5. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P In practice always true 5

  6. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue Problem: value >= p P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P In practice always true 6

  7. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P 7

  8. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P 8

  9. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 if P > 1: return P No timing leak countermeasures despite warnings by IETF & CFRG! 9

  10. With MODP groups: hash-to-group for (counter = 1; counter < 256; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue WPA3: spoof client address P = 𝑤𝑏𝑚𝑣𝑓 (𝑞−1)/𝑟 to obtain different executions if P > 1: return P No timing leak countermeasures despite warnings by IETF & CFRG! 10

  11. Raspberry Pi 1 B+: differences are measurable 11

  12. Raspberry Pi 1 B+: differences are measurable Hostap (WPA3): ~75 measurements / address iwd (EAP-pwd): ~30 measurements / address 12

  13. Leaked information: #iterations needed Client address addrA Measured 13

  14. Leaked information: #iterations needed Client address addrA Measured Password 1 Password 2 Password 3 14

  15. Leaked information: #iterations needed Client address addrA Measured Password 1 Password 2 Password 3 15

  16. Leaked information: #iterations needed Client address addrA addrB Measured Password 1 Password 2 Password 3 16

  17. Leaked information: #iterations needed Client address addrA addrB Measured Password 1 Password 2 Password 3 17

  18. Leaked information: #iterations needed Client address addrA addrB addrC Measured Password 1 Password 2 Password 3 18

  19. Leaked information: #iterations needed Client address addrA addrB addrC Measured forms a signature of the password Password 1 Password 2 Need ~17 addresses to test ~ 10 7 passwords Password 3 19

  20. What about elliptic curves? Hash-to-group with elliptic curves also affected? › By default Dragonfly uses NIST curves › Timing leaks for NIST curves are mitigated Dragonfly also supports Brainpool curves › After our initial disclosure, the Wi-Fi Alliace private created guidelines that mention these are secure to use › Bad news: Brainpool curves in Dragonfly are insecure 20

  21. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 21

  22. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b Problem: no solution for y if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 22

  23. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 23

  24. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 24

  25. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b Problem: different passwords if is_quadratic_residue(y_sqr) and not x: have different execution time x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 25

  26. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x : x = value pw = random()  Always execute at y = sqrt(x^3 + a * x + b) least k iterations return (x, y) 26

  27. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x : x = value In case quadratic test pw = random() is not constant time y = sqrt(x^3 + a * x + b) return (x, y) 27

  28. Hash-to-curve for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b Problem: value >= p if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 28

  29. Hash-to-curve May be true for for (counter = 1; counter < k or not x; counter++) Brainpool curves! value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 29

  30. Hash-to-curve May be true for for (counter = 1; counter < k or not x; counter++) Brainpool curves! value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value Quadratic test may be skipped pw = random() y = sqrt(x^3 + a * x + b) return (x, y) 30

  31. Hash-to-curve May be true for for (counter = 1; counter < k or not x; counter++) Brainpool curves! value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value Quadratic test may be skipped pw = random() y = sqrt(x^3 + a * x + b) A random #(extra iterations) return (x, y) have a too big hash output 31

  32. Influence of extra iterations Execution 1 32

  33. Influence of extra iterations Execution 1 Execution 2 Execution 3 Execution 4 33

  34. Influence of extra iterations Execution 1 Execution 2 Execution 3 Execution 4 34

  35. Influence of extra iterations Execution 1 Execution 2 Execution 3 Execution 4 Variance ~ when password element was found 35

  36. Influence of extra iterations Execution 1 Execution 2 Execution 3 Execution 4 Variance ~ when password element was found Average ~ when found and #iterations with big hash 36

  37. Influence of extra iterations Execution 1 Execution 2 Execution 3 Execution 4 Variance ~ when password element was found Average ~ when found and #iterations with big hash  Again forms a signature of the password 37

  38. Raspberry Pi 1 B+ 38

  39. Raspberry Pi 1 B+ Hostap (WPA3): ~300 measurements / address 39

  40. Cache Attacks 40

  41. Hash-to-curve: Quadratic Residue for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() NIST curves: use Flush+Reload to y = sqrt(x^3 + a * x + b) detect if code is executed in 1 st iteration return (x, y) 41

  42. Hash-to-curve: Quadratic Residue Use as clock to detect in which iteration we are for (counter = 1; counter < k or not x; counter++) value = hash(pw, counter, addr1, addr2) if value >= p: continue y_sqr = value^3 + a * value + b if is_quadratic_residue(y_sqr) and not x: x = value pw = random() NIST curves: use Flush+Reload to y = sqrt(x^3 + a * x + b) detect if code is executed in 1 st iteration return (x, y) 42

Recommend


More recommend