Exemple #1
0
struct net_device *
ipsec_mast_get_device(int vifnum)
{
	int ovifnum = vifnum;

	if(vifnum > IPSECDEV_OFFSET) {
		return ipsec_tunnel_get_device(vifnum-IPSECDEV_OFFSET);
	} else {
		struct net_device *nd;
		
		if(vifnum >= MASTTRANSPORT_OFFSET) {
			vifnum -= MASTTRANSPORT_OFFSET;
		}

		if(vifnum <= mastdevices_max) {
			nd = mastdevices[vifnum];

			if(nd) ipsec_dev_hold(nd);
			return nd;
		} else {
			KLIPS_ERROR(debug_tunnel,
				    "no such vif %d (ovif=%d)\n", vifnum, ovifnum);
			return NULL;
		}
	}
}
Exemple #2
0
/*
 * 	main encrypt service entry point
 * 	called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
 * 	ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
 */
int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
			  int ilen, __u8 * iv, int encrypt)
{
	int ret;
	struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
	int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
			  debug_tunnel : debug_rcv);

	KLIPS_PRINT(debug_flag,
		    "klips_debug:ipsec_alg_esp_encrypt: "
		    "entering with encalg=%d, ixt_e=%p\n",
		    sa_p->ips_encalg, ixt_e);
	if (ixt_e == NULL) {
	  KLIPS_ERROR(debug_flag,
		      "klips_debug:ipsec_alg_esp_encrypt: "
		      "NULL ipsec_alg_enc object\n");
		return -1;
	}
	KLIPS_PRINT(debug_flag,
		    "klips_debug:ipsec_alg_esp_encrypt: "
		    "calling cbc_encrypt encalg=%d "
		    "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
			sa_p->ips_encalg, 
			sa_p->ips_key_e, idat, ilen, iv, encrypt);
	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
				     ilen, iv, encrypt);
	KLIPS_PRINT(debug_flag,
		    "klips_debug:ipsec_alg_esp_encrypt: "
		    "returned ret=%d\n",
		    ret);
	return ret;
}
Exemple #3
0
static IPsecSAref_t
ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
{
	IPsecSAref_t SAref;

	KLIPS_PRINT(debug_xform,
		    "ipsec_SAref_alloc: "
		    "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
		    ipsec_sadb.refFreeListHead,
		    ipsec_sadb.refFreeListCont,
		    ipsec_sadb.refFreeListTail,
		    IPSEC_SA_REF_FREELIST_NUM_ENTRIES);

	if(ipsec_sadb.refFreeListHead == IPSEC_SAREF_NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_SAref_alloc: "
			    "FreeList empty, recycling...\n");
		*error = ipsec_SAref_recycle();
		if(*error) {
			return IPSEC_SAREF_NULL;
		}
	}

	SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
	if(SAref == IPSEC_SAREF_NULL) {
		KLIPS_ERROR(debug_xform,
			    "ipsec_SAref_alloc: "
			    "unexpected error, refFreeListHead = %d points to invalid entry.\n",
			    ipsec_sadb.refFreeListHead);
		*error = -ESPIPE;
		return IPSEC_SAREF_NULL;
	}

	KLIPS_PRINT(debug_xform,
		    "ipsec_SAref_alloc: "
		    "allocating SAref=%d, table=%u, entry=%u of %u.\n",
		    SAref,
		    IPsecSAref2table(SAref),
		    IPsecSAref2entry(SAref),
		    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
	
	ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
	ipsec_sadb.refFreeListHead++;
	if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_SAref_alloc: "
			    "last FreeList entry allocated, resetting list head to empty.\n");
		ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
	}

	return SAref;
}
Exemple #4
0
int
pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
	int error = 0;
	struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;

	KLIPS_PRINT(debug_pfkey,
		    "pfkey_x_satype_process: .\n");

	if(!extr || !extr->ips) {
		KLIPS_PRINT(debug_pfkey,
			    "pfkey_x_satype_process: "
			    "extr or extr->ips is NULL, fatal\n");
		SENDERR(EINVAL);
	}

	if(extr->ips2 == NULL) {
		extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
	}
	if(extr->ips2 == NULL) {
		SENDERR(-error);
	}
	if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
		KLIPS_ERROR(debug_pfkey,
			    "pfkey_x_satype_process: "
			    "proto lookup from satype=%d failed.\n",
			    pfkey_x_satype->sadb_x_satype_satype);
		SENDERR(EINVAL);
	}
	KLIPS_PRINT(debug_pfkey,
		    "pfkey_x_satype_process: "
		    "protocol==%d decoded from satype==%d(%s).\n",
		    extr->ips2->ips_said.proto,
		    pfkey_x_satype->sadb_x_satype_satype,
		    satype2name(pfkey_x_satype->sadb_x_satype_satype));
	
errlab:
	return error;
}
Exemple #5
0
/*
 *	This function assumes it is being called from dev_queue_xmit()
 *	and that skb is filled properly by that function.
 */
int
ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct ipsec_xmit_state *ixs;
	IPsecSAref_t SAref;

	KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: skb=%p\n", skb);
	if(skb == NULL) {
		printk("ipsec_mast_start_xmit: "
			"passed NULL\n");
		return 0;
	}
		
	ixs = ipsec_xmit_state_new(dev);
	if(ixs == NULL)
		return NETDEV_TX_BUSY;

	ixs->dev = dev;
	ixs->skb = skb;
	SAref = 0;
#ifdef NETDEV_25
#if defined(CONFIG_NETFILTER)
	if(skb->nfmark & IPSEC_NFMARK_IS_SAREF_BIT) {
		SAref = NFmark2IPsecSAref(skb->nfmark);
		KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: "
				"getting SAref=%d from nfmark\n",
				SAref);
	}
#endif
#endif

#ifdef CONFIG_INET_IPSEC_SAREF
	if(skb->sp && skb->sp->ref != IPSEC_SAREF_NULL) {
		SAref = skb->sp->ref;
		KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: "
				"getting SAref=%d from sec_path\n",
				SAref);
	}
#endif

	if (ipsec_xmit_sanity_check_skb(ixs) != IPSEC_XMIT_OK) {
		ipsec_xmit_cleanup(ixs);
		ipsec_xmit_state_delete(ixs);
		return 0;
	}

	ixs->ipsp = ipsec_sa_getbyref(SAref, IPSEC_REFOTHER);
	if(ixs->ipsp == NULL) {
		KLIPS_ERROR(debug_mast, "klips_debug:ipsec_mast_start_xmit: "
				"%s: no SA for saref=%d\n",
				dev->name, SAref);
		ipsec_xmit_cleanup(ixs);
		ipsec_xmit_state_delete(ixs);
		return 0;
	}

	/* make sure this packet can go out on this SA */
	if (ipsec_mast_check_outbound_policy(ixs)) {
		ipsec_xmit_cleanup(ixs);
		ipsec_xmit_state_delete(ixs);
		return 0;
	}

	/* fill in outgoing_said using the ipsp we have */
	ixs->outgoing_said = ixs->ipsp->ips_said;

#ifdef NETDEV_25
#if defined(CONFIG_NETFILTER)
	/* prevent recursion through the saref route */
	if(skb->nfmark & 0x80000000) {
		skb->nfmark = 0;
	}
#endif
#endif
#if 0
	/* TODO: do we have to also have to do this? */
	if(skb->sp && skb->sp->ref != IPSEC_SAREF_NULL) {
		secpath_put(skb->sp);
		skb->sp = NULL;
	}
#endif

	/*
	 * we should be calculating the MTU by looking up a route
	 * based upon the destination in the SA, and then cache
	 * it into the SA, but we don't do that right now.
	 */
	ixs->cur_mtu = 1460;
	ixs->physmtu = 1460;

	ixs->mast_mode = 1;
	ixs->xsm_complete = ipsec_mast_xsm_complete;
	ixs->state = IPSEC_XSM_INIT2;	/* we start later in the process */
	ixs->prv = netdev_priv(ixs->dev);
	ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);

	ipsec_xsm(ixs);
	return 0;

}
Exemple #6
0
/*
 * The ipsec_sa table better be locked before it is handed in,
 * or races might happen.
 *
 * this routine assumes the SA has a refcount==0, and we free it.
 * we also assume that the pointers are already cleaned up.
 */
