PKCS#11 with YubiHSM 2 Reference

Configuration

The PKCS#11 module requires a configuration file, default location for this file is current directory and default name is yubihsm_pkcs11.conf using the environment variable YUBIHSM_PKCS11_CONF one can point to a custom location and name.

Configuration options can also be passed as a string in the pReserved field of C_Initialize, using the OpenSSL PKCS#11 engine this can be set in the INIT_ARGS configuration value. This is technically a violation of the PKCS#11 specification (which mandates pReserved to be set to NULL) and is not supported by all applications.

Accepted configuration options:

  • connector: URL pointing at the connector to contact, mandatory
  • debug: Turn on PKCS#11 debugging, default off
  • dinout: Turn on call tracing, default off
  • ibdebug: Turn on debug of libyubihsm, default off
  • debug-file: File to write debug information to, default stderr
  • cacert: File with cacert to verify connector https cert with (not available on Windows)
  • proxy: Proxy server for reaching the connector (not available on Windows)
  • timeout: Timeout to use for initial connection to the connector (in seconds), default 5

A Configuration File Sample can be found below.

Logging In

All interesting operations through the PKCS#11 interface require a logged-in session, and one peculiarity of the PKCS#11 interface is that the user PIN MUST be prefixed by the ID (16 bits, in hexadecimal, zero padded if required) of the corresponding Authentication Key.

Assuming the default Authentication Key with ID 1 and password password, the user PIN would then be 0001password. To be compliant with PKCS#11 standards, the Authentication Key password MUST be at least 8 characters long.

Note that the concept of a Security Officer (SO) is not supported by the device, and the PIN management functions are not implemented for neither user nor SO.

It is recommended that PIN (Authentication Key) management is performed via the yubihsm-shell utility or the libyubihsm functions.

PKCS#11 on Windows

After installing yubihsm-shell using the windows installer, in addition to setting YUBIHSM_PKCS11_CONF environment variable, the YubiHSM Shell\bin directory needs to be added to the system path in order for other applications to be able to load it. This is because the yubihsm-pkcs11.dll is dynamically linked to the libyubihsm*.dll and libcrypto-1_1.dll libraries and they need to be accessible for the PKCS#11 module to be useful.

On Windows 10, setting the system path is done by following these steps:

Step 1:Go to Control Panel > System and Security > System > Advanced system setting
Step 2:Click Environment Variables…
Step 3:Under System Variables, highlight Path and click Edit…
Step 4:Click New and add the absolute path to YubiHSM Shell/bin
Step 5:Under System Variables, click New and add the environment variable YUBIHSM_PKCS11_CONF and set it to the path to the YubiHSM2 PKCS11 configuration file

If setting the system path is not desirable, the libyubihsm*.dll and libcrypto-1_1.dll can be copied into the same directory as the application that needs to access the PKCS#11 module.

Note for Developers

If LoadLibrary is called with an absolute path, it will not look for dependencies of the specified DLL in that directory, but rather in the startup directory of the application that calls LoadLibrary. The solution is to either:

  • Call LoadLibraryEx with the flag LOAD_WITH_ALTERED_SEARCH_PATH for absolute paths
  • Add the directory where the PKCS#11 module is located to the system PATH
  • Or copy the dependencies into the application directory.

Please note that calling LoadLibraryEx with that flag for a non-absolute path is undefined behavior according to MS docs. For example, the way Pkcs11Interop does it is to set a variable to LOAD_WITH_ALTERED_SEARCH_PATH if the path looks absolute, and 0 otherwise; and then always calling LoadLibraryEx. If the flags is 0 then LoadLibraryEx behaves exactly like LoadLibrary.

Software Operations

C_Encrypt and C_Verify for Asymmetric Keys are performed in software, as well as all of the C_Digest operations.

PKCS#11 Attributes

There are a number of attributes defined in PKCS#11 that do not translate to Capabilities of the YubiHSM 2 device, and are therefore treated as always having a fixed value.

PKCS#11 YubiHSM 2 Rationale
CKA_PRIVATE CK_TRUE Login is always required
CKA_DESTROYABLE CK_TRUE
Objects can always be deleted from
the device
CKA_MODIFIABLE CK_FALSE Objects are immutable on the device
CKA_COPYABLE CK_FALSE Objects are immutable on the device
CKA_SENSITIVE CK_TRUE All objects are sensitive
CKA_ALWAYS_SENSITIVE CK_TRUE Objects are immutable on the device

Capabilities and Domains

Objects created via the PKCS#11 module inherit the Domains of the Authentication Key used to establish the session. The Domains cannot be changed or modified via the module.

Object Capabilities are set on creation, depending on their Type, e.g. an RSA signing key (CKK_RSA) created via C_CreateObject with the attribute CKA_SIGN set will have the following Capabilities set sign-pkcs,sign-pss.

Similarly for EC (CKK_EC), the key would have sign-ecdsa set.

See the following tables for mappings:

PKCS#11 RSA (CKK_RSA) EC (CKK_EC) Wrap (CKK_YUBICO _AES* _CCM _WRAP) HMAC (CKK_SHA* _HMAC)
CKA_ENCRYPT N/A N/A wrap-data N/A
CKA_EXTRACTABLE
export-under-wrap export-under-wrap export-under-wrap export-under-wrap
CKA_DECRYPT decrypt-pkcs, decrypt-oaep N/A unwrap-data N/A
CKA_DERIVE N/A derive-ecdh N/A N/A
CKA_SIGN sign-pkcs, sign-pss sign-ecdsa N/A sign-hmac
CKA_VERIFY N/A N/A N/A verify-hmac
CKA_WRAP N/A N/A export-wrapped N/A
CKA_UNWRAP N/A N/A import-wrapped N/A

PKCS#11 Objects

Not all PKCS#11 Object types are implemented, this is a list of what is implemented and what it maps to.

PKCS#11 Supported CKK Comment
CKO_CERTIFICATE  
Opaque object with algorithm
YH_ALGO_OPAQUE_X509
_CERTIFICATE
CKO_DATA  
Opaque object with algorithm
YH_ALGO_OPAQUE_DATA
CKO_PRIVATE_KEY CKK_RSA, CKK_EC
RSA 2048, 3072 & 4096 with
e=0x10001, EC with secp224r1,
secp256r1, secp384r1, secp521r1,
secp256k1, brainpool256r1,
brainpool384r1, brainpool512r1
CKO_PUBLIC_KEY  
does not exist in device, only
as a property of a private key
CKO_SECRET_KEY
CKK_SHA_1_HMAC,
CKK_SHA256_HMAC,
CKK_SHA384_HMAC,
CKK_SHA512_HMAC,
CKK_YUBICO_AES128
_CCM_WRAP,
CKK_YUBICO_AES192
_CCM_WRAP,
CKK_YUBICO_AES256
_CCM_WRAP
 

PKCS#11 Functions

Not all functions in PKCS#11 are implemented in the module, this is a list of what is implemented.

PKCS#11 Comment
C_CloseSession  
C_CloseAllSessions  
C_CreateObject
Use with CKO_PRIVATE_KEY, CKO_SECRET_KEY,
CKO_CERTIFICATE or CKO_DATA
C_Decrypt  
C_DecryptFinal  
C_DecryptInit Decrypt with Wrap Key or RSA key
C_DecryptUpdate  
C_DeriveKey Derive key using ECDH as a PKCS#11 session object
C_DestroyObject  
C_Digest  
C_DigestFinal  
C_DigestInit
Do software digest with CKM_SHA_1, CKM_SHA256,
CKM_SHA384 or CKM_SHA512
C_DigestUpdate  
C_Encrypt  
C_EncryptFinal  
C_EncryptInit
Encrypt with Wrap Key or do software encryption
for RSA key
C_EncryptUpdate  
C_Finalize  
C_FindObjects  
C_FindObjectsFinal  
C_FindObjectsInit  
C_GenerateKey Generate HMAC Key or Wrap Key
C_GenerateKeyPair Generate Asymmetric Key
C_GenerateRandom Generate up to 2021 bytes of random
C_GetAttributeValue  
C_GetFunctionList  
C_GetInfo  
C_GetMechanismList  
C_GetMechanismInfo  
C_GetObjectSize  
C_GetSessionInfo  
C_GetSlotInfo  
C_GetSlotList  
C_GetTokenInfo  
C_Initialize  
C_Login  
C_Logout  
C_OpenSession  
C_Sign  
C_SignFinal  
C_SignInit Sign with HMAC Key or Asymmetric Key
C_SignUpdate  
C_Verify  
C_VerifyFinal  
C_VerifyInit Verify HMAC or software verify asymmetric
C_VerifyUpdate  
C_UnwrapKey Unwrap an object with Wrap Key
C_WrapKey Wrap an object with Wrap Key

PKCS#11 Vendor Definitions

Working with the device Wrap Keys requires using vendor-specific definitions, these are listed in the table below. The Wrap Keys can be used with C_WrapKey, C_Unwrapkey, C_Encrypt & C_Decrypt.

Wrap Type Wrap Key
CKM_YUBICO_AES_CCM_WRAP 0xd9554204
CKK_YUBICO_AES128_CCM_WRAP 0xd955421d
CKK_YUBICO_AES192_CCM_WRAP 0xd9554229
CKK_YUBICO_AES256_CCM_WRAP 0xd955422a

PKCS#11 Configuration

Configuration File Sample

Below is a sample of a yubihsm_pkcs11.conf configuration file.

# This is a sample configuration file for the YubiHSM PKCS#11 module
# Uncomment the various options as needed

# URL of the connector to use. This can be a comma-separated list
connector = http://127.0.0.1:12345

# Enables general debug output in the module
#
# debug

# Enables function tracing (ingress/egress) debug output in the module
#
# dinout

# Enables libyubihsm debug output in the module
#
# libdebug

# Redirects the debug output to a specific file. The file is created
# if it does not exist. The content is appended
#
# debug-file = /tmp/yubihsm_pkcs11_debug

# CA certificate to use for HTTPS validation. Point this variable to
# a file containing one or more certificates to use when verifying
# a peer. Currently not supported on Windows
#
# cacert = /tmp/cacert.pem

# Proxy server to use for the connector
# Currently not supported on Windows
#
# proxy = http://proxyserver.local.com:8080

# Timeout in seconds to use for the initial connection to the connector
# timeout = 5

INIT_ARGS Sample

Below is a sample of using the INIT_ARGS configuration with an openssl.cnf file.

openssl_conf = openssl_init

[openssl_init]
engines = engine_section

[engine_section]
pkcs11 = pkcs11_section

pkcs11_section]
engine_id = pkcs11
dynamic_path = /path/to/engine_pkcs11.so
MODULE_PATH = /path/to/yubihsm_pkcs11.so
INIT_ARGS = connector=http://127.0.0.1:12345 debug
init = 0

Note

OpenSSL 1.1 will auto-load modules present in the system engine directory (like /usr/lib/x86_64-linux-gnu/engines-1.1) so the dynamic_path line has to be dropped there. The error shown will mention “conflicting engine id”.