KerOS 6

Introduction

PKCS#11, also known as "Cryptoki," is a standard API for cryptographic tokens, defining a platform-independent interface to cryptographic devices such as hardware security modules (HSMs) and smart cards. This standard allows applications to interact with cryptographic hardware in a uniform manner, abstracting the details of the underlying hardware.

Purpose and Benefits

PKCS#11 serves as a critical component in securing cryptographic operations by leveraging hardware-based security. It provides a standardized way to:

Specifications

The PKCS#11 standard is maintained by the OASIS PKCS 11 Technical Committee. The latest specifications can be found on the OASIS PKCS 11 Technical Committee website.

PKCS#11 Tools & Documentation

PKCS#11 on Keros 6

On Keros 6, OP-TEE is used as a backend secure provider and provides a standard PKCS#11 module interface. The PKCS#11 module that interfaces with OP-TEE is located at /usr/lib/libckteec.so.0.

On Keros 6, Kerlink will use PKCS#11 module but it is not yet deployed. Therefore, for compatibility reasons, caution must be taken about modifications made to PKCS#11 slots. There are no issues to use it during development, but we must be careful in production.
The certificate /etc/certs/ztp.pem is used to authenticate with Kerlink services. This certificate will gradually be migrated to OP-TEE PKCS#11 module.

OP-TEE offers 3 slots by default. Kerlink will reserve use of slot 0. The other 2 slots will be free for use.

Example

Activation

To activate PKCS#11 module, you have to install pkcs11-tool with apt install opensc libp11. Once installed, you should be able to list PKCS#11 slot:

root@klk-wifc-030336:~# pkcs11-tool --module /usr/lib/libckteec.so.0 --list-token-slots
Available slots:
Slot 0 (0x0): OP-TEE PKCS11 TA - TEE UUID 15b45862-2ede-5c56-8899-7af9b86d1303
token state: uninitialized
Slot 1 (0x1): OP-TEE PKCS11 TA - TEE UUID 15b45862-2ede-5c56-8899-7af9b86d1303
token state: uninitialized
Slot 2 (0x2): OP-TEE PKCS11 TA - TEE UUID 15b45862-2ede-5c56-8899-7af9b86d1303
token state: uninitialized

You may also list the mechanisms supported by the OP-TEE PKCS#11 module using the command:

root@klk-wifc-030336:~# pkcs11-tool --list-mechanisms --module /usr/lib/libckteec.so.0

To use a PKCS#11 slot, it must first be initialized:

root@klk-wifc-030336:~# pkcs11-tool --module /usr/lib/libckteec.so.0 --slot 1 --init-token --label testtoken --so-pin 12341234
root@klk-wifc-030336:~# pkcs11-tool --list-token-slots --module /usr/lib/libckteec.so.0
Available slots:
Slot 0 (0x0): OP-TEE PKCS11 TA - TEE UUID e6f3ab90-1a46-58ff-a81c-4da2994fdcbd
  token label        : kerlink
  token manufacturer : Linaro
  token model        : OP-TEE TA
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 0.0
  firmware version   : 0.1
  serial num         : 0000000000000000
  pin min/max        : 4/128
Slot 1 (0x1): OP-TEE PKCS11 TA - TEE UUID e6f3ab90-1a46-58ff-a81c-4da2994fdcbd
  token label        : testtoken
  token manufacturer : Linaro
  token model        : OP-TEE TA
  token flags        : login required, rng, token initialized
  hardware version   : 0.0
  firmware version   : 0.1
  serial num         : 0000000000000001
  pin min/max        : 4/128
Slot 2 (0x2): OP-TEE PKCS11 TA - TEE UUID e6f3ab90-1a46-58ff-a81c-4da2994fdcbd
  token state:   uninitialized

The user PIN must also be initialized:

root@klk-wifc-030336:~# pkcs11-tool --module /usr/lib/libckteec.so.0 --slot 1 --label testtoken --login --so-pin 12341234 --init-pin --pin 12341234
User PIN successfully initialized

The token is now ready for use.

Generate asymmetric keys

We can now generate asymmetric keys, for example with EC keys:

root@klk-wifc-030336:~# pkcs11-tool --module /usr/lib/libckteec.so.0 --token-label testtoken --pin 12341234 --keypairgen --key-type EC:prime256v1 --label ecctest
Key pair generated:
Private Key Object; EC
  label:      ecctest
  Usage:      sign, derive
  Access:     sensitive, always sensitive, never extractable, local
Public Key Object; EC  EC_POINT 256 bits
  EC_POINT:   04410477229acf1d21d9cfdd1f7192a83b5f0a27fcec03642134bbf544ae693595645898c107fe7bbf462e317c5bcc7aaac1c23e3eedfe2dced8e788dff381b218a709
  EC_PARAMS:  06082a8648ce3d030107
  label:      ecctest
  Usage:      verify, derive
  Access:     local

Or with RSA-2048 keys:

root@klk-wifc-030336:~# pkcs11-tool --module /usr/lib/libckteec.so.0 --token-label testtoken --pin 12341234 --key-type rsa:2048 --keypairgen --label rsatest
Key pair generated:
Private Key Object; RSA
label: rsatest
Usage: decrypt, sign
Access: sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
label: rsatest
Usage: encrypt, verify
Access: local

Use with OpenSSL

We can also use the PKCS#11 module with OpenSSL. To do this, we need to configure OpenSSL to use the module. This can be done by specifying the PKCS#11 module to use in the configuration. For this, a special configuration file /etc/ssl/kerlink.cnf can be used when invoking OpenSSL.

This way, we can use OpenSSL engines by referring to the engine ID so that it uses the PKCS#11 module mentioned in its configuration. It should be noted that OpenSSL uses PKCS#11 URIs to refer to PKCS#11 objects, unlike pkcs11-tool which uses specific arguments. These URIs follow the format "pkcs11:xxxxxxxx" and adhere to RFC 7512.

For example, to refer to the keys we generated, we simply specify the following URI:

pkcs11:token=testtoken;object=ecc-primev1;type=private

As a result, to use the EC keys with openssl to generate for example a self-signed certificate:

root@klk-wifc-030336:~# export OPENSSL_CONF=/etc/ssl/kerlink.cnf
root@klk-wifc-030336:~# openssl req -new -engine pkcs11 -keyform engine -sha256 -key "pkcs11:token=testtoken;object=ecctest;type=private;pin-value=12341234" -sha256 -out test.pem -subj "/C=CB/O=ME/CN=CN"

To extract the public key:

root@klk-wifc-030336:~# openssl pkey -engine pkcs11 -inform engine -in "pkcs11:token=testtoken;object=rsatest;type=public" -pubout

Other usage

It is also possible to use PKCS#11 with other tools that support it, such as curl, openvpn, or strongswan. Keros basicstation also support using PKCS#11 URIs.