cipher.c revision 1.16
1/*
2
3cipher.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8                   All rights reserved
9
10Created: Wed Apr 19 17:41:39 1995 ylo
11
12*/
13
14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.16 1999/11/23 22:25:53 markus Exp $");
16
17#include "ssh.h"
18#include "cipher.h"
19
20#include <ssl/md5.h>
21
22/*
23 * What kind of tripple DES are these 2 routines?
24 *
25 * Why is there a redundant initialization vector?
26 *
27 * If only iv3 was used, then, this would till effect have been
28 * outer-cbc. However, there is also a private iv1 == iv2 which
29 * perhaps makes differential analysis easier. On the other hand, the
30 * private iv1 probably makes the CRC-32 attack ineffective. This is a
31 * result of that there is no longer any known iv1 to use when
32 * choosing the X block.
33 */
34void
35SSH_3CBC_ENCRYPT(des_key_schedule ks1,
36		 des_key_schedule ks2, des_cblock * iv2,
37		 des_key_schedule ks3, des_cblock * iv3,
38		 void *dest, void *src,
39		 unsigned int len)
40{
41	des_cblock iv1;
42
43	memcpy(&iv1, iv2, 8);
44
45	des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT);
46	memcpy(&iv1, dest + len - 8, 8);
47
48	des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT);
49	memcpy(iv2, &iv1, 8);	/* Note how iv1 == iv2 on entry and exit. */
50
51	des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT);
52	memcpy(iv3, dest + len - 8, 8);
53}
54
55void
56SSH_3CBC_DECRYPT(des_key_schedule ks1,
57		 des_key_schedule ks2, des_cblock * iv2,
58		 des_key_schedule ks3, des_cblock * iv3,
59		 void *dest, void *src,
60		 unsigned int len)
61{
62	des_cblock iv1;
63
64	memcpy(&iv1, iv2, 8);
65
66	des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT);
67	memcpy(iv3, src + len - 8, 8);
68
69	des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT);
70	memcpy(iv2, dest + len - 8, 8);
71
72	des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT);
73	/* memcpy(&iv1, iv2, 8); */
74	/* Note how iv1 == iv2 on entry and exit. */
75}
76
77/*
78 * SSH uses a variation on Blowfish, all bytes must be swapped before
79 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
80 */
81static void
82swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
83{
84	/* dst must be properly aligned. */
85	u_int32_t *dst = (u_int32_t *) dst_;
86	union {
87		u_int32_t i;
88		char c[4];
89	} t;
90
91	/* Process 8 bytes every lap. */
92	for (n = n / 8; n > 0; n--) {
93		t.c[3] = *src++;
94		t.c[2] = *src++;
95		t.c[1] = *src++;
96		t.c[0] = *src++;
97		*dst++ = t.i;
98
99		t.c[3] = *src++;
100		t.c[2] = *src++;
101		t.c[1] = *src++;
102		t.c[0] = *src++;
103		*dst++ = t.i;
104	}
105}
106
107void (*cipher_attack_detected) (const char *fmt,...) = fatal;
108
109static inline void
110detect_cbc_attack(const unsigned char *src,
111		  unsigned int len)
112{
113	return;
114
115	log("CRC-32 CBC insertion attack detected");
116	cipher_attack_detected("CRC-32 CBC insertion attack detected");
117}
118
119/* Names of all encryption algorithms.  These must match the numbers defined
120   int cipher.h. */
121static char *cipher_names[] =
122{
123	"none",
124	"idea",
125	"des",
126	"3des",
127	"tss",
128	"rc4",
129	"blowfish"
130};
131
132/* Returns a bit mask indicating which ciphers are supported by this
133   implementation.  The bit mask has the corresponding bit set of each
134   supported cipher. */
135
136unsigned int
137cipher_mask()
138{
139	unsigned int mask = 0;
140	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
141	mask |= 1 << SSH_CIPHER_BLOWFISH;
142	return mask;
143}
144
145/* Returns the name of the cipher. */
146
147const char *
148cipher_name(int cipher)
149{
150	if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
151	    cipher_names[cipher] == NULL)
152		fatal("cipher_name: bad cipher number: %d", cipher);
153	return cipher_names[cipher];
154}
155
156/* Parses the name of the cipher.  Returns the number of the corresponding
157   cipher, or -1 on error. */
158
159int
160cipher_number(const char *name)
161{
162	int i;
163	for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
164		if (strcmp(cipher_names[i], name) == 0 &&
165		    (cipher_mask() & (1 << i)))
166			return i;
167	return -1;
168}
169
170/* Selects the cipher, and keys if by computing the MD5 checksum of the
171   passphrase and using the resulting 16 bytes as the key. */
172
173void
174cipher_set_key_string(CipherContext *context, int cipher,
175		      const char *passphrase, int for_encryption)
176{
177	MD5_CTX md;
178	unsigned char digest[16];
179
180	MD5_Init(&md);
181	MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
182	MD5_Final(digest, &md);
183
184	cipher_set_key(context, cipher, digest, 16, for_encryption);
185
186	memset(digest, 0, sizeof(digest));
187	memset(&md, 0, sizeof(md));
188}
189
190/* Selects the cipher to use and sets the key. */
191
192void
193cipher_set_key(CipherContext *context, int cipher,
194	       const unsigned char *key, int keylen, int for_encryption)
195{
196	unsigned char padded[32];
197
198	/* Set cipher type. */
199	context->type = cipher;
200
201	/* Get 32 bytes of key data.  Pad if necessary.  (So that code
202	   below does not need to worry about key size). */
203	memset(padded, 0, sizeof(padded));
204	memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));
205
206	/* Initialize the initialization vector. */
207	switch (cipher) {
208	case SSH_CIPHER_NONE:
209		/* Has to stay for authfile saving of private key with
210		   no passphrase */
211		break;
212
213	case SSH_CIPHER_3DES:
214		/* Note: the least significant bit of each byte of key is
215		   parity, and must be ignored by the implementation.  16
216		   bytes of key are used (first and last keys are the
217		   same). */
218		if (keylen < 16)
219			error("Key length %d is insufficient for 3DES.", keylen);
220		des_set_key((void *) padded, context->u.des3.key1);
221		des_set_key((void *) (padded + 8), context->u.des3.key2);
222		if (keylen <= 16)
223			des_set_key((void *) padded, context->u.des3.key3);
224		else
225			des_set_key((void *) (padded + 16), context->u.des3.key3);
226		memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
227		memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
228		break;
229
230	case SSH_CIPHER_BLOWFISH:
231		BF_set_key(&context->u.bf.key, keylen, padded);
232		memset(context->u.bf.iv, 0, 8);
233		break;
234
235	default:
236		fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
237	}
238	memset(padded, 0, sizeof(padded));
239}
240
241/* Encrypts data using the cipher. */
242
243void
244cipher_encrypt(CipherContext *context, unsigned char *dest,
245	       const unsigned char *src, unsigned int len)
246{
247	if ((len & 7) != 0)
248		fatal("cipher_encrypt: bad plaintext length %d", len);
249
250	switch (context->type) {
251	case SSH_CIPHER_NONE:
252		memcpy(dest, src, len);
253		break;
254
255	case SSH_CIPHER_3DES:
256		SSH_3CBC_ENCRYPT(context->u.des3.key1,
257				 context->u.des3.key2, &context->u.des3.iv2,
258				 context->u.des3.key3, &context->u.des3.iv3,
259				 dest, (void *) src, len);
260		break;
261
262	case SSH_CIPHER_BLOWFISH:
263		swap_bytes(src, dest, len);
264		BF_cbc_encrypt(dest, dest, len,
265		               &context->u.bf.key, context->u.bf.iv,
266			       BF_ENCRYPT);
267		swap_bytes(dest, dest, len);
268		break;
269
270	default:
271		fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type));
272	}
273}
274
275/* Decrypts data using the cipher. */
276
277void
278cipher_decrypt(CipherContext *context, unsigned char *dest,
279	       const unsigned char *src, unsigned int len)
280{
281	if ((len & 7) != 0)
282		fatal("cipher_decrypt: bad ciphertext length %d", len);
283
284	switch (context->type) {
285	case SSH_CIPHER_NONE:
286		memcpy(dest, src, len);
287		break;
288
289	case SSH_CIPHER_3DES:
290		/* CRC-32 attack? */
291		SSH_3CBC_DECRYPT(context->u.des3.key1,
292				 context->u.des3.key2, &context->u.des3.iv2,
293				 context->u.des3.key3, &context->u.des3.iv3,
294				 dest, (void *) src, len);
295		break;
296
297	case SSH_CIPHER_BLOWFISH:
298		detect_cbc_attack(src, len);
299		swap_bytes(src, dest, len);
300		BF_cbc_encrypt((void *) dest, dest, len,
301			       &context->u.bf.key, context->u.bf.iv,
302			       BF_DECRYPT);
303		swap_bytes(dest, dest, len);
304		break;
305
306	default:
307		fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
308	}
309}
310