Example SEE machines

This chapter documents the example SEE machines.

The supplied C examples consist of the source files and associated makefiles (Linux) and Cmake files (Windows) needed to compile and run the examples. To run the compiled examples correctly, you must have the latest version of the Security World for nShield. If you are using a Linux operating system, you must have version 2.22.34 or later of the HSM firmware. If you are using a Windows operating system, you must be on the latest version of the HSM firmware.

The latest versions of both the Security World for nShield and HSM firmware are supplied on the installation media.
Encrypted SEE machines are not currently supported for use with nShield Connects. When the SEEMachine binary is installed on the Connect itself for automated loading at boot, the SEE Confidentiality key is not available. However, when a client host loads a SEEMachine, it has access to the SEE Confidentiality key and can cause the binary to be decrypted. In this scenario, the Connect works fine with encrypted SEEMachine binaries.

Configure the Windows Build Environment

The Windows build environment requires that the following tools be already installed:

  • CMake for Windows, minimum version 3.9.

  • Visual Studio 2022 Build Tools.

  • Ninja build system for Windows.

Each example is supplied with CMake files for each HSM architecture and Windows host environment.

The specifics of building the C code for the HSM architectures and the Windows host environment are described in the next sections.

In order to build the examples, you must use the Visual Studio Developer Command Prompt. This command prompt needs to be initialized to use the 64-bit compilation tools in the following manner:

  1. Open a Windows command prompt, using Run as Administrator.

  2. Navigate to the Visual Studio Build Tools installation directory. The default location for this is C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build.

  3. At the command prompt, execute the initialization batch file, vcvars64.bat. The batch file sets the required environment variables for using the 64-bit compilation tools.

  4. At this point you may wish to enter the PowerShell environment. This can be done by executing the powershell command at the command prompt.

    If you exit (close) the initialized Windows command prompt (or PowerShell), then these initialization steps must be repeated when you open a new command prompt in order to build the examples.
For information on the different library paths necessary to perform a 64-bit build of your own code, see the nCore API Documentation (supplied as HTML).
We strongly recommend that you familiarize yourself with the process of building the example programs supplied on the CodeSafe installation media before you attempt to adapt the makefiles to any other environments.

Examples for glibc library

This section is relevant when using a glibc based SEE machine with an nShield Solo XC or an nShield Connect XC.

In default CodeSafe installations, the following C examples are supplied in directories under the path /opt/nfast/c/csd/examples/ (Linux) or %NFAST_HOME%\c\csd\examples\ (Windows):

Location Description

glibsee/helloworld.c

This example is a simple, introductory test program.

glibsee/see-random.c

This example demonstrates basic usage of the generic stub within SEE.

glibsee/see-enquiry.c

This example demonstrates host code running within SEE with no large modifications.

glibsee/tcp-proxy.c

This example is a multithreaded TCP-TCP proxy that forwards all connections on port 8080 to 127.0.0.1:80.

If the nShield Connect is configured to use see-sock-serv directly, any supplied glibc examples that use see-sock-serv can be run directly on the nShield Connect, rather than via a client machine.

The examples here show how to run a SEE machine from a command line. Alternatively, if you wish to run a SEE machine directly, please see Deploying SEE Machines.

If you are running see-sock-serv directly on an nShield Connect, port numbers in the examples should be modified to bind to ports within the range 8000-8999.

All supplied examples for glibc, both standard and SSL-related, require one of the see-*-serv host-side utilities. For more information about these utilities, see see-*-serve utilities.

The SEE machine type must be specified as --machine-type=PowerPCELF when running the tct2 tool.

Building the HSM-side code

  1. Create a directory in your home (Linux) or Documents (Windows) location to contain the platform examples. For example, to create and enter a directory called buildGLIBmod:

    Linux
    cd ~
    mkdir buildGLIBmod
    cd buildGLIBmod
    Windows
    cd Documents
    mkdir buildGLIBmod
    cd buildGLIBmod
  2. Configure the module examples build using the command:

    Linux
    cmake -DCMAKE_TOOLCHAIN_FILE=<path to GLIB tool chain> <path to GLIB SEE examples>

    For example, using the default locations for the tool chain and the GLIB SEE examples:

    cmake -DCMAKE_TOOLCHAIN_FILE=/opt/nfast/c/csd/cmake/codesafe-linux-xc-glibsee.cmake /opt/nfast/c/csd/examples/
    Windows
    cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=<path to GLIB tool chain> <path to GLIB SEE examples>

    For example, using the default locations for the tool chain and the GLIB SEE examples:

    cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\Program Files\nCipher\nfast\c\csd\cmake\codesafe-linux-xc-glibsee.cmake" "C:\Program Files\nCipher\nfast\c\csd\examples"
  3. Build the module examples using the command:

    Linux
    cmake --build <build output location>

    For example:

    cmake --build .

    Here, the . specifies the location where the build products should be placed, in this case to the current directory.

    Windows
    Ninja

    This results in the creation of a directory, glibsee, which contains all the compiled examples. The build process will create a file for each example, with an .elf suffix.

Helloworld example

This example source code is a simple example of an SEE machine written in C. It is not intended to be the basis for any real world applications. It is intended only to demonstrate how to write SEE machines in C and the use of an appropriate host utility to handle output to stdout and stderr.

Packing the SEE machine

Use the tct2 command-line utility to convert the ELF (Executable and Linkable Format) file into a SAR (Secure or SEE ARchive) file as follows:

tct2 --pack --machine-type=PowerPCELF --infile=helloworld.elf --outfile=helloworld.sar

For additional security, you can also choose to set options in this command that sign or encrypt the file. For more information, see tct2.

Creating a userdata file

All SEE machines built with the glibc C library must be provided with a valid ASCII-format CPIO archive. This archive forms the base of the file system available to your SEE machine. You can use the cpioc command-utility that we provide to create CPIO archives of the correct type.
Although the helloworld example does not use its file system, you must still create and supply it with dummy userdata as a place-holder.

Create a dummy userdata file as follows:

echo dummy > dummy
cpioc userdata.cpio dummy

Output:

F dummy
Written 'userdata.cpio': 1 files, 0 directories, 0 errors

Running the example

To run the helloworld example on a PowerPC-based SEE machine, use the following commands:

see-stdoe-serv --machine helloworld.sar --userdata-raw userdata.cpio

Output:

nC SEE glibc entering main
Hello world!
If you are using a nShield Connect, you must also set the --no-feature-check option when running the see-stdoe-serv utility.

Before rerunning this example, run the following command to clear all HSMs:

nopclearfail --clear --all

SEE-Random example

This example shows basic usage of the generic stub from within SEE. It requests 128 bytes of random material from the HSM and prints the result in hexadecimal.

Before running or rerunning this example, run the following command to clear all HSMs:

nopclearfail --clear --all

The following assumes that the user is working in the directory that contains the compiled examples (both SXF and ELF files).

Packing the SEE machine

Use the tct2 command-line utility to convert the ELF (Executable and Linkable Format) file into a SAR (Secure or SEE ARchive) file:

tct2 --pack --machine-type=PowerPCELF --infile=see-random.elf --outfile=see-random.sar

For additional security, you can also set options in this command to sign or encrypt the file. For more information, see tct2.

