CXI
Loading...
Searching...
No Matches
Cryptographic eXtended Interface

Content


Introduction


The CXI API provides an general purpose C++ interface used to access the external functions of the CryptoServer firmware module CXI from an application running on a host.
With the CryptoServer API it is possible either to access a CryptoServer plugged in a slot of the local computer or to access a CryptoServer LAN over TCP/IP.
The CXI API can use different logical protocols with a variable number of protocol layers to communicate with the CryptoServer.
To use this interface the firmware module CXI must be loaded into the CryptoServer and the application must be able to load the specific shared library (cxi.dll / libcxi.so).

The CXI API basically supports two operating modes:

  • Dedicated Mode: One instance of CXI represents a logical connection to one CryptoServer.
    This mode has to be used if a dedicated CryptoServer should be addressed (e.g. for key management).
  • Cluster Mode: One instance of CXI represents a logical connection to a cluster of CryptoServers.
    This mode supports a failover mechanism, that automatically switches to another CryptoServer in case of a communication error.
    The API only returns an error if the communication to all devices failed or if the CryptoServer responds an application error.
    Additionally, a load balancing mechanism is supported where the devices can be simultaneously used to distribute the connection processing across the clustered devices.
See also
Programming Interface on how to apply an operating mode.
The CXI API offers various cryptographic services (see cxi::Cxi):
  • Construction / Destruction
    • create instance that represents a logical connection to a dedicated CryptoServer
    • create instance that represents a logical connection to a cluster of CryptoServers
    • create instance based on a configuration file (either dedicated or cluster)
  • Basic Functions
    • execute arbitrary command on CryptoServer
    • get version of CXI API and CXI firmware module
  • Authentication
    • password mechanisms
    • signature mechanisms (RSA, ECDSA) with smartcard
    • signature mechanisms (RSA, ECDSA) with (password encrypted) key files
  • Key Management
    • key generation (DES, AES, RSA, ECDSA, DSA)
    • import and export of keys
    • backup and restore of keys
    • get/set key properties
  • Cryptography
    • encryption / decryption (DES, AES, RSA, ECIES)
    • signature generation / verification (ECDSA, RSA)
    • MAC calculation / verification (DES, AES)
    • calculation of shared secrets (ECDSA)
    • generation of random bytes
Note
The complete class overview can be found here.

The CXI API is also available for the programming languages JAVA (CryptoServerCXI.jar) and the dot.NET languages C#, C++ and Basic (cxi.net.dll).

Key Storage


Within CXI keys are identified by their key name, key group and key specifier. The key name is mandatory, group and specifier are optional and may be omitted.
In either case the combination of name, group and specifier has to be unique.
Keys can either be stored on the CryptoServer (internal) or on the host PC (external). On generation or import of keys the application can decide whether to store the key internally or externally.

In case of internal keys the application receives a key handle that links to the key, otherwise, in case of external keys, the application receives a key blob, that contains the key, encrypted with the CryptoServers Master Backup Key. CXI offers a key store (see cxi::KeyStore) that can be used to store external keys, but the application may also use other storage locations for external keys (e.g. key files).

Any function on the CryptoServer that needs a key as input parameter (e.g. encryption or signature creation), accepts either key handles or key blobs. If a key handle is given the key is loaded from the key database, if a key blob is given the key is decrypted with the Master Backup Key. Basically the usage of internal and external keys can be mixed.

Authentication


Any user who wants to execute security relevant commands on the CryptoServer has to authenticate to the CryptoServer. Some commands can either be executed by one user holding the exclusive permissions or by two users with shared permissions (two-person rule). In either case the CryptoServer calculates the resulting permission level, and checks whether the desired command may be executed.

The CryptoServer API supports the following authentication methods:

  • RSA Signature and ECDSA Signature
    The command is signed with the private part of the RSA or ECDSA key and the CryptoServer verifies the signature with the public part of the key.
    The private part of the key (used to create the signature) can be stored on the following media:
    • plaintext key file
    • password-encrypted key file
    • smartcard (the smartcard reader has to be connected to the host PC)

    In either case the public part of the key has to be imported into the CryptoServer on creation of the user.
  • RSA Smartcard
    This method is a special case of RSA Signature, where the smartcard reader (PIN pad) is directly connected to the CryptoServer.
  • HMAC hashed password Password authentication using a Hash-based Message Authentication Code.
    Note
    On a cluster of CryptoServers only password authentication is supported (see cxi::Cxi::logon_pass).
    In order to apply an authentication method a user with the corresponding authentication mechanism is needed. The authentication mechanism has to be assigned on creation of the user and can't be changed later.

Secure Messaging


Instead of authenticating every command, the CryptoServer API allows to create an encrypted 'Secure Messaging' session with the CryptoServer. Thereby the user only authenticates the creation of the session (exchange of the session key). Any command sent through this session will automatically be authenticated with the permission of the user.

A session can be created by using one of the following methods:

Note
If a session remains idle (no command was sent) for more than 15 minutes, the session expires and is automatically invalidated by the CryptoServer.
Set the keep_alive parameter of the logon_XXX methods to true to prevent a session from expiration.

Key Access Restrictions


Any user who wants to access an - internal or external - key has to authenticate to the CryptoServer. The CryptoServer checks on a resulting permission level of 2 in group 0 (mask: 00000002). The necessary permission level of 2 in group 0 can be achieved by either two user with a permission level of one (Two-Persons-Rule) or one user with a permission level of 2.

If a key has been assigned to a group (on key generation or import), it may only be accessed by a user who is member of the same group. Therefore the user attribute 'CXI_GROUP' has to be set on creation of the user. The CXI_GROUP attribute may also contain wildcards '*' or question marks '?' in order to assign a user to multiple groups.
Examples:

  • User 1: CXI_GROUP=test
    This user may only access keys with the group attribute 'test', other keys are 'invisible' for the user.
  • User 2: CXI_GROUP=test*
    This user may only access whose entity attributes start with 'test' (e.g. 'test', 'test01', 'test_xxx'), other keys are 'invisible' for the user.
  • User 3: CXI_GROUP=*
    This user is allowed to access all keys.

If no group attribute has been set for a key, the key may be accessed by all users regardless of their group membership.

Load Balancing


In a load balancing cluster the CryptoServer devices are configured to optimize the use of resources to reach higher system performance, and to avoid overloading a single device. All CryptoServer in the cluster must be configured identically. A new connection is always established to the CryptoServer with the least number of existing connections. In case of communication errors the API automatically switches to the next device and tries to execute the command on that CryptoServer. Only if the API wasn't able to execute the command on any device, it gives up and throws an exception.

Failover


CXI provides fault tolerant operation on a CryptoServer cluster. In case of communication errors the API automatically switches to the next device and tries to execute the command on that CryptoServer. Only if the API wasn't able to execute the command on any device, it gives up and throws an exception.
After having successfully switched to another device the API basically stays connected with this device and does not switch back. Optionally, a fallback interval may be configured that causes the API to switch back to the first (primary) device of the device list.

Programming Interface


In order to use the CXI API the file 'cxi.h' has to be included and the application has to be linked against the CXI library file.
The API consists of its main class CXI and several other classes that are needed to handle with objects (e.g. keys, properties, configuration).
The complete class overview can be found here

CXI offers three constructors to be used for different purposes:

  • cxi::Cxi::Cxi(char *device, int timeout, int ctimeout)
    Opens the specified CryptoServer with the given connect and command timeouts. Use this constructor if you want to use a single device exclusively.

  • cxi::Cxi::Cxi(char **devices, int ndevs, int timeout, int ctimeout, int fallback_interval)
    Opens multiple CryptoServer as a cluster. Use this constructor if you want to set up a fault-tolerant system that supports failover.

  • cxi::Cxi::Cxi(Config &config)
    Reads the device configuration from the given configuration file. Here you can either configure a single device (e.g. 'Device = PCI:0') or multiple devices as a cluster
    (e.g. 'Device = PCI:0 192.168.4.1 192.168.4.2')
Note
Don't use cluster mode if a dedicated CryptoServer should be addressed!

Examples


The following code illustrates how to manage keys on a single device:

#include <iostream>
#include <cxi.h>
using namespace cxi;
printf("CXI library version: %08x\n", Cxi::get_version());
Cxi *cxi = NULL;
try
{
// init logging
Log &log = Log::getInstance();
log.init("./cxi.log", Log::LEVEL_WARNING, 1000000);
// open CryptoServer PCI
cxi = new Cxi("PCI:0", 20000, 5000);
// logon a user with smartcard based signature authentication mechanism
cxi->logon_sign("SO1", ":cs2:cyb:COM3", NULL);
// logon a second user with key file based signature authentication mechanism
cxi->logon_sign("SO2", "so01_rsa.key", "mypass");
// create a key
PropertyList keyTemplate;
keyTemplate.setAlgo(CXI_KEY_ALGO_AES);
keyTemplate.setSize(256);
keyTemplate.setName("AES test key");
Key aesKey = cxi->key_generate(CXI_FLAG_KEY_OVERWRITE, keyTemplate);
}
catch (Exception &ex)
{
printf("%sat %s\n", ex.err_str, ex.where);
}
// delete Cxi object
delete cxi;
Command interface to CXI firmware module. Handles all communication with the CryptoServer.
Definition: sw/cxi_api_c/def/cxi.h:60
Constructs an exception object.
Definition: sw/cxi_api_c/def/exception.h:22
char * where
name of function where error occurs
Definition: sw/cxi_api_c/def/exception.h:26
char * err_str
plain text error message
Definition: sw/cxi_api_c/def/exception.h:25
Encapsulates key handles or key blobs of type 'Backup Blob', see Format of Key Blobs.
Definition: sw/cxi_api_c/def/key.h:19
Provides unified logging.
Definition: sw/cxi_api_c/def/log.h:33
void init(const char *filename=NULL, int level=Log::LEVEL_NONE, int size=0)
Definition: log.cpp:346
Constructs and parses key property lists, see Key Properties.
Definition: sw/cxi_api_c/def/propertylist.h:19
void setSize(int size)
Definition: propertylist.cpp:497
void setAlgo(int algo)
Definition: propertylist.cpp:481
void setName(const char *name)
Definition: propertylist.cpp:510
#define CXI_KEY_ALGO_AES
AES.
Definition: fw/cxi/def/cxi_defs.h:180
#define CXI_FLAG_KEY_OVERWRITE
Overwrite key if already existing.
Definition: fw/cxi/def/cxi_defs.h:501
Definition: cxi.cpp:173

