[ Team LiB ] |
5.5 Using a Raw Block Cipher5.5.1 ProblemYou're trying to make one of our implementations for other block cipher modes work. They all use raw encryption operations as a foundation, and you would like to understand how to plug in third-party implementations. 5.5.2 SolutionRaw operations on block ciphers consist of three operations: key setup, encryption of a block, and decryption of a block. In other recipes, we provide three macros that you need to implement to use our code. In the discussion for this recipe, we'll look at several desirable bindings for these macros. 5.5.3 Discussion
Raw block ciphers operate on fixed-size chunks of data. That size is called the block size. The input and output are of this same fixed length. A block cipher also requires a key, which may be of a different length than the block size. Sometimes an algorithm will allow variable-length keys, but the block size is generally fixed. Setting up a block cipher generally involves turning the raw key into a key schedule. Basically, the key schedule is just a set of keys derived from the original key in a cipher-dependent manner. You need to create the key schedule only once; it's good for every use of the underlying key because raw encryption always gives the same result for any {key, input} pair (the same is true for decryption). Once you have a key schedule, you can generally pass it, along with an input block, into the cipher encryption function (or the decryption function) to get an output block. To keep the example code as simple as possible, we've written it assuming you are going to want to use one and only one cipher with it (though it's not so difficult to make the code work with multiple ciphers). To get the code in this book working, you need to define several macros:
In the following sections, we'll provide some bindings for these macros for Brian Gladman's AES implementation and for the OpenSSL API. Unfortunately, we cannot use Microsoft's CryptoAPI because it does not allow for exchanging symmetric encryption keys without encrypting them (see Recipe 5.26 and Recipe 5.27 to see how to work around this limitation)—and that would add significant complexity to what we're trying to achieve with this recipe. In addition, AES is only available in the .NET framework, which severely limits portability across various Windows versions. (The .NET framework is available only for Windows XP and Windows .NET Server 2003.) 5.5.3.1 Brian Gladman's AES implementationBrian Gladman has written the fastest freely available AES implementation to date. He has a version in x86 assembly that works with Windows and a portable C version that is faster than the assembly versions other people offer. It's available from his web page at http://fp.gladman.plus.com/AES/. To bind his implementation to our macros, do the following: #include "aes.h" #define SPC_BLOCK_SZ 16 typedef aes_ctx SPC_KEY_SCHED; #define SPC_ENCRYPT_INIT(sched, key, keybytes) aes_enc_key(key, keybytes, sched) #define SPC_DECRYPT_INIT(sched, key, keybytes) aes_dec_key(key, keybytes, sched) #define SPC_DO_ENCRYPT(sched, in, out) aes_enc_block(in, out, sched) #define SPC_DO_DECRYPT(sched, in, out) aes_dec_block(in, out, sched) 5.5.3.2 OpenSSL block cipher implementationsNext, we'll provide implementations for these macros for all of the ciphers in OpenSSL 0.9.7. Note that the block size for all of the algorithms listed in this section is 8 bytes, except for AES, which is 16. Table 5-2 lists the block ciphers that OpenSSL exports, along with the header file you need to include for each cipher and the associated type for the key schedule.
Table 5-3 provides implementations of the SPC_ENCRYPT_INIT macro for each of the block ciphers listed in Table 5-2.
In most of the implementations in Table 5-3, SPC_DECRYPT_INIT will be the same as SPC_ENCRYPT_INIT (you can define one to the other). The two exceptions are AES and IDEA. For AES: #define SPC_DECRYPT_INIT(sched, key, keybytes) \ AES_set_decrypt_key(key, keybytes * 8, sched) For IDEA: #define SPC_DECRYPT_INIT(sched, key, keybytes) { \ IDEA_KEY_SCHEDULE tmp;\ idea_set_encrypt_key(key, &tmp);\ idea_set_decrypt_key(&tmp, sched);\ } Table 5-4 and Table 5-5 provide implementations of the SPC_DO_ENCRYPT and SPC_DO_DECRYPT macros.
5.5.4 See Also
|
[ Team LiB ] |