808bits

OpenSC

read from source · 0.27.1 plus main · LGPL-2.1 · read at 4fab8b5, 2026-09-10

OpenSC is two things to a PKCS#11 user. Its module is the library behind most smart cards and USB tokens on Linux and macOS, and its pkcs11-tool is the command everyone runs first against any module, HSM vendors’ included. The module’s return values are not chosen where the failure happens. They are chosen in one translation function that maps the card library’s errors onto the specification’s, and the map has a default.

The translation function

Every card operation inside the module returns one of libopensc’s own error codes, of which errors.h defines 84. Before a code reaches the caller it passes through sc_to_cryptoki_error_common, a switch with about twenty-five cases. Wrong PIN becomes CKR_PIN_INCORRECT, a blocked PIN becomes CKR_PIN_LOCKED, a missing card CKR_TOKEN_NOT_PRESENT, a card pulled mid-operation CKR_DEVICE_REMOVED. The card’s “security status not satisfied” status word, which the ISO 7816 layer produces from 0x6982, becomes CKR_USER_NOT_LOGGED_IN. Everything the switch does not name falls through to line 122, which returns CKR_GENERAL_ERROR. That default is the finding. On OpenSC the general error does not mean the library is unusable. It means the card said something the translation table has no word for, which is around sixty of the 84 codes. The card’s own reason is in the debug log one line earlier, as a libopensc name and number. The PKCS#11 caller sees only the general error.

Three exceptions by function name

A small table in front of the switch (lines 37 to 42) overrides the mapping when the calling function is known. A PIN length problem during C_GenerateKeyPair is reported as the general error rather than the PIN code. A card refusing C_Sign or C_Decrypt with “not allowed” comes back as CKR_FUNCTION_FAILED, one of only five places in the module that returns that code at all. So the recoverable failure, on OpenSC, most often means the key on the card is not permitted to do what was asked of it. One line in the switch carries a comment. A detached reader maps to CKR_TOKEN_NOT_PRESENT with /* Maybe CKR_DEVICE_REMOVED ? */ beside it (line 114). The two codes have different pages on this site, and the person who wrote the mapping was not sure either.

What pkcs11-tool prints

The string that ends up in the search box comes from p11_fatal, which finalises the library and prints PKCS11 function C_Login failed: rv = CKR_PIN_INCORRECT (0xa0). The name is looked up in CKR2Str, a switch over 85 return values. A value it does not know, which is every vendor-defined one, prints as unknown PKCS11 error with the hex beside it. That hex is what the decoder on this site is for. pkcs11-tool --list-mechanisms is also the only widely installed tool I know of that prints the per-mechanism key sizes and operation flags from C_GetMechanismInfo (list_mechs), which is the half of the mechanism story the vendor pages here had to be probed for.

Return values with a note for this library

  • CKR_GENERAL_ERROR · Not a failed call but a broken library. The specification says nothing further will work, so retrying it is wasted effort.
  • CKR_FUNCTION_FAILED · A recoverable failure. The library is still usable and the token unchanged, so this one is worth investigating rather than restarting.
  • CKR_DEVICE_ERROR · The PKCS#11 catch-all for a token that has gone wrong. Usually a stale handle after a reset, a dead client link, or a mechanism the firmware refuses.
  • CKR_DEVICE_REMOVED · The library noticed the token disappear between one call and the next. Usually a pulled card, a USB power event, or a network HSM whose link reset under you.
  • CKR_PIN_INCORRECT · The credential was wrong. The important part is what your code does next, because automatic retries are how tokens get locked.
  • CKR_PIN_LOCKED · The token has locked the PIN after too many failed attempts. On most HSMs this is not something you can wait out, and on some it destroys the partition.
  • CKR_TOKEN_NOT_PRESENT · Better news than it looks: the slot identifier was right. On a network HSM this usually means the client cannot reach the partition rather than a missing card.
  • CKR_USER_NOT_LOGGED_IN · A private object needs an authenticated session. Often a login that happened on a different session, or one that a token event quietly ended.

How this page was made

Read from the source at the commit linked above, with every claim pinned to a line. Counts of return sites are from a search over the library's own code and are only as exact as a search can be. No mechanism table is shown, because there is no card on the machine this site is built from and the module lists no slots without one.

Scope. Read from the OpenSC repository at the commit named above, the main branch on the day this page was written and a few months after the 0.27.1 release. Counts of return sites are from searching the source under src/pkcs11 and are approximate. No mechanism table is shown, because there is no card on the machine this site is built from and the OpenSC module lists no slots without one.

Sources

  • OpenSC repository at 4fab8b5, OpenSC on GitHub. Read 2026-09-10. Used for the error translation, the pkcs11-tool output format and the return site counts.