xref: /titanic_44/usr/src/cmd/ssh/libssh/common/cipher.c (revision 18c2aff776a775d34a4c9893a4c72e0434d68e36)
1 /*
2  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 /*
6  * Author: Tatu Ylonen <ylo@cs.hut.fi>
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * As far as I am concerned, the code I have written for this software
11  * can be used freely for any purpose.  Any derived versions of this
12  * software must be clearly marked as such, and if the derived work is
13  * incompatible with the protocol description in the RFC file, it must be
14  * called by a name other than "ssh" or "Secure Shell".
15  *
16  *
17  * Copyright (c) 1999 Niels Provos.  All rights reserved.
18  * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions
22  * are met:
23  * 1. Redistributions of source code must retain the above copyright
24  *    notice, this list of conditions and the following disclaimer.
25  * 2. Redistributions in binary form must reproduce the above copyright
26  *    notice, this list of conditions and the following disclaimer in the
27  *    documentation and/or other materials provided with the distribution.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "includes.h"
42 RCSID("$OpenBSD: cipher.c,v 1.61 2002/07/12 15:50:17 markus Exp $");
43 
44 #pragma ident	"%Z%%M%	%I%	%E% SMI"
45 
46 #include "xmalloc.h"
47 #include "log.h"
48 #include "cipher.h"
49 
50 #include <openssl/md5.h>
51 
52 #if OPENSSL_VERSION_NUMBER < 0x00906000L
53 #define SSH_OLD_EVP
54 #define EVP_CIPHER_CTX_get_app_data(e)          ((e)->app_data)
55 #endif
56 
57 extern const EVP_CIPHER *evp_aes_128_ctr(void);
58 extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
59 
60 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
61 #include "rijndael.h"
62 static const EVP_CIPHER *evp_rijndael(void);
63 #endif
64 static const EVP_CIPHER *evp_ssh1_3des(void);
65 static const EVP_CIPHER *evp_ssh1_bf(void);
66 
67 struct Cipher {
68 	char	*name;
69 	int	number;		/* for ssh1 only */
70 	u_int	block_size;
71 	u_int	key_len;
72 	const EVP_CIPHER	*(*evptype)(void);
73 } ciphers[] = {
74 	{ "none", 		SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
75 	{ "des", 		SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
76 	{ "3des", 		SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
77 	{ "blowfish", 		SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
78 	{ "3des-cbc", 		SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
79 	{ "blowfish-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
80 #ifdef SOLARIS_SSH_ENABLE_CAST5_128
81 	{ "cast128-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
82 #endif /* SOLARIS_SSH_ENABLE_CAST5_128 */
83 	{ "arcfour", 		SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
84 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
85 	{ "aes128-cbc", 	SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
86 #ifdef SOLARIS_SSH_ENABLE_AES192
87 	{ "aes192-cbc", 	SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
88 #endif /* SOLARIS_SSH_ENABLE_AES192 */
89 #ifdef SOLARIS_SSH_ENABLE_AES256
90 	{ "aes256-cbc", 	SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
91 	{ "rijndael-cbc@lysator.liu.se",
92 				SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
93 #endif /* SOLARIS_SSH_ENABLE_AES256 */
94 #else
95 	{ "aes128-cbc",		SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc },
96 #ifdef SOLARIS_SSH_ENABLE_AES192
97 	{ "aes192-cbc",		SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc },
98 #endif /* SOLARIS_SSH_ENABLE_AES192 */
99 #ifdef SOLARIS_SSH_ENABLE_AES256
100 	{ "aes256-cbc",		SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
101 	{ "rijndael-cbc@lysator.liu.se",
102 				SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
103 #endif /* SOLARIS_SSH_ENABLE_AES256 */
104 #endif
105 #if OPENSSL_VERSION_NUMBER >= 0x00905000L
106         { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
107 #ifdef SOLARIS_SSH_ENABLE_AES192
108         { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
109 #endif /* SOLARIS_SSH_ENABLE_AES192 */
110 #ifdef SOLARIS_SSH_ENABLE_AES192
111         { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
112 #endif /* SOLARIS_SSH_ENABLE_AES192 */
113 #endif
114 	{ NULL,			SSH_CIPHER_ILLEGAL, 0, 0, NULL }
115 };
116 
117 /*--*/
118 
119 u_int
120 cipher_blocksize(Cipher *c)
121 {
122 	return (c->block_size);
123 }
124 
125 u_int
126 cipher_keylen(Cipher *c)
127 {
128 	return (c->key_len);
129 }
130 
131 u_int
132 cipher_get_number(Cipher *c)
133 {
134 	return (c->number);
135 }
136 
137 u_int
138 cipher_mask_ssh1(int client)
139 {
140 	u_int mask = 0;
141 	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
142 	mask |= 1 << SSH_CIPHER_BLOWFISH;
143 	if (client) {
144 		mask |= 1 << SSH_CIPHER_DES;
145 	}
146 	return mask;
147 }
148 
149 Cipher *
150 cipher_by_name(const char *name)
151 {
152 	Cipher *c;
153 	for (c = ciphers; c->name != NULL; c++)
154 		if (strcasecmp(c->name, name) == 0)
155 			return c;
156 	return NULL;
157 }
158 
159 Cipher *
160 cipher_by_number(int id)
161 {
162 	Cipher *c;
163 	for (c = ciphers; c->name != NULL; c++)
164 		if (c->number == id)
165 			return c;
166 	return NULL;
167 }
168 
169 #define	CIPHER_SEP	","
170 int
171 ciphers_valid(const char *names)
172 {
173 	Cipher *c;
174 	char *ciphers, *cp;
175 	char *p;
176 
177 	if (names == NULL || strcmp(names, "") == 0)
178 		return 0;
179 	ciphers = cp = xstrdup(names);
180 	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
181 	    (p = strsep(&cp, CIPHER_SEP))) {
182 		c = cipher_by_name(p);
183 		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
184 			debug("bad cipher %s [%s]", p, names);
185 			xfree(ciphers);
186 			return 0;
187 		} else {
188 			debug3("cipher ok: %s [%s]", p, names);
189 		}
190 	}
191 	debug3("ciphers ok: [%s]", names);
192 	xfree(ciphers);
193 	return 1;
194 }
195 
196 /*
197  * Parses the name of the cipher.  Returns the number of the corresponding
198  * cipher, or -1 on error.
199  */
200 
201 int
202 cipher_number(const char *name)
203 {
204 	Cipher *c;
205 	if (name == NULL)
206 		return -1;
207 	c = cipher_by_name(name);
208 	return (c==NULL) ? -1 : c->number;
209 }
210 
211 char *
212 cipher_name(int id)
213 {
214 	Cipher *c = cipher_by_number(id);
215 	return (c==NULL) ? "<unknown>" : c->name;
216 }
217 
218 void
219 cipher_init(CipherContext *cc, Cipher *cipher,
220     const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
221     int encrypt)
222 {
223 	static int dowarn = 1;
224 #ifdef SSH_OLD_EVP
225 	EVP_CIPHER *type;
226 #else
227 	const EVP_CIPHER *type;
228 #endif
229 	int klen;
230 
231 	if (cipher->number == SSH_CIPHER_DES) {
232 		if (dowarn) {
233 			error("Warning: use of DES is strongly discouraged "
234 			    "due to cryptographic weaknesses");
235 			dowarn = 0;
236 		}
237 		if (keylen > 8)
238 			keylen = 8;
239 	}
240 	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
241 
242 	if (keylen < cipher->key_len)
243 		fatal("cipher_init: key length %d is insufficient for %s.",
244 		    keylen, cipher->name);
245 	if (iv != NULL && ivlen < cipher->block_size)
246 		fatal("cipher_init: iv length %d is insufficient for %s.",
247 		    ivlen, cipher->name);
248 	cc->cipher = cipher;
249 
250 	type = (*cipher->evptype)();
251 
252 	EVP_CIPHER_CTX_init(&cc->evp);
253 #ifdef SSH_OLD_EVP
254 	if (type->key_len > 0 && type->key_len != keylen) {
255 		debug("cipher_init: set keylen (%d -> %d)",
256 		    type->key_len, keylen);
257 		type->key_len = keylen;
258 	}
259 	EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
260 	    (encrypt == CIPHER_ENCRYPT));
261 #else
262 	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
263 	    (encrypt == CIPHER_ENCRYPT)) == 0)
264 		fatal("cipher_init: EVP_CipherInit failed for %s",
265 		    cipher->name);
266 	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
267 	if (klen > 0 && keylen != klen) {
268 		debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
269 		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
270 			fatal("cipher_init: set keylen failed (%d -> %d)",
271 			    klen, keylen);
272 	}
273 	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
274 		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
275 		    cipher->name);
276 #endif
277 }
278 
279 void
280 cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
281 {
282 	if (len % cc->cipher->block_size)
283 		fatal("cipher_encrypt: bad plaintext length %d", len);
284 #ifdef SSH_OLD_EVP
285 	EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
286 #else
287 	if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
288 		fatal("evp_crypt: EVP_Cipher failed");
289 #endif
290 }
291 
292 void
293 cipher_cleanup(CipherContext *cc)
294 {
295 #ifdef SSH_OLD_EVP
296 	EVP_CIPHER_CTX_cleanup(&cc->evp);
297 #else
298 	if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
299 		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
300 #endif
301 }
302 
303 /*
304  * Selects the cipher, and keys if by computing the MD5 checksum of the
305  * passphrase and using the resulting 16 bytes as the key.
306  */
307 
308 void
309 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
310     const char *passphrase, int encrypt)
311 {
312 	MD5_CTX md;
313 	u_char digest[16];
314 
315 	MD5_Init(&md);
316 	MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
317 	MD5_Final(digest, &md);
318 
319 	cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
320 
321 	memset(digest, 0, sizeof(digest));
322 	memset(&md, 0, sizeof(md));
323 }
324 
325 /* Implementations for other non-EVP ciphers */
326 
327 /*
328  * This is used by SSH1:
329  *
330  * What kind of triple DES are these 2 routines?
331  *
332  * Why is there a redundant initialization vector?
333  *
334  * If only iv3 was used, then, this would till effect have been
335  * outer-cbc. However, there is also a private iv1 == iv2 which
336  * perhaps makes differential analysis easier. On the other hand, the
337  * private iv1 probably makes the CRC-32 attack ineffective. This is a
338  * result of that there is no longer any known iv1 to use when
339  * choosing the X block.
340  */
341 struct ssh1_3des_ctx
342 {
343 	EVP_CIPHER_CTX	k1, k2, k3;
344 };
345 
346 static int
347 ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
348     int enc)
349 {
350 	struct ssh1_3des_ctx *c;
351 	u_char *k1, *k2, *k3;
352 
353 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
354 		c = xmalloc(sizeof(*c));
355 		EVP_CIPHER_CTX_set_app_data(ctx, c);
356 	}
357 	if (key == NULL)
358 		return (1);
359 	if (enc == -1)
360 		enc = ctx->encrypt;
361 	k1 = k2 = k3 = (u_char *) key;
362 	k2 += 8;
363 	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
364 		if (enc)
365 			k3 += 16;
366 		else
367 			k1 += 16;
368 	}
369 	EVP_CIPHER_CTX_init(&c->k1);
370 	EVP_CIPHER_CTX_init(&c->k2);
371 	EVP_CIPHER_CTX_init(&c->k3);
372 #ifdef SSH_OLD_EVP
373 	EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
374 	EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
375 	EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
376 #else
377 	if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
378 	    EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
379 	    EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
380 		memset(c, 0, sizeof(*c));
381 		xfree(c);
382 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
383 		return (0);
384 	}
385 #endif
386 	return (1);
387 }
388 
389 static int
390 ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
391 {
392 	struct ssh1_3des_ctx *c;
393 
394 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
395 		error("ssh1_3des_cbc: no context");
396 		return (0);
397 	}
398 #ifdef SSH_OLD_EVP
399 	EVP_Cipher(&c->k1, dest, (u_char *)src, len);
400 	EVP_Cipher(&c->k2, dest, dest, len);
401 	EVP_Cipher(&c->k3, dest, dest, len);
402 #else
403 	if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
404 	    EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
405 	    EVP_Cipher(&c->k3, dest, dest, len) == 0)
406 		return (0);
407 #endif
408 	return (1);
409 }
410 
411 static int
412 ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
413 {
414 	struct ssh1_3des_ctx *c;
415 
416 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
417 		memset(c, 0, sizeof(*c));
418 		xfree(c);
419 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
420 	}
421 	return (1);
422 }
423 
424 static const EVP_CIPHER *
425 evp_ssh1_3des(void)
426 {
427 	static EVP_CIPHER ssh1_3des;
428 
429 	memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
430 	ssh1_3des.nid = NID_undef;
431 	ssh1_3des.block_size = 8;
432 	ssh1_3des.iv_len = 0;
433 	ssh1_3des.key_len = 16;
434 	ssh1_3des.init = ssh1_3des_init;
435 	ssh1_3des.cleanup = ssh1_3des_cleanup;
436 	ssh1_3des.do_cipher = ssh1_3des_cbc;
437 #ifndef SSH_OLD_EVP
438 	ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
439 #endif
440 	return (&ssh1_3des);
441 }
442 
443 /*
444  * SSH1 uses a variation on Blowfish, all bytes must be swapped before
445  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
446  */
447 static void
448 swap_bytes(const u_char *src, u_char *dst, int n)
449 {
450 	u_char c[4];
451 
452 	/* Process 4 bytes every lap. */
453 	for (n = n / 4; n > 0; n--) {
454 		c[3] = *src++;
455 		c[2] = *src++;
456 		c[1] = *src++;
457 		c[0] = *src++;
458 
459 		*dst++ = c[0];
460 		*dst++ = c[1];
461 		*dst++ = c[2];
462 		*dst++ = c[3];
463 	}
464 }
465 
466 #ifdef SSH_OLD_EVP
467 static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
468 			  const unsigned char *iv, int enc)
469 {
470 	if (iv != NULL)
471 		memcpy (&(ctx->oiv[0]), iv, 8);
472 	memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
473 	if (key != NULL)
474 		BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
475 			    key);
476 }
477 #endif
478 static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
479 
480 static int
481 bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
482 {
483 	int ret;
484 
485 	swap_bytes(in, out, len);
486 	ret = (*orig_bf)(ctx, out, out, len);
487 	swap_bytes(out, out, len);
488 	return (ret);
489 }
490 
491 static const EVP_CIPHER *
492 evp_ssh1_bf(void)
493 {
494 	static EVP_CIPHER ssh1_bf;
495 
496 	memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
497 	orig_bf = ssh1_bf.do_cipher;
498 	ssh1_bf.nid = NID_undef;
499 #ifdef SSH_OLD_EVP
500 	ssh1_bf.init = bf_ssh1_init;
501 #endif
502 	ssh1_bf.do_cipher = bf_ssh1_cipher;
503 	ssh1_bf.key_len = 32;
504 	return (&ssh1_bf);
505 }
506 
507 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
508 /* RIJNDAEL */
509 #define RIJNDAEL_BLOCKSIZE 16
510 struct ssh_rijndael_ctx
511 {
512 	rijndael_ctx	r_ctx;
513 	u_char		r_iv[RIJNDAEL_BLOCKSIZE];
514 };
515 
516 static int
517 ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
518     int enc)
519 {
520 	struct ssh_rijndael_ctx *c;
521 
522 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
523 		c = xmalloc(sizeof(*c));
524 		EVP_CIPHER_CTX_set_app_data(ctx, c);
525 	}
526 	if (key != NULL) {
527 		if (enc == -1)
528 			enc = ctx->encrypt;
529 		rijndael_set_key(&c->r_ctx, (u_char *)key,
530 		    8*EVP_CIPHER_CTX_key_length(ctx), enc);
531 	}
532 	if (iv != NULL)
533 		memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
534 	return (1);
535 }
536 
537 static int
538 ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
539     u_int len)
540 {
541 	struct ssh_rijndael_ctx *c;
542 	u_char buf[RIJNDAEL_BLOCKSIZE];
543 	u_char *cprev, *cnow, *plain, *ivp;
544 	int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
545 
546 	if (len == 0)
547 		return (1);
548 	if (len % RIJNDAEL_BLOCKSIZE)
549 		fatal("ssh_rijndael_cbc: bad len %d", len);
550 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
551 		error("ssh_rijndael_cbc: no context");
552 		return (0);
553 	}
554 	if (ctx->encrypt) {
555 		cnow  = dest;
556 		plain = (u_char *)src;
557 		cprev = c->r_iv;
558 		for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
559 		    cnow+=RIJNDAEL_BLOCKSIZE) {
560 			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
561 				buf[j] = plain[j] ^ cprev[j];
562 			rijndael_encrypt(&c->r_ctx, buf, cnow);
563 			cprev = cnow;
564 		}
565 		memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
566 	} else {
567 		cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
568 		plain = dest+len-RIJNDAEL_BLOCKSIZE;
569 
570 		memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
571 		for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
572 		    plain-=RIJNDAEL_BLOCKSIZE) {
573 			rijndael_decrypt(&c->r_ctx, cnow, plain);
574 			ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
575 			for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
576 				plain[j] ^= ivp[j];
577 		}
578 		memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
579 	}
580 	return (1);
581 }
582 
583 static int
584 ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
585 {
586 	struct ssh_rijndael_ctx *c;
587 
588 	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
589 		memset(c, 0, sizeof(*c));
590 		xfree(c);
591 		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
592 	}
593 	return (1);
594 }
595 
596 static const EVP_CIPHER *
597 evp_rijndael(void)
598 {
599 	static EVP_CIPHER rijndal_cbc;
600 
601 	memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
602 	rijndal_cbc.nid = NID_undef;
603 	rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
604 	rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
605 	rijndal_cbc.key_len = 16;
606 	rijndal_cbc.init = ssh_rijndael_init;
607 	rijndal_cbc.cleanup = ssh_rijndael_cleanup;
608 	rijndal_cbc.do_cipher = ssh_rijndael_cbc;
609 #ifndef SSH_OLD_EVP
610 	rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
611 	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
612 #endif
613 	return (&rijndal_cbc);
614 }
615 #endif
616 
617 /*
618  * Exports an IV from the CipherContext required to export the key
619  * state back from the unprivileged child to the privileged parent
620  * process.
621  */
622 
623 int
624 cipher_get_keyiv_len(CipherContext *cc)
625 {
626 	Cipher *c = cc->cipher;
627 	int ivlen;
628 
629 	if (c->number == SSH_CIPHER_3DES)
630 		ivlen = 24;
631 	else
632 		ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
633 	return (ivlen);
634 }
635 
636 void
637 cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
638 {
639 	Cipher *c = cc->cipher;
640 	u_char *civ = NULL;
641 	int evplen;
642 
643 	switch (c->number) {
644 	case SSH_CIPHER_SSH2:
645 	case SSH_CIPHER_DES:
646 	case SSH_CIPHER_BLOWFISH:
647 		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
648 		if (evplen == 0)
649 			return;
650 		if (evplen != len)
651 			fatal("%s: wrong iv length %d != %d", __func__,
652 			    evplen, len);
653 
654 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
655 		if (c->evptype == evp_rijndael) {
656 			struct ssh_rijndael_ctx *aesc;
657 
658 			aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
659 			if (aesc == NULL)
660 				fatal("%s: no rijndael context", __func__);
661 			civ = aesc->r_iv;
662 		} else
663 #endif
664 		if (c->evptype == evp_aes_128_ctr) {
665 			ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
666 			return;
667 		} else {
668 			civ = cc->evp.iv;
669 		}
670 		break;
671 	case SSH_CIPHER_3DES: {
672 		struct ssh1_3des_ctx *desc;
673 		if (len != 24)
674 			fatal("%s: bad 3des iv length: %d", __func__, len);
675 		desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
676 		if (desc == NULL)
677 			fatal("%s: no 3des context", __func__);
678 		debug3("%s: Copying 3DES IV", __func__);
679 		memcpy(iv, desc->k1.iv, 8);
680 		memcpy(iv + 8, desc->k2.iv, 8);
681 		memcpy(iv + 16, desc->k3.iv, 8);
682 		return;
683 	}
684 	default:
685 		fatal("%s: bad cipher %d", __func__, c->number);
686 	}
687 	memcpy(iv, civ, len);
688 }
689 
690 void
691 cipher_set_keyiv(CipherContext *cc, u_char *iv)
692 {
693 	Cipher *c = cc->cipher;
694 	u_char *div = NULL;
695 	int evplen = 0;
696 
697 	switch (c->number) {
698 	case SSH_CIPHER_SSH2:
699 	case SSH_CIPHER_DES:
700 	case SSH_CIPHER_BLOWFISH:
701 		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
702 		if (evplen == 0)
703 			return;
704 
705 #if (OPENSSL_VERSION_NUMBER < 0x00907000L)
706 		if (c->evptype == evp_rijndael) {
707 			struct ssh_rijndael_ctx *aesc;
708 
709 			aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
710 			if (aesc == NULL)
711 				fatal("%s: no rijndael context", __func__);
712 			div = aesc->r_iv;
713 		} else
714 #endif
715 		if (c->evptype == evp_aes_128_ctr) {
716 			ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
717 			return;
718 		} else {
719 			div = cc->evp.iv;
720 		}
721 		break;
722 	case SSH_CIPHER_3DES: {
723 		struct ssh1_3des_ctx *desc;
724 		desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
725 		if (desc == NULL)
726 			fatal("%s: no 3des context", __func__);
727 		debug3("%s: Installed 3DES IV", __func__);
728 		memcpy(desc->k1.iv, iv, 8);
729 		memcpy(desc->k2.iv, iv + 8, 8);
730 		memcpy(desc->k3.iv, iv + 16, 8);
731 		return;
732 	}
733 	default:
734 		fatal("%s: bad cipher %d", __func__, c->number);
735 	}
736 	memcpy(div, iv, evplen);
737 }
738 
739 #if OPENSSL_VERSION_NUMBER < 0x00907000L
740 #define EVP_X_STATE(evp)	&(evp).c
741 #define EVP_X_STATE_LEN(evp)	sizeof((evp).c)
742 #else
743 #define EVP_X_STATE(evp)	(evp).cipher_data
744 #define EVP_X_STATE_LEN(evp)	(evp).cipher->ctx_size
745 #endif
746 
747 int
748 cipher_get_keycontext(CipherContext *cc, u_char *dat)
749 {
750 	int plen = 0;
751 	Cipher *c = cc->cipher;
752 
753 	if (c->evptype == EVP_rc4) {
754 		plen = EVP_X_STATE_LEN(cc->evp);
755 		if (dat == NULL)
756 			return (plen);
757 		memcpy(dat, EVP_X_STATE(cc->evp), plen);
758 	}
759 	return (plen);
760 }
761 
762 void
763 cipher_set_keycontext(CipherContext *cc, u_char *dat)
764 {
765 	Cipher *c = cc->cipher;
766 	int plen;
767 
768 	if (c->evptype == EVP_rc4) {
769 		plen = EVP_X_STATE_LEN(cc->evp);
770 		memcpy(EVP_X_STATE(cc->evp), dat, plen);
771 	}
772 }
773