nCipher HSM with OpenSSL

I just finished playing with some nCipher’s HSM. Unfortunately there is no integration guide for OpenSSL that cover CHIL interface and nCipher hardware security modules.

nCipher’s installation guide is quite good, but after you finish installing hardware, drivers and daemons, you are on your own.

I found only two helpful sources: Andrea Campi’s blog entry about nCipher NetHSM and OpenSSL and Marek Marcola’s post on openssl-users mailing list.

Both guides ends on key generation and self-signed certificates. Its enough to get CHIL enabled application to work with nCipher’s HSM, but will not help you to convert any existing OpenSSL (not an CHIL-aware) application to use HSM.

CHIL enabled OpenSSL

When you have driver, hardserver and chil library for your HSM installed the next step is to install OpenSSL with CHIL support enabled. Modern Linux distribution may have CHIL already enabled. If so, there should be library in /usr/lib/ssl/engines directory.

If is missing follow OpenSSL installation steps as described in Apache2.2.x, OpenSSL 0.9.8x and nCipher Modules Integration Guide.

When OpenSSL in installed, add /opt/nfast/toolkits/hwcrhk to LD_LIBRARY_PATH:

$ export LD_LIBRARY_PATH=/opt/nfast/toolkits/hwcrhk

To check if OpenSSL is able to communicate with HSM trough CHIL interface run:

$ openssl engine -t chil
(chil) CHIL hardware engine support
     [ available ]

If CHIL is available benchmark HSM with:

$ openssl speed rsa -engine chil -elapsed -multi 50

Hardware accelerated cryptography

Use engine interface to switch to cryptography implementation from hardware security module.

#include <openssl/engine.h>

ENGINE *hwEngine = NULL;

int enable_chil()

    if (!(hwEngine = ENGINE_by_id("CHIL")))
        return -1;

    if (!ENGINE_set_default(hwEngine, ENGINE_METHOD_ALL))
        return -2;

    return 0;

When application finish its cryptography operations, it should free engine.

void disable_chil()
        hwEngine = NULL;

Hardware key protection/storage

If you want to make your private keys more secure you should use hardware key protection (or even storage).

Hardware protected keys are stored on local filesystem, but encrypted by key stored only in HSM. To generate such key use:

$ /opt/nfast/bin/generatekey hwcrhk

Answer some questions (Protected by? module, Key type? RSA, Key size? 4096, Key identifier? keyname) and your encrypted (by module, as you choose in question above) private key is saved in /opt/nfast/kmdata/local/key_hwcrhk_rsa-keyname.

When using locally stored encryption keys you load them as in this example (I use EVP interface for high-level cryptographic functions):

EVP_PKEY *pkey = NULL;

int load_key()
    fp = fopen("filename.key", "r");

    if (fp == NULL)
        return -1;

    pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);

    return 0;

When you have CHIL keys, loading them is also very simple:

void load_key_chil()
    pkey = ENGINE_load_private_key(hwEngine, "rsa-keyname", NULL, NULL);

When key is no longer in use destroy it with:

void free_key()

If application just need to do some hardware accelerated RSA or it need to use hardware protected keys those code pieces along with CHIL-enabled OpenSSL is all you need.

7 thoughts on “nCipher HSM with OpenSSL”

  1. I have a running WindowsXp application that uses openssl (1.0.0d) to load softcard-protected private keys from an Ncipher Net-HSM.
    Next step is loading ocs-protected keys.
    I use the standard UI provided in openssl.
    When calling ENGINE_load_private_key(), the ncipher nfhwcrhk library first calls the UI to get the passphrase
    (e_chil.c::hwcrhk_get_pass) which works.
    After introducing the correct passphrase, the nfhwcrhk asks to insert the smartcard (e_chil.c:hwcrhk_insert_card) and here it goes wrong. It does not detect that the card is in the slot (it is !) and keeps repeating the question.

    Anybody has been there ? (and got further :-))


  2. I have a nCipher hsm module. I am trying to use chil engine for my security operations. I followed your steps to load the private key, but ENGINE_load_private_key() fails.

    How to figure out whats the issue is?


  3. Hi,
    In my code
    ENGINE_by_id does not identify CHIL also tried with “chil”
    (hwEngine = ENGINE_by_id(“CHIL”)) is always NULL
    but the openssl say that chil is available as follows

    # openssl engine -t chil
    (chil) CHIL hardware engine support
    [ available ]
    Please help.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.