Cipher Library

This library provides functions for encrypting and decrypting data. The following ciphers are currently supported:

AES
Block cipher
Symmetric (same key for encryption and decryption)
Block size: 128 bit (16 bytes)
Key sizes: 128 bit (16 bytes), 192 bit (24 bytes), 256 bit (32 bytes)
State of the art. Considered to be secure.
DES
Block cipher
Symmetric (same key for encryption and decryption)
Block size: 64 bit (8 bytes)
Key size: 64 bit (8 bytes)
Effective key strength: 56 bit (7 bytes)
Legacy and insecure. Should not be used unless needed for compatibility with legacy protocols.
RC4
Stream cipher
Symmetric (same key for encryption and decryption)
Block size: none
Key size: any
Keys must be unique and must never be reused.
Should be considered as breakable.
Block ciphers (AES and DES) can be used in different modes of operation. The following modes are currently supported:
ECB (Electronic Code Book Mode)
The size of the data must be a multiple of the block size.
Each block is encrypted / decrypted with the same key.
Prone to statistical cryptanalysis. Should not be used unless needed for compatibility with legacy protocols.
CTR (Counter Mode)
Turns block ciphers into stream ciphers. So any data size can be processed. It doesn't need to be a multiple of the block size.
Additional to the key an initialization vector (IV) is needed.
The combination of key and IV must be unique and must never be reused.
Considered to be secure (unless key and IV are reused).

File information

Filecommon/ilib/cipher.h

Classes Cipher
Data types cipher_t

Examples Encryption with AES-256 in counter mode
Single block encryption with DES
Encryption with RC4

Classes

cipher

class Cipher {
public:
    Cipher();
    void Init(cipher_t type, const byte * key, int keyLen, bool encrypt = true);
    void Block(const byte * in, byte * out);
    void Crypt(const byte * in, byte * out, int len);
    void CtrCrypt(const byte * in, byte * out, int len, byte * iv);
    void Reset();
};

Overview

The cipher class defines a uniform interface for encrypting and decrypting data using different algorithms. Please note that currently only a small selection of ciphers and modes of operation is supported.

Public functions

Init
Initializes the internal state of the object and sets the algorithm to be used.

Parameters

cipher_t type The algorithm to be used.
const byte * key A buffer containing the encryption / decryption key.
int keyLen The size of the key in bytes. Depending on the type the following key sizes are supported.
CIPHER_AES
16 (AES-128)
24 (AES-192)
32 (AES-256)
CIPHER_DES
8
CIPHER_RC4
any positive value
bool encrypt true if the data shall be encrypted. false if the data shall be decrypted.

Remarks

The init function has to be called before using any other functions of the object.
Block
The function encrypts / decrypts a single block of data.

Parameters

const byte * in A buffer containing the data that shall be encrypted / decrypted. The valid buffer sizes for the individual ciphers are:
CIPHER_AES
16
CIPHER_DES
8
const byte * out A buffer to write the encrypted / decrypted data. It must have the same size as the in buffer.

Remarks

The function is not implemented for RC4. If the object was initialized with CIPHER_RC4 the function will fail with an assertion.
Crypt
Implements the ECB mode of operation for AES and DES, and regular encryption for RC4.

Parameters

const byte * in A buffer containing the data that shall be encrypted / decrypted.
byte * out A buffer to write the encrypted / decrypted data. It must be big enough to contain len bytes.
int len The number of bytes that shall be encrypted / decrypted.
CIPHER_AES
multiple of 16 bytes
CIPHER_RC4
any positive value

Remarks

The function is not implemented for DES. If the object was initialized with CIPHER_DES the function will fail with an assertion.
CtrCrypt
Implementation of the counter mode of operation.

Parameters

const byte * in A buffer containing the data that shall be encrypted / decrypted.
byte * out A buffer to write the encrypted / decrypted data. It must be big enough to contain len bytes.
int len Any positive number of bytes that shall be encrypted.
byte * iv The initialization vector for counter mode. The size must match the block size of the underlying cipher (16 bytes for AES). The number in the iv buffer is incremented, so it can be reused for subsequent encryptions. If it isn't reused but a new iv is set by the application, the Reset() function needs to be called before.

Remarks

The function is not implemented for DES and RC4. If the object was initialized with CIPHER_DES or CIPHER_RC4 the function will fail with an assertion.
Reset
This function is only needed in combination with CtrCrypt. It must be called each time a new initialization vector defined by the application is used.

Remarks

The function is not implemented for DES and RC4. If the object was initialized with CIPHER_DES or CIPHER_RC4 the function will fail with an assertion.

Data types

cipher_t

enum cipher_t {
    CIPHER_UNDEFINED,
    CIPHER_DES,
    CIPHER_AES,
    CIPHER_RC4
};

Overview

The cipher_t enum defines all ciphers supported by the library.

Values

CIPHER_UNDEFINEDUsed internally to identify uninitialized objects.
CIPHER_DES
CIPHER_AES
CIPHER_RC4

Remarks

The old algorithms DES and RC4 are insecure. They should not be used for new projects. Please use AES instead.

Code Example

Encryption with AES-256 in counter mode

byte key[32] = { /*...*/ };
cipher c;
c.Init(CIPHER_AES, key, 32, true);

// encryption of the in1 buffer

byte iv1[16] = { /*...*/ };
byte in1[37] = { /*...*/ };
byte out1[37] = { /*...*/ };

c.CtrCrypt(in1, out1, 37, iv1);

// encryption of the in2 buffer in multiple passes

byte iv2[16] = { /*...*/ };
byte in2[132] = { /*...*/ };
byte out2[132] = { /*...*/ };

c.Reset(); // needed because a new IV is set by the application
c.CtrCrypt(in2, out2, 64, iv2);
c.CtrCrypt(in2 + 64, out2 + 64, 64, iv2);
c.CtrCrypt(in2 + 128, out2 + 128, 4, iv2);

Single block encryption with DES

cipher c;
byte key[8] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
byte plaintext[8] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
byte ciphertext[8];
byte plaintext_check[8];

// encrypt
c.Init(CIPHER_DES, key, 8, true);
c.Block(plaintext, ciphertext);

// decrypt
c.Init(CIPHER_DES, key, 8, false);
c.Block(ciphertext, plaintext_check);

if (memcmp(plaintext, plaintext_check, 8) == 0) {
    debug->printf("decryption OK");
}
else {
    debug->printf("decryption failed");
}

Encryption with RC4

byte key[317] = { /*...*/ };
byte plaintext[510] = { /*...*/ };
byte ciphertext[510];

cipher c;
c.Init(CIPHER_RC4, key, sizeof(key), true);
c.Crypt(plaintext, ciphertext, sizeof(plaintext));