Running the example

To run the SEE-Random example on a PowerPC-based SEE machine, use the following commands:

see-stdoe-serv --machine see-random.sar --userdata-raw userdata.cpio

Output:

nC SEE glibc entering main
52 D1 C4 73 28 49 79 62 CD E6 64 14 1C 3B E1 B2 70 3D 6B D5 DF DE CE 7F 47 50 70 06 B6
C0 52 7F 19 3A 0A 7D E4 73 83 D8 EB F4 E5 82 F3 53 38 45 2A E3 08 49 1A 58 77 35 5F 5C
7C D9 7B 57 4A A9 C4 F4 67 C7 30 91 4A CA 0C 15 1F A7 F2 E1 2B 61 E2 3A CE EF BD FF ED
49 07 68 7B 76 D2 AC 8B 98 AA 02 FD 30 01 68 60 49 4C 0F 7E 23 7F AC EC B5 6A DE 0B CD
45 72 89 96 DD E2 96 C2 B8 7B 97 AA
If you are using an nShield Connect, you must also set the --no-feature-check option when running the see-stdoe-serv utility.

SEE-Enquiry example

This example shows how to cross-compile example code, originally written for use from the host environment, to be run within the SEE without any substantial modifications.

Before running or rerunning this example, run the following command to clear all HSMs:

nopclearfail --clear --all

The following assumes that the user is working in the directory that contains the compiled examples (both SXF and ELF files).

This example code is based on enquiry.c provided elsewhere in the software distribution.

Packing the SEE machine

Use the tct2 command-line utility to convert the ELF (Executable and Linkable Format) file into a SAR (Secure or SEE ARchive file):

tct2 --pack --machine-type=PowerPCELF --infile=see-enquiry.elf --outfile=see-enquiry.sar

For additional security, you can also set options in this command to sign or encrypt the file. For more information, see tct2.

Running the example

To run the SEE-Enquiry example on a PowerPC-based SEE machine, use the following commands:

see-stdoe-serv --machine see-enquiry.sar --userdata-raw userdata.cpio

Output:

nC SEE glibc entering main
Server:
 enquiry reply flags  none
 enquiry reply level  Six
 serial number        1BD7-DE7B-A370
 mode                 operational
 version              2.38.7
 speed index          4240
 rec.queue            35..152
 [etc]
If you are using an nShield Connect, you must also set the --no-feature-check option when running the see-stdoe-serv utility.

TCP proxy example

The TCP proxy example demonstrates how to set up a conduit between the local host and a destination IP address.

Before running or rerunning this example, run the following command to clear all HSMs:

nopclearfail --clear --all

The following assumes that the user is working in the directory that contains the compiled examples (both SXF and ELF files).

The default destination address is declared in the source code file tcp-proxy.c as follows:

#define BACKEND_ADDR  "127.0.0.1"

For the TCP proxy example to work correctly, you must change this default destination address. You can replace the default address with the IP address of any valid website.

By default, the example TCP proxy code sets the front end port to 8080 and the back end port to 80. The remainder of this example assumes the use of these values, but you can change them as necessary.

Re-building the HSM-side code

If the file tcp-proxy.c has been modified as described in section [TCP], then the example needs to be rebuilt in order for the changes to be effective. The example can be rebuilt by executing the cmake build command from within the appropriate directory as described in section Examples for glibc library for example:

Linux
cd ~/buildGLIBmod
cmake --build .

In this example the directory path would be ~/buildGLIBmod/glibsee.

Windows
cd C:\Users\<USER-NAME>\Documents\buildGLIBMod
Ninja

In this example the directory path would be C:\Users\<USER-NAME>\Documents\buildGLIBMod\glibsee\.

If the example has been rebuilt, before continuing ensure that you are working in the directory that contains the compiled examples.

Packing the SEE machine

Use the tct2 command-line utility to convert the ELF (Executable and Linkable Format) file into a SAR (Secure or SEE ARchive) file:

tct2 --pack --machine-type=PowerPCELF --infile=tcp-proxy.elf --outfile=tcp-proxy.sar

You can also set options in this command to sign or encrypt the file. For more information, see tct2.

Running the example

Run the example on a PowerPC-based SEE machine as follows:

see-sock-serv --trace --machine tcp-proxy.sar --userdata-raw userdata.cpio

You can check that the example is working correctly by entering the URL http://localhost:8080/ into any browser. If the example is working correctly, the browser displays the website at the address specified in the tcp-proxy.c file.

Examples for SEElib

In default CodeSafe installations, the following C examples are supplied in directories under the path /opt/nfast/c/csd/examples/csee (Linux) or %NFAST_HOME%\c\csd\examples\csee (Windows).

Location Description

csee/hello/

This example source code demonstrates a simple SEE machine in C and how you can use it from a C program on the host.

csee/a3a8/

This example code demonstrates how to write an SEE machine in C code and how to use it from a C program on the host.

csee/nvram/

This example shows the simple use of NVRAM in an SEE machine written in C.

csee/rtc/

This example demonstrates the use of an SEE machine written in C that implements a very simple timestamp service.

csee/tickets/

This example provides an API demonstration showing how an SEE machine can be written in C.

csee/benchmark/

This example implements a very simple utility that uses an SEE machine written in C to time stamp requests to benchmark the speed of response to requests.

We also supply a Java version of the HelloWorld example. This consists of the source files for host-side applications that you can run with the example SEE machines written in C (or any other SEE machines written in any language) in order to understand how simple SEE machines work, see About the Java example.

The nvram, rtc, and benchmark C examples can extract debugging information from the SEE trace buffer in all Security Worlds. If the Security World has restricted or authorized-only access to SEE debugging, the example prompts the user for the number of Administrator Cards required to gain authorization. Therefore, to avoid unnecessary exposure of the Administrator Cards, do not try to run these examples on an HSM in a production Security World. Debugging information from the trace buffer is not available for the A3A8 or tickets C examples.

Building Linux host examples

  1. Create a directory in your home location to contain the host platform examples. For example, create a directory called buildhost, and enter this directory:

    mkdir ~/buildhost
    cd ~/buildhost
  2. Configure the host platform examples using the command:

    cmake <path to SEElib examples>

    For example:

    cmake /opt/nfast/c/csd/examples/

    Here, the location of the examples is the default location, /opt/nfast/c/csd/examples.

  3. Build the host platform examples using the command:

    cmake --build <build output location>

    For example

    cmake --build .

    Here, the . specifies the location where the build products should be placed, in this case to the current directory.

    This results in the creation of a directory, csee, which contains a subdirectory for each of the examples. For example ~/buildhost/csee/a3a8.

Building Windows host examples

  1. Create a directory in your Documents location to contain the host examples. For example, create a directory called host, and enter this directory:

    cd Documents
    mkdir host
    cd host
  2. Configure the host platform examples using the command:

    cmake -G "Ninja" -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl "C:\Program
    Files\nCipher\nfast\c\csd\examples"
  3. Build the host examples using the command:

    ninja

    This results in the creation of a directory, csee, which contains a subdirectory for each of the examples.

    Each example’s subdirectory contains a directory, module, which contains the complied module code.

Building Solo SEE module examples

  1. Create a directory in your home (Linux) or Documents (Windows) location to contain the module examples. For example, create a directory, buildSoloMod, and enter this directory.

    Linux
    cd ~
    mkdir buildSoloMod
    cd buildSoloMod
    Windows
    cd Documents
    mkdir buildSoloMod
    cd buildSoloMod
  2. Configure the module examples build using the command:

    Linux
    cmake -DCMAKE_TOOLCHAIN_FILE=<path to Solo + module tool chain> <path to CSEE examples>

    For example, using default locations for the Solo + module tool chain and the CSEE examples:

    cmake -DCMAKE_TOOLCHAIN_FILE=/opt/nfast/c/csd/cmake/codesafe-linux-solo-csee.cmake /opt/nfast/c/csd/examples/
    Windows
    cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\Program Files\nCipher\nfast\c\csd\cmake\codesafe-linux-solo-csee.cmake" "C:\Program Files\nCipher\nfast\c\csd\examples"
  3. Build the modules using the command:

    Linux
    cmake --build <build output location>

    For example:

    cmake --build .

    Here the . specifies the location where the build products should be placed, in this case to current directory.

    Windows
    Ninja

    This will result in the creation of a directory, csee, which contains a subdirectory for each of the examples. Each example’s subdirectory contains a directory, module, which contains the compiled module code. For example, ~/buildSoloMod/csee/a3a8/module. The compiled module executables have the suffix sxf.

Building Solo XC SEE module examples

  1. Create a directory in your home (Linux) or Documents (Windows) location to contain the module platform examples. For example, create a directory, buildXCmod, and enter this directory:

    Linux
    cd ~
    mkdir buildXCmod
    cd bukdXCmod
    Windows
    cd Documents
    mkdir buildXCmod
    cd buildXCmod
  2. Configure the module examples build using the command:

    Linux
    cmake -DCMAKE_TOOLCHAIN_FILE=<path to Solo XC module tool chain> <path to SEElib examples>

    For example, using the default locations for the Solo XC module tool chain and the SEELib examples, the command would be:

    cmake -DCMAKE_TOOLCHAIN_FILE=/opt/nfast/c/csd/cmake/codesafe-linux-xc-csee.cmake /opt/nfast/c/csd/examples/
    Windows
    cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="C:\Program Files\nCipher\nfast\c\csd\cmake\codesafe-linux-xc-csee.cmake" "C:\Program Files\nCipher\nfast\c\csd\examples"
  3. Build the module examples using the command:

    Linux
    cmake --build <build output location>

    For example:

    cmake --build .

    Here the . specifies the location where the build products should be placed, in this case to current directory.

    Windows
    Ninja

    This will result in the creation of a directory, csee, which contains a subdirectory for each of the examples Each example’s subdirectory contains a directory, module, which contains the compiled module code. For example, ~/buildXCMod/csee/a3a8/module. The compiled module executables have the suffix .elf.

Example: Hello-World

This example source code demonstrates a simple SEE machine in C and how you can use it from a C program on the host. The SEE machine examines the characters in the SEE job passed to it and replaces each lowercase alphabetic character with the corresponding uppercase character, returning the result as the SEE job reply. Additionally, if the SEE World is created with a userdata file, any characters found in the userdata file are replaced in the input SEE job with the character X.

The Hello-World example is not intended to be the basis for any real world applications. It is intended only to demonstrate how to write SEE machines in C and host-side use of an SEE machine by code written in C.
There is also an example of the host-side code written in Java, supplied in the nCipherKM-SEE-Examples.jar found in /opt/nfast/java/examples/ (Linux) or %NFAST_HOME%\java\examples\ (Windows).

Signing, packing, and loading the SEE machine

  1. Generate a key with which to sign the SEE machine:

    generatekey -m 1 seeinteg
  2. Complete the prompts as follows:

    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA, ECDSA, KCDSA) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    plainname: Key name? [] > hellomachine
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation      Operation to perform            generate
     application    Application                     seeinteg
     protect        Protected by                    token
     slot           Slot to read cards from         0
     recovery       Key recovery                    yes
     verify         Verify security of key          yes
     type           Key type                        RSA
     size           Key size                        2048
     pubexp         Public exponent for RSA         key (hex)
     plainname      Key name                        hellomachine
     nvram          Blob in NVRAM (needs ACS)       no
    
    Loading `dev-ocs':
      Module 1: 0 cards of 1 read
      Module 1 slot 0: `dev-ocs' #1
      Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    Key successfully generated.
    Path to key: <path-to-key>

    Where <path-to-key> is /opt/nfast/kmdata/local/key_seeinteg_hellomachine (Linux) or C:\ProgramData\nCipher\Key Management Data\local\key_seeinteg_hellomachine (Windows).

  3. Change to the module directory.

    For nShield Solo:

    Linux
    cd ~/buildSoloMod/csee/hello/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\hello\module

    For nShield Solo XC:

    Linux
    cd ~/buildSoloXC/csee/hello/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\hello\module
  4. Use the tct2 command line utility to convert the file into a SAR file.

    For nShield Solo:

    Convert the hello.sxf file to a SAR file:

    Linux
    tct2 --sign-and-pack --is-machine -i hello.sxf --machine-type=PowerPCSXF -o hello.sar -k hellomachine
    Windows
    tct2 -m 1 --sign-and-pack --is-machine -i .\hello.sxf --machine-type=PowerPCSXF -o hello.sar -k hellomachine

    Output:

    Signing machine as `PowerPCSXF'.
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.

    For nShield Solo XC:

    Convert the hello.elf file to a SAR file:

    Linux
    tct2 --sign-and-pack --is-machine -i hello.elf --machine-type=PowerPCELF -o hello.sar -k hellomachine
    Windows
    tct2 --sign-and-pack --is-machine -i .\hello.elf --machine-type=PowerPCELF -o hello.sar -k hellomachine

    Output:

    Signing machine as `PowerPCELF'.
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    For more information about this command, see tct2.
  5. Load the SEE machine into the HSM by running the command:

    loadmache -m 1 hello.sar
    This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. See Automatically loading an SEE machine.

Preparing example userdata

You do not need to create real userdata for this example. Instead, you can simply pack a small text file with tct2 and pass the packed file to the SEE machine to serve as userdata.

However, you can also choose to create and sign a real userdata file in the same way as for the A3A8 example; see A3A8 example

When you run the Hello-World example, because the characters in the userdata you supply are converted from lower case to replaced by the character X in the output file, including a new line sequence in the userdata can produce unexpected results.

Running the example

To run the C example change to the host application directory by running the command:

Linux
cd ~/buildHost/csee/hello/hostside
Windows
cd C:\Users\<USER-NAME>\Documents\hostside\csee\hello\hostside

Pack the desired user data in the SAR file suitable for loading onto the HSM. Optionally, you could use the Trusted Code Tool (tct2) to create a signed and packed SAR file for this step.

Usage

The hello example program has the following arguments:

hello <FILENAME> [<USERDATA>.sar]
FILENAME

This parameter is the name of the input file that contains the source string.

USERDATA

This optional parameter is the name of a file that contains letters to be replaced by the ASCII character X in the output file.

What the code actually does

The host-side C code performs the following tasks:

  1. It prompts the user to supply a file name and an optional USERDATA file.

  2. It sends the string in the file, converted if necessary to standard output.

