Cryptography Reference
In-Depth Information
This works, but there's a problem with this routine, if you plan to use it in
a larger program. Every call starts over at the beginning of the key space. You
want to treat each call as if it was the next part of a very long string, which
means you need to keep track of the state of the algorithm. You can't just make
i , j , and S static variables. In addition to not being thread-safe, you need to keep
multiple RC4 contexts around. Instead, defi ne a structure to store the rc4 state
in, as shown in Listing 2-48.
Listing 2-48: “rc4.h” rc4_state structure
#define RC4_STATE_ARRAY_LEN 256
typedef struct
{
int i;
int j;
unsigned char S[ RC4_STATE_ARRAY_LEN ];
}
rc4_state;
Now, instead of initializing this on each invocation, let the caller pass in a
pointer to this structure. It is updated as rc4_operate completes, and the caller
can pass it back in to the next invocation to pick up where it left off, so that the
output looks like one, long, continuous stream of encrypted data.
The only remaining issue is when to do the initial key scheduling algorithm;
the one illustrated in Figure 2-15. This should be done one time, but never
again afterward. You can sort of “cheat,” here, as shown in Listing 2-49. The
rc4_operate algorithm checks the state parameter; if the S array starts with two
zeros — an impossible state — assume that the caller is passing in an uninitial-
ized rc4_state structure. Otherwise, it is accepted as provided.
Listing 2-49: “rc4.c” rc4_operate with persistent state
static void rc4_operate( const unsigned char *plaintext,
int plaintext_len,
unsigned char *ciphertext,
const unsigned char *key,
int key_len,
rc4_state *state )
{
int i, j;
unsigned char *S;
unsigned char tmp;
i = state->i;
j = state->j;
S = state->S;
// KSA (key scheduling algorithm)
Search WWH ::




Custom Search