Getting Started: HSM6 with JETSON NANO

Install HSM6 Developer Kit onto Jetson Nano


Prerequisites

  • Ubuntu/Tegra 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).

1. Install the HSM6

Fit your HSM onto the 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)

Your 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 HAT

- Power off your Jetson before proceeding

Follow the above pictures to position the Hat. The HSM6 and battery should be facing the Jetson and concealed from view. You should not be able to see the 3V battery slot when looking down at your Jetson.

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

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

Now power up the Jetson 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

For the Jetson Nano, the Operating System - Tegra - is based on Ubuntu. The I2C bus is enabled by default. There are no additional steps required.

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


5. Install Software Packages and API

The Zymbit install process uses curl which is not included with Tegra (Ubuntu 18.04) by default. Install curl: sudo apt install curl

Download and install the necessary Zymbit services.
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. After rebooting, the Jetson will temporarily bind the HSM6 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 Nano 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 Nano 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 Jetson 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 Jetson and it is impossible to move or bind your HSM to another Jetson. 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 Jetson(with power down on the Jetson)
  3. Turn on the Jetson (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 the 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.