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