When Good Turns Evil
Using Intel SGX to Stealthily Steal Bitcoins
Michael Schwarz@misc0110

Moritz Lipp
@mlqxyzOutline

1

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Outline

1

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Outline

SGX

1Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Outline

SGX

1Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Outline

SGX

1Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Outline

SGX

1Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Whoami• Michael Schwarz• PhD Student, Graz University of Technology

2•@misc0110•

michael.schwarz@iaik.tugraz.at

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Whoami• Moritz Lipp
• PhD Student, Graz University of Technology

3•@mlqxyz•moritz.lipp@iaik.tugraz.at

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

And the teamThe research team• Daniel Gruss• Clémentine Maurice• Samuel Weiser• Stefan Mangard
from Graz University of Technology

4Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part
Create Enclave

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Gate

Create Enclave
Trusted Fnc.

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

ReturnOperating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

ReturnOperating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

Return...

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX
Application
Untrusted part

Trusted part

Call Trusted Fnc.

Call Gate

Create Enclave
Trusted Fnc.

Return...

Operating System

5Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Wallets• Ledger SGX Enclave for blockchain applications• BitPay Copay Bitcoin wallet• Teechain payment channel using SGX

6

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Wallets• Ledger SGX Enclave for blockchain applications• BitPay Copay Bitcoin wallet• Teechain payment channel using SGX
Teechain[...] We assume the TEE guarantees to hold and do not consider
side-channel attacks [5, 35, 46] on the TEE. Such attacks and their
mitigations [36, 43] are outside the scope of this work. [...]

6

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

7

d

mod n

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result7=

C

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×square7

Result×C
multiply

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×

Resultsquare7Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×

Resultsquare7Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×square7

Result×C
multiply

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×square7

Result×C
multiply

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Signatures (RSA)

M=C

d

mod n

1 1 0 0 1 1 0 ...

Result=Result×

Resultsquare7Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

ECDSA• Used to sign transactions

8

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

ECDSA• Used to sign transactions• Point multiplication is similar to RSA exponentiation

8

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

ECDSA• Used to sign transactions• Point multiplication is similar to RSA exponentiation• Simplest implemention double-and-add or constant-time
Montgomery ladder

8

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

ECDSA• Used to sign transactions• Point multiplication is similar to RSA exponentiation• Simplest implemention double-and-add or constant-time
Montgomery ladder• Both algorithms have secret-dependent memory accesses

8

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...

9

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...

9Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...
• cached data (fast)

9

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...
• cached data (fast)• uncached data (slow)

9

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...
• cached data (fast)• uncached data (slow)• is used to attack secret-dependent memory accesses

9Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...
• cached data (fast)• uncached data (slow)• is used to attack secret-dependent memory accesses• is applied to a part of the CPU cache, a cache set

9Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe Cache Attack

Prime+Probe [OST06; Liu+15; Mau+17]...
• exploits the timing difference when accessing...
• cached data (fast)• uncached data (slow)• is used to attack secret-dependent memory accesses• is applied to a part of the CPU cache, a cache set• works across CPU cores as the last-level cache is shared

9

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress spaceloads data

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress spaceloads data

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Victimaddress spaceCacheloads data

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Victimaddress spaceCacheloads data

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data
Step 2: Attacker probes data to determine if the set was accessed

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache

Victimaddress space

ss

cce

ta

fas
Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data
Step 2: Attacker probes data to determine if the set was accessed

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Prime+Probe

Attackeraddress space

Cache
slo
w

Victimaddress space

acc

ess

Step 0: Attacker fills the cache (prime)
Step 1: Victim evicts cache lines by accessing own data
Step 2: Attacker probes data to determine if the set was accessed

10

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack

Attack Settings

Victim11

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

VictimSGX

11Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

VictimSGX

Transaction
Signature+ private key

Wallet API

11

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker

VictimSGX

Transaction
Signature+ private key

Wallet API

11

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker
SGX

VictimSGX

Transaction
Signature+ private key

