Using OpenSC pkcs11-tool

It may be convenient to define a shell-level alias for the pkcs11-tool --module ... command. It may also be convenient to add the environment variable to point at the yubihsm_pkcs11.so library.

To accomplish all of the above for the Bash shell one would add the following lines to the ~/.bash_profile or ~/.bashrc file:

export YUBIHSM_PKCS11_CONF=/path/to/user/home/yhsm2-p11.conf
export YUBIHSM_PKCS11_MODULE=/usr/local/lib/yubihsm_pkcs11.so
alias yhsm2-tool='pkcs11-tool --module ${YUBIHSM_PKCS11_MODULE} --login'

The --login option was added because practically no operation of the HSM device can be performed without logging in to it first.

Assuming that:

  • RSA signing/verifying keypair has been generated with id 0x0401 and capabilities including asymmetric_sign_pkcs:asymmetric_sign_pss;

  • RSA encrypting/decrypting keypair has been generated with id 0x0402 and capabilities including asymmetric_decrypt_pkcs:asymmetric_decrypt_oaep;

  • ECDSA signing/verifying keypair has been generated with id 0x0203 and capabilities including asymmetric_sign_ecdsa:asymmetric_sign_decdsa

  • EC keypair for deriving ECDH keys has been generated with id 0x0204 and capabilities including derive-ecdh;

the following commands illustrate the use of OpenSC pkcs11-tool with YubiHSM for cryptographic operations.

Note that since pkcs11-tool can only perform private key-based cryptographic operations - i.e., it can decrypt a ciphertext or create a digital signature, but it can not encrypt a plaintext or verify a digital signature - OpenSSL is used to accomplish that.

The following files are used as samples:

  • t32.dat is a binary file containing 32 bytes;

  • t3200.dat is a binary file containing 3200 bytes;

  • t64.txt is a text file containing 65 bytes (64 ASCII characters and <CR>).

  • peer_key.der is a file containing an EC public key in DER format

Creating digital signatures

RSA-PSS

Sign a file using RSA-PSS padding with SHA-384:

yhsm2-tool --sign -m SHA384-RSA-PKCS-PSS --id 0401 -i t3200.dat -o t3200.dat.sig-pss
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using signature algorithm SHA384-RSA-PKCS-PSS
PSS parameters: hashAlg=SHA384, mgf=MGF1-SHA384, salt_len=48

and verify the created signature with OpenSSL (with libp11 PKCS#11 engine installed)

openssl dgst -engine pkcs11 -keyform engine -verify "pkcs11:token=YubiHSM;id=%04%01;type=public" -signature t3200.dat.sig-pss -sigopt rsa_padding_mode:pss -sha384 t3200.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for YubiHSM:
Verified OK
$

RSA-PKCS#1 v1.5

Sign a file using RSA-PKCS#1 v1.5 padding:

yhsm2-tool --sign --id 0401 -m SHA384-RSA-PKCS -i t3200.dat -o t3200.pkcs1.sig
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using signature algorithm SHA384-RSA-PKCS
openssl dgst -engine pkcs11 -keyform engine -verify "pkcs11:token=YubiHSM;id=%04%01;type=public" -signature t3200.pkcs1.sig -sha384 t3200.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for YubiHSM:
Verified OK
$

ECDSA

Sign a file using ECDSA with SHA-384 hash:

yhsm2-tool --sign --id 0203 -m ECDSA-SHA384 -f openssl -i t3200.dat -o t3200.ec384.sig2
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using signature algorithm ECDSA-SHA384
openssl dgst -engine pkcs11 -keyform engine -verify "pkcs11:token=YubiHSM;id=%02%03;type=public" -signature t3200.ec384.sig2 -sha384 t3200.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for YubiHSM:
Verified OK
$

Performing Decryption

RSA-PKCS#1 v1.5

Decrypt a file using RSA-PKCS#1 v1.5 padding:

cat t64.txt
4aa58c448f3264c777be1b5ad94cf3e0a68911ed3f18db9e568ff2179e263f76
yhsm2-tool --decrypt --id 0402 -m RSA-PKCS -i t64.txt.pkcs1
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using decrypt algorithm RSA-PKCS
4aa58c448f3264c777be1b5ad94cf3e0a68911ed3f18db9e568ff2179e263f76
$

RSA-OAEP

Decrypt a file using RSA-OAEP and SHA-384. The file t64.txt was encrypted with RSA-OAEP using SHA-384 for digest and Mask Generation Function (MGF):

cat t64.txt
4aa58c448f3264c777be1b5ad94cf3e0a68911ed3f18db9e568ff2179e263f76
yhsm2-tool --decrypt --id 0402 -m RSA-PKCS-OAEP --hash-algorithm SHA384 --mgf MGF1-SHA384 -i t64.txt.oaep
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using decrypt algorithm RSA-PKCS-OAEP
OAEP parameters: hashAlg=SHA384, mgf=MGF1-SHA384, source_type=0, source_ptr=0x0, source_len=0
4aa58c448f3264c777be1b5ad94cf3e0a68911ed3f18db9e568ff2179e263f76
yhsm2-tool --decrypt --id 0402 -m RSA-PKCS-OAEP --hash-algorithm SHA384 -i t64.txt.oaep
Using slot 0 with a present token (0x0)
Logging in to "YubiHSM".
Please enter User PIN:
Using decrypt algorithm RSA-PKCS-OAEP
OAEP parameters: hashAlg=SHA384, mgf=MGF1-SHA384, source_type=0, source_ptr=0x0, source_len=0
4aa58c448f3264c777be1b5ad94cf3e0a68911ed3f18db9e568ff2179e263f76
$

Derive ECDH Key

Derive an ECDH key using a private key on the YubiHSM and a public key read from a file.

yhsm2-tool --derive --input-file peer_key.der --id 0204
Logging in to "YubiHSM".
Please enter User PIN:
Using slot 0 with a present token (0x0)
Using derive algorithm 0x00001050 ECDH1-DERIVE
34a03079c38947a679a924f3e20657cd4f69dd36df395b7e759e727524da87dc
$

Obtaining Random Data

yhsm2-tool --pin xxxxxxxx --generate-random 64 | xxd -c 64 -p
Using slot 0 with a present token (0x0)
e3384c2a8f7263b46879d27d068779ebf82dfabe74bf057637a591a314dea86f12f35a79712950695dcbe54824eebe284430e942e1707991e315148e072d59f7
$

Acknowledgements

We would like to thank Uri Blumenthal (uri@mit.edu) for contributing to this document.