Security User Guide: Intel® FPGA Programmable Acceleration Card D5005

ID 683877
Date 8/25/2020
Public

3.10. Creating a Custom HSM Manager

PACSign is a Python tool that uses a plugin architecture for the HSM interface. PACSign is distributed with managers for both OpenSSL and PKCS #11. This section describes the functionality required by PACSign from the HSM interface and shows how to construct a plugin.

The distribution of PACSign uses the following directory structure:

├───hsm_managers
│ ├───openssl_manager
│ │ └───library
│ └───pkcs11_manager
└───source

The top level contains PACSign.py with the generic signing code in source. The HSM managers reside each in their own subdirectory under hsm_managers as packages. The directory name is what is given to PACSign’s --HSM_MANAGER command-line option. If the specific manager requires additional information, you can provide it using the optional --HSM_config command-line option. For example, the PKCS #11 plugin requires a *.json file describing the tokens and keys available on the HSM.

You must place each plugin that is to be supported in a subdirectory of the hsm_managers directory. Use a descriptive name for the directory that clearly describes the supported HSM. This subdirectory may have an __init__.py file whose contents import the modules needed by the plugin. The names of the plugin modules are not important to the proper functioning of PACSign.

The newly-created plugin must be able to export one attribute named HSM_MANAGER that is invoked by PACSign with an optional configuration file name provided on the command-line. Invocation of HSM_MANAGER(config_file) returns a class with certain methods exposed, which are described in later sections.

Current implementations of HSM_MANAGER define it as a Python class object. The initialization function of the class reads and parses the configuration file (if present) and performs HSM initialization. For the PKCS #11 implementation, the class looks like this:
class HSM_MANAGER(object):
	def __init__(self, cfg_file = None):
		common_util.assert_in_error(cfg_file, \
			PKCS11 HSM manager requires a configuration file")
		self.session = None
		with open(cfg_file, "r") as read_file:
			self.j_data = json.load(read_file)
		j_data = self.j_data

		lib = pkcs11.lib(j_data['lib_path'])
		token = lib.get_token(token_label=j_data['token']['label'])
		self.session = token.open(user_pin=j_data['token']['user_password'])
		self.curve = j_data['curve']

		self.ecparams = self.session.create_domain_parameters( \
		pkcs11.KeyType.EC, {pkcs11.Attribute: \
		pkcs11.util.ec.encode_named_curve_parameters(self.curve)}, \
		local=True)
Error handling code has been omitted for clarity. This code does the following:
  • Opens and parses the *.json configuration file.
  • Loads the vendor-supplied PKCS #11 library into the program.
  • Sets up a session with the correct token.
  • Retrieves the proper elliptic curve parameters for the curve you select.

The following sections describe the required exported methods of this class.