Thursday, May 28, 2020

History

Since the beginning of pcsc-lite (at least since the first version of
pcsc-lite in 2002 that is in a Version Control System) only a subset of ASCII
was considered as legal characters for a PC/SC reader name.

In 2011 I added the character ";" in the list so that it is possible to use
the "&" sign (encoded as "&amp;" since the reader list is encoded as
XML in the Info.plist file). This was to support a reader name like "Giesecke
& Devrient".

Sponsors

They sponsor me for a total of $9/month. This number is NOT public but I want to be transparent with you. What you can see on my sponsor page is that I am "90% towards $10 per month goal". So after some mathematical calculation it is easy to get the $9/month.

Github also has the GitHub Sponsors Matching Fund. So half of that money comes from github/Microsoft. That is is first time I receive something from Microsoft 😀.

Results

The history

I don't know why this delay is needed. I went into the previous versions of the source code file PCSC/src/winscard_clnt.c but the oldest version (from March 2002, 18 years ago) already has this delay.

The code was written David Corcoran, the initial author of pcsc-lite. It was my very early days in the pcsc-lite project at that time.

The solution

I don't see any good reasons to have a delay here. I guess it was to solve a problem with the communication between pcscd and libpcsclite at that time. The communication mechanism has been redesigned in version 1.6.0 (May 2010) and the delay should now be useless and even problematic as we saw.

My solution is then to remove the problematic code. The was done in this commit.

The results

I used again my Python program to measure the performances of SCardEndTransaction(). I now have:

The mean delay is 9.5x10-6 s so 9 µs or 0.009 ms or 0.000009 second. The speedup factor is huge: x647.
The function is now 600 times faster than before.

You can note a high decrease on the 4 first values. My guess is that it is an effect of CPU memory caches in action. I have not investigated this point. This is left as an exercise for my readers.

Macro benchmark

It is nice to have a huge improvement in one PC/SC function but does that help real applications?

For a real smart card application I used OpenSC with a standard command: list all the objects of a smart card.
I used a very simple shell script:

#!/bin/bashfor i in {1..100}
do
pkcs11-tool --list-objects
done

Slow smart card

First I used a very old smart card I have in my collection: a Gemplus GPK 8000 card.
Since the card is very old and slow the shell script will do 10 rounds instead of 100.

what

time (s)

Before

23.34

After

22.84

Speedup: x1.02 or 2%

The gain is very limited. This is because the card is so slow that the benefit from the new SCardEndTransaction() is negligible.

Fast smart card

I then used a much faster smart card: a Yubikey 5 from Yubico. It is not a real smart card but a token with a CCID interface and a chip that understand APDU commands.
Since the device is fast I used 100 rounds of pkcs11-tool.

what

time (s)

Before

9.85

After

3.02

Speedup: x3.26 or 226%

This time the gain is highly visible. The pkcs11-tool command is now 3 times faster.

Results

You will get a high acceleration with fast smart card.
I was able to get a full execution of pkcs11-tool 3 (three) times faster than before the change.

I was really impressed by this result. For almost 10 years pcsc-lite was slow and could be improved by just removing 2 lines of code.

Potential regression?

I don't think this change will create a regression and will break existing code.

Friday, May 1, 2020

Lazarus

What is Lazarus?
Lazarus is a Delphi compatible cross-platform IDE for Rapid Application Development. It has variety of components ready for use and a graphical form designer to easily create complex graphical user interfaces.

License

The Pascal PC/SC Sample is freeware and can be used for any purpose.
By downloading the Pascal PC/SC Sample you agree to the terms of use.

The terms of use is different from the license available on the github project. For example the terms of use does not explicitly allow modification of the source code, and the use is allowed only for legal purpose. In general it is a bad idea to re-invent a new license text.

Installation

You copy the files MD_Events.pas, MD_PCSC.pas, MD_PCSCDef.pas, MD_PCSCRaw.pas and MD_Tools.pas.

Remarks

You will have to create a Form with a TMemo widget and a TButton widget. This part of the solution is not described here.

You click on the button and the program executes.

Output

Comments

High level API

I used the low level API provided in file MD_PCSCRaw.pas. These are direct equivalent of the WinSCard API. But a higher level API is also available and is provided in the file MD_PCSC.pas.

Unfortunately I was not able to find a way to get the list of connected readers with the high level API. Maybe I missed something (I am very new to Free Pascal). I reported the issue at make TPCSC.GetPCSCReaderList() a public method.

64-bits and GNU/Linux issue

A much more important issue is that this wrapper does not work on a 64-bits GNU/Linux system. I had to install a Debian system on a i386 CPU to write and test my code.

The problem is that the wrapper uses a Free Pascal type THandle to store the SCARDCONTEXT and SCARDHANDLE types. The problem is that a THandle in 32-bits on a 64-bits CPU but SCARDCONTEXT and SCARDHANDLE are 64-bits types on a 64-bits CPU using GNU/Linux.

The problem comes from the definition of long (DWORD) on a 64-bits CPU. On GNU/Linux a long is 64-bits. But on Windows a long is 32-bits only. If you want to have a 64-bits variable on Windows you need to use the long long type. This is because Linux is LP64 and Windows is LLP64. See 64-bit data models for more details.

The wrapper should work on macOS even on a 64-bits CPU. This is because Apple does not use any DWORD in the WinSCard API but int32_t instead.

Windows only?

As I already wrote in the introduction the, more recent, code available at https://github.com/ccy/pcsc is for Windows only. Some work is needed to make it available (again) for macOS and GNU/Linux.

Conclusion

If you use the Free Pascal language and you use Windows then this wrapper can help you.
If your system is not Windows or you want portability on diffrent systems then this wrapper may not be a good choice.