des_ecb3_encrypt() -- SSLeay 0.9.0b -- January 1999

NAME

des_encrypt3, des_decrypt3, des_ecb3_encrypt, des_3cbc_encrypt,
des_ede3_cbc_encrypt, des_ede3_cfb64_encrypt,
des_ede3_ofb64_encrypt -- triple-DES encryption

SYNOPSIS

#include "des.h"

void des_encrypt3(data,ks1,ks2,ks3)
DES_LONG *data;
des_key_schedule ks1, ks2, ks3;

void des_decrypt3(data,ks1,ks2,ks3)
DES_LONG *data;
des_key_schedule ks1, ks2, ks3;

void des_ecb3_encrypt(input,output,ks1,ks2,ks3,enc)
des_cblock *input, *output;
des_key_schedule ks1, ks2, ks3;
int enc;

void des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,enc)
des_cblock *input, *output, *ivec1, *ivec2;
long length;
des_key_schedule sk1, sk2;
int enc;

void des_ede3_cbc_encrypt(inout,output,length,ks1,ks2,ks3,ivec,enc)
des_cblock *input, *output, *ivec;
long length;
des_key_schedule ks1, ks2, ks3;
int enc;

void des_ede3_cfb64_encrypt(in,out,length,ks1,ks2,ks3,ivec,num,enc)
unsigned char *in, *out;
long length;
des_key_schedule ks1, ks2, ks3;
des_cblock *ivec;
int *num, enc;

void des_ede3_ofb64_encrypt(in,out,length,ks1,ks2,ks3,ivec,num)
unsigned char *in, *out;
long length;
des_key_schedule ks1, ks2, ks3;
des_cblock *ivec;
int *num;

DESCRIPTION

In any function prototype which has arguments input and output, the same variable can be passed for both arguments.

des_encrypt3() and des_decrypt3 are the basic building blocks used by all of the other DES encryption routines. They should be used only to implement a DES mode that the library doesn't already supply.

des_encrypt3 and des_decrypt operate on data which is a pointer to two DES_LONGs (at least 4 characters per element, maybe more depending on how large a long is on your machine, but in that case, the extra bytes are treated as padding). In order to make this work right, each function implementing a DES mode does conversion of the input block, essentially a string of characters, to an array of DES_LONGs before invoking des_encrypt3 or des_decrypt3. After the encryption the function does the reverse conversion. Here's an example (from ecb3_enc.c):

void des_ecb3_encrypt(input, output, ks1, ks2, ks3, encrypt)
des_cblock (*input);
des_cblock (*output);
des_key_schedule ks1;
des_key_schedule ks2;
des_key_schedule ks3;
int encrypt;
        {
        register DES_LONG l0,l1;
        register unsigned char *in,*out;
        DES_LONG ll[2];

        in=(unsigned char *)input;
        out=(unsigned char *)output;
        c2l(in,l0);
        c2l(in,l1);
        ll[0]=l0;
        ll[1]=l1;
        if (encrypt)
                des_encrypt3(ll,ks1,ks2,ks3);
        else
                des_decrypt3(ll,ks1,ks2,ks3);
        l0=ll[0];
        l1=ll[1];
        l2c(l0,out);
        l2c(l1,out);
        }

ks1, ks2 and ks3 are previously-initialized des_key_schedules.

des_ecb3_encrypt() is the 3 key EDE mode of ECB DES. What this means is that the 8 bytes of input are encrypted with ks1, decrypted with ks2 and then encrypted again with ks3, before being put into output; C=E(ks3,D(ks2,E(ks1,M))).

The des_cblock pointed to by input is encrypted into the block pointed to by output (which may be the same as input).

ks1, ks2 and ks3 are previously-initialized des_key_schedule's.

encrypt takes either the value DES_ENCRYPT, in which case encryption is performed, or DES_DECRYPT, in which case decryption is performed.

A macro, des_ecb2_encrypt(), is supplied, that only takes 2 des_key_schedules, reusing ks1 for the final encrypt, C=E(ks1,D(ks2,E(ks1,M))):