static int ipsec_sa_del(struct ipsec_sa *ips)
{
	unsigned int hashval;
	struct ipsec_sa *ipstp;
	char sa[SATOT_BUF];
	size_t sa_len;

	if (ips == NULL) {
		KLIPS_ERROR(debug_xform,
			    "klips_error:ipsec_sa_del: "
			    "null pointer passed in!\n");
		return -ENODATA;
	}

	if (ips->ips_next) {
		struct ipsec_sa *in = ips->ips_next;

		ips->ips_next = NULL;
		ipsec_sa_put(in);
	}

	sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
	hashval = IPS_HASH(&ips->ips_said);

	KLIPS_PRINT(debug_xform,
		    "klips_debug:ipsec_sa_del: "
		    "deleting SA:%s (ref=%u), hashval=%d.\n",
		    sa_len ? sa : " (error)",
		    ips->ips_ref,
		    hashval);

	if (ipsec_sadb_hash[hashval] == NULL) {
		/* if this is NULL, then we can be sure that the SA was never
		 * added to the SADB, so we just free it.
		 */
		KLIPS_PRINT(debug_xform,
			    "klips_debug:ipsec_sa_del: "
			    "no entries in ipsec_sa table for hash=%d (ref=%u) of SA:%s.\n",
			    hashval,
			    ips->ips_ref,
			    sa_len ? sa : " (error)");
		return -ENOENT;
	}

	if (ips == ipsec_sadb_hash[hashval]) {
		ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
		ips->ips_hnext = NULL;

		ipsec_sa_put(ips);
		KLIPS_PRINT(debug_xform,
			    "klips_debug:ipsec_sa_del: "
			    "successfully deleted first ipsec_sa in chain.\n");
		return 0;
	} else {
		for (ipstp = ipsec_sadb_hash[hashval];
		     ipstp;
		     ipstp = ipstp->ips_hnext) {
			if (ipstp->ips_hnext == ips) {
				ipstp->ips_hnext = ips->ips_hnext;
				ips->ips_hnext = NULL;
				ipsec_sa_put(ips);
				KLIPS_PRINT(debug_xform,
					    "klips_debug:ipsec_sa_del: "
					    "successfully deleted link in ipsec_sa chain.\n");
				return 0;
			}
		}
	}

	KLIPS_PRINT(debug_xform,
		    "klips_debug:ipsec_sa_del: "
		    "no entries in linked list for hash=%d of SA:%s.\n",
		    hashval,
		    sa_len ? sa : " (error)");
	return -ENOENT;
}
Exemple #7
0
/*
 * 	encryption key context creation function
 * 	called from pfkey_v2_parser.c:pfkey_ips_init() 
 */
int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
	int ret = 0;
	int keyminbits, keymaxbits;
	caddr_t ekp = NULL;
	struct ipsec_alg_enc *ixt_e = 
		(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT,
						      sa_p->ips_encalg);

	KLIPS_PRINT(debug_pfkey,
		    "klips_debug:ipsec_alg_enc_key_create: "
		    "entering with encalg=%d ixt_e=%p\n",
		    sa_p->ips_encalg, ixt_e);
	if (!ixt_e) {
		KLIPS_ERROR(debug_pfkey,
			    "klips_debug:ipsec_alg_enc_key_create: "
			    "NULL ipsec_alg_enc object\n");
		return -EPROTO;
	}

	/* 
	 * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo 
	 */
	switch(ixt_e->ixt_common.ixt_support.ias_id) {
		case ESP_3DES:
			keyminbits=keymaxbits=192;break;
		case ESP_DES:
			keyminbits=keymaxbits=64;break;
		default:
			keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
			keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
	}
	if (sa_p->ips_key_bits_e<keyminbits ||
		sa_p->ips_key_bits_e>keymaxbits) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"incorrect encryption key size for id=%d: %d bits -- "
			"must be between %d,%d bits\n" /*octets (bytes)\n"*/,
			ixt_e->ixt_common.ixt_support.ias_id,
			sa_p->ips_key_bits_e, keyminbits, keymaxbits);
		ret=-EINVAL;
		goto ixt_out;
	}

	if (ixt_e->ixt_e_new_key) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"using ixt_e_new_key to generate key\n");

		if ((ekp = ixt_e->ixt_e_new_key(ixt_e,
			sa_p->ips_key_e,
			sa_p->ips_key_bits_e/8)) == NULL) {
			ret = -EINVAL;
			goto ixt_out;
		}
	} else if (ixt_e->ixt_e_set_key) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"using ixt_e_set_key to generate key context\n");

		if ((ekp = (caddr_t)kmalloc(ixt_e->ixt_e_ctx_size,
			GFP_ATOMIC)) == NULL) {
			ret = -ENOMEM;
			goto ixt_out;
		}
		/* zero-out key_e */
		memset(ekp, 0, ixt_e->ixt_e_ctx_size);

		/* I cast here to allow more decoupling in alg module */
		KLIPS_PRINT(debug_pfkey,
			"set_key(key_ctx=%p, key=%p, key_size=%d)\n",
			ekp, (caddr_t)sa_p->ips_key_e, sa_p->ips_key_bits_e/8);

		ret = ixt_e->ixt_e_set_key(ixt_e,
			ekp, (caddr_t)sa_p->ips_key_e, sa_p->ips_key_bits_e/8);
		if (ret < 0) {
			kfree(ekp);
			goto ixt_out;
		}
	} else {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"no function available to generate a key!\n");

		ret = -EPROTO;
		goto ixt_out;
	}

	if (sa_p->ips_key_e) {
		memset(sa_p->ips_key_e, 0, sa_p->ips_key_bits_e/8);
		kfree(sa_p->ips_key_e);
	}

	sa_p->ips_key_e = ekp;
	sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size;

	sa_p->ips_alg_enc = ixt_e;
	ixt_e = NULL;

ixt_out:
	if (ixt_e)
		ipsec_alg_put((struct ipsec_alg *)ixt_e);

	return ret;
}