The Cipher subroutines.

These routines require "evp.h" to be included.

These functions are a higher level interface to the various cipher
routines found in this library.  As such, they allow the same code to be
used to encrypt and decrypt via different ciphers with only a change
in an initial parameter.  These routines also provide buffering for block
ciphers.

These routines all take a pointer to the following structure to specify
which cipher to use.  If you wish to use a new cipher with these routines,
you would probably be best off looking an how an existing cipher is
implemented and copying it.  At this point in time, I'm not going to go
into many details.  This structure should be considered opaque

typedef struct pem_cipher_st
	{
	int type;
	int block_size;
	int key_len;
	int iv_len;
	void (*enc_init)();	/* init for encryption */
	void (*dec_init)();	/* init for decryption */
	void (*do_cipher)();	/* encrypt data */
	} EVP_CIPHER;
	
The type field is the object NID of the cipher type
(read the section on Objects for an explanation of what a NID is).
The cipher block_size is how many bytes need to be passed
to the cipher at a time.  Key_len is the
length of the key the cipher requires and iv_len is the length of the
initialisation vector required.  enc_init is the function
called to initialise the ciphers context for encryption and dec_init is the
function to initialise for decryption (they need to be different, especially
for the IDEA cipher).

One reason for specifying the Cipher via a pointer to a structure
is that if you only use des-cbc, only the des-cbc routines will
be included when you link the program.  If you passed an integer
that specified which cipher to use, the routine that mapped that
integer to a set of cipher functions would cause all the ciphers
to be link into the code.  This setup also allows new ciphers
to be added by the application (with some restrictions).

The thirteen ciphers currently defined in this library are

EVP_CIPHER *EVP_des_ecb();     /* DES in ecb mode,     iv=0, block=8, key= 8 */
EVP_CIPHER *EVP_des_ede();     /* DES in ecb ede mode, iv=0, block=8, key=16 */
EVP_CIPHER *EVP_des_ede3();    /* DES in ecb ede mode, iv=0, block=8, key=24 */
EVP_CIPHER *EVP_des_cfb();     /* DES in cfb mode,     iv=8, block=1, key= 8 */
EVP_CIPHER *EVP_des_ede_cfb(); /* DES in ede cfb mode, iv=8, block=1, key=16 */
EVP_CIPHER *EVP_des_ede3_cfb();/* DES in ede cfb mode, iv=8, block=1, key=24 */
EVP_CIPHER *EVP_des_ofb();     /* DES in ofb mode,     iv=8, block=1, key= 8 */
EVP_CIPHER *EVP_des_ede_ofb(); /* DES in ede ofb mode, iv=8, block=1, key=16 */
EVP_CIPHER *EVP_des_ede3_ofb();/* DES in ede ofb mode, iv=8, block=1, key=24 */
EVP_CIPHER *EVP_des_cbc();     /* DES in cbc mode,     iv=8, block=8, key= 8 */
EVP_CIPHER *EVP_des_ede_cbc(); /* DES in cbc ede mode, iv=8, block=8, key=16 */
EVP_CIPHER *EVP_des_ede3_cbc();/* DES in cbc ede mode, iv=8, block=8, key=24 */
EVP_CIPHER *EVP_desx_cbc();    /* DES in desx cbc mode,iv=8, block=8, key=24 */
EVP_CIPHER *EVP_rc4();         /* RC4,                 iv=0, block=1, key=16 */
EVP_CIPHER *EVP_idea_ecb();    /* IDEA in ecb mode,    iv=0, block=8, key=16 */
EVP_CIPHER *EVP_idea_cfb();    /* IDEA in cfb mode,    iv=8, block=1, key=16 */
EVP_CIPHER *EVP_idea_ofb();    /* IDEA in ofb mode,    iv=8, block=1, key=16 */
EVP_CIPHER *EVP_idea_cbc();    /* IDEA in cbc mode,    iv=8, block=8, key=16 */
EVP_CIPHER *EVP_rc2_ecb();     /* RC2 in ecb mode,     iv=0, block=8, key=16 */
EVP_CIPHER *EVP_rc2_cfb();     /* RC2 in cfb mode,     iv=8, block=1, key=16 */
EVP_CIPHER *EVP_rc2_ofb();     /* RC2 in ofb mode,     iv=8, block=1, key=16 */
EVP_CIPHER *EVP_rc2_cbc();     /* RC2 in cbc mode,     iv=8, block=8, key=16 */
EVP_CIPHER *EVP_bf_ecb();      /* Blowfish in ecb mode,iv=0, block=8, key=16 */
EVP_CIPHER *EVP_bf_cfb();      /* Blowfish in cfb mode,iv=8, block=1, key=16 */
EVP_CIPHER *EVP_bf_ofb();      /* Blowfish in ofb mode,iv=8, block=1, key=16 */
EVP_CIPHER *EVP_bf_cbc();      /* Blowfish in cbc mode,iv=8, block=8, key=16 */

