<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Made of Bugs &#187; EE</title>
	<atom:link href="http://blog.nelhage.com/tag/ee/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Security doesn&#8217;t respect abstraction boundaries</title>
		<link>http://blog.nelhage.com/2010/03/security-doesnt-respect-abstraction/</link>
		<comments>http://blog.nelhage.com/2010/03/security-doesnt-respect-abstraction/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 00:20:26 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Computer Security]]></category>
		<category><![CDATA[abstraction]]></category>
		<category><![CDATA[EE]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[xor]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=171</guid>
		<description><![CDATA[The fundamental tool of any engineering discipline is the notion of abstraction. If we can build a set of useful, easily-described behaviors out of a complex system, we can build other systems on top of those pieces, without having to understand to worry about the full complexity of the underlying system. Without this notion of [...]]]></description>
			<content:encoded><![CDATA[<p>The fundamental tool of any engineering discipline is the notion of
abstraction. If we can build a set of useful, easily-described
behaviors out of a complex system, we can build other systems on top
of those pieces, without having to understand to worry about the full
complexity of the underlying system. Without this notion of
abstracting away complexity, we&#8217;d be stuck writing our webapps in
assembly code &ndash; if not toggling them in to our frontpanels after
painstakingly translating them into hex by hand.
</p>

<p></p><p>
One of the interesting things about computer security, which makes it
both so difficult and so fascinating, is that it often doesn&#8217;t obey
abstraction boundaries. For the most part, security problems happen
when abstractions are violated, and you leave the realm of behaviors
that can be described in terms of your abstractions. One class of
security problems are &#8220;spec bugs&#8221; &ndash; problems of the form &#8220;Oops, we
forgot we needed authentication for that operation&#8221; &ndash; but the
&#8220;interesting&#8221; ones, at least to me, are the ones where the security
problem can&#8217;t be fully understood in terms of the usual abstractions.
</p>
<p>
Here&#8217;s one of my favorite examples. I&#8217;ve heard it claimed that the US
actually used an attack of this sort against the KGB during the Cold War, but
that may be apocryphal. I certainly haven&#8217;t found a citation. The example is illustrative in any case.
</p>
<h2>One-Time Pads</h2>
<p>
Everyone knows that a one-time pad, used properly, provides perfect
encryption. Given a message M and a randomly generated key K of the same length, we can
compute C=M⊕K (that&#8217;s an XOR), and as long as K is only ever used
once, the ciphertext C is perfectly random and provides no information
about M, no matter how sophisticated the attacker.
</p>
<p>
So, let&#8217;s imagine, secure in that knowledge, we build a one-time pad
encryption system. It looks something like this:
</p>

<p><a href="http://blog.nelhage.com/wp-content/uploads/2010/03/otp.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/03/otp.png" alt="" title="One-Time Pad setup" width="132" height="203" class="aligncenter size-full wp-image-174" /></a></p>

<p>
A key flows in off of some kind of key storage system, and an operator
types in a message. These values flow in to an XOR gate, and we send
the output of the gate down the wire off to our collaborators in another big building somewhere.
</p>

<p>
We use the system for months, being very careful about key
management &#8212; we generate keys based off of readings from a geiger counter pointed at a mildly radioactive source, and only ever using any given section of the pad once. All is well and good until, six months down the line, we
discover Eve sitting somewhere between us and our allies, probes carefully
spliced into our cable. Even more disconcertingly, we find a stack of
printouts of every message we&#8217;ve ever sent across our communications line! We know that we&#8217;ve been utterly paranoid in distributing and protecting our keys, so there seems to only be one conclusion left: Eve has somehow broken our &#8220;perfect&#8221; encryption system!
</p>

<h2>So what went wrong?</h2>

<p>
Let&#8217;s look at our XOR gate. We know it&#8217;s an XOR gate, so it must have the
following truth table:
</p>

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides" >
<col align="right"></col><col align="right"></col><col align="right"></col>
<thead>
<tr><th>m</th><th>k</th><th>c</th></tr>
</thead>
<tbody>
<tr><td>0</td><td>0</td><td>0</td></tr>
<tr><td>1</td><td>0</td><td>1</td></tr>
<tr><td>0</td><td>1</td><td>1</td></tr>
<tr><td>1</td><td>1</td><td>0</td></tr>
</tbody>
</table>

<p>
But there aren&#8217;t actually mathematical logic values entering it &#8211;
this is a physical system, implemented on physical hardware, and there
is something representing those logic values. We&#8217;re using a digital
logic system, and so we&#8217;re representing those values with voltages, in
the range 0-5v.
</p>

<p></p><p>
The fundamental abstraction of digital logic is the notion of the
<b>static discipline</b>, which defines the range that input and output
voltages of devices fall into. Ignoring noise margins for the moment,
for a 5v system, we might stipulate that voltages under 2v represent a
logical &#8220;zero&#8221;, and voltages above 3v represent a logical &#8220;one&#8221;. So,
instead of the above table, we actually have the following behavior
table for a legal XOR gate:
</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<col align="left"></col><col align="left"></col><col align="left"></col>
<thead>
<tr><th>m</th><th>k</th><th>c</th></tr>
</thead>
<tbody>
<tr><td>&lt;2v</td><td>&lt;2v</td><td>&lt;2v</td></tr>
<tr><td>&lt;2v</td><td>&gt;3v</td><td>&gt;3v</td></tr>
<tr><td>&gt;3v</td><td>&lt;2v</td><td>&gt;3v</td></tr>
<tr><td>&gt;3v</td><td>&gt;3v</td><td>&lt;2v</td></tr>
</tbody>
</table>

<p>
Pulling out our trusty oscilloscope and signal generator, we disconnect
our own XOR gate, strap it to the test bench, and measure its
response. And lo and behold, we discover the following result:
</p>

<p><table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<col align="left"></col><col align="left"></col><col align="left"></col>
<thead>
<tr><th>m</th><th>k</th><th>c</th></tr>
</thead>
<tbody>
<tr><td>&lt;2v</td><td>&lt;2v</td><td>0.5v</td></tr>
<tr><td>&lt;2v</td><td>&gt;3v</td><td>4v</td></tr>
<tr><td>&gt;3v</td><td>&lt;2v</td><td>4.5v</td></tr>
<tr><td>&gt;3v</td><td>&gt;3v</td><td>1v</td></tr>
</tbody>
</table></p>

<p></p><p>
So all Eve has been doing is listening to our communication line with
her own oscilloscope, and reading off voltages, and she can extract
both M and K!</p>

<h2>In conclusion</h2>

<p>
So what went wrong here? We <b>assumed our attacker was using the same abstractions we were</b>. Within the scope of our abstraction, our system
was secure. The math tells us that a one-time pad using an XOR gate is
perfectly secure, and within the abstraction of our static discipline,
our gate was a correctly functioning XOR gate. But the problem was,
Eve isn&#8217;t constrained to use our abstractions. To analyze the security
of our system, we can&#8217;t just look at it in terms of the abstraction we
model it using, but we have to consider the details of the actual
implemention.
</p>

<p></p><p>
Abstraction layers are not a fundamental property of a system. They
are lines that we agree to draw onto it to keep ourselves sane when
designing complex systems. But they are only that, and no more. No one
is required to respect those lines, and so we are forced to analyze
the system as it really exists, without those nice lines drawn on it,
if we want to make it secure.
</p>

<p>This is also not to say that abstraction has no role in security, or in building secure systems requires working without abstractions. Far from it &#8212; complexity is an enemy of security, and abstractions are a key tool to reducing complexity. But it just means that you have to be careful, and build your abstractions with security in mind. Cryptography, for example, starts with a set of primitives &#8212; hash functions, public key encryption algorithms, and so on &#8212; and builds from them some basic tools &#8212; pseudo-random number generators, commitment schemes, etc. &#8212; that can be used to design cryptographic protocols. But, as much as possible, such constructions are based around mathematical proofs of the security properties of the derived constructions, starting from the mathematically well-defined security properties of the primitives.</p>

<p>Also, while this is one of the cutest examples I know of, there are still many examples of this principle in pure computer science. My favorite in software is perhaps exploiting buffer overflows and other memory corruption issues in C. The behavior of the system, in terms of C&#8217;s abstractions, is undefined once you overflow a buffer. And so, in order to exploit a buffer overflow, or understand how exploitation is possible, you have to look under that abstraction, and understand the underlying system. And defenses like stack cookies or ASLR are all about changing the underlying implementations to be harder to exploit in certain ways, while preserving the visible part of the abstraction. The arms race of exploitation techniques and memory protection techniques we&#8217;ve witnessed over the last decade or so is all about playing various games below the layer of the usual abstraction barriers.</p>

<h3>Addendum</h3>

<p></p><p>Probably no one has ever built an XOR gate as egregiously asymmetrical as the one I described above. But if we look at, e.g. the <a href="http://en.wikipedia.org/wiki/File:CmosXORGate.png">standard CMOS wiring</a> of an XOR gate, we see that it is in fact asymmetrical, so it&#8217;s totally conceivable that the output need not be perfectly symmetric with regard to the two inputs. Note also that my point is not at all that this problem is difficult to solve &#8212; one could easily stick some buffers on the output of the XOR gate, or do any of a number of other things. But the point is that without understanding the details underneath the usual abstractions you work with, this problem isn&#8217;t even conceivable, never mind solvable.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/03/security-doesnt-respect-abstraction/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

