OpenSSL
This guide outlines step-by-step instructions for seamlessly integrating OpenSSL with a Luna HSM device or Luna Cloud HSM service. OpenSSL, an open-source project with a cryptographic library and SSL/TLS toolkit, provides powerful command-line tools for symmetric encryption, public-key encryption, and digital signing hash. Integration with Luna HSMs, powered by the Gem Engine, enables OpenSSL to efficiently access HSM resources, enhancing performance and security.
The key benefits of this integration are:
- 
Secure generation, storage, and protection of the identity signing private keys using either FIPS 140-2 or FIPS 140-3 Level 3 validated hardware. 
- 
Full life cycle management of the keys to ensure their integrity and reliability throughout their usage. 
- 
Maintenance of a comprehensive HSM audit trail for transparency and accountability in key operations. It's important to note that Luna Cloud HSM service does not have access to this secure audit trail. 
- 
Significant performance enhancements by offloading cryptographic operations from application servers. 
Supported platforms
This integration has been tested and verified on the following platforms:
Platforms supported by Luna HSM
| OpenSSL Toolkit | Platform Tested | 
|---|---|
| Luna OpenSSL Provider | RHEL 9 | 
| GemEngine 1.6 | Windows Server 2022 RHEL 9 RHEL 8 | 
| GemEngine 1.5 | Windows Server 2019 RHEL 9 RHEL 8 | 
| GemEngine 1.4 | Windows Server 2019 RHEL 8 | 
| GemEngine 1.3 GemEngine 1.2 | Windows Server 2019 Windows Server 2016 Windows Server 2012 R2 RHEL 7 | 
This integration been tested using Luna Client in both High Availability (HA) and FIPS-compliant modes.
Platforms supported by Luna Cloud HSM
| OpenSSL Toolkit | Platform Tested | 
|---|---|
| GemEngine 1.6 | Windows Server 2022 RHEL 8 | 
| GemEngine 1.5 | Windows Server 2019 RHEL 8 | 
| GemEngine 1.3 | Windows Server 2019 Windows Server 2016 RHEL 7 | 
Prerequisites
The prerequisites for this integration are:
Set up Luna HSM
As the first step to accomplish this integration, you need to set up either On-Premise Luna HSM or Luna Cloud HSM.
Set up on-premise Luna HSM
Follow these steps to set up your on-premise Luna HSM:
Ensure that the HSM is set up, initialized, provisioned, and ready for deployment. For more information, refer to Luna HSM documentation.
Create a partition that will be later on used by OpenSSL.
Create and exchange certificate between the Luna Network HSM and client system. Register client and assign partition to create an NTLS connection.
Initialize Crypto Officer and Crypto User roles for the registered partition.
Run the following command to verify that the partition has been successfully registered and configured:
/usr/safenet/lunaclient/bin/lunacm
Upon successful execution, you should observe an output similar to the example provided below:
lunacm (64-bit) v10.5.1-174. Copyright (c) 2022 Thales Group. All rights reserved. Available HSMs: Slot Id -> 0 Label -> TPA01 Serial Number -> 1312109862206 Model -> LunaSA 7.7.1 Firmware Version -> 7.7.1 Bootloader Version -> 1.1.2 Configuration -> Luna User Partition With SO (PW) Key Export With Cloning Mode Slot Description -> Net Token Slot FM HW Status -> Non-FM
Refer to Luna HSM documentation for detailed steps on creating NTLS connection, initializing the partitions, and assigning various user roles.
For proper configuration of a PED-based Luna HSM, it is recommended to activate partition policies 22 and 23, allowing for both activation and auto-activation.
Set up Luna HSM high-availability group
Refer to Luna HSM documentation for HA steps and details regarding configuring and setting up two or more HSM boxes on host systems. You must enable the HAOnly setting in HA for failover to work so that if the primary goes down due to any reason, all calls get automatically routed to the secondary until the primary recovers and starts up. 
Set up Luna HSM in FIPS mode
To configure Luna HSM in FIPS Mode, it's important to ensure that your RSA key generation methods comply with FIPS 186-3/4 standards. Specifically, FIPS 186-3/4 approves two methods for generating keys: 186-3 with primes and 186-3 with aux primes. This means that RSA PKCS and X9.31 key generation methods are no longer allowed when operating your Luna HSM in a FIPS-compliant mode. When using the Luna HSM in FIPS mode, you should make adjustments to your configuration settings by following these steps:
Open the configuration file for your Luna HSM.
Look for the [Misc] section within the configuration file.
Add or modify the following setting within the [Misc] section:
RSAKeyGenMechRemap=1
This setting instructs the Luna HSM to redirect older key generation mechanisms to the newly approved mechanism when the HSM is operating in FIPS mode.
This adjustment is not necessary for the Universal Client.
This configuration change applies exclusively to Luna Client 7.x.
Set up Luna Cloud HSM
Follow these steps to set up your Luna Cloud HSM:
Transfer the downloaded .zip file to your client workstation using pscp, scp, or other secure means
This integration has been certified on the RHEL platform.
Extract the .zip file into a directory on your client workstation.
Extract or untar the appropriate client package for your operating system. Do not extract to a new subdirectory; place the files in the client install directory.
tar -xvf cvclient-min.tar
Run the setenv script to create a new configuration file containing information required by the Luna Cloud HSM service.
source ./setenv
To add the configuration to an already installed UC client, use the –addcloudhsm option when running the setenv script.
Run the LunaCM utility and verify that the Cloud HSM service is listed.
If your organization requires non-FIPS algorithms for your operations, ensure that the Allow non-FIPS approved algorithms check box is checked. For more information, refer to Supported Mechanisms.
Set Up OpenSSL Toolkit for Luna Provider
Download the OpenSSL toolkit with Luna Provider support from the Thales GitHub repository. Before proceeding, ensure you are familiar with OpenSSL. For more information, see the OpenSSL documentation.
To use PQC algorithms, you must have Luna Client version 10.9.0 or later and Luna HSM Firmware version 7.9.0 or later. Firmware 7.9.0 supports MLKEM and MLDSA only. If your HSM firmware is below version 7.9.0, upgrade to FW 7.9.0 or refer to the Luna PQC FM Integration Guide for PQC algorithm support.
Set up OpenSSL toolkit with Gem Engine support
To set up the OpenSSL toolkit with Gem Engine support, download it from the Thales Customer Support Portal, ensuring it includes the appropriate Gem Engine version for your environment. You can also download the toolkit from the Thales GitHub repository if you plan to compile and build the Gem Engine yourself.
The following versions are available from the Customer Support Portal:
- 
GemEngine v1.6 — Doc ID KB0026742 
- 
GemEngine v1.5 — Doc ID KB0024584 
- 
GemEngine v1.3 — Doc ID KB0017806 
- 
GemEngine v1.2 — Doc ID KB0016309 
Before proceeding, ensure you are familiar with OpenSSL usage and configuration. For more details, see the OpenSSL Documentation.
You can use either the Luna Provider or the Gem Engine based on your requirements. However, starting with OpenSSL 3.2.x, the Engine framework is deprecated and the Provider is the recommended option.
Integrating Luna HSM with OpenSSL using Luna Provider
To integrate Luna HSM with OpenSSL using the Luna Provider, perform the following steps according to your environment configuration:
- 
Verify the OpenSSL and Luna HSM Integration Using Classic Algorithms 
- 
Verify the OpenSSL and Luna HSM Integration Using PQC Algorithms 
Install and configure the OpenSSL toolkit
To install and configure the OpenSSL toolkit on UNIX, choose one of the following scenarios based on your requirements:
- 
Scenario A: Compile the Luna Provider for integration with an existing installation of OpenSSL 
- 
Scenario B: Compile and install OpenSSL from source, then compile and install the Luna Provider 
- 
Scenario C: Configure OpenSSL to enable the Luna Provider by default 
Scenario A: Compile the Luna Provider for integration with an existing installation of OpenSSL
Ensure that your system has a C compiler installed and access to the make utility.
Follow these steps to compile the Luna Provider against an existing OpenSSL installation:
Download the version that is closest to your existing OpenSSL installation. For example, if you have OpenSSL v3.4.0 installed, download any OpenSSL v3.4.x release (where x can be any number).
# tar xvfz openssl-x.x.x.tar.gz
Clone the liboqs repository and check out the required version.
# git clone https://github.com/open-quantum-safe/liboqs # cd liboqs/ # git checkout -b 0.12.0 0.12.0
Navigate to the OpenSSL Luna Provider toolkit directory and run the following command:
# ./gembuild locate-providers

Note the OpenSSL providers directory displayed. You will use this path as input for the next step.
Configure the Luna Provider with the appropriate paths:
./gembuild config --openssl-source=<Path to extracted OpenSSL source directory> --openssl-providers=<Path to provider directory from step 3> --liboqs-source=<Path to liboqs source from step 2> --liboqs-prefix=/usr/local --config-bits=64
Example:
./gembuild config --openssl-source=/home/marif/openssl-3.4.1 --openssl-providers=/usr/lib64/ossl-modules --liboqs-source=/home/marif/liboqs --liboqs-prefix=/usr/local --config-bits=64
Note: If the OpenSSL development package is not already installed on the system, you must install it before proceeding. By default, OpenSSL headers and libraries are assumed to be located in /usr/include and /usr/lib64. If they are installed in a custom location, use the --openssl-includes and --openssl-libs options to specify the absolute paths to the header and library directories (where libcrypto.so is available). In addition, the gembuild script provides the option --openssl-api=<major> to indicate the major version of OpenSSL, for example --openssl-api=3.0 or --openssl-api=1.1.1. Any version of OpenSSL later than 3.2 uses the 3.2 API.
Build and install liboqs.
# ./gembuild liboqs-build # ./gembuild liboqs-install
Build and install the OpenSSL Luna Provider.
# ./gembuild provider-build # ./gembuild provider-install
Build and install sautil. By default, the sautil utility installs at /usr/local/bin/sautil. If a customized location is required, specify it with the --sautil-prefix option, or provide the option directly with the install command.
# ./gembuild sautil-build # ./gembuild sautil-install
Verify Luna Provider integration with OpenSSL.
# openssl list -provider lunaprov -provider default -providers

Scenario B: Compile and install OpenSSL from source, then compile and install the Luna Provider
Follow these steps to build OpenSSL from source and then build the Luna Provider against it.
Download openssl-x.x.xx.tar.gz from OpenSSL Source and extract it.
# tar xvfz openssl-x.x.xx.tar.gz
Clone the repository and check out the required release.
# git clone https://github.com/open-quantum-safe/liboqs # cd liboqs/ # git checkout -b 0.12.0 0.12.0 # cd ..
Extract the toolkit, navigate to its directory, and run gembuild config with a prefix for installation.
./gembuild config --openssl-source=<path to extracted OpenSSL source> --liboqs-source=<path to liboqs directory> --prefix=/usr/local --liboqs-prefix=/usr/local --config-bits=64
Example:
./gembuild config --openssl-source=/home/marif/openssl-3.4.1 --liboqs-source=/home/marif/liboqs --prefix=/usr/local --liboqs-prefix=/usr/local --config-bits=64
If the OpenSSL development package is not already installed, install it before continuing. By default, OpenSSL headers and libraries are assumed to be in /usr/include and /usr/lib64. If they are in custom locations, specify them with the --openssl-includes and --openssl-libs options (absolute paths required). The gembuild script also supports the --openssl-api=<major> option to indicate the OpenSSL API version (e.g., --openssl-api=3.0 or --openssl-api=1.1.1). Versions later than OpenSSL 3.2 use the 3.2 API.
Build and install liboqs.
# ./gembuild liboqs-build # ./gembuild liboqs-install
Build and install OpenSSL.
# ./gembuild openssl-build # ./gembuild openssl-install
Build and install the OpenSSL Luna Provider.
# ./gembuild provider-build # ./gembuild provider-install
Build and install the sautil utility. By default, sautil is installed at <prefix>/sautil/bin/sautil where <prefix> is the directory specified with the --prefix option in Step 3.
# ./gembuild sautil-build # ./gembuild sautil-install
Update environment variables. Add OpenSSL and sautil to your PATH, and add the OpenSSL library path to LD_LIBRARY_PATH.
# export PATH=/usr/local/ssl/bin:/usr/local/sautil/bin:$PATH # export LD_LIBRARY_PATH=/usr/local/ssl/lib:$LD_LIBRARY_PATH
Verify Luna Provider integration with OpenSSL.
# openssl list -provider lunaprov -provider default -providers

Scenario C: Configure OpenSSL to enable the Luna Provider by default
Follow these steps to configure OpenSSL so that the Luna Provider loads automatically without requiring the -provider flag.  
Run the following command to identify the OpenSSL configuration directory:
# openssl version -d
Example output:
OPENSSLDIR: "/usr/local/ssl"
This command reflects the OpenSSL version that is active in your PATH. Run which openssl to confirm that you are referencing the correct binary and configuration file.
Edit the openssl.cnf file to include Luna Provider configuration. Add the following lines:
At the very beginning of the file:
openssl_conf = openssl_init
Then scroll to the section [openssl_init] (or create one if it doesn’t exist) and configure it as follows:  
[openssl_init] providers = provider_sect [provider_sect] lunaprov = lunaprov_sect default = default_sect [default_sect] activate = 1 [lunaprov_sect] activate = 1
If you explicitly activate any other provider (for example, the Luna Crypto Provider), you must also explicitly activate the default provider. Otherwise, the default provider becomes unavailable in OpenSSL. This can cause applications that rely on OpenSSL to malfunction, potentially leading to system-level issues, including loss of remote access.
Run the following command without specifying any provider:
# openssl list -providers
Example output:
Providers:
  default
    name: OpenSSL Default Provider
    version: 3.2.2
    status: active
  lunaprov
    name: Thales Luna Provider
    version: 1.7.0
    status: active
If the output shows both default and lunaprov as active, the Luna Provider is configured to load by default.  
Generate a certificate request without specifying the provider:
# openssl req -out CSR.csr -new -newkey mldsa44 -nodes -keyout privateKey.key
If the private key and certificate request are successfully created on the Luna HSM without referencing a specific provider, the Luna Provider is active by default.
Configure Luna Provider to use Luna HSM on Unix
To configure the OpenSSL Luna Provider to use a Luna HSM on UNIX, update the configuration file and establish a session with the HSM.
Open the /etc/Chrystoki.conf file and add the following section:
GemEngine = {
   LibPath64 = /usr/safenet/lunaclient/lib/libCryptoki2_64.so;
   LibPath = /usr/safenet/lunaclient/lib/libCryptoki2.so;
   DisableEcdsa = 0;
   DisableEd = 0;
   DisableEm = 0;
   DisablePqc = 0;
   IncludePqc = ALL;
   ExcludePqc = NONE;
   EnableRsaGenKeyPair = 1;
   EnableEcGenKeyPair = 1;
   EnableEdGenKeyPair = 1;
   EnableEmGenKeyPair = 1;
   EnablePqcGenKeyPair = 1;
   EnableRsaSignVerify = 1;
   EnableLoadPubKey = 1;
   EnableLoadPrivKey = 1;
   DisableCheckFinalize = 1;
   IntermediateProcesses = 0;
   DisableSessionCache = 0;
   EngineInit = <slot_id>:10:11;
}
Replace <slot_id> with the actual physical or virtual slot number of your Luna HSM.
Open a persistent session on the Luna HSM slot using the following command:
# sautil -v -s <slot_id> -i 10:11 -o -q

If a persistent session is not required, refer to the README-GEM-CONFIG file in the <OpenSSL Luna Provider Toolkit directory>/docs folder for other login methods.
Verify the OpenSSL and Luna HSM Integration Using Classic Algorithms
After configuring the Luna Provider, verify the integration by testing with classic cryptographic algorithms. This process consists of two parts:
Generate Cryptographic Objects for OpenSSL CMS
To generate the CA private key, CA certificate, and the sender/receiver certificates for OpenSSL CMS, follow these steps:
Open <OPENSSLDIR>/openssl.cnf in a text editor and edit the [CA_default] section. Make the following changes:
dir = /usr/local/ssl new_certs_dir = $dir/certs
You can set dir to any directory of your choice, but ensure that you use the correct path in the subsequent steps.
If it doesn’t already exist, create the directory where generated certificates will be stored.
# mkdir -p /usr/local/ssl/certs
Create required OpenSSL database files.
# touch /usr/local/ssl/index.txt # touch /usr/local/ssl/serial
Edit /usr/local/ssl/serial, add 01 on the first line, and save the file.
Create a 2048-bit RSA key that will reside on the Luna HSM partition.
openssl genpkey -provider lunaprov -provider default -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /usr/local/ssl/certs/ca.key
Run the following command to confirm that the CA key is present on the partition:
# <LunaClient_Installation_Directory>/bin/cmu list
Example:
# /usr/safenet/lunaclient/bin/cmu list

When prompted, provide the partition password. The output will list the generated CA keys.
Use the CA key generated on Luna HSM to create a CSR. Provide the certificate details when prompted.
openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/ca.key -new -out /usr/local/ssl/certs/ca.csr
Generate a self-signed CA certificate based on the CA key and CSR. This certificate will be used to sign the sender and receiver certificates.
openssl x509 -provider lunaprov -provider default -signkey /usr/local/ssl/certs/ca.key -in /usr/local/ssl/certs/ca.csr -req -days 365 -out /usr/local/ssl/certs/ca.crt
Create directories for sender and receiver.
# mkdir /usr/local/ssl/certs/sender # mkdir /usr/local/ssl/certs/receiver
Generate a key and CSR for the sender.
openssl genpkey -provider lunaprov -provider default -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /usr/local/ssl/certs/sender/sender.key
openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/sender/sender.key -new -out /usr/local/ssl/certs/sender/sender.csr
The sender’s CSR will be signed by the CA to produce the sender certificate.
List the generated sender key pair using cmu.
# <LunaClient_Installation_Directory>/bin/cmu list
Example:
# /usr/safenet/lunaclient/bin/cmu list

When prompted, enter the partition password. The output will display the sender keys along with the CA keys already present on the partition.
Generate a key and CSR for the receiver.
openssl genpkey -provider lunaprov -provider default -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /usr/local/ssl/certs/receiver/receiver.key
openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/receiver/receiver.key -new -out /usr/local/ssl/certs/receiver/receiver.csr
The receiver’s CSR will be signed by the CA to produce the receiver certificate.
List the generated receiver key pair using cmu.
# <LunaClient_Installation_Directory>/bin/cmu list
Example:
# /usr/safenet/lunaclient/bin/cmu list

When prompted, enter the partition password. The output will display the receiver keys along with other keys stored on the partition.
Use the CA certificate and key to sign the sender CSR and generate the sender certificate.
openssl ca -provider lunaprov -provider default -policy policy_anything -cert /usr/local/ssl/certs/ca.crt -in /usr/local/ssl/certs/sender/sender.csr -keyfile /usr/local/ssl/certs/ca.key -out /usr/local/ssl/certs/sender/sender.crt
Type y and press Enter when prompted to commit.  

Similarly, sign the receiver CSR to generate the receiver certificate.
openssl ca -provider lunaprov -provider default -policy policy_anything -cert /usr/local/ssl/certs/ca.crt -in /usr/local/ssl/certs/receiver/receiver.csr -keyfile /usr/local/ssl/certs/ca.key -out /usr/local/ssl/certs/receiver/receiver.crt
Type y and press Enter when prompted to commit.  
Use OpenSSL CMS Cryptographic Objects to Sign, Verify, Encrypt, and Decrypt a Message
In a typical CMS (Cryptographic Message Syntax) workflow, secure communication between two parties is achieved through a combination of signing and encryption. The sender signs the message with their private key to guarantee authenticity and then encrypts it with the receiver’s public key to ensure confidentiality. Upon receiving the message, the receiver decrypts it with their private key and verifies the signature using the sender’s public key and certificate. The following procedure walks you through this process step by step.
Create a text file named message.txt containing the message to be sent.

Sender and Receiver keys are stored on the Luna HSM or Luna Cloud HSM service. Use the object label of the keys on the Luna HSM partition to decrypt and sign messages.
Sign message.txt with the sender’s private key.
openssl cms -provider lunaprov -provider default -sign -in message.txt -signer /usr/local/ssl/certs/sender/sender.crt -keyopt rsa_padding_mode:rsa -inkey /usr/local/ssl/certs/sender/sender.key -out sendmail.msg
Encrypt sendmail.msg using the receiver’s public key from the receiver certificate.
openssl cms -provider default -provider lunaprov -encrypt -in sendmail.msg -out sendmail_enc.msg -recip /usr/local/ssl/certs/receiver/receiver.crt -keyopt rsa_padding_mode:oaep
Decrypt sendmail_enc.msg with the receiver’s private key.
openssl cms -provider lunaprov -provider default -decrypt -in sendmail_enc.msg -inkey /usr/local/ssl/certs/receiver/receiver.key -out sendmail_dec.msg
Verify the signature of sendmail_dec.msg using the sender’s certificate and the CA certificate.
openssl cms -provider lunaprov -provider default -verify -in sendmail_dec.msg -CAfile /usr/local/ssl/certs/ca.crt -CApath /usr/local/ssl/certs/ -out out.txt -signer /usr/local/ssl/certs/sender/sender.crt -noverify

Open out.txt and compare it with message.txt. Both files must contain the same content, confirming that the sign, encrypt, decrypt, and verify operations completed successfully.
If using a Luna HSM slot, close the persistent sautil session:
# /usr/local/bin/sautil -c -s <slot_id> -i 10:11 -q
This completes the integration of OpenSSL with Luna Network HSM using the OpenSSL Luna Provider on UNIX.
Verify the OpenSSL and Luna HSM Integration Using PQC Algorithms
Post-quantum cryptography (PQC) algorithms are designed to safeguard data against the emerging threats posed by quantum computing. Verifying PQC functionality ensures that the OpenSSL Luna Provider and Luna HSM are working together seamlessly to support quantum-safe operations. This verification is divided into the following tasks:
Run a Sample Command with OpenSSL
Use the following commands to check version information and confirm the PQC algorithms supported by the Luna Provider:
Check the Luna Provider version information.
# openssl list -provider lunaprov -providers -verbose

Check the quantum-safe signature algorithms supported by the Luna Provider.
# openssl list -signature-algorithms -provider lunaprov

The sample output shown in documentation is truncated. Run the command in your environment to view the complete list of algorithms supported by luna-openssl-provider.
Check the quantum-safe Key Encapsulation Mechanisms (KEMs) supported by the Luna Provider.
# openssl list -kem-algorithms -provider lunaprov

As with signature algorithms, the displayed list is truncated for brevity. Run the command to view the full list of supported KEM algorithms.
Generate Cryptographic Materials Using PQC Algorithms
Generate the CA private key and CA certificate for OpenSSL, then use them to generate the server and user certificates.
Open the <OPENSSLDIR>/openssl.cnf file in a text editor and edit the [CA_default] section. Make the following changes:
dir = /usr/local/ssl new_certs_dir = $dir/certs
You can use the directory of your choice, but make sure to use the correct path in the subsequent steps.
Create a directory for saving the generated certificates if it doesn’t already exist.
# mkdir -p /usr/local/ssl/certs
Create the text files /usr/local/ssl/index.txt and /usr/local/ssl/serial.
# touch /usr/local/ssl/index.txt # touch /usr/local/ssl/serial
Open the /usr/local/ssl/serial file, write 01 at the top, press Enter, and save the file.
Create CA keys using PQC algorithms. For example, the following command generates a CA key using the mldsa87 algorithm:
openssl genpkey -provider lunaprov -provider default -algorithm mldsa87 -out /usr/local/ssl/certs/mldsa87_CA.key
The example above uses the mldsa87 PQC signature algorithm, but the same command can be used with any ML-DSA variant supported by the Luna Provider. Luna firmware v7.9.0 supports only ML-DSA and ML-KEM algorithms.
Generate the CSR using the CA key.
openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/mldsa87_CA.key -new -out /usr/local/ssl/certs/mldsa87_CA.csr
Sign the CSR using the CA key to generate a self-signed CA certificate.
openssl x509 -provider lunaprov -provider default -signkey /usr/local/ssl/certs/mldsa87_CA.key -in /usr/local/ssl/certs/mldsa87_CA.csr -req -days 365 -out /usr/local/ssl/certs/mldsa87_CA.crt
Provide the partition password when prompted.
Create a directory to generate the certificate request for the server and a user.
# mkdir /usr/local/ssl/certs/server # mkdir /usr/local/ssl/certs/user
Generate a certificate request for the server.
# openssl genpkey -provider lunaprov -provider default -algorithm mldsa65 -out /usr/local/ssl/certs/server/server.key # openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/server/server.key -new -out /usr/local/ssl/certs/server/server.csr
The server CSR is used to generate the server’s certificate signed by the CA. The example above uses the PQC mldsa65 signature algorithm, but you can use any PQC signature algorithm supported by the Luna Provider. Luna firmware v7.9.0 supports ML-DSA and ML-KEM algorithms only.
Sign the server’s certificate request using the CA.
# openssl ca -provider lunaprov -provider default -policy policy_anything -cert /usr/local/ssl/certs/mldsa87_CA.crt -in /usr/local/ssl/certs/server/server.csr -keyfile /usr/local/ssl/certs/mldsa87_CA.key -out /usr/local/ssl/certs/server/server.crt

Generate a certificate request for a user.
# openssl genpkey -provider lunaprov -provider default -algorithm mldsa44 -out /usr/local/ssl/certs/user/user1.key # openssl req -provider lunaprov -provider default -key /usr/local/ssl/certs/user/user1.key -new -out /usr/local/ssl/certs/user/user1.csr
The user CSR is used to generate the user’s certificate signed by the CA. The example above uses the PQC mldsa44 signature algorithm, but you can use any PQC signature algorithm supported by the Luna Provider. Luna firmware v7.9.0 supports ML-DSA and ML-KEM algorithms only.
Sign the user’s certificate request using the CA.
# openssl ca -provider lunaprov -provider default -policy policy_anything -cert /usr/local/ssl/certs/mldsa87_CA.crt -in /usr/local/ssl/certs/user/user1.csr -keyfile /usr/local/ssl/certs/mldsa87_CA.key -out /usr/local/ssl/certs/user/user1.crt
List the generated key pairs using the cmu utility.
# <LunaClient_Installation_Directory>/bin/cmu list
Example:
# /usr/safenet/lunaclient/bin/cmu list

Provide the partition password when prompted.
Set Up a Quantum-Safe TLS Server with KEM Algorithms: An example
Using the keys and certificates generated in the Generate Cryptographic Materials Using PQC Algorithms section, you can now configure a quantum-safe TLS server and verify client connectivity. The OpenSSL 3 server, enabled with quantum-safe cryptography, leverages KEM algorithms supported by the Luna Provider when establishing secure sessions.
Start the TLS server with a quantum-safe KEM algorithm and certificate.
# openssl s_server -provider lunaprov -provider default -cert /usr/local/ssl/certs/server/server.crt -key /usr/local/ssl/certs/server/server.key -www -tls1_3 -groups mlkem512:mlkem768:mlkem1024 -CAfile /usr/local/ssl/certs/mldsa87_CA.crt

In the -groups option, you may specify mlkem512:mlkem768:mlkem1024 or any other KEM algorithms supported by the Luna Provider. The TLS server will negotiate the connection using one of the algorithms listed. Luna firmware v7.9.0 supports only ML-DSA and ML-KEM algorithms.
In a new terminal, connect a client to the TLS server using a quantum-safe KEM algorithm.
# openssl s_client -provider lunaprov -provider default -groups mlkem768
This example uses the PQC mlkem768 KEM algorithm, but any quantum-safe KEM algorithm supported by the Luna Provider can be specified with the -groups option. For the full list of available algorithms, see the PQC KEM algorithms supported by the Luna Provider. Luna firmware v7.9.0 supports only ML-DSA and ML-KEM algorithms.
If the setup is successful, the TLS handshake output will confirm that the server and client negotiated a quantum-safe KEM algorithm. An example of the connection output is shown below:
[root@JJN4WL3 ~]# openssl s_client -provider lunaprov -provider default -groups mlkem768
Connecting to ::1
CONNECTED(00000006)
depth=1 C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
verify error:num=19:self-signed certificate in certificate chain
verify return:1
depth=1 C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
verify error:num=79:invalid CA certificate
verify return:1
depth=1 C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
verify error:num=26:unsuitable certificate purpose
verify return:1
depth=1 C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
verify return:1
depth=0 C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=Server
verify return:1
Certificate chain
 0 s:C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=Server
   i:C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
   a:PKEY: mldsa65, 192 (bit); sigalg: mldsa87
   v:NotBefore: Jul  9 15:07:28 2025 GMT; NotAfter: Jul  9 15:07:28 2026 GMT
 1 s:C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
   i:C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
   a:PKEY: mldsa87, 256 (bit); sigalg: mldsa87
   v:NotBefore: Jul  9 15:06:08 2025 GMT; NotAfter: Jul  9 15:06:08 2026 GMT
Server certificate
-----BEGIN CERTIFICATE-----
MIIbJjCCCPugAwIBAgIBAzANBgsrBgEEAQKCCwwIBzBcMQswCQYDVQQGEwJJbjEN
MAsGA1UECAwEVVBTVDEOMAwGA1UEBwwFTm9pZGExDzANBgNVBAoMBlRoYWxlczEN
MAsGA1UECwwETHVuYTEOMAwGA1UEAwwFUFFDQ0EwHhcNMjUwNzA5MTUwNzI4WhcN
MjYwNzA5MTUwNzI4WjBdMQswCQYDVQQGEwJJbjENMAsGA1UECAwEVVBTVDEOMAwG
A1UEBwwFTm9pZGExDzANBgNVBAoMBlRoYWxlczENMAsGA1UECwwETHVuYTEPMA0G
A1UEAwwGU2VydmVyMIIHtDANBgsrBgEEAQKCCwwGBQOCB6EAqgL42S2wwt8Ff/U9
hVTcc7BEtUBm74iQzTB5XvkolmwD2EIuo49Ta682g6dw/PfFAUWXdPFHpDBnWJ7I
YEQeXSFEjaZCs82ZICYqCdLyX+3IGskAxaCkMTCj/r4DN0U9YmDJUyXMPCT8XEvc
H0XzwyrIJr3yU3giMdKbtK5tzSl/jrvuvggkDGUN4V5YHVDvztSMCv+1+76AYx/R
tbqEMb6sdG3UaVjwpPphNCfMSS18X+uDASfF2EbCISdVwU3Y7JY84YCjzz11ujWs
JBBB6EfXTVm/fKLFPJs/OkAkHPEZHwtqW+O0GHgK1zuvymFj45KOnD+6FvmjLoZm
UHd5oLpkuo1TZIdO2sDGQHV4WWnjFUSigAyzAye42Pisicm1Mtriqk/yxzVG0coU
jWxVblnDst6wpkckmOu5LTDtpl6HBiMPJ7IGYBKcNJ8GZltpU3ZUDylEzV+/5w3D
BDDr2mamdlucmTZSQf/PC7ErbYLYh2pnLcZ9BM7F5VEhlxCJUQwMsSwCm6c9GH+5
I77K3WIDJUuB8j/Gz03ue9ojKW8Ofwlb8FOOcqMBPUaTWrlYx5cth9Fyw4Rnqzut
3dptRoiITvgm7Vbh/086sjlF4wd+YNNiNFD6CL2zQJc9JTdnDZr5O989fTE+8YS8
wVtq1wobWv7uUl6eb+AaUZPTK64fYEhifcfvA5JALWNmawVuzExy0haIwT1htsjl
19v+yjcxhlyu12VM0JMQr5vPK4l7iyytk41ljhmRWHJNpx8YiqTNKmieOfuvwqAm
p/W7nIUhn+aPWIzzIGi4hAGVp23j9wlLNPAtzuwG9winBbB6S0jV313xhgAuP4w8
zvlwgUZQE0PrtWr5rIp5NL83NFkGf3bDuTtjTNlHkY1+mu9Bm5uDm2C8GWVrJ1Nj
usgmgYvivAiW4100r2kNtVK+yXURmnkzb/785ear3z1/AbkdN6il7o25ewVMINoZ
oscf6LvP9ufEwybALC2Rfi+4wgWlvtL7xTJ1QTh1BCpj7P/r3ocxLLYW8GMviBO5
ZG0hFdAmnp7iORoIX0mGLkc6EVm8i5kkmqE5jiWgdS9oMbK3lh5BgAzhaoTog40Z
qHAFZ3FG2ug6ZrVfxnZkOZsCi8WSHdVM3Bc1SnnUmkm2ydrlLEtT1o/uzZzN2U30
e15n2z3BPRzICuIhqvyypXQymZ82Ph2/0WpLQrgCsOHxDCui7xcXtO1h1R8rcpXh
RpHEI02YA45h7+Rv9DwHPxAjOpfniIJP7cXXadDoAAjvmJYDHV0Bwju0HTrc7wWP
WwLT/6DWlkBc0BOUI55bfD+FfalQwKbrct1ImorocQ78QZjGZptkmLNPY9/u9RmN
TAJQvtbSLvEuFx3941f8NWAnMrFkid89hHVqWLg2iN0XrssCUDN0zrvLUk/S3AAR
OGehikf4RPxEe1OL65oEPAPPcUfhRbpIWQeNy0DXm7zRZeimW1iUSdXwUeGQkwiZ
Tff0X7zQuGu9vljBWgAv7qfU23rPY6BSY0egV9KUV4QzElWIwjgrQGcSGhJKWVbD
FIjLs5Pw5JCyBot9IpgZRRYeHkaAkqbBNrmN25ONWV1LHxKlm63KXFR5WGetMrvT
XLcIX590ToV+nmuAGGFvBNzxNq2Dkzo/1rPFQ4ZqBz+Q++OtcCRYVRvcCHoY0Gyv
4PR9SbwkvfThUetOPktzPFPp9pfqPKRUxvW/QKKct0hhdy0KYS40eEwlFviqbJws
tKls12ii0LKBJ+F96k6MMNt9FB3gfC7pYGPR0nKRbhwt6tiIoz+QwoLMgoAJqqqN
HW1/khwMLig+h0o8CcY2g6SnxrKJ2Q5mftPJxQaQQffjuGYEkKP7TMztWHI2x8vs
e3g9yDlbp7VMpxCzCPyiqsGP4gCMOkWskl9b6riDoIL55BYTp3ojkUD/Vn1b3Cn0
g0pfC433fWcIJvpmG01nWq2y0crXtg9LeDPq9Q3nd0Bu4Db9e/Pp1cCKZ40Trll2
sndh7dHsBlqtNMC3Y8SwEi/gXf59jADuz26ka+5ial7Etacv7kJ5wPqdLG4T2rIE
CIMNHcXn0BMY4LQVWGlb2eobrCjBkIif0rLg4gImQWItc+RTS5EtYnuvlspNmGv1
2IE74CvMoKSRfIUUaHMcD1omhA1YQnPxaLw48yO2ML3DfuLS1oX2SswEsTi4HqVV
pjPf1CA4wUl2DZ6WT2LIVEpB2drulsY7v3AlD/+e4Zvo+KkT0qOVAtzJc90LjpfI
hBqA8EyygEnfnpBWagbMU6b2rImpYwj5aNZdg5buv62V4uYFuGDmvImbBn8YXwqw
4HaCpBBNxe1RqyTV+0JYRM7JxatpOM1LJPc8szXjj0Z/v99tTYatS8LG6/tNiNnu
BxsoXIoPCn0BwPhcvrZE/uheANzFEYyE4lLqHcqdfCIWiS7tUFHhmmoyudbbNW8v
Rri8ZaN6cH1R6ojw5zJawORqOiVCyI2ClI8R5bFZVcgqHwOrGvWYkV+dQe+t+e99
ugOZm/VxcE9o7INmSB94i7BrgT7g5RdNkKFLFGGTxx+e15MorQ1fiISoJFF5quxn
nbAM4o9DO/rHtJKj5C0fOy9c2NGjTTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFEV2
Qtbgo21zBgg7tLyKdzAtPUaKMB8GA1UdIwQYMBaAFA/VlrcqD47HvItQ15ahdbuh
8/I6MA0GCysGAQQBAoILDAgHA4ISFADNa81KW44ZUQg9UD8u9NqZFVusdiuFSI2B
J+8ub7HlOw8pyh31Y6HP+Ny0WBrPPX9aJ0743La36Hoxa56wypyjWjdYvdRh9EQ2
3W/9/6ZHQHmwyOtEzA3PPoHAGytJq6U+mVebGH6VUanVsgMT8gPYSEZeDyhlxpQr
QQev9UZg1DW/pWCvvMqzhQSHEHV1EcEdTfvpvCMdcKUWwbOGrdSEd9QG/Hi6Kxuz
pGLZuPYeMFfPs69QXJjtQ6XAynR91CqnHtBQjSU/uuX3fddPuGLJ38pAMr4r2+6v
QeJag0Hmh8JI26etRs/uPvGkt95PMMjT0s45lA/6Z+IPfqBB0CzBlCrJlt59gYmT
uId7IPnx766oxbq4aHt+MKTN10eNNodTp5+YESw0xds5qJbNEcVP2JaPG3qp2Qwz
f3T6DA7znRe73zPEEefnkp7sDp6P2rhfjKFG0fkvcijC/hAOYgXEpTESULHg1JOq
Kwf3lkSTJC2vn6PWZ+ABQYhVZsrP3FivDojiIkJppC1yQ3tMuMwm3PWf7w0qpAQS
zNSN8V7tuqfej67i/3GHfp4S0WOtJuy2lPANDreOh+3V6XfX8wubNWNUNKT+9oxT
yF3lu69p1hzgKqKGwt89p0Ex+s29ds+8AVEyGaUwSSbePd8XM8lb/9et93QvE00J
dd2ELGYxFXpxuJSQP77gvptRjyfEVKiDELApaTjJOJ2vphiBGcpQSbE5ZtnZNLDr
mce5nEray3EGDwjOjsjJNSP3+xmrLwTMp6kDFRjspLzYtiMr8b4OOfrPEDjtnGYS
uXIt4QuxKnqceBzUXbj1o/hV2Je0SthH05P6Fdy9X1sOZbe6MuphI8jktRyQG7xQ
LbKEi4lNrYLEBdiFxmHMPU4ezqbi0RVTZneVA1+kEzW668FTng7kKiMR+sxUe0/9
EMnnILo6v1AbedFwezK0kh0vAQ00AQja2jcPZBOyJICn1fSKHU5XOt6gYAbrsLrx
rk7FuRAq3oNN9wGxtCKFcMDKSi99my+SUmuTBMmzlcD/l2FhHSj5GuCajfIEhT7e
OxIf25p6J/TCklXTV94nZsJ4JTwx0DJZBDeovavonlpvaJWL94d3OsbohN0IFJ3S
z8R6ptsUbEAl3iBnV398/Sr7euk0WB/R3zPY9R31NnjyCM6SN9yE2FekZ6Ed9cRO
8P5Vgn+NlVoGsqKESm0kLj2BZdGynvdlSoDHrtk9fbtkDSQmPny8ZsZd0ZOTZUEH
D7WzbdP4lY1IEl4Ga4dK4oP+Xj/mJhUekTO2GSvk0en08sItivBKsLwzq6456eiB
ttktTGYHkyaWRBaonfmX/JJtjMTmStneWupM4XIfndhiClJ76LWRZ8b8OeLqL7N4
pjalE8m2Io2O8cyX6c2cIhzUgSGiDbwMpHHGV2br2f4luPtHJndDBrLxkFd0xvT7
MVNiMbAMKbrxu1Ls+U0N/9ZD/b2AhZCCzPjvw49BQG+IaMstooqvlrD8rRIboRMi
NT9PV6mjnSxC3VElnJqRYLZEYjD/8LrHb7hIU54g9zJ5kgrzp1v4eVoGaTt/OF+0
pqePGITqfn4GUrf5uwV+C6f48pGH4ql23jOrAkZ73/gOExLSZWA8ToQulqL5Do8y
MMEzx4LMjY1lkHU0lJk+vU7H4fXVcSyAdlUVmgrfAhyi759seN9wwXJdUbTl78bq
wch1YuH+mJYoNyJG7zE7kbQYSgPC9u4DC9D0gDae4UdOvLey3YsG76BxFGRTfbdv
lLzo91DpnGMARaqczBNbNKoBhQD3OsQD4WEx2647sJzWQwJqbthWlR3BGPPzy0Oj
qn9QeW6dWHHsW7id0maDlaIXBRPWhN9TM6t2/zK2T21B0ApC5Td1R99n8sWtZFXD
JIj8A0fGLOF5Rmgnv53kbUG1mdaognHM8+r61Ve9Krb3gJUPjOUo00c5D+wBNmy/
k5GocBrJ68XGEU4AKaO4T5hp/jB6AffImmC+R+grpuvpSGP9KaRsXkd44U82DE5q
ON7k1YYcwXOgDpfvD0xpEQYN3xr3MST7/Ccne+csb60Fy3tqAk/myxye23g+BVQN
LKBnqsvCtr+ul0uYsK7LJM4i+kCAhGjpqd8rvo9h+bRq21QOoJFvWvPiklTb5C/s
N8vSoPl77Z5fXnhMfjvFJuvLN/6HBHgwzgwZaLcfpuGwe2+Bxcfc4jxuq0ANu2Qu
hrs7iIjm8czWT3R+93KvninwptXRHafb4NBueCiU1BfeiVpYlQRvdY7KFGQYCFPf
thxx0GkfAIvcE6lkDpNv+8oHlowRwvwvTRl623BEUWlxiAVb4I3IDhwgLcyQrEqw
htZuvpJQ8mvC/yFKynWnFtpEa7/CWXjVAt0z8Dnw4WL3D1P1O37Qy5MYsaZR+mf7
tk0mmB3EzNKTwjiASlDTd+0xpUkNm2dDwQbYd0a3UbW53bhhZuXuacWNHeSVvaKY
zXm8TsOpNjZZspI0+l71BVtyw8bPJqGOzAAcy85aRGPT3CFwfNAAqd1Bj73FQ9Cj
/hHOuanDUxDQ8nKnYNcMPb5H2GhQQHHeHyxHiFkN+LPXXJmHFeQXL2a/ib/tMRW9
A2KnWi+cMxjvi7QsaFx5QJu75Dyk950f4Cd+aAD48h1yjaP9pedhlo9+olxIOhZ+
8zl7sYChD5Ip+/G2us5FaikMTm3JmlkI9wwAPsZnWxERhC+8KkkCD6DSr5zJjTYW
5Y1I9sw44gg0r8Z5MNh5HVbMEua7+0xAp8NoRRAdC8L1suPU7LtplSm2arT/lbCi
0BEefUdgxa+OIRQLili/6toTzXtf8HsYmjA43W824thwUbAz1BWBQ8nbUC3AmePF
XvbeTy63c4A0tILBFk7+cMNQGY158Sm09pA9omB1H0K9R4LJ01HHMNN1NQus7za/
rEINUN31pzMpNsDdS0LJghYqtzGv+xGR+QKem2RSedCgUH1yg94GeESPcj5c+sYh
YROd28Urq+rh9Z/WlCrMKuNQ2hfbUPDRnAvJ9i7+mPAi1E6G2A++BOD+f/6VIlgV
RXWDxY8TkFRaSbIfOQMjZtYd0QbKuRijsLJ+GtcvQXPA96v8dUPVSiqTTmgk1N+s
IpVTIlySNl9M3k97v/dNX27RCyTVcZpIrtVsXeMM1WSSpRTdCRK16wjvc0ZGD3Z4
3IO3Y56ZeMFHMuJBRJHVdvkYkctIlrhLQGHyx8FDvufBYcC2NnPxa300tLuA5Bx7
FC6SkZ+VBxzmGMpPMnbFl/UmflaXHIB0ynoDU2yYdS/O1kGT/ijxXzcBePe/rJ9M
1w/5dmRHHUyNT8kITuzJK6O+HptJ51uJSFpIQdmL0QivBJEfd81n4uZx1cg3+yCz
p++bQ6s4TWnwqKR5vtd0qWGKVp4xLcgEBK7ZOSThaNUOat61+TL/lRGoEfTMnntK
IcGJd/w66+UcWXyv1/CLYb+FiZDcNyJTSm2KA2XxutE9q1PmOsFVCPK3NhohEEQ4
OcltguhpIjNROS2785q2wePs5Jn1XCVa+3uUpCMfJgIljaFO5BePg+28K4ulhie8
LqVIgjARLrWWDmXm0t7RpIYMJ/HJUt6r4sg88Iq5W5I25RNt851IdxzmC/omKoz+
G6SzfYManpi9cJiUEnow7dB02O2JT8PrqUdkseFbqPLTzCL/svyO/aaFEEpS5Kyy
TNC6keHLZ6N0nFHjbUEF14u3OPQoXv117LccTGPrRRnT4z1EGagd3rphN4mgDvGQ
RGoauRZo1DcqRCVimVaixgZI2u9Dzil4+0Fl7mrJs0SfqGKzoe4kHbiq+ocIqcZv
s2gYg0V+QCbboP6fySoGDLJDz3I+hBNAbPJ67JxOiV1rQiZxhjpd9obRgvQs2qFZ
XDs7yYKTuLLjKCTkXW5mWPFRc9BdPCJ1mfeWyDtwkvumh2TgkMIg50qaU4MafSmr
H9lIu2og9xqXa3i9xeaCJ5TNMH/kSEAOk+kSnjLjQO2u0gPJKKV/C24xq4SCGVqn
r/UwmrL0tnPY4l9azVw6eJWBEMs7Mq3P1HtZzpbESY3dHi9k43TlH3POXnM2WOzT
6y6b8LPxia1r65Ew/XtauJO27Cg4s18F+8NvJe632UO6I4vTyw+99i69KwHGHiKk
kzln/2kXSC1A4myED/2QwO/8igBl4ZyuR9xwBqpKSXUennHtBRB4ajj0/Clg3+4S
N0JqeXYDD3rrFKt8ypolxzuKHz0kMfVvHQWJxb7rjbD6DgjYAtkMONK156DrUgPa
wDRCidzWxti+UFh1d4riR/UEtZ/XmNJrkg+GM1xOKN3PuQhwgB2kIF6i+VItOeCa
oiBqRGErwpaK6rdrAFMt1Ye9mUdRd6KyOIpZv98b9FwP9FZR/3ylr7FhxKF1pTbY
7+HJonyYWuUJ17w2K61R7BHxC5QnUdtewURZtSn1A9pZjADCMCvK3BFTYsymGARz
y7/xEn5TuUIKAWW/4NDp3+02xAZE4IBiDBFzfzoAKPoUMkC5JAjTZQyPp5zeJxzl
Ve1MphiHh726vKvcqRqiyyLCBz/t8y9GcwTvpTS6uJjkBRUePFxVJlgo9em6BtNy
sHxGmlI3SEi5oQ4DDInnSEROYJt/K6M/SuYyaxm1Z2LZaNg3HoAMu2kymHRwpuy2
V+ngzCYaQn6TrGYlEdIzB1VjKcsRlmNBwqSZGMQzZXOjoUb5iCLyt9HLOZgjUS8j
h68KBFolM3GO+kzmN+ozNdRA69GNyal035JXTvjdslBdJo9pMj/kUCd+2bqxa3X5
v/tshVYcqyoQn27/tTBbM7hNQwTL2f0x1kOv/kyM9zDBhdo/oQYt3RrgW6mFLzpQ
WrIufxTIhAMSQEGGnBkgJHGOaPbja9+G0qnog2zsh5n+h2eV9MA8WeKQf7Sac9G2
cq1HrDOqVA2Fc5j1UQbg/cE1uSEQNOMZkefmc1OCLmi55WUM52ZhJzi6/9kSD4WV
p2UbLndodQeM2dd+uHNZnnCmCgBYsSpeUCLACGWCjCWtArJjUeyz66/IUyGVurut
JjCgPMH1WrhQcMa8LTEa11uGzquwaPiBNwabzRxN3u12u4L9lcuBFFk2y8ex+xcD
jc9UuEm4G7VIr0ZVCQ/7hqqHmzzV4ViGF1lhJuo+esXgUGlhhSmsDAGmDIOU4bes
VHHa3LNoRy9M2EXFDc5vtr4ij52KXuGt7ZK7FD1KL38iCj+MOV/RnssRvq/pR31a
ROhanQHUHCF1WQf4uh9aq2ilalWJwOJHt+p7vmowlHGbgBcpa4ypANoAGIs2TRPT
lMQhz4oiN9k8TzOsfHNUcHX5vR6zISy8/DNpf2d0qNX0rvpTkEYs89MoRODnelDt
dQatBX1WoHTpH60YBsK5v6K5It8SV3P5HDxNZy4dR4jSNzh2I3qNIXlqZmMP9/Tf
km7EE5lvxgx7Z4UdxB8Lvt2jYn9sG9V/SVgfNq81SiTaCu1PWwnX/NETZIetEmzD
Pu9K0L+PRh78S01IoTIsEayXvOkIyG6QyePDnjT+de+S97e63SMeuct1M1V/VqWG
LA9xpGqkukMeqTGoVjOCovUKFi5pBJmSNtQfhpIQC2MHdzTkSmYaWJ9XSeSYLtOo
u1CFyLye09ncacwXCX72cNRLgPnw8xxSNbGkNGmCY3B3Vz9NUZmAKdAnfJrcOaa2
6OXSk5uwdq5klmhI8x/P59Db5LvdbyPRoVv7C2vnmCDtYie3Bkv5oQE1L6G0whLV
bZv0OeZTrQLkD+xvsVZmZsIWKXc6Wp1aUWp9I8Tzpy7iRd4+PfDAsVauqSadVvDr
Qa0GqZPUKbquQHX+mFsCs65W9wUAPi6Aj5NdJK1esVeMdK9se+mfRP24dXuFegUn
JAzgrFb7v/LOKWlrUXKOwVor0XPbhi3Jb4wNO177uBhxlXfg3j0V3EToUzhT/RtS
U0TqMcbYLqegNMyZ92vZdmOm4IXTv7sGZVUXbPXwMSsRD2P1QOBUqUCwteOrCsAs
drvTWI4ioxdoGX5d3zUpVyGesWEISltJDcIGQgbGmJ4+gmV4j4U4yATBXg6t3Xfj
Ak03tXYstwQL1ff7DzRigo7A8g8mJ1mM5RwlOVCBucHDxNbqGiszWaHDzQALIi5M
tL/uAFWDlZfAw+D8Ax00ftDmAAAAAAAAAAAAAAAAAAAAAAUMEh0kLDU7
-----END CERTIFICATE-----
subject=C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=Server
issuer=C=In, ST=UPST, L=Noida, O=Thales, OU=Luna, CN=PQCCA
No client certificate CA names sent
Peer signature type: mldsa65
Negotiated TLS1.3 group: mlkem768
SSL handshake has read 19204 bytes and written 1622 bytes
Verification error: unsuitable certificate purpose
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Server public key is 192 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 26 (unsuitable certificate purpose)
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 4852BE1F2A7C0548585A061EEC4E836AC7D95ADA7EFFB7604D32D5E18325F89B
    Session-ID-ctx:
    Resumption PSK: 9DA69ED63DED12C11BFFDEB93C1289BBF0D83912964E4D271D475E940221B5FD8F97E978F1648F130D39F6BCD3815C15
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 74 dc 3d 78 92 32 00 73-dc b4 d5 a4 c7 0a a7 b6   t.=x.2.s........
    0010 - 28 79 f4 c4 d9 45 10 90-5e 5e a7 42 c8 49 3c 4a   .y...E..^^.B.I<.
    0020 - d0 ac 54 df e3 fe de 9c-84 27 ba b5 1e 0b 70 cb   ..T......^....p.
    0030 - 0b 92 5f 89 8f 54 36 61-ae 57 f2 a7 94 19 23 c6   .._..T6a.W....#.
    0040 - 2b 52 b2 74 53 f1 17 28-49 3a 4a 04 66 9c 05 80   +R.tS..^I:J.f...
    0050 - 8d 8f 20 a0 36 66 ed 13-5e d6 9b d2 6b 18 28 e9   .. .6f..^...k.(.
    0060 - 71 00 9c f3 c9 77 f3 bf-30 a1 58 f6 21 e1 82 40   q....w..0.X.!..@
    0070 - 59 79 ca e0 4f b1 c8 69-a2 4d 12 78 f0 f9 46 4d   Yy..O..i.M.x..FM
    0080 - 98 78 64 35 c2 af 50 79-3a fb d3 7d 64 6b a7 02   .xd5..Py:...dk..
    0090 - 02 64 14 46 57 4c 5a 7a-9c a2 13 09 d4 d5 0d 0f   .d.FWLZz........
    00a0 - 3b bc 2a 82 ea 87 91 17-18 58 42 ee 04 0e ca 5b   ;.*......XB....[
    00b0 - 08 a2 a0 5b 4b 2a 5c f7-0e af ca fa 45 f0 2a e2   ...[K*\.....E.*.
    00c0 - a2 bb ce 57 5d ef fd 75-62 fb 24 19 f1 14 60 1c   ...W]..ub.$...`.
    Start Time: 1752073970
    Timeout   : 7200 (sec)
    Verify return code: 26 (unsuitable certificate purpose)
    Extended master secret: no
    Max Early Data: 0
read R BLOCK
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: E72EDC255B00765A3D818C7972F2833B8457396C715F19CD1B8C3ACF3A7AD601
    Session-ID-ctx:
    Resumption PSK: EF3D5BB631A67B1099FF567EC4472A1C75A0EF16E95D06B253BA52296C753BA9DA9B4E033CF6B18EF1583EE15DD10B6D
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 74 dc 3d 78 92 32 00 73-dc b4 d5 a4 c7 0a a7 b6   t.=x.2.s........
    0010 - c3 34 86 bb ce 72 4b b4-69 8c d8 54 35 84 33 c8   .4...rK.i..T5.3.
    0020 - aa 88 f2 e1 2c 45 ae af-02 05 49 ff 78 62 54 96   ....,E....I.xbT.
    0030 - d5 62 59 5d ac ea 61 fb-14 59 e0 4e 40 08 f1 74   .bY]..a..Y.N@..t
    0040 - ba 92 7d 5c 25 66 f4 84-80 df 5f e3 19 76 e1 a7   ..r\%f...._..v..
    0050 - e7 60 94 e5 e4 dd a5 23-c8 96 0a fa b9 5e a4 26   .`.....#.....^.&
    0060 - 93 d5 d4 67 d7 a7 4e e1-a0 ee c0 ff e8 29 ea 86   ...g..N......)..
    0070 - ec 94 1a e4 5c 5a a7 f1-be ee c2 36 d0 05 d7 41   ....\Z.....6...A
    0080 - 2a 63 e4 8a 77 12 ce 30-45 a8 28 e5 06 31 ac 5e   *c..w..0E.(..1.^
    0090 - 5a 16 68 2e 2b c1 ee 27-b9 75 9f 1e d8 52 de 97   Z.h.+....u...R..
    00a0 - fc 31 b8 57 2f 6d d9 0e-56 c5 ae c6 06 72 c0 4e   .1.W%m..V....r.N
    00b0 - 26 37 f4 22 31 b4 4a 2d-4a 68 df b6 6b 3b 80 70   &7.E1.J-Jh..k;.p
    00c0 - 66 c7 bb e5 18 21 b5 1c-55 00 54 64 a2 df b4 36   f....!..U.Td...6
    Start Time: 1752073970
    Timeout   : 7200 (sec)
    Verify return code: 26 (unsuitable certificate purpose)
    Extended master secret: no
    Max Early Data: 0
read R BLOCK
After the client connection is established, issue the command GET / at the client prompt. This instructs the quantum-safe crypto–enabled OpenSSL 3 server to return details about the established connection. The server responds with connection details, including the negotiated cipher suite and the quantum-safe KEM algorithm. An example output is shown below:
GET /
HTTP/1.0 200 ok
Content-type: text/html
<HTML><BODY BGCOLOR="#ffffff">
<pre>
s_server -provider lunaprov -provider default -cert /usr/local/ssl/certs/server/server.crt -key /usr/local/ssl/certs/server/server.key -www -tls1_3 -groups mlkem512:mlkem768:mlkem1024 -CAfile /usr/local/ssl/certs/mldsa87_CA.crt
This TLS version forbids renegotiation.
Ciphers supported in s_server binary
TLSv1.3    :TLS_AES_256_GCM_SHA384    TLSv1.3    :TLS_CHACHA20_POLY1305_SHA256
TLSv1.3    :TLS_AES_128_GCM_SHA256    TLSv1.2    :ECDHE-ECDSA-AES256-GCM-SHA384
TLSv1.2    :ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2    :DHE-RSA-AES256-GCM-SHA384
TLSv1.2    :ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2    :ECDHE-RSA-CHACHA20-POLY1305
TLSv1.2    :DHE-RSA-CHACHA20-POLY1305 TLSv1.2    :ECDHE-ECDSA-AES128-GCM-SHA256
TLSv1.2    :ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2    :DHE-RSA-AES128-GCM-SHA256
TLSv1.2    :ECDHE-ECDSA-AES256-SHA384 TLSv1.2    :ECDHE-RSA-AES256-SHA384
TLSv1.2    :DHE-RSA-AES256-SHA256     TLSv1.2    :ECDHE-ECDSA-AES128-SHA256
TLSv1.2    :ECDHE-RSA-AES128-SHA256   TLSv1.2    :DHE-RSA-AES128-SHA256
TLSv1.0    :ECDHE-ECDSA-AES256-SHA    TLSv1.0    :ECDHE-RSA-AES256-SHA
SSLv3      :DHE-RSA-AES256-SHA        TLSv1.0    :ECDHE-ECDSA-AES128-SHA
TLSv1.0    :ECDHE-RSA-AES128-SHA      SSLv3      :DHE-RSA-AES128-SHA
TLSv1.2    :RSA-PSK-AES256-GCM-SHA384 TLSv1.2    :DHE-PSK-AES256-GCM-SHA384
TLSv1.2    :RSA-PSK-CHACHA20-POLY1305 TLSv1.2    :DHE-PSK-CHACHA20-POLY1305
TLSv1.2    :ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2    :AES256-GCM-SHA384
TLSv1.2    :PSK-AES256-GCM-SHA384     TLSv1.2    :PSK-CHACHA20-POLY1305
TLSv1.2    :RSA-PSK-AES128-GCM-SHA256 TLSv1.2    :DHE-PSK-AES128-GCM-SHA256
TLSv1.2    :AES128-GCM-SHA256         TLSv1.2    :PSK-AES128-GCM-SHA256
TLSv1.2    :AES256-SHA256             TLSv1.2    :AES128-SHA256
TLSv1.0    :ECDHE-PSK-AES256-CBC-SHA384 TLSv1.0    :ECDHE-PSK-AES256-CBC-SHA
SSLv3      :SRP-RSA-AES-256-CBC-SHA   SSLv3      :SRP-AES-256-CBC-SHA
TLSv1.0    :RSA-PSK-AES256-CBC-SHA384 TLSv1.0    :DHE-PSK-AES256-CBC-SHA384
SSLv3      :RSA-PSK-AES256-CBC-SHA    SSLv3      :DHE-PSK-AES256-CBC-SHA
SSLv3      :AES256-SHA                TLSv1.0    :PSK-AES256-CBC-SHA384
SSLv3      :PSK-AES256-CBC-SHA        TLSv1.0    :ECDHE-PSK-AES128-CBC-SHA256
TLSv1.0    :ECDHE-PSK-AES128-CBC-SHA  SSLv3      :SRP-RSA-AES-128-CBC-SHA
SSLv3      :SRP-AES-128-CBC-SHA       TLSv1.0    :RSA-PSK-AES128-CBC-SHA256
TLSv1.0    :DHE-PSK-AES128-CBC-SHA256 SSLv3      :RSA-PSK-AES128-CBC-SHA
SSLv3      :DHE-PSK-AES128-CBC-SHA    SSLv3      :AES128-SHA
TLSv1.0    :PSK-AES128-CBC-SHA256     SSLv3      :PSK-AES128-CBC-SHA
---
Ciphers common between both SSL end points:
TLS_AES_256_GCM_SHA384     TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256
ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-SHA384  ECDHE-RSA-AES256-SHA384    DHE-RSA-AES256-SHA256
ECDHE-ECDSA-AES128-SHA256  ECDHE-RSA-AES128-SHA256    DHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES256-SHA     ECDHE-RSA-AES256-SHA       DHE-RSA-AES256-SHA
ECDHE-ECDSA-AES128-SHA     ECDHE-RSA-AES128-SHA       DHE-RSA-AES128-SHA
AES256-GCM-SHA384          AES128-GCM-SHA256          AES256-SHA256
AES128-SHA256              AES256-SHA                 AES128-SHA
Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:ecdsa_brainpoolP256r1_sha256:ecdsa_brainpoolP384r1_sha384:ecdsa_brainpoolP512r1_sha512:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512:dilithium2:p256_dilithium2:rsa3072_dilithium2:dilithium3:p384_dilithium3:dilithium5:p521_dilithium5:mldsa44:p256_mldsa44:rsa3072_mldsa44:mldsa44_pss2048:mldsa44_rsa2048:mldsa44_ed25519:mldsa44_p256:mldsa44_bp256:mldsa65:p384_mldsa65:mldsa65_pss3072:mldsa65_rsa3072:mldsa65_p256:mldsa65_bp256:mldsa65_ed25519:mldsa87:p521_mldsa87:mldsa87_p384:mldsa87_bp384:mldsa87_ed448:falcon512:p256_falcon512:rsa3072_falcon512:falconpadded512:p256_falconpadded512:rsa3072_falconpadded512:falcon1024:p521_falcon1024:falconpadded1024:p521_falconpadded1024:sphincssha2128fsimple:p256_sphincssha2128fsimple:rsa3072_sphincssha2128fsimple:sphincssha2128ssimple:p256_sphincssha2128ssimple:rsa3072_sphincssha2128ssimple:sphincssha2192fsimple:p384_sphincssha2192fsimple:sphincsshake128fsimple:p256_sphincsshake128fsimple:rsa3072_sphincsshake128fsimple
Shared Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:ecdsa_brainpoolP256r1_sha256:ecdsa_brainpoolP384r1_sha384:ecdsa_brainpoolP512r1_sha512:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:dilithium2:p256_dilithium2:rsa3072_dilithium2:dilithium3:p384_dilithium3:dilithium5:p521_dilithium5:mldsa44:p256_mldsa44:rsa3072_mldsa44:mldsa44_pss2048:mldsa44_rsa2048:mldsa44_ed25519:mldsa44_p256:mldsa44_bp256:mldsa65:p384_mldsa65:mldsa65_pss3072:mldsa65_rsa3072:mldsa65_p256:mldsa65_bp256:mldsa65_ed25519:mldsa87:p521_mldsa87:mldsa87_p384:mldsa87_bp384:mldsa87_ed448:falcon512:p256_falcon512:rsa3072_falcon512:falconpadded512:p256_falconpadded512:rsa3072_falconpadded512:falcon1024:p521_falcon1024:falconpadded1024:p521_falconpadded1024:sphincssha2128fsimple:p256_sphincssha2128fsimple:rsa3072_sphincssha2128fsimple:sphincssha2128ssimple:p256_sphincssha2128ssimple:rsa3072_sphincssha2128ssimple:sphincssha2192fsimple:p384_sphincssha2192fsimple:sphincsshake128fsimple:p256_sphincsshake128fsimple:rsa3072_sphincsshake128fsimple
Supported groups: mlkem768
Shared groups: mlkem768
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 4793C6AAE036787E50DB5BEA1BECA4F9FA5CB17591FB5D7437C2F5BC7B1CB315
    Session-ID-ctx: 01000000
    Resumption PSK: EF3D5BB631A67B1099FF567EC4472A1C75A0EF16E95D06B253BA52296C753BA9DA9B4E033CF6B18EF1583EE15DD10B6D
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1752073970
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
   0 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   1 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   1 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)
---
no client certificate available
</pre></BODY></HTML>
closed
This completes the demonstration of an OpenSSL TLS server successfully negotiating secure sessions with quantum-safe KEM algorithms using the Luna Provider and Luna HSM.
Perform Quantum-Safe Digital Signature and Verification
Using OpenSSL CMS, you can create and verify quantum-safe digital signatures. To do so, first generate a certificate using a PQC signature algorithm, and then use that certificate to sign and verify data.
Use the user certificate created in steps 11–12 of the Generate Cryptographic Materials Using PQC Algorithms procedure.
Create a text file named inputfile containing sample data to be signed.
# echo "Sample data to validate the signing using PQC Signature Algorithms supported by the Luna Provider" > inputfile
Sign the data using CMS. Unlike PQC certificate creation, CMS signing requires a digest algorithm, so you must pass one explicitly with the -md parameter (for example, sha512).
# openssl cms -provider lunaprov -provider default -in inputfile -sign -signer /usr/local/ssl/certs/user/user1.crt -inkey /usr/local/ssl/certs/user/user1.key -nodetach -outform pem -binary -out signedfile -md sha512
The input data is read from inputfile, and the signed CMS object is written to signedfile. The PQC signature algorithm used is the same algorithm applied when generating the user1.crt certificate.
Verify the CMS file (signedfile) and compare the output with the original input file.
# openssl cms -provider lunaprov -provider default -verify -CAfile /usr/local/ssl/certs/mldsa87_CA.crt -inform pem -in signedfile -crlfeol -out outputfile -signer /usr/local/ssl/certs/user/user1.crt -noverify
If the contents of inputfile and outputfile are identical, signing and verification have succeeded.
In addition to CMS, you can also sign and verify using the openssl dgst command. Below is an example using the same keys and certificates.
Sign the data using the user’s private key:
# openssl dgst -provider lunaprov -provider default -sign /usr/local/ssl/certs/user/user1.key -out dgstsignfile inputfile
Extract the public key from the user’s certificate:
# openssl x509 -provider lunaprov -provider default -in /usr/local/ssl/certs/user/user1.crt -pubkey -noout > user1.pubkey
Here, user1.pubkey is the extracted public key from the user’s certificate.
Verify the signature using the extracted public key:
# openssl dgst -provider lunaprov -provider default -signature dgstsignfile -verify user1.pubkey inputfile
In this command, dgstsignfile is the signed data, and user1.pubkey is the corresponding public key extracted from the user’s certificate.
This completes the quantum-safe digital signature and verification example. OpenSSL, integrated with the Luna Provider, successfully performs key generation and cryptographic operations using post-quantum algorithms within the secure Luna HSM boundary.
Integrating Luna HSM with OpenSSL using Gem Engine
For a seamless integration of Luna HSM with OpenSSL using Gem Engine, execute one of the following series of steps, depending on your environment:
Integrate OpenSSL with Luna HSM on UNIX
To integrate OpenSSL with Luna HSM on UNIX, use the following steps:
Install and configure OpenSSL toolkit on UNIX
To install and configure OpenSSL toolkit on UNIX, follow one of the scenarios below as per your requirements:
- 
Scenario A: Integrate a pre-built dynamic engine with an existing OpenSSL installation 
- 
Scenario B: Compile the dynamic engine and integrate it with an existing OpenSSL installation 
- 
Scenario C: Compile and install OpenSSL from source and compile and install Gem Engine 
- 
Scenario D: Configure OpenSSL to enable Gem Engine by default 
Scenario A: Integrate a pre-built dynamic engine with an existing OpenSSL installation
Follow these steps to integrate a pre-built dynamic engine with an existing OpenSSL installation:
Extract the Gem Engine toolkit and go to the Gem Engine directory.
Find the libgem.so or gem.so and sautil binaries in the builds/linux/<distributor>/<bit_version>/<OpenSSL_version> directory. For example: builds/linux/rhel/64/3.0/.
For OpenSSL version 1.1.x onwards, the dynamic engine library is gem.so.
Use gembuild to locate the OpenSSL Engines directory.
./gembuild locate-engines
Copy the libgem.so or gem.so to the OpenSSL engines directory to install the Gem Engine. For instance:
cp <gem-engine directory>/builds/linux/rhel/64/3.0/gem.so /usr/lib64/engines-3
Copy the sautil utility to /usr/local/bin based on your OpenSSL version.
cp <gem-engine directory>/builds/linux/rhel/64/3.0/sautil /usr/local/bin
Run the sautil utility to ensure all options are listed.
/usr/local/bin/sautil
Add the openssl and sautil locations to the PATH environment variable if they are not in the system defaults.
export PATH=/usr/local/bin:$PATH
Add the openssl library location to the LD_LIBRARY_PATH environment variable if not present in system defaults.
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
Verify Gem Engine support.
openssl engine gem -v
Scenario B: Compile the dynamic engine and integrate it with an existing OpenSSL installation
Follow these steps to compile the dynamic engine and integrate it with an existing OpenSSL installation:
Ensure the system has a C compiler and access to the make utility.
Download and unzip the OpenSSL source from https://www.openssl.org/source/. Pick a version that closely matches your current OpenSSL installation. For example, if you have OpenSSL v1.1.1, download any version within the v1.1.x series.
tar xvfz openssl-x.x.x.tar.gz
Navigate to the Gem Engine directory to find the engine location for the existing OpenSSL. Note the OpenSSL Engine directory for the next command.
./gembuild locate-engines
Run gembuild config, providing the necessary inputs to compile the engine.
./gembuild config --openssl-source=<Path to extracted OpenSSL source directory> --openssl-engines=<Path to Engine directory from step 2> --config-bits=64
Install the OpenSSL development package on the system if it is not already installed. If the OpenSSL headers directory is not in the default location /usr/include, use the --openssl-includes option. If the libcrypto.so file is not in the default libs location, use the --openssl-libs option. For GemEngine 1.6, you can specify the major version of the OpenSSL build using the new option --openssl-api=<major>. Here are examples:
--openssl-api=3.0
--openssl-api=1.1.1
Install the required EC header files.
./gembuild openssl-ec-headers
Compile the engine.
./gembuild engine-build
If you encounter an issue, refer to the Troubleshooting section.
Install the Gem Engine.
./gembuild engine-install
Verify Gem Engine support.
openssl engine gem -v
Compile and install sautil. By default, it will be installed to /usr/local/bin/sautil. If you prefer a different location, you can either use the --sautil-prefix option during compilation or specify the desired directory with the ./gembuild sautil-install command. 
./gembuild sautil-build ./gembuild sautil-install
Scenario C: Compile and install OpenSSL and Gem Engine
Proceed with the following instructions to compile and install OpenSSL from source, and subsequently, compile and install the Gem Engine:
Download openssl-x.x.xx.tar.gz.
tar xvfz openssl-x.x.xx.tar.gz
Download and extract the OpenSSL FIPS module if FIPS is enabled. Otherwise, proceed to the next step.
tar xvfz openssl-fips-2.0.x.tar.gz
This step is applicable until OpenSSL v1.0.2 and can be omitted for the latest OpenSSL versions.
Extract the Gem Engine toolkit, access the Gem Engine directory, and then execute the gembuild config command, making sure to include the --prefix option.
If you are using OpenSSL v1.0.2 with the FIPS module, incorporate --openssl-fips-source=<Path to openssl-fips-2.0.x> into the gembuild config command: ./gembuild config --openssl-source=<Path to extracted OpenSSL source directory> --prefix=/usr/local --config-bits=64
If you are utilizing GemEngine v1.3 or a later version to construct and install OpenSSL v1.0.2, make sure to include --compat-102 in the command mentioned above. It's important to note that GemEngine v1.6 no longer supports OpenSSL v1.0.2. Instead, it introduces a new option, --openssl-api=<major>, where <major> signifies the major version of the OpenSSL build. For example, --openssl-api=3.0 or --openssl-api=1.1.1.
Proceed to compile and install the FIPS module, if FIPS is enabled. Otherwise, move on to next step. Please note that this step is relevant for OpenSSL v1.0.2 and can be skipped for the latest OpenSSL versions.
./gembuild openssl-fips-build ./gembuild openssl-fips-install
Compile and install OpenSSL using the toolkit.
./gembuild openssl-build ./gembuild openssl-install
Compile and install the Gem dynamic engine and verify the engine.
./gembuild engine-build ./gembuild engine-install /usr/local/ssl/bin/openssl engine gem -v
If you encounter any known issues, refer to the Troubleshooting section.
Compile and install sautil.
./gembuild sautil-build ./gembuild sautil-install
The sautil tool will be installed in the directory <prefix>/sautil/bin/sautil, where <prefix> is the directory specified in a previous step using the --prefix option. If you wish to choose a different location, use the --sautil-prefix option when running the /gembuild sautil-install command.
Add openssl and sautil locations to the PATH environment variable. For example:
export PATH=/usr/local/ssl/bin:/usr/local/sautil/bin:$PATH
Add the openssl library location to the LD_LIBRARY_PATH environment variable. For example:
export LD_LIBRARY_PATH=/usr/local/ssl/lib:$LD_LIBRARY_PATH
Scenario D: Configure OpenSSL to enable Gem Engine by default
Follow these steps to configure OpenSSL to enable Gem Engine by default:
Open your terminal and type the following command to find the location where OpenSSL is installed:
openssl version -d
Make note of the OpenSSL directory location, indicated by OPENSSLDIR: "/usr/local/ssl".
Run the following command to discover the directory containing the Gem Engine files libgem.so or gem.so:
./gembuild locate-engines
Make note of this directory as it holds the Gem Engine files.
Ensure OpenSSL is set via the PATH environment variable. Verify with which openssl to ensure the correct configuration file is accessed.
Modify the openssl.cnf file as follows:
# Insert near the top of the file openssl.cnf: openssl_conf = openssl_init # Insert at the bottom of the file openssl.cnf: [ openssl_init ] engines = engine_section [ engine_section ] gem = gem_section [ gem_section ] dynamic_path = /usr/local/ssl/lib/engines/libgem.so default_algorithms = ALL
Ensure the correct dynamic engine library is provided in dynamic_path.
Confirm that the Gem Engine is loaded as the default engine.
openssl engine -v
Check the application by generating a certificate request without using the engine parameter.
openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key
Configure Gem Engine to use Luna HSM on UNIX
To set up Gem Engine for Luna HSM on UNIX, follow one of the tasks below, based on the type of Luna HSM you are using:
Configure Gem Engine for Luna HSM
To set up Gem Engine for Luna HSM, follow these steps:
Open the /etc/Chrystoki.conf file and include the following GemEngine section:
GemEngine = {
    LibPath = /usr/safenet/lunaclient/lib/libCryptoki2.so;
    LibPath64 = /usr/safenet/lunaclient/lib/libCryptoki2_64.so;
    EnableDsaGenKeyPair = 1;
    EnableRsaGenKeyPair = 1;
    DisablePublicCrypto = 1;
    EnableRsaSignVerify = 1;
    EnableLoadPubKey = 1;
    EnableLoadPrivKey = 1;
    DisableCheckFinalize = 1;
    DisableEcdsa = 1;
    DisableDsa = 0;
    DisableRand = 0;
    EngineInit = <slot_id>:10:11;
}
Replace <slot_id> with the actual value of the physical or virtual slot.
Run the sautil utility to initiate a persistent sautil session on the Luna HSM slot:
/usr/local/bin/sautil -v -s <slot_id> -i 10:11 -o -q
If a persistent session is not required, alternative methods for login can be found in the README-GEM-CONFIG file located in the <GemEngine_Directory>/docs folder.
Configure Gem Engine for Luna Cloud HSM
Follow these steps to configure Gem Engine for Luna Cloud HSM:
Create a text file to store the partition crypto officer password:
echo <partition_password> > <path_to_my_passfile>/passfile
Open the /<ChrystokiConfigurationFile_Directory>/Chrystoki.conf file and insert the following in the GemEngine section:
   GemEngine = {
       LibPath = <path to LibCryptoki2.so>;
       LibPath64 = <path to LibCryptoki2_64.so>;
       EnableDsaGenKeyPair = 1;
       EnableRsaGenKeyPair = 1;
       DisablePublicCrypto = 1;
       EnableRsaSignVerify = 1;
       EnableLoadPubKey = 1;
       EnableLoadPrivKey = 1;
       DisableCheckFinalize = 1;
       DisableEcdsa = 1;
       DisableDsa = 0;
       DisableRand = 0;
       EngineInit = "<Partition Label>":0:0:passfile=<path_to_my_passfile>/passfile;
       EnableLoginInit = 1;
   }
Replace <Partition Label> with your partition label, and ensure that passfile points to the correct path for the file containing the Crypto Officer password.
In the Misc section of Chrystoki.conf, add the following flag and save the changes. Do not remove the default values already present in the Misc section:
   Misc = {
     FinalizeOnClose = 1;
   }
Verify OpenSSL and Gem Engine integration on UNIX
Follow these steps for verifying the integration of OpenSSL and Gem Engine on UNIX:
Generate cryptographic objects for OpenSSL CMS
To generate the necessary cryptographic objects for OpenSSL CMS, including the CA private key, CA certificate, and receiver and sender certificates:
Open the <OPENSSLDIR>/openssl.cnf file in a text editor, and within the [CA_default] section, make the following changes:
dir = /usr/local/ssl new_certs_dir = $dir/certs
You can customize the dir parameter, but ensure to use the correct path in subsequent steps.
If the directory for saving certificates doesn't exist, create it:
mkdir -p /usr/local/ssl/certs
Create the text files /usr/local/ssl/index.txt and /usr/local/ssl/serial.
Open /usr/local/ssl/serial, insert the value 01 at the top of the file, and press the Enter key. Save the changes to the file.
Generate a 2048-bit private key for the Certificate Authority (CA) using the Gem Engine. The key is generated on the Luna HSM’s partition:
openssl genrsa -engine gem 2048
List the generated key pair using the cmu utility:
<LunaClient_Installation_Directory>/bin/cmu list
Example:
/usr/safenet/lunaclient/bin/cmu list
Provide the partition password when prompted and take note of the private key label for the CA keys.
Generate a CA certificate using the key created in a previous step for signing other certificates:
openssl req -engine gem -new -x509 -days 365 -key rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd -keyform engine -out /usr/local/ssl/certs/ca.cer
Replace rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd with the object label for the CA private key on Luna HSM or Luna Cloud HSM.
Create directories for generating certificate requests for the sender and receiver:
mkdir /usr/local/ssl/certs/sender mkdir /usr/local/ssl/certs/receiver
Generate a certificate request for the sender:
openssl req -engine gem -newkey rsa:2048 -out /usr/local/ssl/certs/sender/sender.txt
The sender's request is used to generate the sender's certificate signed by the CA.
List the generated key pair using the cmu utility:
/usr/safenet/lunaclient/bin/cmu list
Provide the partition password when prompted and note down the private key label of sender keys.
Generate a certificate request for the receiver:
openssl req -engine gem -newkey rsa:2048 -out /usr/local/ssl/certs/receiver/receiver.txt
The receiver's request is used to generate the receiver's certificate signed by the CA.
List the generated key pair using the cmu utility:
/usr/safenet/lunaclient/bin/cmu list
Provide the partition password when prompted and note down the private key label of receiver keys.
Sign the certificate request of the sender by CA:
openssl ca -engine gem -policy policy_anything -cert /usr/local/ssl/certs/ca.cer -in /usr/local/ssl/certs/sender/sender.txt -keyfile rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd -keyform engine -out /usr/local/ssl/certs/sender/sender.cer
Replace rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd with the object label for the CA private key on Luna HSM or Luna Cloud HSM created in a previous step.
Sign the certificate request for the receiver by CA:
openssl ca -engine gem -policy policy_anything -cert /usr/local/ssl/certs/ca.cer -in /usr/local/ssl/certs/receiver/receiver.txt -keyfile rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd -keyform engine -out /usr/local/ssl/certs/receiver/receiver.cer
Replace rsa-private-a55e015d94ee6c4a559dfab7c39a2069d4064bcd with the object label for the CA private key on Luna HSM or Luna Cloud HSM created in a previous step.
Use OpenSSL CMS cryptographic objects to sign, verify, encrypt, and decrypt a message
Follow these steps for using OpenSSL CMS to sign, verify, encrypt, and decrypt a message between a sender and receiver, all facilitated by the Gem Engine on Luna HSM or Luna Cloud HSM:
While OpenSSL CMS relies exclusively on RSA_PKCS, Luna Cloud HSM and Luna HSM firmware versions 7.7.2 onwards do not support RSA_PKCS for encryption/decryption when operating in FIPS mode. If your HSM is configured in FIPS mode, it is recommended to refer to APPENDIX A for guidance on executing the same cryptographic operations under these specific circumstances. This ensures compatibility and adherence to security protocols while utilizing the OpenSSL CMS.
Create a text file named message.txt.
Sign the message.txt file using the sender’s private key.
openssl cms -engine gem -sign -in message.txt -signer /usr/local/ssl/certs/sender/sender.cer -inkey rsa-private-7dfdb3caaf25a63b3d8a81d2a3b51668decafe0f -keyform engine -out sendmail.msg
Replace rsa-private-7dfdb3caaf25a63b3d8a81d2a3b51668decafe0f with the object label for the sender's private key.
Encrypt the sendmail.msg using the receiver’s public key.
openssl cms -engine gem -encrypt -in sendmail.msg -out sendmail_enc.msg /usr/local/ssl/certs/receiver/receiver.cer
Decrypt the sendmail_enc.msg using the receiver’s private key.
openssl cms -engine gem -decrypt -in sendmail_enc.msg -inkey rsa-private-ec0fcb1ce9114662556caab35fc2baf0565752ec -keyform engine -out sendmail_dec.msg
Replace rsa-private-ec0fcb1ce9114662556caab35fc2baf0565752ec with the object label for the receiver's private key.
Verify the signature of sendmail_dec.msg using the sender’s public key.
openssl cms -engine gem -verify -in sendmail_dec.msg -CAfile /usr/local/ssl/certs/ca.cer -out out.txt /usr/local/ssl/certs/sender/sender.cer
Open out.txt and compare its contents with message.txt. Both files should contain the same message, confirming successful cryptographic operations.
Close the sautil session if you are using Luna HSM slot.
/usr/local/bin/sautil -c -s <slot_id> -i 10:11 -q
The integration of OpenSSL with Luna HSM or Luna Cloud HSM using Gem Engine on UNIX is now complete.
Integrate OpenSSL with Luna HSM on Windows
To integrate OpenSSL with Luna HSM on Windows, use the following steps:
Install and configure OpenSSL toolkit on Windows
For installation and configuration of the OpenSSL toolkit on your Windows system, proceed through the following steps:
Go to the OpenSSL toolkit directory within <engine-directory>\builds\win. Extract the contents of sautil-win64-openssl-x.x.xx.tar.gz and ssl-win64-openssl-x.x.xx.tar.gz into the C:\ directory.
Enhance your system environment by adding C:\cygwin\usr\local\sautil\bin and C:\cygwin\usr\local\ssl\bin to the system path. You can achieve this through Control Panel -> System -> Change Settings -> Advanced -> Environment Variables -> System Variables.
While this step is recommended for convenience, it is not mandatory.
Establish a centralized working directory by creating the C:\ssl directory for your Windows installation.
In the newly created working directory, generate an openssl.cnf file. Copy and paste the provided text into openssl.cnf, saving it as C:\ssl\openssl.cnf:
# SSLeay example configuration file. # This is mostly being used for generation of certificate requests. RANDFILE = .rnd #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] certs = certs # Directory for issued certificates crl_dir = crl # Directory for certificate revocation lists (CRL) database = index.txt # Database index file new_certs_dir = certs # Default directory for new certificates certificate = cacert.pem # File path for the CA certificate serial = serial.txt # File containing the current serial number crl = crl.pem # File containing the current Certificate Revocation List (CRL) private_key = private\cakey.pem # File path for the private key RANDFILE = private\private.rnd # File path for private random number file x509_extensions = x509v3_extensions # Extensions to add to the certificate default_days = 365 # Duration for which certificates are valid (in days) default_crl_days = 30 # Duration before the next Certificate Revocation List (CRL) default_md = md5 # Message Digest algorithm to use preserve = no # Maintain passed DN (Distinguished Name) ordering # Define the policy for matching attributes in the certificate request # For CA type, the listed attributes must match, and optional # and supplied fields are exactly that :-) policy = policy_match # Define the matching criteria for CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = match commonName = supplied emailAddress = optional # Define the policy for 'anything' type # At this point, list all acceptable 'object' types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### # Certificate Request Configuration [ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes # Distinguished Name fields for the certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (city, for example) organizationName = Organization Name (company, for example) organizationalUnitName = Organizational Unit Name (section, for example) commonName = Common Name (domain name of your website, for example) commonName_max = 64 emailAddress = Email Address emailAddress_max = 40 # Additional request attributes [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 # Extensions for the certificate request [ x509v3_extensions ] # Add more extensions as needed # under ASN.1, the 0 bit would be encoded as 80 # nsCertType = 0x40 # nsBaseUrl # nsRevocationUrl # nsRenewalUrl # nsCaPolicyUrl # nsSslServerName # nsCertSequence # nsCertExt # nsDataType
Ensure proper configuration using the openssl.cnf file.
Set the OpenSSL configuration file path. Execute the following command in the command prompt:
set OPENSSL_CONF=C:\ssl\openssl.cnf
Configure Gem Engine to use Luna HSM on Windows
To set up Gem Engine for Luna HSM on Windows, complete one of the following tasks based on your specific needs:
Configure Gem Engine for Luna HSM on Windows
To configure Gem Engine for Luna HSM on Windows:
Open the crystoki.ini file and append the following configuration to the GemEngine section:
[GemEngine] LibPath = <Luna Client Installation Directory>\cryptoki.dll LibPath64 = <Luna Client Installation Directory>\cryptoki.dll EnableDsaGenKeyPair = 1 EnableRsaGenKeyPair = 1 DisablePublicCrypto = 1 EnableRsaSignVerify = 1 EnableLoadPubKey = 1 EnableLoadPrivKey = 1 DisableCheckFinalize = 1 DisableEcdsa = 1 DisableDsa = 0 DisableRand = 0 EngineInit = <slot_id>:10:11
Ensure to replace <Luna Client Installation Directory> with the actual path and <slot_id> with the specific slot ID.
Run the sautil utility to initiate a persistent session on the Luna HSM slot:
sautil -v -s <slot_id> -i 10:11 -o -q
If you are running it from Windows and the binary is located under C:\OpenSSL\sautil\bin\, use:
C:\OpenSSL\sautil\bin\sautil.exe -v -s <slot_id> -i 10:11 -o -q
Refer to the README-GEM-CONFIG file in <GemEngine_Directory>\docs for additional login methods and session details.
Configure Gem Engine for Luna HA slot or Luna Cloud HSM service on Windows
To configure Gem Engine for Luna HA slot or Luna Cloud HSM service:
Create a text file named passfile in <path_to_my_passfile> and save the partition password in it.
Open the crystoki.ini file and insert the following configuration into the GemEngine section:
[GemEngine] LibPath = <Path to cryptoki.dll> LibPath64 = <Path to cryptoki.dll> EnableDsaGenKeyPair = 1 EnableRsaGenKeyPair = 1 DisablePublicCrypto = 1 EnableRsaSignVerify = 1 EnableLoadPubKey = 1 EnableLoadPrivKey = 1 DisableCheckFinalize = 1 DisableEcdsa = 1 DisableDsa = 0 DisableRand = 0 EngineInit = "myTokenLabel":0:0:passfile=<path_to_my_passfile>\passfile EnableLoginInit = 1
Replace <Path to cryptoki.dll> and <path_to_my_passfile> with the actual paths and labels relevant to your configuration.
Verify the OpenSSL and Gem Engine integration on Windows
Follow these steps to ensure the successful integration of OpenSSL and Gem Engine:
Generate cryptographic objects for OpenSSL CMS
To prepare cryptographic objects for OpenSSL CMS, follow these steps:
Set the OPESSL_CONF path to specify the configuration file for OpenSSL:
set OPESSL_CONF=<Path to openssl.conf>
Create the necessary directories for OpenSSL operations:
C:\ssl>mkdir keys C:\ssl>mkdir requests C:\ssl>mkdir certs
Create the index.txt file, an empty (zero-byte) text file located at C:\ssl\index.txt.
Create the serial.txt file by opening C:\ssl\serial.txt, adding the string 01 on the first line, and then saving the file.
Transfer the libeay32.dll and ssleay32.dll libraries to the folder housing the sautil.exe file. Skip this step if you're utilizing Gem Engine version 1.3 or higher.
Generate a 2048-bit private key on the Luna HSM using Gem Engine for subsequent CA creation. This action generates the RSA 2048-bit key on either the Luna HSM partition or the Luna Cloud HSM service.
C:\ssl>openssl genrsa -engine gem 2048
List the generated key pair using the cmu utility:
C:\ssl> <LunaClient_Installation_Directory>\Cmu.exe list
Example:
C:\ssl> C:\Program Files\SafeNet\LunaClient\Cmu.exe list
Provide the partition password when prompted.
Create a CA certificate based on the generated key:
C:\ssl> openssl req -engine gem -new -x509 -days 365 -key rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e -keyform engine -out certs/ca.cer
Here, rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e refers to the object label for the CA private key on the Luna HSM or Luna Cloud HSM service created in a previous step.
Create a certificate request for the sender. This sender request is used to generate the sender’s certificate signed by the CA.
C:\ssl> openssl req -engine gem -newkey rsa:2048 -out requests/sender.txt
List the generated key pair using the cmu utility:
C:\ssl> <LunaClient_Installation_Directory>\Cmu.exe list
Example:
C:\ssl> C:\Program Files\SafeNet\LunaClient\Cmu.exe list
Provide the partition password when prompted.
Create a certificate request for the receiver. This receiver request is used to generate the receiver’s certificate signed by the CA.
C:\ssl> openssl req -engine gem -newkey rsa:2048 -out requests/receiver.txt
List the generated key pair using the cmu utility:
C:\ssl> <LunaClient_Installation_Directory>\Cmu.exe list
Example:
C:\ssl> C:\Program Files\SafeNet\LunaClient\Cmu.exe list
Provide the partition password when prompted.
Use the CA to sign the certificate request for the sender:
C:\ssl> openssl ca -engine gem -policy policy_anything -cert certs/ca.cer -in requests/sender.txt -keyfile rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e -keyform engine -out certs/sender.cer
Here, rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e represents the object label for the CA private key on the Luna HSM or HSM on Luna Cloud HSM service created in step 6.
Use the CA to sign the certificate request for the receiver:
C:\ssl> openssl ca -engine gem -policy policy_anything -cert certs/ca.cer -in requests/receiver.txt -keyfile rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e -keyform engine -out certs/receiver.cer
Again, rsa-private-08bde9331fa3be515d2e7db9dd1e28b36b50632e denotes the object label for the CA private key on the Luna HSM or HSM on Luna Cloud HSM service created in a previous step.
Utilize OpenSSL CMS cryptographic objects to sign, verify, encrypt, and decrypt a message
To use OpenSSL CMS to securely send and receive messages with Luna HSM:
While OpenSSL CMS relies exclusively on RSA_PKCS, Luna Cloud HSM and Luna HSM firmware versions 7.7.2 onwards do not support RSA_PKCS for encryption/decryption when operating in FIPS mode. If your HSM is configured in FIPS mode, it is recommended to refer to APPENDIX A for guidance on executing the same cryptographic operations under these specific circumstances. This ensures compatibility and adherence to security protocols while utilizing the OpenSSL CMS.
Create a text file named message.txt in the C:\ssl directory.
Sign the message.txt using the sender’s private key.
C:\ssl>openssl cms -engine gem -sign -in message.txt -signer certs\sender.cer -inkey rsa-private-605ddfab1e95bfac36eec44f291647e8a3ff5f64 -keyform engine -out sendmail.msg
Replace rsa-private-605ddfab1e95bfac36eec44f291647e8a3ff5f64 with the object label for the sender’s private key on Luna HSM or Luna Cloud HSM service.
Encrypt sendmail.msg using the receiver’s public key.
C:\ssl>openssl cms -engine gem -encrypt -in sendmail.msg -out sendmail_enc.msg certs\receiver.cer
Decrypt sendmail_enc.msg using the receiver’s private key.
C:\ssl>openssl cms -engine gem -decrypt -in sendmail_enc.msg -inkey rsa-private-a216d3b9276268459598f163ff7163aa30cbd3d0 -keyform engine -out sendmail_dec.msg
Replace rsa-private-a216d3b9276268459598f163ff7163aa30cbd3d0 with the object label for the receiver’s private key on Luna HSM or Luna Cloud HSM service.
Verify the signature of sendmail_dec.msg using the sender’s public key.
C:\ssl>openssl cms -engine gem -verify -in sendmail_dec.msg -CAfile certs\ca.cer -out out.txt certs\sender.cer
Open out.txt and compare its contents with message.txt.
Close the session with sautil, if you are using Luna HSM partition.
sautil -c -s <slot_id> -i 10:11 -q
This concludes the integration of OpenSSL with Luna Network HSM or Luna Cloud HSM service using Gem Engine on Windows.
Appendix A
To use OpenSSL CMS to securely send and receive messages with Luna HSM:
While OpenSSL CMS relies exclusively on RSA_PKCS, Luna Cloud HSM and Luna HSM firmware versions 7.7.2 onwards do not support RSA_PKCS for encryption/decryption when operating in FIPS mode. If your HSM is configured in FIPS mode, it is advisable to follow these steps to ensure the execution of the same cryptographic operations under these specific circumstances. This approach guarantees compatibility and adherence to security protocols while utilizing OpenSSL CMS for a secure and seamless cryptographic experience.
Create a text file named message.txt to serve as the content for your secure communication.
The keys for both the sender and receiver are securely stored on the Luna HSM. Utilize the object label of keys on the Luna HSM partition for decrypting and signing messages.
Sign the message.txt file using the sender's private key stored on the Luna HSM.
openssl cms -engine gem -sign -in message.txt -signer /usr/local/ssl/certs/sender/sender.cer -inkey rsa-private-613247c58f0ca0d7f2bb5a14efb2c7d53ed45322 -keyform engine -out sendmail.msg
Here, rsa-private-613247c58f0ca0d7f2bb5a14efb2c7d53ed45322 is the object label for the sender’s private key on the Luna HSM.
Encrypt the signed file sendmail.msg using the receiver's public key:
a. Generate an AES key:
openssl rand -engine gem -hex 32 > encryption_aes.key
b. Encrypt the signed message using the generated AES key:
openssl enc -aes-256-cbc -a -pbkdf2 -k encryption_aes.key -in sendmail.msg -out sendmail.enc
c. Encrypt the AES key using the receiver's public key:
openssl rsautl -encrypt -oaep -engine gem -in encryption_aes.key -out encryption_aes.enc -certin -inkey /usr/local/ssl/certs/receiver/receiver.cer
Transmit both the encrypted message (sendmail.enc) and the encrypted AES key to the receiver for secure communication.
Decrypt the received AES key (encryption_aes.enc) using the private key and then decrypt the encrypted message (sendmail.enc) using the decrypted AES key:
a. Decrypt the AES key using the Receiver’s Private Key:
openssl rsautl -decrypt -oaep -engine gem -in encryption_aes.enc -out encryption_aes.key -inkey rsa-private-489393ff23d93012ab85d859cf3386ef42fcc186 -keyform engine
Here, rsa-private-489393ff23d93012ab85d859cf3386ef42fcc186 is the object label for the receiver’s private key on the Luna HSM.
b. Decrypt the signed message using the decrypted AES key:
openssl enc -aes-256-cbc -d -a -pbkdf2 -k encryption_aes.key -in sendmail.enc -out sendmail.dec
Verify the signature of the decrypted message (sendmail.dec) using the public key associated with the sender’s certificate.
openssl cms -engine gem -verify -in sendmail.dec -CAfile /usr/local/ssl/certs/ca.cer -out sendmail.txt /usr/local/ssl/certs/sender/sender.cer
Open the sendmail.txt file and compare its contents with the original message.txt. Both files should have the same message, confirming the successful completion of all cryptographic operations.
Troubleshooting
If you're facing technical issues, browse through our troubleshooting tips to find the answers you need.
Unable to detect sautil on the system
If sautil is not detected on your system, it could be due to a prior installation of OpenSSL or if you've applied patches to the Luna Engine in the OpenSSL source code.
Solution
If sautil is not available, you can install it by following these steps:
Traverse to the toolkit and untar the luna-samples file.
Under luna-samples, locate sautil. Within sautil, find the sautil.c file.
Open sautil.c, search for #define LUNA_OSSL_ECDSA (1), and disable it.
Save and close the file.
Run the following commands in the sautil directory under luna-samples:
./configure.sh make
Verify that /usr/local/sautil/bin/sautil is installed on your system.
This should address the issue of sautil not being found on your system. If you encounter any further problems, please refer to the documentation or seek assistance from your system administrator.
Encountering an error during OpenSSL source installation with the gembuild script provided by the OpenSSL toolkit:
make[2]: *** No rule to make target `../../include/openssl/idea.h', needed by `e_idea.o'. Stop. make[2]: Leaving directory `/home/openssl-1.0.1s/crypto/evp' make[1]: *** [subdirs] Error 1 make[1]: Leaving directory `/home/openssl-1.0.1s/crypto' make: *** [build_crypto] Error 1 ERROR: There was an issue compiling OpenSSL. See /home/gemengine-1.1/logs/openssl-build.log for details.
Solution
To address this issue, insert make depend into the gembuild script at line 453, immediately after the make clean command. This error stems from a recent modification in OpenSSL, requiring the execution of make depend before make install.
Encountering a segmentation fault (core dumped) error during the OpenSSL sign operation with OpenSSL v1.1.0 and Gem Engine:
openssl req -engine gem -new -x509 -days 365 -key rsa-private-d6b5261ac7f89d6b3b80d4c0f8aea11f185b95a1 -keyform engine -out /usr/local/ssl/certs/ca.cer engine "gem" set. You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) []:IN State or Province Name (full name) []:Uttar Pradesh Locality Name (eg, city) []:Noida Organization Name (eg, company) []: Thales Organizational Unit Name (eg, section) []: HSM Common Name (eg, your website's domain name) []:ca.example.com Email Address []: Segmentation fault (core dumped)
Solution
To resolve the error caused by the Gem Engine calling the function luna_fini_p11 while in the execution path of exit(), follow these steps:
Open the e_gem.c file in the vi editor:
vi /home/gemengine-1.3/engine/e_gem.c
At line 934, comment the function as follows:
//luna_fini_p11();
Save and close the file.
Remove gem.so from the OpenSSL engine directory:
rm -rf /usr/local/ssl/lib/engines-1.1/gem.so
Recompile gem.so:
./gembuild engine-build ./gembuild engine-install
Rerun the OpenSSL sign operation command that previously encountered the segmentation fault. The certificate signing process should now complete without displaying any segmentation faults.
openssl req -engine gem -new -x509 -days 365 -key rsa-private-d6b5261ac7f89d6b3b80d4c0f8aea11f185b95a1 -keyform engine -out /usr/local/ssl/certs/ca.cer engine "gem" set. You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) []:IN State or Province Name (full name) []:Uttar Pradesh Locality Name (for example, city) []:Noida Organization Name (for example, company) []:Thales Organizational Unit Name (for example, section) []:HSM Common Name (for example, your websites domain name) []:ca.example.com Email Address []: