Getting Started: HSM4 with Raspberry Pi

Install HSM4 Developer Kit onto Raspberry Pi


Prerequisites

  • Raspberry Pi 3 or 4.
  • Raspbian or Ubuntu is installed.
    • Other Linux distributions will work, but may require extra configuration. We will gladly provide guidance, but cannot guarantee support. For information see the Operating Systems section.
  • Adequate power supply is used (5V).
    • If the Red Power LED on the Pi is not illuminated this means the supply voltage is inadequate.
    • More info here.

1. Install the HSM4

Fit your HSM onto the PiZero HAT (Hardware Attached on Top). The connector plugs into the pins on the board.


2. Install Battery (Optional, but highly recommended)

Battery installation is highly recommended if your device is vulnerable to physical access. If main power to the HSM is removed, then the real-time-clock and tamper detect features will not function. The battery is used to maintain operation of the real-time-clock and tamper detect features in the event that main power (from the GPIO header) is lost.

Primary Battery Holder (Recommended)

YourPiZero HAT can be fitted with a 3V CR2032 coincell. This battery should last 3-5 years. We recommend using a high quality one like this.

IMPORTANT: Note the correct polarity with +ve facing upwards !!

Optional Battery Connector (Alternative)

Caution: Ensure you select the right connector type-- Molex 51021-0200-B (1.25mm Pitch). You can purchase the battery here.

Battery should look like this:

Mating component specifications:

Plug wired CR2032 battery into optional battery connector, located below.


3. Install Pi HAT

- Power off your Raspberry Pi before proceeding

Follow the above pictures to position the PiHAT. The HSM and battery should be facing the Raspberry Pi and concealed from view. You should not be able to see the 3V battery slot when looking down at your pi.

WARNING: Be sure all the GPIO pins are aligned and have a respective slot. If misaligned, this could cause damage to the HSM, PiHAT, and/or your Raspberry Pi.

Once aligned properly, press firmly down onto the header. Your PiHAT should fit relatively snug.

Now power up the Pi and you will see a blue LED blinking rapidly and consistently (5 blinks per second). This indicates the HSM is operational but not configured. If the blue LED blinks erratically, or not at all, then there is an installation error and you should check your connections.

HSM4-LED-5times-per-second


4. Turn on the I2C Bus

  1. Log in to your pi and run sudo raspi-config
  2. Select Interfacing Options → I2C →
    Would you like the ARM I2C interface to be enabled? select (Yes), enter, enter
  3. Arrow Right to Finish

Your I2C bus is now on and ready to talk to the HSM.

The default I2C address for HSM is 0x30. If needed, you can change the I2C Address after following steps 5 and 6.


5. Install Software Packages and API

For a bare Raspbian system, first login to your Pi.

Then download and install the necessary Zymbit services onto your Pi.
curl -G https://s3.amazonaws.com/zk-sw-repo/install_zk_sw.sh | sudo bash
(grab a cup of coffee because this will take between 4 and 20 minutes).


6. Developer Mode (temporary binding)

When the software installation has completed, reboot your Pi. After rebooting, the Pi will temporarily bind the HSM to itself. Once bound, the blue LED should blink once every 3 seconds.

HSM4-LED-every-3-seconds

Your HSM is now in Developer Mode. The binding is temporary and the HSM can be moved to another Pi and the binding process repeated. Now is the time to prototype. Do all development work with the HSM in this mode. You can safely test the self-destruct features here. A self-destruct in this mode will stop all HSM functionality until the Pi is rebooted. Only in production mode will the HSM actually self-destruct.

Before moving on to Production mode, ensure your application is running correctly. Explore our HSM resources for help:

If you have any questions, feel free to create a new post here in the Community and we will get back to you.

To test some of the API and see it’s functionality, you can also run these pre-installed scripts:
python /usr/local/share/zymkey/examples/zk_app_utils_test.py
python /usr/local/share/zymkey/examples/zk_crypto_test.py


7. Production Mode (permanent binding)

When you are ready to deploy your system into the field we recommend that you permanently bind your HSM to a specific host Pi and SD card.

WARNING: THIS BINDING PROCESS IS PERMANENT AND CANNOT BE REVERSED. PAY ATTENTION TO THE FOLLOWING:

  • Your specific HSM will be locked to the specific host Pi and it is impossible to move or bind your HSM to another Pi. There are no factory resets, masterkeys or other forms of recovery.

  • If you are using the perimeter_detect features, the sequence in which you arm, disarm is very important in production mode. Be sure to follow the process steps below.

  • Once you have locked your HSM into production mode, Zymbit cannot guarantee its operation if you subsequently do a major distribution upgrade (e.g. Raspbian Jessie to Stretch). Contact Zymbit for more information.

  • If you decide that you are not ready for permanent binding then leave it in developer mode, but beware this makes it easier for a bad actor to replace the host with rogue hardware.

Moving from Developer Mode to Production Mode

