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