Enabling Production Mode - SCM

If left in Development Mode, self-destruct events are simulated with LED flash sequences and recovery rather than destruction to allow for experimentation with the security functions. The LED sequence will repeat three times and then the system will recover.

DESTRUCTIVE ACTION

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

  • If you are using the Perimeter Detect features, then the sequence in which you arm and disarm this feature is very important. Be sure to carefully follow the process steps below.

If you decide that you are not ready for permanent binding, leave the SCM in developer mode.

The table below summarizes the differences between Development Mode (no Bind Lock) and Production Mode (Bind Locked)

EventDevelopment ModeProduction ModeTriggers
Tamper Event6 flash + channel sub-flashDestroy all keysImmediately
Low Temp Threshold20 flash + 1 sub-flashDo Not BootImmediately
High Temp Threshold20 flash + 2 sub-flashDo Not BootImmediately
Low Battery Voltage Threshold4 flash + 1 sub-flashTwo Policies: Prevent Boot or Destroy all keysPower Off
Supervised Boot Failure4 flash + 2 sub-flashTwo Policies: Prevent Boot or Destroy all keysOn Boot

Once locked, setting the Event Action modes are limited in the following way:

EventSetting
TamperOne time after locked
Low Temp ThresholdMust be set prior to locking
High Temp ThresholdMust be set prior to locking
Low Battery Voltage ThresholdMust be set prior to locking
Supervised Boot FailureNo limit

When you have completed your development work with the SCM and are ready to deploy your system into the field, we recommend that you permanently bind your SCM to a specific host device.

Summary of Steps

Develop your application

[ ] Ensure your host has all the necessary prerequisites in place to interface with the SCM and that it will be able to run your software application.

Activate Production Mode

[ ] Permanently bind your SCM to the host device.

Develop your application

The following steps should be complete:

[ ] Install a battery on the Zymbit SCM I/O board.

[ ] Install all necessary software for your application on the host and establish temporary binding in development mode.

After these steps have been completed, you are ready to prepare your device for permanent binding.

Prepare Perimeter Detect

The Perimeter Event Actions for your SCM should be set to none or notify only. If your SCM’s action mode is set to self_destruct, you might render your unit /c/Users/bobgu/OneDrive/Desktop/Atom.lnkuseless while attempting to activate Production Mode.

To do this quickly, with the SCM client libraries installed, you can run the following shell command to use the Python API to communicate with the SCM and set the Perimeter Event Actions to only Notify when triggered:

python3 -c "import zymkey;
for ch in (0, 1):
    zymkey.client.set_perimeter_event_actions(ch, action_notify=True, action_self_destruct=False)
zymkey.client.clear_perimeter_detect_info()"

Prepare your application

You should then install your application on your host SBC. The SCM root partition is pre-encrypted and is secured by the SCM itself.

Test, debug, and test again

Danger
DO NOT skip this step. If you encounter a major issue with your application after your SCM has been permanently bound to your device and armed, you may not be able to fix it.

Test the functionality of your application thoroughly to ensure it is free of major defects that will prevent it from functioning properly. In Production Mode when Perimeter Detect features are in use, it may be difficult to make significant changes to your configuration without locking youself out of the SCM, depending on the nature of your application and its configuration.

Activate Production Mode

To put the SCM into Production Mode only requires a function call followed by a power cycle.

The API function lock_binding puts the SCM into Production Mode. Below are three examples which check the current binding info, lock the SCM binding, then check the current binding info again. Remove the comments around the lock binding function to move to Production Mode.

C - zkLockBinding
// gcc example_binding.c -I /usr/include/zymkey -l zk_app_utils -o example_binding

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "zk_app_utils.h"
#include "zk_b64.h"

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("SCM 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("SCM 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("SCM 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("SCM 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("SCM is bound: " + str(tup[1]))
print("Binding is locked: " + str(tup[0]))

#zymkey.client.lock_binding()

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

Do not proceed without completing the steps outlined above, including setting the `Perimeter Event Actions` to `none` or `notify`. Prior to setting the Bind Lock.

Finalize your device for deployment

After using the APIs to lock binding, reboot. The blink pattern on the SCM will change to 3 rapid blinks once every 3 seconds to indicate that SCM has bound to the host in Production Mode.

If you are using the Perimeter Detect features, close your perimeter circuits (for example, by closing the enclosure’s lid), and then clear any Perimeter Detect Events using the API:

python3 -c "import zymkey; idx = 0;
zymkey.client.clear_perimeter_detect_info()
for p in zymkey.client.get_perimeter_detect_info():
  if p:
    print(f'Channel {idx} has a detected breach event. Clear the Perimeter Detect Events again.')
    idx += 1
  else:
    print('No perimeter breach detected.')"

If you get a message that a breach event was detected from the above command, run it again to ensure all events have been cleared.

Warning
You only get one chance to set Perimeter Event Actions once you are in Production Mode!

When it confirms that no breach events have been detected, it is then safe to arm the system by setting the Perimeter Event Actions to notify or selfdestruct, if desired.

Your system is now armed and ready to be used in the field!