Exemple #1
0
/*
  Configure node_t myself and set up the local sockets (listen only)
*/
static bool setup_myself(void) {
	config_t *cfg;
	subnet_t *subnet;
	char *name, *hostname, *mode, *afname, *cipher, *digest, *type;
	char *fname = NULL;
	char *address = NULL;
	char *proxy = NULL;
	char *space;
	char *envp[5] = {NULL};
	struct addrinfo *ai, *aip, hint = {0};
	bool choice;
	int i, err;
	int replaywin_int;

	myself = new_node();
	myself->connection = new_connection();

	myself->hostname = xstrdup("MYSELF");
	myself->connection->hostname = xstrdup("MYSELF");

	myself->connection->options = 0;
	myself->connection->protocol_version = PROT_CURRENT;

	if(!(name = get_name())) {
		logger(LOG_ERR, "Name for tinc daemon required!");
		return false;
	}

	myself->name = name;
	myself->connection->name = xstrdup(name);
	xasprintf(&fname, "%s/hosts/%s", confbase, name);
	read_config_options(config_tree, name);
	read_config_file(config_tree, fname);
	free(fname);

	if(!read_rsa_private_key())
		return false;

	if(!get_config_string(lookup_config(config_tree, "Port"), &myport))
		myport = xstrdup("655");

	if(!atoi(myport)) {
		struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM);
		sockaddr_t sa;
		if(!ai || !ai->ai_addr)
			return false;
		free(myport);
		memcpy(&sa, ai->ai_addr, ai->ai_addrlen);
		sockaddr2str(&sa, NULL, &myport);
	}

	get_config_string(lookup_config(config_tree, "Proxy"), &proxy);
	if(proxy) {
		if((space = strchr(proxy, ' ')))
			*space++ = 0;

		if(!strcasecmp(proxy, "none")) {
			proxytype = PROXY_NONE;
		} else if(!strcasecmp(proxy, "socks4")) {
			proxytype = PROXY_SOCKS4;
		} else if(!strcasecmp(proxy, "socks4a")) {
			proxytype = PROXY_SOCKS4A;
		} else if(!strcasecmp(proxy, "socks5")) {
			proxytype = PROXY_SOCKS5;
		} else if(!strcasecmp(proxy, "http")) {
			proxytype = PROXY_HTTP;
		} else if(!strcasecmp(proxy, "exec")) {
			proxytype = PROXY_EXEC;
		} else {
			logger(LOG_ERR, "Unknown proxy type %s!", proxy);
			return false;
		}

		switch(proxytype) {
			case PROXY_NONE:
			default:
				break;

			case PROXY_EXEC:
				if(!space || !*space) {
					logger(LOG_ERR, "Argument expected for proxy type exec!");
					return false;
				}
				proxyhost =  xstrdup(space);
				break;

			case PROXY_SOCKS4:
			case PROXY_SOCKS4A:
			case PROXY_SOCKS5:
			case PROXY_HTTP:
				proxyhost = space;
				if(space && (space = strchr(space, ' ')))
					*space++ = 0, proxyport = space;
				if(space && (space = strchr(space, ' ')))
					*space++ = 0, proxyuser = space;
				if(space && (space = strchr(space, ' ')))
					*space++ = 0, proxypass = space;
				if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) {
					logger(LOG_ERR, "Host and port argument expected for proxy!");
					return false;
				}
				proxyhost = xstrdup(proxyhost);
				proxyport = xstrdup(proxyport);
				if(proxyuser && *proxyuser)
					proxyuser = xstrdup(proxyuser);
				if(proxypass && *proxypass)
					proxypass = xstrdup(proxypass);
				break;
		}

		free(proxy);
	}

	/* Read in all the subnets specified in the host configuration file */

	cfg = lookup_config(config_tree, "Subnet");

	while(cfg) {
		if(!get_config_subnet(cfg, &subnet))
			return false;

		subnet_add(myself, subnet);

		cfg = lookup_config_next(config_tree, cfg);
	}

	/* Check some options */

	if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
		myself->options |= OPTION_INDIRECT;

	if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
		myself->options |= OPTION_TCPONLY;

	if(myself->options & OPTION_TCPONLY)
		myself->options |= OPTION_INDIRECT;

	get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
	get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets);
	get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
	get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
	strictsubnets |= tunnelserver;

	if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
		if(!strcasecmp(mode, "router"))
			routing_mode = RMODE_ROUTER;
		else if(!strcasecmp(mode, "switch"))
			routing_mode = RMODE_SWITCH;
		else if(!strcasecmp(mode, "hub"))
			routing_mode = RMODE_HUB;
		else {
			logger(LOG_ERR, "Invalid routing mode!");
			return false;
		}
		free(mode);
	}

	if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) {
		if(!strcasecmp(mode, "off"))
			forwarding_mode = FMODE_OFF;
		else if(!strcasecmp(mode, "internal"))
			forwarding_mode = FMODE_INTERNAL;
		else if(!strcasecmp(mode, "kernel"))
			forwarding_mode = FMODE_KERNEL;
		else {
			logger(LOG_ERR, "Invalid forwarding mode!");
			return false;
		}
		free(mode);
	}

	choice = true;
	get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice);
	if(choice)
		myself->options |= OPTION_PMTU_DISCOVERY;

	choice = true;
	get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice);
	if(choice)
		myself->options |= OPTION_CLAMP_MSS;

	get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
	get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl);
	if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) {
		if(!strcasecmp(mode, "no"))
			broadcast_mode = BMODE_NONE;
		else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst"))
			broadcast_mode = BMODE_MST;
		else if(!strcasecmp(mode, "direct"))
			broadcast_mode = BMODE_DIRECT;
		else {
			logger(LOG_ERR, "Invalid broadcast mode!");
			return false;
		}
		free(mode);
	}

#if !defined(SOL_IP) || !defined(IP_TOS)
	if(priorityinheritance)
		logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
#endif

	if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
		macexpire = 600;

	if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
		if(maxtimeout <= 0) {
			logger(LOG_ERR, "Bogus maximum timeout!");
			return false;
		}
	} else
		maxtimeout = 900;

	if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
		if(udp_rcvbuf <= 0) {
			logger(LOG_ERR, "UDPRcvBuf cannot be negative!");
			return false;
		}
	}

	if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) {
		if(udp_sndbuf <= 0) {
			logger(LOG_ERR, "UDPSndBuf cannot be negative!");
			return false;
		}
	}

	if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) {
		if(replaywin_int < 0) {
			logger(LOG_ERR, "ReplayWindow cannot be negative!");
			return false;
		}
		replaywin = (unsigned)replaywin_int;
	}

	if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
		if(!strcasecmp(afname, "IPv4"))
			addressfamily = AF_INET;
		else if(!strcasecmp(afname, "IPv6"))
			addressfamily = AF_INET6;
		else if(!strcasecmp(afname, "any"))
			addressfamily = AF_UNSPEC;
		else {
			logger(LOG_ERR, "Invalid address family!");
			return false;
		}
		free(afname);
	}

	get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames);

	/* Generate packet encryption key */

	if(get_config_string
	   (lookup_config(config_tree, "Cipher"), &cipher)) {
		if(!strcasecmp(cipher, "none")) {
			myself->incipher = NULL;
		} else {
			myself->incipher = EVP_get_cipherbyname(cipher);

			if(!myself->incipher) {
				logger(LOG_ERR, "Unrecognized cipher type!");
				return false;
			}
		}
	} else
		myself->incipher = EVP_bf_cbc();

	if(myself->incipher)
		myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len;
	else
		myself->inkeylength = 1;

	myself->connection->outcipher = EVP_bf_ofb();

	if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
		keylifetime = 3600;

	keyexpires = now + keylifetime;
	
	/* Check if we want to use message authentication codes... */

	if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) {
		if(!strcasecmp(digest, "none")) {
			myself->indigest = NULL;
		} else {
			myself->indigest = EVP_get_digestbyname(digest);

			if(!myself->indigest) {
				logger(LOG_ERR, "Unrecognized digest type!");
				return false;
			}
		}
	} else
		myself->indigest = EVP_sha1();

	myself->connection->outdigest = EVP_sha1();

	if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) {
		if(myself->indigest) {
			if(myself->inmaclength > myself->indigest->md_size) {
				logger(LOG_ERR, "MAC length exceeds size of digest!");
				return false;
			} else if(myself->inmaclength < 0) {
				logger(LOG_ERR, "Bogus MAC length!");
				return false;
			}
		}
	} else
		myself->inmaclength = 4;

	myself->connection->outmaclength = 0;

	/* Compression */

	if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) {
		if(myself->incompression < 0 || myself->incompression > 11) {
			logger(LOG_ERR, "Bogus compression level!");
			return false;
		}
	} else
		myself->incompression = 0;

	myself->connection->outcompression = 0;

	/* Done */

	myself->nexthop = myself;
	myself->via = myself;
	myself->status.reachable = true;
	node_add(myself);

	graph();

	if(strictsubnets)
		load_all_subnets();

	/* Open device */

	devops = os_devops;

	if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
		if(!strcasecmp(type, "dummy"))
			devops = dummy_devops;
		else if(!strcasecmp(type, "raw_socket"))
			devops = raw_socket_devops;
		else if(!strcasecmp(type, "multicast"))
			devops = multicast_devops;
