Trustway Crypt2pay
The Crypt2pay HSM integration is supported on Linux (x86_64). It has been tested with the following devices: BULL PKCS11 C2P 5.0.7 (Release) Unix64
How the KMS connects to the HSM
The KMS talks to the HSM exclusively through the vendor PKCS#11 library /lib/libpkcs11c2p.so.
Everything below the PKCS#11 API (the network channel to the HSM, TLS, the vendor key files)
is handled by that library, driven by the c2p.xml file that C2P_CONF points to
(default location when C2P_CONF is not set: /c2p/c2p.xml).
| Concern | Handled by | Configured in |
|---|---|---|
| Loading the library | KMS (/lib/libpkcs11c2p.so) | fixed path, see Copy the library |
| Slot login (PIN/password) | KMS, via PKCS#11 C_Login | hsm_slot / hsm_password (KMS config) |
.kdk and .ksk key files | Crypt2pay library, not the KMS | c2p.xml (KDKfile, KSKfile) |
| HSM certificate validation | Crypt2pay library, not the KMS | c2p.xml (SSLDefinition/authorities) |
| KMS certificate to the HSM (mTLS) | Crypt2pay library, not the KMS | c2p.xml (SSLDefinition/certificate, privateKey), see mTLS |
The .kdk and .ksk files
Per the Crypt2pay PKCS#11 API User Guide (§5), the PKCS#11 library protects the keys it stores with technical keys that are created on the Crypt2pay Key Management Centre (KMC) and distributed as files:
- KDK (key storage key): encrypts the RSA, ECDSA and (HSM firmware 8.05 and later) secret keys generated through
PKCS#11. It is distributed in a
.kdkfile (one per HSM), or on a smart card. - KSK (the
.kskfile carries the KMS storage key): only needed for secret keys generated with an HSM firmware older than 8.05. Optional on newer firmware.
At session opening the Crypt2pay library loads the KDK tokens from the .kdk file into the HSM (and the KMS key from the
.ksk file, if configured). With KDKintroduction set to start or login, it additionally asks for the KDK to be
inserted from a smart card through a PIN pad connected to the HSM, at C_OpenSession or C_Login time.
Smart-card insertion is meant for manually operated platforms and is not suitable for automated load-balanced setups.
The diagram below shows who owns what. The KMS process never touches the key files: the Crypt2pay PKCS#11 library, loaded in the KMS process, reads them from the KMS host filesystem and pushes them to the HSM.
flowchart LR
KMC["Crypt2pay KMC<br/>(HSM administrators)"]
subgraph HOST["KMS host"]
subgraph FS["Host filesystem (C2P_DIR)"]
XML["c2p.xml"]
KDK[".kdk file<br/>KDK key storage key"]
KSK[".ksk file (optional)<br/>KMS key, firmware below 8.05"]
SSL["ssl/ trusted CAs<br/>client cert and key (mTLS)"]
OBJ["token_objects/<br/>wrapped key store"]
end
subgraph PROC["KMS process"]
KMS["Eviden KMS<br/>slot, password only"]
LIB["libpkcs11c2p.so<br/>Crypt2pay PKCS#11 library"]
end
end
subgraph HSM["Crypt2pay HSM"]
MK["KM2bntx master key<br/>(never leaves the HSM)"]
KEYS["KDK and KMS keys loaded<br/>application keys in use"]
end
KMC -- "① generates and distributes" --> KDK
KMC -- "① generates and distributes" --> KSK
KMS -- "② PKCS#11 calls, C_Login" --> LIB
LIB -- "③ reads at session opening" --> XML
LIB -- "③ reads at session opening" --> KDK
LIB -- "③ reads at session opening" --> KSK
LIB -- "③ reads" --> SSL
LIB <-->|"stores and loads"| OBJ
LIB == "④ TLS, KDK and KMS tokens loaded<br/>then crypto operations" ==> KEYS
MK -. "decrypts the KDK tokens" .-> KEYS
Steps ① to ④: the administrators create the key files on the KMC and copy them to the host; the KMS only issues PKCS#11 calls; the library reads its configuration and key files when a session is opened; the library then opens the (optionally mutually authenticated) TLS connection, loads the KDK tokens into the HSM, and relays the crypto operations.
Consequences for the KMS:
- The files are generated by the HSM administrators on the KMC and copied to
[C2P_DIR]on the KMS host. The KMS never reads, loads, or transmits them to the HSM, and it has no configuration option for them. - The load therefore goes from the KMS host to the HSM, performed by the Crypt2pay PKCS#11 library, not by the KMS.
- The KMS performs no certificate handling for the HSM link. The KMS server's own TLS and client-certificate settings are unrelated to this link.
- The KMS opens the PKCS#11 session and logs in lazily, when the first session on a slot is opened.
With the special password
<NO_LOGIN>no login is performed. - If
c2p.xmlsetslogin User="<CommonName>",hsm_passwordmust be the user PIN; withUser="@"it must be of the formcommonname@PIN(PKCS#11 API User Guide, §4.2.2.4).
HSM files installation
Copy the Crypt2pay PKCS#11 library to /lib
Copy libpkcs11c2p.so to /lib.
Make sure it is readable by the user running the KMS.
Create the c2p directory
Create a c2p directory in, say, /etc/c2p (hereafter called [C2P_DIR])
In this directory copy the following files:
c2padmin<- The Crypt2pay admin toolc2p.xml<- The Crypt2pay configuration fileca.der<- The CA certificateinstallca<- The Crypt2pay CA installation toolp11tool<- The PKCS#11 tool used to test the connection- The files with extensions
.kdk(one per HSM) and.ksk(optional) <- The Crypt2pay key distribution files generated on the Crypt2pay KMC. They are only referenced fromc2p.xml; see The.kdkand.kskfiles
Install the CA certificate
This certificate is the one that signed the HSM certificate and will be used to authenticate the HSM.
In the [C2P_DIR], run the installca tool:
./installca -i ./ca.der ssl
This will create an ssl directory in the [C2P_DIR] and copy the CA certificate there.
To check that the CA certificate is installed correctly, run:
./installca -l ./ssl/
Edit the c2p.xml file and insert the full path to the CA certificate ssl directory in C2PConfig/SSLDefinition/authorities:
<C2PConfig>
...
<SSLDefinition>
<authorities>[C2P_DIR]/ssl</authorities>
</SSLDefinition>
...
</C2PConfig>
replace [C2P_DIR] with the actual path.
Set logging and Verify the c2p.xml file
In the c2p.xml file, set the logging to
<C2Pconfig>
<TraceLevel>debug functions parameters pkcs hsm</TraceLevel>
<TraceFile>+logs\c2p.trc</TraceFile>
...
</C2Pconfig>
Check the Crypt2pay manual (PKCS#11 API User Guide, §4.2.2) to make sure that other elements of the c2p.xml are correct, in particular:
C2PConfig/LocalKeyOwner(mandatory) andC2PConfig/LocalKeyIndex(optional, default00): identify the KDK used by the PKCS#11 library- the name of the
.kdkfile inC2PConfig/C2PSlot/KDKfile(can be overridden per HSM inC2PBox/KDKfile) - the name of the
.kskfile inC2PConfig/KSKfile: optional, only needed for secret keys generated with an HSM firmware older than 8.05 - the IP address of the HSM in
C2PConfig/C2PSlot/C2PBox/IP, andssl="on"on theC2PBoxelement to use TLS (port3001for TLS connections,2001for clear connections)
.. and recover the configured Slot ID(s) in the Id attribute of C2PConfig/C2PSlot.
Mutual authentication (mTLS)
The configuration above authenticates the HSM to the KMS host only. To also authenticate the KMS host to the HSM,
add the client certificate, its private key and its chain to the SSLDefinition section of c2p.xml
(PKCS#11 API User Guide, §4.2.2.3):
<SSLDefinition>
<authorities>[C2P_DIR]/ssl</authorities>
<certificate>[C2P_DIR]/ssl/client.pem</certificate>
<privateKey password="<KEY_PASSWORD>">[C2P_DIR]/ssl/client-key.pem</privateKey>
<certificateChain format="pkcs7">[C2P_DIR]/ssl/chain.der</certificateChain>
</SSLDefinition>
authoritiesis mandatory for both HSM authentication and mutual authentication.certificateandcertificateChainare only required for mutual authentication. DefiningprivateKeyis what turns mutual authentication on. PKCS#12 is also supported (format="pkcs12").- A password-protected private key must be in PEM format. The
passwordattribute can be plain text or encrypted in the file ({++AES}...,{AES256}...); see the manual for thecipherModeoptions. SSLDefinitioncan be set globally, perC2PSlot, or perC2PBox, the most specific one taking precedence.- The HSM must in turn trust the CA that signed this client certificate, and the client certificate's common name must be an authorized crypto user on the HSM. This is prepared on the HSM side with the Crypt2pay KMC and administration interface; see the User Handbook: Securing network communication with TLS protocol (§2.1 to §2.3).
The KMS is not involved in any of this: it is entirely configured in c2p.xml and handled by libpkcs11c2p.so.
Set the C2P_CONF environment variable to [C2P_DIR]/c2p.xml
export C2P_CONF=[C2P_DIR]/c2p.xml
replace [C2P_DIR] with the actual path.
Test the configuration
Run the p11tool tool to create a new 256-bit AES key:
./p11tool -genkey -keyalg aes -keysize 256 -shared /lib/libpkcs11c2p.so -slot 1 -verbose
The creation should be successful and print the key alias and ID:
use slot #1
Alias 'mykey' selected
Secret key #1000004 created
The logs are available in [C2P_DIR]/logs/c2p.trc.
KMS Configuration
When using the TOML configuration file, enable HSM support by setting these parameters:
hsm_model = "crypt2pay"
hsm_admin = "<HSM_ADMIN_USERNAME>" # defaults to "admin"
hsm_slot = [0, 0, ] # example [0,4] for slots 0 and 4
hsm_password = ["<password>", "<password>", ] # example ["648219", "648219"] for slots 0 and 4
NOTE:
hsm_slotandhsm_passwordmust always be arrays, even if only one slot is used.The order of the passwords must match the order of the slots in the
hsm_slotarray.If you want to login with an empty (null) password, use an empty string.
If you do not want to login, use the special password value
<NO_LOGIN>
Configuration via command-line
HSM support can also be enabled with command-line arguments:
--hsm-model "crypt2pay" \
--hsm-admin "<HSM_ADMIN_USERNAME>" \
--hsm-slot <number_of_1st_slot> --hsm-password <password_of_1st_slot> \
--hsm-slot <number_of_2and_slot> --hsm-password <password_of_2and_slot>
The hsm-model parameter is the HSM model. Use crypt2pay.
The hsm-admin parameter is the username of the HSM administrator.
The HSM administrator is the only user who can create objects on the HSM via the KMIP Create operation
and delegate other operations to other users.
The hsm-slot and hsm-password parameters are the slot number and user password (PIN) of the HSM slots used by the KMS.
These options can be repeated to configure multiple slots.
NOTE: To list available slots and keys run from the
[C2P_DIR]directory:./p11tool -list -shared /lib/libpkcs11c2p.so -verbose
Kubernetes (Helm chart)
Use an official KMS image unmodified (ghcr.io/cosmian/kms below, or ghcr.io/cosmian/kms-fips).
An init container copies libpkcs11c2p.so from a small client image and unpacks the [C2P_DIR]
configuration from a Kubernetes Secret. See the
Helm chart HSM overview.
Unlike other HSM libraries, the Crypt2pay library writes inside [C2P_DIR] at runtime: logs/ and
the objects directory (<ObjectsDirectory> in c2p.xml, for example QuickStart_<date>_p11/),
which stores the keys generated through PKCS#11, wrapped by the KDK. [C2P_DIR] is therefore a
PersistentVolumeClaim mounted read-write at /etc/c2p, and the KMS runs as a single replica
(replicaCount: 1, autoscaling disabled). Otherwise each pod would keep its own objects directory.
Validated on minikube against a live Crypt2pay with the values below, with the non-FIPS and FIPS images: HSM key creation, AES-GCM encryption and decryption through the KMS pod, and decryption with the same HSM key after the pod was deleted and recreated.
1. Crypt2pay client image
Build it once per library version. libpkcs11c2p.so links only against glibc (check yours with
ldd libpkcs11c2p.so). If yours lists other libraries, copy them into /opt/c2p/lib too and set
LD_LIBRARY_PATH to /usr/local/cosmian/lib/hsm:/opt/c2p/lib in extraEnv:
FROM debian:bookworm-slim
COPY libpkcs11c2p.so /opt/c2p/lib/libpkcs11c2p.so
2. Crypt2pay configuration in a Secret
Prepare and test [C2P_DIR] on a workstation as described above, with [C2P_DIR] = /etc/c2p.
Absolute paths under /etc/c2p are recommended in c2p.xml (Authorities, mTLS files,
TraceFile), e.g. <TraceFile>+/etc/c2p/logs/c2p.trc</TraceFile>; relative KSKfile and
ObjectsDirectory entries resolve under /etc/c2p. Lower TraceLevel (for example error):
debug traces grow by gigabytes and share the volume with the objects directory. Pack the
configuration, the installed CA tree and the key files into one archive (add <name>.ksk and the
mTLS client key file referenced by <privateKey>, if used):
cd /etc/c2p
tar -cf c2p-config.tar c2p.xml ssl <name>.kdk
kubectl -n kms create secret generic c2p-files --from-file=c2p-config.tar
kubectl -n kms create secret generic c2p-password --from-literal=password='<PIN>'
PersistentVolumeClaim for [C2P_DIR]:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: c2p-data
namespace: kms
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
3. Helm values
At each pod start, the init container refreshes the configuration on the volume and leaves the objects directory intact:
image:
repository: ghcr.io/cosmian/kms
tag: <version>
nodeSelector: {kubernetes.io/arch: amd64} # the crypt2pay model is Linux x86_64 only
replicaCount: 1
extraArgs: [--hsm-model, crypt2pay, --hsm-slot, "<slot>", --hsm-admin, admin]
extraEnv:
- name: CRYPT2PAY_PKCS11_LIB
value: /opt/c2p/lib/libpkcs11c2p.so
- name: C2P_CONF
value: /etc/c2p/c2p.xml
- name: KMS_HSM_PASSWORD
valueFrom:
secretKeyRef: {name: c2p-password, key: password}
initContainers:
- name: c2p-client
image: <registry>/c2p-client:<library-version>
command: [sh, -c, 'cp /opt/c2p/lib/* /c2p-lib/ && tar -xf /c2p-secret/c2p-config.tar -C /etc/c2p && mkdir -p /etc/c2p/logs']
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
volumeMounts:
- {name: c2p-lib, mountPath: /c2p-lib}
- {name: c2p-secret, mountPath: /c2p-secret, readOnly: true}
- {name: c2p, mountPath: /etc/c2p}
extraVolumes:
- name: c2p-lib
emptyDir: {}
- name: c2p-secret
secret:
secretName: c2p-files
defaultMode: 0440
- name: c2p
persistentVolumeClaim:
claimName: c2p-data
extraVolumeMounts:
- name: c2p-lib
mountPath: /opt/c2p/lib
readOnly: true
- name: c2p
mountPath: /etc/c2p
The pod must reach the HSM on TCP port 3001 (TLS).