There is probably no risk of exaggeration in saying that a full paradigm change with regard to downloadable program code in smart cards occurred within one year (1997–98). Downloadable program code in smart cards is now considered to be the rule rather than the exception. The reasons for the sudden increase in the importance of downloading executable program code cannot be completely and unambiguously ascertained, even in retrospect. One trigger may have been the floating-point error (in the FDIV instruction) in the then widely used Pentium processor, which became common knowledge in 1994. This could not be corrected by downloading new software, since the error was in the hardware. However, there were software patches (work-arounds) available for many applications. It is likely that this error is the reason why some large system operators, shortly after it became well known, suddenly made plans to allow executable code to be downloaded to smart cards. One of the largest applications that can accept executable program code is the German Eurocheque card. However, this capability is not presently used, so it in fact represents only a ‘sheet anchor’ to be used in case serious programming errors are discovered. In the GSM system, there are also operating systems for SIMs that allow program code for special applications to be downloaded via the radio interface. However, in contrast to all other computer operating systems, with smart cards it is not common practice to load programs into the cards after they have been issued and then run these programs as desired, despite the fact that this (along with storing data) is actually a primary function of every operating system. There are naturally good reasons why this particular functionality has been largely absent in smart cards up to now. From a technical and functional perspective, executable program code (stored in EFs, for example) does not present any problems at all. Modern operating systems can manage files containing executable code, and they also allow executable code to be downloaded after the card has been personalized. This makes it possible, for example, for an application provider to have executable code in the smart card that is not known to the producer of the operating system. An application provider could thus load a private encryption algorithm into the card and have it run there. This would allow the knowledge of the security features of the system to be distributed among several parties, which is one of the basic requirements for secure systems.

Another significant reason for allowing program code to be downloaded is that it makes it possible to correct programming errors in fully personalized cards (bug fixing). Known errors in the operating system can thereby be corrected or at least rendered less critical by using downloaded code. There are two basic ways to run downloaded code in a smart card. The first and technically simplest way is to load native code (code that has been compiled into the machine language of the target processor) into files in the smart card. This program code must of course be relocatable, since the memory addresses are not known outside the card. In addition to its technical simplicity, this solution has the advantage that the program can be run at the full execution speed of the processor, which makes it particularly attractive for downloaded algorithms. In addition, there is no need for extra program code for an interpreter. The main problem with this approach is that the downloaded program can also access the memory regions of other applications if the microcontroller does not have a memory management unit (MMU). The second way to execute downloadable code in a smart card is to interpret the code. In this case, the interpreter can check the memory regions that are being addressed while the program is running. However, the interpretation must run quickly, since there is no benefit to having code that runs slowly. The implementation of the interpreter should also occupy the least possible amount of memory, since only a very limited amount of memory is available. Presently, the best known versions of this approach are the Java Card specification [Javasoft, JFC] and the C interpreter MEL (Multos Executable Language) from Multos [Maosco] (as well as Windows for Smart Cards, which has now again been cancelled). There is even a Basic interpreter for smart cards, which has been available for several years [Zeitcontrol]. Incidentally, interpreters are not suitable for correcting errors in smart card operating systems, since they make a specific region of protected memory available to an application program and thus do not have access to the areas where the operating system routines and data are stored.

The age-old problem with interpreters is their slowness, which is an inherent property of interpreted code. There are several different approaches that can be used to compensate for this drawback and keep the size of the program code of the actual interpreter as small as possible. This simplest approach is to interpret a pseudocode, which ideally is as similar as possible to the machine instructions of the target hardware. The processing speed of the interpreter is thus relatively high because the pseudocode is close to the machine language, while machine-independent program code can still be used. Memory accesses during interpretation can be monitored, but this is not mandatory. A slower solution, which is also somewhat more complicated in terms of programming logistics, is to split the interpreter into an offcard part (the ‘offcard virtual machine’) and an oncard part (the ‘oncard virtual machine’). This approach is taken by many current Java Card implementations. Its main advantages are reliable memory protection and complete hardware independence. However, dividing of the interpreter into oncard and offcard parts has drawbacks. It makes cryptographic protection mandatory for transferring programs between the two parts of the interpreter, since otherwise the oncard part of the interpreter could be deliberately caused to misbehave by using manipulated program code. The optimum technical solution is to have a complete interpreter in the smart card. This makes it possible to load any desired program into the card and run it without any risk to other programs located in the card. However, the code size of a full interpreter is so large that it will certainly take several years and several generations of smart card microcontrollers before this solution becomes widely established in the smart card world.