Simulated Hardware Security Module


The Alexa Voice Service (AVS) Device SDK 1.26 adds support for the Public-Key Cryptography Standards #11 (PKCS#11) API. You use this API to integrate a hardware security module (HSM) in the SDK to support encryption at rest.

Configure a simulated hardware module in the SDK

The following tutorial shows you how to configure a simulated hardware security module (HSM) for use with the AVS Device SDK. This configuration uses SoftHSM, which is a pure software implementation that uses the PKCS#11 application programming interface (API).

Use this tutorial to test how your application stores private keys with a PKCS#11-compatible service.

Prerequisites

  • The AVS Device SDK 1.26 or higher.
  • Ubuntu, Raspberry PI, macOS, or Windows.
  • SoftHSM.

    If you don't use SoftHSM, these instructions aren't applicable to you. Instead, follow your vendor-specific instructions to install and configure your token.

Ubuntu/Raspberry Pi/Mac OS

Step 1: Set PKCS#11 parameters

Set the following PKCS#11 parameters in your AVS Device SDK configuration file. Make sure that the ACSDK_PKCS11_MODULE parameter points to your PKCS#11 interface library. The SDK uses these values when you generate a token.

# example values. Change as necessary

ACSDK_PKCS11_TOKEN=ACSDK
ACSDK_PKCS11_PIN=1234
ACSDK_PKCS11_MAIN_KEY=acsdkMain
ACSDK_PKCS11_MODULE=/usr/lib/softhsm/libsofthsm2.so

Step 2: Install and configure SoftHSM

In this step, you install SoftHSM, configure it, and create a token to manage your HSM secrets.

  1. Install SoftHSM:

    # Ubuntu and Raspberry PI
    sudo apt-get install softhsm2
    
    # Mac OS
    brew install softhsm2
    
  2. Create a user-specific SoftHSM configuration.

    mkdir -p $HOME/.softhsm2/tokens
    chmod -R 700 $HOME/.softhsm2
    cat >> $HOME/.profile << END
    
    # User Config for SoftHSM
    
    SOFTHSM2_CONF="$HOME/.softhsm2/softhsm2.conf"
    END
    export SOFTHSM2_CONF="$HOME/.softhsm2/softhsm2.conf"
    cat > $HOME/.softhsm2/softhsm2.conf << END
    directories.tokendir = $HOME/.softhsm2/tokens
    objectstore.backend = file
    END
    

    You can view more information about your SoftHSM configuration with the following command.

    man softhsm2.conf
    
  3. Create a PKCS11 token using the values you configured in Step 1: Set PKCS#11 parameters.

    softhsm2-util --init-token --free \
      --label $ACSDK_PKCS11_TOKEN \
      --pin $ACSDK_PKCS11_PIN
    

Step 3: Create your HSM secret

The AVS Device SDK uses AES-GCM encryption to protect sensitive information. To maintain security, only manage your main encryption key with HSM and make sure it's not accessible from anywhere outside of your SDK configuration. Only provision your encryption key a single time per device.

Your key must have the following properties:

  • Object type: AES
  • Size: 256 bits
  • Key is private: Software must use a user PIN to access key functions
  • Key is sensitive: Software can't retrieve keys from HSM

To create an HSM secret

  1. Install OpenSC.

    # Ubuntu and Raspberry PI
    sudo apt-get install opensc
    
    # Mac OS
    brew install opensc
    
  2. Create a private and sensitive AES secret object in HSM.

    OpenSC version 0.18.0 and lower doesn't support the --sensitive flag. If you're using an older version of OpenSC and encounter an error, omit --sensitive.

    To determine what version of OpenSC you have, run opensc-tool -i.

    pkcs11-tool --module $ACSDK_PKCS11_MODULE \
      --login \
      --pin $ACSDK_PKCS11_PIN \
      --token-label $ACSDK_PKCS11_TOKEN \
      --keygen \
      --key-type aes:32 \
      --private \
      --sensitive \
      --label $ACSDK_PKCS11_MAIN_KEY
    

Step 4: Verify your HSM secret

Verify that you generated your HSM secret correctly by checking the PKCS11 output. In your output, make sure there is exactly one token with the $ACSDK_PKCS11_TOKEN label, and exactly one object with $ACSDK_PKCS11_MAIN_KEY label.

pkcs11-tool --module $ACSDK_PKCS11_MODULE \
  --login --pin $ACSDK_PKCS11_PIN \
  --token-label $ACSDK_PKCS11_TOKEN -LO

The following example shows a real output similar to what you should receive.

Available slots:
Slot 0 (0x690a7cc4): SoftHSM slot ID 0x690a7cc4
  token label        : ACSDK
  token manufacturer : SoftHSM project
  token model        : SoftHSM v2
  token flags        : login required, rng, token initialized, PIN initialized, other flags=0x20
  hardware version   : 2.2
  firmware version   : 2.2
  serial num         : dc4d8ada690a7cc4
  pin min/max        : 4/255
Slot 1 (0x1): SoftHSM slot ID 0x1
  token state:   uninitialized
Using slot 0 with a present token (0x690a7cc4)
Secret Key Object; AES length 32
warning: PKCS11 function C_GetAttributeValue(VALUE) failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11)

  label:      acsdkMain
  Usage:      encrypt, decrypt, verify, wrap, unwrap