#ifdef ENABLE_UML
		else if(!strcasecmp(type, "uml"))
			devops = uml_devops;
#endif
#ifdef ENABLE_VDE
		else if(!strcasecmp(type, "vde"))
			devops = vde_devops;
#endif
	}

	if(!devops.setup())
		return false;

	/* Run tinc-up script to further initialize the tap interface */
	xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
	xasprintf(&envp[1], "DEVICE=%s", device ? : "");
	xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
	xasprintf(&envp[3], "NAME=%s", myself->name);

	execute_script("tinc-up", envp);

	for(i = 0; i < 4; i++)
		free(envp[i]);

	/* Run subnet-up scripts for our own subnets */

	subnet_update(myself, NULL, true);

	/* Open sockets */

	if(!do_detach && getenv("LISTEN_FDS")) {
		sockaddr_t sa;
		socklen_t salen;

		listen_sockets = atoi(getenv("LISTEN_FDS"));
#ifdef HAVE_UNSETENV
		unsetenv("LISTEN_FDS");
#endif

		if(listen_sockets > MAXSOCKETS) {
			logger(LOG_ERR, "Too many listening sockets");
			return false;
		}

		for(i = 0; i < listen_sockets; i++) {
			salen = sizeof sa;
			if(getsockname(i + 3, &sa.sa, &salen) < 0) {
				logger(LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno));
				return false;
			}

			listen_socket[i].tcp = i + 3;

#ifdef FD_CLOEXEC
		        fcntl(i + 3, F_SETFD, FD_CLOEXEC);
#endif

			listen_socket[i].udp = setup_vpn_in_socket(&sa);
			if(listen_socket[i].udp < 0)
				return false;

			ifdebug(CONNECTIONS) {
				hostname = sockaddr2hostname(&sa);
				logger(LOG_NOTICE, "Listening on %s", hostname);
				free(hostname);
			}

			memcpy(&listen_socket[i].sa, &sa, salen);
		}
	} else {
Exemple #2
0
int libCryptoProcessorInit(TProcessingModule *ProcMod, const char *Args)
{
int result=FALSE;

#ifdef HAVE_LIBSSL
libCryptoProcessorData *Data;
EVP_CIPHER_CTX *ctx;
char *CipherList[]={"blowfish","rc2","rc4","rc5","des","desx","cast","idea","aes","aes-256",NULL};
int val;
char *Tempstr=NULL;

val=MatchTokenFromList(ProcMod->Name,CipherList,0);
if (val==-1) return(FALSE);
if (! libCryptoCipherAvailable(val)) return(FALSE);
Data=(libCryptoProcessorData *) calloc(1,sizeof(libCryptoProcessorData));

//Tempstr here holds the cipher name
InitialiseEncryptionComponents(Args, &Tempstr, &Data->InputVector, &Data->InputVectorLen, & Data->Key, &Data->KeyLen,&ProcMod->Flags);

if (StrLen(ProcMod->Name)==0) ProcMod->Name=CopyStr(ProcMod->Name,Tempstr);

switch(val)
{
/*
	case CI_NONE:
	Data->Cipher=EVP_enc_null();
	break;
*/

	case CI_BLOWFISH:
		#ifdef HAVE_EVP_BF_CBC
		Data->Cipher=EVP_bf_cbc();
		#endif
		break;

	case CI_RC2:
		#ifdef HAVE_EVP_RC2_CBC
		Data->Cipher=EVP_rc2_cbc();
		#endif
		break;

	case CI_RC4:
		#ifdef HAVE_EVP_RC4_CBC
		Data->Cipher=EVP_rc4();
		#endif
		break;

	case CI_RC5:
		#ifdef HAVE_EVP_RC5_32_12_16_CBC
		//Data->Cipher=EVP_rc5_32_12_16_cbc();
		#endif
		break;

	case CI_DES:
		#ifdef HAVE_EVP_DES_CBC
		Data->Cipher=EVP_des_cbc();
		#endif
		break;

	case CI_DESX:
		#ifdef HAVE_EVP_DESX_CBC
		Data->Cipher=EVP_desx_cbc();
		#endif
		break;

	case CI_CAST:
		#ifdef HAVE_EVP_CAST5_CBC
		Data->Cipher=EVP_cast5_cbc();
		#endif
		break;

	case CI_IDEA:
		#ifdef HAVE_EVP_IDEA_CBC
		Data->Cipher=EVP_idea_cbc();
		#endif
		break;

	case CI_AES:
		#ifdef HAVE_EVP_AES_128_CBC
		Data->Cipher=EVP_aes_128_cbc();
		#endif
		break;

	case CI_AES_256:
		#ifdef HAVE_EVP_AES_256_CBC
		Data->Cipher=EVP_aes_256_cbc();
		#endif
		break;
}


if (Data->Cipher)
{
Data->enc_ctx=(EVP_CIPHER_CTX *) calloc(1,sizeof(EVP_CIPHER_CTX));
Data->dec_ctx=(EVP_CIPHER_CTX *) calloc(1,sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(Data->enc_ctx);
EVP_CIPHER_CTX_init(Data->dec_ctx);
Data->BlockSize=EVP_CIPHER_block_size(Data->Cipher);

EVP_EncryptInit_ex(Data->enc_ctx,Data->Cipher,NULL,Data->Key,Data->InputVector);
EVP_DecryptInit_ex(Data->dec_ctx,Data->Cipher,NULL,Data->Key,Data->InputVector);

if (ProcMod->Flags & DPM_NOPAD_DATA) EVP_CIPHER_CTX_set_padding(Data->enc_ctx,FALSE);

ProcMod->Data=Data;
result=TRUE;

DataProcessorSetValue(ProcMod,"Cipher",Tempstr);
Tempstr=FormatStr(Tempstr,"%d",Data->BlockSize);
DataProcessorSetValue(ProcMod,"BlockSize",Tempstr);
}

DestroyString(Tempstr);
#endif
return(result);
}
Exemple #3
0
/*
 * Encrypt or decrypt buf, returning a pointer to the transformed data,
 * or NULL on error.
 * The returned data is the same size as the input data,
 * which means we must turn off cipher padding, and require that buflen
 * be a multiple of the cipher block size (8 for Blowfish).
 * To keep things simple, the return value is a malloc'd
 * buffer that is overwritten on each call.
 *
 * Ken Lalonde <*****@*****.**>, 2003
 */
char *
cipher(char *buf, int buflen, int do_encrypt)
{
	static EVP_CIPHER_CTX ctx;
	static char *out = NULL;	/* return value, grown as necessary */
	static int outlen = 0;
	static int init = 0, which, blocksize;
	int n;

	if (!init) {
		static const EVP_CIPHER *cipher;
		unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
		// Read key from $HOME/.ermt.key
		char *keyfile = ".ermt.key";
		unsigned char buf[128];
		FILE *fp;
		int i;

		openlog("ermt", LOG_PID, LOG_DAEMON);
		// Not needed: OpenSSL_add_all_algorithms();
		// Not needed: ERR_load_crypto_strings();
		cipher = EVP_bf_cbc();	// or: EVP_aes_{128,192,256}_cbc()
		// We want the ability to decrypt the output
		// using "openssl enc -d -kfile K -nopad -nosalt", which
		// means we must read the key file the same way
		// openssl does.  But be careful: if the key contains
		// \0 or \r or \n, the effective size will be reduced.
		if ((fp = fopen(keyfile, "r")) == NULL) {
			syslog(LOG_ERR, "Can't open key file %s: %m", keyfile);
			return NULL;
		}
		buf[0] = '\0';
		if (!fgets(buf, sizeof buf, fp)) {
			syslog(LOG_ERR, "Error reading key file %s: %m", keyfile);
			return NULL;
		}
		fclose(fp);
		i = strlen(buf);
		if ((i > 0) &&
			((buf[i-1] == '\n') || (buf[i-1] == '\r')))
			buf[--i]='\0';
		if ((i > 0) &&
			((buf[i-1] == '\n') || (buf[i-1] == '\r')))
			buf[--i]='\0';
		if (i < 1) {
			syslog(LOG_ERR, "zero length key");
			errno = EINVAL;
			return NULL;
		}
		EVP_BytesToKey(cipher, EVP_md5(), NULL,
			buf, strlen(buf), 1, key, iv);
		EVP_CIPHER_CTX_init(&ctx);
		EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, do_encrypt);
		EVP_CIPHER_CTX_set_padding(&ctx, 0);	// -nopad
		OPENSSL_cleanse(buf, sizeof buf);
		OPENSSL_cleanse(key, sizeof key);
		OPENSSL_cleanse(iv, sizeof iv);
		blocksize = EVP_CIPHER_CTX_block_size(&ctx);
		which = do_encrypt;
		init = 1;
	}
	if (which != do_encrypt) {
		syslog(LOG_ERR, "Cannot switch modes");
		errno = EINVAL;
		return NULL;
	}
	if ((buflen % blocksize) != 0) {
		syslog(LOG_ERR, "Buffer size is not a multiple of cipher block size");
		errno = EINVAL;
		return NULL;
	}
	if (outlen < buflen+blocksize) {
		outlen = (buflen+blocksize) * 2;
		out = realloc(out, outlen);
	}
	if (!EVP_CipherUpdate(&ctx, out, &n, buf, buflen)) {
		syslog(LOG_ERR, "EVP_CipherUpdate failed");
		errno = EINVAL;
		return NULL;
	}
	if (n != buflen) {
		syslog(LOG_ERR, "EVP_CipherUpdate: %d != %d", n, buflen);
		errno = EINVAL;
		return NULL;
	}
	// assert(ctx->buf_len == 0);
	return out;
}
Exemple #4
0
/*-
 * Copyright (c) 2005-2010 Pawel Jakub Dawidek <*****@*****.**>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#else
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <openssl/evp.h>
#define	_OpenSSL_
#endif
#include <geom/eli/g_eli.h>

#ifdef _KERNEL
MALLOC_DECLARE(M_ELI);

static int
g_eli_crypto_done(struct cryptop *crp)
{

	crp->crp_opaque = (void *)crp;
	wakeup(crp);
	return (0);
}

static int
g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
    const u_char *key, size_t keysize)
{
	struct cryptoini cri;
	struct cryptop *crp;
	struct cryptodesc *crd;
	uint64_t sid;
	u_char *p;
	int error;

	KASSERT(algo != CRYPTO_AES_XTS,
	    ("%s: CRYPTO_AES_XTS unexpected here", __func__));

	bzero(&cri, sizeof(cri));
	cri.cri_alg = algo;
	cri.cri_key = __DECONST(void *, key);
	cri.cri_klen = keysize;
	error = crypto_newsession(&sid, &cri, CRYPTOCAP_F_SOFTWARE);
	if (error != 0)
		return (error);
	p = malloc(sizeof(*crp) + sizeof(*crd), M_ELI, M_NOWAIT | M_ZERO);
	if (p == NULL) {
		crypto_freesession(sid);
		return (ENOMEM);
	}
	crp = (struct cryptop *)p;	p += sizeof(*crp);
	crd = (struct cryptodesc *)p;	p += sizeof(*crd);

	crd->crd_skip = 0;
	crd->crd_len = datasize;
	crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
	if (enc)
		crd->crd_flags |= CRD_F_ENCRYPT;
	crd->crd_alg = algo;
	crd->crd_key = __DECONST(void *, key);
	crd->crd_klen = keysize;
	bzero(crd->crd_iv, sizeof(crd->crd_iv));
	crd->crd_next = NULL;

	crp->crp_sid = sid;
	crp->crp_ilen = datasize;
	crp->crp_olen = datasize;
	crp->crp_opaque = NULL;
	crp->crp_callback = g_eli_crypto_done;
	crp->crp_buf = (void *)data;
	crp->crp_flags = CRYPTO_F_CBIFSYNC;
	crp->crp_desc = crd;

	error = crypto_dispatch(crp);
	if (error == 0) {
		while (crp->crp_opaque == NULL)
			tsleep(crp, PRIBIO, "geli", hz / 5);
		error = crp->crp_etype;
	}

	free(crp, M_ELI);
	crypto_freesession(sid);
	return (error);
}
#else	/* !_KERNEL */
static int
g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
    const u_char *key, size_t keysize)
{
	EVP_CIPHER_CTX ctx;
	const EVP_CIPHER *type;
	u_char iv[keysize];
	int outsize;

	assert(algo != CRYPTO_AES_XTS);

	switch (algo) {
	case CRYPTO_NULL_CBC:
		type = EVP_enc_null();
		break;
	case CRYPTO_AES_CBC:
		switch (keysize) {
		case 128:
			type = EVP_aes_128_cbc();
			break;
		case 192:
			type = EVP_aes_192_cbc();
			break;
		case 256:
			type = EVP_aes_256_cbc();
			break;
		default:
			return (EINVAL);
		}
		break;
	case CRYPTO_BLF_CBC:
		type = EVP_bf_cbc();
		break;
#ifndef OPENSSL_NO_CAMELLIA
	case CRYPTO_CAMELLIA_CBC:
		switch (keysize) {
		case 128:
			type = EVP_camellia_128_cbc();
			break;
		case 192:
			type = EVP_camellia_192_cbc();
			break;
		case 256:
			type = EVP_camellia_256_cbc();
			break;
		default:
			return (EINVAL);
		}
		break;
#endif
	case CRYPTO_3DES_CBC:
		type = EVP_des_ede3_cbc();
		break;
	default:
		return (EINVAL);
	}

	EVP_CIPHER_CTX_init(&ctx);

	EVP_CipherInit_ex(&ctx, type, NULL, NULL, NULL, enc);
	EVP_CIPHER_CTX_set_key_length(&ctx, keysize / 8);
	EVP_CIPHER_CTX_set_padding(&ctx, 0);
	bzero(iv, sizeof(iv));
	EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, enc);

	if (EVP_CipherUpdate(&ctx, data, &outsize, data, datasize) == 0) {
		EVP_CIPHER_CTX_cleanup(&ctx);
		return (EINVAL);
	}
	assert(outsize == (int)datasize);

	if (EVP_CipherFinal_ex(&ctx, data + outsize, &outsize) == 0) {
		EVP_CIPHER_CTX_cleanup(&ctx);
		return (EINVAL);
	}
	assert(outsize == 0);

	EVP_CIPHER_CTX_cleanup(&ctx);
	return (0);
}
Exemple #5
0
void
OpenSSL_add_all_ciphers(void)
{
#ifndef OPENSSL_NO_DES
	EVP_add_cipher(EVP_des_cfb());
	EVP_add_cipher(EVP_des_cfb1());
	EVP_add_cipher(EVP_des_cfb8());
	EVP_add_cipher(EVP_des_ede_cfb());
	EVP_add_cipher(EVP_des_ede3_cfb());
	EVP_add_cipher(EVP_des_ede3_cfb1());
	EVP_add_cipher(EVP_des_ede3_cfb8());

	EVP_add_cipher(EVP_des_ofb());
	EVP_add_cipher(EVP_des_ede_ofb());
	EVP_add_cipher(EVP_des_ede3_ofb());

	EVP_add_cipher(EVP_desx_cbc());
	EVP_add_cipher_alias(SN_desx_cbc, "DESX");
	EVP_add_cipher_alias(SN_desx_cbc, "desx");

	EVP_add_cipher(EVP_des_cbc());
	EVP_add_cipher_alias(SN_des_cbc, "DES");
	EVP_add_cipher_alias(SN_des_cbc, "des");
	EVP_add_cipher(EVP_des_ede_cbc());
	EVP_add_cipher(EVP_des_ede3_cbc());
	EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
	EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");

	EVP_add_cipher(EVP_des_ecb());
	EVP_add_cipher(EVP_des_ede());
	EVP_add_cipher(EVP_des_ede3());
#endif

#ifndef OPENSSL_NO_RC4
	EVP_add_cipher(EVP_rc4());
	EVP_add_cipher(EVP_rc4_40());
#ifndef OPENSSL_NO_MD5
	EVP_add_cipher(EVP_rc4_hmac_md5());
#endif
#endif

#ifndef OPENSSL_NO_IDEA
	EVP_add_cipher(EVP_idea_ecb());
	EVP_add_cipher(EVP_idea_cfb());
	EVP_add_cipher(EVP_idea_ofb());
	EVP_add_cipher(EVP_idea_cbc());
	EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
	EVP_add_cipher_alias(SN_idea_cbc, "idea");
#endif

#ifndef OPENSSL_NO_RC2
	EVP_add_cipher(EVP_rc2_ecb());
	EVP_add_cipher(EVP_rc2_cfb());
	EVP_add_cipher(EVP_rc2_ofb());
	EVP_add_cipher(EVP_rc2_cbc());
	EVP_add_cipher(EVP_rc2_40_cbc());
	EVP_add_cipher(EVP_rc2_64_cbc());
	EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
	EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
#endif

#ifndef OPENSSL_NO_BF
	EVP_add_cipher(EVP_bf_ecb());
	EVP_add_cipher(EVP_bf_cfb());
	EVP_add_cipher(EVP_bf_ofb());
	EVP_add_cipher(EVP_bf_cbc());
	EVP_add_cipher_alias(SN_bf_cbc, "BF");
	EVP_add_cipher_alias(SN_bf_cbc, "bf");
	EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
#endif

#ifndef OPENSSL_NO_CAST
	EVP_add_cipher(EVP_cast5_ecb());
	EVP_add_cipher(EVP_cast5_cfb());
	EVP_add_cipher(EVP_cast5_ofb());
	EVP_add_cipher(EVP_cast5_cbc());
	EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
	EVP_add_cipher_alias(SN_cast5_cbc, "cast");
	EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
	EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
#endif

#ifndef OPENSSL_NO_AES
	EVP_add_cipher(EVP_aes_128_ecb());
	EVP_add_cipher(EVP_aes_128_cbc());
	EVP_add_cipher(EVP_aes_128_cfb());
	EVP_add_cipher(EVP_aes_128_cfb1());
	EVP_add_cipher(EVP_aes_128_cfb8());
	EVP_add_cipher(EVP_aes_128_ofb());
	EVP_add_cipher(EVP_aes_128_ctr());
	EVP_add_cipher(EVP_aes_128_gcm());
	EVP_add_cipher(EVP_aes_128_xts());
	EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
	EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
	EVP_add_cipher(EVP_aes_192_ecb());
	EVP_add_cipher(EVP_aes_192_cbc());
	EVP_add_cipher(EVP_aes_192_cfb());
	EVP_add_cipher(EVP_aes_192_cfb1());
	EVP_add_cipher(EVP_aes_192_cfb8());
	EVP_add_cipher(EVP_aes_192_ofb());
	EVP_add_cipher(EVP_aes_192_ctr());
	EVP_add_cipher(EVP_aes_192_gcm());
	EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
	EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
	EVP_add_cipher(EVP_aes_256_ecb());
	EVP_add_cipher(EVP_aes_256_cbc());
	EVP_add_cipher(EVP_aes_256_cfb());
	EVP_add_cipher(EVP_aes_256_cfb1());
	EVP_add_cipher(EVP_aes_256_cfb8());
	EVP_add_cipher(EVP_aes_256_ofb());
	EVP_add_cipher(EVP_aes_256_ctr());
	EVP_add_cipher(EVP_aes_256_gcm());
	EVP_add_cipher(EVP_aes_256_xts());
	EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
	EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#endif
#endif

#ifndef OPENSSL_NO_CAMELLIA
	EVP_add_cipher(EVP_camellia_128_ecb());
	EVP_add_cipher(EVP_camellia_128_cbc());
	EVP_add_cipher(EVP_camellia_128_cfb());
	EVP_add_cipher(EVP_camellia_128_cfb1());
	EVP_add_cipher(EVP_camellia_128_cfb8());
	EVP_add_cipher(EVP_camellia_128_ofb());
	EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
	EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
	EVP_add_cipher(EVP_camellia_192_ecb());
	EVP_add_cipher(EVP_camellia_192_cbc());
	EVP_add_cipher(EVP_camellia_192_cfb());
	EVP_add_cipher(EVP_camellia_192_cfb1());
	EVP_add_cipher(EVP_camellia_192_cfb8());
	EVP_add_cipher(EVP_camellia_192_ofb());
	EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
	EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
	EVP_add_cipher(EVP_camellia_256_ecb());
	EVP_add_cipher(EVP_camellia_256_cbc());
	EVP_add_cipher(EVP_camellia_256_cfb());
	EVP_add_cipher(EVP_camellia_256_cfb1());
	EVP_add_cipher(EVP_camellia_256_cfb8());
	EVP_add_cipher(EVP_camellia_256_ofb());
	EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
	EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
#endif

#ifndef OPENSSL_NO_CHACHA
	EVP_add_cipher(EVP_chacha20());
#endif

#ifndef OPENSSL_NO_GOST
	EVP_add_cipher(EVP_gost2814789_ecb());
	EVP_add_cipher(EVP_gost2814789_cfb64());
	EVP_add_cipher(EVP_gost2814789_cnt());
#endif
}
void OpenSSL_add_all_ciphers(void)
{

#ifndef OPENSSL_NO_DES
    EVP_add_cipher(EVP_des_cfb());
    EVP_add_cipher(EVP_des_cfb1());
    EVP_add_cipher(EVP_des_cfb8());
    EVP_add_cipher(EVP_des_ede_cfb());
    EVP_add_cipher(EVP_des_ede3_cfb());
    EVP_add_cipher(EVP_des_ede3_cfb1());
    EVP_add_cipher(EVP_des_ede3_cfb8());

    EVP_add_cipher(EVP_des_ofb());
    EVP_add_cipher(EVP_des_ede_ofb());
    EVP_add_cipher(EVP_des_ede3_ofb());

    EVP_add_cipher(EVP_desx_cbc());
    EVP_add_cipher_alias(SN_desx_cbc, "DESX");
    EVP_add_cipher_alias(SN_desx_cbc, "desx");

    EVP_add_cipher(EVP_des_cbc());
    EVP_add_cipher_alias(SN_des_cbc, "DES");
    EVP_add_cipher_alias(SN_des_cbc, "des");
    EVP_add_cipher(EVP_des_ede_cbc());
    EVP_add_cipher(EVP_des_ede3_cbc());
    EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
    EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");

    EVP_add_cipher(EVP_des_ecb());
    EVP_add_cipher(EVP_des_ede());
    EVP_add_cipher(EVP_des_ede3());
#endif

#ifndef OPENSSL_NO_RC4
    EVP_add_cipher(EVP_rc4());
    EVP_add_cipher(EVP_rc4_40());
#endif

#ifndef OPENSSL_NO_IDEA
    EVP_add_cipher(EVP_idea_ecb());
    EVP_add_cipher(EVP_idea_cfb());
    EVP_add_cipher(EVP_idea_ofb());
    EVP_add_cipher(EVP_idea_cbc());
    EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
    EVP_add_cipher_alias(SN_idea_cbc, "idea");
#endif

#ifndef OPENSSL_NO_SEED
    EVP_add_cipher(EVP_seed_ecb());
    EVP_add_cipher(EVP_seed_cfb());
    EVP_add_cipher(EVP_seed_ofb());
    EVP_add_cipher(EVP_seed_cbc());
    EVP_add_cipher_alias(SN_seed_cbc, "SEED");
    EVP_add_cipher_alias(SN_seed_cbc, "seed");
#endif

#ifndef OPENSSL_NO_RC2
    EVP_add_cipher(EVP_rc2_ecb());
    EVP_add_cipher(EVP_rc2_cfb());
    EVP_add_cipher(EVP_rc2_ofb());
    EVP_add_cipher(EVP_rc2_cbc());
    EVP_add_cipher(EVP_rc2_40_cbc());
    EVP_add_cipher(EVP_rc2_64_cbc());
    EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
    EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
#endif

#ifndef OPENSSL_NO_BF
    EVP_add_cipher(EVP_bf_ecb());
    EVP_add_cipher(EVP_bf_cfb());
    EVP_add_cipher(EVP_bf_ofb());
    EVP_add_cipher(EVP_bf_cbc());
    EVP_add_cipher_alias(SN_bf_cbc, "BF");
    EVP_add_cipher_alias(SN_bf_cbc, "bf");
    EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
#endif

#ifndef OPENSSL_NO_CAST
    EVP_add_cipher(EVP_cast5_ecb());
    EVP_add_cipher(EVP_cast5_cfb());
    EVP_add_cipher(EVP_cast5_ofb());
    EVP_add_cipher(EVP_cast5_cbc());
    EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
    EVP_add_cipher_alias(SN_cast5_cbc, "cast");
    EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
    EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
#endif

#ifndef OPENSSL_NO_RC5
    EVP_add_cipher(EVP_rc5_32_12_16_ecb());
    EVP_add_cipher(EVP_rc5_32_12_16_cfb());
    EVP_add_cipher(EVP_rc5_32_12_16_ofb());
    EVP_add_cipher(EVP_rc5_32_12_16_cbc());
    EVP_add_cipher_alias(SN_rc5_cbc, "rc5");
    EVP_add_cipher_alias(SN_rc5_cbc, "RC5");
#endif

#ifndef OPENSSL_NO_AES
    EVP_add_cipher(EVP_aes_128_ecb());
    EVP_add_cipher(EVP_aes_128_cbc());
    EVP_add_cipher(EVP_aes_128_cfb());
    EVP_add_cipher(EVP_aes_128_cfb1());
    EVP_add_cipher(EVP_aes_128_cfb8());
    EVP_add_cipher(EVP_aes_128_ofb());
# if 0
    EVP_add_cipher(EVP_aes_128_ctr());
# endif
    EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
    EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
    EVP_add_cipher(EVP_aes_192_ecb());
    EVP_add_cipher(EVP_aes_192_cbc());
    EVP_add_cipher(EVP_aes_192_cfb());
    EVP_add_cipher(EVP_aes_192_cfb1());
    EVP_add_cipher(EVP_aes_192_cfb8());
    EVP_add_cipher(EVP_aes_192_ofb());
# if 0
    EVP_add_cipher(EVP_aes_192_ctr());
# endif
    EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
    EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
    EVP_add_cipher(EVP_aes_256_ecb());
    EVP_add_cipher(EVP_aes_256_cbc());
    EVP_add_cipher(EVP_aes_256_cfb());
    EVP_add_cipher(EVP_aes_256_cfb1());
    EVP_add_cipher(EVP_aes_256_cfb8());
    EVP_add_cipher(EVP_aes_256_ofb());
# if 0
    EVP_add_cipher(EVP_aes_256_ctr());
# endif
    EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
    EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
#endif

#ifndef OPENSSL_NO_CAMELLIA
    EVP_add_cipher(EVP_camellia_128_ecb());
    EVP_add_cipher(EVP_camellia_128_cbc());
    EVP_add_cipher(EVP_camellia_128_cfb());
    EVP_add_cipher(EVP_camellia_128_cfb1());
    EVP_add_cipher(EVP_camellia_128_cfb8());
    EVP_add_cipher(EVP_camellia_128_ofb());
    EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
    EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
    EVP_add_cipher(EVP_camellia_192_ecb());
    EVP_add_cipher(EVP_camellia_192_cbc());
    EVP_add_cipher(EVP_camellia_192_cfb());
    EVP_add_cipher(EVP_camellia_192_cfb1());
    EVP_add_cipher(EVP_camellia_192_cfb8());
    EVP_add_cipher(EVP_camellia_192_ofb());
    EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
    EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
    EVP_add_cipher(EVP_camellia_256_ecb());
    EVP_add_cipher(EVP_camellia_256_cbc());
    EVP_add_cipher(EVP_camellia_256_cfb());
    EVP_add_cipher(EVP_camellia_256_cfb1());
    EVP_add_cipher(EVP_camellia_256_cfb8());
    EVP_add_cipher(EVP_camellia_256_ofb());
    EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
    EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
#endif
}
Exemple #7
0
static int hb_EVP_CIPHER_ptr_to_id( const EVP_CIPHER * p )
{
   int n;

   if(      p == EVP_enc_null()            ) n = HB_EVP_CIPHER_ENC_NULL;
#ifndef OPENSSL_NO_DES
   else if( p == EVP_des_ecb()             ) n = HB_EVP_CIPHER_DES_ECB;
   else if( p == EVP_des_ede()             ) n = HB_EVP_CIPHER_DES_EDE;
   else if( p == EVP_des_ede3()            ) n = HB_EVP_CIPHER_DES_EDE3;
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
   else if( p == EVP_des_ede_ecb()         ) n = HB_EVP_CIPHER_DES_EDE_ECB;
   else if( p == EVP_des_ede3_ecb()        ) n = HB_EVP_CIPHER_DES_EDE3_ECB;
#endif
   else if( p == EVP_des_cfb()             ) n = HB_EVP_CIPHER_DES_CFB;
   else if( p == EVP_des_ede_cfb()         ) n = HB_EVP_CIPHER_DES_EDE_CFB;
   else if( p == EVP_des_ede3_cfb()        ) n = HB_EVP_CIPHER_DES_EDE3_CFB;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_des_cfb64()           ) n = HB_EVP_CIPHER_DES_CFB64;
   else if( p == EVP_des_cfb1()            ) n = HB_EVP_CIPHER_DES_CFB1;
   else if( p == EVP_des_cfb8()            ) n = HB_EVP_CIPHER_DES_CFB8;
   else if( p == EVP_des_ede_cfb64()       ) n = HB_EVP_CIPHER_DES_EDE_CFB64;
   else if( p == EVP_des_ede3_cfb64()      ) n = HB_EVP_CIPHER_DES_EDE3_CFB64;
   else if( p == EVP_des_ede3_cfb1()       ) n = HB_EVP_CIPHER_DES_EDE3_CFB1;
   else if( p == EVP_des_ede3_cfb8()       ) n = HB_EVP_CIPHER_DES_EDE3_CFB8;
