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