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

📄 ipsec_esp.c

📁 openswan
💻 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.13.2.4 2006/05/06 03:07:38 ken 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 */#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_DEBUG#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)#else#define ESP_DMP(_x,_y,_z)#endif#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->h.raw;	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;	//unsigned char *idat = (unsigned char *)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->h.raw[irs->ilen]);	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;	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;	}	aa = irs->authfuncs;	/* copy the initialized keying material */	memcpy(&tctx, irs->ictx, irs->ictx_len);#ifdef HASH_DEBUG	ESP_DMP("ictx", irs->ictx, irs->ictx_len);	ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);#endif	(*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);	(*aa->final)(irs->hash, (void *)&tctx);#ifdef HASH_DEBUG	ESP_DMP("hash1", irs->hash, aa->hashlen);#endif	memcpy(&tctx, irs->octx, irs->octx_len);#ifdef HASH_DEBUG	ESP_DMP("octx", irs->octx, irs->octx_len);#endif	(*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 i;	int pad = 0, padlen;	int badpad = 0;	int esphlen = 0;	__u8 *idat;	/* pointer to content to be decrypted/authenticated */	int encaplen = 0;	struct sk_buff *skb;	struct ipsec_alg_enc *ixt_e=NULL;	skb=irs->skb;	idat = skb->h.raw;	/* encaplen is the distance between the end of the IP	 * header and the beginning of the ESP header.	 * on ESP headers it is zero, but on UDP-encap ESP	 * it includes the space for the UDP header.	 *	 * Note: UDP-encap code has already moved the	 *       skb->data forward to accomodate this.	 */	encaplen = idat - (skb->nh.raw + irs->iphlen);	ixt_e=ipsp->ips_alg_enc;	esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;	KLIPS_PRINT(debug_rcv,		    "klips_debug:ipsec_rcv: "		    "encalg=%d esphlen=%d\n",		    ipsp->ips_encalg, esphlen);	idat += esphlen;	irs->ilen -= esphlen;	if (ipsec_alg_esp_encrypt(ipsp, 				  idat, irs->ilen, espp->esp_iv, 				  IPSEC_ALG_DECRYPT) <= 0) {		KLIPS_ERROR(debug_rcv, "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;	} 	ESP_DMP("postdecrypt", idat, irs->ilen);	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);		}		KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,				" %02x",				idat[irs->ilen - 2 - padlen + i - 1]);		if(i != idat[irs->ilen - 2 - padlen + i - 1]) {			badpad = 1;		}		if((i % 16) == 0) {			KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,					"\n");		}	}	if((i % 16) != 1) {		KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,						"\n");	}	if(badpad) {		KLIPS_PRINT(debug_rcv & DB_RX_IPAD,			    "klips_debug:ipsec_rcv: "			    "warning, decrypted packet from %s has bad padding\n",			    irs->ipsaddr_txt);		KLIPS_PRINT(debug_rcv & DB_RX_IPAD,			    "klips_debug:ipsec_rcv: "			    "...may be bad decryption -- not dropped\n");		ipsp->ips_errs.ips_encpad_errs += 1;	}	KLIPS_PRINT(debug_rcv & DB_RX_IPAD,		    "klips_debug:ipsec_rcv: "		    "packet decrypted from %s: next_header = %d, padding = %d\n",

⌨️ 快捷键说明

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