#endif
   else if( p == EVP_des_ofb()             ) n = HB_EVP_CIPHER_DES_OFB;
   else if( p == EVP_des_ede_ofb()         ) n = HB_EVP_CIPHER_DES_EDE_OFB;
   else if( p == EVP_des_ede3_ofb()        ) n = HB_EVP_CIPHER_DES_EDE3_OFB;
   else if( p == EVP_des_cbc()             ) n = HB_EVP_CIPHER_DES_CBC;
   else if( p == EVP_des_ede_cbc()         ) n = HB_EVP_CIPHER_DES_EDE_CBC;
   else if( p == EVP_des_ede3_cbc()        ) n = HB_EVP_CIPHER_DES_EDE3_CBC;
   else if( p == EVP_desx_cbc()            ) n = HB_EVP_CIPHER_DESX_CBC;
#endif
#ifndef OPENSSL_NO_RC4
   else if( p == EVP_rc4()                 ) n = HB_EVP_CIPHER_RC4;
   else if( p == EVP_rc4_40()              ) n = HB_EVP_CIPHER_RC4_40;
#endif
#ifndef OPENSSL_NO_IDEA
   else if( p == EVP_idea_ecb()            ) n = HB_EVP_CIPHER_IDEA_ECB;
   else if( p == EVP_idea_cfb64()          ) n = HB_EVP_CIPHER_IDEA_CFB64;
   else if( p == EVP_idea_cfb()            ) n = HB_EVP_CIPHER_IDEA_CFB;
   else if( p == EVP_idea_ofb()            ) n = HB_EVP_CIPHER_IDEA_OFB;
   else if( p == EVP_idea_cbc()            ) n = HB_EVP_CIPHER_IDEA_CBC;
#endif
#ifndef OPENSSL_NO_RC2
   else if( p == EVP_rc2_ecb()             ) n = HB_EVP_CIPHER_RC2_ECB;
   else if( p == EVP_rc2_cbc()             ) n = HB_EVP_CIPHER_RC2_CBC;
   else if( p == EVP_rc2_40_cbc()          ) n = HB_EVP_CIPHER_RC2_40_CBC;
   else if( p == EVP_rc2_64_cbc()          ) n = HB_EVP_CIPHER_RC2_64_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_rc2_cfb64()           ) n = HB_EVP_CIPHER_RC2_CFB64;
#endif
   else if( p == EVP_rc2_cfb()             ) n = HB_EVP_CIPHER_RC2_CFB;
   else if( p == EVP_rc2_ofb()             ) n = HB_EVP_CIPHER_RC2_OFB;
#endif
#ifndef OPENSSL_NO_BF
   else if( p == EVP_bf_ecb()              ) n = HB_EVP_CIPHER_BF_ECB;
   else if( p == EVP_bf_cbc()              ) n = HB_EVP_CIPHER_BF_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_bf_cfb64()            ) n = HB_EVP_CIPHER_BF_CFB64;
#endif
   else if( p == EVP_bf_cfb()              ) n = HB_EVP_CIPHER_BF_CFB;
   else if( p == EVP_bf_ofb()              ) n = HB_EVP_CIPHER_BF_OFB;
#endif
#ifndef OPENSSL_NO_CAST
   else if( p == EVP_cast5_ecb()           ) n = HB_EVP_CIPHER_CAST5_ECB;
   else if( p == EVP_cast5_cbc()           ) n = HB_EVP_CIPHER_CAST5_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_cast5_cfb64()         ) n = HB_EVP_CIPHER_CAST5_CFB64;
#endif
   else if( p == EVP_cast5_cfb()           ) n = HB_EVP_CIPHER_CAST5_CFB;
   else if( p == EVP_cast5_ofb()           ) n = HB_EVP_CIPHER_CAST5_OFB;
#endif
#ifndef OPENSSL_NO_RC5
   else if( p == EVP_rc5_32_12_16_cbc()    ) n = HB_EVP_CIPHER_RC5_32_12_16_CBC;
   else if( p == EVP_rc5_32_12_16_ecb()    ) n = HB_EVP_CIPHER_RC5_32_12_16_ECB;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_rc5_32_12_16_cfb64()  ) n = HB_EVP_CIPHER_RC5_32_12_16_CFB64;
#endif
   else if( p == EVP_rc5_32_12_16_cfb()    ) n = HB_EVP_CIPHER_RC5_32_12_16_CFB;
   else if( p == EVP_rc5_32_12_16_ofb()    ) n = HB_EVP_CIPHER_RC5_32_12_16_OFB;
#endif
#ifndef OPENSSL_NO_AES
   else if( p == EVP_aes_128_ecb()         ) n = HB_EVP_CIPHER_AES_128_ECB;
   else if( p == EVP_aes_128_cbc()         ) n = HB_EVP_CIPHER_AES_128_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_aes_128_cfb1()        ) n = HB_EVP_CIPHER_AES_128_CFB1;
   else if( p == EVP_aes_128_cfb8()        ) n = HB_EVP_CIPHER_AES_128_CFB8;
   else if( p == EVP_aes_128_cfb128()      ) n = HB_EVP_CIPHER_AES_128_CFB128;
