Anki Nelaturu recently blogged about Java Card 3’s split VM. His post is accurate, and provides interesting information for most people. However, for some old Java Carders, split VM has another meaning. It refers to the fact that, in Java Card 2, class files are trnasformed into CAP files, and bytecode verification usually happens during this transformation. In short, with a Java Card 2 split VM, bytecode verification is not performed on the card.
This kind of split VM leads to many vulnerabilities, and has led to the development of defensive virtual machine on smart cards, in which many runtime checks are performed at runtime, although they are performed only by the verifier in most VM implementations. Several on-card bytecode verifiers have been developed, in particular by Trusted Logic and Gemalto, but their deployment has remained limited, most likely because of load performance reasons.
With Java Card 3, the situation depends on the edition:
- On Classic Edition, “split VM” still refers to the Java Card 2 system, in which on-card verification is optional. CAP files are loaded, and no verification is performed.
- On Connection Edition, “split VM” refers to the JSR-202 style verification, in which stack maps are precomputed by the compiler, and then verified on the device.
Both VMs are split, but not exactly in the same way. This is going to be fun.