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
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.
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).
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 --------------------------------------------------
------------------------------------------------ end interruption --------------------------------------------------
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.
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.)
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.
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.
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
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
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.
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
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.
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.
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
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.
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.
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: |
|
|