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).
- CFB (Cipher Feedback 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).
- GCM (Galois 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.
- Also it does a message authentication over the plaintext and some optional associated data, like headers (AEAD cipher). This is useful for avoiding the extra CPU power needed for a keyed hash function like HMAC-SHA256.
- Considered to be secure (unless key and IV are reused).
File information
Classes
cipher
class Cipher {
public:
Cipher();
void Init(cipher_t type, const byte * key, int keyLen, bool encrypt = true, bool makekey = 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);
bool GcmCrypt(const byte * aad, int aad_len, const byte * in, byte * out, int len, byte * iv, byte * tag);
void CfbCrypt(const byte * in, byte * out, int len, byte * iv);
void CbcCrypt(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.
|
bool makekey |
true if the key is to be generated/modified by means of a protocol-specific method. false if the key is to be taken as-is (currently for DES only).
|
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.
CfbCrypt
Implementation of the cipher feedback 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 cipher feedback mode. The size must match the block size of the underlying cipher (16 bytes for AES).
The content of the buffer is updated, so it can be reused for subsequent encryptions / decryptions.
|
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.
CbcCrypt
Implementation of the cipher block chaining 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 |
The number of bytes that shall be encrypted / decrypted. Must be a multiple of the block size (8 bytes for DES).
|
byte * iv |
The initialization vector for cipher block chaining mode. The size must match the block size of the underlying cipher (8 bytes for DES).
The content of the buffer is updated, so it can be reused for subsequent encryptions / decryptions.
|
Remarks
The function is not implemented for RC4. If the object was initialized with 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_UNDEFINED | Used 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);
Encryption with AES-128 in cipher feedback mode
byte key[16] = { /*...*/ };
cipher c;
c.Init(CIPHER_AES, key, 16, true);
// encryption of the in1 buffer
byte iv1[16] = { /*...*/ };
byte in1[37] = { /*...*/ };
byte out1[37] = { /*...*/ };
c.CfbCrypt(in1, out1, 37, iv1);
// encryption of the in2 buffer in multiple passes
byte iv2[16] = { /*...*/ };
byte in2[132] = { /*...*/ };
byte out2[132] = { /*...*/ };
c.CfbCrypt(in2, out2, 64, iv2);
c.CfbCrypt(in2 + 64, out2 + 64, 64, iv2);
c.CfbCrypt(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->iprintf("decryption OK");
}
else {
debug->iprintf("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));