MCRYPT(3)
MCRYPT(3) π
so like. bestie. this is the MCRYPT(3) page from the Library Functions Manual, and it is LONG, so buckle up π«Ά
β¨ NAME β¨
libmcrypt β encryption/decryption library π
πΈ SYNOPSIS πΈ
[see also mcrypt.h for more information]
π¦ DESCRIPTION π¦
okay so libmcrypt is a data encryption library. she is thread safe and she gives you encryption AND decryption functions, both. this version supports a whole slew of encryption algorithms and encryption modes. some of the algorithms she supports: SERPENT, RIJNDAEL, 3DES, GOST, SAFER+, CAST-256, RC2, XTEA, 3WAY, TWOFISH, BLOWFISH, ARCFOUR, WAKE and more. yes more. she's like that π
OFB, CBC, ECB, nOFB, nCFB and CFB are the modes that all algorithms may function in. ECB, CBC encrypt in blocks but CTR, nCFB, nOFB, CFB and OFB work in bytes (streams). note that everywhere else in this document, CFB and OFB mean the "8bit CFB or OFB" mode. nOFB and nCFB modes represent an n-bit OFB/CFB mode, where n stands for the algorithm's block size. the library also supports an extra STREAM mode so it can include some stream algorithms like WAKE or ARCFOUR. π
in this version of the library all modes and algorithms are modular, which means the algorithm and the mode get loaded at run-time. the way that lets you add algorithms and modes faster, and way easier. periodt β¨
π the symmetric (block) algorithms, one by one π
LibMcrypt includes the following symmetric (block) algorithms:
DESβ the traditional DES algorithm, designed by IBM and US NSA. uses a 56 bit key and a 64 bit block. it is now considered a weak algorithm, because of its small key size (it was never intended for use with classified data). π3DESor Triple DES β DES but with multiple (triple) encryption. 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 calledCAST5) which has a 128bit key and 64bit block size. πCAST-256β 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 arbitrary 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β 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 Whiting, 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β 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 strengthened 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 theRFC2268. π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 a compatible cipher namedARCFOURis 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 provided only as an extra module to libmcrypt. β οΈRIJNDAELβ Rijndael is a block cipher, designed by Joan Daemen and Vincent Rijmen, and was approved for the USA's NIST Advanced Encryption Standard,FIPS-197. the cipher has a variable block length and key length. Rijndael 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 space. β‘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 Algorithm 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 cryptanalyst. 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 Cryptography book by Bruce Schneier. they were used in an application 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 questionable. - This code is based on the 25 November 1993 draft translation by Aleksandr Malchik, with Whitfield Diffie, of the Government Standard of the U.S.S.R. GOST 28149-89, "Cryptographic 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 Wollongong, 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-64andSAFER 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 onlySAFER SK-64andSAFER SK-128are used. π‘οΈSAFER+β designed by Prof. J.L. Massey, Prof. Gurgen 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 XORed with the plaintext. so 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 independently. 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 different. 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 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. 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 streams. π
ok bestie, we were literally just talking about modes, so let's keep it going π
nCFBβ the Cipher-Feedback Mode, but in n bits. That n is the size of the block of the algorithm. It's a self-synchronizing stream cipher built out of a block cipher, and it operates in streams. π¦CTRβ the Counter Mode. Also a stream cipher made from a block cipher. It takes the cipher and uses it to encrypt a bunch of input blocks called counters, and those blocks get XORed with the plaintext. In libmcrypt the counter is literally the IV you gave it, and it gets incremented at every single step. Operates in streams too. β¨
π Error Recovery, aka the part where things go wrong
ok so listen carefully because this one matters:
If bytes get removed or lost from the file or stream inECB,CTR,CBCandOFBmodes, recovering them is impossible.CFBandnCFBwill recover though β slay for them I guess. π
And if some bytes get altered, here's the damage report:
- a full block of plaintext is affected in
ECB,nOFBandCTRmodes - two blocks in
CBC,nCFBandCFBmodes - but only the corresponding byte in
OFBmode
π₯ How to actually encrypt, step by step
First you open a module. A call to this function:
MCRYPT mcrypt_module_open( char *algorithm, char* algorithm_directory, char* mode, char* mode_directory);
This one associates the algorithm and the mode you specified, bestie. The name of the algorithm goes in algorithm, e.g. "twofish", and algorithm_directory is the directory where that algorithm lives (it can be null if you're chill with the default). Same deal for the mode. πΈ
The library gets closed by calling mcrypt_module_close(), but do NOT call that if mcrypt_generic_end() was called before. Normally it returns an encryption descriptor, or MCRYPT_FAILED on error. π«Ά
Then a call to:
int mcrypt_generic_init( MCRYPT td, void *key, int lenofkey, void *IV);
This initializes all the buffers for the specified thread. The maximum value of lenofkey should be the one you got from calling mcrypt_get_key_size(), and every value smaller than that is legal. π
Note that lenofkey should be specified in bytes, not bits. Not me stressing this. BYTES. π
The IV should normally have the size of the algorithm's block size, but you must obtain that size by calling mcrypt_get_iv_size(). The IV is ignored in ECB. The IV MUST exist in CFB, CBC, STREAM, nOFB and OFB modes. It needs to be random and unique (but not secret, iykyk). The same IV must be used for encryption/decryption, fr fr. 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, int len);
This is the main encryption function, the icon, the main character. 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 operates 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, int len);
The decryption function. It is almost the same as 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 encryption descriptor (td). Actually it clears all the buffers and closes all the modules used. Returns a negative value on error.
This function is deprecated. Usemcrypt_generic_deinit()andmcrypt_module_close()instead. periodt. π
int mcrypt_generic_deinit( MCRYPT td);
This function terminates encryption specified by the encryption descriptor (td). Actually it clears all the buffers. The difference with mcrypt_generic_end() is that this function does not close the modules used. So 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. bye bestie π
π§ Extra functions on modules that have been opened
These ones have the prefix mcrypt_enc_* β¨
int mcrypt_enc_set_state(MCRYPT td, void *state, int size);β sets the state of the algorithm. Can be used only with block algorithms and certain modes likeCBC,CFBetc. It's useful if you want to restart or start a different encryption quickly. Returns zero on success. The state is the output ofmcrypt_enc_get_state(). π«int mcrypt_enc_get_state(MCRYPT td, void *state, int *size);β returns the state of the algorithm. Can be used only with certain modes and algorithms. The size will hold the size of the state, and the state must have enough bytes to hold it. Returns zero on success.int mcrypt_enc_self_test( MCRYPT td);β 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);β returns1if the mode is for use with block algorithms, otherwise it returns0. (e.g.0for stream, and1forcbc,cfb,ofb)int mcrypt_enc_is_block_algorithm( MCRYPT td);β returns1if the algorithm is a block algorithm, or0if it's a stream algorithm.int mcrypt_enc_is_block_mode( MCRYPT td);β returns1if the mode outputs blocks of bytes, or0if it outputs bytes. (e.g.1forcbcandecb, and0forcfbandstream)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 usingmcrypt_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 algorithm MUST be opened usingmcrypt_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 it returnsNULLthen all key sizes between1andmcrypt_get_key_size()are supported by the algorithm. If it is1then only themcrypt_get_key_size()size is supported andsizes[0]is equal to it. If it is greater than1then that number specifies the number of elements in sizes, which are the key sizes that the algorithm supports.
The returned value is allocated with malloc, so do not forget to free it. bestie. the way that memory leaks are NOT the vibe π
int mcrypt_enc_get_iv_size( MCRYPT td);β returns the size of the IV of the algorithm specified by the encryption descriptor, in bytes. The algorithm MUST be opened usingmcrypt_module_open(). If it's'0'then the IV is ignored in that algorithm. IV is used inCBC,CFB,OFBmodes, and in some algorithms inSTREAMmode.int mcrypt_enc_mode_has_iv( MCRYPT td);β returns1if the mode needs an IV,0otherwise. Some'stream'algorithms may need an IV even if the mode itself does not need an IV. πchar* mcrypt_enc_get_algorithms_name( MCRYPT td);β returns a character array containing the name of the algorithm. The returned value is allocated withmalloc, 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 returned value is allocated withmalloc, so you should not forget to free it.
π Extra functions on modules
These ones carry the prefix mcrypt_module_* β
int mcrypt_module_self_test (char* algorithm, char* directory);β 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);β returns1if the mode is for use with block algorithms, otherwise it returns0. (e.g.0for stream, and1forcbc,cfb,ofb)int mcrypt_module_is_block_algorithm( char* mode, char* directory);β returns1if the algorithm is a block algorithm, or0if it is a stream algorithm.int mcrypt_module_is_block_mode( char* mode, char* directory);β returns1if the mode outputs blocks of bytes, or0if it outputs bytes. (e.g.1forcbcandecb, and0forcfbandstream)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* algorithm, char* directory, int* sizes);β returns the key sizes supported by the algorithm. If sizes is zero and returnsNULLthen all key sizes between1andmcrypt_get_key_size()are supported by the algorithm. If it is1then only themcrypt_get_key_size()size is supported andsizes[0]is equal to it. If it is greater than1then that number specifies the number of elements in sizes, which are the key sizes that the algorithm supports.
This function differs from mcrypt_enc_get_supported_key_sizes(), because the return value here is allocated (not static), so it should be freed. π₯
char** mcrypt_list_algorithms ( char* libdir, int* size);β returns a pointer to a character array containing all the mcrypt algorithms located in the libdir, or if it isNULL, in the default directory. The size is the number of the character arrays. The arrays are allocated internally and should be freed by usingmcrypt_free_p(). π¦char** mcrypt_list_modes ( char* libdir, int *size);β returns a pointer to a character array containing all the mcrypt modes located in the libdir, or if it isNULL, in the default directory. The size is the number of the character arrays. The arrays should be freed by usingmcrypt_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);β prints a human readable description of the error'err'in thestderr. The err should be a value returned bymcrypt_generic_init(). π£οΈconst char* mcrypt_strerror(int err);β returns a human readable description of the error'err'. The err should be a value returned bymcrypt_generic_init().int mcrypt_mutex_register ( void (*mutex_lock)(void) , void (*mutex_unlock)(void) );β this function is only used in multithreaded applications, and only if compiled with dynamic module loading support. This is actually used internally in libltdl. Except for the dynamic module loading, libmcrypt is thread safe. π«Ά
π The example programs
Some example programs follow here, bestie. Compile as cc prog.c -lmcrypt, or cc prog.c -lmcrypt -lltdl 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 */
so anyway, bestie, the fastest way to actually get this library is to read the code, so here's the whole first example, verbatim, no edits, copy it into a file and vibe:
#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;
}
okay let's unpack this icon behavior β¨ it opens the twofish cipher in cfb mode with mcrypt_module_open("twofish", NULL, "cfb", NULL), and if that comes back as MCRYPT_FAILED it just bounces out with return 1. it grabs an IV sized by mcrypt_enc_get_iv_size(td), and then fills it with rand() β and bestie, the manpage literally says these are not real random data, so consider using /dev/random or /dev/urandom instead, that's the note in the code and it's not a joke π it calls mcrypt_generic_init( td, key, keysize, IV), and if that returns anything less than 0 it prints with mcrypt_perror(i) and bails. the key here is 16 bytes, which is 128 bits, and the "key" is literally the string "A_large_key" memmove'd in β the mhash_keygen( KEYGEN_MCRYPT, MHASH_MD5, key, keysize, NULL, 0, password, strlen(password)); line is commented out, so if you want the fancy keygen, uncomment it yourself, iykyk.
then the encryption loop! and this is the part that matters: in CFB, encryption is performed in bytes, so it reads one byte at a time with fread (&block_buffer, 1, 1, stdin), calls mcrypt_generic (td, &block_buffer, 1), and writes it back out. to decrypt you comment out the mcrypt_generic and uncomment mdecrypt_generic (td, &block_buffer, 1); β the comments in the code say exactly that. and when it's all done it calls mcrypt_generic_end(td) to deinit the encryption thread and unload the module. π
okay, second example, and this one's giving grown crypto β CBC mode with SAFER+ and a 192-bit key:
/* 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_enc_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;
}
so here keysize = 24, because 192 bits == 24 bytes, and the key string is "A_large_and_random_key" β but the comment is loud about it: unfortunately this does not fill all the key so the rest bytes are padded with zeros, so try to use large keys or convert them with mcrypt_gen_key(). and yeah, the key declaration comment even says created using mcrypt_gen_key β manifesting, honestly. π
the IV situation is the same deal, rand()-filled, again not real random data, again consider /dev/random or /dev/urandom. it opens "saferplus" in "cbc" mode, sizes the buffer with mcrypt_enc_get_block_size(td) and malloc(blocksize).
and here's the glow-up: in CBC, encryption is performed in blocks, so it reads blocksize bytes at a time (fread (block_buffer, 1, blocksize, stdin) == blocksize), calls mcrypt_generic (td, block_buffer, blocksize), and writes blocksize back out. swap in mdecrypt_generic (td, block_buffer, blocksize); to go the other way. then it wraps up with mcrypt_generic_deinit (td) to deinitialize the encryption thread and mcrypt_module_close(td) to unload the loaded module. not me noticing this one does not call mcrypt_generic_init error-checking β the first example does, this one just sends it. π
β οΈ okay important: the library does not install any signal handler. so that's on you, bestie, plan accordingly.
π questions, complaints, fan mail
got questions about libmcrypt? send them to:
mcrypt-dev@lists.hellug.gr
or, if that 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).
and a huge thank you to all the people who reported problems and suggested various improvements for mcrypt; who are too numerous to cite here. y'all ate, fr fr. π«Ά
and that's the whole page, bestie! this one's dated 10 March 2002 and it's the MCRYPT(3) manual, from Version 2.4 β so go forth, encrypt responsibly, use real random data, and remember: signal handlers don't install themselves. mwah ππΈβ¨
π¦ where this page comes from
- alpine 3.24: libmcrypt-doc 2.5.8-r11 Β· LGPL-2.1-or-later
- arch rolling: libmcrypt 2.5.8-7 Β· LGPL-2.0-or-later
- epel 9: libmcrypt 2.5.8-30.el9 Β· LGPLv2+
- fedora 43: libmcrypt 2.5.8-42.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 43: libmcrypt 2.5.8-42.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 44: libmcrypt 2.5.8-43.fc44 Β· LicenseRef-Callaway-LGPLv2+
- fedora 44: libmcrypt 2.5.8-43.fc44 Β· LicenseRef-Callaway-LGPLv2+
- nixos 26.05: libmcrypt 2.5.8
- nixpkgs unstable: libmcrypt 2.5.8
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms