Procedures
This guide describes several scenarios using module, softcard and OCS protection.
Install the HSM
Install the HSM by following the instructions in the Installation Guide for the HSM.
We recommend that you install the HSM before configuring the Security World Software in the OpenSSL server.
Install the Security World Software and create the security world
To install the Security World Software and create the security world:
-
On the computer that you want to use OpenSSL, install the latest version of the Security World Software as described in the Installation Guide for the HSM.
Entrust recommends that you uninstall all existing nShield software before you install new nShield software.
-
Create the security world as described in the User Guide, creating the ACS and OCS that you require.
Install OpenSSL and required packages
The installation of OpenSSL varies depending on the operating system.
Installation on RedHat Linux 9:
sudo yum install -y openssl-pkcs11 openssl-libs mod_ssl opensc expect
Set up the PKCS #11 engine
To avoid problems associated with the Entrust supplied OpenSSL, which is used internally by generatekey
to make certificates, ensure that /opt/nfast/bin
is NOT at the front of your $PATH
.
You can confirm that the right binary is being run with the following command:
% which openssl
/usr/bin/openssl
If this command returns anything inside /opt/nfast
, check your $PATH
variable.
Configure OpenSSL
-
Locate the OpenSSL configuration file:
% openssl version -d OPENSSLDIR: "/etc/pki/tls"
The minimum configuration is similar to the following:
# # OpenSSL example configuration file. # This is mostly being used for generation of certificate requests. # # Note that you can include other files from the main configuration # file using the .include directive. #.include filename .include = /etc/pki/tls/openssl.original.cnf # This definition stops the following lines choking if HOME isn't # defined. HOME = . RANDFILE = $ENV::HOME/.rnd #OJW: nShield PKCS11 openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 #dynamic_path = /usr/lib/ssl/engines/libpkcs11.so #Ubuntu16.04 #dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/pkcs11.so #Debian9&10, Ubuntu18.04 #dynamic_path = /usr/lib64/openssl/engines/pkcs11.so #RHEL/CentOS7 #dynamic_path = /usr/lib64/engines-1.1/pkcs11.so #RHEL/CentOS8 dynamic_path = /usr/lib64/engines-3/pkcs11.so #RHEL 9 MODULE_PATH = /opt/nfast/toolkits/pkcs11/libcknfast.so init = 0 #!
The following message can appear when you are creating certificates:
unable to find 'distinguished_name' in config problems making Certificate Request 140493626791824:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:324:group=req name=distinguished_name
If it does, you need to add the following to your OpenSSL configuration, adjusted to your organization’s values:
# [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = US ST = FL L = Sunrise O = Entrust OU = nShield CN = www.entrust.com [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = www.entrust.com DNS.2 = entrust.com
Make sure the server’s host name matches the CN in the certificate.
-
Create or edit the
/etc/pki/tls/openssl.pkcs11.cnf
file:% sudo vi /etc/pki/tls/openssl.pkcs11.cnf
-
Enter the settings from above, and save the file.
Set up /opt/nfast/cknfastrc
You might have to add the following variables to the /opt/nfast/cknfastrc
file.
They are referenced in this guide to address specific situations and their use depends on your current environment.
CKNFAST_DEBUG=10
CKNFAST_DEBUGFILE=/path/to/debug/file
CKNFAST_FAKE_ACCELERATOR_LOGIN=1
CKNFAST_LOADSHARING=1
Turn debug off in a production environment. |
Test the configuration
-
Export the
OPENSSL_CONF
environment variable:% export OPENSSL_CONF=/etc/pki/tls/openssl.pkcs11.cnf
-
Test the configuration:
% openssl engine -tt -c -v (pkcs11) pkcs11 engine [RSA, rsaEncryption, id-ecPublicKey] [ available ] SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
Debugging notes
Security world permissions
The following message can appear:
Unable to load module /opt/nfast/toolkits/pkcs11/libcknfast.so
If it does, it indicates that there is no security world. Make sure you create a security world first.
Missing PKCS #11 engine in the output
If you don’t see the PKCS #11 engine in the output, check the dynamic_path
line in the openssl.pkcs11.cnf
configuration file.
This may vary on other platforms and other operating system versions.
dynamic_path = /usr/lib64/engines-3/pkcs11.so #RHEL 9
Test cases
The test cases cover module, softcard and OCS protection. Create an OCS card and a softcard so they can be used with the test cases.
-
Create an OCS card called
testOCS
:% createocs -m1 -s2 --persist -Q 1/1 -N testOCS
-
Create a softcard called
testSC
:% ppmk -n testSC
Test case execution
-
Generate an RSA key pair where private key is protected with HSM using
pkcs11-tool
:Module protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --slot-index 0 -l \ --pin ncipher --keypairgen --key-type rsa:2048 --label rsa_key_1
Softcard protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --token-label testSC \ -l --pin ncipher --keypairgen --key-type rsa:2048 --label rsa_key_1
OCS protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --token-label testOCS \ -l --pin ncipher --keypairgen --key-type rsa:2048 --label rsa_key_2
-
Generate an RSA key pair where private key is protected with HSM using
generatekey
:Module protection
% generatekey -b -g -m1 pkcs11 plainname=rsa_key_2 type=rsa \ protect=module size=2048
Softcard protection
% generatekey -b -g -m1 pkcs11 plainname=rsa_key_2 type=rsa \ protect=softcard size=2048 softcard=testSC
OCS protection
% generatekey -b -g -m1 pkcs11 plainname=rsa_key_2 type=rsa \ protect=token size=2048 cardset=testOCS
-
List the keys that have been generated:
% nfkminfo -l
-
Generate a DSA key pair where private key is protected with HSM using
generatekey
:Module protection
% generatekey -b -g -m1 pkcs11 plainname=dsa_key_1 type=dsa \ protect=module size=2048
Softcard protection
% generatekey -b -g -m1 pkcs11 plainname=dsa_key_1 type=dsa \ protect=softcard size=2048 softcard=testSC
OCS protection
% generatekey -b -g -m1 pkcs11 plainname=dsa_key_1 type=dsa \ protect=token size=2048 cardset=testOCS
-
List the keys that have been generated:
% nfkminfo -l
-
Generate an ECC key pair where private key is protected with HSM using
generatekey
:Module protection
% generatekey -b -g -m1 pkcs11 plainname=ecc_key_1 \ type=ECDSA curve=NISTP224 protect=module
Softcard protection
% generatekey -b -g -m1 pkcs11 plainname=ecc_key_1 \ type=ECDSA curve=NISTP224 protect=softcard softcard=testSC
OCS protection
% generatekey -b -g -m1 pkcs11 plainname=ecc_key_1 \ type=ECDSA curve=NISTP224 protect=token cardset=testOCS
-
List the keys that have been generated:
% nfkminfo -l
-
Generate a symmetric AES key protected with HSM using
pkcs11-tool
:The following warning appears during execution, for module, softcard and OCS protection but it does not affect key creation.
warning: PKCS11 function C_GetAttributeValue(VALUE) failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11)
If you don’t supply the
--private
option, for softcard and OCS protection, the following error appears:error: PKCS11 function C_GenerateKey failed: rv = CKR_TEMPLATE_INCONSISTENT (0xd1) Aborting.
Module protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --slot-index 0 \ -l --pin ncipher --keygen --key-type AES:32 --label aes_key_1
Softcard protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --token-label testSC \ -l --pin ncipher --private --keygen --key-type AES:32 --label aes_key_1
OCS protection
% pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so --token-label testOCS \ -l --pin ncipher --private --keygen --key-type AES:32 --label aes_key_1
-
Generate a symmetric AES key protected with HSM using
generatekey
:Module protection
% generatekey -b -g -m1 pkcs11 plainname=aes_key_2 type=aes \ protect=module size=256
Softcard protection
% generatekey -b -g -m1 pkcs11 plainname=aes_key_2 type=aes \ protect=softcard size=256 softcard=testSC
OCS protection
% generatekey -b -g -m1 pkcs11 plainname=aes_key_2 type=aes \ size=256 protect=token cardset=testOCS
-
List the keys that have been generated:
% nfkminfo -l
-
Generate CSR from RSA Key:
Module protection:
% openssl req -engine pkcs11 -keyform engine \ -key pkcs11:token=loadshared%20accelerator;pin-value=ncipher;type=private;object=rsa_key_2 \ -new -out /tmp/csrfile.csr
Softcard protection
% openssl req -engine pkcs11 -keyform engine \ -key pkcs11:token=testSC;pin-value=ncipher;type=private;object=rsa_key_2 \ -new -out /tmp/csrfile.csr
OCS protection
% openssl req -engine pkcs11 -keyform engine \ -key pkcs11:token=testOCS;pin-value=ncipher;type=private;object=rsa_key_2 \ -new -out /tmp/csrfile.csr
-
Check the CSR file:
% ls -al /tmp/csrfile.csr -rw-r--r--. 1 cccc cccc 1086 Apr 17 11:17 /tmp/csrfile.csr % file /tmp/csrfile.csr /tmp/csrfile.csr: PEM certificate request
-
Generate a self-signed certificate:
Module protection
% openssl req -x509 -new -engine pkcs11 -keyform engine \ -key pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/certificate.pem -days 365
Softcard protection
% openssl req -x509 -new -engine pkcs11 -keyform engine \ -key pkcs11:token=testSC;pin-value=ncipher;type=private;object=rsa_key_2 \ -out /tmp/certificate.pem -days 365
OCS protection
% openssl req -x509 -new -engine pkcs11 -keyform engine \ -key pkcs11:token=testOCS;pin-value=ncipher;type=private;object=rsa_key_2 \ -out /tmp/certificate.pem -days 365
-
Check the self-signed certificate:
% ls -al /tmp/certificate.pem -rw-r--r--. 1 cccc cccc 1224 Apr 17 11:26 /tmp/certificate.pem % file /tmp/certificate.pem /tmp/csrfile.csr: PEM certificate request
-
Before you import the self-signed certificate, list the available keys:
% nfkminfo -l
-
Import the certificate:
When you import the certificate, the key and the certificate will have the same label. The signed certificate is also imported but it will be protected by the module.
Module protection
% ckcerttool -n -f /tmp/module.pem -L rsa_key_2 \ -k uaa48299ba93d20591d8b914f187de24afec50775b
Softcard protection
% ckcerttool -c testSC -f /tmp/softcard.pem -L rsa_key_2 \ -k ucb0d00b55bc6a5fe7aa1caf88bc9c8e70a26f051a-34668473dab910e0497ae44bb9e0b1fb5c8d2d3e
OCS protection
% ckcerttool -c testOCS -f /tmp/ocs.pem -L rsa_key_2 \ -k uc063c0d5280a8c3046acc6b8dce312387ce0e3855-166c4e5fedb0995db1bbe0c1ffecf4b537bab85e
-
List the available keys again:
% nfkminfo -l
-
Look for the imported certificate by running
cklist
that lists certificates and the keys:% cklist -pncipher -n -l rsa_key_2
Look for:
CKA_CLASS CKO_CERTIFICATE
andCKA_LABEL "rsa_key_2"
. -
Encrypt and decrypt a text file with the RSA key.
During FIPS Level 3 testing the following error was found at the decryption step:
Public Key operation error 409C08B1AC7F0000:error:41800070:PKCS#11 module:ERR_CKR_error:Mechanism invalid:p11_rsa.c:150:
This happens because
CKM_RSA_PKCS
is not allowed in FIPS mode. You have to use OAEP, which is more secure. Add theoaep
flag toopenssl pkeyutl
:-pkeyopt rsa_padding_mode:oaep
Create a file to be encrypted with the RSA key:
This file was created to be encrypted. Just a regular text file.
-
Encrypt the file with the RSA key:
Module protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/encryptedfile.txt -pkeyopt rsa_padding_mode:oaep
Softcard protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=testSC;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/encryptedfile.txt -pkeyopt rsa_padding_mode:oaep
OCS protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=testOCS;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/encryptedfile.txt -pkeyopt rsa_padding_mode:oaep
-
Verify the encryption by decrypting the file:
Module protection
% openssl pkeyutl -decrypt -engine pkcs11 -keyform engine -in /tmp/encryptedfile.txt \ -inkey pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/decryptedfile.txt -pkeyopt rsa_padding_mode:oaep
Softcard protection
% openssl pkeyutl -decrypt -engine pkcs11 -keyform engine -in /tmp/encryptedfile.txt \ -inkey pkcs11:token=testSC;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/decryptedfile.txt -pkeyopt rsa_padding_mode:oaep
OCS protection
% openssl pkeyutl -decrypt -engine pkcs11 -keyform engine -in /tmp/encryptedfile.txt \ -inkey pkcs11:token=testOCS;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/decryptedfile.txt -pkeyopt rsa_padding_mode:oaep
-
List the contents of the decrypted file:
% cat /tmp/decryptedfile.txt This file was created to be encrypted. Just a regular text file.
-
Sign a file with existing RSA key.
Create a file to encrypt:
This file was created to be encrypted. Just a regular text file.
-
Perform the signing:
Module protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt
Softcard protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=testSC;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt
OCS protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=testOCS;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt
-
Extract the public key:
Module protection
% openssl rsa -engine pkcs11 -inform ENGINE -pubout -text \ -in pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/pub.signature.key
Softcard protection
% openssl rsa -engine pkcs11 -inform ENGINE -pubout -text \ -in pkcs11:token=testSC;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/pub.signature.key
OCS protection
% openssl rsa -engine pkcs11 -inform ENGINE -pubout -text \ -in pkcs11:token=testOCS;pin-value=ncipher;object=rsa_key_2 \ -out /tmp/pub.signature.key
-
Verify the signature:
% openssl dgst -verify /tmp/pub.signature.key -signature /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt Verified OK
-
Encrypt and decrypt a text file with the AES key.
Create a file to encrypt:
This file was created to be encrypted. Just a regular text file.
-
Perform the encryption:
Module protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=aes_key_2 \ -out /tmp/encryptedfile.txt Engine "pkcs11" set. No private keys found. Key not found. PKCS11_get_private_key returned NULL Could not read private key from org.openssl.engine:pkcs11:pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=aes_key_2 408CDDF3FB7F0000:error:40000065:pkcs11 engine:ERR_ENG_error:object not found:eng_back.c:974: 408CDDF3FB7F0000:error:13000080:engine routines:ENGINE_load_private_key:failed loading private key:crypto/engine/eng_pkey.c:79: pkeyutl: Error initializing context
Softcard protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=testSC;pin-value=ncipher;object=aes_key_2 \ -out /tmp/encryptedfile.txt Engine "pkcs11" set. No private keys found. Key not found. PKCS11_get_private_key returned NULL Could not read private key from org.openssl.engine:pkcs11:pkcs11:token=testSC;pin-value=ncipher;object=aes_key_2 40AC8394D97F0000:error:40000065:pkcs11 engine:ERR_ENG_error:object not found:eng_back.c:974: 40AC8394D97F0000:error:13000080:engine routines:ENGINE_load_private_key:failed loading private key:crypto/engine/eng_pkey.c:79: pkeyutl: Error initializing context
OCS protection
% openssl pkeyutl -encrypt -engine pkcs11 -keyform engine -in /tmp/filetoencrypt.txt \ -inkey pkcs11:token=testOCS;pin-value=ncipher;object=aes_key_2 -out /tmp/encryptedfile.txt Engine "pkcs11" set. No private keys found. Key not found. PKCS11_get_private_key returned NULL Could not read private key from org.openssl.engine:pkcs11:pkcs11:token=testOCS;pin-value=ncipher;object=aes_key_2 403CF2A61C7F0000:error:40000065:pkcs11 engine:ERR_ENG_error:object not found:eng_back.c:974: 403CF2A61C7F0000:error:13000080:engine routines:ENGINE_load_private_key:failed loading private key:crypto/engine/eng_pkey.c:79: pkeyutl: Error initializing context
It seems it is not possible to encrypt a file with an AES key. More information:
-
Sign a file with an existing ECC key.
Create a file to encrypt:
This file was created to be encrypted. Just a regular text file.
-
Perform the signing:
Module protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=loadshared%20accelerator;pin-value=ncipher;object=ecc_key_1 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt Engine "pkcs11" set. 2024-04-17 15:10:15 [106907] t40ac5c9f757f0000: pkcs11: 000008CB Error: pData: length 32 but NULL buffer
Softcard protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=testSC;pin-value=ncipher;object=ecc_key_1 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt Engine "pkcs11" set. 2024-04-17 15:12:59 [107022] t405c6f45a57f0000: pkcs11: 000008CB Error: pData: length 32 but NULL buffer
OCS protection
% openssl dgst -sha256 -engine pkcs11 -keyform engine \ -sign pkcs11:token=testOCS;pin-value=ncipher;object=ecc_key_1 \ -out /tmp/filetoencrypt.sig /tmp/filetoencrypt.txt Engine "pkcs11" set. 2024-04-17 15:14:47 [107133] t405c9dbcd27f0000: pkcs11: 000008CB Error: pData: length 32 but NULL buffer
This test case fails. The text file cannot be signed with an ECC key. Entrust believes this to be an OpenSSL 3 issue.
FIPS Level 3 remarks and recommendations
Recommendations for when a FIPS Level 3 world file is used for the HSM configuration:
-
Create an OCS card 1/N where N is at least the number of HSMs being used in the configuration.
-
Leave the OCS card inserted on HSM used in the configuration.
-
The OCS card must be present any time new key material is created (FIPS authorization).