Wallet API

11

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker
SGX

VictimSGXKey
Extractor

Transaction
Signature+ private key

Loader11

Wallet API

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker
SGX

VictimSGXKey
Extractor

Transaction
Signature+ private key

Loader11

Wallet API

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker
SGX

VictimSGXKey
Extractor

Transaction
Signature+ private key

11

LoaderWallet API

L1/L2 Cache

L1/L2 Cache

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Attack Settings

Attacker

Victim

SGX

SGX

Key
Extractor

Transaction
Signature(Prime+Probe)+ private key

LoaderWallet API

L1/L2 Cache

L1/L2 Cache

Shared LLC

11Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:
• No access to high-precision timer (rdtsc)

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:
• No access to high-precision timer (rdtsc)• No syscalls

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:
• No access to high-precision timer (rdtsc)• No syscalls• No shared memory

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:
• No access to high-precision timer (rdtsc)• No syscalls• No shared memory• No physical addresses

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

SGX Limitations

Classical Prime+Probe cannot be mounted within SGX:
• No access to high-precision timer (rdtsc)• No syscalls• No shared memory• No physical addresses• No 2 MB large pages

12

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Timer• We have to build our own timer

13

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Timer• We have to build our own timer• Timer resolution must be in the order of cycles

13

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Timer• We have to build our own timer• Timer resolution must be in the order of cycles• Start a thread that continuously increments a global variable13

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Timer• We have to build our own timer• Timer resolution must be in the order of cycles• Start a thread that continuously increments a global variable• The global variable is our timestamp

13

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Self-built Timer

CPU cycles one increment takes

rdtsc

1
4.7

1

timestamp = r d t s c ( ) ;

4.67
0.87

14

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Self-built Timer

CPU cycles one increment takes

rdtsc

1
4.7

C

while (1) {t i m e s t a m p ++;
3 }
1
2

4.67
0.87

14

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Self-built Timer

CPU cycles one increment takes

rdtsc

1

C

4.7

Assembly

4.67

mov &time stamp , %r c x
1 : i n c l (% r c x )3 jmp 1b
1
2

0.87

14

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Self-built Timer

CPU cycles one increment takes

rdtsc
C

4.7

Assembly

4.67

Optimized

14

1
mov &time stamp , %r c x
1 : i n c %r a x
3 mov %r a x , (% r c x )4 jmp 1b
1
2

0.87

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses• Cache set is determined by part of physical address [Mau+15]15Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses• Cache set is determined by part of physical address [Mau+15]• We have no knowledge of physical addresses

15

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses• Cache set is determined by part of physical address [Mau+15]• We have no knowledge of physical addresses• Use the reverse-engineered DRAM mapping [Pes+16]

15Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses• Cache set is determined by part of physical address [Mau+15]• We have no knowledge of physical addresses• Use the reverse-engineered DRAM mapping [Pes+16]• Exploit timing differences to find DRAM row borders

15

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses• Cache set is determined by part of physical address [Mau+15]• We have no knowledge of physical addresses• Use the reverse-engineered DRAM mapping [Pes+16]• Exploit timing differences to find DRAM row borders• The 18 LSBs are ‘0’ at a row border

15

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses
0127

8 kB row x in BG0 (1) and channel (1)Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (1) and channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (0)4 kB Page #1
16

Page #3

Page #4

Page #5

Page #6

Page #7

Page #84095

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses0127
BG0 (0), Channel (0)BG0 (0), Channel (0)8 kB row x in BG0 (1) and channel (1)Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)8 kB row x in BG0 (0) and channel (1)BG0 (0), Channel (0)BG0 (0), Channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (1) and channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)8 kB row x in BG0 (0) and channel (0)BG0 (0), Channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)4 kB Page #1
16

4095

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses0127
BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (0)BG0 (1), Channel (0)8 kB row x in BG0 (1) and channel (1)Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)BG0 (1), Channel (0)8 kB row x in BG0 (0) and channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (0)BG0 (1), Channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (1) and channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)BG0 (1), Channel (0)8 kB row x in BG0 (0) and channel (0)BG0 (0), Channel (0)BG0 (1), Channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)BG0 (1), Channel (0)4 kB Page #1
16

4095

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses0127
BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)8 kB row x in BG0 (1) and channel (1)Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (1) and channel (0)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (0)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)4 kB Page #1
16

4095

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses0127
BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)BG0 (0), Channel (0)BG0 (1), Channel (0)BG0 (0), Channel (1)BG0 (1), Channel (1)4 kB Page #1
16

8 kB row x in BG0 (1) and channel (1)Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #1

Page #2

Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (1)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (1) and channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #8

8 kB row x in BG0 (0) and channel (0)Page #3

Page #4

Page #5

Page #6

Page #7

Page #84095

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

row n

17

row n + 1

row n + 2

row n + 3

row n + 4

row n + 5

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Physical Addresses

Latency [cycles]

Result on an Intel i5-6200U
600
500

0

200

400

600

800

1,000 1,200 1,400 1,600 1,800 2,000

Array index [kB]18

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Combining Everything

1. Use the counting primitive to measure DRAM accesses

19

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Combining Everything

1. Use the counting primitive to measure DRAM accesses
2. Through the DRAM side channel, determine the row borders

19

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Combining Everything

1. Use the counting primitive to measure DRAM accesses
2. Through the DRAM side channel, determine the row borders
3. Row borders have the 18 LSBs set to ‘0’ → maps to cache set ‘0’19Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Combining Everything

1. Use the counting primitive to measure DRAM accesses
2. Through the DRAM side channel, determine the row borders
3. Row borders have the 18 LSBs set to ‘0’ → maps to cache set ‘0’
4. Build the eviction set for the Prime+Probe attack

19

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Combining Everything

1. Use the counting primitive to measure DRAM accesses
2. Through the DRAM side channel, determine the row borders
3. Row borders have the 18 LSBs set to ‘0’ → maps to cache set ‘0’
4. Build the eviction set for the Prime+Probe attack
5. Mount Prime+Probe on the buffer containing themultiplier [Sch+17]19Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Results

Measured Trace

Raw Prime+Probe trace...

20

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Measured Trace...processed with a simple moving average...

21

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Measured Trace...allows to clearly see the bits of the exponent

1 1 1 00 1 1 1 0 1 1 1 0000000 1 000 1 0 1 00 1 1 00 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1 000 1 00 1 1 1 0 1 000 1 1 1 0000 1 1 1

22

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Performance counter value

Performance Counters

23

Native

·109

1
0.5
0
L1 Hits

L1 Misses

L3 Hits

L3 Misses

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Performance counter value

Performance Counters

23

Native
SGX

·109

1
0.5
0
L1 Hits

L1 Misses

L3 Hits

L3 Misses

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Countermeasures

Source Level• Cache attacks can be prevented on source level

24

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Source Level• Cache attacks can be prevented on source level• Use side-channel resistant crypto implementations

24

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Source Level• Cache attacks can be prevented on source level• Use side-channel resistant crypto implementations• Exponent blinding for RSA prevents multi-trace attacks

24

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Source Level• Cache attacks can be prevented on source level• Use side-channel resistant crypto implementations• Exponent blinding for RSA prevents multi-trace attacks• Bit-sliced implementations are not vulnerable to cache attacks

24

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Operating System Level• Trusting the operating system weakens SGX threat model

25

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Operating System Level• Trusting the operating system weakens SGX threat model• Method for the operating system to inspect enclave code

25

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Operating System Level• Trusting the operating system weakens SGX threat model• Method for the operating system to inspect enclave code
• Re-enable certain performance counters, such as L3 hits/misses

25

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Operating System Level• Trusting the operating system weakens SGX threat model• Method for the operating system to inspect enclave code
• Re-enable certain performance counters, such as L3 hits/misses• Enclave coloring to prevent cross-enclave attacks