#define des_ecb2_encrypt(i,o,k1,k2,e) \
        des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))

des_3cbc_encrypt() should not be used; it is buggy in some circumstances. This routine implements outer triple cbc encryption using 2 key schedules and 2 ivec's. Use des_ede2_cbc_encrypt() instead.

des_ede3_cbc_encrypt() implements inner triple CBC DES encryption with 3 keys. What this means is that each 'DES' operation inside the cbc mode is really a C=E(ks3,D(ks2,E(ks1,M))).

The des_cblock pointed to by input is encrypted into the block pointed to by output (which may be the same as input).

Length should contain the number of des_cblocks * 8 (i.e. the total length of the input).

If length is not a multiple of 8, the results are unpredictable.

ks1, ks2 and ks3 are previously-initialized des_key_schedules.

encrypt takes either the value DES_ENCRYPT, in which case encryption is performed, or DES_DECRYPT, in which case decryption is performed.

ivec is used to hold the output cipher text before calling the function again, if you are encrypting a text in several separate calls. This output is typically used in some way to modify the algorithm so that, if you use one of the chaining or feedback modes, encryption of the same block of text does not always give the same output (but encryption of the same block of text, with the same ivec in place, will typically give the same output).

See DES encryption modes overview for a discussion of the various modes.

For more details about the modes, see FIPS Pub 81: DES Modes of Operation; this is the updated version from May of 1996.

ivec must be initialized to some known (but randomly generated) state before calling this function on the first chunk of data (and when you decrypt the data, the same initialization needs to be used for the first decryption call).

This mode is used by SSL. A macro, des_ede2_cbc_encrypt(), is supplied, that only takes 2 des_key_schedules, reusing ks1 for the final encrypt, C=E(ks1,D(ks2,E(ks1,M))):

#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))

This form of triple-DES is used by the RSAref library.

des_ede3_cfb64_encrypt() implements inner triple CFB DES encryption with 3 keys. What this means is that each 'DES' operation inside the cfb mode is really a C=E(ks3,D(ks2,E(ks1,M))).

This function uses the Cipher Feedback mode of DES. This implementation 'feeds back' in 64 bit blocks. The input in) and the output out is in multiples of 8 bytes. length is the number of bytes in in, which should be a multiple of 8.

The num argument is updated to show how many bytes of the ivec have been used; one step in the algorithm includes the xor of a byte of the plaintext with a byte of the (encrypted) ivec, so that all 8 bytes of the ivec are used in turn for an input block of 8 bytes. As each byte of the ivec is used, a new byte is created by the algorithm and stuffed into the ivec in place of the used byte. The following byte would be used next, and so on. num can be thought of as a pointer into the ivec to show which byte to start xor-ing with, the next time the function is called.

ivec is used to keep intermediate results for subsequent calls, and as input to the function the first time it is called on a text.

It should be initialized to a known (but randomly generated) state before this function is called on the first part of a piece of data.

ks1, ks2 and ks3 are previously-initialized des_key_schedule's.

enc takes either the value DES_ENCRYPT, in which case encryption is performed, or DES_DECRYPT, in which case decryption is performed.

A macro, des_ede2_cfb64_encrypt(), is supplied, that only takes 2 des_key_schedules, reusing ks1 for the final encrypt, C=E(ks1,D(ks2,E(ks1,M))):

#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))

des_ede3_ofb64_encrypt() implements inner triple OFB DES encryption with 3 keys. What this means is that each 'DES' operation inside the ofb mode is really a C=E(ks3,D(ks2,E(ks1,M))).

This function implements the Output Feedback Mode of DES, with 64 bit feedback. Its arguments are the same as those of des_ede3_cfb64_encrypt(), except that there is no enc argument; encryption and decryption use the same arguments.

A macro, des_ede2_ofb64_encrypt(), is supplied, that only takes 2 des_key_schedules, reusing ks1 for the final encrypt, C=E(ks1,D(ks2,E(ks1,M))):

#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))