NAME
libmcrypt - encryption/decryption library
SYNOPSIS
[see also mcrypt.h for more information]
DESCRIPTION
The libmcrypt is a data encryption library. The library is
thread safe and provides encryption and decryption func-
tions. This version of the library supports many encryption
algorithms and encryption modes. Some algorithms which are
supported: SERPENT, RIJNDAEL, 3DES, GOST, SAFER+, CAST-256,
RC2, XTEA, 3WAY, TWOFISH, BLOWFISH, ARCFOUR, WAKE and more.
OFB, CBC, ECB, nOFB, nCFB and CFB are the modes that all
algorithms may function. ECB, CBC, nCFB and nOFB encrypt in
blocks but CFB and OFB in bytes (8bits). Note that CFB and
OFB in the rest of the document represent the "8bit CFB or
OFB" mode. nOFB and nCFB modes represents a n-bit OFB/CFB
mode, n is used to represent the algorithm's block size.
The library supports an extra STREAM mode to include some
stream algorithms like WAKE or ARCFOUR.
In this version of the library all modes and algorithms are
modular, which means that the algorithm and the mode is
loaded at run-time. This way you can add algorithms and
modes faster, and much easier.
LibMcrypt includes the following symmetric (block) algo-
rithms:
DES: The traditional DES algorithm designed by IBM and US
NSA. Uses 56 bit key and 64 bit block. It is now considered
a weak algorithm, due to its small key size (it was never
intended for use with classified data).
3DES or Triple DES: DES but with multiple (triple) encryp-
tion. It encrypts the plaintext once, then decrypts it with
the second key, and encrypts it again with the third key
(outer cbc mode used for cbc). Much better than traditional
DES since the key is now 168 bits (actually the effective
key length is 112 bits due to the meet-in-the-middle
attack).
CAST-128: CAST was designed in Canada by Carlisle Adams and
Stafford Tavares. The original algorithm used a 64bit key
and block. The algorithm here is CAST-128 (also called
CAST5) which has a 128bit key and 64bit block size.
CAST-256: CAST-256 was designed by Carlisle Adams. It is a
symmetric cipher designed in accordance with the CAST design
procedure. It is an extention of the CAST-128, having a 128
bit block size, and up to 256 bit key size.
xTEA: TEA stands for the Tiny Encryption Algorithm. It is a
feistel cipher designed by David Wheeler & Roger M. Needham.
The original TEA was intended for use in applications where
code size is at a premium, or where it is necessary for
someone to remember the algorithm and code it on an arbi-
trary machine at a later time. The algorithm used here is
extended TEA and has a 128bit key size and 64bit block size.
3-WAY: The 3way algorithm designed by Joan Daemen. It uses
key and block size of 96 bits.
SKIPJACK: SKIPJACK was designed by the US NSA. It was part
of the ill-fated "Clipper" Escrowed Encryption Standard
(EES) (FIPS 185) proposal. It operates on 64bit blocks and
uses a key of 80 bits. SKIPJACK is provided only as an extra
module to libmcrypt.
BLOWFISH: The Blowfish algorithm designed by Bruce Schneier.
It is better and faster than DES. It can use a key up to 448
bits.
TWOFISH: Twofish was designed by Bruce Schneier, Doug Whit-
ing, John Kelsey, Chris Hall, David Wagner for Counterpane
systems. Intended to be highly secure and highly flexible.
It uses a 128bit block size and 128,192,256 bit key size.
(Twofish is the default algorithm)
LOKI97: LOKI97 was designed by Lawrie Brown and Josef
Pieprzyk. It has a 128-bit block length and a 256bit key
schedule, which can be initialized using 128, 192 or 256 bit
keys. It has evolved from the earlier LOKI89 and LOKI91 64-
bit block ciphers, with a strenghtened key schedule and a
larger keyspace.
RC2: RC2 (RC stands for Rivest Cipher) was designed by Ron
Rivest. It uses block size of 64 bit and a key size from 8
to 1024 bits. It is optimized for 16bit microprocessors
(reflecting its age). It is described in the RFC2268.
ARCFOUR: RC4 was designed by Ron Rivest. For several years
this algorithm was considered a trade secret and details
were not available. In September 1994 someone posted the
source code in the cypherpunks mailing list. Although the
source code is now available RC4 is trademarked by RSADSI so
this algorithm is not included in the mcrypt distribution. A
compatible cipher named ARCFOUR is included in the mcrypt
distribution. It is a stream cipher and has a maximum key of
2048 bits.
RC6: RC6 was designed by Ron Rivest for RSA labs. In mcrypt
it uses block size of 128 bit and a key size of 128/192/256
bits. Refer to RSA Labs and Ron Rivest for any copyright,
patent or license issues for the RC6 algorithm. RC6 is pro-
vided only as an extra module to libmcrypt.
RIJNDAEL: Rijndael is a block cipher, designed by Joan Dae-
men and Vincent Rijmen as a candidate algorithm for the AES.
The cipher has a variable block length and key length. Rijn-
dael can be implemented very efficiently on a wide range of
processors and in hardware. The design of Rijndael was
strongly influenced by the design of the block cipher
Square. There exist three versions of this algorithm,
namely: RIJNDAEL-128 (the AES winner) , RIJNDAEL-192 ,
RIJNDAEL-256 The numerals 128, 192 and 256 stand for the
length of the block size.
MARS: MARS is a 128-bit block cipher designed by IBM as a
candidate for the Advanced Encryption Standard. Refer to IBM
for any copyright, patent or license issues for the MARS
algorithm. MARS is provided only as an extra module to
libmcrypt.
PANAMA: PANAMA is a cryptographic module that can be used
both as a cryptographic hash function and as a stream
cipher. It designed by Joan Daemen and Craig Clapp. PANAMA
(the stream cipher) is included in libmcrypt.
WAKE: WAKE stands for Word Auto Key Encryption, and is an
encryption system for medium speed encryption of blocks and
of high security. WAKE was designed by David J. Wheeler. It
is intended to be fast on most computers and relies on
repeated table use and having a large state spece.
SERPENT: Serpent is a 128-bit block cipher designed by Ross
Anderson, Eli Biham and Lars Knudsen as a candidate for the
Advanced Encryption Standard. Serpent's design was limited
to well understood mechanisms, so that could rely on the
wide experience of block cipher cryptanalysis, and achieve
the highest practical level of assurance that no shortcut
attack will be found. Serpent has twice as many rounds as
are necessary, to block all currently known shortcut
attacks. Despite these exacting design constraints, Serpent
is faster than DES.
IDEA: IDEA stands for International Data Encryption Algo-
rithm and was designed by Xuejia Lai and James Massey. It
operates on 64bit blocks and uses a key of 128 bits. Refer
to Ascom-Tech AG for any copyright, patent or license issues
for the IDEA algorithm. IDEA is provided only as an extra
module to libmcrypt.
ENIGMA (UNIX crypt): A one-rotor machine designed along the
lines of Enigma but considerable trivialized. Very easy to
break for a skilled cryptanalist. I suggest against using
it. Added just for completeness.
GOST: A former soviet union's algorithm. An acronym for
"Gosudarstvennyi Standard" or Government Standard. It uses a
256 bit key and a 64 bit block.
The S-boxes used here are described in the Applied Cryptog-
raphy book by Bruce Schneier. They were used in an applica-
tion for the Central Bank of the Russian Federation.
Some quotes from gost.c: The standard is written by A.
Zabotin (project leader), G.P. Glazkov, and V.B. Isaeva. It
was accepted and introduced into use by the action of the
State Standards Committee of the USSR on 2 June 1989 as No.
1409. It was to be reviewed in 1993, but whether anyone
wishes to take on this obligation from the USSR is question-
able.
This code is based on the 25 November 1993 draft transla-
tion by Aleksandr Malchik, with Whitfield Diffie, of the
Government Standard of the U.S.S.R. GOST 28149-89, "Crypto-
graphic Transformation Algorithm", effective 1 July 1990.
(Whitfield.Diffie@eng.sun.com) Some details have been
cleared up by the paper "Soviet Encryption Algorithm" by
Josef Pieprzyk and Leonid Tombak of the University of Wol-
longong, New South Wales. (josef/leo@cs.adfa.oz.au)
SAFER: SAFER (Secure And Fast Encryption Routine) is a block
cipher developed by Prof. J.L. Massey at the Swiss Federal
Institute of Technology. There exist four versions of this
algorithm, namely: SAFER K-64 , SAFER K-128 , SAFER SK-64
and SAFER SK-128. The numerals 64 and 128 stand for the
length of the user-selected key, 'K' stands for the original
key schedule and 'SK' stands for the strengthened key
schedule (in which some of the "weaknesses" of the original
key schedule have been removed). In mcrypt only SAFER SK-64
and SAFER SK-128 are used.
SAFER+: SAFER+ was designed by Prof. J.L. Massey, Prof. Gur-
gen H. Khachatrian and Dr. Melsik K. Kuregian for Cylink.
SAFER+ is based on the existing SAFER family of ciphers and
provides for a block size of 128bits and 128, 192 and 256
bits key length.
A short description of the modes supported by libmcrypt:
STREAM: The mode used with stream ciphers. In this mode the
keystream from the cipher is xor'ed with the plaintext. Thus
you should NOT ever use the same key.
ECB: The Electronic CodeBook mode. It is the simplest mode
to use with a block cipher. Encrypts each block indepen-
dently. It is a block mode so plaintext length should be a
multiple of blocksize (n*blocksize).
CBC: The Cipher Block Chaining mode. It is better than ECB
since the plaintext is XOR'ed with the previous ciphertext.
A random block should be placed as the first block (IV) so
the same block or messages always encrypt to something dif-
ferent. It is a block mode so plaintext length should be a
multiple of blocksize (n*blocksize).
CFB: The Cipher-Feedback Mode (in 8bit). This is a self-
synchronizing stream cipher implemented from a block cipher.
This is the best mode to use for encrypting strings or
streams. This mode requires an IV.
OFB: The Output-Feedback Mode (in 8bit). This is a synchro-
nous stream cipher implemented from a block cipher. It is
intended for use in noisy lines, because corrupted cipher-
text blocks do not corrupt the plaintext blocks that follow.
Insecure (because used in 8bit mode) so it is recommended
not to use it. Added just for completeness.
nOFB: The Output-Feedback Mode (in nbit). n Is the size of
the block of the algorithm. This is a synchronous stream
cipher implemented from a block cipher. It is intended for
use in noisy lines, because corrupted ciphertext blocks do
not corrupt the plaintext blocks that follow. This mode
operates in n bit blocks.
nCFB: The Cipher-Feedback Mode (in nbit). n Is the size of
the block of the algorithm. This is a self synchronizing
stream cipher implemented from a block cipher. This mode
operates in n bit blocks.
Error Recovery in these modes: If bytes are removed or lost
from the file or stream in ECB, CBC and OFB modes, are
impossible to recover, although CFB and nCFB modes will
recover. If some bytes are altered then a full block of
plaintext is affected in ECB mode, two blocks in CBC, nCFB
and CFB modes, but only the corresponding byte in OFB mode.
Encryption can be done as follows:
A call to function: MCRYPT mcrypt_module_open( char *algo-
rithm, char* algorithm_directory, char*
mode, char* mode_directory);
This function opens the module of the algorithm and the mode
to be used. The name of the algorithm is specified in algo-
rithm, eg "twofish", and the algorithm_directory is the
directory where the algorithm is (it may be null if it is
the default). The same applies for the mode. The library is
closed by calling mcrypt_module_close(), but you should not
call that function if mcrypt_generic_end() is called before.
Normally it returns an encryption descriptor, or
MCRYPT_FAILED on error.
A call to function: int mcrypt_generic_init( MCRYPT td,
void *key, int lenofkey, void *IV);
This function initializes all buffers for the specified
thread The maximum value of lenofkey should be the one
obtained by calling mcrypt_get_key_size() and every value
smaller than this is legal. Note that Lenofkey should be
specified in bytes not bits. The IV should normally have
the size of the algorithms block size, but you must obtain
the size by calling mcrypt_get_iv_size(). IV is ignored in
ECB. IV MUST exist in CFB, CBC, STREAM, nOFB and OFB modes.
It needs to be random and unique (but not secret). The same
IV must be used for encryption/decryption. If you do not
want to use it you should set it to zeros, or NULL, but this
is not recommended. After calling this function you can use
the descriptor for encryption or decryption (not both).
Returns a negative value on error.
To encrypt now call:
int mcrypt_generic( MCRYPT td, void *plaintext,
This is the main encryption function. td is the encryption
descriptor returned by mcrypt_generic_init(). Plaintext is
the plaintext you wish to encrypt and len should be the
length (in bytes) of the plaintext and it should be
k*algorithms_block_size if used in a mode which operated in
blocks (cbc, ecb, nofb), or whatever when used in cfb or ofb
which operate in streams. The plaintext is replaced by the
ciphertext. Returns 0 on success.
To decrypt you can call:
int mdecrypt_generic( MCRYPT td, void *ciphertext,
The decryption function. It is almost the same with
mcrypt_generic. Returns 0 on success.
When you're finished you should call:
int mcrypt_generic_end( MCRYPT td);
This function terminates encryption specified by the encryp-
tion descriptor (td). Actually it clears all buffers, and
closes all the modules used. Returns a negative value on
error. This function is deprecated. Use
mcrypt_generic_deinit() and mcrypt_module_close() instead.
int mcrypt_generic_deinit( MCRYPT td);
This function terminates encryption specified by the encryp-
tion descriptor (td). Actually it clears all buffers. The
difference with mcrypt_generic_end() is that this function
does not close the modules used. Thus you should use
mcrypt_module_close(). Using this function you gain in
speed if you use the same modules for several encryptions.
Returns a negative value on error.
int mcrypt_module_close( MCRYPT td);
This function closes the modules used by the descriptor td.
These are some extra functions that operate on modules that
have been opened: These functions have the prefix
mcrypt_enc_*.
int mcrypt_enc_set_state(MCRYPT td, void *iv, int This func-
tion sets the state (actually IV) of the algorithm. Can be
used only with block algorithms. It is usefully if you want
to restart or start a different encryption quickly. Returns
zero on success.
int mcrypt_enc_self_test( MCRYPT td);
This function runs the self test on the algorithm specified
by the descriptor td. If the self test succeeds it returns
zero.
int mcrypt_enc_is_block_algorithm_mode( MCRYPT td);
Returns 1 if the mode is for use with block algorithms, oth-
erwise it returns 0. (eg. 0 for stream, and 1 for cbc, cfb,
ofb)
int mcrypt_enc_is_block_algorithm( MCRYPT td);
Returns 1 if the algorithm is a block algorithm or 0 if it
is a stream algorithm.
int mcrypt_enc_is_block_mode( MCRYPT td);
Returns 1 if the mode outputs blocks of bytes or 0 if it
outputs bytes. (eg. 1 for cbc and ecb, and 0 for cfb and
stream)
int mcrypt_enc_get_block_size( MCRYPT td);
Returns the block size of the algorithm specified by the
encryption descriptor in bytes. The algorithm MUST be opened
using mcrypt_module_open().
int mcrypt_enc_get_key_size( MCRYPT td);
Returns the maximum supported key size of the algorithm
specified by the encryption descriptor in bytes. The algo-
rithm MUST be opened using mcrypt_module_open().
int* mcrypt_enc_get_supported_key_sizes( MCRYPT td, int*
sizes)
Returns the key sizes supported by the algorithm specified
by the encryption descriptor. If sizes is zero and returns
NULL then all key sizes between 1 and mcrypt_get_key_size()
are supported by the algorithm. If it is 1 then only the
mcrypt_get_key_size() size is supported and sizes[0] is
equal to it. If it is greater than 1 then that number speci-
fies the number of elements in sizes which are the key sizes
that the algorithm supports. The retured value is allocated
with malloc, so you should not forget to free it.
int mcrypt_enc_get_iv_size( MCRYPT td);
Returns size of the IV of the algorithm specified by the
encryption descriptor in bytes. The algorithm MUST be opened
using mcrypt_module_open(). If it is '0' then the IV is
ignored in that algorithm. IV is used in CBC, CFB, OFB
modes, and in some algorithms in STREAM mode.
char* mcrypt_enc_get_algorithms_name( MCRYPT td);
Returns a character array containing the name of the algo-
rithm. The retured value is allocated with malloc, so you
should not forget to free it.
char* mcrypt_enc_get_modes_name( MCRYPT td);
Returns a character array containing the name of the mode.
The retured value is allocated with malloc, so you should
not forget to free it.
These are some extra functions that operate on modules:
These functions have the prefix mcrypt_module_*.
int mcrypt_module_self_test (char* algorithm, char* direc-
tory);
This function runs the self test on the specified algorithm.
If the self test succeeds it returns zero.
int mcrypt_module_is_block_algorithm_mode( char* algorithm,
char* directory);
Returns 1 if the mode is for use with block algorithms, oth-
erwise it returns 0. (eg. 0 for stream, and 1 for cbc, cfb,
ofb)
int mcrypt_module_is_block_algorithm( char* mode, char*
directory);
Returns 1 if the algorithm is a block algorithm or 0 if it
is a stream algorithm.
int mcrypt_module_is_block_mode( char* mode, char* direc-
tory);
Returns 1 if the mode outputs blocks of bytes or 0 if it
outputs bytes. (eg. 1 for cbc and ecb, and 0 for cfb and
stream)
int mcrypt_module_get_algo_block_size( char* algorithm,
char* directory);
Returns the block size of the algorithm.
int mcrypt_module_get_algo_key_size( char* algorithm, char*
directory);
Returns the maximum supported key size of the algorithm.
int* mcrypt_module_get_algo_supported_key_sizes( char* algo-
rithm, char* directory,
Returns the key sizes supported by the algorithm. If sizes
is zero and returns NULL then all key sizes between 1 and
mcrypt_get_key_size() are supported by the algorithm. If it
is 1 then only the mcrypt_get_key_size() size is supported
and sizes[0] is equal to it. If it is greater than 1 then
that number specifies the number of elements in sizes which
are the key sizes that the algorithm supports. This function
differs to mcrypt_enc_get_supported_key_sizes(), because the
return value here is allocated (not static), thus it should
be freed.
char** mcrypt_list_algorithms ( char* libdir, int*
Returns a pointer to a character array cointaining all the
mcrypt algorithms located in the libdir, or if it is NULL,
in the default directory. The size is the number of the
character arrays. The arrays are allocated internally and
should be freed by using mcrypt_free_p().
char** mcrypt_list_modes ( char* libdir, int
Returns a pointer to a character array cointaining all the
mcrypt modes located in the libdir, or if it is NULL, in the
default directory. The size is the number of the character
arrays. The arrays should be freed by using
mcrypt_free_p().
void mcrypt_free_p (char **p, int size);
Frees the pointer to array returned by previous functions.
void mcrypt_free (void *ptr);
Frees the memory used by the pointer.
void mcrypt_perror(int err);
This function prints a human readable description of the
error 'err' in the stderr. The err should be a value
returned by mcrypt_generic_init().
const char* mcrypt_strerror(int err);
This function returns a human readable description of the
error 'err'. The err should be a value returned by
mcrypt_generic_init().
int mcrypt_mutex_register ( void (*mutex_lock)(void) ,
This function is only used in multithreaded application.
This is actually used internally in libltdl. Except for the
dynamic module loading libmcrypt is thread safe.
Some example programs follow here. Compile as "cc prog.c
-lmcrypt -lltdl", or "cc prog.c -lmcrypt -ldl" depending on
your installation. Libltdl is used for opening dynamic
libraries (modules).
/* First example: Encrypts stdin to stdout using TWOFISH with 128 bit key and CFB */
#include <mcrypt.h>
#include <stdio.h>
#include <stdlib.h>
/* #include <mhash.h> */
main() {
MCRYPT td;
int i;
char *key;
char password[20];
char block_buffer;
char *IV;
int keysize=16; /* 128 bits */
key=calloc(1, keysize);
strcpy(password, "A_large_key");
/* Generate the key using the password */
/* mhash_keygen( KEYGEN_MCRYPT, MHASH_MD5, key, keysize, NULL, 0, password, strlen(password));
*/
memmove( key, password, strlen(password));
td = mcrypt_module_open("twofish", NULL, "cfb", NULL);
if (td==MCRYPT_FAILED) {
return 1;
}
IV = malloc(mcrypt_enc_get_iv_size(td));
/* Put random data in IV. Note these are not real random data,
* consider using /dev/random or /dev/urandom.
*/
/* srand(time(0)); */
for (i=0; i< mcrypt_enc_get_iv_size( td); i++) {
IV[i]=rand();
}
i=mcrypt_generic_init( td, key, keysize, IV);
if (i<0) {
mcrypt_perror(i);
return 1;
}
/* Encryption in CFB is performed in bytes */
while ( fread (&block_buffer, 1, 1, stdin) == 1 ) {
mcrypt_generic (td, &block_buffer, 1);
/* Comment above and uncomment this to decrypt */
/* mdecrypt_generic (td, &block_buffer, 1); */
fwrite ( &block_buffer, 1, 1, stdout);
}
/* Deinit the encryption thread, and unload the module */
mcrypt_generic_end(td);
return 0;
}
/* Second Example: encrypts using CBC and SAFER+ with 192 bits key */
#include <mcrypt.h>
#include <stdio.h>
#include <stdlib.h>
main() {
MCRYPT td;
int i;
char *key; /* created using mcrypt_gen_key */
char *block_buffer;
char *IV;
int blocksize;
int keysize = 24; /* 192 bits == 24 bytes */
key = calloc(1, keysize);
strcpy(key, "A_large_and_random_key");
td = mcrypt_module_open("saferplus", NULL, "cbc", NULL);
blocksize = mcrypt_get_block_size(td);
block_buffer = malloc(blocksize);
/* but unfortunately this does not fill all the key so the rest bytes are
* padded with zeros. Try to use large keys or convert them with mcrypt_gen_key().
*/
IV=malloc(mcrypt_enc_get_iv_size(td));
/* Put random data in IV. Note these are not real random data,
* consider using /dev/random or /dev/urandom.
*/
/* srand(time(0)); */
for (i=0; i < mcrypt_enc_get_iv_size(td); i++) {
IV[i]=rand();
}
mcrypt_generic_init ( td key, keysize, IV);
/* Encryption in CBC is performed in blocks */
while ( fread (block_buffer, 1, blocksize, stdin) == blocksize ) {
mcrypt_generic (td, block_buffer, blocksize);
/* mdecrypt_generic (td, block_buffer, blocksize); */
fwrite ( block_buffer, 1, blocksize, stdout);
}
/* deinitialize the encryption thread */
mcrypt_generic_deinit (td);
/* Unload the loaded module */
mcrypt_module_close(td);
return 0;
}
The library does not install any signal handler.
Questions about libmcrypt should be sent to:
mcrypt-dev@lists.hellug.gr or, if this fails, to the
author addresses given below. The mcrypt home page is:
http://mcrypt.hellug.gr
AUTHORS
Version 2.4 Copyright (C) 1998-1999 Nikos Mavroyanopoulos
(nmav@hellug.gr).
Thanks to all the people who reported problems and suggested
various improvements for mcrypt; who are too numerous to
cite here.
Man(1) output converted with
man2html