The HSM-side code awaits jobs from the host and performs the following:

  1. It transforms the contents of the input file, capitalizing all input and replacing any characters that appear in the optional USERDATA file with an ASCII character X.

  2. It sends the result as output.

A3A8 example

This example code demonstrates how to write an SEE machine in C code and how to use it from a C program on the host.

The A3A8 example is not intended to be the basis for any real world applications. The algorithm used, known as ACOMP128, has been shown to be insecure and is not appropriate for production use. It is used here only to demonstrate the implementation of an algorithm in an SEE application, not to endorse it in any way.
This example does not support debugging when the SEE debug level is set to Generate Authorization Key.

The SEE machine is used to process data with the A3/A8 algorithm in conjunction with a Triple-DES key as follows:

  1. Data comes in the form of a sequence of 16-byte input values.

  2. These values are split into two 8-byte halves that are each Triple-DES ECB decrypted with the master key and reassembled to give a 16-byte key.

  3. Then a 16-byte random value is generated and, along with the 16-byte key, is fed into the A3/A8 algorithm to produce a 12-byte output value.

  4. The output from the HSM consists of a sequence of 28-byte blocks comprising the random value and the output value.

There is also an example of the host-side code written in Java, supplied in the nCipherKM-SEE-Examples.jar found in opt/nfast/java/examples (Linux) or %NFAST_HOME%\java\examples (Windows).

Signing, packing, and loading the SEE machine

To sign, pack, and load the SEE machine:

  1. Generate a key with which to sign the SEE machine:

    generatekey -m 1 seeinteg
  2. Complete the prompts as follows:

    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA, ECDSA, KCDSA) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    plainname: Key name? [] > a3a8machine
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation    Operation to perform               generate
     application  Application                        seeinteg
     protect      Protected by                       token
     slot         Slot to read cards from            0
     recovery     Key recovery                       yes
     verify       Verify security of key             yes
     type         Key type                           RSA
     size         Key size                           2048
     pubexp       Public exponent for RSA key (hex)
     plainname    Key name                           a3a8machine
     nvram        Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: <path-to-key>

    <path-to-key> is /opt/nfast/kmdata/local/key_seeinteg_a3a8machine (Linux) or C:\ProgramData\nCipher\Key Management Data\local\key_seeinteg_a3a8machine (Windows).

  3. Change to the directory by running the command:

    For nShield Solo

    Linux
    cd ~/buildSoloMod/csee/a3a8/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\a3a8\module

    For nShield Solo XC

    Linux
    cd ~/buildXCMod/csee/a3a8/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\a3a8\module
  4. Use the tct2 command line utility to convert the file into a SAR file.

    $ generatekey -m 1 seeinteg
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA, ECDSA, KCDSA) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    plainname: Key name? [] > a3a8machine
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation   Operation to perform                  generate
     application  Application                           seeinteg
      protect      Protected by                          token
     slot         Slot to read cards from               0
     recovery     Key recovery                          yes
     verify       Verify security of key                yes
     type         Key type                              RSA
     size         Key size                              2048
     pubexp       Public exponent for RSA key (hex)
     plainname    Key name                              a3a8machine
     nvram Blob in NVRAM (needs ACS) no
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: /opt/nfast/kmdata/local/key_seeinteg_a3a8machine
  5. Change to the directory by running the command:

    For nShield Solo

    Convert the a3a8mach.sxf file into a SAR file.

    tct2 -m 1 --sign-and-pack --is-machine -i a3a8mach.sxf --machine-type=PowerPCSXF -o a3a8mach.sar -k a3a8machine

    Output:

    Signing machine as `PowerPCSXF'.
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.

    For nShield Solo XC

    Convert the a3a8mach.elf file into a SAR file.

    tct2 -m 1 --sign-and-pack --is-machine -i a3a8mach.elf --machine-type=PowerPCELF -o a3a8mach.sar -k a3a8machine

    Output:

    Signing machine as `PowerPCELF'.
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
  6. Load the SEE machine into the HSM by running the command:

    loadmache -m 1 a3a8mach.sar
This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. See Automatically loading an SEE machine

Creating and signing userdata

To create and sign the userdata file:

  1. Change to the host-side code directory by running the command:

    Linux
    $ cd ~/buildhost/csee/a3a8/hostside
    Windows
    cd C:\Users\<USER-NAME>\Documents\hostside\csee\a3a8\hostside
  2. Generate a key with which to sign a dummy userdata file for the example by running the command:

    generatekey -m 1 seeinteg
  3. Complete the prompts as follows:

    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA, ECDSA, KCDSA) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    plainname: Key name? [] > a3a8userdata
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation    Operation to perform               generate
     application  Application                        seeinteg
     protect      Protected by                       token
     slot         Slot to read cards from            0
     recovery     Key recovery                       yes
     verify       Verify security of key             yes
     type         Key type                           RSA
     size         Key size                           2048
     pubexp       Public exponent for RSA key (hex)
     plainname    Key name                           a3a8userdata
     nvram        Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: <path-to-key>

    <path-to-key> is /opt/nfast/kmdata/local/key_seeinteg_a3a8userdata (Linux) or C:\ProgramData\nCipher\Key Management Data\local\key_seeinteg_a3a8userdata (Windows).

  4. Create a dummy userdata file. Because the A3/A8 algorithm does not use the initialization data, the dummy userdata need contain only one arbitrary character to use as userdata.

  5. Use the tct2 command-line utility to sign and pack a dummy userdata file for the example:

    For nShield Solo

    Linux
    tct2 --sign-and-pack --machine-type=PowerPCSXF --infile a3a8userdata --outfile=a3a8userdata.sar --machine-key-ident=a3a8machine -k a3a8userdata

    Output:

    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.[sudo] password for XXX:
    Windows
    tct2 --sign-and-pack --machine-type=PowerPCSXF --infile=a3a8userdata --outfile=a3a8userdata.sar --machine-keyident=a3a8machine -k a3a8userdata

    Output:

    No module specified, using 1
    Signing machine as 'PowerPCSXF'.

    For nShield Solo XC:

    Linux
    tct2 --sign-and-pack  --machine-type=PowerPCELF --infile a3a8userdata --outfile a3a8userdata.sar --machine-key-ident=a3a8machine -k a3a8userdata

    Output:

    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    Windows
    tct2 --sign-and-pack --machine-type=PowerPCELF --infile=a3a8userdata --outfile=a3a8userdata.sar --machine-keyident=a3a8machine -k a3a8userdata

    Output:

    No module specified, using 1
    Signing machine as 'PowerPCELF'.
    For more information about this command, see tct2
Running and testing the example

The a3test example application takes the following arguments:

a3test [-m <MODULEID>] <USERDATA>.sar
-m <MODULEID>

This option specifies the ModuleID of the HSM to use.

<USERDATA>.sar

This parameter specifies a userdata file (packed as a SAR) to use.

Thus, you can run the a3test program created in this example with a command of the form:

Linux
./a3test -m 1 a3a8userdata.sar
Windows
a3test -m 1 a3a8userdata.sar

The a3test example then processes data for approximately 20 seconds. If the example program runs successfully, its final output is of the form:

Getting Sarfile info (400 bytes)....
Creating world: init status was 0 (OK)
Making Master Key:
Get ticket.......
Sending ticket to SEEWorld:
181000 triples, 21 sec
Releasing context
Thank you for watching. The end.

If the output from a3test takes any other form, this indicates an error. In case of an error, use the enquiry command-line utility to check:

  • Whether the correct firmware is installed

  • Whether the correct server is running

  • Whether the HSM is in the operational state.

NVRAM example

The NVRAM example shows the simple use of NVRAM in an SEE machine written in C. It uses a file in NVRAM as a sort of postage meter. The contents of the file are interpreted as a little-endian integer that determines how many 'stamps' can be issued. Each time the host program is invoked, it requests one or more stamps from the machine, and the NVRAM counter is decreased accordingly.

The NVRAM example is not intended to be the basis for any real world applications. It is intended only to demonstrate how to write SEE machines in C that access the HSM’s NVRAM.

Signing, packing, and loading the SEE machine

To sign, pack, and load the SEE machine:

  1. Generate a key with which to sign the SEE machine:

    generatekey seeinteg
  2. Complete the prompts as follows:

    module: Module to use? (1, 2) [1] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA) [RSA] >
    size: Key size? (bits, minimum 1024) [1024] >
    OPTIONAL: pubexp: Public exponent for RSA key (in hex)? []
    >
    plainname: Key name? [] > nvrammachine
    key generation parameters:
     operation    Operation to perform                  generate
     application  Application                           seeinteg
     module       Module to use                         1
     protect      Protected by                          token
     slot         Slot to read cards from               0
     recovery     Key recovery                          yes
     verify       Verify security of key                yes
     type         Key type                              RSA
     size         Key size                              1024
     pubexp       Public exponent for RSA key (in hex)
     plainname    Key name                              nvrammachine
    Key successfully generated.
    Path to key: <path-to-key>

    <path-to-key> is /opt/nfast/kmdata/local/key_seeinteg_nvrammachine (Linux) or %NFAST_KMDATA%\local\key_seeinteg_nvrammachine (Windows).

  3. Change to the directory by running the command:

    For nShield Solo

    Linux
    cd ~/buildSoloMod/csee/nvram/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\nvram\module

    For nShield Solo XC

    Linux
    cd ~/buildXCMod/csee/nvram/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\nvram\module
  4. Use the tct2 command line utility to convert the file.

    For nShield Solo

    Convert the nvram.sxf file into a SAR file.

    Linux
    tct2 --sign-and-pack --is-machine -i nvram.sxf --machine-type=PowerPCSXF -o nvram.sar -k nvrammachine
    Windows
    tct2 -m 1 --sign-and-pack --is-machine -i nvram.sxf --machine-type=PowerPCSXF -o nvram.sar -k nvrammachine

    Output:

    Signing machine as 'PowerPCSXF'.
    
    Loading `ocs-dev':
    Module 1: 0 cards of 1 read
    Module 1 slot 0: `ocs-dev' #1
    Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.

    For nShield Solo XC

    Convert the nvram.elf file into a SAR file.

    Linux
    tct2 --sign-and-pack  --is-machine -i nvram.elf --machine-type=PowerPCELF -o nvram.sar -k nvrammachine
    Windows
    tct2 -m 1 --sign-and-pack --is-machine -i nvram.elf --machine-type=PowerPCELF -o nvram.sar -k nvrammachine

    Output:

    Signing machine as 'PowerPCELF'.
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    For more information about this command, see tct2.
  5. Load the packed SEE machine into the HSM by running the command:

    loadmache nvram.sar
This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. For information about configuration files, see the User Guide.
Creating NVRAM and userdata files

