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