808bits

YubiHSM 2

read from source · 2.8.0 development · Apache-2.0 · read at b3ba0e8, 2026-09-10

The YubiHSM 2 is the small HSM that custody teams and CAs reach for when a rack unit is too much, and its PKCS#11 module is open source. The module speaks to the device through a connector process over HTTP, so the failures a caller sees are a mix of device answers and transport ones, translated in a single function. Two of its choices are worth knowing before the first C_Login.

The PIN is an address

C_Login on this module does not take a PIN. It takes the four hex digits of an authentication key id followed by that key’s password, parsed in C_Login with an optional @ or #label# prefix in front. A PIN whose first four characters are not hex is refused with CKR_PIN_INCORRECT before anything is sent to the device, so that code can mean “wrong format” as well as “wrong password”. The device’s own authentication failure and a cryptogram mismatch during session setup are mapped to the same code. There is no lockout in the module. Whatever retry policy exists is on the device.

Thirty-two device codes, one switch

yrc_to_rv translates every one of libyubihsm’s 32 result codes. A connector that cannot be reached is CKR_DEVICE_REMOVED, a connector with no device behind it is CKR_TOKEN_NOT_PRESENT, and a device that refuses for lack of capability is CKR_FUNCTION_REJECTED, which is one of the few libraries here to use that code at all. The device’s generic error becomes CKR_FUNCTION_FAILED and the switch’s own default is CKR_GENERAL_ERROR, which appears only nine times in the whole module. Outside a login, a device authentication failure is reported as CKR_DEVICE_ERROR.

Vendor constants that spell YUB

The module defines its vendor constants from a base of 0x59554200, which is the ASCII for YUB followed by a zero byte, OR’d with the device’s own algorithm or object type number (pkcs11y.h). So CKM_YUBICO_AES_CCM_WRAP is 0xD9554204 and CKM_YUBICO_RSA_WRAP is 0xD9554209, and the three CKK_YUBICO_AES*_CCM_WRAP key types follow the same rule. They are in the decoder here because the source is public. No other vendor on this site embeds its name in its numbers. The mechanism list is built at run time from the algorithms the device reports, so there is no observed table without a device. The code can offer 38 mechanism names, two of them Yubico’s own.

Vendor mechanisms with a published number

2 of the 2 vendor-defined mechanism names in the documentation come with a number somewhere in it. The rest are names only, so they cannot be matched to a value seen in a log.

MechanismHexDecimal
CKM_YUBICO_AES_CCM_WRAP0xD95542043646374404
CKM_YUBICO_RSA_WRAP0xD95542093646374409

Return values with a note for this library

  • CKR_SLOT_ID_INVALID · The library does not have that slot. Usually a number hard-coded from a machine where the enumeration came out differently.
  • 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_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.

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 module's own code and are only as exact as a search can be. No device was available, so the mechanism list, which the module builds from what the device reports, is not shown.

Scope. The main branch on the day of reading, a development version after the 2.7 release. The translation function has changed between releases before and may again. A device running older firmware reports fewer algorithms and so lists fewer mechanisms than the 38 the module knows.

Sources

Names and numbers only. No vendor documentation text is reproduced here.