You must now use the setup example application to create:

  • An NVRAM file

  • A userdata file that contains only the exact name of the specified NVRAM file.

    1. Change to the host-side application directory by running the command:

      Linux
      cd ~/buildhost/csee/nvram/hostside
      Windows
      cd C:\Users\<USER-NAME>\Documents\hostside\csee\nvram\host
    2. Create these files by running the setup command with 'root' (Linux) or Administrator (Windows) privileges:

      Linux
      ./setup nvramfile 100 nvramuserdata
      Windows
      setup.exe nvramfile 100 nvramuserdata
    3. Complete the on-screen instructions:

      Please insert the next administrator card and press enter.
      Please enter card passphrase:
      allocated NVRAM file `nvramfile'.
setup

The setup example application takes the following arguments:

setup [-k|--key <APPNAME>,<IDENT>] <nvram-filename> <stamp-count> <userdatafile>
-k|--key <APPNAME>,<IDENT>

This option specifies a signing key identified by APPNAME and IDENT. Specifying a signing key creates an NVRAM file that can only be accessed with authorization from that key (for example, by signing the userdata with the same key). A signing key is optional.

<nvram-filename>

This parameter specifies the name of an NVRAM file to create. The name must contain no more than 11 characters.

<tampcount>

This parameter specifies the number of stamps to issue.

<userdatafile>

This parameter specifies the name of the userdata SAR file created when the setup example application is run.

You can also use the setup example application to delete an existing NVRAM file. To delete a file, run setup with the --delete option, as follows:

setup --delete <nvram-filename>

In this case, setup deletes the NVRAM file specified by nvram-filename.

Signing and packing the userdata

Run the Trusted Code Tool (tct2) to sign and pack the created userdata file you created with the setup example application:

Linux
tct2 -m 1 --pack --infile nvramuserdata --outfile nvramuserdata.sar
Windows
tct2 --pack --infile nvramuserdata --outfile nvramuserdata.sar
If the NVRAM file created by the setup example application is bound to a key (that is, if you specified the -k|--key option when running setup), use that same key when signing the userdata file with tct2.
Running and testing the example

Run the nvram example application as follows:

Linux
./nvram ./nvramuserdata.sar 50
Windows
nvram.exe nvramuserdata.sar 50

Output:

SEEJob: read 1 bytes...
Stamp Request Accepted.
SEEJob: read 1 bytes...
Stamp Request Accepted.
SEEJob: read 1 bytes...
.
.
.
nvram

The nvram example application takes the following arguments:

nvram <userdatafile>.sar [<iterations>]
<userdatafile>.sar

This parameter specifies the name of the userdata SAR file to use. Normally, this file has been created by the setup example application (its name specified by that utility’s userdatafile parameter).

<iterations>

This parameter specifies an integer that is the amount by which the nvram example application is to decrease its counter (as it issues virtual stamps).

What the code actually does

The host-side code performs the following tasks in order:

  1. It allocates an NVRAM file with an access control list that requires the permission of a specified key for reading or writing.

  2. It requests the name of a file to be loaded as a packed user data block and, optionally, the number of virtual stamps to request.

The HSM-side code awaits jobs from the host and returns a single byte to indicate whether or not a stamp has been issued.

Example: RTC

This source code provides an example of an SEE machine written in C that implements a very simple timestamp service.

Your SEE-Ready HSM must have an onboard real-time clock for this example to run correctly, and you must have set the clock using the rtc command-line utility.

The rtc example code is deficient in a number of ways and is not intended to be the basis for any real world applications. It is intended only to demonstrate some important concepts in writing SEE machines in C to perform time-stamping.

Signing, packing, and loading the SEE machine

To sign, pack, and load the SEE machine:

  1. Generate a key with which to sign the SEE machine:

    generatekey -m 1 seeinteg
  2. Complete the prompts as follows:

    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (RSA, DSA, ECDSA, KCDSA) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    plainname: Key name? [] > rtccode
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation    Operation to perform               generate
     application  Application                        seeinteg
     protect      Protected by                       token
     slot         Slot to read cards from            0
     recovery     Key recovery                       yes
     verify       Verify security of key             yes
     type         Key type                           RSA
     size         Key size                           2048
     pubexp       Public exponent for RSA key (hex)
     plainname    Key name                           rtccode
     nvram        Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    Key successfully generated.
    Path to key: <path-to-key>

    <path-to-key is /opt/nfast/kmdata/local/key_seeinteg_rtccode (Linux) or C:\ProgramData\nCipher\Key Management Data\local\key_seeinteg_rtccode (Windows).

  3. Change to the directory by running the command:

    For nShield Solo:

    Linux
    cd ~/buildSoloMod/csee/rtc/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\rtc\module

    For nShield Solo XC:

    Linux
    cd ~/build-XC/csee/rtc/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\rtc\module
  4. Use the tct2 command-line utility to convert the file into a SAR file.

    For nShield Solo

    tct2 -m 1 --sign-and-pack --is-machine -i rtc.sxf --machine-type=PowerPCSXF -o rtc.sar -k rtccode

    Output:

    Signing machine as `PowerPCSXF'.
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    
    
    Card reading complete.

    For nShield Solo XC:

    tct2 -m 1 --sign-and-pack --is-machine -i rtc.elf --machine-type=PowerPCELF -o rtc.sar -k rtccode

    Output:

    Signing machine as `PowerPCELF'.
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    
    
    Card reading complete.
  5. Load the packed SEE machine into the HSM by running the command:

    loadmache rtc.sar
    This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. For information about configuration files, see the User Guide.
rtc

The rtc example application takes the following arguments:

rtc [-y|--verify <file>] [-a|--userdata <SEEDATA>] <userdatafile> <APPNAME>,<IDENT>
-y|---verify

This option verifies the returned time-stamp for the file named file.

-a|---userdata <SEEDATA>

This option specifies use of the file SEEDATA for SEE userdata.

<userdatafile>

This parameter specifies a userdata file that contains at least one character.

<APPNAME>,<IDENT>

These parameters specify the APPNAME and IDENT of the key for the rtc example application to use.

Running the example
  1. Enter the host-side application directory by running the command:

    Linux
    cd ~/buildhost/csee/rtc/hostside/
    Windows
    cd C:\Users\<USER-NAME>\Documents\host\csee\rtc\hostside
  2. Create the test userdata file to be time-stamped by running the command:

    Linux
    cp /opt/nfast/c/csd/examples/csee/rtc/host/rtc.c ./mytestuserdata
    Windows
    copy "C:\Program Files\nCipher\nfast\c\csd\examples\csee\rtc\hostside\rtc.c" mytestuserdata
  3. Generate an RSA key for the RTC example to use by running the command and completing the prompts in the output as follows:

    Linux
    generatekey simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512, HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > rtctest
    plainname: Key name? [] > rtctest
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, nvrammachine, a3a8userdata, hellomachine, rtccode) []
    >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
    operation     Operation to perform               generate
    application   Application                        simple$ ./rtc mytestuserdata simple,rtctest > mytestuserdata.stamp
    Please insert the next operator card and press enter.
    Please enter card passphrase:
    rtc: timestamp issued.
    
    protect       Protected by                       token
    slot          Slot to read cards from            0
    recovery      Key recovery                       yes
    verify        Verify security of key             yes
    type          Key type                           RSA
    size          Key size                           2048
    pubexp        Public exponent for RSA key (hex)
    ident         Key identifier                     rtctest
    plainname     Key name                           rtctest
    seeintegname  SEE integrity key
    nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: /opt/nfast/kmdata/local/key_simple_rtctest
    Windows
    generatekey -m 1 simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,
                     HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512,
                     HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > rtctest
    plainname: Key name? [] > rtctest
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, a3a8userdata, hellomachine, rtccode) [] >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation     Operation to perform               generate
     application   Application                        simple
     protect       Protected by                       token
     slot          Slot to read cards from            0
     recovery      Key recovery                       yes
     verify        Verify security of key             yes
     type          Key type                           RSA
     size          Key size                           2048
     pubexp        Public exponent for RSA key (hex)
     ident         Key identifier                     rtctest
     plainname     Key name                           rtctest
     seeintegname  SEE integrity key
     nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: C:\ProgramData\nCipher\Key Management Data\local\key_simple_rtctest
    The rtc example application only supports the use of RSA keys.
  4. Run the RTC example by executing the following command:

    Linux
    ./rtc mytestuserdata simple,rtctest > mytestuserdata.stamp
    Windows
    rtc.exe mytestuserdata simple,rtctest > mytestuserdata.stamp
  5. Complete the on-screen instructions:

    Please insert the next operator card annvramd press enter.
    Please enter card passphrase:
    rtc: timestamp issued.
What the code actually does

The host-side code performs the following tasks in order:

  1. It sends a session key to the HSM.

  2. When a time-stamped command is returned, it verifies the time-stamp using the session key.

The HSM-side code performs the following tasks in order:

  1. It awaits a job from the host.

  2. It time-stamps the contents of the job and signs the result with the session key.

  3. It returns the job to the host.

Example: Tickets

This example source code is an API demonstration showing how an SEE machine can be written in C.

The Tickets example is not intended to be the basis for any real world applications. In particular, it does not support the loading of keys protected by card sets with the -k option. It is intended to demonstrate:

  • How to write SEE machines in C

  • Simple, custom-built marshalling and unmarshalling of jobs

  • The use of tickets. See Internals for information about key tickets; also, for information about the consumption of single ticket, see Loading stored keys.

Windows only

%NFAST_HOME%\c\csd\examples\csee\tickets\

The C code consists of the following parts:

  • In the module directory, the source for the SEE machine:

    • armtickets.c (SEE machine start-up and job-processing threads)

    • usrjobs.c (job processing code)

  • In the host directory, source for the host application:

    • hosttickets.c (starts the SEE machine, sends jobs and traces debug).

  • The common directory contains a simple header file (common.h) for shared data structures between the HSM and the host code.

Sample makefiles are provided for building the HSM and host-side code (Makefile-host) and can be found in their respective directories.

Signing, packing, and loading the SEE machine

To sign, pack, and load the SEE machine:

  1. Change to the module directory by running the command:

    For nShield Solo

    Linux
    cd ~/buildSoloMod/csee/tickets/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\tickets\module

    For nShield Solo XC

    Linux
    cd ~/buildXCMod/csee/tickets/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\tickets\module
  2. Use the tct2 command line utility to convert the file into a SAR file.

    For nShield Solo

    Convert the armtickets.sxf file into a SAR file.

    tct2 -m 1 --pack --infile armtickets.sxf --outfile armtickets.sar

    For nShield Solo XC

    Convert the armtickets.elf file into a SAR file.

    tct2 -m 1 --pack --infile armtickets.elf --outfile armtickets.sar
  3. Load the SEE machine into the HSM by running the command:

    loadmache armtickets.sar
    This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. For information about configuration files, see the User Guide
  4. Generate a key for the example to use by running the command and completing the prompts in the output as follows:

    Linux
    generatekey simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,
    HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512,
    HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > ticketkey
    plainname: Key name? [] > ticketkey
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, nvrammachine, a3a8userdata, hellomachine, rtccode) []
    >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
    operation     Operation to perform               generate
    application   Application                        simple
    protect       Protected by                       token
    slot          Slot to read cards from            0
    recovery      Key recovery                       yes
    verify        Verify security of key             yes
    type          Key type                           RSA
    size          Key size                           2048
    pubexp        Public exponent for RSA key (hex)
    ident         Key identifier                     ticketkey
    plainname     Key name                           ticketkey
    seeintegname  SEE integrity key
    nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: /opt/nfast/kmdata/local/key_simple_ticketkey
    Windows
    generatekey -m 1 simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,
                    HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512,
                    HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > ticketkey
    plainname: Key name? [] > ticketkey
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, a3a8userdata, hellomachine, rtccode) [] >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation     Operation to perform               generate
     application   Application                        simple
     protect       Protected by                       token
     slot          Slot to read cards from            0
     recovery      Key recovery                       yes
     verify        Verify security of key             yes
     type          Key type                           RSA
     size          Key size                           2048
     pubexp        Public exponent for RSA key (hex)
     ident         Key identifier                     ticketkey
     plainname     Key name                           ticketkey
     seeintegname  SEE integrity key
     nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: C:\ProgramData\nCipher\Key Management Data\local\key_simple_ticketkey

hosttickets

The hosttickets example application takes the following arguments:

hosttickets [-f|--file <userdatafile>][-k|--key <APPNAME>,<IDENT>]
-k|--key <APPNAME>,<IDENT>

These options specify a Security World key.

For the public/private key pair, a Security World key can be specified with the -k option. The specified Security World key must be an RSA key of the type simple that is not tied to an SEE code-signing key. Otherwise, a fresh RSA key pair is generated automatically.

-f|--file <userdatafile>

These options specify a file for the userdata block.

The option to load a file for the userdata block is included only for example purposes.

Running the example application

  1. Change to the host application directory by running the following command:

    Linux
    cd ~/buildhost/csee/tickets/hostside/
    Windows
    cd C:\Users\<USER-NAME>\Documents\hostside\csee\tickets\hostside
  2. Run the hosttickets example application, specifying the simple key created earlier:

    Linux
    ./hosttickets -k simple,ticketkey
    Windows
    hosttickets.exe -k simple,ticketkey
  3. Complete the on-screen instructions:

    Enter string to be encrypted (256 characters maximum): lskjfdljsdlfjsdlk
    HostSide> Loading security world key (simple,ticketkey)
    
    Please present the cardset protecting the key:
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    HostSide> Creating World: init status was 0 (OK)
    HostSide> Sending ticket for private RSA key to module
    HostSide> Generating AES session key and creating blob under public RSA key
    HostSide> Sending key blob to module
    HostSide> Sending cipher-text to module
    HostSide> decrypted cipher text received from SEE machine:
    "lskjfdljsdlfjsdlk"
    HostSide> Thank you for watching. The end.

What the code actually does

The host-side code performs the following tasks in order:

  1. It prompts the user for a string.

  2. It acquires an RSA key pair, either freshly created or loaded from the Security World (only HSM protected key pairs are supported).

  3. It sends a ticket for the private half of the RSA key to the HSM-side code.

  4. It generates a session key (DES3).

  5. It encrypts the session key as a blob with the public half of the RSA key.

  6. It sends the resulting blob to the HSM-side code.

  7. It encrypts the string with the session key.

  8. It sends the encrypted string to the HSM-side code.

  9. It receives the decrypted string back from the HSM.

The HSM-side code awaits jobs from the host and performs the following tasks in order:

  1. It receives and redeems the ticket for the private RSA key.

  2. It receives the session key blob and decrypts it with the private RSA key.

  3. It receives the encrypted string and decrypts it with the session key.

  4. It sends the decrypted string back to the HSM.

Example: Benchmark

This example source code implements a very simple utility that uses an SEE machine written in C to time stamp requests to benchmark the speed of response to requests. You can use it for benchmarking during the development of other SEE machines or adapt it as required.

Your SEE-Ready HSM must have an onboard real-time clock for this example to run correctly, and you must have set the clock using the rtc command-line utility
This utility does not accept encrypted user data.

bm-test

The bm-test example application takes the following arguments:

bm-test [-l|--log <LOGFILE>][-a|--userdata <userdatafile>] <APPNAME>,<IDENT>
-l|--log <LOGFILE>

These options specify a file name to which to write time-stamps. If no log file is specified, no logging occurs.

-a|--userdata <userdatafile>

These options specify a file for an (optional) userdata block.

<APPNAME>,<IDENT>

These parameters specify the APPNAME and IDENT of a key that is to be into the SEE machine (and that SEE machine thereafter uses for signing purposes).

This utility does not have the --slot or --debug standard options.

bm-verify

The bm-verify example application takes the following arguments:

bm-verify <LOGFILE>

The LOGFILE parameter specifies the name of the log file created by the bm-test example application (specified by that application’s -l|--log option).

Packing and loading the SEE machine

To pack and load the SEE machine:

  1. Change to the module directory by running the command:

    For nShield Solo

    Linux
    cd ~/buildSoloMod/csee/benchmark/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildSoloMod\csee\benchmark\module

    For nShield XC

    Linux
    cd ~/buildXCMod/csee/benchmark/module
    Windows
    cd C:\Users\<USER-NAME>\Documents\buildXCMod\csee\benchmark\module
  2. Use the tct2 command line utility to convert the file into a SAR file.

    For nShield Solo

    Convert the bm-machine.sxf file into a SAR file.

    tct2 -m 1 --pack --infile bm-machine.sxf --outfile bm-machine.sar

    For nShield XC

    Convert the bm-machine.elf file into a SAR file.

    tct2 -m 1 --pack --infile bm-machine.elf --outfile bm-machine.sar
  3. Load the SEE machine into the HSM by running the command:

    loadmache bm-machine.sar
    This example describes how to load the SEE machine by running the loadmache command-line utility. In a production environment, you can choose to configure the load_seemachine section of the host or client configuration file so that an SEE machine is loaded automatically. For information about configuration files, see the User Guide.
  4. Generate a key for the benchmark application to use by running the command and completing the prompts in the output as follows:

    Linux
    generatekey simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,
    HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512,
    HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > benchmark-test
    plainname: Key name? [] > benchmark
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, nvrammachine, a3a8userdata, hellomachine, rtccode) []
    >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
    operation     Operation to perform               generate
    application   Application                        simple
    protect       Protected by                       token
    slot          Slot to read cards from            0
    recovery      Key recovery                       yes
    verify        Verify security of key             yes
    type          Key type                           RSA
    size          Key size                           2048
    pubexp        Public exponent for RSA key (hex)
    ident         Key identifier                     benchmark-test
    plainname     Key name                           benchmark
    seeintegname  SEE integrity key
    nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `ocs-dev':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `ocs-dev' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: /opt/nfast/kmdata/local/key_simple_benchmark-test
    Windows
    generatekey -m 1 simple

    Output:

    protect: Protected by? (token, module) [token] >
    recovery: Key recovery? (yes/no) [yes] >
    type: Key type? (AES, DES2, DES3, DH, DHEx, DSA, EC, ECDH, ECDSA, Ed25519,
                     HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512,
                     HMACTiger, KCDSA, Rijndael, RSA, X25519) [RSA] >
    size: Key size? (bits, minimum 1024) [2048] >
    OPTIONAL: pubexp: Public exponent for RSA key (hex)? []
    >
    ident: Key identifier? [] > benchmark-test
    plainname: Key name? [] > benchmark-test
    OPTIONAL: seeintegname: SEE integrity key?
    (a3a8machine, a3a8userdata, hellomachine, rtccode) [] >
    nvram: Blob in NVRAM (needs ACS)? (yes/no) [no] >
    key generation parameters:
     operation     Operation to perform               generate
     application   Application                        simple
     protect       Protected by                       token
     slot          Slot to read cards from            0
     recovery      Key recovery                       yes
     verify        Verify security of key             yes
     type          Key type                           RSA
     size          Key size                           2048
     pubexp        Public exponent for RSA key (hex)
     ident         Key identifier                     benchmark-test
     plainname     Key name                           benchmark-test
     seeintegname  SEE integrity key
     nvram         Blob in NVRAM (needs ACS)          no
    
    Loading `dev-ocs':
     Module 1: 0 cards of 1 read
     Module 1 slot 0: `dev-ocs' #1
     Module 1 slot 0:- passphrase supplied - reading card
    Card reading complete.
    
    Key successfully generated.
    Path to key: C:\ProgramData\nCipher\Key Management Data\local\key_simple_benchmark-test

Running the example application

To use the example change to the host application directory by running the command:

Linux
cd ~/buildhost/csee/benchmark/hostside/
Windows
cd C:\Users\<USER-NAME>\Documents\host\csee\benchmark\hostside

Run the bm-test example application as follows, completing any on-screen instructions in the output:

Linux
./bm-test -l bmtest.log simple benchmark-test
Windows
bm-test.exe -l bmtest.log simple benchmark-test

Output:

Please insert the next operator card and press enter.
Please enter card passphrase:
1 878 878.00
2 1758 879.00
3 2639 879.67
4 3522 880.50
5 4406 881.20
6 5284 880.67
.
.
.
The application will run indefinitely, the user must terminate the application manually by using Ctrl-C.

Run the bm-verify example application, specifying the log file, bm-test.log, created in the previous step by the bm-test application.

Linux
./bm-verify bmtest.log
Windows
bm-verify.exe bmtest.log

Output:

Verified timestamp #1.
Verified timestamp #2.
Verified timestamp #3.
Verified timestamp #4.
Verified timestamp #5.
Verified timestamp #6.

.
.
.

What the code actually does

The host program performs the following tasks in order:

  1. It tickets a generated key into the SEE machine.

  2. The SEE machine uses that key for signing purposes.

  3. Each request is concatenated with the current time and then signed.

  4. The signature is concatenated with the time and then returned to the host side.

