cipher.c revision 296781
1/* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *                    All rights reserved
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 *
13 *
14 * Copyright (c) 1999 Niels Provos.  All rights reserved.
15 * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "includes.h"
39
40#include <sys/types.h>
41
42#include <string.h>
43#include <stdarg.h>
44#include <stdio.h>
45
46#include "cipher.h"
47#include "misc.h"
48#include "sshbuf.h"
49#include "ssherr.h"
50#include "digest.h"
51
52#include "openbsd-compat/openssl-compat.h"
53
54#ifdef WITH_SSH1
55extern const EVP_CIPHER *evp_ssh1_bf(void);
56extern const EVP_CIPHER *evp_ssh1_3des(void);
57extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
58#endif
59
60struct sshcipher {
61	char	*name;
62	int	number;		/* for ssh1 only */
63	u_int	block_size;
64	u_int	key_len;
65	u_int	iv_len;		/* defaults to block_size */
66	u_int	auth_len;
67	u_int	discard_len;
68	u_int	flags;
69#define CFLAG_CBC		(1<<0)
70#define CFLAG_CHACHAPOLY	(1<<1)
71#define CFLAG_AESCTR		(1<<2)
72#define CFLAG_NONE		(1<<3)
73#ifdef WITH_OPENSSL
74	const EVP_CIPHER	*(*evptype)(void);
75#else
76	void	*ignored;
77#endif
78};
79
80static const struct sshcipher ciphers[] = {
81#ifdef WITH_SSH1
82	{ "des",	SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
83	{ "3des",	SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
84	{ "blowfish",	SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
85#endif /* WITH_SSH1 */
86#ifdef WITH_OPENSSL
87	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
88	{ "3des-cbc",	SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
89	{ "blowfish-cbc",
90			SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
91	{ "cast128-cbc",
92			SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
93	{ "arcfour",	SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
94	{ "arcfour128",	SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
95	{ "arcfour256",	SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
96	{ "aes128-cbc",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
97	{ "aes192-cbc",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
98	{ "aes256-cbc",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
99	{ "rijndael-cbc@lysator.liu.se",
100			SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
101	{ "aes128-ctr",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
102	{ "aes192-ctr",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
103	{ "aes256-ctr",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
104# ifdef OPENSSL_HAVE_EVPGCM
105	{ "aes128-gcm@openssh.com",
106			SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
107	{ "aes256-gcm@openssh.com",
108			SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
109# endif /* OPENSSL_HAVE_EVPGCM */
110#else /* WITH_OPENSSL */
111	{ "aes128-ctr",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
112	{ "aes192-ctr",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
113	{ "aes256-ctr",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
114	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
115#endif /* WITH_OPENSSL */
116	{ "chacha20-poly1305@openssh.com",
117			SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
118
119	{ NULL,		SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
120};
121
122/*--*/
123
124/* Returns a comma-separated list of supported ciphers. */
125char *
126cipher_alg_list(char sep, int auth_only)
127{
128	char *tmp, *ret = NULL;
129	size_t nlen, rlen = 0;
130	const struct sshcipher *c;
131
132	for (c = ciphers; c->name != NULL; c++) {
133		if (c->number != SSH_CIPHER_SSH2)
134			continue;
135		if (auth_only && c->auth_len == 0)
136			continue;
137		if (ret != NULL)
138			ret[rlen++] = sep;
139		nlen = strlen(c->name);
140		if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
141			free(ret);
142			return NULL;
143		}
144		ret = tmp;
145		memcpy(ret + rlen, c->name, nlen + 1);
146		rlen += nlen;
147	}
148	return ret;
149}
150
151u_int
152cipher_blocksize(const struct sshcipher *c)
153{
154	return (c->block_size);
155}
156
157u_int
158cipher_keylen(const struct sshcipher *c)
159{
160	return (c->key_len);
161}
162
163u_int
164cipher_seclen(const struct sshcipher *c)
165{
166	if (strcmp("3des-cbc", c->name) == 0)
167		return 14;
168	return cipher_keylen(c);
169}
170
171u_int
172cipher_authlen(const struct sshcipher *c)
173{
174	return (c->auth_len);
175}
176
177u_int
178cipher_ivlen(const struct sshcipher *c)
179{
180	/*
181	 * Default is cipher block size, except for chacha20+poly1305 that
182	 * needs no IV. XXX make iv_len == -1 default?
183	 */
184	return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
185	    c->iv_len : c->block_size;
186}
187
188u_int
189cipher_get_number(const struct sshcipher *c)
190{
191	return (c->number);
192}
193
194u_int
195cipher_is_cbc(const struct sshcipher *c)
196{
197	return (c->flags & CFLAG_CBC) != 0;
198}
199
200u_int
201cipher_mask_ssh1(int client)
202{
203	u_int mask = 0;
204	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
205	mask |= 1 << SSH_CIPHER_BLOWFISH;
206	if (client) {
207		mask |= 1 << SSH_CIPHER_DES;
208	}
209	return mask;
210}
211
212const struct sshcipher *
213cipher_by_name(const char *name)
214{
215	const struct sshcipher *c;
216	for (c = ciphers; c->name != NULL; c++)
217		if (strcmp(c->name, name) == 0)
218			return c;
219	return NULL;
220}
221
222const struct sshcipher *
223cipher_by_number(int id)
224{
225	const struct sshcipher *c;
226	for (c = ciphers; c->name != NULL; c++)
227		if (c->number == id)
228			return c;
229	return NULL;
230}
231
232#define	CIPHER_SEP	","
233int
234ciphers_valid(const char *names)
235{
236	const struct sshcipher *c;
237	char *cipher_list, *cp;
238	char *p;
239
240	if (names == NULL || strcmp(names, "") == 0)
241		return 0;
242	if ((cipher_list = cp = strdup(names)) == NULL)
243		return 0;
244	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
245	    (p = strsep(&cp, CIPHER_SEP))) {
246		c = cipher_by_name(p);
247		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
248			free(cipher_list);
249			return 0;
250		}
251	}
252	free(cipher_list);
253	return 1;
254}
255
256/*
257 * Parses the name of the cipher.  Returns the number of the corresponding
258 * cipher, or -1 on error.
259 */
260
261int
262cipher_number(const char *name)
263{
264	const struct sshcipher *c;
265	if (name == NULL)
266		return -1;
267	for (c = ciphers; c->name != NULL; c++)
268		if (strcasecmp(c->name, name) == 0)
269			return c->number;
270	return -1;
271}
272
273char *
274cipher_name(int id)
275{
276	const struct sshcipher *c = cipher_by_number(id);
277	return (c==NULL) ? "<unknown>" : c->name;
278}
279
280const char *
281cipher_warning_message(const struct sshcipher_ctx *cc)
282{
283	if (cc == NULL || cc->cipher == NULL)
284		return NULL;
285	if (cc->cipher->number == SSH_CIPHER_DES)
286		return "use of DES is strongly discouraged due to "
287		    "cryptographic weaknesses";
288	return NULL;
289}
290
291int
292cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
293    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
294    int do_encrypt)
295{
296#ifdef WITH_OPENSSL
297	int ret = SSH_ERR_INTERNAL_ERROR;
298	const EVP_CIPHER *type;
299	int klen;
300	u_char *junk, *discard;
301
302	if (cipher->number == SSH_CIPHER_DES) {
303		if (keylen > 8)
304			keylen = 8;
305	}
306#endif
307	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
308	cc->encrypt = do_encrypt;
309
310	if (keylen < cipher->key_len ||
311	    (iv != NULL && ivlen < cipher_ivlen(cipher)))
312		return SSH_ERR_INVALID_ARGUMENT;
313
314	cc->cipher = cipher;
315	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
316		return chachapoly_init(&cc->cp_ctx, key, keylen);
317	}
318#ifndef WITH_OPENSSL
319	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
320		aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
321		aesctr_ivsetup(&cc->ac_ctx, iv);
322		return 0;
323	}
324	if ((cc->cipher->flags & CFLAG_NONE) != 0)
325		return 0;
326	return SSH_ERR_INVALID_ARGUMENT;
327#else
328	type = (*cipher->evptype)();
329	EVP_CIPHER_CTX_init(&cc->evp);
330	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
331	    (do_encrypt == CIPHER_ENCRYPT)) == 0) {
332		ret = SSH_ERR_LIBCRYPTO_ERROR;
333		goto bad;
334	}
335	if (cipher_authlen(cipher) &&
336	    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
337	    -1, (u_char *)iv)) {
338		ret = SSH_ERR_LIBCRYPTO_ERROR;
339		goto bad;
340	}
341	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
342	if (klen > 0 && keylen != (u_int)klen) {
343		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) {
344			ret = SSH_ERR_LIBCRYPTO_ERROR;
345			goto bad;
346		}
347	}
348	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
349		ret = SSH_ERR_LIBCRYPTO_ERROR;
350		goto bad;
351	}
352
353	if (cipher->discard_len > 0) {
354		if ((junk = malloc(cipher->discard_len)) == NULL ||
355		    (discard = malloc(cipher->discard_len)) == NULL) {
356			free(junk);
357			ret = SSH_ERR_ALLOC_FAIL;
358			goto bad;
359		}
360		ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len);
361		explicit_bzero(discard, cipher->discard_len);
362		free(junk);
363		free(discard);
364		if (ret != 1) {
365			ret = SSH_ERR_LIBCRYPTO_ERROR;
366 bad:
367			EVP_CIPHER_CTX_cleanup(&cc->evp);
368			return ret;
369		}
370	}
371#endif
372	return 0;
373}
374
375/*
376 * cipher_crypt() operates as following:
377 * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
378 * Theses bytes are treated as additional authenticated data for
379 * authenticated encryption modes.
380 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
381 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
382 * This tag is written on encryption and verified on decryption.
383 * Both 'aadlen' and 'authlen' can be set to 0.
384 */
385int
386cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
387   const u_char *src, u_int len, u_int aadlen, u_int authlen)
388{
389	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
390		return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
391		    len, aadlen, authlen, cc->encrypt);
392	}
393#ifndef WITH_OPENSSL
394	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
395		if (aadlen)
396			memcpy(dest, src, aadlen);
397		aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
398		    dest + aadlen, len);
399		return 0;
400	}
401	if ((cc->cipher->flags & CFLAG_NONE) != 0) {
402		memcpy(dest, src, aadlen + len);
403		return 0;
404	}
405	return SSH_ERR_INVALID_ARGUMENT;
406#else
407	if (authlen) {
408		u_char lastiv[1];
409
410		if (authlen != cipher_authlen(cc->cipher))
411			return SSH_ERR_INVALID_ARGUMENT;
412		/* increment IV */
413		if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
414		    1, lastiv))
415			return SSH_ERR_LIBCRYPTO_ERROR;
416		/* set tag on decyption */
417		if (!cc->encrypt &&
418		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
419		    authlen, (u_char *)src + aadlen + len))
420			return SSH_ERR_LIBCRYPTO_ERROR;
421	}
422	if (aadlen) {
423		if (authlen &&
424		    EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
425			return SSH_ERR_LIBCRYPTO_ERROR;
426		memcpy(dest, src, aadlen);
427	}
428	if (len % cc->cipher->block_size)
429		return SSH_ERR_INVALID_ARGUMENT;
430	if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
431	    len) < 0)
432		return SSH_ERR_LIBCRYPTO_ERROR;
433	if (authlen) {
434		/* compute tag (on encrypt) or verify tag (on decrypt) */
435		if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0)
436			return cc->encrypt ?
437			    SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;
438		if (cc->encrypt &&
439		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
440		    authlen, dest + aadlen + len))
441			return SSH_ERR_LIBCRYPTO_ERROR;
442	}
443	return 0;
444#endif
445}
446
447/* Extract the packet length, including any decryption necessary beforehand */
448int
449cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
450    const u_char *cp, u_int len)
451{
452	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
453		return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
454		    cp, len);
455	if (len < 4)
456		return SSH_ERR_MESSAGE_INCOMPLETE;
457	*plenp = get_u32(cp);
458	return 0;
459}
460
461int
462cipher_cleanup(struct sshcipher_ctx *cc)
463{
464	if (cc == NULL || cc->cipher == NULL)
465		return 0;
466	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
467		explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
468	else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
469		explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
470#ifdef WITH_OPENSSL
471	else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
472		return SSH_ERR_LIBCRYPTO_ERROR;
473#endif
474	return 0;
475}
476
477/*
478 * Selects the cipher, and keys if by computing the MD5 checksum of the
479 * passphrase and using the resulting 16 bytes as the key.
480 */
481int
482cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher,
483    const char *passphrase, int do_encrypt)
484{
485	u_char digest[16];
486	int r = SSH_ERR_INTERNAL_ERROR;
487
488	if ((r = ssh_digest_memory(SSH_DIGEST_MD5,
489	    passphrase, strlen(passphrase),
490	    digest, sizeof(digest))) != 0)
491		goto out;
492
493	r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
494 out:
495	explicit_bzero(digest, sizeof(digest));
496	return r;
497}
498
499/*
500 * Exports an IV from the sshcipher_ctx required to export the key
501 * state back from the unprivileged child to the privileged parent
502 * process.
503 */
504int
505cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
506{
507	const struct sshcipher *c = cc->cipher;
508	int ivlen = 0;
509
510	if (c->number == SSH_CIPHER_3DES)
511		ivlen = 24;
512	else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
513		ivlen = 0;
514	else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
515		ivlen = sizeof(cc->ac_ctx.ctr);
516#ifdef WITH_OPENSSL
517	else
518		ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
519#endif /* WITH_OPENSSL */
520	return (ivlen);
521}
522
523int
524cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
525{
526	const struct sshcipher *c = cc->cipher;
527#ifdef WITH_OPENSSL
528 	int evplen;
529#endif
530
531	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
532		if (len != 0)
533			return SSH_ERR_INVALID_ARGUMENT;
534		return 0;
535	}
536	if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
537		if (len != sizeof(cc->ac_ctx.ctr))
538			return SSH_ERR_INVALID_ARGUMENT;
539		memcpy(iv, cc->ac_ctx.ctr, len);
540		return 0;
541	}
542	if ((cc->cipher->flags & CFLAG_NONE) != 0)
543		return 0;
544
545	switch (c->number) {
546#ifdef WITH_OPENSSL
547	case SSH_CIPHER_SSH2:
548	case SSH_CIPHER_DES:
549	case SSH_CIPHER_BLOWFISH:
550		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
551		if (evplen == 0)
552			return 0;
553		else if (evplen < 0)
554			return SSH_ERR_LIBCRYPTO_ERROR;
555		if ((u_int)evplen != len)
556			return SSH_ERR_INVALID_ARGUMENT;
557#ifndef OPENSSL_HAVE_EVPCTR
558		if (c->evptype == evp_aes_128_ctr)
559			ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
560		else
561#endif
562		if (cipher_authlen(c)) {
563			if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
564			   len, iv))
565			       return SSH_ERR_LIBCRYPTO_ERROR;
566		} else
567			memcpy(iv, cc->evp.iv, len);
568		break;
569#endif
570#ifdef WITH_SSH1
571	case SSH_CIPHER_3DES:
572		return ssh1_3des_iv(&cc->evp, 0, iv, 24);
573#endif
574	default:
575		return SSH_ERR_INVALID_ARGUMENT;
576	}
577	return 0;
578}
579
580int
581cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
582{
583	const struct sshcipher *c = cc->cipher;
584#ifdef WITH_OPENSSL
585 	int evplen = 0;
586#endif
587
588	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
589		return 0;
590	if ((cc->cipher->flags & CFLAG_NONE) != 0)
591		return 0;
592
593	switch (c->number) {
594#ifdef WITH_OPENSSL
595	case SSH_CIPHER_SSH2:
596	case SSH_CIPHER_DES:
597	case SSH_CIPHER_BLOWFISH:
598		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
599		if (evplen <= 0)
600			return SSH_ERR_LIBCRYPTO_ERROR;
601		if (cipher_authlen(c)) {
602			/* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
603			if (!EVP_CIPHER_CTX_ctrl(&cc->evp,
604			    EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
605				return SSH_ERR_LIBCRYPTO_ERROR;
606		} else
607			memcpy(cc->evp.iv, iv, evplen);
608		break;
609#endif
610#ifdef WITH_SSH1
611	case SSH_CIPHER_3DES:
612		return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24);
613#endif
614	default:
615		return SSH_ERR_INVALID_ARGUMENT;
616	}
617	return 0;
618}
619
620#ifdef WITH_OPENSSL
621#define EVP_X_STATE(evp)	(evp).cipher_data
622#define EVP_X_STATE_LEN(evp)	(evp).cipher->ctx_size
623#endif
624
625int
626cipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)
627{
628#ifdef WITH_OPENSSL
629	const struct sshcipher *c = cc->cipher;
630	int plen = 0;
631
632	if (c->evptype == EVP_rc4) {
633		plen = EVP_X_STATE_LEN(cc->evp);
634		if (dat == NULL)
635			return (plen);
636		memcpy(dat, EVP_X_STATE(cc->evp), plen);
637	}
638	return (plen);
639#else
640	return 0;
641#endif
642}
643
644void
645cipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)
646{
647#ifdef WITH_OPENSSL
648	const struct sshcipher *c = cc->cipher;
649	int plen;
650
651	if (c->evptype == EVP_rc4) {
652		plen = EVP_X_STATE_LEN(cc->evp);
653		memcpy(EVP_X_STATE(cc->evp), dat, plen);
654	}
655#endif
656}
657