xref: /freebsd/crypto/openssh/cipher.c (revision 3ff369fed2a08f32dda232c10470b949bef9489f)
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  *
12  *
13  * Copyright (c) 1999 Niels Provos.  All rights reserved.
14  * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include "includes.h"
38 RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $");
39 RCSID("$FreeBSD$");
40 
41 #include "xmalloc.h"
42 #include "log.h"
43 #include "cipher.h"
44 
45 #include <openssl/md5.h>
46 #include "rijndael.h"
47 
48 static EVP_CIPHER *evp_ssh1_3des(void);
49 static EVP_CIPHER *evp_ssh1_bf(void);
50 static EVP_CIPHER *evp_rijndael(void);
51 
52 struct Cipher {
53 	char	*name;
54 	int	number;		/* for ssh1 only */
55 	u_int	block_size;
56 	u_int	key_len;
57 	EVP_CIPHER	*(*evptype)(void);
58 } ciphers[] = {
59 	{ "none", 		SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
60 	{ "des", 		SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
61 	{ "3des", 		SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
62 	{ "blowfish", 		SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
63 
64 	{ "3des-cbc", 		SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
65 	{ "blowfish-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
66 	{ "cast128-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
67 	{ "arcfour", 		SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
68 	{ "aes128-cbc", 	SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
69 	{ "aes192-cbc", 	SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
70 	{ "aes256-cbc", 	SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
71 
72 	{ NULL,			SSH_CIPHER_ILLEGAL, 0, 0, NULL }
73 };
74 
75 /*--*/
76 
77 u_int
78 cipher_blocksize(Cipher *c)
79 {
80 	return (c->block_size);
81 }
82 u_int
83 cipher_keylen(Cipher *c)
84 {
85 	return (c->key_len);
86 }
87 
88 u_int
89 cipher_mask_ssh1(int client)
90 {
91 	u_int mask = 0;
92 	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
93 	mask |= 1 << SSH_CIPHER_BLOWFISH;
94 	if (client) {
95 		mask |= 1 << SSH_CIPHER_DES;
96 	}
97 	return mask;
98 }
99 
100 Cipher *
101 cipher_by_name(const char *name)
102 {
103 	Cipher *c;
104 	for (c = ciphers; c->name != NULL; c++)
105 		if (strcasecmp(c->name, name) == 0)
106 			return c;
107 	return NULL;
108 }
109 
110 Cipher *
111 cipher_by_number(int id)
112 {
113 	Cipher *c;
114 	for (c = ciphers; c->name != NULL; c++)
115 		if (c->number == id)
116 			return c;
117 	return NULL;
118 }
119 
120 #define	CIPHER_SEP	","
121 int
122 ciphers_valid(const char *names)
123 {
124 	Cipher *c;
125 	char *ciphers, *cp;
126 	char *p;
127 
128 	if (names == NULL || strcmp(names, "") == 0)
129 		return 0;
130 	ciphers = cp = xstrdup(names);
131 	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
132 	    (p = strsep(&cp, CIPHER_SEP))) {
133 		c = cipher_by_name(p);
134 		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
135 			debug("bad cipher %s [%s]", p, names);
136 			xfree(ciphers);
137 			return 0;
138 		} else {
139 			debug3("cipher ok: %s [%s]", p, names);
140 		}
141 	}
142 	debug3("ciphers ok: [%s]", names);
143 	xfree(ciphers);
144 	return 1;
145 }
146 
147 /*
148  * Parses the name of the cipher.  Returns the number of the corresponding
149  * cipher, or -1 on error.
150  */
151 
152 int
153 cipher_number(const char *name)
154 {
155 	Cipher *c;
156 	if (name == NULL)
157 		return -1;
158 	c = cipher_by_name(name);
159 	return (c==NULL) ? -1 : c->number;
160 }
161 
162 char *
163 cipher_name(int id)
164 {
165 	Cipher *c = cipher_by_number(id);
166 	return (c==NULL) ? "<unknown>" : c->name;
167 }
168 
169 void
170 cipher_init(CipherContext *cc, Cipher *cipher,
171     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
172     int encrypt)
173 {
174 	static int dowarn = 1;
175 	const EVP_CIPHER *type;
176 	int klen;
177 
178 	if (cipher->number == SSH_CIPHER_DES) {
179 		if (dowarn) {
180 			error("Warning: use of DES is strongly discouraged "
181 			    "due to cryptographic weaknesses");
182 			dowarn = 0;
183 		}
184 		if (keylen > 8)
185 			keylen = 8;
186 	}
187 	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
188 
189 	if (keylen < cipher->key_len)
190 		fatal("cipher_init: key length %d is insufficient for %s.",
191 		    keylen, cipher->name);
192 	if (iv != NULL && ivlen < cipher->block_size)
193 		fatal("cipher_init: iv length %d is insufficient for %s.",
194 		    ivlen, cipher->name);
195 	cc->cipher = cipher;
196 
197 	type = (*cipher->evptype)();
198 
199 	EVP_CIPHER_CTX_init(&cc->evp);
200 	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
201 	    (encrypt == CIPHER_ENCRYPT)) == 0)
202 		fatal("cipher_init: EVP_CipherInit failed for %s",
203 		    cipher->name);
204 	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
205 	if (klen > 0 && keylen != klen) {
206 		debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
207 		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
208 			fatal("cipher_init: set keylen failed (%d -> %d)",
209 			    klen, keylen);
210 	}
211 	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
212 		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
213 		    cipher->name);
214 }
215 
216 void
217 cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
218 {
219 	if (len % cc->cipher->block_size)
220 		fatal("cipher_encrypt: bad plaintext length %d", len);
221 	if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
222 		fatal("evp_crypt: EVP_Cipher failed");
223 }
224 
225 void
226 cipher_cleanup(CipherContext *cc)
227 {
228 	if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
229 		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
230 }
231 
232 /*
233  * Selects the cipher, and keys if by computing the MD5 checksum of the
234  * passphrase and using the resulting 16 bytes as the key.
235  */
236 
237 void
238 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
239     const char *passphrase, int encrypt)
240 {
241 	MD5_CTX md;
242 	u_char digest[16];
243 
244 	MD5_Init(&md);
245 	MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
246 	MD5_Final(digest, &md);
247 
248 	cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
249 
250 	memset(digest, 0, sizeof(digest));
251 	memset(&md, 0, sizeof(md));
252 }
253 
254 /* Implementations for other non-EVP ciphers */
255 
256 /*
257  * This is used by SSH1:
258  *
259  * What kind of triple DES are these 2 routines?
260  *
261  * Why is there a redundant initialization vector?
262  *
263  * If only iv3 was used, then, this would till effect have been
264  * outer-cbc. However, there is also a private iv1 == iv2 which
265  * perhaps makes differential analysis easier. On the other hand, the
266  * private iv1 probably makes the CRC-32 attack ineffective. This is a
267  * result of that there is no longer any known iv1 to use when
268  * choosing the X block.
269  */
270 struct ssh1_3des_ctx
271 {
272 	EVP_CIPHER_CTX	k1, k2, k3;
273 };
274 static int
275 ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
276     int enc)
277 {
278 	struct ssh1_3des_ctx *c;
279 	u_char *k1, *k2, *k3;
280 
281 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
282 		c = xmalloc(sizeof(*c));
283 		EVP_CIPHER_CTX_set_app_data(ctx, c);
284 	}
285 	if (key == NULL)
286 		return (1);
287 	if (enc == -1)
288 		enc = ctx->encrypt;
289 	k1 = k2 = k3 = (u_char *) key;
290 	k2 += 8;
291 	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
292 		if (enc)
293 			k3 += 16;
294 		else
295 			k1 += 16;
296 	}
297 	EVP_CIPHER_CTX_init(&c->k1);
298 	EVP_CIPHER_CTX_init(&c->k2);
299 	EVP_CIPHER_CTX_init(&c->k3);
300 	if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
301 	    EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
302 	    EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
303 		memset(c, 0, sizeof(*c));
304 		xfree(c);
305 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
306 		return (0);
307 	}
308 	return (1);
309 }
310 static int
311 ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
312 {
313 	struct ssh1_3des_ctx *c;
314 
315 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
316 		error("ssh1_3des_cbc: no context");
317 		return (0);
318 	}
319 	if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
320 	    EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
321 	    EVP_Cipher(&c->k3, dest, dest, len) == 0)
322 		return (0);
323 	return (1);
324 }
325 static int
326 ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
327 {
328 	struct ssh1_3des_ctx *c;
329 
330 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
331 		memset(c, 0, sizeof(*c));
332 		xfree(c);
333 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
334 	}
335 	return (1);
336 }
337 static EVP_CIPHER *
338 evp_ssh1_3des(void)
339 {
340 	static EVP_CIPHER ssh1_3des;
341 
342 	memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
343 	ssh1_3des.nid = NID_undef;
344 	ssh1_3des.block_size = 8;
345 	ssh1_3des.iv_len = 0;
346 	ssh1_3des.key_len = 16;
347 	ssh1_3des.init = ssh1_3des_init;
348 	ssh1_3des.cleanup = ssh1_3des_cleanup;
349 	ssh1_3des.do_cipher = ssh1_3des_cbc;
350 	ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
351 	return (&ssh1_3des);
352 }
353 
354 /*
355  * SSH1 uses a variation on Blowfish, all bytes must be swapped before
356  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
357  */
358 static void
359 swap_bytes(const u_char *src, u_char *dst, int n)
360 {
361 	u_char c[4];
362 
363 	/* Process 4 bytes every lap. */
364 	for (n = n / 4; n > 0; n--) {
365 		c[3] = *src++;
366 		c[2] = *src++;
367 		c[1] = *src++;
368 		c[0] = *src++;
369 
370 		*dst++ = c[0];
371 		*dst++ = c[1];
372 		*dst++ = c[2];
373 		*dst++ = c[3];
374 	}
375 }
376 static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
377 static int
378 bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
379 {
380 	int ret;
381 
382 	swap_bytes(in, out, len);
383 	ret = (*orig_bf)(ctx, out, out, len);
384 	swap_bytes(out, out, len);
385 	return (ret);
386 }
387 static EVP_CIPHER *
388 evp_ssh1_bf(void)
389 {
390 	static EVP_CIPHER ssh1_bf;
391 
392 	memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
393 	orig_bf = ssh1_bf.do_cipher;
394 	ssh1_bf.nid = NID_undef;
395 	ssh1_bf.do_cipher = bf_ssh1_cipher;
396 	ssh1_bf.key_len = 32;
397 	return (&ssh1_bf);
398 }
399 
400 /* RIJNDAEL */
401 #define RIJNDAEL_BLOCKSIZE 16
402 struct ssh_rijndael_ctx
403 {
404 	rijndael_ctx	r_ctx;
405 	u_char		r_iv[RIJNDAEL_BLOCKSIZE];
406 };
407 
408 static int
409 ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
410     int enc)
411 {
412 	struct ssh_rijndael_ctx *c;
413 
414 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
415 		c = xmalloc(sizeof(*c));
416 		EVP_CIPHER_CTX_set_app_data(ctx, c);
417 	}
418 	if (key != NULL) {
419 		if (enc == -1)
420 			enc = ctx->encrypt;
421 		rijndael_set_key(&c->r_ctx, (u_char *)key,
422 		    8*EVP_CIPHER_CTX_key_length(ctx), enc);
423 	}
424 	if (iv != NULL)
425 		memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
426 	return (1);
427 }
428 static int
429 ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
430     u_int len)
431 {
432 	struct ssh_rijndael_ctx *c;
433 	u_char buf[RIJNDAEL_BLOCKSIZE];
434 	u_char *cprev, *cnow, *plain, *ivp;
435 	int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
436 
437 	if (len == 0)
438 		return (1);
439 	if (len % RIJNDAEL_BLOCKSIZE)
440 		fatal("ssh_rijndael_cbc: bad len %d", len);
441 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
442 		error("ssh_rijndael_cbc: no context");
443 		return (0);
444 	}
445 	if (ctx->encrypt) {
446 		cnow  = dest;
447 		plain = (u_char *)src;
448 		cprev = c->r_iv;
449 		for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
450 		    cnow+=RIJNDAEL_BLOCKSIZE) {
451 			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
452 				buf[j] = plain[j] ^ cprev[j];
453 			rijndael_encrypt(&c->r_ctx, buf, cnow);
454 			cprev = cnow;
455 		}
456 		memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
457 	} else {
458 		cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
459 		plain = dest+len-RIJNDAEL_BLOCKSIZE;
460 
461 		memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
462 		for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
463 		    plain-=RIJNDAEL_BLOCKSIZE) {
464 			rijndael_decrypt(&c->r_ctx, cnow, plain);
465 			ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
466 			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
467 				plain[j] ^= ivp[j];
468 		}
469 		memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
470 	}
471 	return (1);
472 }
473 static int
474 ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
475 {
476 	struct ssh_rijndael_ctx *c;
477 
478 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
479 		memset(c, 0, sizeof(*c));
480 		xfree(c);
481 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
482 	}
483 	return (1);
484 }
485 static EVP_CIPHER *
486 evp_rijndael(void)
487 {
488 	static EVP_CIPHER rijndal_cbc;
489 
490 	memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
491 	rijndal_cbc.nid = NID_undef;
492 	rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
493 	rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
494 	rijndal_cbc.key_len = 16;
495 	rijndal_cbc.init = ssh_rijndael_init;
496 	rijndal_cbc.cleanup = ssh_rijndael_cleanup;
497 	rijndal_cbc.do_cipher = ssh_rijndael_cbc;
498 	rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
499 	    EVP_CIPH_ALWAYS_CALL_INIT;
500 	return (&rijndal_cbc);
501 }
502