This document provides information about Infrastructure IO Encryption, both
the use and adding new encryption techniques.
Encryption is enabled by adding the encryption type and an encryption key
("TCP logicalName Host Port EncType EncKey")
to a normal queue definition.
Using this technique, any infrastructure communication path may be encrypted.
Currently, there are two encryption types supported, Blowfish and AES.
Blowfish can use keys of any length while AES keys must be a MINIMUM of 12
CHARACTERS LONG.
The key provided is actually a "seed" used to create the actual encryption key.
The system dithers (modifies) each connection's key per additional random information, thus each connection uses a different key.
For any two processes to communicate via an encrypted channel, they must be
using the same encryption type and the exact same key.
A process may communicate with different remote processes using different encryption by assigning each encryption type/key to a different host port.
Each encryption type requires a suite of five functions to support it.
The following are generic descriptions of these encryption functions.
The "xx" is the prefix like "bf" for blowfish and "aes" for AES.
The reason I broke the functions out the way they are is so they may also be used by other parts of the system or stand alone programs.
xxAddVecs( cryp_t *ecb )
When the connection is being established a new connection control block is built and this function is called by ioBldEnc() to populate it with the correct encryption vectors (mkKey, end, dec, and free).
xxMkKey( cryp_t *ecb, char *seed, int dither, int typ )
Creates encryption keys for either the input or output IO buffers contained in the connection control block, whenever the connection is first established.
"ecb" is the encryption control block where the key will be stored.
The "seed" and "dither" are combined to seed the new key.
"typ" determines if this is an encrypt (output) or decrypt (input) key.
xxEnc( u_char *data, int len, cryp_t *ecb )
Encrypting the header and data in an out-bound message at the last instant before actual transmission via the socket.
"data" is the address of the data to be encrypted, "len" is the number of bytes to encrypt, and "ecb" is the encryption control block.
xxDec( u_char *data, int len, cryp_t *ecb )
Decrypting the header then the data immediately after receipt from the socket.
"data" is the address of the data to be decrypted, "len" is the number of bytes to decrypt, and "ecb" is the encryption control block.
xxFree( cryp_t *ecb )
Frees the keys in the encryption control block when the socket connection is torn down.
typedef struct cryp {
// ENCRYPTION CONTROL BLOCK
void
*key;
// THE ENCRYPTION KEY
pfi_t
mkKey;
// MAKE ENCRYPTION KEY
pfi_t
enc;
// ENCRYPT CALL
pfi_t
dec;
// DECRYPT CALL
pfi_t
free;
// FREE KEY CALL
int
encMod;
// ENCRYPTION MODULUS
}cryp_t;
The encryption control block, or ecb, contains 6 fields:
void *key points to the key specific to the encryption method.
pfi_t mkKey is the key creation function vector.
pfi_t enc is the encryption function vector.
pfi_t dec is the decryption function vector.
pfi_t free is the key deallocation or free function vector.
encMod is the encryption modulus or the multiple of space the encryption technique requires.
All messages will be allocated to an even mulitple of this byte count.
Example:
Below is a 'C' example of how to decrypt a simple block of data using the infrastructure's built in encryption/decryption.
This example uses blowfish which could be altered to AES by simply changing the 3 function prefixes from bf to aes.
In aesMkKey( &cry, ESPKEYseed, keylen, 'I' ) (or bfMkKey()) 'I' should be used for decryption whilc 'O' should be used for encryption.
#include "inf.h"
cryp_t cry;
memset( &cry, 0, sizeof( cryp_t ));
bfMkKey( &cry, ESPKEY, 271828, 'I' );
bfDec( buf, rdLen, &cry );
bfFree( &cry );