aboutsummaryrefslogtreecommitdiffstats
path: root/doc/cipher.doc
blob: d49ba78c5cd305bc64b29680d915fc5a5eb5f733 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
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().