⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipsec_esp.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * processing code for ESP * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. */char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.8 2004/09/14 00:22:57 mcr Exp $";#include <linux/config.h>#include <linux/version.h>#define __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h> /* printk() */#include "openswan/ipsec_param.h"#ifdef MALLOC_SLAB# include <linux/slab.h> /* kmalloc() */#else /* MALLOC_SLAB */# include <linux/malloc.h> /* kmalloc() */#endif /* MALLOC_SLAB */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/netdevice.h>	/* struct device, and other headers */#include <linux/etherdevice.h>	/* eth_type_trans */#include <linux/ip.h>		/* struct iphdr */#include <linux/skbuff.h>#include <openswan.h>#ifdef SPINLOCK# ifdef SPINLOCK_23#  include <linux/spinlock.h> /* *lock* */# else /* SPINLOCK_23 */#  include <asm/spinlock.h> /* *lock* */# endif /* SPINLOCK_23 */#endif /* SPINLOCK */#ifdef NET_21# include <asm/uaccess.h># include <linux/in6.h># define proto_priv cb#endif /* NET21 */#include <asm/checksum.h>#include <net/ip.h>#include <net/protocol.h>#include "openswan/radij.h"#include "openswan/ipsec_encap.h"#include "openswan/ipsec_sa.h"#include "openswan/ipsec_radij.h"#include "openswan/ipsec_xform.h"#include "openswan/ipsec_tunnel.h"#include "openswan/ipsec_rcv.h"#include "openswan/ipsec_xmit.h"#include "openswan/ipsec_auth.h"#ifdef CONFIG_KLIPS_ESP#include "openswan/ipsec_esp.h"#endif /* CONFIG_KLIPS_ESP */#include "openswan/ipsec_proto.h"#include "openswan/ipsec_alg.h"#ifdef CONFIG_KLIPS_ESPenum ipsec_rcv_valueipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,		     struct sk_buff *skb){	__u8 proto;	int len;	/* packet length */	len = skb->len;	proto = irs->ipp->protocol;	/* XXX this will need to be 8 for IPv6 */	if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {		printk("klips_error:ipsec_rcv: "		       "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",		       len - irs->iphlen,		       irs->ipsaddr_txt);		if(irs->stats) {			irs->stats->rx_errors++;		}		return IPSEC_RCV_BADLEN;	}	if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {		KLIPS_PRINT(debug_rcv & DB_RX_INAU,			    "klips_debug:ipsec_rcv: "			    "runt esp packet of skb->len=%d received from %s, dropped.\n",			    skb->len,			    irs->ipsaddr_txt);		if(irs->stats) {			irs->stats->rx_errors++;		}		return IPSEC_RCV_BADLEN;	}	irs->protostuff.espstuff.espp = (struct esphdr *)(skb->data + irs->iphlen);	irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;	return IPSEC_RCV_OK;}enum ipsec_rcv_valueipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,			    struct sk_buff *skb,			    __u32          *replay,			    unsigned char **authenticator){	struct esphdr *espp = irs->protostuff.espstuff.espp;	KLIPS_PRINT(debug_rcv,		    "klips_debug:ipsec_rcv: "		    "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",		    irs->ipsaddr_txt,		    (__u32)ntohl(espp->esp_rpl),		    (__u32)ntohl(*((__u32 *)(espp->esp_iv)    )),		    (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),		    irs->len,		    irs->ilen,		    irs->sa_len ? irs->sa : " (error)");	*replay = ntohl(espp->esp_rpl);	*authenticator = &(skb->data[irs->len - irs->authlen]);	return IPSEC_RCV_OK;}enum ipsec_rcv_valueipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,		       struct sk_buff *skb){	struct auth_alg *aa;	struct esphdr *espp = irs->protostuff.espstuff.espp;	union {		MD5_CTX		md5;		SHA1_CTX	sha1;	} tctx;#ifdef CONFIG_KLIPS_ALG	if (irs->ipsp->ips_alg_auth) {		KLIPS_PRINT(debug_rcv,				"klips_debug:ipsec_rcv: "				"ipsec_alg hashing proto=%d... ",				irs->said.proto);		if(irs->said.proto == IPPROTO_ESP) {			ipsec_alg_sa_esp_hash(irs->ipsp,					(caddr_t)espp, irs->ilen,					irs->hash, AHHMAC_HASHLEN);			return IPSEC_RCV_OK;		}		return IPSEC_RCV_BADPROTO;	}#endif	aa = irs->authfuncs;	/* copy the initialized keying material */	memcpy(&tctx, irs->ictx, irs->ictx_len);	(*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);	(*aa->final)(irs->hash, (void *)&tctx);	memcpy(&tctx, irs->octx, irs->octx_len);	(*aa->update)((void *)&tctx, irs->hash, aa->hashlen);	(*aa->final)(irs->hash, (void *)&tctx);	return IPSEC_RCV_OK;}enum ipsec_rcv_valueipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs){	struct ipsec_sa *ipsp = irs->ipsp;	struct esphdr *espp = irs->protostuff.espstuff.espp;	int esphlen = 0;	__u8 *idat;	/* pointer to content to be decrypted/authenticated */	__u32 iv[2];	int pad = 0, padlen;	int badpad = 0;	int i;	struct sk_buff *skb;#ifdef CONFIG_KLIPS_ALG	struct ipsec_alg_enc *ixt_e=NULL;#endif /* CONFIG_KLIPS_ALG */	skb=irs->skb;	idat = skb->data + irs->iphlen;#ifdef CONFIG_KLIPS_ALG	if ((ixt_e=ipsp->ips_alg_enc)) {		esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;		KLIPS_PRINT(debug_rcv,				"klips_debug:ipsec_rcv: "				"encalg=%d esphlen=%d\n",				ipsp->ips_encalg, esphlen);	} else#endif /* CONFIG_KLIPS_ALG */	switch(ipsp->ips_encalg) {	case ESP_3DES:		iv[0] = *((__u32 *)(espp->esp_iv)    );		iv[1] = *((__u32 *)(espp->esp_iv) + 1);		esphlen = sizeof(struct esphdr);		break;	default:		ipsp->ips_errs.ips_alg_errs += 1;		if(irs->stats) {			irs->stats->rx_errors++;		}		return IPSEC_RCV_ESP_BADALG;	}	idat += esphlen;	irs->ilen -= esphlen;#ifdef CONFIG_KLIPS_ALG	if (ixt_e)	{		if (ipsec_alg_esp_encrypt(ipsp, 					idat, irs->ilen, espp->esp_iv, 					IPSEC_ALG_DECRYPT) <= 0)		{			printk("klips_error:ipsec_rcv: "					"got packet with esplen = %d "					"from %s -- should be on "					"ENC(%d) octet boundary, "					"packet dropped\n",					irs->ilen,					irs->ipsaddr_txt,					ipsp->ips_encalg);			if(irs->stats) {				irs->stats->rx_errors++;			}			return IPSEC_RCV_BAD_DECRYPT;		}	} else#endif /* CONFIG_KLIPS_ALG */	switch(ipsp->ips_encalg) {	case ESP_3DES:		if ((irs->ilen) % 8) {			ipsp->ips_errs.ips_encsize_errs += 1;			printk("klips_error:ipsec_rcv: "			       "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n",			       irs->ilen,			       irs->ipsaddr_txt);			if(irs->stats) {				irs->stats->rx_errors++;			}			return IPSEC_RCV_3DES_BADBLOCKING;		}		des_ede3_cbc_encrypt((des_cblock *)idat,				     (des_cblock *)idat,				     irs->ilen,				     ((struct des_eks *)(ipsp->ips_key_e))[0].ks,				     ((struct des_eks *)(ipsp->ips_key_e))[1].ks,				     ((struct des_eks *)(ipsp->ips_key_e))[2].ks,				     (des_cblock *)iv, 0);		break;	}	ipsec_rcv_dmp("postdecrypt", skb->data, skb->len);	irs->next_header = idat[irs->ilen - 1];	padlen = idat[irs->ilen - 2];	pad = padlen + 2 + irs->authlen;	KLIPS_PRINT(debug_rcv & DB_RX_IPAD,		    "klips_debug:ipsec_rcv: "		    "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",		    padlen);	for (i = 1; i <= padlen; i++) {		if((i % 16) == 1) {			KLIPS_PRINT(debug_rcv & DB_RX_IPAD,				    "klips_debug:           %02x:",				    i - 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -