<?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>On the road to Bandol &#187; Virtual machine</title>
	<atom:link href="https://javacard.vetilles.com/category/java-card-2x/virtual-machine/feed/" rel="self" type="application/rss+xml" />
	<link>https://javacard.vetilles.com</link>
	<description>A weblog on Java Card, security, and other things personal</description>
	<lastBuildDate>Mon, 18 Aug 2025 06:48:26 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.0.32</generator>
	<item>
		<title>The misuse of bytecode verification</title>
		<link>https://javacard.vetilles.com/2011/10/19/the-misuse-of-bytecode-verification/</link>
		<comments>https://javacard.vetilles.com/2011/10/19/the-misuse-of-bytecode-verification/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 08:42:21 +0000</pubDate>
		<dc:creator><![CDATA[Eric Vétillard]]></dc:creator>
				<category><![CDATA[Discussions]]></category>
		<category><![CDATA[Java Card 2.x]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Virtual machine]]></category>
		<category><![CDATA[bytecode]]></category>
		<category><![CDATA[GlobalPlatform]]></category>
		<category><![CDATA[static analysis]]></category>

		<guid isPermaLink="false">http://javacard.vetilles.com/?p=759</guid>
		<description><![CDATA[Bytecode verification has been an interesting debate since the very beginning of Java Card. Back then, in 1997, Java was very much about Java applets, and the bytecode verifier was the essential piece of software that allowed untrusted code to run in a browser efficiently (i.e., without doing expensive runtime checks, and without having to [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bytecode verification has been an interesting debate since the very beginning of Java Card. Back then, in 1997, Java was very much about Java applets, and the bytecode verifier was the essential piece of software that allowed untrusted code to run in a browser efficiently (<em>i.e.</em>, without doing expensive runtime checks, and without having to setup a complex process of applet vetting). We inherited this view of bytecode verification in Java Card, and the verifier was integrated in the Java Card virtual machine.</p>
<p>Since then, there have been many debates about bytecode verification, and my own position has evolved over the years. Today, my opinion is a bit contrasted, some may even say contradictory. Nevertheless, here it is:</p>
<ul>
<li>Bytecode verification has limited use for Java Card runtime security.</li>
<li>Extended bytecode verification is a very good tool for application vetting.</li>
</ul>
<p>Let me give a few more details about these two opinions.</p>
<h4>Bytecode verification and runtime security</h4>
<p>The idea of runtime verification is that it is performed after getting the code, and right before to run it. The code that runs is therefore known correct, at least regarding bytecode execution (unrelated attacks remain possible, of course).</p>
<p>The first big issue with bytecode verification is that, in Java Card, with the split virtual machine model, verification is not performed on the card, but outside of the card, before/during/after converting the application into Java Card&#8217;s specific binary format (CAP file). Then, the application is sent to the card over some channel that may be attacked. Here, we rely on GlobalPlatform&#8217;s cryptography-based security to protect the integrity of the code. So, basically, we still need to establish trust, and we must say goodbye to the power of running untrusted code from arbitrary developers.</p>
<p>This is not a big issue in practice, because there is no business model that allows arbitrary code to be loaded on cards. However, this causes an organizational problem, as the verification process needs to be well organized. Researchers from Nijmegen and Limoges have shown that it is possible to fool the verification process with fake export files, and then load on a card verified code that will perform type confusion attacks.</p>
<p>Going beyond that, some people have designed applications that can be verified, but have been designed to be attacked through hardware attacks (fault induction, usually). Such attacks, usually known as hybrid attacks, completely fool the bytecode verification process.</p>
<p>Most security experts will then remind you at this point of the discussion that bytecode verification is only one part of the process, that GlobalPlatform is also important, that the origin of code is usually known, that this makes it very difficult to include attack code in an application, <em>etc</em>. By doing this, they are just about accepting the fact that bytecode verification is useless or at best  marginally useful: the real security of cards is in the trust between issuers and application providers, and some cryptographic process. Basically, this works because the ecosystems are small enough to be controlled (which is true for cards, and fine for me).</p>
<p>Finally, some vendors claim to have developed defensive virtual machines, which do not require a bytecode verifier, and perform enough runtime verifications to accept any bytecode, good or bad, without any risk. In that case, bytecode verification is really useless, and I believe that it makes things much simpler. Of course, such virtual machines are difficult to design and implement efficiently, but this is definitely possible, and I think that it has been done in the past (or at least that some people has come very close to it).</p>
<p>To conclude, I will get back many years ago. In 2000, Trusted Logic was very proud of its on-card bytecode verifier; the technology worked, but it has not been widely adopted. I believe that the first factor was performance, as verification made the loading and linking process much slower. I also believe that a second factor, less obvious, is that on-card bytecode verification makes the card&#8217;s security more brittle, by encouraging VM developers to rely too much on static verification rather than runtime checks (which also prevent other runtime attacks, for instance using fault induction). More than ten years later, most people admit that this was not the way to go, and I just go one step further by stating that bytecode verification is not that useful for runtime security.</p>
<h4>Bytecode verification and application vetting</h4>
<p>Bytecode verification simply consists of a very simple static analysis of the application code. Basically, this is is a program proof, but a very simple one, whose complexity can be controlled. The objective of such simple proofs is not to demonstrate that a program is correct with respect to its specification, but that this program obeys a predefined set of properties.</p>
<p>For Java bytecode verification, these properties are related to the proper ues of the bytecode instructions. However, the same algorithms can be extended in order to prove many more properties, covering many aspects of application security. Among the things that can be proven, we have the following:</p>
<ul>
<li>Method <em>M</em> is not called.</li>
<li>Method <em>M</em> is not called with arguments <em>A1</em>, &#8230;, <em>An</em>.</li>
<li>Method <em>M</em> is always called before/after method <em>N</em>.</li>
<li>Method <em>M</em> never throws a <code>NullPointerException</code> (or any other exception).</li>
<li>Command <em>INS</em> can only return status codes <em>SW1</em>, &#8230;, <em>SWn</em></li>
<li>Toolkit buffers are only used when they are available.</li>
<li>and many more.</li>
</ul>
<p>Of course, there is no magic. When extending static analysis to many properties, it becomes more and more difficult to avoid false positives, <em>i.e.</em> errors that are caused by weaknesses in the algorithms. Put simply, an application is rejected although it is in fact correct.</p>
<p>Apart from working on the algorithms to make them better, there are two ways to deal with this issue:</p>
<ul>
<li>Providing the verification tool to developers, together with explanations about the rules to follow. Usually, it is rather simple for developers to ensure that their application can be verified, provided that they can use the tool throughout the development process.</li>
<li>Use the tool in a vetting process as a guide for evaluators, who then perform additional verifications. In that case, broken rules are considered as warnings, and then verified by the evaluators. Simple applications can usually be verified easily, and more complex verification requires a few checks, simplified by the fact that the most boring tasks are performed automatically.</li>
</ul>
<p>I believe in both approaches, but the second one has been proven efficient by my then colleagues of Trusted Labs. By using such a static analysis tool, they are able to optimize the vetting process of Java Card applications (and MIDlets, but this is another story) significantly, by allowing them to focus on the the most important parts of the applications.</p>
<p>In addition, this approach allows us to include many more security rules. For instance, hybrid applications must include code that can be modified into attack code through a simple attack. It is possible to build a library of patterns of such code sequences, and to check for them statically. Then, evaluators can be warned of the possible presence of an hybrid attack and check for it. This can be promising, because such checks (very boring to do, but very unlikely to lead to anything) are usually poorly performed by humans.</p>
<p>Finally, extended bytecode verification, or static analysis, has been proven to be a very efficient optimization tool. All optimizing compilers include a static analysis phase to perform their most complex optimizations. Java Card can take great advantage of this, because of the isolation between applications, and also because of the closed world hypothesis that is sometimes possible, when cards are closed (no additional applications can be downloaded).</p>
<p>So, bytecode verification has many uses in Java Card, but runtime security just isn&#8217;t the most compelling.</p>
]]></content:encoded>
			<wfw:commentRss>https://javacard.vetilles.com/2011/10/19/the-misuse-of-bytecode-verification/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Defensive virtual machines</title>
		<link>https://javacard.vetilles.com/2006/12/03/defensive-virtual-machines/</link>
		<comments>https://javacard.vetilles.com/2006/12/03/defensive-virtual-machines/#comments</comments>
		<pubDate>Sat, 02 Dec 2006 22:24:53 +0000</pubDate>
		<dc:creator><![CDATA[Eric Vétillard]]></dc:creator>
				<category><![CDATA[Java Card 2.x]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Virtual machine]]></category>

		<guid isPermaLink="false">http://javacard.vetilles.com/2006/12/03/defensive-virtual-machines/</guid>
		<description><![CDATA[The notion of defensive virtual machine is a bit awkward. The official presentation of the Java (Card) Virtual Machine describes it as inherently secure, so the notion of defensive is a bit contradictory with this message. In fact, the notion of defensive virtual machine is the result of a long process: Virtual machines usually present [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The notion of <em>defensive virtual machine</em> is a bit awkward. The official presentation of the Java (Card) Virtual Machine describes it as inherently secure, so the notion of defensive is a bit contradictory with this message.</p>
<p>In fact, the notion of defensive virtual machine is the result of a long process:</p>
<ul>
<li>Virtual machines usually present the advantage to introduce a good level of control. For instance, to name a few things available on Java, good typing is guaranteed, only existing and initialized local variables can be accessed, and it is not possible to access data out of the bounds of arrays.</li>
<li>Performing all these checks makes a virtual machine slow, so the designers of the Java Virtual Machine (JVM) have designed the code to be statically verifiable. This means that most of the checks (basically, all but the array bounds checks) are performed once and for all by analyzing the code at load time. Thanks to these optimizations, the performance of the JVM is rather good, while keeping its security.</li>
<li>On a platform like Java Card, which can be attacked, this raises security issues. If code is modified in an attack, the guarantees do not hold any more. We then get to the defensive virtual machine, which performs <em>redundant</em> checks. Some of the original checks are performed, in order to have some guarantees or correct execution even in the hypothesis of an attack.</li>
</ul>
<p>In Java Card, there is an additional reason to resort to defensive virtual machines: the bytecode verifier is not run on the execution platform, but on a separate platform. This provides an attacker with many additional opportunities to modify the code and perform an interesting attack. It is therefore more tempting to include additional defences.</p>
<p>Many smart card manufacturers claim that their Java Card VM is defensive, but this word covers a wide variety of things. Some VM&#8217;s simply include a few redundant bounds check, whereas some others include complete bounds checks, as well as some typing checks. When confronted with badly typed applets (the ultimate attack that defensive VM&#8217;s defend against), the simplest ones simply cause the attacker to think a few more minutes; with the most complex ones, badly typed code becomes very inefficient, and usually leads to no interesting result.</p>
<p>In the end, defensive virtual machines are yet another instance of the perpetual dilemma between performance and security.</p>
]]></content:encoded>
			<wfw:commentRss>https://javacard.vetilles.com/2006/12/03/defensive-virtual-machines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