Pre-binding Checklist
Make sure this is done before continuing

  1. Install the battery onto HAT and install HSM onto HAT
  2. Place HAT onto the Pi (with power down on the Pi)
  3. Turn on the Pi (LED: 5 blinks per second)
  4. Configure the I2C bus
  5. Install HSM interface software package (LED: 1 blink every 3 seconds)
  6. Set Perimeter Event Actions to “none” or “notify only” (It is “none” by default)
  7. Create your LUKS encrypted volume (If encrypting SD card)
  8. Install your applications into your encrypted volume (If encrypting SD card)
  9. Confirm your system and applications work fully as you intend

With the Zymkey, a physical tab was cut to go into production mode. In the HSM models, to go into production mode it only requires a function call followed by a reboot.

The API function lock binding puts the HSM into production mode. Below are three scripts which check the current binding info, lock the HSM binding, then check the current binding info again. Remove the comments around the lock binding function to move to production mode.

C - zkLockBinding
void check_code(int code, char* location){
  if (code < 0)
  {
    fprintf(stderr, "FAILURE: %s - %s\n", location, strerror(code));
  }
  else if (code >= 0)
  {
    fprintf(stdout, "SUCCESS: %s - %d\n", location, code);
  }
}

void HSM_soft_bind(zkCTX zk_ctx)
{
  bool binding_is_locked = false;
  bool is_bound = false;
  int ret = zkGetCurrentBindingInfo(zk_ctx, &binding_is_locked, &is_bound);
  check_code(ret, "zkGetCurrentBindingInfo");
  printf("Binding is locked: ");
  printf(binding_is_locked ? "true" : "false");
  printf("\n");
  printf("HSM is bound: ");
  printf(is_bound ? "true" : "false");
  printf("\n\n");

  //ret = zkLockBinding(zk_ctx);
  //if(binding_is_locked && is_bound)
  //{
  //  check_code(ret, "zkLockBinding - Already Bound");
  //}
  //else
  //{
  //  check_code(ret, "zkLockBinding");
  //}
  //printf("\n");

  ret = zkGetCurrentBindingInfo(zk_ctx, &binding_is_locked, &is_bound);
  check_code(ret, "zkGetCurrentBindingInfo");
  printf("Binding is locked: ");
  printf(binding_is_locked ? "true" : "false");
  printf("\n");
  printf("HSM is bound: ");
  printf(is_bound ? "true" : "false");
  printf("\n\n");
}

int main()
{
  zkCTX zk_ctx;
  int status = zkOpen(&zk_ctx);
  check_code(status, "zkOpen");
  printf("\n\n");

  HSM_soft_bind(zk_ctx);

  status = zkClose(zk_ctx);
  check_code(status, "zkClose");
  printf("\n");

  return 0;
}
C++ - lockBinding
#include <stdio.h>
#include <zkAppUtilsClass.h>

using namespace std;
using namespace zkAppUtils;

void HSM_soft_bind(zkClass* zk_inst)
{
  bool binding_is_locked = false;
  bool is_bound = false;
  zk_inst->getCurrentBindingInfo(binding_is_locked, is_bound);
  printf("Binding is locked: ");
  printf(binding_is_locked ? "true" : "false");
  printf("\n");
  printf("HSM is bound: ");
  printf(is_bound ? "true" : "false");
  printf("\n");

  //zk_inst->lockBinding();
  //printf("lockBinding successful\n");

  zk_inst->getCurrentBindingInfo(binding_is_locked, is_bound);
  printf("Binding is locked: ");
  printf(binding_is_locked ? "true" : "false");
  printf("\n");
  printf("HSM is bound: ");
  printf(is_bound ? "true" : "false");
  printf("\n");
}

int main()
{
  zkClass* zk_inst;
  zk_inst = new zkClass();
 
  HSM_soft_bind(zk_inst);

  delete zk_inst;
  return 0;
}
Python - lock_binding
import zymkey
tup = zymkey.client.get_current_binding_info()
print("HSM is bound: " + str(tup[1]))
print("Binding is locked: " + str(tup[0]))

#zymkey.client.lock_binding()

tup = zymkey.client.get_current_binding_info()
print("HSM is bound: " + str(tup[1]))
print("Binding is locked: " + str(tup[0]))

Once you have successfully moved to Production Mode and rebooted your system, the LED blink pattern will change to 3 rapid blinks once every 3 seconds to indicate that HSM has bound to the host in production mode.

HSM4-LED-3times-every-3-seconds

Prime perimeter detect (optional)

After bind locking the HSM, if using the perimeter detect features, prime your perimeter detect using the API.

  1. Close your perimeter circuit(s) (enclosure lid)
  2. Clear Perimeter Detect Events
  3. Get Perimeter Detect Info to confirm prior events are cleared and the perimeter is closed.
  4. If the Perimeter Detect Event returns clear, then you can ‘arm your system’ as you require by setting Set Perimeter Event Actions to “none”, “notify” or “selfdestruct” (You can only do this once!).
  5. Your system is now armed.

Please see Zymbit software documentation for further details.