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 libchil.so library in /usr/lib/ssl/engines directory.

If libchil.so 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()
{
    ENGINE_load_builtin_engines();

    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()
{
    if(hwEngine)
    {
        ENGINE_finish(hwEngine);
        hwEngine = NULL;
        ENGINE_cleanup();
    }
}

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()
{
    EVP_PKEY_free(pkey);
}

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.

6 comments to nCipher HSM with OpenSSL

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>