On the host side, two programs are generated:

  • bm-test

  • bm-verify.

The bm-test command is used to generate pseudo-random values that are sent to the HSM-side code to be signed. Every second, the total number of completed time-stamp requests is printed, along with the average number completed each second.

The bm-verify command looks for the file specified as LOGFILE on the host. From this file, bm-verify extracts the public key and verifies the time-stamp requests until it finds an invalid request or reaches the end of the file.

About the Java example

We supply a Java version of the HelloWorld example. This consists of the source files for host-side applications that you can run with the example SEE machines written in C (or any other SEE machines written in any language) in order to understand how simple SEE machines work.

For information about the C examples for SEElib, see Examples for SEElib

The Java SEE example files can be found within the nCipherKM-SEE-Examples jar located in /opt/nfast/java/examples (Linux) or %NFAST_HOME%\java\examples (Windows). A common directory is also supplied which contains files that are used by more than one of the examples.

The Java examples have the same options as their equivalent, similarly named C examples.

Supported versions of Java

The following versions of Java have been tested to work with, and are supported by, your nShield Security World Software:

  • Java7 (or Java 1.7x)

  • Java8 (or Java 1.8x)

  • Java11

We recommend that you ensure Java is installed before you install the Security World Software. The Java executable must be on your system path.

If you can do so, please use the latest Java version currently supported by Entrust that is compatible with your requirements. Java versions before those shown are no longer supported. If you are maintaining older Java versions for legacy reasons, and need compatibility with current software, please contact https://www.oracle.com/java/technologies/javase-jdk11-downloads.html for Java downloads.

HelloWorld.java
The HelloWorld.java example is not intended to be the basis for any real world applications. It is intended only to demonstrate host-side use of an SEE machine by code written in Java.

First, ensure you have already built the file hello.sxf as described in Examples for SEElib converted this into the file hello.sar and loaded it into the HSM as described in Signing, packing, and loading the SEE machine.

To build the example:

  1. Change to the example directory by running the command:

    Linux
    cd /opt/nfast/java/examples
    Windows
    cd %NFAST_HOME%\java\examples
  2. Extract the example files by running the command:

    Linux
    jar xf nCipherKM-SEE-Examples.jar
    jar xf ../classes/nCipherKM-jhsee.jar
    Windows
    jar xf nCipherKM-SEE-Examples.jar
    jar xf ..\classes\nCipherKM-jhsee.jar
  3. Compile the example using this command:

    Linux
    javac -cp /opt/nfast/java/classes/nCipherKM.jar com/ncipher/see/hostside/*.java
    javac -cp .:/opt/nfast/java/classes/nCipherKM.jar com/ncipher/see/hostside/examples/helloworld/HelloWorld.java
    Windows
    javac -cp "%NFAST_HOME%\java\classes\nCipherKM.jar com\ncipher\see\hostside\*.java"
    javac -cp "%NFAST_HOME%\java\classes\nCipherKM.jar ^ com\ncipher\see\hostside\examples\helloworld\HelloWorld.java"

To run the helloworld example:

  1. Ensure you are in the example’s directory by running the command:

    Linux
    cd /opt/nfast/java/examples
    Windows
    cd %NFAST_HOME%\java\examples
  2. Run the example:

    Linux
    java -cp .:/opt/nfast/java/classes/nCipherKM.jar com/ncipher/see/hostside/examples/helloworld/HelloWorld <FILENAME> [<USERDATA>]
    Windows
    java -cp "%NFAST_HOME%\java\classes\nCipherKM.jar ^
    com\ncipher\see\hostside\examples\helloworld\HelloWorld <FILENAME> [<USERDATA>]"

In this example, <FILENAME> is the name of an input file to pass to the SEE machine as an SEE job, and <USERDATA> the name of an (optional) userdata file. The SEE machine transforms the input by replacing all lowercase alphabetic characters in <FILENAME> with their uppercase equivalents and replacing any characters in <FILENAME> that are also found in <USERDATA> (if supplied) with the character X.