About the SmartCard-HSM

Most smart cards compatible with OpenSC will offer only RSA 1024 bits key usage. Some will offer also RSA 2048 bits, but only very few do more. The OpenPGP card and the Cryptostick are known to be able to handle 4096 bits keys. However, the storage capacity of the OpenPGP is quite limited and the Cryptostick isn't available anymore (a new version is in beta, though).

Elliptic Curve Cryptography done on smart cards is very rare. And this is where the SmartCard-HSM stands out and it even works with OpenSC!

In this article I will only cover on initializing the tokend and usage of simple RSA keys, the usage on ECC is for a future post.


OpenSC 0.14 release fixed the use of EC keys with the SmartCard-HSM. Grab it in my PPA for Ubuntu: opensc-backports PPA Expect some update on this how-to soon.

OpenSC support in Ubuntu/Debian

Unfortunately not all of the patches have made it in OpenSC 0.13.0 for properly supporting the SmartCard-HSM. The first issue I've encountered was the inability to work with RSA keys of 2048 bits.

Here's my bug report and fix taken from upstream for that: LP Bug #1311921. Ubuntu Trusty (14.04) and up includes the fix for this in 0.13.0-3ubuntu4.1.

A similar issue is present for EC keys and requires OpenSC 0.14 for it to work. Ubuntu Vivid (15.04) and Debian Jessie will include 0.14, but for any current Ubuntu version you can install the backports I've compiled in my opensc-backports PPA.

For Debian support, the maintainer decided not to backport the fixes to Wheezy (7.x). The Jessie (8.x) release includes 0.14 and should be all fine.

Initializing the card

First, choose a SO-PIN of exactly 16 hexadecimal characters. It will be stored internally as an 8-byte key.

My recommendation is to store the SO PIN in a very safe place.

Secondly, make up a (user) PIN. It can be of any length from four up to sixteen ASCII characters with an important limitation listed below.


Some really big warnings here! Don't say I didn't warn you. Read them.

  • Any further reinitialization of the card will require you to enter the SO PIN. Unlike other smart cards or tokens, you cannot erase the card without the knowledge of the SO PIN!

  • The counter for wrong-entered SO PINs is 15 and is not unblockable. So, yes, entering the SO PIN wrong for 15 times renders the card unusable forever.

  • The initialization tool only takes SO PIN and PIN using command line arguments (opposed to reading from keyboard interactively). Any user on the system can see these secrets by doing a full process listing on the machine. You may want to run the initialization in an offline Live CD environment. Also, the full PINs will end up in your shell history. Bash allows you to omit this by prepending the command with a space.

  • Card versions up to 1.0 will not allow you to change this SO PIN ever again. To check your card version, run pkcs11-tool -L, e.g.:

    $ pkcs11-tool --module opensc-pkcs11.so -L
  • While the (User) PIN can be changed, it's not allowed to change it to another size (length). Andreas Schwier of CardContact confirmed this unfortunate restriction in private communication while noting that this holds for cards at least up to and including card version 1.2. Changing the size of the PIN currently requires reinitialization of the card (wiping its contents!).

Initialize using the sc-hsm-tool command shipped with OpenSC:

# prepend the command with a space to avoid saving in bash history
$  sc-hsm-tool --initialize --so-pin 0123012301230123 --pin abcdABCD12349876

Unfortunately, it's not (yet) possible to initialize the card using the more generic pkcs15-init tool.

Generating first keypair

To create an RSA keypair of 2048 bits (maximum size for SmartCard-HSM) use pkcs11-tool like this:

$ pkcs11-tool --module opensc-pkcs11.so -l --keypairgen --key-type rsa:2048 --id 10 --label "My first RSA keypair"

It will ask for your PIN and the keypair will be generated on-card. I've made up an ID and label here; choose your own.

To see the keypair listed, you could use

$ pkcs11-tool --module opensc-pkcs11.so --list-objects
Using slot 1 with a present token (0x1)
Public Key Object; RSA 2048 bits
label:      My first RSA keypair
ID:         10
Usage:      none

Note it lists Usage: none. This really should be something like Usage: encrypt, verify, wrap. I'm not sure what's going on here, but I am able to use the public key to encrypt data.

Obtaining the public key

$ pkcs15-tool --read-public-key 10 > /tmp/publickey.pem

where 10 is the ID of the object.

In case you see

error: object not found

you're probably hit by LP Bug #1311921. Install your system updates or if you're still running anything older than Trusty, scroll up and install the package from my PPA.

Encrypting and Decrypting data

RSA is not meant to encrypt/decrypt large amounts of data. 245 bytes is the maximum message length for a 2048 bits key as described in an earlier article: How to encrypt a LUKS container using a smart card or token.

  1. Create a random piece of data and hash it so we can identify it's the same later:

    $ dd if=/dev/urandom of=/tmp/mydata bs=1 count=245
    $ sha256sum /tmp/mydata
  2. Encrypt the data using the public key, in a PKCS#1 padding:

    $ openssl rsautl -inkey /tmp/publickey.pem -pubin -encrypt -pkcs -in /tmp/mydata -out /tmp/encrypteddata.pkcs1
  3. Decrypt the data again using the smart card:

    $ pkcs15-crypt --decipher --key 10 --input /tmp/encrypteddata.pkcs1 --pkcs1 --raw > /tmp/decrypteddata
    $ sha256sum /tmp/decrypteddata

More applications

Many many applications can be found for using any smart card or token. On some of them I have written (or will write later):

  • Disk encryption using LUKS
  • SSH publickey authentication
  • Set up your own PKI
  • OpenVPN
  • Second-factor in workstation login
  • E-mail encryption/signing
  • GnuPG
  • SSL Client authentication on web servers


Share on: TwitterHacker NewsFacebookLinkedInRedditEmail


comments powered by Disqus

Related Posts


Last Updated




Connect with me on...