Offshore Banking & Asset Protection

The world of Memory SmartCards

Memory SmartCard Programming

Buy Smart Cards books from Amazon

This article describes how to write and read data into one of the most common memory Smart Card, the GemPlus GPM2K, by means of one of the most common SmartCard reader: the GemPlus GemPC410. Read this article and *you* become an expert.

  • Updates
  • Forewords and acknowledgments
  • Objectives of this article and applications
  • SmartCard background
  • SmartCard readers
  • Prerequisites and literature
  • GemCore 1.21 operating system
  • Understanding commands
  • Reader commands to know
  • SmartCard commands to know
  • How to send commands to the reader
  • GemPlus Block Protocol (GBP)
  • Build the DLL
  • Notes about the source code
  • Examples in C++
  • Useful applications
  • Digital signature
  • Note about Windows 2000 and XP
  • Updates

    March 8th, 2004: my friend Luca S. from Rome helped me fixing a little bug.

    Forewords and acknowledgments

    First of all I want to thank Marco Monzani from Sweden, a great programmer that had the patience to introduce me to the world of SmartCard programming. Thanks Marco, without your guidance it would have taken much more time for me for this project to complete.

    Then I would say that developing Smart Card aware applications is simple, powerful, and cheap. It is as simple as reading this article, and it is powerful because you can add unique and impenetrable features to your critical apps; finally it is cheap, because a memory SmartCard is worth a buck (in limited quantities), and the SmartCard reader does not cost more than 60/70 bucks per unit.

    I have not been payed from GemPlus for publishing this article (although I wish they had !), I just choose GemPlus products because they are widespread, reliable and cheap.

    Objectives of this article and applications

    The objective of this article is to explain how to write data into a memory SmartCard and read it back again; then modify data, read it back again, and so forth.

    There is plenty of applications for this kind of operations, let's revise some together:

    • software protection: if you want to distribute software and don't want that copies of it might run without your permission, you can release your software together with a Smart Card, and the software won't run without the SmartCard inserted into the reader. This result is usually achieved by means of those expensive and obsolete parallel port hardware keys. Now you can get rid of hardware keys and just use cheap SmartCards ! You can also let the Smart Card expire at an exact date (see example below)
    • usage count: if you want to distribute software that the end user must pay according to its usage, just like Adobe and Kofax do, the SmartCard again is the cheapest solution. (Adobe and Kofax still sell their software with hardware keys, but they'd better turn to SmartCards)
    • identification: if you want to securely identify the SmartCard holder, i.e. the person that is using it, you can do it with a memory Smart Card
    • loyalty programs: if you want to release fidelity cards to people affiliated with some commercial organizations (bookstores, cinemas, etc.), the SmartCard, again, is the perfect solution
    • health cards: if you want to release a card to patients that are submitted to frequent health treatments, you can provide them with the SmartCard, which holds all of the patient's history and curing parameters
    • phone cards: you can sell phone cards that the user pay in advance
    Other applications are just limited by your immagination.

    See Useful applications to learn about implementing some of the applications described above.

    If you read this article you can build the DLL that you can use in your application software (directions and full win32asm code provided herein).

    SmartCard background

    A SmartCard is just the size of a credit card, it is robust and durable, and can be one of the following two categories:
    • memory SmartCard
    • microprocessor SmartCard
    In this article we will revise memory SmartCards, and in a future article we will see how to use microprocessor SmartCards for digital signature applications.

    A memory SmartCard, just as its name says, can be written to and can retain data up to ten years long, even if it is being held in a wallet for several consecutive months or left in a car under the summer hot sun all the day long.

    The memory SmartCard has its own chip built into the hard plastic foil, and use contacts to be connected to foreign hardware.

    The foreign hardware is usually a SmartCard reader that is actually used both for writing and reading purposes, even if it is always referred to as the "reader". We will talk about readers later.

    The main characteristic of any SmartCard, being it a memory or a microprocessor card, is its inherent security: it will never happen that any user can break the SmartCard defence against intrusions. The SmartCard prefers to destroy itself rather than to let somebody perform unauthorized access.

    The GemPlus GPM2K, the memory SmartCard that we will use in this project, can be read from anybody as many times as they want (up to 100.000 times, or 10 years) but if you want to write some data it is necessary to present the Card Security Code (CSC). This code is 24 bits long, and you have 3 chanches to present the correct code. At the 4th wrong CSC presented (being it consecutive or not) the card will reject any other CSC presentation, and it will never be written to again for the rest of its life even if the correct CSC is being presented again (the card can still be read, but it is no use).

    You have 3 chances among 16.777.216 to present the correct CSC. It is the same to say that anybody has no chance to force the GPM2K security.

    (Note: the GemClub Memo memory SmartCard is better for identification applications, in that it has a 32 bit long security code, the wrong code presentation counter gives 4 chances, and the counter is always resetted after the good code has been presented.)

    The autodefence characteristic can be proficiently utilized to implement any of the applications depicted above (software protection, usage count, identification, etc.).

    The SmartCard takes its power supply from the SmartCard reader: the operating system of the reader usually provides two system calls to power up and to power down the card at the beginning and at the end of its operations.

    GemPlus produces three very common memory SmartCards:

    • GPM2K: a 256 bytes memory card (released in 1996)
    • GPM8K: a 1kB memory card
    • GemClub Memo: a 256 bytes memory card (released in 1998)
    The technical data sheets for any of these cards can be easily obtained from GemPlus support service, which is fast and effective.
    ----------------------------------------------- page interruption --------------------------------------------------
    SUBLIMINAL AD:  
    ------------------------------------------------ end interruption --------------------------------------------------

    SmartCard readers

    There exists a wide range of SmartCard readers. A reader has always a slot into which a SmartCard can be inserted. It might also have one or more of the following additional features:
    • an internal memory
    • a LED
    • a LCD
    • a keypad
    • a buzzer
    • a realtime internal clock
    • a serial port
    • an USB port
    • additional SmartCard slots

    GemPlus reader model GemPC 410, the reader we will use in this project, has just a slot for a SmartCard, a LED, and a serial port connection cable. It takes its power supply from the PS2-type-plug of the PC keyboard connector. It is easy to install, and cheap.

    More complex readers, those that have LCD, keypad, buzzer, clock, etc., don't need to be connected to a PC to run an application: they have their own internal memory and can run standalone applications. These readers are called POS (Point Of Selling, because are mainly used in stores, or similar places where people pays with some kind of cards) and are not covered in this article.

    Prerequisites and literature

    For this project to implement you must be provided with the followings:
    • a GemPlus GemPC 410 SmartCard reader
    • a GemPlus GPM2K memory SmartCard
    • "GemCore V1.21-Based Reader Reference Manual Version 1.0, April 2000": this PDF file is an easy catch at GemPlus site; you shoud print and bind a copy of it, and keep it at hand because it is the reference of the operating system of the GemPC410 SmartCard reader
    Important note: the "GemCore V1.21-Based Reader Reference Manual Version 1.0, April 2000" is only a reference, and is *not* a complete document you can learn something from. But keep on reading: this article will give you sufficient information to let you understand the whole subject without problems.

    It is worth to say, whatever GemPlus Hotline could say, that figure 5 at page 9 in the GemCore V1.21-Based Reader Reference is wrong, in that it shows a serial connection between the reader and the SmartCard, and makes the programmer think that TLP and GBP are designed to talk to the SmartCard. This can't be more far from the truth. The correct figure is the following:


    fig. 1
    The truth is that the host communicates only with the reader by means of the serial communication port. Commands are sent to the reader in one of the available protocols (TLP or GBP, see below). Then it is the reader's own internal affairs how to communicate with the SmartCard, if necessary. (The reader actually communicates with the SmartCard through a complex series of electrical microsequences, but this is out of the programmer's reach and interest.)

    GemCore 1.21 operating system

    GemPlus does not explicity say what GemCore 1.21 is, but I've assumed it is sort of operating system for readers, and you can make this assumption too.

    Just like any operating system, GemCore 1.21 offers a set of system calls ("commands" from now on), specifically designed to support a wide range of different SmartCards and SmartCard readers.

    GemCore 1.21 O.S. has been adopted by many different readers, GemPC410 and POS included, and any reader that supports this operating system is usually referred to as a GemCore 1.21 based reader (or GBR for short).

    Any GemCore V1.21 command has the following format: a Command Code byte, followed by some optional Parameters, and followed by some Data (if necessary).

    Any GemCore V1.21 command returns the following: a Status byte followed by some Data (where appropriate). The status byte is always referred to as S, so please remember this. The complete list of possible status bytes is given at Appendix A in the GemCore V1.21-Based Reader Reference Manual, page 94. The reference manual does not say, but I am advising you here, that S=0 means that the command has been successfully completed.

    This is the complete list of GemCore 1.21 commands (an asterisk beside a command means that it will be explained here and will be used in the source code):

    • GBR configuration commands:
      • Restart (*)
      • Configure SIO line
      • Set mode
      • Set delay
      • Read firmware version (*)
      • Restart and run specified application
      • Deselect application
      • Set Reader in halt Mode
    • Card interface commands:
      • Common card interface commands:
        • Power down (*)
        • Define main card type (*)
        • Define type and set auxiliary card
        • Directory
        • Set operating mode
      • Specific commands for asynchronous cards, generic operating mode:
        • Power up
        • Change card communication parameters
        • ISO output
        • ISO input
        • Exchange APDU
        • Card status
      • Specific commands for asynchronous cards, EMV-compliant operating mode:
        • Power up
        • Exchange APDU
        • Card status
      • Specific commands for asynchronous cards in trasparent mode:
        • Change transparent mode parameters
        • Power up
        • Exchange block
        • Card status
      • Specific commands for synchronous cards:
        • Power up (*)
        • Read data (ISO out) (*)
        • Send data (ISO in) (*)
        • Exchange APDU
        • Card status
    • Reader memory management commands:
      • Read memory
      • Write memory
      • Erase flash memory
      • Select external memory page
      • Read CPU port
      • Write CPU port
    • LCD commands:
      • Init the LCD
      • Display character string
      • Display character
      • Send LCD command
    • Keypad and buzzer commands:
      • Set key press timeout
      • Sound buzzer
    • Realtime clock commands:
      • Read date and time
      • Update date and time
    • GemPC410 control commands:
      • GemPC410 set timeout
      • GemPC410 refresh
      • GemPC410 power down
      • GemPC410 LED management (*)
      • GemPC410 status
    You don't have to worry about all of these calls: only few of them are required to carry out this project. Many calls stand there for historical reasons, and most of them will never be used in simple PC applications.

    Understanding commands

    Reader commands are those of the reader's operating system (i.e. the GemCore V1.21 commands that we have just listed in the preceeding paragraph).

    SmartCard commands are specific to any SmartCard. The commands explained in this article are GPM2K specific (you can't use them with other SmartCards like the GPM8K or the GemClub Memo; refer to the command set of these SmartCards if you want to use them).

    Please keep *distinguished* reader commands from SmartCard commands.

    (All these commands are merely sequences of bytes.)

    The host can:

    • send reader commands to the reader
    • send SmartCard commands to the SmartCard

    Now pay attention: the host can send reader commands directly to the reader, but *cannot* send SmartCard commands directly to the SmartCard. Read this carefully: SmartCard commands must be sent to the reader, which in turn forwards the command to the SmartCard.

    Use ISO in or ISO out reader commands to forward SmartCard commands from the host to the SmartCard.

    ISO in and ISO out reader commands are used to send sequences of bytes (i.e.: SmartCard commands) to the SmartCard. ISO out also returns sequences of bytes out of the SmartCard. ISO in and ISO out reader commands are merely SmartCard command carriers.

    ISO in and ISO out reader commands, like any other reader command, receive the status byte S on return. The meaning of S is related to the ISO command that has been executed. Remember to *not* consider S as a return value from the SmartCard command that has been carried by ISO in or ISO out reader commands.

    Reader commands to know

    Now we will cover the details of those commands that will actually be used in the source code. These commands have been marked with an asterisk in the GemCore V1.21 operating system paragraph.

    • Restart
      • description: used to reset the GemPC410 reader to its default operating conditions:
        • 9.600 baud
        • 8 bit word
        • no parity
        • one stop bit
        • ROS command compatibility (ROS -Reader Operating System- is a former operating system for readers, don't care about this)
        • TLP mode (the GemCore V1.21-Based Reader Reference Manual does not say, but I guarantee you, that you can restart the reader and start sending commands in GBP mode as well)
        • no Halt Mode
        • blinking LED
      • command code: 0x0C
      • parameters: 0x00 0x00 0x00
      • return value: this command is the *only* command that, despite what I stated above, doesn't return S. Or, better, it returns S only if the command has gone wrong. If the command is properly executed no S is returned; we will discuss about this later
      • example: send the reader this sequence of bytes: 0x0C 0x00 0x00 0x00
    • Read firmware version
      • description: is not a strictly necessary command, but I used it just to play around with a simple command, and to check whether my code was properly working or not. I must say that once I was able to run "Read firmware version" command, then all the successive commands have been easy for me to implement
      • command code: 0x22
      • parameters: 0x05 0x3F 0xE0 0x10
      • return value:
        • S=0: the command has been properly executed
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • example: send the reader this sequence of bytes: 0x22 0x05 0x3F 0xE0 0x10
    • Disable ROS compatibility
      • description: is not mentionned in the GemCore V1.21-Based Reader Command Reference Manual, but I have copied it from a working example that Marco Monzani gave me. I must say that you can disable ROS compatibility or not, the GemPC410 reader is not affected by this command. Anycase I left it into my code, just to not waste the time to delete it
    • GemPC410 LED management
      • description: is a GemPC410 specific command. Actually there is no need to deal with the GemPC410 LED, you can leave it run for its own life. But from a coreographical standpoint it is better to make it appear steady green when the SmartCard is inserted into the reader, and to make it blink again when the SmartCard is removed
      • command code: 0x55
      • parameters: one byte, according to the following:
        • 0x00 turn off the LED
        • 0x01 turn on the LED
        • 0x02 blinking LED (default)
      • return value:
        • S=0: the command has been properly executed
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • example: if you want to turn on the LED you should send the reader the following two-bytes sequence: 0x55 0x01
    • Define main card type
      • description: tells the GemPC410 that the SmartCard inserted into its slot is a GPM2K
      • command code: 0x17
      • parameters: 0x09 (in the case of GPM2K)
      • return value:
        • S=0: the command has been properly executed
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • example: send the reader this sequence of bytes: 0x17 0x09 to tell that the SmartCard you are going to use is a GPM2K
    • Power up
      • description: used to let the reader feed the electrical power to the SmartCard *and* to detect the presence of the SmartCard into the slot of the reader.
      • command code: 0x12
      • parameters: none
      • return value:
        • S=0: the card is inserted into the slot of the reader, and has been powered up
        • S=0xFB: the card is not inserted into the reader
      • example: send the reader this byte: 0x12
    • Power down
      • description: used to let the reader power down to the SmartCard
      • command code: 0x11
      • parameters: none
      • return value:
        • S=0: the card has been powered down
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • example: send the reader this byte: 0x11
    • Send Data (ISO in)
      • description: use this command to send a sequence of bytes to the SmartCard
      • command code: 0x14
      • parameters: the sequence of bytes to send
      • return value:
        • S=0: the command has been properly executed
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • examples: see Present Card Secret Code, Write Data Area and Write Security Area
    • Read Data (ISO out)
      • description: use this command to receive a sequence of bytes from the SmartCard
      • command code: 0x13
      • parameters: none
      • return value:
        • S=0: the command has been properly executed
        • S>0: see "Appendix A, status codes", GemCore V1.21 reference, pag. 94
      • example: see Read Data Area

    SmartCard commands to know

    This is the list of the commands used in the source code:
    • Present Card Secret Code:
      • description: should be used prior to write something into the memory of the GPM2K SmartCard. Differently you can't write anything. You must present the correct CSC. If you present three times (consecutive or not) a wrong CSC then it will be refused forever, and you won't be able to write anything to the GPM2K forever
      • command format: 0x00 0x20 0x00 0x00 0x03
      • parameters: CSC1 CSC2 CSC3 (these are the three individual bytes of the 24-bit Card Secret Code. The default CSC, i.e. the CSC that the GPM2K comes with from the factory, is 0xAA 0xAA 0xAA)
      • how to execute this command: use the GemCore V1.21 ISO in reader command to send this command to the GPM2K
      • return value: none (S is referred to the "ISO in" command, not to "Present Card Secret Code" command)
      • example: to present the factory default CSC send the reader this string of bytes: 0x14 0x00 0x20 0x00 0x00 0x03 0xAA 0xAA 0xAA, and the reader will gently present the CSC to the GPM2K. The first byte (0x14) is the ISO in command code that tells the reader to forward the remaining bytes (0x00 0x20 0x00 0x00 0x03 0xAA 0xAA 0xAA) to the SmartCard
      • note: a return code S=0 to the "ISO in" command does not mean that the CSC that has been presented was OK: it only means that the "ISO in" command has been successfully executed, but you migth also have presended a *wrong* CSC. You will be aware that the correct CSC has been presented only when you will write some data into the memory of the SmartCard. And the only way to check whether a write operation has been correctly performed is to read the data back again and compare it with the original data
    • Write Data Area:
      • description: use this command to write a sequence of bytes into the memory of the GPM2K. You should have presented the correct CSC before writing, differently nothing will be written
      • command format: 0x00 0xD0 0x00
      • parameters:
        • memory address: one byte
        • number of data bytes to write: one byte
        • data bytes: as many bytes as declared
      • how to execute this command: use the GemCore V1.21 ISO in reader command to send this command to the GPM2K
      • return value: none (S is referred to the "ISO in" command, not to "Write Data Area" command)
      • example: to write the following two bytes 0x8F 0xDE at address 0x32 send the reader this string of bytes: 0x14 0x00 0xD0 0x00 0x32 0x02 0x8F 0xDE to the reader, and the reader will actually write the memory of the GPM2K (0x14 is the ISO in command code, 0x00 0xD0 0x00 is the Write Data Area command, 0x32 is the memory address, 0x02 is the number of data bytes to write, and 0x8F 0xDE are the data bytes)
      • note: a return code S=0 to the "ISO in" command does not mean that your data bytes have been actually written: it only means that the "ISO in" command has been successfully executed
    • Write Security Area:
      • description: use this command to set a new CSC. You should have presented the correct current CSC before setting the new CSC, differently the CSC will not be updated
      • command format: 0x00 0xD0 0xC0
      • parameters:
        • 0x01 (memory address of the CSC)
        • 0x03 (the CSC is 3 bytes long)
        • CSC1 CSC2 CSC3 (these are the three individual bytes of the new 24-bit Card Secret Code)
      • how to execute this command: use the GemCore V1.21 ISO in reader command to send this command to the GPM2K
      • return value: none (S is referred to the "ISO in" command, not to "Write Security Area" command)
      • example: to set this CSC: 0x34 0xBF 0x8A send the reader this string of bytes: 0x14 0x00 0xD0 0xC0 0x01 0x03 0x34 0xBF 0x8A, and the reader will set the new CSC into the SmartCard's Security Area (0x14 is the ISO in command code, 0x00 0xD0 0xC0 is the Write Security Area command, 0x01 is the address of the CSC, 0x03 is the number of bytes of the CSC, and 0x34 0xBF 0x8A is the new CSC itself)
      • note: a return code S=0 to the "ISO in" command does not mean that the new CSC has been actually set: it only means that the "ISO in" command has been successfully executed
    • Read Data Area:
      • description: use this command to read a sequence of bytes from the memory of the GPM2K. It is not necessary to present the correct CSC before reading
      • command format: 0x00 0xB0 0x00
      • parameters:
        • memory start address: one byte
        • number of data bytes to read: one byte
      • how to execute this command: use the GemCore V1.21 ISO out reader command to send this command to the GPM2K
      • return value: the requested sequence of bytes (you will see below that the sequence of bytes that have been read from the memory of the SmartCard is actually preceeded by S, that acknowledges or not the proper execution of the "ISO out" reader command)
      • example: to read ten bytes starting at address 0x32 send the reader this string of bytes: 0x13 0x00 0xB0 0x00 0x32 0x0A to the reader, and the reader will read the memory of the GPM2K for you (0x13 is the ISO out command code, 0x00 0xB0 0x00 is the Read Data Area command, 0x32 is the start address to read, and 0x0A is the number of bytes to read)
      • note: a return code S=0 to the "ISO out" command does not mean that the SmartCard memory has been actually read, in that it only means that the "ISO out" command has been successfully executed

    How to send commands to the reader

    Commands are actually sequences of bytes. Commands are sent to the reader using one of some simple protocols like TLP or GBP. We will use GBP in this project. GBP is explained in the next paragraph.

    Please note that there is an implementation of GBP distributed by GemPlus, it is the GBP Interface Library Kit that can be downloaded at GemPlus site. It is free, and it has been designed to be operating-system-independent. The library comes ready to be used in Linux. To use it in Windows you have to modify only one source file, the source C code that interacts with the operating system calls.

    I wasn't able to use it because I had problems in integrating the code in my Borland C++ Builder environment. So I decided to do it "my way" in the good old style: a win32asm DLL. I don't care about operating system independence, because I am only interested in Win32 and Linux. It would have been nice if the library kit had been language-independent, but it is only C, and there is no reason to develop C applications in Linux since Perl has been invented.

    GemPlus Block Protocol (GBP)

    The GemPlus Block Protocol (GBP for short) is a kind of elementary protocol used to send commands to the GBR (GemCore Based Reader) and receive the status code (S) and any eventual data from it. Any command is sent to the reader into a block, and any response from the reader is returned into another block.

    Three types of blocks are defined in this protocol:

    • I-Block (information block): holds the data to be sent from the host to the reader
    • R-Block (receive ready block): holds the data returned from the reader to the host
    • S-Block (supervisory block): not used in this project, I couldn't understand its purpose, forget about it
    Any block, being it an I-Block, an R-Block, or an S-Block, is a sequence of five fields:
    • NAD: a one-byte field used to identify the source and the destination of the block itself; the most significant nibble is the destination identifier, and the least significant nibble is the source identifier (0100b is the host, and 0010b is the reader); the NAD of an I-Block, a block that is sent from the host to the reader, is 0x24; the NAD of an R-Block, a block that is sent from the reader to the host, is 0x42
    • PCB: the format of this one-byte field depends on the type of block:
      • I-Block PCB:
        • bit 7: set to 0
        • bit 6: Sequence bit (see below)
        • bit 5: set to 0
        • bit 4: unused
        • bit 3: unused
        • bit 2: unused
        • bit 1: unused
        • bit 0: unused
      • R-Block PCB:
        • bit 7: set to 1
        • bit 6: set to 0
        • bit 5: set to 0
        • bit 4: sequence number containing the error
        • bit 3: set to 0
        • bit 2: set to 0
        • bit 1: error
        • bit 0: EDC error in the preceeding I-Block
      The Sequence bit (SB for short) in the PCB of I-Blocks is a one-bit sequence counter: if an I-Block sent from the host to the reader has SB=0, the next should have SB=1, the successive SB=0, and so forth. If you send two consecutive I-Blocks with the same SB the second block is not processed by the reader, and the reader itself returns an R-Block indicating a sequence error. This circumstance is favorable to determine which is the sequence bit to start with when restarting the reader (see the Restart command implementation). The procedure that I have implemented in my code is the following: guess a sequence bit number, say 0; then send the Restart command: if an error is signalled in the PCB of the R-Block coming from the reader then the guess was bad; if the reader does not respond anything in the next three seconds then the guess was correct (note: the reader not responding to Restart means that the Restart was good, in fact a good Restart is the only command that does not return S, and thus the host will never receive an R-Block of acknowledgement).
      The PCB of R-Blocks is capable of signalling some errors in the communication process (see bits 1 and 0). In this project we don't care the type of error, we just check whether the PCB of the R-Block is 10000000b or not: if yes then the last I-Block received from the host has been correctly received and processed.
    • LEN: a one-byte field indicating the length of the next field (DAT)
    • DAT: this field holds the data being transmitted (from/to the host)
    • EDC: a one-byte field used for checksum purpose: it is the XOR (eXclusive OR) performed over the NAD, PCB, LEN and DAT bytes; if the host transmits a block with a wrong EDC then bit 0 in the PCB of the R-Block returned by the reader is set

    Build the DLL

    My experiences with the GemPC410 and the GPM2k are enclosed in the DLL that I am going to introduce.

    The DLL is written in win32asm. The source code is given, and you must compile it yourself. To compile the DLL you must have MASM32 v.6 (or later) installed in your PC. You can download the free compiler at hutch's site.

    The source code is either well commented or self explanatory, but you can send me inquiries to help clarifying any instruction that (despite my efforts to make it clear) might result obscure.

    C++ programmers can write their own version of the DLL in C++, although this would result in complicating a simple thing.

    Commented C++ source code examples that utilize the DLL are also given in the next paragraphs.

    The DLL offers 13 built in functions:

    • FFGCR121StartComm: used to initialize the serial port. The function takes the following parameter:
      • (int) COM-port-number (from 1 to 4, no default)
      and returns 0 if the COM port has been properly initialized. Read the note about Windows 2000 and XP below if this function fails, and to understand the mechanism of port assignment in new releases of Windows
    • FFGCR121StopComm: used to disengage the serial port when your application program is finished using the SmartCard reader. This function takes no parameters and does not return any value
    • FFGCR121Reset: used to reset the GemCore V1.21-based-reader. This function takes no parameters, and returns an integer:
      • 0: the reader has been successfully resetted
      • 1: the reader does not respond for one of the following reasons: the reader is not connected to the proper serial port, is not powered, or is broken
    • FFGCR121FirmVers: used to read the firmware version number of the GemCore V1.21-based-reader. This function takes no parameters, and returns a pointer to an ASCIIZ string
    • FFGCR121DisRosComp: used to disable the ROS compatibility, unuseful
    • FFGPC410Led: used to control the GemPC410 LED. This function takes the following parameter:
      • (int) LED control number: valid values are the following:
        • 0: turn off the LED
        • 1: turn on the LED
        • 2: let the LED blink
      This function does not return any value
    • FFGPM2KSetCardType: used to tell the GemPC410 that the SmartCard that we have inserted into its slot is a GPM2K. This function takes no parameters and returns an integer: the status byte of the reader (S)
    • FFGPM2KCardPowerUp: used to check the actual presence of the SmartCard into the slot of the GemPC410, and to power up the card. This function takes no parameters and returns an integer: the status byte of the reader (S). Remember that S=0 means that the card is present and has been correctly powered up, but S=251 means that no card is inserted into the reader
    • FFGPM2KCardPowerDn: used to power down the SmartCard that we have inserted into the slot of the GemPC410. This function takes no parameters and returns an integer: the status byte of the reader (S)
    • FFGPM2KChkSecrCode: used to present the CSC to the SmartCard. This function takes the following parameter:
      • (char*) CSC (a three bytes string)
      This function returns an integer: the status byte of the reader (S)
    • FFGPM2KSetSecrCode: used to set a new CSC for the SmartCard. This function takes the following parameter:
      • (char*) new CSC (a three bytes string)
      This function returns an integer: the status byte of the reader (S)
    • FFGPM2KRead: used to read the memory of the GPM2K. This function takes the following two parameters:
      • (int) address of the 1st byte to read
      • (int) number of bytes to read
      and returns a pointer to a sequence of as many bytes as the number in the 2nd parameter: these bytes have been read in the memory of the GPM2K
    • FFGPM2KWrite: used to write the memory of the GPM2K. This function takes the following three parameters:
      • (int) address of the 1st byte to write
      • (int) number of bytes to write
      • (char*) pointer to a sequence of as many bytes as the number in the 2nd parameter
      and returns an integer: the status byte of the reader (S)

    Four files are required to build the DLL:

    • one ASM file that contains the data segment and the DLL entry point
    • one INC file that has to be included into the ASM file
    • one DEF file that contains the name of the DLL and the name of the functions that have to be exported
    • one BAT file that acts as the *makefile* for the DLL to build
    Remember that to build the DLL you should have MASM32 installed in your PC.

    Directions to build the DLL are the following:

    • make a working directory in your hard disk and name it GemCore. You will use this directory to keep the files ordered
    • cut this file and paste it into an ASCII file named FFGCR121.ASM
    • cut this file and paste it into an ASCII file named FFGCR121.INC
    • cut this file and paste it into an ASCII file named FFGCR121.DEF
    • cut this file and paste it into an ASCII file named MAKEDLL.BAT
    • run MAKEDLL.BAT and have the DLL done, together with its LIB import library file for static linking.
    If you want the FFGCR121.DLL already assembled and ready to use send a beautyful postcard from your town to:

    Alvise Valsecchi c/o HOCHFEILER
    via Monte delle Gioie 22 interno 3 - 00199 ROMA - ITALIA

    and don't forget to put your e-mail address to let me attach the DLL for you. Also put your own ordinary mail address if you want to receive a beautyful postcard from Rome, that I can send you.

    Notes about the source code

    Variables in the data segment prefixed with GBP are involved in the GBP protocol. Those prefixed with GCR121 are referred to the GemCore reader (V.1.21). Etcetera.

    GBP variables with one and two underscores are referred to, respectively, blocks that go from the host to the reader and from the reader to the host. Example: GBP_NAD is the NAD of blocks that are sent from the host to the reader, and GBP__NAD is the NAD of blocks that are sent in the opposite direction.

    The heart of the GBP protocol relies upon these three routines:

    • PREP_GBP_COMMAND (prepare GBP command): this routine prepares GBP_NAD, GBP_PCB, GBP_LEN, GBP_DAT and GBP_EDC, and put them alltogether at address GBP_Command, that represents the string of bytes to be sent to the reader; the number of bytes to be sent is GBP_LEN
    • SEND_GBP_COMMAND (send GBP command): this routine merely sends GBP_Command to the serial port; the experience has proven that there is no need to flush the buffer (FlushFileBuffers is commented)
    • RECV_GBP_RESPONSE (receive GBP response): reads one byte (GBP__NAD) from the serial port; then reads another byte (GBP__PCB); at each step these bytes are checked against unexpected values; then reads another byte (GBP__LEN); then reads GBP__LEN bytes of data; and finally reads one byte (GBP__EDC). Every read operation is subject to timeout. If a timeout is reached the reader is supposed to be not responding
    Nothing special about the rest of the code. I revised the code while preparing this web page: the code isn't perfect but is easy to read and, very important, it works.

    Examples in C++

    Now to the examples how to use the DLL. I use Borland C++ Builder 3 Professional Edition. You can use whatever you want, provided you make some minor changes that might occur depending on the C++ development tool that you are using.

    Add to your header the declarations in this file.

    The example code in this file is broken in 3 sections:

    • Section 1 - load the DLL and the addresses of its function calls: put this section into the constructor of the main form of the application program, or wherever you want, provided it is executed only once at program start
    • Section 2 - call the functions: an example is given for any function; useful ideas about using the functions are given in the next paragraph
    • Section 3 - unload the DLL: put this section into the destructor of the main form of the application program, or wherever you want, provided it is executed only once at program exit

    Useful applications

    Prepare a GPM2K SmartCard with your secret CSC: this is a prerequisite for implementing the next examples. You need a GPM2K with a CSC that is known only by you and your application software. This SmartCard will be given to your customer. Directions:
    • insert a GPM2K fresh from the factory into the GemPC410
    • initialize the serial port
    • restart the reader
    • set card type to GPM2K
    • check card presence and power it up
    • present the Card Secret Code (use FFGPM2KChkSecrCode, the CSC is 0xAA 0xAA 0xAA)
    • set a new CSC (use FFGPM2KSetSecrCode, invent your own CSC)
    • power off the card
    • free the serial port
    • remove the card from the reader and personalize it; don't write the CSC on the card itself, write something that reminds it to you instead; also write the name of the application program and, if useful, the name of the customer
    Software protection: to be used to let your program run only if a GPM2K SmartCard that you have prepared is inserted into the GemPC410 reader. Directions:
    • your customer inserts the GPM2K that you gave him into the GemPC410
    • your application program does the following:
      • initialize the serial port
      • restart the reader
      • set cart type to GPM2K
      • check card presence and power it up
      • present the Card Secret Code
      • write some data into the GPM2K and read it back again
      • compare the string that has been written with the string that has been read
      • if the comparison is not OK the application program exits
    Software protection with expiration date: same as the previous example, but the application program will only run before an expiration date that you have programmed. Directions:
    • prepare a GPM2K with a secret CSC
    • the application program should perform the same steps of the preceeding example and, in addition:
      • get the system date; use:
        
        LPTSTR lpDateStr;
        GetDateFormat ( LOCALE_SYSTEM_DEFAULT, 0, 0, "yyyyMMdd", lpDateStr, 32 );
        
        
      • compare it with the expiration date (EXP_DATE, that is written into the program itself in the following format: YYYYMMDD):
        
        int n = atoi ( lpDateStr );
        if ( n > EXP_DATE )
             {
               // if the program falls into this block the expiration date has 
               // come, and you just present 3 times a wrong CSC to invalidate 
               // the GPM2K forever
             }
        
        

    Identification of the card holder: your application program should let the user set her/his own PIN once, then it will be asked again at any time it will be necessary. Only the true card owner knows the PIN, of course. The PIN can be a number between 0 and 16.777.216 (the CSC is 24 bit long), but you'd better arrange for a seven-digits PIN between 0000000 and 9999999 (you could ask for a number between 0 and 16.777.216, but it appears to be more professional to ask a number from 0000000 and 9999999).

    Usage count: your application program can write a counter into the memory of the GPM2K, and decrement it any time it is required. It is impossible to put a different GPM2K into the reader and fake your application software, because to decrement the counter it is necessary to present the correct CSC.

    Digital signature

    I bought a couple of GemPlus GPK 16000, those SmartCards used for Public Keys criptography applications, and a friend gave me the Digital Signature SDK from GemPlus.

    As soon as I have time I will start experimenting with the digital signature, but I don't expect much from this kind of applications, because the digital signature process has some serious security holes that in some circumstances might vanish the the benefits of the signature itself.

    Note about Windows 2000 and XP

    If you install a GemPC410 reader in a Win95/98 PC you will read the Plug & Play message at startup: "New hardware found, blah blah blah". If you install a GemPC410 reader in a Win2000/XP PC, instead, you will not read any message, but something unexpected is being performed at startup: the device is *automatically* installed without asking you any permission.

    For this reason the serial port that the reader is connected to is being used by the operating system, and the FFGCR121StartComm function fails. This because Microsoft thinks that every application software should follow its rules and use the drivers provided by the operating system and nothing else.

    To overcome this problem print and distribute a copy of the following directions:

    • Start
    • right click Computer's Resources
    • click Properties
    • click Hardware
    • click Peripherals handling
    • select SmartCard reader from the hardware tree
    • uninstall it
    • close the windows that have been opened

        (end-of-this-article)

        Working with SCSI ? This is the book to buy:


         

        A DAY FOR HEARTS : Congenital
 Heart Defects Awareness Day
- Click here for details