25

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Operating System Level• Trusting the operating system weakens SGX threat model• Method for the operating system to inspect enclave code
• Re-enable certain performance counters, such as L3 hits/misses• Enclave coloring to prevent cross-enclave attacks• Heap randomization to randomize cache sets

25

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware• Combine Cache Allocation Technology (CAT) with SGX

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware• Combine Cache Allocation Technology (CAT) with SGX• Instead of controlling CAT from the OS, combine it with eenter

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware• Combine Cache Allocation Technology (CAT) with SGX• Instead of controlling CAT from the OS, combine it with eenter• Entering an enclave would automatically activate CAT for this core

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware• Combine Cache Allocation Technology (CAT) with SGX• Instead of controlling CAT from the OS, combine it with eenter• Entering an enclave would automatically activate CAT for this core
• L3 is then isolated from all other enclaves and applications

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Hardware Level• Intel could prevent attacks by changing the hardware• Combine Cache Allocation Technology (CAT) with SGX• Instead of controlling CAT from the OS, combine it with eenter• Entering an enclave would automatically activate CAT for this core
• L3 is then isolated from all other enclaves and applications• Provide a non-shared secure memory element which is not cached

26

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Exploiting Non-Side-Channel
Bugs using Side-Channel Attacks

The Black Box• Assuming a side-channel resistant crypto implementation

27

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Black Box• Assuming a side-channel resistant crypto implementation• Everything is inside the enclave

27

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Black Box• Assuming a side-channel resistant crypto implementation• Everything is inside the enclave• No source or (unencrypted) binary available

27

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Black Box• Assuming a side-channel resistant crypto implementation• Everything is inside the enclave• No source or (unencrypted) binary available• A blackbox with an API

27

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player

DRM

28

Video
PlayerMichael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player• A classical digitial rights management scenario
DRM

29

Video
PlayerMichael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player• A classical digitial rights management scenario
DRM

29

Video
Player• Encrypted video file with a signed header

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player• A classical digitial rights management scenario
DRM

29

Video
Player• Encrypted video file with a signed header• The header contains the validity period

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player• A classical digitial rights management scenario
DRM

Video
Player• Encrypted video file with a signed header• The header contains the validity period• Checks whether current time is within period and signature is valid

29

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player• A classical digitial rights management scenario
DRM

Video
Player• Encrypted video file with a signed header• The header contains the validity period• Checks whether current time is within period and signature is valid• Plays the file, e.g., using Intel’s Protected Audio Video Path (PAVP)

29

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Circumvent the Protection• We do not like DRM

30

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Circumvent the Protection• We do not like DRM• And we want to keep our stolen Bitcoins...

30

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Circumvent the Protection• We do not like DRM• And we want to keep our stolen Bitcoins...
• ...not pay for the same movie over and over30

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Circumvent the Protection• We do not like DRM• And we want to keep our stolen Bitcoins...
• ...not pay for the same movie over and over
• No cache attack on crypto this time30

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Codevoid play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}31

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Codevoid play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}DRM-protected file

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}31

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Codevoid play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}DRM-protected fileTampering detected

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}31

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Codevoid play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}DRM-protected fileTampering detected

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}Expiredvoid * data = decrypt ( file - > content ) ;play_secure ( data ) ;}31

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Codevoid play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}DRM-protected fileTampering detected

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;ExpiredEverything is fine}31

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Race Condition• Although the code looks correct, there is a problem

32

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Race Condition• Although the code looks correct, there is a problem• SGX enclaves can access non-enclave memory

32

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Race Condition• Although the code looks correct, there is a problem• SGX enclaves can access non-enclave memory• For convenience, memory is often shared between enclave andloader32

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Race Condition• Although the code looks correct, there is a problem• SGX enclaves can access non-enclave memory• For convenience, memory is often shared between enclave andloader• This can create race conditions