Step 5: Build the SDK with SoftHSM

Now that you have set up SoftHSM, you can build the SDK with the -DPKCS11=ON flag.

When you run your CMake command, make sure that your AlexaClientSDKConfig.json contains the values from Step 1: Set PKCS#11 parameters.

The following example shows a full CMake build command on aRaspberry Pi, with SoftHSM included.

cmake /home/pi/sdk-folder/sdk-source/avs-device-sdk \
-DPKCS11=ON \ 
-DGSTREAMER_MEDIA_PLAYER=ON \
-DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH=/home/pi/sdk-folder/third-party/portaudio/lib/.libs/libportaudio.a \
-DPORTAUDIO_INCLUDE_DIR=/home/pi/sdk-folder/third-party/portaudio/include
-DCURL_INCLUDE_DIR=/home/pi/sdk-folder/third-party/curl-7.67.0/include/curl \
-DCURL_LIBRARY=/home/pi/sdk-folder/third-party/curl-7.67.0/lib/.libs/libcurl.so
Windows

Step 1: Set PKCS#11 parameters

Set the following PKCS#11 parameters in your AVS Device SDK configuration file. Make sure that the ACSDK_PKCS11_MODULE parameter points to your PKCS#11 interface library. The SDK uses these values when you generate a token.

# example values. Change as necessary.

$Env:ACSDK_PKCS11_TOKEN='ACSDK'
$Env:ACSDK_PKCS11_PIN='1234'
$Env:ACSDK_PKCS11_MAIN_KEY='acsdkMain'
$Env:ACSDK_PKCS11_MODULE='C:\SoftHSM2\lib\softhsm2-x64.dll'

Step 2: Install and configure SoftHSM

In this step, you install SoftHSM, configure it, and create a token to manage your HSM secrets.

  1. Install SoftHSM:

    C:\ProgramData\chocolatey\bin\choco install softhsm
    $Env:SOFTHSM2_CONF='C:\SoftHSM2\etc\softhsm2.conf'
    [System.Environment]::SetEnvironmentVariable('SOFTHSM2_CONF',$Env:SOFTHSM2_CONF)
    $Env:Path += ';C:\Program Files\OpenSC Project\OpenSC\tools'
    
  2. Create a PKCS11 token using the values you configured in Step 1: Set PKCS#11 parameters.

    softhsm2-util --init-token --free `
      --label $Env:ACSDK_PKCS11_TOKEN `
      --pin $Env:ACSDK_PKCS11_PIN
    

Step 3: Create your HSM secret

The AVS Device SDK uses AES-GCM encryption to protect sensitive information. To maintain security, only manage your main encryption key with HSM and make sure it's not accessible from anywhere outside of your SDK configuration. Only provision your encryption key a single time per device.

Your key must have the following properties:

  • Object type: AES
  • Size: 256 bits
  • Key is private: Software must use a user PIN to access key functions
  • Key is sensitive: Software can't retrieve keys from HSM

To create an HSM secret

  1. Install OpenSC.

    choco install opensc
    $Env:Path += ';C:\Program Files\OpenSC Project\OpenSC\tools'  
    
  2. Create a private and sensitive AES secret object in HSM.

    OpenSC version 0.18.0 and lower doesn't support the --sensitive flag. If you're using an older version of OpenSC and encounter an error, omit --sensitive.

    To determine what version of OpenSC you have, run opensc-tool -i.

    pkcs11-tool --module $Env:ACSDK_PKCS11_MODULE `
      --login `
      --pin $Env:ACSDK_PKCS11_PIN `
      --token-label $Env:ACSDK_PKCS11_TOKEN `
      --keygen `
      --key-type aes:32 `
      --private `
      --sensitive `
      --label $Env:ACSDK_PKCS11_MAIN_KEY
    

Step 4: Verify your HSM secret

Verify that you generated your HSM secret correctly by checking the PKCS11 output. In your output, make sure there is exactly one token with the $ENV:ACSDK_PKCS11_TOKEN label, and exactly one object with $ENV:ACSDK_PKCS11_MAIN_KEY label.

pkcs11-tool --module $Env:ACSDK_PKCS11_MODULE `
  --login --pin $Env:ACSDK_PKCS11_PIN `
  --token-label $Env:ACSDK_PKCS11_TOKEN -O

The following example shows a real output similar to what you should receive.

Secret Key Object; AES length 32
warning: PKCS11 function C_GetAttributeValue(VALUE) failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11)

label: <value of ACSDK_PKCS11_MAIN_KEY>
Usage: encrypt, decrypt, verify, wrap, unwrap
Access: sensitive, always sensitive, never extractable, local

If the output contains multiple keys with the same label, delete the extra one with the following command:

pkcs11-tool --module $Env:ACSDK_PKCS11_MODULE `
  --login --pin $Env:ACSDK_PKCS11_PIN `
  --token-label $Env:ACSDK_PKCS11_TOKEN --delete-object `
  --label $Env:ACSDK_PKCS11_MAIN_KEY`

Was this page helpful?

Last updated: Aug 15, 2022