mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
346 lines
15 KiB
Plaintext
346 lines
15 KiB
Plaintext
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().
|