0% found this document useful (0 votes)
3 views55 pages

lecture12

The document discusses the implementation of functions for publishing statistics and looking up results related to COVID-19 test records, focusing on information flow and declassification. It also addresses timing leaks in cryptographic algorithms, specifically in the context of RSA, and presents the Montgomery Representation to optimize modular multiplication. The content emphasizes the importance of maintaining security while handling sensitive data and preventing potential information leakage.

Uploaded by

christian
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views55 pages

lecture12

The document discusses the implementation of functions for publishing statistics and looking up results related to COVID-19 test records, focusing on information flow and declassification. It also addresses timing leaks in cryptographic algorithms, specifically in the context of RSA, and presents the Montgomery Representation to optimize modular multiplication. The content emphasizes the importance of maintaining security while handling sensitive data and preventing potential information leakage.

Uploaded by

christian
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

02244 Logic for Security

Information Flow
Week 12: Information Leakage

Sebastian Mödersheim

May 5, 2025

Sebastian Mödersheim 1 of 26
Challenge

testrecord = record [ subject : cpr {shs:shs},


positive: bool {shs:shs} ]
publish_stat(db:array[testrecord:{⊥}]{⊥})
returns infections:int{⊥}

lookup_result(db:array[testrecord:{⊥}]{⊥},
client:cpr{⊥})
returns result:bool{client:client}

shs is for sundhedsstyrelsen


Implement the functions publish stat (giving total number of
infections, i.e., positive testrecords) and lookup result (giving the
result of the specified client):
• What authority/declassifications do the functions need?
• Prove that this is indeed safe.
Sebastian Mödersheim 2 of 26
Challenge
testrecord = record[subject:cpr{shs:shs},positive:bool{shs:shs}]
publish_stat(db:array[testrecord:{⊥}]{⊥})
returns infections:int{⊥}{
count:int {shs:shs} = 0;
i:int{⊥} = 0;
while (i<db.length){
if (db[i].positive) count=count+1;
// Infoflow: db[i].positive,i,db.length --> count
// OK: {⊥},{shs:shs} <= {shs:shs}
i=i+1;
// Infoflow: i,db.length --> i
// OK: {⊥} <= {⊥}
}
if_acts_for(publish_stat,shs){
infections = declassify(count,{⊥});
// Infoflow: count-->infections not allowed without declassification
// declassif. count:{shs:shs} to {⊥} is allowed when acting as shs
// Infoflow: declassify(count,{⊥}) -> infections
// OK: {⊥} <= {⊥}
}
}
Sebastian Mödersheim 3 of 26
Challenge
testrecord = record[subject:cpr{shs:shs},positive:bool{shs:shs}]
lookup_result(db:array[testrecord:{⊥}]{⊥},client:cpr{⊥})
returns result:bool{client:client}{
int:i{⊥} = 0;
tmp_result:bool{shs:shs} = false;
while (i<db.length){
if (db[i].subject=client){
tmp_result=db[i].positive;
// Infoflow: i,db.length,db[i].subject,client,db[i].positive
// --> tmp_result
// OK: {⊥},{shs:shs} <= {shs:shs}
}
i = i+1; // similar as in publish_stat
}
if_acts_for(lookup_result,shs){
result := declassify(tmp_result,{⊥});
// IF: tmp_result-->result not allowed without declassification
// decl. tmp_result:{shs:shs} to {⊥} is allowed when acting as shs
// Infoflow: declassify(tmp_result,{⊥}) -> result
// OK: {⊥} <= {client:client}
}
}
Sebastian Mödersheim 4 of 26
Timing Leaks

Consider the following naı̈ve algorithm for b x mod N:

finished=false;
result=1;
while(x>0){
result=result*b mod N;
x=x-1;
}
finished=true

• Assume finished is level Low, while all other variables are High.

Sebastian Mödersheim 5 of 26
Timing Leaks

Consider the following naı̈ve algorithm for b x mod N:

finished=false;
result=1;
while(x>0){
result=result*b mod N;
x=x-1;
}
finished=true

• Assume finished is level Low, while all other variables are High.
• This satisfies classical information flow.

Sebastian Mödersheim 5 of 26
Timing Leaks

Consider the following naı̈ve algorithm for b x mod N:

finished=false;
result=1;
while(x>0){
result=result*b mod N;
x=x-1;
}
finished=true

• Assume finished is level Low, while all other variables are High.
• This satisfies classical information flow.
• However, an intruder who can observe finished can estimate x
— if they have a clock.

Sebastian Mödersheim 5 of 26
Timing Leaks

Consider the following naı̈ve algorithm for b x mod N:

finished=false;
result=1;
while(x>0){
result=result*b mod N;
x=x-1;
}
finished=true

• Assume finished is level Low, while all other variables are High.
• This satisfies classical information flow.
• However, an intruder who can observe finished can estimate x
— if they have a clock.
• This can be a problem in cryptographic algorithms, although the
above example would never be used in crypto. (Why?)
Sebastian Mödersheim 5 of 26
Timing Leaks
Consider the following less naı̈ve algorithm for b x mod N:
result=1;
while(x>1){
if (x%2==0){x=x/2;}
else{
x=(x-1)/2;
result=result*b % N;
}
b=b*b % N;
}
result=result*b % N;

Sebastian Mödersheim 6 of 26
Timing Leaks
Consider the following less naı̈ve algorithm for b x mod N:
result=1;
while(x>1){
if (x%2==0){x=x/2;}
else{
x=(x-1)/2;
result=result*b % N;
}
b=b*b % N;
}
result=result*b % N;
• The runtime still depends on x

Sebastian Mödersheim 6 of 26
Timing Leaks
Consider the following less naı̈ve algorithm for b x mod N:
result=1;
while(x>1){
if (x%2==0){x=x/2;}
else{
x=(x-1)/2;
result=result*b % N;
}
b=b*b % N;
}
result=result*b % N;
• The runtime still depends on x
⋆ position of the most significant set bit in x
⋆ number of bits set in x

Sebastian Mödersheim 6 of 26
Timing Leaks
Consider the following less naı̈ve algorithm for b x mod N:
result=1;
while(x>1){
if (x%2==0){x=x/2;}
else{
x=(x-1)/2;
result=result*b % N;
}
b=b*b % N;
}
result=result*b % N;
• The runtime still depends on x
⋆ position of the most significant set bit in x
⋆ number of bits set in x
• It is not difficult to make this algorithm constant time:
⋆ Ensure that also the then case performs a modular multiplication.
⋆ Ensure that there are exactly η rounds of the while loop
Sebastian Mödersheim
where η is the number of bits of x. 6 of 26
A Remote Timing Attack on RSA

As a more realistic example for timing leaks in cryptography, we


consider now the paper

[1] D. Brumley and D. Boneh: Remote timing attacks are practical,


Comput. Networks, 48(5), pp. 701–716, 2005.

• We skip some parts


• We make some simplifications
• You do not need to make any such analysis in your report!

Sebastian Mödersheim 7 of 26
Recall: RSA
Keygeneration:
• Choose bit-size η (recommended: η ≥ 2048)
• Choose random primes p, q of size η2 .
• Let N := p · q
• Choose random e of size η
• Compute d := e −1 mod (p − 1)(q − 1)
• The resulting public key is (N, e)
⋆ in OFMC for instance pk(B)
• The resulting private key is (p, q, d)
⋆ in OFMC for instance: inv(pk(B))
Encryption:
• c := me mod N
⋆ in OFMC for instance: {m}pk(B)
Decryption:
• m := c d mod N
⋆ in OFMC: decryption handled as part of the Dolev-Yao rules
Sebastian Mödersheim 8 of 26
Recall: RSA
Keygeneration:
• Choose bit-size η (recommended: η ≥ 2048)
• Choose random primes p, q of size η2 .
• Let N := p · q
• Choose random e of size η
• Compute d := e −1 mod (p − 1)(q − 1)
• The resulting public key is (N, e)
⋆ in OFMC for instance pk(B)
• The resulting private key is (p, q, d)
⋆ in OFMC for instance: inv(pk(B))
Encryption: to prevent guessing and multiplication attacks
e
• c := pad,m,rand mod N
⋆ where pad is a fixed padding string, rand is a fresh random string
Decryption:
• pad,m,rand := c d mod N
⋆ if pad is the fixed padding string, return m, otherwise error.
Sebastian Mödersheim 8 of 26
Montgomery Representation

• Computing the · mod N operation is very expensive, but is


needed up to 2η times during an exponentiation.
• Idea: with a different representation of numbers, we can reduce
it to one single · mod N operation!
Montgomery Representation (MR)
⋆ Let R = 2η
⋆ Represent a number a as a · R mod N .
⋆ Note: while a · R has 2η bits, modulo N we have again η bits.
⋆ We just write a · R in the following for short.

Sebastian Mödersheim 9 of 26
Multiplication modulo N in MR

Multiplying two numbers a and b in MR:

a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits

Sebastian Mödersheim 10 of 26
Multiplication modulo N in MR

Multiplying two numbers a and b in MR:

a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits

• Now the result must be divided by R to obtain


a · b · R , i.e., the MR of a · b.

Sebastian Mödersheim 10 of 26
Multiplication modulo N in MR

Multiplying two numbers a and b in MR:

a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits

• Now the result must be divided by R to obtain


a · b · R , i.e., the MR of a · b.
• Suppose:
a · b · R · R = XY 0...0 (1)
| {z } |{z} | {z }
2η bits η bits η bits

⋆ then the division by R would just be XY .


| {z }
η bits

Sebastian Mödersheim 10 of 26
Multiplication modulo N in MR

Multiplying two numbers a and b in MR:

a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits

• Now the result must be divided by R to obtain


a · b · R , i.e., the MR of a · b.
• Suppose:
a · b · R · R = XY 0...0 (1)
| {z } |{z} | {z }
2η bits η bits η bits

⋆ then the division by R would just be XY .


| {z }
η bits

• But how to achieve (1)?

Sebastian Mödersheim 10 of 26
Multiplication modulo N in MR

• It is nearly certain that the lower η bits of a · b · R · R are not


all zero.
• But note that a ≡N a + N, i.e. adding the modulus any number
of times does not change the result modulo N.

Sebastian Mödersheim 11 of 26
Multiplication modulo N in MR

• It is nearly certain that the lower η bits of a · b · R · R are not


all zero.
• But note that a ≡N a + N, i.e. adding the modulus any number
of times does not change the result modulo N.
• For instance say N = ⟨101⟩2

a 1 0 1 1 0 1 0 0
+4N 0 0 0 1 0 1 0 0
≡N a 1 1 0 0 1 0 0 0

Sebastian Mödersheim 11 of 26
Multiplication modulo N in MR

• It is nearly certain that the lower η bits of a · b · R · R are not


all zero.
• But note that a ≡N a + N, i.e. adding the modulus any number
of times does not change the result modulo N.
• For instance say N = ⟨101⟩2

a 1 0 1 1 0 1 0 0
+4N 0 0 0 1 0 1 0 0
≡N a 1 1 0 0 1 0 0 0

• In this way we can achieve the lower half to be zero without


changing the result modulo N.

Sebastian Mödersheim 11 of 26
Multiplication modulo N in MR

So we now have:
• Step 1:
a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits
• Step 2:
a · b · R · R + k · N = XY 0...0
| {z } |{z} | {z }
2η bits η bits η bits

• Step 3: a · b · R ≡N XY
|{z}
η bits

Sebastian Mödersheim 12 of 26
Multiplication modulo N in MR

So we now have:
• Step 1:
a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits
• Step 2:
a · b · R · R + k · N = XY 0...0
| {z } |{z} | {z }
2η bits η bits η bits

• Step 3: a · b · R ≡N XY
|{z}
η bits
• But there is one small problem: XY may be larger than N (but
not larger than 2N)
⋆ So Step 4: if XY > N subtract N from it!

Sebastian Mödersheim 12 of 26
Multiplication modulo N in MR

So we now have:
• Step 1:
a · R · b · R ≡N a · b · R · R
| {z } | {z } | {z }
η bits η bits 2η bits
• Step 2:
a · b · R · R + k · N = XY 0...0
| {z } |{z} | {z }
2η bits η bits η bits

• Step 3: a · b · R ≡N XY
|{z}
η bits
• But there is one small problem: XY may be larger than N (but
not larger than 2N)
⋆ So Step 4: if XY > N subtract N from it!
• This last step is a timing leak!
⋆ In the exponentation c d mod N, this is happening more often if
c is close to N, and that can give a measurable difference!
Sebastian Mödersheim 12 of 26
Chinese Remainder Theorem

• So the exponentiation with MR can leak the modulus N.


• N in RSA is public, however, upon decryption, the factors
p · q = N are known.
• Implementations usually exploit this using the Chinese Remainder
Theorem:
⋆ One can compute c d mod N from the smaller problems
▶ cd mod p
mod p
▶ cd mod q
mod q
⋆ This essentially makes it possible to obtain q by a timing attack,
and thus the rest of the private key.
▶ The paper uses also another timing leak in the multiplication.

Sebastian Mödersheim 13 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?

Sebastian Mödersheim 14 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?
• Suppose the intruder already knows the a few of the most
significant bits of q. Then the next bit can be obtained like this:

g = b1 b2 b3 0 0 0 0 0
ghi = b1 b2 b3 1 0 0 0 0

Sebastian Mödersheim 14 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?
• Suppose the intruder already knows the a few of the most
significant bits of q. Then the next bit can be obtained like this:

g = b1 b2 b3 0 0 0 0 0
ghi = b1 b2 b3 1 0 0 0 0

• Then q is either (a) between g and ghi or (b) above ghi .

Sebastian Mödersheim 14 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?
• Suppose the intruder already knows the a few of the most
significant bits of q. Then the next bit can be obtained like this:

g = b1 b2 b3 0 0 0 0 0
ghi = b1 b2 b3 1 0 0 0 0

• Then q is either (a) between g and ghi or (b) above ghi .


• Measure the time for c = g and c = ghi (under some transf.)

Sebastian Mödersheim 14 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?
• Suppose the intruder already knows the a few of the most
significant bits of q. Then the next bit can be obtained like this:

g = b1 b2 b3 0 0 0 0 0
ghi = b1 b2 b3 1 0 0 0 0

• Then q is either (a) between g and ghi or (b) above ghi .


• Measure the time for c = g and c = ghi (under some transf.)
• Timing reliably tells whether (a) or (b) is the case.
⋆ This is a bit tricky, see original paper...

Sebastian Mödersheim 14 of 26
The Timing Attack

Scenario: server running OpenSSL:

A → B : {PMS}pk(B) , ... (PMS is a fresh key)

The intruder can send an arbitrary value c and B will try to decrypt
it. What to send as c?
• Suppose the intruder already knows the a few of the most
significant bits of q. Then the next bit can be obtained like this:

g = b1 b2 b3 0 0 0 0 0
ghi = b1 b2 b3 1 0 0 0 0

• Then q is either (a) between g and ghi or (b) above ghi .


• Measure the time for c = g and c = ghi (under some transf.)
• Timing reliably tells whether (a) or (b) is the case.
⋆ This is a bit tricky, see original paper...
• Compute the next bit...
Sebastian Mödersheim 14 of 26
Counter-Measures

• Recommendations [1]:
⋆ blinding: multiply c with random r before decryption (and divide
result by r afterwards)
⋆ constant time: ensure runtime does not depend on the data.
• Compiler Design with special forms of information flow can help
here:
⋆ Generate Code that does not have timing leaks.
⋆ Compiler ensures that optimizations are not introducing time
leaks.
⋆ Target all popular processors.
⋆ Verified implementation (no gap to mathematical model)

• Project Everest: https://project-everest.github.io


• There is (almost) no excuse for using unverified crypto
implementations!

Sebastian Mödersheim 15 of 26
Spectre

Another spooky timing/side channel attack:

[3] Paul Kocher et al.: Spectre attacks: exploiting speculative


execution, Commun. ACM, 63(7), pp. 93–101, 2020.

• Exploit combines two common performance optimizations of


modern processors.
⋆ Caching
⋆ Speculative execution.
• Essentially: using speculative execution to leave “traces” in the
cache and obtain these traces.
• Works on a wide variety of processors.

Sebastian Mödersheim 16 of 26
Speculative Execution

a =3;
b=A r r a y [ 6 ] ;
c=f ( a ) ;

• Accessing Array[6] may be slow if not in cache.


• Instead of waiting, we could start computing f(a).

Sebastian Mödersheim 17 of 26
Speculative Execution

a =3;
i f ( Array [6] >3)
c=f ( a ) ;
else
c=g ( a ) ;

• If Array[6] takes time, we do not know for some time what is


the next command.

Sebastian Mödersheim 18 of 26
Speculative Execution

a =3;
i f ( Array [6] >3)
c=f ( a ) ;
else
c=g ( a ) ;

• If Array[6] takes time, we do not know for some time what is


the next command.
• Branch prediction: if we know Array[6]>3 has been often true
in the past, we could speculate it is going to be true again.

Sebastian Mödersheim 18 of 26
Speculative Execution

a =3;
i f ( Array [6] >3)
c=f ( a ) ;
else
c=g ( a ) ;

• If Array[6] takes time, we do not know for some time what is


the next command.
• Branch prediction: if we know Array[6]>3 has been often true
in the past, we could speculate it is going to be true again.
⋆ Go ahead computing f(a)
⋆ If Array[6]>3 turns out to be true, we win.
⋆ Otherwise, we have to revert the processor,
but we did not loose anything.

Sebastian Mödersheim 18 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Dramatis personae:
...
• y: chosen by the intruder. B[0] . . .
• A: array of size size. B[512] . . .
• The intruder is allowed to B[2 ∗ 512] . . .
know arrays A and B. ...
• There is a secret in the B[115 ∗ 512] . . .
application memory ...
somewhere after A.

Sebastian Mödersheim 19 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Suppose
...
• size is not in the cache. B[0] . . .
• A is not in the cache. B[512] . . .
• B is not in the cache. B[2 ∗ 512] . . .
• secret is in the cache. ...
B[115 ∗ 512] . . .
• Branch prediction expects
...
y<size to be true.

Sebastian Mödersheim 20 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
• The intruder guesses y , so ...
that A + y is the address
of secret. B[0] . . .
⋆ So: y>=size!
B[512] . . .
B[2 ∗ 512] . . .
...
B[115 ∗ 512] . . .
...

Sebastian Mödersheim 21 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
• The intruder guesses y , so ...
that A + y is the address
of secret. B[0] . . .
⋆ So: y>=size!
B[512] . . .
B[2 ∗ 512] . . .
• Evaluate y<size:
...
⋆ size not cached,
⋆ branch prediction is B[115 ∗ 512] . . .
positive ...

Sebastian Mödersheim 21 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
• The intruder guesses y , so . . .
that A + y is the address
of secret. B[0] . . .
⋆ So: y>=size!
B[512] . . .
B[2 ∗ 512] . . .
• Evaluate y<size:
...
⋆ size not cached,
⋆ branch prediction is B[115 ∗ 512] . . .
positive ...
Thus start speculative execution of B[A[y]*512].

Sebastian Mödersheim 21 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Speculative execution of
...
B[A[y]*512]
B[0] . . .
• A + y is address of secret. B[512] . . .
B[2 ∗ 512] . . .
...
B[115 ∗ 512] . . .
...

Sebastian Mödersheim 22 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Speculative execution of
...
B[A[y]*512]
B[0] . . .
• A + y is address of secret. B[512] . . .
• So A[y ] is in the cache! B[2 ∗ 512] . . .
...
B[115 ∗ 512] . . .
...

Sebastian Mödersheim 22 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Speculative execution of
...
B[A[y]*512]
B[0] . . .
• A + y is address of secret. B[512] . . .
• So A[y ] is in the cache! B[2 ∗ 512] . . .
• So processor loads ...
B[A[y ] ∗ 512] = B[115 ∗ 512] . . .
B[115 ∗ 512] ...

Sebastian Mödersheim 22 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Speculative execution of
...
B[A[y]*512]
B[0] . . .
• A + y is address of secret. B[512] . . .
• So A[y ] is in the cache! B[2 ∗ 512] . . .
• So processor loads ...
B[A[y ] ∗ 512] = B[115 ∗ 512] . . .
B[115 ∗ 512] ...
• ... it is now cached.

Sebastian Mödersheim 22 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Also size has arrived
...
• Thus, y<size can be B[0] . . .
computed to be false. B[512] . . .
• Thus, the processor B[2 ∗ 512] . . .
reverts to the state before. ...
B[115 ∗ 512] . . .
...

Sebastian Mödersheim 23 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Also size has arrived
...
• Thus, y<size can be B[0] . . .
computed to be false. B[512] . . .
• Thus, the processor B[2 ∗ 512] . . .
reverts to the state before. ...
• But the cache remains! B[115 ∗ 512] . . .
...

Sebastian Mödersheim 23 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Also size has arrived
...
• Thus, y<size can be B[0] . . .
computed to be false. B[512] . . .
• Thus, the processor B[2 ∗ 512] . . .
reverts to the state before. . . .
• But the cache remains! B[115 ∗ 512] . . .
...
The intruder can now try to access B[k*512] for k ∈ {0..255}.

Sebastian Mödersheim 23 of 26
Spectre: Example

Victim code size


i f ( y<s i z e ) ...
temp &= B [ A [ y ] ∗ 5 1 2 ] A[0] A[1] A[2] A[3] A[4] A[5]
...
s e c r e t
Also size has arrived
...
• Thus, y<size can be B[0] . . .
computed to be false. B[512] . . .
• Thus, the processor B[2 ∗ 512] . . .
reverts to the state before. . . .
• But the cache remains! B[115 ∗ 512] . . .
...
The intruder can now try to access B[k*512] for k ∈ {0..255}.
This is fast iff k = 115: he knows the first letter of the secret.
Sebastian Mödersheim 23 of 26
Speculative load hardening

The hardened code contains a few more operations:


mov size, %rax
mov y, %rbx
mov $0, $rdx
cmp %rbx, %rax
jbe END
cmovbe $-1, %rdx
mov A(%rbx), %rax
shl $9, %rax
or %rdx, %rax
mov B(%rax), %rax
or %rdx, %rax
and %rax, temp
END: ...

Sebastian Mödersheim 24 of 26
Side Channel Analysis

• Side channels are usually leaks that the designers never have
thought of.
• Many problems exist for years without getting noticed – how
much else is out there?
• Very active research field:
⋆ In order to prove a solution correct, one needs a precise model
first.
⋆ For instance Speculative non-interference and the Spectector tool.
[2] Marco Guarnieri et al.: Spectector: Principled Detection of
Speculative Information Flows, Security and Privacy, 2020.

Sebastian Mödersheim 25 of 26
References I

D. Brumley and D. Boneh.


Remote timing attacks are practical.
Comput. Networks, 48(5):701–716, 2005.
M. Guarnieri, B. Köpf, J. F. Morales, J. Reineke, and A. Sánchez.
Spectector: Principled detection of speculative information flows.
In 2020 IEEE Symposium on Security and Privacy, SP 2020, San
Francisco, CA, USA, May 18-21, 2020, pages 1–19. IEEE, 2020.
P. Kocher, J. Horn, A. Fogh, D. Genkin, D. Gruss, W. Haas,
M. Hamburg, M. Lipp, S. Mangard, T. Prescher, M. Schwarz,
and Y. Yarom.
Spectre attacks: exploiting speculative execution.
Commun. ACM, 63(7):93–101, 2020.

Sebastian Mödersheim 26 of 26

You might also like