1264377Sdes/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */
2224638Sbrooks/* $FreeBSD$ */
357429Smarkm/*
457429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
557429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
657429Smarkm *                    All rights reserved
760576Skris *
865674Skris * As far as I am concerned, the code I have written for this software
965674Skris * can be used freely for any purpose.  Any derived versions of this
1065674Skris * software must be clearly marked as such, and if the derived work is
1165674Skris * incompatible with the protocol description in the RFC file, it must be
1265674Skris * called by a name other than "ssh" or "Secure Shell".
1360576Skris *
1465674Skris *
1565674Skris * Copyright (c) 1999 Niels Provos.  All rights reserved.
1692559Sdes * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
1765674Skris *
1865674Skris * Redistribution and use in source and binary forms, with or without
1965674Skris * modification, are permitted provided that the following conditions
2065674Skris * are met:
2165674Skris * 1. Redistributions of source code must retain the above copyright
2265674Skris *    notice, this list of conditions and the following disclaimer.
2365674Skris * 2. Redistributions in binary form must reproduce the above copyright
2465674Skris *    notice, this list of conditions and the following disclaimer in the
2565674Skris *    documentation and/or other materials provided with the distribution.
2665674Skris *
2765674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2865674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2965674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3065674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3165674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3265674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3365674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3465674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3565674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3665674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3757429Smarkm */
3857429Smarkm
3957429Smarkm#include "includes.h"
4057429Smarkm
41162856Sdes#include <sys/types.h>
42162856Sdes
43162856Sdes#include <string.h>
44162856Sdes#include <stdarg.h>
45262566Sdes#include <stdio.h>
46162856Sdes
4760576Skris#include "xmalloc.h"
4876262Sgreen#include "log.h"
49262566Sdes#include "misc.h"
5076262Sgreen#include "cipher.h"
51264377Sdes#include "buffer.h"
52264377Sdes#include "digest.h"
5357429Smarkm
54149753Sdes/* compatibility with old or broken OpenSSL versions */
55149753Sdes#include "openbsd-compat/openssl-compat.h"
5698941Sdes
57124211Sdesextern const EVP_CIPHER *evp_ssh1_bf(void);
58124211Sdesextern const EVP_CIPHER *evp_ssh1_3des(void);
59124211Sdesextern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
6057429Smarkm
6192559Sdesstruct Cipher {
6292559Sdes	char	*name;
6392559Sdes	int	number;		/* for ssh1 only */
6492559Sdes	u_int	block_size;
6592559Sdes	u_int	key_len;
66248619Sdes	u_int	iv_len;		/* defaults to block_size */
67248619Sdes	u_int	auth_len;
68149753Sdes	u_int	discard_len;
69262566Sdes	u_int	flags;
70262566Sdes#define CFLAG_CBC		(1<<0)
71262566Sdes#define CFLAG_CHACHAPOLY	(1<<1)
7298684Sdes	const EVP_CIPHER	*(*evptype)(void);
73255767Sdes};
74255767Sdes
75255767Sdesstatic const struct Cipher ciphers[] = {
76248619Sdes	{ "none",	SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
77248619Sdes	{ "des",	SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
78248619Sdes	{ "3des",	SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
79248619Sdes	{ "blowfish",	SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
8069591Sgreen
81248619Sdes	{ "3des-cbc",	SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
82248619Sdes	{ "blowfish-cbc",
83248619Sdes			SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
84248619Sdes	{ "cast128-cbc",
85248619Sdes			SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
86248619Sdes	{ "arcfour",	SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
87248619Sdes	{ "arcfour128",	SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
88248619Sdes	{ "arcfour256",	SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
89248619Sdes	{ "aes128-cbc",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
90248619Sdes	{ "aes192-cbc",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
91248619Sdes	{ "aes256-cbc",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
9298684Sdes	{ "rijndael-cbc@lysator.liu.se",
93248619Sdes			SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
94248619Sdes	{ "aes128-ctr",	SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
95248619Sdes	{ "aes192-ctr",	SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
96248619Sdes	{ "aes256-ctr",	SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
97248619Sdes#ifdef OPENSSL_HAVE_EVPGCM
98248619Sdes	{ "aes128-gcm@openssh.com",
99248619Sdes			SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
100248619Sdes	{ "aes256-gcm@openssh.com",
101248619Sdes			SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
10298684Sdes#endif
103262566Sdes	{ "chacha20-poly1305@openssh.com",
104262566Sdes			SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
105248619Sdes	{ NULL,		SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
10692559Sdes};
10769591Sgreen
10892559Sdes/*--*/
10957429Smarkm
110262566Sdes/* Returns a list of supported ciphers separated by the specified char. */
111255767Sdeschar *
112262566Sdescipher_alg_list(char sep, int auth_only)
113255767Sdes{
114255767Sdes	char *ret = NULL;
115255767Sdes	size_t nlen, rlen = 0;
116255767Sdes	const Cipher *c;
117255767Sdes
118255767Sdes	for (c = ciphers; c->name != NULL; c++) {
119255767Sdes		if (c->number != SSH_CIPHER_SSH2)
120255767Sdes			continue;
121262566Sdes		if (auth_only && c->auth_len == 0)
122262566Sdes			continue;
123255767Sdes		if (ret != NULL)
124262566Sdes			ret[rlen++] = sep;
125255767Sdes		nlen = strlen(c->name);
126255767Sdes		ret = xrealloc(ret, 1, rlen + nlen + 2);
127255767Sdes		memcpy(ret + rlen, c->name, nlen + 1);
128255767Sdes		rlen += nlen;
129255767Sdes	}
130255767Sdes	return ret;
131255767Sdes}
132255767Sdes
13398684Sdesu_int
134126277Sdescipher_blocksize(const Cipher *c)
13557429Smarkm{
13692559Sdes	return (c->block_size);
13757429Smarkm}
13899063Sdes
13998684Sdesu_int
140126277Sdescipher_keylen(const Cipher *c)
14169591Sgreen{
14292559Sdes	return (c->key_len);
14369591Sgreen}
14499063Sdes
14598684Sdesu_int
146262566Sdescipher_seclen(const Cipher *c)
147262566Sdes{
148262566Sdes	if (strcmp("3des-cbc", c->name) == 0)
149262566Sdes		return 14;
150262566Sdes	return cipher_keylen(c);
151262566Sdes}
152262566Sdes
153262566Sdesu_int
154248619Sdescipher_authlen(const Cipher *c)
155248619Sdes{
156248619Sdes	return (c->auth_len);
157248619Sdes}
158248619Sdes
159248619Sdesu_int
160248619Sdescipher_ivlen(const Cipher *c)
161248619Sdes{
162262566Sdes	/*
163262566Sdes	 * Default is cipher block size, except for chacha20+poly1305 that
164262566Sdes	 * needs no IV. XXX make iv_len == -1 default?
165262566Sdes	 */
166262566Sdes	return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
167262566Sdes	    c->iv_len : c->block_size;
168248619Sdes}
169248619Sdes
170248619Sdesu_int
171126277Sdescipher_get_number(const Cipher *c)
17298684Sdes{
17398684Sdes	return (c->number);
17498684Sdes}
17569591Sgreen
17676262Sgreenu_int
177192595Sdescipher_is_cbc(const Cipher *c)
178192595Sdes{
179262566Sdes	return (c->flags & CFLAG_CBC) != 0;
180192595Sdes}
181192595Sdes
182192595Sdesu_int
18369591Sgreencipher_mask_ssh1(int client)
18457429Smarkm{
18576262Sgreen	u_int mask = 0;
18692559Sdes	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
18757429Smarkm	mask |= 1 << SSH_CIPHER_BLOWFISH;
18869591Sgreen	if (client) {
18969591Sgreen		mask |= 1 << SSH_CIPHER_DES;
19069591Sgreen	}
19157429Smarkm	return mask;
19257429Smarkm}
19369591Sgreen
194255767Sdesconst Cipher *
19569591Sgreencipher_by_name(const char *name)
19660576Skris{
197255767Sdes	const Cipher *c;
19869591Sgreen	for (c = ciphers; c->name != NULL; c++)
199147005Sdes		if (strcmp(c->name, name) == 0)
20069591Sgreen			return c;
20169591Sgreen	return NULL;
20260576Skris}
20357429Smarkm
204255767Sdesconst Cipher *
20569591Sgreencipher_by_number(int id)
20657429Smarkm{
207255767Sdes	const Cipher *c;
20869591Sgreen	for (c = ciphers; c->name != NULL; c++)
20969591Sgreen		if (c->number == id)
21069591Sgreen			return c;
21169591Sgreen	return NULL;
21257429Smarkm}
21357429Smarkm
21460576Skris#define	CIPHER_SEP	","
21560576Skrisint
21660576Skrisciphers_valid(const char *names)
21760576Skris{
218255767Sdes	const Cipher *c;
219137019Sdes	char *cipher_list, *cp;
22060576Skris	char *p;
22160576Skris
22261212Skris	if (names == NULL || strcmp(names, "") == 0)
22360576Skris		return 0;
224137019Sdes	cipher_list = cp = xstrdup(names);
22569591Sgreen	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
22692559Sdes	    (p = strsep(&cp, CIPHER_SEP))) {
22769591Sgreen		c = cipher_by_name(p);
228224638Sbrooks#ifdef NONE_CIPHER_ENABLED
229224638Sbrooks		if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
230224638Sbrooks		    c->number != SSH_CIPHER_NONE)) {
231224638Sbrooks#else
232224638Sbrooks		if (c == NULL || (c->number != SSH_CIPHER_SSH2)) {
233224638Sbrooks#endif
23469591Sgreen			debug("bad cipher %s [%s]", p, names);
235255767Sdes			free(cipher_list);
23660576Skris			return 0;
23760576Skris		}
23860576Skris	}
23969591Sgreen	debug3("ciphers ok: [%s]", names);
240255767Sdes	free(cipher_list);
24160576Skris	return 1;
24260576Skris}
24360576Skris
24457429Smarkm/*
24557429Smarkm * Parses the name of the cipher.  Returns the number of the corresponding
24657429Smarkm * cipher, or -1 on error.
24757429Smarkm */
24857429Smarkm
24957429Smarkmint
25057429Smarkmcipher_number(const char *name)
25157429Smarkm{
252255767Sdes	const Cipher *c;
25361212Skris	if (name == NULL)
25461212Skris		return -1;
255147005Sdes	for (c = ciphers; c->name != NULL; c++)
256147005Sdes		if (strcasecmp(c->name, name) == 0)
257147005Sdes			return c->number;
258147005Sdes	return -1;
25957429Smarkm}
26057429Smarkm
26169591Sgreenchar *
26269591Sgreencipher_name(int id)
26357429Smarkm{
264255767Sdes	const Cipher *c = cipher_by_number(id);
26569591Sgreen	return (c==NULL) ? "<unknown>" : c->name;
26657429Smarkm}
26757429Smarkm
26860576Skrisvoid
269255767Sdescipher_init(CipherContext *cc, const Cipher *cipher,
27092559Sdes    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
271137019Sdes    int do_encrypt)
27257429Smarkm{
27392559Sdes	static int dowarn = 1;
27498941Sdes#ifdef SSH_OLD_EVP
27598941Sdes	EVP_CIPHER *type;
27698941Sdes#else
27792559Sdes	const EVP_CIPHER *type;
278149753Sdes	int klen;
27998941Sdes#endif
280149753Sdes	u_char *junk, *discard;
28192559Sdes
28292559Sdes	if (cipher->number == SSH_CIPHER_DES) {
28392559Sdes		if (dowarn) {
28492559Sdes			error("Warning: use of DES is strongly discouraged "
28592559Sdes			    "due to cryptographic weaknesses");
28692559Sdes			dowarn = 0;
28792559Sdes		}
28892559Sdes		if (keylen > 8)
28992559Sdes			keylen = 8;
29092559Sdes	}
29192559Sdes	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
292248619Sdes	cc->encrypt = do_encrypt;
29392559Sdes
29469591Sgreen	if (keylen < cipher->key_len)
29569591Sgreen		fatal("cipher_init: key length %d is insufficient for %s.",
29669591Sgreen		    keylen, cipher->name);
297248619Sdes	if (iv != NULL && ivlen < cipher_ivlen(cipher))
29869591Sgreen		fatal("cipher_init: iv length %d is insufficient for %s.",
29969591Sgreen		    ivlen, cipher->name);
30069591Sgreen	cc->cipher = cipher;
30192559Sdes
302262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
303262566Sdes		chachapoly_init(&cc->cp_ctx, key, keylen);
304262566Sdes		return;
305262566Sdes	}
30692559Sdes	type = (*cipher->evptype)();
30792559Sdes	EVP_CIPHER_CTX_init(&cc->evp);
30898941Sdes#ifdef SSH_OLD_EVP
30998941Sdes	if (type->key_len > 0 && type->key_len != keylen) {
31098941Sdes		debug("cipher_init: set keylen (%d -> %d)",
31198941Sdes		    type->key_len, keylen);
31298941Sdes		type->key_len = keylen;
31398941Sdes	}
31498941Sdes	EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
315137019Sdes	    (do_encrypt == CIPHER_ENCRYPT));
31698941Sdes#else
31792559Sdes	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
318137019Sdes	    (do_encrypt == CIPHER_ENCRYPT)) == 0)
31992559Sdes		fatal("cipher_init: EVP_CipherInit failed for %s",
32092559Sdes		    cipher->name);
321248619Sdes	if (cipher_authlen(cipher) &&
322248619Sdes	    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
323248619Sdes	    -1, (u_char *)iv))
324248619Sdes		fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s",
325248619Sdes		    cipher->name);
32692559Sdes	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
327149753Sdes	if (klen > 0 && keylen != (u_int)klen) {
328113911Sdes		debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
32992559Sdes		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
33092559Sdes			fatal("cipher_init: set keylen failed (%d -> %d)",
33192559Sdes			    klen, keylen);
33292559Sdes	}
33392559Sdes	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
33492559Sdes		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
33592559Sdes		    cipher->name);
33698941Sdes#endif
337149753Sdes
338149753Sdes	if (cipher->discard_len > 0) {
339149753Sdes		junk = xmalloc(cipher->discard_len);
340149753Sdes		discard = xmalloc(cipher->discard_len);
341149753Sdes		if (EVP_Cipher(&cc->evp, discard, junk,
342149753Sdes		    cipher->discard_len) == 0)
343149753Sdes			fatal("evp_crypt: EVP_Cipher failed during discard");
344264377Sdes		explicit_bzero(discard, cipher->discard_len);
345255767Sdes		free(junk);
346255767Sdes		free(discard);
347149753Sdes	}
34857429Smarkm}
34957429Smarkm
350248619Sdes/*
351248619Sdes * cipher_crypt() operates as following:
352248619Sdes * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
353248619Sdes * Theses bytes are treated as additional authenticated data for
354248619Sdes * authenticated encryption modes.
355248619Sdes * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
356248619Sdes * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
357248619Sdes * This tag is written on encryption and verified on decryption.
358248619Sdes * Both 'aadlen' and 'authlen' can be set to 0.
359262566Sdes * cipher_crypt() returns 0 on success and -1 if the decryption integrity
360262566Sdes * check fails.
361248619Sdes */
362262566Sdesint
363262566Sdescipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
364248619Sdes    u_int len, u_int aadlen, u_int authlen)
36560576Skris{
366262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
367262566Sdes		return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
368262566Sdes		    aadlen, authlen, cc->encrypt);
369248619Sdes	if (authlen) {
370248619Sdes		u_char lastiv[1];
371248619Sdes
372248619Sdes		if (authlen != cipher_authlen(cc->cipher))
373248619Sdes			fatal("%s: authlen mismatch %d", __func__, authlen);
374248619Sdes		/* increment IV */
375248619Sdes		if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
376248619Sdes		    1, lastiv))
377248619Sdes			fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
378248619Sdes		/* set tag on decyption */
379248619Sdes		if (!cc->encrypt &&
380248619Sdes		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
381248619Sdes		    authlen, (u_char *)src + aadlen + len))
382248619Sdes			fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__);
383248619Sdes	}
384248619Sdes	if (aadlen) {
385248619Sdes		if (authlen &&
386248619Sdes		    EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
387248619Sdes			fatal("%s: EVP_Cipher(aad) failed", __func__);
388248619Sdes		memcpy(dest, src, aadlen);
389248619Sdes	}
39069591Sgreen	if (len % cc->cipher->block_size)
391248619Sdes		fatal("%s: bad plaintext length %d", __func__, len);
392248619Sdes	if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
393248619Sdes	    len) < 0)
394248619Sdes		fatal("%s: EVP_Cipher failed", __func__);
395248619Sdes	if (authlen) {
396248619Sdes		/* compute tag (on encrypt) or verify tag (on decrypt) */
397248619Sdes		if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) {
398248619Sdes			if (cc->encrypt)
399248619Sdes				fatal("%s: EVP_Cipher(final) failed", __func__);
400248619Sdes			else
401262566Sdes				return -1;
402248619Sdes		}
403248619Sdes		if (cc->encrypt &&
404248619Sdes		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
405248619Sdes		    authlen, dest + aadlen + len))
406248619Sdes			fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
407248619Sdes	}
408262566Sdes	return 0;
40960576Skris}
41060576Skris
411262566Sdes/* Extract the packet length, including any decryption necessary beforehand */
412262566Sdesint
413262566Sdescipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
414262566Sdes    const u_char *cp, u_int len)
415262566Sdes{
416262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
417262566Sdes		return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
418262566Sdes		    cp, len);
419262566Sdes	if (len < 4)
420262566Sdes		return -1;
421262566Sdes	*plenp = get_u32(cp);
422262566Sdes	return 0;
423262566Sdes}
424262566Sdes
42560576Skrisvoid
42692559Sdescipher_cleanup(CipherContext *cc)
42757429Smarkm{
428262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
429264377Sdes		explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
430262566Sdes	else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
43192559Sdes		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
43257429Smarkm}
43357429Smarkm
43469591Sgreen/*
43569591Sgreen * Selects the cipher, and keys if by computing the MD5 checksum of the
43669591Sgreen * passphrase and using the resulting 16 bytes as the key.
43769591Sgreen */
43857429Smarkm
43960576Skrisvoid
440255767Sdescipher_set_key_string(CipherContext *cc, const Cipher *cipher,
441137019Sdes    const char *passphrase, int do_encrypt)
44257429Smarkm{
44376262Sgreen	u_char digest[16];
44457429Smarkm
445264377Sdes	if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase),
446264377Sdes	    digest, sizeof(digest)) < 0)
447264377Sdes		fatal("%s: md5 failed", __func__);
44857429Smarkm
449137019Sdes	cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
45057429Smarkm
451264377Sdes	explicit_bzero(digest, sizeof(digest));
45257429Smarkm}
45392559Sdes
45492559Sdes/*
45598684Sdes * Exports an IV from the CipherContext required to export the key
45698684Sdes * state back from the unprivileged child to the privileged parent
45798684Sdes * process.
45898684Sdes */
45998684Sdes
46098684Sdesint
461126277Sdescipher_get_keyiv_len(const CipherContext *cc)
46298684Sdes{
463255767Sdes	const Cipher *c = cc->cipher;
46498684Sdes	int ivlen;
46598684Sdes
46698684Sdes	if (c->number == SSH_CIPHER_3DES)
46798684Sdes		ivlen = 24;
468262566Sdes	else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
469262566Sdes		ivlen = 0;
47098684Sdes	else
47198684Sdes		ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
47298684Sdes	return (ivlen);
47398684Sdes}
47498684Sdes
47598684Sdesvoid
47698684Sdescipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
47798684Sdes{
478255767Sdes	const Cipher *c = cc->cipher;
47998684Sdes	int evplen;
48098684Sdes
481262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
482262566Sdes		if (len != 0)
483262566Sdes			fatal("%s: wrong iv length %d != %d", __func__, len, 0);
484262566Sdes		return;
485262566Sdes	}
486262566Sdes
48798684Sdes	switch (c->number) {
488224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
489224638Sbrooks	case SSH_CIPHER_NONE:
490224638Sbrooks#endif
49198684Sdes	case SSH_CIPHER_SSH2:
49298684Sdes	case SSH_CIPHER_DES:
49398684Sdes	case SSH_CIPHER_BLOWFISH:
49498684Sdes		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
495149753Sdes		if (evplen <= 0)
49698684Sdes			return;
497149753Sdes		if ((u_int)evplen != len)
49898684Sdes			fatal("%s: wrong iv length %d != %d", __func__,
49998684Sdes			    evplen, len);
500157019Sdes#ifdef USE_BUILTIN_RIJNDAEL
501124211Sdes		if (c->evptype == evp_rijndael)
502124211Sdes			ssh_rijndael_iv(&cc->evp, 0, iv, len);
503124211Sdes		else
50498684Sdes#endif
505248619Sdes#ifndef OPENSSL_HAVE_EVPCTR
506124211Sdes		if (c->evptype == evp_aes_128_ctr)
507124211Sdes			ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
508124211Sdes		else
509248619Sdes#endif
510248619Sdes		memcpy(iv, cc->evp.iv, len);
51198684Sdes		break;
512124211Sdes	case SSH_CIPHER_3DES:
513124211Sdes		ssh1_3des_iv(&cc->evp, 0, iv, 24);
514124211Sdes		break;
51598684Sdes	default:
51698684Sdes		fatal("%s: bad cipher %d", __func__, c->number);
51798684Sdes	}
51898684Sdes}
51998684Sdes
52098684Sdesvoid
52198684Sdescipher_set_keyiv(CipherContext *cc, u_char *iv)
52298684Sdes{
523255767Sdes	const Cipher *c = cc->cipher;
52498684Sdes	int evplen = 0;
52598684Sdes
526262566Sdes	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
527262566Sdes		return;
528262566Sdes
52998684Sdes	switch (c->number) {
530224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
531224638Sbrooks	case SSH_CIPHER_NONE:
532224638Sbrooks#endif
53398684Sdes	case SSH_CIPHER_SSH2:
53498684Sdes	case SSH_CIPHER_DES:
53598684Sdes	case SSH_CIPHER_BLOWFISH:
53698684Sdes		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
53798684Sdes		if (evplen == 0)
53898684Sdes			return;
539157019Sdes#ifdef USE_BUILTIN_RIJNDAEL
540124211Sdes		if (c->evptype == evp_rijndael)
541124211Sdes			ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
542124211Sdes		else
54398684Sdes#endif
544248619Sdes#ifndef OPENSSL_HAVE_EVPCTR
545124211Sdes		if (c->evptype == evp_aes_128_ctr)
546124211Sdes			ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
547124211Sdes		else
548248619Sdes#endif
549248619Sdes		memcpy(cc->evp.iv, iv, evplen);
55098684Sdes		break;
551124211Sdes	case SSH_CIPHER_3DES:
552124211Sdes		ssh1_3des_iv(&cc->evp, 1, iv, 24);
553124211Sdes		break;
55498684Sdes	default:
55598684Sdes		fatal("%s: bad cipher %d", __func__, c->number);
55698684Sdes	}
55798684Sdes}
55898684Sdes
55998684Sdesint
560126277Sdescipher_get_keycontext(const CipherContext *cc, u_char *dat)
56198684Sdes{
562255767Sdes	const Cipher *c = cc->cipher;
56398684Sdes	int plen = 0;
56498684Sdes
565248619Sdes	if (c->evptype == EVP_rc4) {
56698684Sdes		plen = EVP_X_STATE_LEN(cc->evp);
56798684Sdes		if (dat == NULL)
56898684Sdes			return (plen);
56998684Sdes		memcpy(dat, EVP_X_STATE(cc->evp), plen);
57098684Sdes	}
57198684Sdes	return (plen);
57298684Sdes}
57398684Sdes
57498684Sdesvoid
57598684Sdescipher_set_keycontext(CipherContext *cc, u_char *dat)
57698684Sdes{
577255767Sdes	const Cipher *c = cc->cipher;
57898684Sdes	int plen;
57998684Sdes
580248619Sdes	if (c->evptype == EVP_rc4) {
58198684Sdes		plen = EVP_X_STATE_LEN(cc->evp);
58298684Sdes		memcpy(EVP_X_STATE(cc->evp), dat, plen);
58398684Sdes	}
58498684Sdes}
585