Edward, a former vice president of Forth Inc., is a freelance programmer. He can be contacted at [email protected]
Smart cards (technically known as "Integrated Circuit Cards" or ICCs) are being promoted as a more secure and more capable replacement for existing magnetic-stripe cards, such as credit and debit cards. An ICC typically contains a low-power processor (such as the Hitachi H8/300) and up to 16 KB of memory (mostly EEPROM, with some RAM). An ICC makes secure off-line transactions possible, and is capable of supporting multiple applications -- credit, debit, stored-value cash, and the like -- on a single card.
Software has been a significant barrier to the growth of the smart-card market. In particular, the primary challenge has been the new requirement for supporting multiple applications on single cards and, more importantly, on the variety of relatively low-end point-of-sale (POS) terminals that accept the cards. These terminals typically have simple processors, such as a 6303 or 8051, and limited memory (128 KB or so, most of which is required for data storage). The multiple application problem cannot be solved easily just by adding memory; the POS terminal business is extremely competitive and cost-sensitive, and memory represents one of the largest cost components. There are two additional important constraints.
- Applications may be supplied by competing organizations and must be absolutely prohibited from interacting or accessing each other's data.
- It is expensive to write and certify a financial application, and it would be highly desirable to make an application independent of CPU and terminal type.
In 1995, Europay International (http://www.europay.com/), Europe's largest financial services organization, which handles MasterCard in Europe as well as numerous other card-based financial products, recognized the multiapplication, multiterminal problem and mounted an ambitious program to address it. The result is the "Open Terminal Architecture" (OTA), a published standard for terminal software backed by a family of software development tools. To prove the concept, Europay, together with Forth Inc. (http://www.forth.com/) and MPE Ltd. (http://www.mpe.co.uk/), produced a variety of terminal kernels and application programs. OTA was first demonstrated publicly at Europay's 1996 Members' Meeting in Seville, Spain, running two applications on six different terminal types. The first field prototypes have been operational since May 1997.
Open Terminal Architecture
As Figure 1 shows, the Open Terminal Architecture has three conceptual layers:
- The Virtual Machine (VM) is a common, theoretical 32-bit processor that is implemented on every terminal; it is discussed in detail in the following section. The code for the VM is terminal specific and highly optimized for the particular terminal on which it runs. The VM provides a set of services to programs provided and stored in token (bytecode) form. These are called "modules" (conceptually similar to Java applets). Modules are executed by a token interpreter in the VM. The VM manages actual terminal resources such as memory and peripherals for its client modules, which have no direct access to any terminal functions except via VM-provided services. The VM can run from PROM, and is intended to be sufficiently general to last for the product lifetime of the terminal (two to 10 years).
- The Terminal-Resident Services (TRS) module and its libraries, which are terminal specific but CPU independent and therefore may be tokenized. These are supplied as one or more token modules of a few KB each. The TRS provides higher-level services, such as host communications and user interface functions, to the actual applications. New versions of the TRS and/or its libraries, as well as all application modules, may be remotely downloaded to the terminal via a modem at any time. Thus, the terminal's functionality can be extensively modified without costly field PROM changes or lengthy downloads.
- Application modules, which represent specific card-handling and financial functions. For example, Visa Cash, Mondex, or Europay's CLIP (stored value) system would be supported by separate modules. Application modules are both CPU and terminal independent. This means that a given module need be written and certified only once, and will thereafter run without change on any certified OTA terminal. Only one application module can run at a time. It is selected and executed by the VM or TRS based on the card itself, user selection, or other means. The module is instantiated only when it is running; it is fully encapsulated, and can address only its own volatile data space. Even its databases are managed by the VM: A module logically accesses database(s) it owns only through VM requests, and the module itself has no knowledge of where a database actually is.
OTA is based on the Forth language, extended with commands to facilitate development of payment applications, in particular those compliant with a financial-transaction specification (usually referred to as EMV) developed by Europay, MasterCard, and Visa. Europay chose Forth because it provides a compact and efficient means of representing both terminal programs and the code that may reside on the ICC itself. The OTA architecture has been further modified for use with other programming languages; for example, it includes frame memory for local variables used in C. Both C and Forth compilers exist for OTA, and others may be added.
The OTA token set contains about 350 tokens, including about 250 1-byte tokens, each of which represents an instruction for the VM. The token set has three main components: low-level operations for arithmetic, stack management, flow-of-control, and so on (the great majority of these form a subset of ANS Forth); I/O and communications functions; and OTA-specific functions, such as databases, messages, and Tag-Length-Value (TLV) data formats used in ICC communications. Some tokens also have associated in-line values, for such things as literal values or address offsets.
Security is extremely important in financial applications. In addition to isolation of application modules in the terminal, all critical communications between the terminal and an ICC are encrypted using SHA or RSA algorithms. The latter requires modulo multiplication, shifting, and subtraction using numbers up to 1024 bits long. Achieving this with satisfactory execution time on simple 8-bit CPUs (the 8051, for example) required careful optimization, but eventually fell below Europay's maximum allowable security-verification time (one to three seconds, depending on key length).
Running an application involves two steps. First, the application token module is instantiated, meaning that it is assigned data storage space for its local variables, and links are established to any library routines it calls. Second, it is executed, which means that its tokens are interpreted by the VM. When the module finishes executing, its local data space is cleared for security reasons.
One of the services the VM and TRS jointly provide is maintenance of the module storage area, which is usually in extended memory. A utility is available in module form for downloading new modules, a process that is extremely quick since the average size is very small.
The OTA Virtual Machine
The basic architecture of the OTA Virtual Machine is conceptually similar to the Java Virtual Machine with bytecode applets. However, there are some significant differences:
- OTA is extremely compact, with most VMs running in 32 to 64 KB, and applications typically only a few thousand bytes in size. It is running today on production terminals with CPUs ranging from 8051s to 68xxxs and as little as 128 KB of total memory, with good performance on even the low-end devices.
- The OTA token (command) set is specifically optimized for smart-card applications, including not only general-purpose tokens for arithmetic, string handling, and the like, but also commands for managing card communication, databases, TLV data structures, cryptography functions, user-interface messages, and other application-specific functions.
- OTA is designed from the ground up to provide maximum security and isolation for multiple applications.
The entire OTA system is language independent. Both VMs and applications have been written in C and in Forth (a language designed specifically for embedded systems programming), and a Java compiler is under consideration.
Although OTA applies only to terminal software, Europay explored a similar VM approach for the ICCs themselves, and others are actively developing such VMs. The two most popular systems currently are JavaCard and MULTOS. Since the functions the ICC needs to execute (mostly data storage and retrieval) are much simpler than terminal functions, the card VMs and applications are correspondingly smaller. Typical sizes of 10 to 18 KB for JavaCard and 6 to 8 KB for MULTOS have been reported.
With VMs both on the card and in the terminal, it is theoretically feasible to pass not only data but also application code between the two. OTA includes functions that allow a card to download code to a terminal application, to be executed at predesignated points (sockets) in the application. Such code might be used to implement a loyalty reward, the exact form of which is determined by the downloaded code: That is, for cards issued by a certain bank, a terminal transaction could also post miles to the owner's frequent-flier account. For security and contractual reasons, the terminal application controls whether socketed code is allowed to execute, and both terminal and card application code undergo stringent testing and certification.
Virtual Machine Architecture
The OTA Virtual Machine is a byte-addressed, two's complement, 32-bit machine, with 32-bit registers. It is based on a multiple-stack architecture, as is usual in Forth; see Figure 2. OTA was carefully designed to keep applications separate, and so the VM employs the so-called "Harvard Architecture," with separate code and data spaces. The data, return, and exception stacks, although technically in data RAM, are not in accessible memory space and can only be managed through specific tokens. Code memory is used only by the VM kernel and is not available to token programs (which are handled as data); thus, code memory can be considered to be in ROM. Initialized data space is preset at compile time, and will be instantiated in the target at run time. Uninitialized data is similar but preset to binary zero. These data spaces, as well as extensible scratch memory and nonvolatile memory are available to token programs, but again only through specific tokens.
The VM kernel contains all of the functions whose implementation depends on a particular platform (CPU and sometimes a terminal operating system). Besides elementary functions such as arithmetic, stack support, and program flow control, the kernel includes a number of specialized OTA functions such as support for terminal-specific I/O and support for the token loader/interpreter, which manages the CPU-independent libraries and application modules. Most OTA kernels to date have been written in Forth, although some have been written in C. The reentrance capability inherent in the Forth language results in quite compact kernels, less than 32 KB for an 8-bit or 16-bit CPU.
The VM's registers are described in Table 1. The local variable frame requires two pointers to allow the traditional C calling sequences. Frames grow down in memory, matching the behavior of the majority of CISC processor machine stacks. How VM registers are mapped onto the target CPU architecture is up to the kernel implementer for that CPU. Although these registers are conceptually present, for security, no direct access is provided to them by the token set.
Most OTA tokens are single-byte (primary) tokens. A 1-byte prefix token allow a theoretical maximum of 65,536 tokens, regarding prefixes as defining pages of 256 tokens each (secondary tokens). In fact, only the primary 1-byte page and two (largely unfilled) secondary pages are needed.
Tables 2, 3, and 4 show some examples of tokens in each of the three major classifications. For convenience, tokens are named when they are defined, although they are processed solely as numerical values (shown here in hex; two values indicate a secondary token).
The code for the low-level tokens in a VM implementation is nearly all assembly, as is the code for most of the I/O and communications tokens. Assembly is used to optimize execution speed for commonly used tokens and/or because hardware is being accessed directly. Many of the OTA-specific tokens, on the other hand, are coded in high-level Forth for convenience; their relatively infrequent execution does not result in a serious performance penalty. The code for DBADDREC, for example, is shown in Example 1.
The code for DBADDREC checks to see if the file is ordered, and if it is, generates an exception. Otherwise it sets the parameter AVAILABLE (indicating the next available record number) to the end of the file, and calls the previously defined routine INSERT-RECORD, which actually performs the insertion.
Using OTA-specific tokens, the modularized and encapsulated application programs and supporting libraries are managed as individual data modules. One module may call another, but only at specific published entry points. Module code is written in terms of tokens, and modules have no way to access code space, which is private to the VM. Data space needed by an application may be of two kinds: local scratch data space, which is used during a transaction but erased when the transaction is completed, and databases used for long-term storage, such as transaction logs. Databases are managed by the VM as a server, which provides access to data in databases one record at a time, and only to the application that instantiated the database(s). The absolute location of a database is not known even to the application that owns it.
Memory requirements are somewhat flexible, but for good performance a terminal should provide:
- 32 KB of code space (ROM or RAM) for most 8-bit or 16-bit processors, more for 32-bit processors.
- At least 16 KB of local (directly accessible) RAM for both VM and module use during transaction processing. This is managed in several distinct regions: initialized memory for tables, and so on; uninitialized memory for VM buffers; extensible memory, allocated to modules on request using a rubberband management algorithm; and frame memory, to support C calling sequences. About half of this 16 KB is used by the VM.
- At least 64 KB of nonvolatile data storage (can be battery-backed extended memory, disk, or equivalent) for databases such as user messages and transaction logs.
- At least 32 KB (preferably 64 KB) of nonvolatile data storage for the modules themselves.
Although it is possible to use extended memory, flash, or even disk for database and module storage, the medium designated for this purpose can have a significant impact on performance. Writing flash, for example, is much slower than writing RAM, so data storage operations are slow. Similarly, executing modules in memory accessed only through lengthy mapping operations or OS calls is slower than from more directly accessible RAM. Vendors designing new terminals that will be used with OTA can make choices that will greatly enhance their performance, at relatively low unit cost.
Writing OTA Applications
OTA provides a token set that is rich in high-level functions and that greatly simplifies the task of writing smart-card applications. The token set not only provides standard operators for arithmetic, logical operations, flow-of-control structures, and so on, it also provides tokens for such advanced features as:
- Device control. Standardized tokens for functions such as open, close, read, write, error handling, and so forth.
- Database management. Defining databases with named fields, allocating and releasing records, and searching on keys, for example.
- Language and message handling. Management of a database of up to 255 messages in one or more languages, including tokens for adding and deleting messages or whole languages. Messages are accessed by number or name, which will always display the corresponding message in the language currently selected by the user.
- TLV services. EMV provides for standardized message handling between the terminal and card using ISO/IEC 8825 (1990) Basic Encoding Rules-Tag, Length, Value (BER-TLV or just TLV). TLV data structures may be quite complex. The OTA VM manages a global list of TLV tags defined by currently instantiated modules, along with tokens for parsing, reading, and writing these structures and individual items.
- Hot card list management. The VM can maintain an internal database of PAN (Primary Account Number) entries for blocked cards that is accessible only through tokens. These tokens provide for searching and other management functions such as "wild cards" (block an entire bank or country, for example).
- Cryptographic services. Several critical cryptographic functions are provided by the VM, including SHA and RSA algorithms and supporting subroutines; these complex functions are usually coded in assembler for optimum performance.
- Function sockets. The VM provides 64 "sockets," or execution vectors, that can be invoked during a transaction to execute a function whose details may be provided temporarily by the application, the TRS, or even the card itself. Provision is made for security checks around the "plugging" of a socket by an external module.
Library modules are available for high-level functions such as menu construction, report generation, communications protocols, and a library of all transaction steps defined in published financial specifications. As a result, applications tend to be short and easy to write.
The typical environment for OTA kernel and application development consists of a PC host connected to the target terminal with an interactive serial communications link. The software development of a multiapplication terminal under OTA takes place in several steps.
- 1. First the VM for that terminal is written by the manufacturer, certified by a party acceptable to all application issuers (Europay) and installed in that terminal's firmware. The VM itself cannot be tokenized, but must be physically installed. However, its lifetime is expected to match that of the terminal, seven to 10 years.
- 2. Next a tokenized and downloadable terminal program is written. This program is the terminal's outer loop, managing ICC insertion and application selection. Each tokenized application is written separately by its issuer and certified with a Reference Platform, a terminal emulator running on a PC, which has itself been previously certified to be OTA compliant.
- 3. Then the separate applications are downloaded to each OTA-compliant terminal as desired.
Example 2 is code for a sample application. The functions whose names begin with TRS- are provided in the terminal-specific TRS library; those beginning with EMV- or ICC- are from the Europay financial transaction library, and those beginning with MSG- are named messages which will be displayed in the language currently selected by users. Other functions have been previously defined in this application. As Example 2 illustrates, it is relatively simple to put together applications using these tested, high-level library functions.
To show how small resulting applications are, Table 5 lists the modules required to run an existing offline CLIP (stored value) application. The module named CLIP is the application; all the others are library modules that would also support another application. An online application would also require a communications protocol module; these are typically about seven KB in size.
Smart cards have enormously increased capability over current magnetic-stripe cards, but programming the wide variety of low-end terminals that accept them is difficult to do in a cost-effective way. The Open Terminal Architecture is an approach that converts all types of terminals into the same VM with a common set of bytecode token instructions. Using OTA, applications may be written, tested, and certified once for use on any OTA-compliant terminal. The published OTA standard includes provision for multiple competing applications in the terminal and/or on the ICC, and is carefully designed to keep applications from interacting. OTA is optimized for small size and fast execution, and has demonstrated successful operation of multiple applications on terminals as small as a 6303 processor with 128 KB of memory.
Although OTA was initially intended for financial applications, its token instruction set and associated features (such as database management) were designed to be general in nature, and easily support nonfinancial applications as well. If needed, extension of the token set to other specific application-related functions is relatively simple, particularly because the code for a token may be written in a high-level language such as Forth or C.
Copyright © 1998, Dr. Dobb's Journal