#endif
   else if( p == EVP_aes_128_cfb()         ) n = HB_EVP_CIPHER_AES_128_CFB;
   else if( p == EVP_aes_128_ofb()         ) n = HB_EVP_CIPHER_AES_128_OFB;
   else if( p == EVP_aes_192_ecb()         ) n = HB_EVP_CIPHER_AES_192_ECB;
   else if( p == EVP_aes_192_cbc()         ) n = HB_EVP_CIPHER_AES_192_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_aes_192_cfb1()        ) n = HB_EVP_CIPHER_AES_192_CFB1;
   else if( p == EVP_aes_192_cfb8()        ) n = HB_EVP_CIPHER_AES_192_CFB8;
   else if( p == EVP_aes_192_cfb128()      ) n = HB_EVP_CIPHER_AES_192_CFB128;
#endif
   else if( p == EVP_aes_192_cfb()         ) n = HB_EVP_CIPHER_AES_192_CFB;
   else if( p == EVP_aes_192_ofb()         ) n = HB_EVP_CIPHER_AES_192_OFB;
   else if( p == EVP_aes_256_ecb()         ) n = HB_EVP_CIPHER_AES_256_ECB;
   else if( p == EVP_aes_256_cbc()         ) n = HB_EVP_CIPHER_AES_256_CBC;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
   else if( p == EVP_aes_256_cfb1()        ) n = HB_EVP_CIPHER_AES_256_CFB1;
   else if( p == EVP_aes_256_cfb8()        ) n = HB_EVP_CIPHER_AES_256_CFB8;
   else if( p == EVP_aes_256_cfb128()      ) n = HB_EVP_CIPHER_AES_256_CFB128;
#endif
   else if( p == EVP_aes_256_cfb()         ) n = HB_EVP_CIPHER_AES_256_CFB;
   else if( p == EVP_aes_256_ofb()         ) n = HB_EVP_CIPHER_AES_256_OFB;
#endif
#ifndef OPENSSL_NO_CAMELLIA
   else if( p == EVP_camellia_128_ecb()    ) n = HB_EVP_CIPHER_CAMELLIA_128_ECB;
   else if( p == EVP_camellia_128_cbc()    ) n = HB_EVP_CIPHER_CAMELLIA_128_CBC;
   else if( p == EVP_camellia_128_cfb1()   ) n = HB_EVP_CIPHER_CAMELLIA_128_CFB1;
   else if( p == EVP_camellia_128_cfb8()   ) n = HB_EVP_CIPHER_CAMELLIA_128_CFB8;
   else if( p == EVP_camellia_128_cfb128() ) n = HB_EVP_CIPHER_CAMELLIA_128_CFB128;
   else if( p == EVP_camellia_128_cfb()    ) n = HB_EVP_CIPHER_CAMELLIA_128_CFB;
   else if( p == EVP_camellia_128_ofb()    ) n = HB_EVP_CIPHER_CAMELLIA_128_OFB;
   else if( p == EVP_camellia_192_ecb()    ) n = HB_EVP_CIPHER_CAMELLIA_192_ECB;
   else if( p == EVP_camellia_192_cbc()    ) n = HB_EVP_CIPHER_CAMELLIA_192_CBC;
   else if( p == EVP_camellia_192_cfb1()   ) n = HB_EVP_CIPHER_CAMELLIA_192_CFB1;
   else if( p == EVP_camellia_192_cfb8()   ) n = HB_EVP_CIPHER_CAMELLIA_192_CFB8;
   else if( p == EVP_camellia_192_cfb128() ) n = HB_EVP_CIPHER_CAMELLIA_192_CFB128;
   else if( p == EVP_camellia_192_cfb()    ) n = HB_EVP_CIPHER_CAMELLIA_192_CFB;
   else if( p == EVP_camellia_192_ofb()    ) n = HB_EVP_CIPHER_CAMELLIA_192_OFB;
   else if( p == EVP_camellia_256_ecb()    ) n = HB_EVP_CIPHER_CAMELLIA_256_ECB;
   else if( p == EVP_camellia_256_cbc()    ) n = HB_EVP_CIPHER_CAMELLIA_256_CBC;
   else if( p == EVP_camellia_256_cfb1()   ) n = HB_EVP_CIPHER_CAMELLIA_256_CFB1;
   else if( p == EVP_camellia_256_cfb8()   ) n = HB_EVP_CIPHER_CAMELLIA_256_CFB8;
   else if( p == EVP_camellia_256_cfb128() ) n = HB_EVP_CIPHER_CAMELLIA_256_CFB128;
   else if( p == EVP_camellia_256_cfb()    ) n = HB_EVP_CIPHER_CAMELLIA_256_CFB;
   else if( p == EVP_camellia_256_ofb()    ) n = HB_EVP_CIPHER_CAMELLIA_256_OFB;
#endif
#ifndef OPENSSL_NO_SEED
   else if( p == EVP_seed_ecb()            ) n = HB_EVP_CIPHER_SEED_ECB;
   else if( p == EVP_seed_cbc()            ) n = HB_EVP_CIPHER_SEED_CBC;
   else if( p == EVP_seed_cfb128()         ) n = HB_EVP_CIPHER_SEED_CFB128;
   else if( p == EVP_seed_cfb()            ) n = HB_EVP_CIPHER_SEED_CFB;
   else if( p == EVP_seed_ofb()            ) n = HB_EVP_CIPHER_SEED_OFB;
#endif
   else                                      n = HB_EVP_CIPHER_UNSUPPORTED;

   return n;
}
Exemple #8
0
const EVP_CIPHER * hb_EVP_CIPHER_par( int iParam )
{
   const EVP_CIPHER * p;

   if( HB_ISCHAR( iParam ) )
      return EVP_get_cipherbyname( hb_parc( iParam ) );

   switch( hb_parni( iParam ) )
   {
      case HB_EVP_CIPHER_ENC_NULL:             p = EVP_enc_null();            break;
#ifndef OPENSSL_NO_DES
      case HB_EVP_CIPHER_DES_ECB:              p = EVP_des_ecb();             break;
      case HB_EVP_CIPHER_DES_EDE:              p = EVP_des_ede();             break;
      case HB_EVP_CIPHER_DES_EDE3:             p = EVP_des_ede3();            break;
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
      case HB_EVP_CIPHER_DES_EDE_ECB:          p = EVP_des_ede_ecb();         break;
      case HB_EVP_CIPHER_DES_EDE3_ECB:         p = EVP_des_ede3_ecb();        break;
#endif
      case HB_EVP_CIPHER_DES_CFB:              p = EVP_des_cfb();             break;
      case HB_EVP_CIPHER_DES_EDE_CFB:          p = EVP_des_ede_cfb();         break;
      case HB_EVP_CIPHER_DES_EDE3_CFB:         p = EVP_des_ede3_cfb();        break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_DES_CFB1:             p = EVP_des_cfb1();            break;
      case HB_EVP_CIPHER_DES_CFB8:             p = EVP_des_cfb8();            break;
      case HB_EVP_CIPHER_DES_CFB64:            p = EVP_des_cfb64();           break;
      case HB_EVP_CIPHER_DES_EDE_CFB64:        p = EVP_des_ede_cfb64();       break;
      case HB_EVP_CIPHER_DES_EDE3_CFB1:        p = EVP_des_ede3_cfb1();       break;
      case HB_EVP_CIPHER_DES_EDE3_CFB8:        p = EVP_des_ede3_cfb8();       break;
      case HB_EVP_CIPHER_DES_EDE3_CFB64:       p = EVP_des_ede3_cfb64();      break;
#endif
      case HB_EVP_CIPHER_DES_OFB:              p = EVP_des_ofb();             break;
      case HB_EVP_CIPHER_DES_EDE_OFB:          p = EVP_des_ede_ofb();         break;
      case HB_EVP_CIPHER_DES_EDE3_OFB:         p = EVP_des_ede3_ofb();        break;
      case HB_EVP_CIPHER_DES_CBC:              p = EVP_des_cbc();             break;
      case HB_EVP_CIPHER_DES_EDE_CBC:          p = EVP_des_ede_cbc();         break;
      case HB_EVP_CIPHER_DES_EDE3_CBC:         p = EVP_des_ede3_cbc();        break;
      case HB_EVP_CIPHER_DESX_CBC:             p = EVP_desx_cbc();            break;
#endif
#ifndef OPENSSL_NO_RC4
      case HB_EVP_CIPHER_RC4:                  p = EVP_rc4();                 break;
      case HB_EVP_CIPHER_RC4_40:               p = EVP_rc4_40();              break;
#endif
#ifndef OPENSSL_NO_IDEA
      case HB_EVP_CIPHER_IDEA_ECB:             p = EVP_idea_ecb();            break;
      case HB_EVP_CIPHER_IDEA_CFB64:           p = EVP_idea_cfb64();          break;
      case HB_EVP_CIPHER_IDEA_CFB:             p = EVP_idea_cfb();            break;
      case HB_EVP_CIPHER_IDEA_OFB:             p = EVP_idea_ofb();            break;
      case HB_EVP_CIPHER_IDEA_CBC:             p = EVP_idea_cbc();            break;
#endif
#ifndef OPENSSL_NO_RC2
      case HB_EVP_CIPHER_RC2_ECB:              p = EVP_rc2_ecb();             break;
      case HB_EVP_CIPHER_RC2_CBC:              p = EVP_rc2_cbc();             break;
      case HB_EVP_CIPHER_RC2_40_CBC:           p = EVP_rc2_40_cbc();          break;
      case HB_EVP_CIPHER_RC2_64_CBC:           p = EVP_rc2_64_cbc();          break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_RC2_CFB64:            p = EVP_rc2_cfb64();           break;
#endif
      case HB_EVP_CIPHER_RC2_CFB:              p = EVP_rc2_cfb();             break;
      case HB_EVP_CIPHER_RC2_OFB:              p = EVP_rc2_ofb();             break;
#endif
#ifndef OPENSSL_NO_BF
      case HB_EVP_CIPHER_BF_ECB:               p = EVP_bf_ecb();              break;
      case HB_EVP_CIPHER_BF_CBC:               p = EVP_bf_cbc();              break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_BF_CFB64:             p = EVP_bf_cfb64();            break;
#endif
      case HB_EVP_CIPHER_BF_CFB:               p = EVP_bf_cfb();              break;
      case HB_EVP_CIPHER_BF_OFB:               p = EVP_bf_ofb();              break;
#endif
#ifndef OPENSSL_NO_CAST
      case HB_EVP_CIPHER_CAST5_ECB:            p = EVP_cast5_ecb();           break;
      case HB_EVP_CIPHER_CAST5_CBC:            p = EVP_cast5_cbc();           break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_CAST5_CFB64:          p = EVP_cast5_cfb64();         break;
#endif
      case HB_EVP_CIPHER_CAST5_CFB:            p = EVP_cast5_cfb();           break;
      case HB_EVP_CIPHER_CAST5_OFB:            p = EVP_cast5_ofb();           break;
#endif
#ifndef OPENSSL_NO_RC5
      case HB_EVP_CIPHER_RC5_32_12_16_CBC:     p = EVP_rc5_32_12_16_cbc();    break;
      case HB_EVP_CIPHER_RC5_32_12_16_ECB:     p = EVP_rc5_32_12_16_ecb();    break;
      case HB_EVP_CIPHER_RC5_32_12_16_CFB:     p = EVP_rc5_32_12_16_cfb();    break;
      case HB_EVP_CIPHER_RC5_32_12_16_OFB:     p = EVP_rc5_32_12_16_ofb();    break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_RC5_32_12_16_CFB64:   p = EVP_rc5_32_12_16_cfb64();  break;
#endif
#endif
#ifndef OPENSSL_NO_AES
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
      case HB_EVP_CIPHER_AES_128_GCM:          p = EVP_aes_128_gcm();         break;
#endif
      case HB_EVP_CIPHER_AES_128_ECB:          p = EVP_aes_128_ecb();         break;
      case HB_EVP_CIPHER_AES_128_CBC:          p = EVP_aes_128_cbc();         break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_AES_128_CFB1:         p = EVP_aes_128_cfb1();        break;
      case HB_EVP_CIPHER_AES_128_CFB8:         p = EVP_aes_128_cfb8();        break;
      case HB_EVP_CIPHER_AES_128_CFB128:       p = EVP_aes_128_cfb128();      break;
#endif
      case HB_EVP_CIPHER_AES_128_CFB:          p = EVP_aes_128_cfb();         break;
      case HB_EVP_CIPHER_AES_128_OFB:          p = EVP_aes_128_ofb();         break;
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
      case HB_EVP_CIPHER_AES_192_GCM:          p = EVP_aes_192_gcm();         break;
#endif
      case HB_EVP_CIPHER_AES_192_ECB:          p = EVP_aes_192_ecb();         break;
      case HB_EVP_CIPHER_AES_192_CBC:          p = EVP_aes_192_cbc();         break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_AES_192_CFB1:         p = EVP_aes_192_cfb1();        break;
      case HB_EVP_CIPHER_AES_192_CFB8:         p = EVP_aes_192_cfb8();        break;
      case HB_EVP_CIPHER_AES_192_CFB128:       p = EVP_aes_192_cfb128();      break;
#endif
      case HB_EVP_CIPHER_AES_192_CFB:          p = EVP_aes_192_cfb();         break;
      case HB_EVP_CIPHER_AES_192_OFB:          p = EVP_aes_192_ofb();         break;
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
      case HB_EVP_CIPHER_AES_256_GCM:          p = EVP_aes_256_gcm();         break;
#endif
      case HB_EVP_CIPHER_AES_256_ECB:          p = EVP_aes_256_ecb();         break;
      case HB_EVP_CIPHER_AES_256_CBC:          p = EVP_aes_256_cbc();         break;
#if OPENSSL_VERSION_NUMBER >= 0x00907050L
      case HB_EVP_CIPHER_AES_256_CFB1:         p = EVP_aes_256_cfb1();        break;
      case HB_EVP_CIPHER_AES_256_CFB8:         p = EVP_aes_256_cfb8();        break;
      case HB_EVP_CIPHER_AES_256_CFB128:       p = EVP_aes_256_cfb128();      break;
#endif
      case HB_EVP_CIPHER_AES_256_CFB:          p = EVP_aes_256_cfb();         break;
      case HB_EVP_CIPHER_AES_256_OFB:          p = EVP_aes_256_ofb();         break;
#endif
#ifndef OPENSSL_NO_CAMELLIA
      case HB_EVP_CIPHER_CAMELLIA_128_ECB:     p = EVP_camellia_128_ecb();    break;
      case HB_EVP_CIPHER_CAMELLIA_128_CBC:     p = EVP_camellia_128_cbc();    break;
      case HB_EVP_CIPHER_CAMELLIA_128_CFB1:    p = EVP_camellia_128_cfb1();   break;
      case HB_EVP_CIPHER_CAMELLIA_128_CFB8:    p = EVP_camellia_128_cfb8();   break;
      case HB_EVP_CIPHER_CAMELLIA_128_CFB128:  p = EVP_camellia_128_cfb128(); break;
      case HB_EVP_CIPHER_CAMELLIA_128_CFB:     p = EVP_camellia_128_cfb();    break;
      case HB_EVP_CIPHER_CAMELLIA_128_OFB:     p = EVP_camellia_128_ofb();    break;
      case HB_EVP_CIPHER_CAMELLIA_192_ECB:     p = EVP_camellia_192_ecb();    break;
      case HB_EVP_CIPHER_CAMELLIA_192_CBC:     p = EVP_camellia_192_cbc();    break;
      case HB_EVP_CIPHER_CAMELLIA_192_CFB1:    p = EVP_camellia_192_cfb1();   break;
      case HB_EVP_CIPHER_CAMELLIA_192_CFB8:    p = EVP_camellia_192_cfb8();   break;
      case HB_EVP_CIPHER_CAMELLIA_192_CFB128:  p = EVP_camellia_192_cfb128(); break;
      case HB_EVP_CIPHER_CAMELLIA_192_CFB:     p = EVP_camellia_192_cfb();    break;
      case HB_EVP_CIPHER_CAMELLIA_192_OFB:     p = EVP_camellia_192_ofb();    break;
      case HB_EVP_CIPHER_CAMELLIA_256_ECB:     p = EVP_camellia_256_ecb();    break;
      case HB_EVP_CIPHER_CAMELLIA_256_CBC:     p = EVP_camellia_256_cbc();    break;
      case HB_EVP_CIPHER_CAMELLIA_256_CFB1:    p = EVP_camellia_256_cfb1();   break;
      case HB_EVP_CIPHER_CAMELLIA_256_CFB8:    p = EVP_camellia_256_cfb8();   break;
      case HB_EVP_CIPHER_CAMELLIA_256_CFB128:  p = EVP_camellia_256_cfb128(); break;
      case HB_EVP_CIPHER_CAMELLIA_256_CFB:     p = EVP_camellia_256_cfb();    break;
      case HB_EVP_CIPHER_CAMELLIA_256_OFB:     p = EVP_camellia_256_ofb();    break;
#endif
#ifndef OPENSSL_NO_SEED
      case HB_EVP_CIPHER_SEED_ECB:             p = EVP_seed_ecb();            break;
      case HB_EVP_CIPHER_SEED_CBC:             p = EVP_seed_cbc();            break;
      case HB_EVP_CIPHER_SEED_CFB128:          p = EVP_seed_cfb128();         break;
      case HB_EVP_CIPHER_SEED_CFB:             p = EVP_seed_cfb();            break;
      case HB_EVP_CIPHER_SEED_OFB:             p = EVP_seed_ofb();            break;
#endif
      default:                                 p = NULL;
   }

   return p;
}
Exemple #9
0
/*
  Configure node_t myself and set up the local sockets (listen only)
*/
static bool setup_myself(void) {
	config_t *cfg;
	subnet_t *subnet;
	char *name, *hostname, *mode, *afname, *cipher, *digest, *type;
	char *fname = NULL;
	char *address = NULL;
	char *envp[5];
	struct addrinfo *ai, *aip, hint = {0};
	bool choice;
	int i, err;
	int replaywin_int;

	myself = new_node();
	myself->connection = new_connection();

	myself->hostname = xstrdup("MYSELF");
	myself->connection->hostname = xstrdup("MYSELF");

	myself->connection->options = 0;
	myself->connection->protocol_version = PROT_CURRENT;

	if(!get_config_string(lookup_config(config_tree, "Name"), &name)) {	/* Not acceptable */
		logger(LOG_ERR, "Name for tinc daemon required!");
		return false;
	}

	if(!check_id(name)) {
		logger(LOG_ERR, "Invalid name for myself!");
		free(name);
		return false;
	}

	myself->name = name;
	myself->connection->name = xstrdup(name);
	xasprintf(&fname, "%s/hosts/%s", confbase, name);
	read_config_options(config_tree, name);
	read_config_file(config_tree, fname);
	free(fname);

	if(!read_rsa_private_key())
		return false;

	if(!get_config_string(lookup_config(config_tree, "Port"), &myport))
		myport = xstrdup("655");

	if(!atoi(myport)) {
		struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM);
		sockaddr_t sa;
		if(!ai || !ai->ai_addr)
			return false;
		free(myport);
		memcpy(&sa, ai->ai_addr, ai->ai_addrlen);
		sockaddr2str(&sa, NULL, &myport);
	}

	/* Read in all the subnets specified in the host configuration file */

	cfg = lookup_config(config_tree, "Subnet");

	while(cfg) {
		if(!get_config_subnet(cfg, &subnet))
			return false;

		subnet_add(myself, subnet);

		cfg = lookup_config_next(config_tree, cfg);
	}

	/* Check some options */

	if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
		myself->options |= OPTION_INDIRECT;

	if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
		myself->options |= OPTION_TCPONLY;

	if(myself->options & OPTION_TCPONLY)
		myself->options |= OPTION_INDIRECT;

	get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
	get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets);
	get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
	strictsubnets |= tunnelserver;

	if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
		if(!strcasecmp(mode, "router"))
			routing_mode = RMODE_ROUTER;
		else if(!strcasecmp(mode, "switch"))
			routing_mode = RMODE_SWITCH;
		else if(!strcasecmp(mode, "hub"))
			routing_mode = RMODE_HUB;
		else {
			logger(LOG_ERR, "Invalid routing mode!");
			return false;
		}
		free(mode);
	}

	if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) {
		if(!strcasecmp(mode, "off"))
			forwarding_mode = FMODE_OFF;
		else if(!strcasecmp(mode, "internal"))
			forwarding_mode = FMODE_INTERNAL;
		else if(!strcasecmp(mode, "kernel"))
			forwarding_mode = FMODE_KERNEL;
		else {
			logger(LOG_ERR, "Invalid forwarding mode!");
			return false;
		}
		free(mode);
	}

	choice = true;
	get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice);
	if(choice)
		myself->options |= OPTION_PMTU_DISCOVERY;

	choice = true;
	get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice);
	if(choice)
		myself->options |= OPTION_CLAMP_MSS;

	get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);

#if !defined(SOL_IP) || !defined(IP_TOS)
	if(priorityinheritance)
		logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
#endif

	if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
		macexpire = 600;

	if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
		if(maxtimeout <= 0) {
			logger(LOG_ERR, "Bogus maximum timeout!");
			return false;
		}
	} else
		maxtimeout = 900;

	if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
		if(udp_rcvbuf <= 0) {
			logger(LOG_ERR, "UDPRcvBuf cannot be negative!");
			return false;
		}
	}

	if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) {
		if(udp_sndbuf <= 0) {
			logger(LOG_ERR, "UDPSndBuf cannot be negative!");
			return false;
		}
	}

	if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) {
		if(replaywin_int < 0) {
			logger(LOG_ERR, "ReplayWindow cannot be negative!");
			return false;
		}
		replaywin = (unsigned)replaywin_int;
	}

	if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
		if(!strcasecmp(afname, "IPv4"))
			addressfamily = AF_INET;
		else if(!strcasecmp(afname, "IPv6"))
			addressfamily = AF_INET6;
		else if(!strcasecmp(afname, "any"))
			addressfamily = AF_UNSPEC;
		else {
			logger(LOG_ERR, "Invalid address family!");
			return false;
		}
		free(afname);
	}

	get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames);

	/* Generate packet encryption key */

	if(get_config_string
	   (lookup_config(config_tree, "Cipher"), &cipher)) {
		if(!strcasecmp(cipher, "none")) {
			myself->incipher = NULL;
		} else {
			myself->incipher = EVP_get_cipherbyname(cipher);

			if(!myself->incipher) {
				logger(LOG_ERR, "Unrecognized cipher type!");
				return false;
			}
		}
	} else
		myself->incipher = EVP_bf_cbc();

	if(myself->incipher)
		myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len;
	else
		myself->inkeylength = 1;

	myself->connection->outcipher = EVP_bf_ofb();

	if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
		keylifetime = 3600;

	keyexpires = now + keylifetime;
	
	/* Check if we want to use message authentication codes... */

	if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) {
		if(!strcasecmp(digest, "none")) {
			myself->indigest = NULL;
		} else {
			myself->indigest = EVP_get_digestbyname(digest);

			if(!myself->indigest) {
				logger(LOG_ERR, "Unrecognized digest type!");
				return false;
			}
		}
	} else
		myself->indigest = EVP_sha1();

	myself->connection->outdigest = EVP_sha1();

	if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) {
		if(myself->indigest) {
			if(myself->inmaclength > myself->indigest->md_size) {
				logger(LOG_ERR, "MAC length exceeds size of digest!");
				return false;
			} else if(myself->inmaclength < 0) {
				logger(LOG_ERR, "Bogus MAC length!");
				return false;
			}
		}
	} else
		myself->inmaclength = 4;

	myself->connection->outmaclength = 0;

	/* Compression */

	if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) {
		if(myself->incompression < 0 || myself->incompression > 11) {
			logger(LOG_ERR, "Bogus compression level!");
			return false;
		}
	} else
		myself->incompression = 0;

	myself->connection->outcompression = 0;

	/* Done */

	myself->nexthop = myself;
	myself->via = myself;
	myself->status.reachable = true;
	node_add(myself);

	graph();

	if(strictsubnets)
		load_all_subnets();

	/* Open device */

	if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
		if(!strcasecmp(type, "dummy"))
			devops = dummy_devops;
		else if(!strcasecmp(type, "raw_socket"))
			devops = raw_socket_devops;
#ifdef ENABLE_UML
		else if(!strcasecmp(type, "uml"))
			devops = uml_devops;
#endif
#ifdef ENABLE_VDE
		else if(!strcasecmp(type, "vde"))
			devops = vde_devops;
#endif
		else {
			logger(LOG_ERR, "Unknown device type %s!", type);
			return false;
		}
	} else {
		devops = os_devops;
	}

	if(!devops.setup())
		return false;

	/* Run tinc-up script to further initialize the tap interface */
	xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
	xasprintf(&envp[1], "DEVICE=%s", device ? : "");
	xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
	xasprintf(&envp[3], "NAME=%s", myself->name);
	envp[4] = NULL;

	execute_script("tinc-up", envp);

	for(i = 0; i < 5; i++)
		free(envp[i]);

	/* Run subnet-up scripts for our own subnets */

	subnet_update(myself, NULL, true);

	/* Open sockets */

	get_config_string(lookup_config(config_tree, "BindToAddress"), &address);

	hint.ai_family = addressfamily;
	hint.ai_socktype = SOCK_STREAM;
	hint.ai_protocol = IPPROTO_TCP;
	hint.ai_flags = AI_PASSIVE;

	err = getaddrinfo(address, myport, &hint, &ai);

	if(err || !ai) {
		logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo",
			   gai_strerror(err));
		return false;
	}

	listen_sockets = 0;

	for(aip = ai; aip; aip = aip->ai_next) {
		listen_socket[listen_sockets].tcp =
			setup_listen_socket((sockaddr_t *) aip->ai_addr);

		if(listen_socket[listen_sockets].tcp < 0)
			continue;

		listen_socket[listen_sockets].udp =
			setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);

		if(listen_socket[listen_sockets].udp < 0)
			continue;

		ifdebug(CONNECTIONS) {
			hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
			logger(LOG_NOTICE, "Listening on %s", hostname);
			free(hostname);
		}

		memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen);
		listen_sockets++;
	}

	freeaddrinfo(ai);

	if(listen_sockets)
		logger(LOG_NOTICE, "Ready");
	else {
		logger(LOG_ERR, "Unable to create any listening socket!");
		return false;
	}

	return true;
}