cipher.c revision 126277
157429Smarkm/*
257429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
357429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
457429Smarkm *                    All rights reserved
560576Skris *
665674Skris * As far as I am concerned, the code I have written for this software
765674Skris * can be used freely for any purpose.  Any derived versions of this
865674Skris * software must be clearly marked as such, and if the derived work is
965674Skris * incompatible with the protocol description in the RFC file, it must be
1065674Skris * called by a name other than "ssh" or "Secure Shell".
1160576Skris *
1265674Skris *
1365674Skris * Copyright (c) 1999 Niels Provos.  All rights reserved.
1492559Sdes * Copyright (c) 1999, 2000 Markus Friedl.  All rights reserved.
1565674Skris *
1665674Skris * Redistribution and use in source and binary forms, with or without
1765674Skris * modification, are permitted provided that the following conditions
1865674Skris * are met:
1965674Skris * 1. Redistributions of source code must retain the above copyright
2065674Skris *    notice, this list of conditions and the following disclaimer.
2165674Skris * 2. Redistributions in binary form must reproduce the above copyright
2265674Skris *    notice, this list of conditions and the following disclaimer in the
2365674Skris *    documentation and/or other materials provided with the distribution.
2465674Skris *
2565674Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2665674Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2765674Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2865674Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2965674Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3065674Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3165674Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3265674Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3365674Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3465674Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3557429Smarkm */
3657429Smarkm
3757429Smarkm#include "includes.h"
38126277SdesRCSID("$OpenBSD: cipher.c,v 1.68 2004/01/23 19:26:33 hshoexer Exp $");
3957429Smarkm
4060576Skris#include "xmalloc.h"
4176262Sgreen#include "log.h"
4276262Sgreen#include "cipher.h"
4357429Smarkm
4457464Sgreen#include <openssl/md5.h>
4598684Sdes
4698941Sdes#if OPENSSL_VERSION_NUMBER < 0x00906000L
4798941Sdes#define SSH_OLD_EVP
4898941Sdes#define EVP_CIPHER_CTX_get_app_data(e)          ((e)->app_data)
4998941Sdes#endif
5098941Sdes
5198684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L
52124211Sdesextern const EVP_CIPHER *evp_rijndael(void);
53124211Sdesextern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
5498684Sdes#endif
55126277Sdes
56126277Sdes#if !defined(EVP_CTRL_SET_ACSS_MODE)
57126277Sdes# if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
58126277Sdesextern const EVP_CIPHER *evp_acss(void);
59126277Sdes#  define EVP_acss evp_acss
60126277Sdes#  define EVP_CTRL_SET_ACSS_MODE xxx	/* used below */
61126277Sdes# else
62126277Sdes#  define EVP_acss NULL /* Don't try to support ACSS on older OpenSSL */
63126277Sdes# endif /* (OPENSSL_VERSION_NUMBER >= 0x00906000L) */
64126277Sdes#endif /* !defined(EVP_CTRL_SET_ACSS_MODE) */
65126277Sdes
66124211Sdesextern const EVP_CIPHER *evp_ssh1_bf(void);
67124211Sdesextern const EVP_CIPHER *evp_ssh1_3des(void);
68124211Sdesextern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
69124211Sdesextern const EVP_CIPHER *evp_aes_128_ctr(void);
70124211Sdesextern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
7157429Smarkm
7292559Sdesstruct Cipher {
7392559Sdes	char	*name;
7492559Sdes	int	number;		/* for ssh1 only */
7592559Sdes	u_int	block_size;
7692559Sdes	u_int	key_len;
7798684Sdes	const EVP_CIPHER	*(*evptype)(void);
7892559Sdes} ciphers[] = {
7992559Sdes	{ "none", 		SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
8092559Sdes	{ "des", 		SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
8192559Sdes	{ "3des", 		SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
8292559Sdes	{ "blowfish", 		SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
8369591Sgreen
8492559Sdes	{ "3des-cbc", 		SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
8592559Sdes	{ "blowfish-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
8692559Sdes	{ "cast128-cbc", 	SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
8792559Sdes	{ "arcfour", 		SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
8898684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L
8992559Sdes	{ "aes128-cbc", 	SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
9092559Sdes	{ "aes192-cbc", 	SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
9192559Sdes	{ "aes256-cbc", 	SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
9298684Sdes	{ "rijndael-cbc@lysator.liu.se",
9398684Sdes				SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
9498684Sdes#else
9598684Sdes	{ "aes128-cbc",		SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc },
9698684Sdes	{ "aes192-cbc",		SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc },
9798684Sdes	{ "aes256-cbc",		SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
9898684Sdes	{ "rijndael-cbc@lysator.liu.se",
9998684Sdes				SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
10098684Sdes#endif
101126277Sdes#if OPENSSL_VERSION_NUMBER >= 0x00905000L
102124211Sdes	{ "aes128-ctr", 	SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
103124211Sdes	{ "aes192-ctr", 	SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
104124211Sdes	{ "aes256-ctr", 	SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
105124211Sdes#endif
106126277Sdes#if defined(EVP_CTRL_SET_ACSS_MODE)
107126277Sdes	{ "acss@openssh.org",	SSH_CIPHER_SSH2, 16, 5, EVP_acss },
108126277Sdes#endif
10992559Sdes	{ NULL,			SSH_CIPHER_ILLEGAL, 0, 0, NULL }
11092559Sdes};
11169591Sgreen
11292559Sdes/*--*/
11357429Smarkm
11498684Sdesu_int
115126277Sdescipher_blocksize(const Cipher *c)
11657429Smarkm{
11792559Sdes	return (c->block_size);
11857429Smarkm}
11999063Sdes
12098684Sdesu_int
121126277Sdescipher_keylen(const Cipher *c)
12269591Sgreen{
12392559Sdes	return (c->key_len);
12469591Sgreen}
12599063Sdes
12698684Sdesu_int
127126277Sdescipher_get_number(const Cipher *c)
12898684Sdes{
12998684Sdes	return (c->number);
13098684Sdes}
13169591Sgreen
13276262Sgreenu_int
13369591Sgreencipher_mask_ssh1(int client)
13457429Smarkm{
13576262Sgreen	u_int mask = 0;
13692559Sdes	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
13757429Smarkm	mask |= 1 << SSH_CIPHER_BLOWFISH;
13869591Sgreen	if (client) {
13969591Sgreen		mask |= 1 << SSH_CIPHER_DES;
14069591Sgreen	}
14157429Smarkm	return mask;
14257429Smarkm}
14369591Sgreen
14469591SgreenCipher *
14569591Sgreencipher_by_name(const char *name)
14660576Skris{
14769591Sgreen	Cipher *c;
14869591Sgreen	for (c = ciphers; c->name != NULL; c++)
14969591Sgreen		if (strcasecmp(c->name, name) == 0)
15069591Sgreen			return c;
15169591Sgreen	return NULL;
15260576Skris}
15357429Smarkm
15469591SgreenCipher *
15569591Sgreencipher_by_number(int id)
15657429Smarkm{
15769591Sgreen	Cipher *c;
15869591Sgreen	for (c = ciphers; c->name != NULL; c++)
15969591Sgreen		if (c->number == id)
16069591Sgreen			return c;
16169591Sgreen	return NULL;
16257429Smarkm}
16357429Smarkm
16460576Skris#define	CIPHER_SEP	","
16560576Skrisint
16660576Skrisciphers_valid(const char *names)
16760576Skris{
16869591Sgreen	Cipher *c;
16965674Skris	char *ciphers, *cp;
17060576Skris	char *p;
17160576Skris
17261212Skris	if (names == NULL || strcmp(names, "") == 0)
17360576Skris		return 0;
17465674Skris	ciphers = cp = xstrdup(names);
17569591Sgreen	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
17692559Sdes	    (p = strsep(&cp, CIPHER_SEP))) {
17769591Sgreen		c = cipher_by_name(p);
17869591Sgreen		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
17969591Sgreen			debug("bad cipher %s [%s]", p, names);
18060576Skris			xfree(ciphers);
18160576Skris			return 0;
18269591Sgreen		} else {
18369591Sgreen			debug3("cipher ok: %s [%s]", p, names);
18460576Skris		}
18560576Skris	}
18669591Sgreen	debug3("ciphers ok: [%s]", names);
18760576Skris	xfree(ciphers);
18860576Skris	return 1;
18960576Skris}
19060576Skris
19157429Smarkm/*
19257429Smarkm * Parses the name of the cipher.  Returns the number of the corresponding
19357429Smarkm * cipher, or -1 on error.
19457429Smarkm */
19557429Smarkm
19657429Smarkmint
19757429Smarkmcipher_number(const char *name)
19857429Smarkm{
19969591Sgreen	Cipher *c;
20061212Skris	if (name == NULL)
20161212Skris		return -1;
20269591Sgreen	c = cipher_by_name(name);
20369591Sgreen	return (c==NULL) ? -1 : c->number;
20457429Smarkm}
20557429Smarkm
20669591Sgreenchar *
20769591Sgreencipher_name(int id)
20857429Smarkm{
20969591Sgreen	Cipher *c = cipher_by_number(id);
21069591Sgreen	return (c==NULL) ? "<unknown>" : c->name;
21157429Smarkm}
21257429Smarkm
21360576Skrisvoid
21469591Sgreencipher_init(CipherContext *cc, Cipher *cipher,
21592559Sdes    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
21692559Sdes    int encrypt)
21757429Smarkm{
21892559Sdes	static int dowarn = 1;
21998941Sdes#ifdef SSH_OLD_EVP
22098941Sdes	EVP_CIPHER *type;
22198941Sdes#else
22292559Sdes	const EVP_CIPHER *type;
22398941Sdes#endif
22492559Sdes	int klen;
22592559Sdes
22692559Sdes	if (cipher->number == SSH_CIPHER_DES) {
22792559Sdes		if (dowarn) {
22892559Sdes			error("Warning: use of DES is strongly discouraged "
22992559Sdes			    "due to cryptographic weaknesses");
23092559Sdes			dowarn = 0;
23192559Sdes		}
23292559Sdes		if (keylen > 8)
23392559Sdes			keylen = 8;
23492559Sdes	}
23592559Sdes	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
23692559Sdes
23769591Sgreen	if (keylen < cipher->key_len)
23869591Sgreen		fatal("cipher_init: key length %d is insufficient for %s.",
23969591Sgreen		    keylen, cipher->name);
24069591Sgreen	if (iv != NULL && ivlen < cipher->block_size)
24169591Sgreen		fatal("cipher_init: iv length %d is insufficient for %s.",
24269591Sgreen		    ivlen, cipher->name);
24369591Sgreen	cc->cipher = cipher;
24492559Sdes
24592559Sdes	type = (*cipher->evptype)();
24692559Sdes
24792559Sdes	EVP_CIPHER_CTX_init(&cc->evp);
24898941Sdes#ifdef SSH_OLD_EVP
24998941Sdes	if (type->key_len > 0 && type->key_len != keylen) {
25098941Sdes		debug("cipher_init: set keylen (%d -> %d)",
25198941Sdes		    type->key_len, keylen);
25298941Sdes		type->key_len = keylen;
25398941Sdes	}
25498941Sdes	EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
25598941Sdes	    (encrypt == CIPHER_ENCRYPT));
25698941Sdes#else
25792559Sdes	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
25892559Sdes	    (encrypt == CIPHER_ENCRYPT)) == 0)
25992559Sdes		fatal("cipher_init: EVP_CipherInit failed for %s",
26092559Sdes		    cipher->name);
26192559Sdes	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
26292559Sdes	if (klen > 0 && keylen != klen) {
263113911Sdes		debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
26492559Sdes		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
26592559Sdes			fatal("cipher_init: set keylen failed (%d -> %d)",
26692559Sdes			    klen, keylen);
26792559Sdes	}
26892559Sdes	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
26992559Sdes		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
27092559Sdes		    cipher->name);
27198941Sdes#endif
27257429Smarkm}
27357429Smarkm
27460576Skrisvoid
27592559Sdescipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
27660576Skris{
27769591Sgreen	if (len % cc->cipher->block_size)
27869591Sgreen		fatal("cipher_encrypt: bad plaintext length %d", len);
27998941Sdes#ifdef SSH_OLD_EVP
28098941Sdes	EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
28198941Sdes#else
28292559Sdes	if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
28392559Sdes		fatal("evp_crypt: EVP_Cipher failed");
28498941Sdes#endif
28560576Skris}
28660576Skris
28760576Skrisvoid
28892559Sdescipher_cleanup(CipherContext *cc)
28957429Smarkm{
29098941Sdes#ifdef SSH_OLD_EVP
29198941Sdes	EVP_CIPHER_CTX_cleanup(&cc->evp);
29298941Sdes#else
29392559Sdes	if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
29492559Sdes		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
29598941Sdes#endif
29657429Smarkm}
29757429Smarkm
29869591Sgreen/*
29969591Sgreen * Selects the cipher, and keys if by computing the MD5 checksum of the
30069591Sgreen * passphrase and using the resulting 16 bytes as the key.
30169591Sgreen */
30257429Smarkm
30360576Skrisvoid
30469591Sgreencipher_set_key_string(CipherContext *cc, Cipher *cipher,
30592559Sdes    const char *passphrase, int encrypt)
30657429Smarkm{
30769591Sgreen	MD5_CTX md;
30876262Sgreen	u_char digest[16];
30957429Smarkm
31069591Sgreen	MD5_Init(&md);
31169591Sgreen	MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
31269591Sgreen	MD5_Final(digest, &md);
31357429Smarkm
31492559Sdes	cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
31557429Smarkm
31669591Sgreen	memset(digest, 0, sizeof(digest));
31769591Sgreen	memset(&md, 0, sizeof(md));
31857429Smarkm}
31992559Sdes
32092559Sdes/*
32198684Sdes * Exports an IV from the CipherContext required to export the key
32298684Sdes * state back from the unprivileged child to the privileged parent
32398684Sdes * process.
32498684Sdes */
32598684Sdes
32698684Sdesint
327126277Sdescipher_get_keyiv_len(const CipherContext *cc)
32898684Sdes{
32998684Sdes	Cipher *c = cc->cipher;
33098684Sdes	int ivlen;
33198684Sdes
33298684Sdes	if (c->number == SSH_CIPHER_3DES)
33398684Sdes		ivlen = 24;
33498684Sdes	else
33598684Sdes		ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
33698684Sdes	return (ivlen);
33798684Sdes}
33898684Sdes
33998684Sdesvoid
34098684Sdescipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
34198684Sdes{
34298684Sdes	Cipher *c = cc->cipher;
34398684Sdes	int evplen;
34498684Sdes
34598684Sdes	switch (c->number) {
34698684Sdes	case SSH_CIPHER_SSH2:
34798684Sdes	case SSH_CIPHER_DES:
34898684Sdes	case SSH_CIPHER_BLOWFISH:
34998684Sdes		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
35098684Sdes		if (evplen == 0)
35198684Sdes			return;
35298684Sdes		if (evplen != len)
35398684Sdes			fatal("%s: wrong iv length %d != %d", __func__,
35498684Sdes			    evplen, len);
35598684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L
356124211Sdes		if (c->evptype == evp_rijndael)
357124211Sdes			ssh_rijndael_iv(&cc->evp, 0, iv, len);
358124211Sdes		else
35998684Sdes#endif
360124211Sdes		if (c->evptype == evp_aes_128_ctr)
361124211Sdes			ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
362124211Sdes		else
363124211Sdes			memcpy(iv, cc->evp.iv, len);
36498684Sdes		break;
365124211Sdes	case SSH_CIPHER_3DES:
366124211Sdes		ssh1_3des_iv(&cc->evp, 0, iv, 24);
367124211Sdes		break;
36898684Sdes	default:
36998684Sdes		fatal("%s: bad cipher %d", __func__, c->number);
37098684Sdes	}
37198684Sdes}
37298684Sdes
37398684Sdesvoid
37498684Sdescipher_set_keyiv(CipherContext *cc, u_char *iv)
37598684Sdes{
37698684Sdes	Cipher *c = cc->cipher;
37798684Sdes	int evplen = 0;
37898684Sdes
37998684Sdes	switch (c->number) {
38098684Sdes	case SSH_CIPHER_SSH2:
38198684Sdes	case SSH_CIPHER_DES:
38298684Sdes	case SSH_CIPHER_BLOWFISH:
38398684Sdes		evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
38498684Sdes		if (evplen == 0)
38598684Sdes			return;
38698684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L
387124211Sdes		if (c->evptype == evp_rijndael)
388124211Sdes			ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
389124211Sdes		else
39098684Sdes#endif
391124211Sdes		if (c->evptype == evp_aes_128_ctr)
392124211Sdes			ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
393124211Sdes		else
394124211Sdes			memcpy(cc->evp.iv, iv, evplen);
39598684Sdes		break;
396124211Sdes	case SSH_CIPHER_3DES:
397124211Sdes		ssh1_3des_iv(&cc->evp, 1, iv, 24);
398124211Sdes		break;
39998684Sdes	default:
40098684Sdes		fatal("%s: bad cipher %d", __func__, c->number);
40198684Sdes	}
40298684Sdes}
40398684Sdes
40498684Sdes#if OPENSSL_VERSION_NUMBER < 0x00907000L
40598684Sdes#define EVP_X_STATE(evp)	&(evp).c
40698684Sdes#define EVP_X_STATE_LEN(evp)	sizeof((evp).c)
40798684Sdes#else
40898684Sdes#define EVP_X_STATE(evp)	(evp).cipher_data
40998684Sdes#define EVP_X_STATE_LEN(evp)	(evp).cipher->ctx_size
41098684Sdes#endif
41198684Sdes
41298684Sdesint
413126277Sdescipher_get_keycontext(const CipherContext *cc, u_char *dat)
41498684Sdes{
41598684Sdes	Cipher *c = cc->cipher;
41698684Sdes	int plen = 0;
41798684Sdes
418126277Sdes	if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
41998684Sdes		plen = EVP_X_STATE_LEN(cc->evp);
42098684Sdes		if (dat == NULL)
42198684Sdes			return (plen);
42298684Sdes		memcpy(dat, EVP_X_STATE(cc->evp), plen);
42398684Sdes	}
42498684Sdes	return (plen);
42598684Sdes}
42698684Sdes
42798684Sdesvoid
42898684Sdescipher_set_keycontext(CipherContext *cc, u_char *dat)
42998684Sdes{
43098684Sdes	Cipher *c = cc->cipher;
43198684Sdes	int plen;
43298684Sdes
433126277Sdes	if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
43498684Sdes		plen = EVP_X_STATE_LEN(cc->evp);
43598684Sdes		memcpy(EVP_X_STATE(cc->evp), dat, plen);
43698684Sdes	}
43798684Sdes}
438