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

β–Ά
dragonblood analyzing the dragonfly
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1

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

Mathy Vanhoef and Eyal Ronen

  • ANRW. Montreal, Canada, 22 July 2019.
slide-2
SLIDE 2

Background: Dragonfly in WPA3

2

Negotiate session key Provide mutual authentication

Forward secrecy & prevent offline dictionary attacks Protect against server compromise

= Password Authenticated Key Exchange (PAKE)

slide-3
SLIDE 3

Dragonfly

3

Convert password to elliptic curve point P Convert password to elliptic curve point P

Commit phase Confirm phase

slide-4
SLIDE 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

slide-5
SLIDE 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

5

In practice always true

slide-6
SLIDE 6

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

6

In practice always true Problem: value >= p

slide-7
SLIDE 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

slide-8
SLIDE 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

slide-9
SLIDE 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

9

No timing leak countermeasures despite warnings by IETF & CFRG!

slide-10
SLIDE 10

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

10

No timing leak countermeasures despite warnings by IETF & CFRG! WPA3: spoof client address to obtain different executions

slide-11
SLIDE 11

Raspberry Pi 1 B+: differences are measurable

11

slide-12
SLIDE 12

Raspberry Pi 1 B+: differences are measurable

12

Hostap (WPA3): ~75 measurements / address iwd (EAP-pwd): ~30 measurements / address

slide-13
SLIDE 13

Leaked information: #iterations needed

13

Client address addrA Measured

slide-14
SLIDE 14

Leaked information: #iterations needed

14

Client address addrA Measured Password 1 Password 2 Password 3

slide-15
SLIDE 15

Leaked information: #iterations needed

15

Client address addrA Measured Password 1 Password 2 Password 3

slide-16
SLIDE 16

Leaked information: #iterations needed

16

Client address addrA addrB Measured Password 1 Password 2 Password 3

slide-17
SLIDE 17

Leaked information: #iterations needed

17

Client address addrA addrB Measured Password 1 Password 2 Password 3

slide-18
SLIDE 18

Leaked information: #iterations needed

18

Client address addrA addrB addrC Measured Password 1 Password 2 Password 3

slide-19
SLIDE 19

Leaked information: #iterations needed

19

Client address addrA addrB addrC Measured Password 1 Password 2 Password 3

forms a signature of the password Need ~17 addresses to test ~107 passwords

slide-20
SLIDE 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

20

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

slide-21
SLIDE 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

slide-22
SLIDE 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 if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y)

22

Problem: no solution for y

slide-23
SLIDE 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

slide-24
SLIDE 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

slide-25
SLIDE 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 if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y)

25

Problem: different passwords have different execution time

slide-26
SLIDE 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() y = sqrt(x^3 + a * x + b) return (x, y)

26

οƒ  Always execute at least k iterations

slide-27
SLIDE 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 pw = random() y = sqrt(x^3 + a * x + b) return (x, y)

27

In case quadratic test is not constant time

slide-28
SLIDE 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 if is_quadratic_residue(y_sqr) and not x: x = value pw = random() y = sqrt(x^3 + a * x + b) return (x, y)

28

Problem: value >= p

slide-29
SLIDE 29

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)

29

May be true for Brainpool curves!

slide-30
SLIDE 30

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)

30

May be true for Brainpool curves!

Quadratic test may be skipped

slide-31
SLIDE 31

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)

31

May be true for Brainpool curves!

Quadratic test may be skipped A random #(extra iterations) have a too big hash output

slide-32
SLIDE 32

Influence of extra iterations

32

Execution 1

slide-33
SLIDE 33

Influence of extra iterations

33

Execution 1 Execution 2 Execution 3 Execution 4

slide-34
SLIDE 34

Influence of extra iterations

34

Execution 1 Execution 2 Execution 3 Execution 4

slide-35
SLIDE 35

Influence of extra iterations

35

Execution 1 Execution 2 Execution 3 Execution 4

Variance ~ when password element was found

slide-36
SLIDE 36

Influence of extra iterations

36

Execution 1 Execution 2 Execution 3 Execution 4

Variance ~ when password element was found Average ~ when found and #iterations with big hash

slide-37
SLIDE 37

Influence of extra iterations

37

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

slide-38
SLIDE 38

Raspberry Pi 1 B+

38

slide-39
SLIDE 39

Raspberry Pi 1 B+

39

Hostap (WPA3): ~300 measurements / address

slide-40
SLIDE 40

40

Cache Attacks

slide-41
SLIDE 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() y = sqrt(x^3 + a * x + b) return (x, y)

41

NIST curves: use Flush+Reload to detect if code is executed in 1st iteration

slide-42
SLIDE 42

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() y = sqrt(x^3 + a * x + b) return (x, y)

42

NIST curves: use Flush+Reload to detect if code is executed in 1st iteration Use as clock to detect in which iteration we are

slide-43
SLIDE 43

Hash-to-curve: Brainpool big hash

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)

43

Brainpool: use Flush+Reload to detect if code is executed in 1st iteration Use as clock to detect in which iteration we are

slide-44
SLIDE 44

There’s a lot more!

Implementation-specific vulnerabilities β€Ί Invalid curve attacks, reflection attacks, bad randomness Wi-Fi specific attacks β€Ί Downgrades to WPA2 & denial-of-service Practical impact β€Ί Brute-force attacks on GPUs: $1 for RockYou database β€Ί 802.11 being updated to use Shallue-Woestijne-Ulas

44

slide-45
SLIDE 45

Thank you! Questions?

Lessons learned: β€Ί Must be constant-time and efficient β€Ί Allow offline computation of P β€Ί Discuss impact of bad randomness β€Ί Limit number of parameters (e.g. curves) β€Ί Dragonfly is hard to implement securely https://wpa3.mathyvanhoef.com

45