The following code illustrates how to use cryptographic functions on a cluster of devices:

#include <cxi.h>
using namespace cxi;
Cxi *cxi = NULL;
try
{
// create configuration object
Config config = Config("./cxi.cfg");
// create new Cxi object with the given configuration
cxi = new Cxi(config);
// logon a user with password mechanism
cxi->logon_pass("USER", "swordfish", true);
// open previously generated AES key
PropertyList keyTemplate;
keyTemplate.setName("AES test key");
Key aesKey = cxi->key_open(CXI_KEY_FLAG_EXTERNAL, keyTemplate);
// encrypt data with the key
ByteArray data = ByteArray("Change, we can believe in");
ByteArray crypt = cxi->crypt(0, aesKey, mechParam, data);
}
catch (Exception &ex)
{
printf("%sat %s\n", ex.err_str, ex.where);
}
// delete Cxi object
delete cxi;
Encapsulates an array of primitive type char in an object and provides methods to operate on binary d...
Definition: sw/cxi_api_c/def/bytearray.h:22
Reads and parses configuration files and provides methods to access configuration items.
Definition: sw/cxi_api_c/def/config.h:28
Constructs mechanism parameter that are used on cryptographic operations. A mechanism parameter consi...
Definition: sw/cxi_api_c/def/mechparam.h:21
#define CXI_MECH_CHAIN_CBC
Cipher Block Chaining.
Definition: fw/cxi/def/cxi_defs.h:357
#define CXI_MECH_MODE_ENCRYPT
Encryption mode.
Definition: fw/cxi/def/cxi_defs.h:332
#define CXI_MECH_PAD_NONE
Don't apply padding.
Definition: fw/cxi/def/cxi_defs.h:395

Supported Algorithms


The CXI firmware module supports the following algorithms and mechanisms:

Algorithm Key Sizes [bit] Mode Chaining Padding
DES 56,112,168 Encryption, Decryption ECB, CBC None, PKCS#5, ISO7816, Random
Mac CBC, CBC-Retail, CFB-Retail None, Zero, PKCS#5, ISO7816, Random
AES 128,192,256 Encryption, Decryption ECB, CBC, GCM, OFB, CCM None, PKCS#5, ISO7816, Random
Mac CBC, GMAC, CMAC None, Zero, PKCS#5, ISO7816, Random
RSA 512...16384 (delta = 1bit) Encryption, Decryption - None, PKCS#1, PKCS-OAEP
Sign, Verify - PKCS#1, X9.31, PKCS-PSS
ECDSA Brainpool: 160..512
NIST: 192..521
secp: 112..571
Encryption, Decryption
(ECIES)
- -
Sign, Verify
(Raw Format, ASN.1 Format)
- -
DSA P: 512..1024, Q: 160 Sign, Verify - -

The following hash algorithms are supported:

  • SHA1
  • SHA224
  • SHA256
  • SHA384
  • SHA512
  • SHA3-224
  • SHA3-256
  • SHA3-384
  • SHA3-512
  • MD5
  • RipeMD160

Installation


Step 1:

Load the firmware module package (e.g. SecurityServer-XX-Series-x.x.x.mpkg) into the CryptoServer.

Example:
csadm <authentication> LoadPKG=SecurityServer-CS-Series-2.21.5.mpkg

Step 2:

Create one or more users with authentication mechanism either HMAC-password or signature (RSA, ECDSA) and the following properties:

  • permission of level 2 in group 0 ('00000002').
  • attribute 'CXI_GROUP=<key-group>', where 'key-group' represents the group of keys the user will be allowed to access.
    Use wildcards ('*', '?') to assign a user to multiple groups.

    Example:
    csadm <authentication> AddUser=CXI,00000002{CXI_GROUP=test*},hmacpwd,<password>

Requirements


Microsoft Visual C++ SP1 redistributable package

On Microsoft Windows the CXI API requires the redistributable package runtime library to be installed. It is required to run applications developed with Visual C++ 2008 SP1 on a PC that have no Visual C++ 2008 SP1 installed. The package is automatically installed on installation of the Utimaco CryptoServer Product CD, but it also can be obtained from the Microsoft websites (a version for 32 bit and 64 bit is available).