Rijndael Encryption Algorithm
The Rijndael encryption algorithm has been designed to replace the aging DES algorithm. Like DES, it is a block cipher. It uses 128-bit, 192-bit or 256-bit keys. This implementation encrypts 128-bit blocks. (DES used 56-bit keys and 64-bit blocks.)
The code in this package is a modified version of an implementation placed in the public domain by the following persons:
The original code has been posted as rijndael.zip.
The modified code is easier to use than the original, and it compiles as either C or C++.
The modified code resides in the files rijndael.h and rijndael.c, which have been combined into the single file rijndael.txt. Download this file and then use a text editor to separate the two components. Then #include the file rijndael.h in any module that uses Rijndael encryption, and compile and link the file rijndael.c to the application.
To perform Rijndael encryption or decryption, first set up a buffer for encryption or decryption:
nrounds = rijndaelSetupEncrypt(rk, key, keybits); for encryption nrounds = rijndaelSetupDecrypt(rk, key, keybits); for decryption unsigned long *rk; pointer to encryption/decryption buffer, required space: keybits 32-bit words required 128 44 192 52 256 60 const unsigned char *key; key, where length in bytes is: keybits number of bytes 128 16 192 24 256 32 int keybits; number of bits in key, must be 128, 192 or 256 int nrounds; number of rounds: keybits nrounds 128 10 192 12 256 14
The package provides three macros to convert the keybits value to closely related values:
KEYLENGTH(keybits) number of bytes in key array RKLENGTH(keybits) number of 32-bit words in rk array NROUNDS(keybits) number of rounds
Encryption and decryption are performed, a block at a time, with the following two functions:
rijndaelEncrypt(rk, nrounds, plaintext, ciphertext); rijndaelDecrypt(rk, nrounds, ciphertext, plaintext); const unsigned long *rk; pointer to encryption/decryption buffer which was filled by rijndaelSetupEncrypt() or rijndaelSetupDecrypt() int nrounds; number of rounds, as computed by rijndaelSetupEncrypt(), rijndaelSetupDecrypt() or NROUNDS [const] unsigned char plaintext; [const] unsigned char ciphertext; pointers to 16-byte buffers to be encrypted or decrypted; the source buffer has a const qualifier
To satisfy the truly paranoid user, it is probably advisable to clear and delete the buffers after the process is finished.
In the file rijndael.c, a preprocessor macro FULL_UNROLL has been defined. This causes the compiler to generate inline code instead of loops in some places. This produces faster but larger code. You may want to remove this definition if you are programming for an environment that needs smaller but slower code.
The downloaded source code also includes a simple file encryption program and its corresponding decryption program.
The encryption program is called as follows:
encrypt password cryptofile
It encrypts the standard input (padding it with spaces, if necessary), and writes the result to the specified cryptofile.
The decryption program is called as follows:
decrypt password cryptofile
It decrypts the cryptofile contents and sends the result (padded with spaces, if necessary) to the standard output.
These programs should be used only for demonstration purposes, because the use of a password as a key gives an effective key length much shorter than the 256-bit key passed to the Rijndael encryption package.
The programs also have another shortcoming that some users may object to. They encrypt and decrypt each 128-bit block separately. If the plaintext contains identical 128-byte blocks, as many text files do, the blocks will be encrypted identically. This makes some of the plaintext structure visible in the ciphertext, even to someone who does not have the key. The usual practice is to combine each block after the first with the previous blocks (usually by some kind of XOR operation) before encrypting it. This hides repeated blocks very effectively, but it can wreak havoc if even one block of ciphertext is corrupted. The corrupted block AND ALL SUBSEQUENT BLOCKS will become unreadable.