The meaning of the compound names is as follows.
des	The base cipher is DES.
idea	The base cipher is IDEA
rc4	The base cipher is RC4-128
rc2	The base cipher is RC2-128
ecb	Electronic Code Book form of the cipher.
cbc	Cipher Block Chaining form of the cipher.
cfb	64 bit Cipher Feedback form of the cipher.
ofb	64 bit Output Feedback form of the cipher.
ede	The cipher is used in Encrypt, Decrypt, Encrypt mode.  The first
	and last keys are the same.
ede3	The cipher is used in Encrypt, Decrypt, Encrypt mode.

All the Cipher routines take a EVP_CIPHER_CTX pointer as an argument.
The state of the cipher is kept in this structure.

typedef struct EVP_CIPHER_Ctx_st
	{
	EVP_CIPHER *cipher;
	int encrypt;		/* encrypt or decrypt */
	int buf_len;		/* number we have left */
	unsigned char buf[8];
	union	{
		.... /* cipher specific stuff */
		} c;
	} EVP_CIPHER_CTX;

Cipher is a pointer the the EVP_CIPHER for the current context.  The encrypt
flag indicates encryption or decryption.  buf_len is the number of bytes
currently being held in buf.
The 'c' union holds the cipher specify context.

The following functions are to be used.

int EVP_read_pw_string(
char *buf,
int len,
char *prompt,
int verify,
	This function is the same as des_read_pw_string() (des.doc).

void EVP_set_pw_prompt(char *prompt);
	This function sets the 'default' prompt to use to use in
	EVP_read_pw_string when the prompt parameter is NULL.  If the
	prompt parameter is NULL, this 'default prompt' feature is turned
	off.  Be warned, this is a global variable so weird things
	will happen if it is used under Win16 and care must be taken
	with a multi-threaded version of the library.

char *EVP_get_pw_prompt();
	This returns a pointer to the default prompt string.  NULL
	if it is not set.

int EVP_BytesToKey(
EVP_CIPHER *type,
EVP_MD *md,
unsigned char *salt,
unsigned char *data,
int datal,
int count,
unsigned char *key,
unsigned char *iv);
	This function is used to generate a key and an initialisation vector
	for a specified cipher from a key string and a salt.  Type
	specifies the cipher the 'key' is being generated for.  Md is the
	message digest algorithm to use to generate the key and iv.  The salt
	is an optional 8 byte object that is used to help seed the key
	generator.
	If the salt value is NULL, it is just not used.  Datal is the
	number of bytes to use from 'data' in the key generation.  
	This function returns the key size for the specified cipher, if
	data is NULL, this value is returns and no other
	computation is performed.  Count is
	the number of times to loop around the key generator.  I would
	suggest leaving it's value as 1.  Key and iv are the structures to
	place the returning iv and key in.  If they are NULL, no value is
	generated for that particular value.
	The algorithm used is as follows
	
	/* M[] is an array of message digests
	 * MD() is the message digest function */
	M[0]=MD(data . salt);
	for (i=1; i<count; i++) M[0]=MD(M[0]);

	i=1
	while (data still needed for key and iv)
		{
		M[i]=MD(M[i-1] . data . salt);
		for (i=1; i<count; i++) M[i]=MD(M[i]);
		i++;
		}

	If the salt is NULL, it is not used.
	The digests are concatenated together.
	M = M[0] . M[1] . M[2] .......

	For key= 8, iv=8 => key=M[0.. 8], iv=M[ 9 .. 16].
	For key=16, iv=0 => key=M[0..16].
	For key=16, iv=8 => key=M[0..16], iv=M[17 .. 24].
	For key=24, iv=8 => key=M[0..24], iv=M[25 .. 32].

	This routine will produce DES-CBC keys and iv that are compatible
	with the PKCS-5 standard when md2 or md5 are used.  If md5 is
	used, the salt is NULL and count is 1, this routine will produce
	the password to key mapping normally used with RC4.
	I have attempted to logically extend the PKCS-5 standard to
	generate keys and iv for ciphers that require more than 16 bytes,
	if anyone knows what the correct standard is, please inform me.
	When using sha or sha1, things are a bit different under this scheme,
	since sha produces a 20 byte digest.  So for ciphers requiring
	24 bits of data, 20 will come from the first MD and 4 will
	come from the second.

	I have considered having a separate function so this 'routine'
	can be used without the requirement of passing a EVP_CIPHER *,
	but I have decided to not bother.  If you wish to use the
	function without official EVP_CIPHER structures, just declare
	a local one and set the key_len and iv_len fields to the
	length you desire.

The following routines perform encryption and decryption 'by parts'.  By
this I mean that there are groups of 3 routines.  An Init function that is
used to specify a cipher and initialise data structures.  An Update routine
that does encryption/decryption, one 'chunk' at a time.  And finally a
'Final' function that finishes the encryption/decryption process.
All these functions take a EVP_CIPHER pointer to specify which cipher to
encrypt/decrypt with.  They also take a EVP_CIPHER_CTX object as an
argument.  This structure is used to hold the state information associated
with the operation in progress.

void EVP_EncryptInit(
EVP_CIPHER_CTX *ctx,
EVP_CIPHER *type,
unsigned char *key,
unsigned char *iv);
	This function initialise a EVP_CIPHER_CTX for encryption using the
	cipher passed in the 'type' field.  The cipher is initialised to use
	'key' as the key and 'iv' for the initialisation vector (if one is
	required).  If the type, key or iv is NULL, the value currently in the
	EVP_CIPHER_CTX is reused.  So to perform several decrypt
	using the same cipher, key and iv, initialise with the cipher,
	key and iv the first time and then for subsequent calls,
	reuse 'ctx' but pass NULL for type, key and iv.  You must make sure
	to pass a key that is large enough for a particular cipher.  I
	would suggest using the EVP_BytesToKey() function.

void EVP_EncryptUpdate(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
int *outl,
unsigned char *in,
int inl);
	This function takes 'inl' bytes from 'in' and outputs bytes
	encrypted by the cipher 'ctx' was initialised with into 'out'.  The
	number of bytes written to 'out' is put into outl.  If a particular
	cipher encrypts in blocks, less or more bytes than input may be
	output.  Currently the largest block size used by supported ciphers
	is 8 bytes, so 'out' should have room for 'inl+7' bytes.  Normally
	EVP_EncryptInit() is called once, followed by lots and lots of
	calls to EVP_EncryptUpdate, followed by a single EVP_EncryptFinal
	call.

void EVP_EncryptFinal(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
int *outl);
	Because quite a large number of ciphers are block ciphers, there is
	often an incomplete block to write out at the end of the
	encryption.  EVP_EncryptFinal() performs processing on this last
	block.  The last block in encoded in such a way that it is possible
	to determine how many bytes in the last block are valid.  For 8 byte
	block size ciphers, if only 5 bytes in the last block are valid, the
	last three bytes will be filled with the value 3.  If only 2 were
	valid, the other 6 would be filled with sixes.  If all 8 bytes are
	valid, a extra 8 bytes are appended to the cipher stream containing
	nothing but 8 eights.  These last bytes are output into 'out' and
	the number of bytes written is put into 'outl'  These last bytes
	are output into 'out' and the number of bytes written is put into
	'outl'.  This form of block cipher finalisation is compatible with
	PKCS-5.  Please remember that even if you are using ciphers like
	RC4 that has no blocking and so the function will not write
	anything into 'out', it would still be a good idea to pass a
	variable for 'out' that can hold 8 bytes just in case the cipher is
	changed some time in the future.  It should also be remembered
	that the EVP_CIPHER_CTX contains the password and so when one has
	finished encryption with a particular EVP_CIPHER_CTX, it is good
	practice to zero the structure 
	(ie. memset(ctx,0,sizeof(EVP_CIPHER_CTX)).
	
void EVP_DecryptInit(
EVP_CIPHER_CTX *ctx,
EVP_CIPHER *type,
unsigned char *key,
unsigned char *iv);
	This function is basically the same as EVP_EncryptInit() accept that
	is prepares the EVP_CIPHER_CTX for decryption.

void EVP_DecryptUpdate(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
int *outl,
unsigned char *in,
int inl);
	This function is basically the same as EVP_EncryptUpdate()
	except that it performs decryption.  There is one
	fundamental difference though.  'out' can not be the same as
	'in' for any ciphers with a block size greater than 1 if more
	than one call to EVP_DecryptUpdate() will be made.  This
	is because this routine can hold a 'partial' block between
	calls.  When a partial block is decrypted (due to more bytes
	being passed via this function, they will be written to 'out'
	overwriting the input bytes in 'in' that have not been read
	yet.  From this it should also be noted that 'out' should
	be at least one 'block size' larger than 'inl'.  This problem
	only occurs on the second and subsequent call to
	EVP_DecryptUpdate() when using a block cipher.

int EVP_DecryptFinal(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
int *outl);
	This function is different to EVP_EncryptFinal in that it 'removes'
	any padding bytes appended when the data was encrypted.  Due to the
	way in which 1 to 8 bytes may have been appended when encryption
	using a block cipher, 'out' can end up with 0 to 7 bytes being put
	into it.  When decoding the padding bytes, it is possible to detect
	an incorrect decryption.  If the decryption appears to be wrong, 0
	is returned.  If everything seems ok, 1 is returned.  For ciphers
	with a block size of 1 (RC4), this function would normally not
	return any bytes and would always return 1.  Just because this
	function returns 1 does not mean the decryption was correct. It
	would normally be wrong due to either the wrong key/iv or
	corruption of the cipher data fed to EVP_DecryptUpdate().
	As for EVP_EncryptFinal, it is a good idea to zero the
	EVP_CIPHER_CTX after use since the structure contains the key used
	to decrypt the data.
	
The following Cipher routines are convenience routines that call either
EVP_EncryptXxx or EVP_DecryptXxx depending on weather the EVP_CIPHER_CTX
was setup to encrypt or decrypt.  

void EVP_CipherInit(
EVP_CIPHER_CTX *ctx,
EVP_CIPHER *type,
unsigned char *key,
unsigned char *iv,
int enc);
	This function take arguments that are the same as EVP_EncryptInit()
	and EVP_DecryptInit() except for the extra 'enc' flag.  If 1, the
	EVP_CIPHER_CTX is setup for encryption, if 0, decryption.

void EVP_CipherUpdate(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
int *outl,
unsigned char *in,
int inl);
	Again this function calls either EVP_EncryptUpdate() or
	EVP_DecryptUpdate() depending on state in the 'ctx' structure.
	As noted for EVP_DecryptUpdate(), when this routine is used
	for decryption with block ciphers, 'out' should not be the
	same as 'in'.

int EVP_CipherFinal(
EVP_CIPHER_CTX *ctx,
unsigned char *outm,
int *outl);
	This routine call EVP_EncryptFinal() or EVP_DecryptFinal()
	depending on the state information in 'ctx'.  1 is always returned
	if the mode is encryption, otherwise the return value is the return
	value of EVP_DecryptFinal().