32

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Code - Again
void play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}33

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Code - Again
void play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}Shared memory

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}33

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Code - Again
Shared memory
void play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {First access of shared memory// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}33

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Code - Again
Shared memory
void play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {First access of shared memory// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
Second access of shared memory
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}33

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

A Glance at the Code - Again
Shared memory
void play_file ( DRMFile * file ) {if ( c h ec k_ si g na tu re ( file - > header ) == ERR_INVALID ) {First access of shared memory// invalid s i g n a t u r e
return ;Headers can be changed here!
}

int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
Second access of shared memory
return ;}void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}33

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double Fetches• A time-of-check-to-time-of-use (TOCTTOU) bug

34

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double Fetches• A time-of-check-to-time-of-use (TOCTTOU) bug• After the signature check, the memory might change

34

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double Fetches• A time-of-check-to-time-of-use (TOCTTOU) bug• After the signature check, the memory might change• Adversary can abuse this to set arbitrary validity period

34

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double Fetches• A time-of-check-to-time-of-use (TOCTTOU) bug• After the signature check, the memory might change• Adversary can abuse this to set arbitrary validity period• Caused by accessing the shared memory twice

34

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double Fetches• A time-of-check-to-time-of-use (TOCTTOU) bug• After the signature check, the memory might change• Adversary can abuse this to set arbitrary validity period• Caused by accessing the shared memory twice• Also called double-fetch bugs

34

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Detecting Double Fetches• We cheated by looking at the code

35

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Detecting Double Fetches• We cheated by looking at the code
• What if we have neither code nor binary?

35

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Detecting Double Fetches• We cheated by looking at the code
• What if we have neither code nor binary?
• Memory accesses are visible in the cache

35

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Detecting Double Fetches• We cheated by looking at the code
• What if we have neither code nor binary?
• Memory accesses are visible in the cache• Observe memory accesses via cache attack

35

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload• Shared memory makes it a lot easier

36

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload• Shared memory makes it a lot easier• Constantly flush value from cache using clflush instruction

36

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload• Shared memory makes it a lot easier• Constantly flush value from cache using clflush instruction• Schedule victim

36

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload• Shared memory makes it a lot easier• Constantly flush value from cache using clflush instruction• Schedule victim• Measure access time to value

36

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload• Shared memory makes it a lot easier• Constantly flush value from cache using clflush instruction• Schedule victim• Measure access time to value• If access is fast, victim accessed (and cached) the data

36

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload

Access time [cycles]

260

240

220

200
0.1

0.2

0.3

0.4

0.5

0.6

Runtime [cycles]

37

0.7

0.8

0.9

1

1.1

·106

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Flush+Reload

Access time [cycles]

260

240

220
Data was accessed

200
0.1

0.2

0.3

0.4

0.5

0.6

Runtime [cycles]

37

0.7

0.8

0.9

1

1.1

·106

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Detection

Access time
[cycles]

260

240

220

200
0.1

0.2

0.3

0.4

0.5

0.6

Runtime [cycles]

38

0.7

0.8

0.9

1
·106

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Detection

Access time
[cycles]

260

240

220
First access

200
0.1

0.2

0.3

0.4

0.5

0.6

Runtime [cycles]

38

0.7

0.8

0.9

1
·106

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Detection

Access time
[cycles]

260

240

220
First accessSecond access

200
0.1

0.2

0.3

0.4

0.5

0.6

Runtime [cycles]

38

0.7

0.8

0.9

1
·106

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Dynamic Double-fetch Detection• Cache attacks dynamically detect double fetches in black boxes

39

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Dynamic Double-fetch Detection• Cache attacks dynamically detect double fetches in black boxes• The further apart the two fetches, the higher the probability

39

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Dynamic Double-fetch Detection• Cache attacks dynamically detect double fetches in black boxes• The further apart the two fetches, the higher the probability• Minimum time between accesses is approximately 600 cycles

39

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Dynamic Double-fetch Detection• Cache attacks dynamically detect double fetches in black boxes• The further apart the two fetches, the higher the probability• Minimum time between accesses is approximately 600 cycles• If the time is ≥ 3 000 cycles, detection rate is close to 100 %39

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Dynamic Double-fetch Detection• Cache attacks dynamically detect double fetches in black boxes• The further apart the two fetches, the higher the probability• Minimum time between accesses is approximately 600 cycles• If the time is ≥ 3 000 cycles, detection rate is close to 100 %• Allows automated detection of double fetches in many scenarios

39

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Bug Exploitation• After detecting a double fetch, we want to exploit it40

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Bug Exploitation• After detecting a double fetch, we want to exploit it• There is only a small time window to modify the value

40

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Bug Exploitation• After detecting a double fetch, we want to exploit it• There is only a small time window to modify the value• State-of-the-art exploitation:• Flip the value as fast as possible between two values• At some point, we hit the time window• Probability is not very high40

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Double-fetch Bug Exploitation• After detecting a double fetch, we want to exploit it• There is only a small time window to modify the value• State-of-the-art exploitation:• Flip the value as fast as possible between two values• At some point, we hit the time window• Probability is not very high• We need a trigger

40

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger• Use the cache side channel as trigger

41

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger• Use the cache side channel as trigger• We already detect the memory accesses

41

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger• Use the cache side channel as trigger• We already detect the memory accesses• The first memory access acts as our trigger

41

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger• Use the cache side channel as trigger• We already detect the memory accesses• The first memory access acts as our trigger• Simply change the value immediately after the first access

41

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger

Access time
[cycles]

260

240

220

200
3

3.5

4

4.5

5
Runtime [cycles]

42

5.5

6

6.5

7

·105

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger

Access time
[cycles]

260

240

220
First access

200
3

3.5

4

4.5

5
Runtime [cycles]

42

5.5

6

6.5

7

·105

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger

Access time
[cycles]

260

240

220
First access

Modify value

200
3

3.5

4

4.5

5
Runtime [cycles]

42

5.5

6

6.5

7

·105

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Cache-based Trigger

Access time
[cycles]

260

240

220
First access

Modify value

Second access with modified value

200
3

3.5

4

4.5

5
Runtime [cycles]

42

5.5

6

6.5

7

·105

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

An SGX DRM Video Player

Live
DEMO

43

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Preventing Exploitation of
Double-fetch Bugs

Eliminate Double-fetch Bugs

• Double fetches are not bad by itself

44

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Double fetches are not bad by itself• Sometimes they are necessary

44

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Double fetches are not bad by itself• Sometimes they are necessary• Only problematic if a modified value leads to an exploit

44

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Double fetches are not bad by itself• Sometimes they are necessary• Only problematic if a modified value leads to an exploit• Even frameworks to exploit such race conditions [Wei+16]44

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Double fetches are not bad by itself• Sometimes they are necessary• Only problematic if a modified value leads to an exploit• Even frameworks to exploit such race conditions [Wei+16]• With cache trigger very reliable [Sch+18]44Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Idea: Ensure that both accesses are atomic...

45

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Idea: Ensure that both accesses are atomic...
• ...or at least look atomic from an attacker’s perspective

45

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Idea: Ensure that both accesses are atomic...
• ...or at least look atomic from an attacker’s perspective• We have such a mechanism on modern Intel CPUs

45

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Eliminate Double-fetch Bugs

• Idea: Ensure that both accesses are atomic...
• ...or at least look atomic from an attacker’s perspective• We have such a mechanism on modern Intel CPUs
• Intel TSX provides exactly this functionality in hardware

45

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory• Intel TSX is an implementation of hardware transactional memory

46

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory• Intel TSX is an implementation of hardware transactional memory• Ensures that multiple reads and writes are atomic

46

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory• Intel TSX is an implementation of hardware transactional memory• Ensures that multiple reads and writes are atomic• Operations are wrapped in a transaction

46

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory• Intel TSX is an implementation of hardware transactional memory• Ensures that multiple reads and writes are atomic• Operations are wrapped in a transaction• If something conflicts, transaction is rolled back46

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory• Intel TSX is an implementation of hardware transactional memory• Ensures that multiple reads and writes are atomic• Operations are wrapped in a transaction• If something conflicts, transaction is rolled back• Implemented using the cache

46

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

47

Cache

Thread 1

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

Thread 1

xbeginxend
else pathof xbegin

47

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

Thread 1

xbegin
mov

read

read

mov

data

xend
else pathof xbegin47

read set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbegin
mov
mov

read

Thread 1

data

read

read

data

write

mov
mov

data
xend
else pathof xbegin47

read set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbegin
mov
mov
mov

read

data

read

read
read

Thread 1

data

write
write

data

mov
mov
mov

xend
else pathof xbegin47

read set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbegin
mov
mov
mov

read

Thread 1

data

read

read

data

read

write
write

data

mov
mov
mov

xend
else pathof xbegin47

transactio

nal abortread set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbeginmov
movFirst access
mov

read

Thread 1

data

read

read

data

read

write
write

data

mov
mov
mov

xend
else pathof xbegin47

transactio

nal abortread set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbeginmov
movFirst access
mov

read

Thread 1

data

read

read

data

read

write
write

data

mov
mov
Modification
mov

xend
else pathof xbegin47

transactio

nal abortread set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbeginmov
movFirst accessSecond access
mov

read

Thread 1

data

read

read

data

read

write
write

data

mov
mov
Modification
mov

xend
else pathof xbegin47

transactio

nal abortread set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Transactional Memory

Thread 0

Cache

xbeginmov
movFirst accessSecond access
mov

read

Thread 1

data

read

read

data

read

write
write

data

mov
mov
Modification
mov

xend
else
path
Exploitdetectedof xbegin47

transactio

nal abortread set

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• We created DropIt, a tiny library48

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• We created DropIt, a tiny library• It prevents exploitation of double fetches using TSX

48

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• We created DropIt, a tiny library• It prevents exploitation of double fetches using TSX• Open source:

48

https://github.com/IAIK/libdropit

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• We created DropIt, a tiny library• It prevents exploitation of double fetches using TSX• Open source:

https://github.com/IAIK/libdropit• Easy to use, 3 additional lines of code are sufficient48

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Protected Codevoid play_file ( DRMFile * file ) {doublefetch_t config = d o u b l e f e t c h _ i n i t (10) ;d o u b l e f e t c h _ s t a r t ( config ) ;if ( c h ec k_ s ig na tu r e ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}d ou bl ef e tc h_ en d ( config , { printf ( " Exploit detected !\ n " ) ; exit ( -1) ;}) ;void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}49

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Protected Codevoid play_file ( DRMFile * file ) {doublefetch_t config = d o u b l e f e t c h _ i n i t (10) ;Retry maximum 10 times
d o u b l e f e t c h _ s t a r t ( config ) ;if ( c h ec k_ s ig na tu r e ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}d ou bl ef e tc h_ en d ( config , { printf ( " Exploit detected !\ n " ) ; exit ( -1) ;}) ;void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}49

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Protected Codevoid play_file ( DRMFile * file ) {doublefetch_t config = d o u b l e f e t c h _ i n i t (10) ;Retry maximum 10 times
Start protection d o u b l e f e t c h _ s t a r t ( config ) ;if ( c h ec k_ s ig na tu r e ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}d ou bl ef e tc h_ en d ( config , { printf ( " Exploit detected !\ n " ) ; exit ( -1) ;}) ;void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}49

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Protected Codevoid play_file ( DRMFile * file ) {doublefetch_t config = d o u b l e f e t c h _ i n i t (10) ;Retry maximum 10 times
Start protection d o u b l e f e t c h _ s t a r t ( config ) ;if ( c h ec k_ s ig na tu r e ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;}int now = g e t _ t i m e s t a m p _ s e c u r e () ;End protection

if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}d ou bl ef e tc h_ en d ( config , { printf ( " Exploit detected !\ n " ) ; exit ( -1) ;}) ;void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}49

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

The Protected Codevoid play_file ( DRMFile * file ) {doublefetch_t config = d o u b l e f e t c h _ i n i t (10) ;Retry maximum 10 times
Start protection d o u b l e f e t c h _ s t a r t ( config ) ;if ( c h ec k_ s ig na tu r e ( file - > header ) == ERR_INVALID ) {// invalid s i g n a t u r e
return ;Everything in between is atomic}
int now = g e t _ t i m e s t a m p _ s e c u r e () ;End protection

if ( now < file - > header . from || now > file - > header . to ) {// not allowed to watch it now
return ;}d ou bl ef e tc h_ en d ( config , { printf ( " Exploit detected !\ n " ) ; exit ( -1) ;}) ;void * data = decrypt ( file - > content ) ;play_secure ( data ) ;}49

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• Efficient and easy solution to a complex problem

50

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• Efficient and easy solution to a complex problem• Faster than traditional locking (≈ 18 %)50

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• Efficient and easy solution to a complex problem• Faster than traditional locking (≈ 18 %)• Unfortunately limited to new Intel CPUs

50

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

DropIt: TSX against Double-fetch Bugs

• Efficient and easy solution to a complex problem• Faster than traditional locking (≈ 18 %)• Unfortunately limited to new Intel CPUs
• Many CPUs with SGX also have TSX

50

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

ConclusionBlack Hat Sound Bytes

Black Hat Sound Bytes.
• Side channels can cost you money

51

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Black Hat Sound Bytes

Black Hat Sound Bytes.
• Side channels can cost you money• Do not consider side channels out-of-scope

51

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Black Hat Sound Bytes

Black Hat Sound Bytes.
• Side channels can cost you money• Do not consider side channels out-of-scope• Exploitable code + SGX = exploitable SGX enclave

51

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

Thank you!

When Good Turns Evil
Using Intel SGX to Stealthily Steal Bitcoins

Michael Schwarz@misc0110

Moritz Lipp
@mlqxyzF. Liu, Y. Yarom, Q. Ge, G. Heiser, and R. B. Lee. Last-Level Cache Side-Channel Attacks
are Practical. In: S&P. 2015.
C. Maurice, N. Le Scouarnec, C. Neumann, O. Heen, and A. Francillon. Reverse
Engineering Intel Complex Addressing Using Performance Counters. In: RAID. 2015.
C. Maurice, M. Weber, M. Schwarz, L. Giner, D. Gruss, C. A. Boano, S. Mangard, and
K. Römer. Hello from the Other Side: SSH over Robust Cache Covert Channels in the
Cloud. In: NDSS. 2017.
D. A. Osvik, A. Shamir, and E. Tromer. Cache Attacks and Countermeasures: the Case of
AES. In: CT-RSA. 2006.
P. Pessl, D. Gruss, C. Maurice, M. Schwarz, and S. Mangard. DRAMA: Exploiting DRAM
Addressing for Cross-CPU Attacks. In: USENIX Security Symposium. 2016.
M. Schwarz, S. Weiser, D. Gruss, C. Maurice, and S. Mangard. Malware Guard Extension:
Using SGX to Conceal Cache Attacks. In: DIMVA. 2017.

52

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)

M. Schwarz, D. Gruss, M. Lipp, C. Maurice, T. Schuster, A. Fogh, and S. Mangard.
Automated Detection, Exploitation, and Elimination of Double-Fetch Bugs using Modern
CPU Features. In: AsiaCCS’18. 2018.
N. Weichbrodt, A. Kurmus, P. Pietzuch, and R. Kapitza. AsyncShock: Exploiting
synchronisation bugs in Intel SGX enclaves. In: ESORICS’16. 2016.

53

Michael Schwarz (@misc0110), Moritz Lipp (@mlqxyz)