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

📄 ipsec_alg.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
int register_ipsec_alg(struct ipsec_alg *ixt) {	int ret=-EINVAL;	/*	Validation 	*/	if (ixt==NULL)		barf_out("NULL ipsec_alg object passed\n");	if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))		barf_out("incorrect version: %d.%d.%d-%d, "			"must be %d.%d.%d[-%d]\n",				IPSEC_ALG_VERSION_QUAD(ixt->ixt_version), 				IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));	switch(ixt->ixt_alg_type) {		case IPSEC_ALG_TYPE_AUTH:			if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))				goto out;			break;		case IPSEC_ALG_TYPE_ENCRYPT: 			if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))				goto out; 			/* 			 * Adapted two lines below: 			 * 	ivlen == 0 is possible (NULL enc has blocksize==1)			 *			 * fixed NULL support by David De Reu <DeReu@tComLabs.com> 			 */			if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1)				ixt->ixt_ivlen = ixt->ixt_blocksize*8;			break;		default:			barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);	}	INIT_LIST_HEAD(&ixt->ixt_list);	ret = ipsec_alg_insert(ixt);	if (ret<0) 		barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."				"Not loaded (ret=%d).\n",				ixt->ixt_alg_id, ret);	ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));	if (ret==0) {		ixt->ixt_state |= IPSEC_ALG_ST_SUPP;		/*	send register event to userspace	*/		pfkey_register_reply(SADB_SATYPE_ESP, NULL);	} else		printk(KERN_ERR "pfkey_list_insert_supported returned %d. "				"Loading anyway.\n", ret);	ret=0;out:	return ret;}/*  * 	unregister ipsec_alg object from own tables, if  * 	success => calls pfkey_list_remove_supported() */int unregister_ipsec_alg(struct ipsec_alg *ixt) {	int ret= -EINVAL;	switch(ixt->ixt_alg_type) {		case IPSEC_ALG_TYPE_AUTH:		case IPSEC_ALG_TYPE_ENCRYPT: 			break;		default:			/*	this is not a typo :) */			barf_out("frog found in list (\"%s\"): ixt_p=NULL\n", 				ixt->ixt_name);	}	ret=ipsec_alg_delete(ixt);	if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {		ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;		pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));		/*	send register event to userspace	*/		pfkey_register_reply(SADB_SATYPE_ESP, NULL);	}out:	return ret;}/* * 	Must be called from user context * 	used at module load type for testing algo implementation */static int ipsec_alg_test_encrypt(int enc_alg, int test) {	int ret;	caddr_t buf = NULL;	int iv_size, keysize, key_e_size;	struct ipsec_alg_enc *ixt_e;	void *tmp_key_e = NULL;	#define BUFSZ	1024	#define MARGIN	0	#define test_enc   (buf+MARGIN)	#define test_dec   (test_enc+BUFSZ+MARGIN)	#define test_tmp   (test_dec+BUFSZ+MARGIN)	#define test_key_e (test_tmp+BUFSZ+MARGIN)	#define test_iv    (test_key_e+key_e_size+MARGIN)	#define test_key   (test_iv+iv_size+MARGIN)	#define test_size  (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)	ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);	if (ixt_e==NULL) {		KLIPS_PRINT(1, 			    "klips_debug: ipsec_alg_test_encrypt: "			    "encalg=%d object not found\n",			    enc_alg);		ret=-EINVAL;		goto out;	}	iv_size=ixt_e->ixt_ivlen / 8;	key_e_size=ixt_e->ixt_e_ctx_size;	keysize=ixt_e->ixt_e_keylen;	KLIPS_PRINT(1, 		    "klips_debug: ipsec_alg_test_encrypt: "		    "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",		    enc_alg, iv_size, key_e_size, keysize);	if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {		ret= -ENOMEM;		goto out;	}	get_random_bytes(test_key, keysize);	get_random_bytes(test_iv, iv_size);	if (ixt_e->ixt_e_new_key) {		tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);		ret = tmp_key_e ? 0 : -EINVAL;	} else {		tmp_key_e = test_key_e;		ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);	}	if (ret < 0)		goto out;	get_random_bytes(test_enc, BUFSZ);	memcpy(test_tmp, test_enc, BUFSZ);	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);	printk(KERN_INFO		    "klips_info: ipsec_alg_test_encrypt: "		    "cbc_encrypt=1 ret=%d\n", 		    	ret);	ret=memcmp(test_enc, test_tmp, BUFSZ);	printk(KERN_INFO		    "klips_info: ipsec_alg_test_encrypt: "		    "memcmp(enc, tmp) ret=%d: %s\n", ret,			ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );	memcpy(test_dec, test_enc, BUFSZ);	ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);	printk(KERN_INFO		    "klips_info: ipsec_alg_test_encrypt: "		    "cbc_encrypt=0 ret=%d\n", ret);	ret=memcmp(test_dec, test_tmp, BUFSZ);	printk(KERN_INFO		    "klips_info: ipsec_alg_test_encrypt: "		    "memcmp(dec,tmp) ret=%d: %s\n", ret,			ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );	{		/*	Shamelessly taken from drivers/md sources  O:)  */		unsigned long now;		int i, count, max=0;		int encrypt, speed;		for (encrypt=0; encrypt <2;encrypt ++) {			for (i = 0; i < 5; i++) {				now = jiffies;				count = 0;				while (jiffies == now) {					mb();					ixt_e->ixt_e_cbc_encrypt(ixt_e, 							tmp_key_e, test_tmp, 							BUFSZ, test_iv, encrypt);					mb();					count++;					mb();				}				if (count > max)					max = count;			}			speed = max * (HZ * BUFSZ / 1024);			printk(KERN_INFO				    "klips_info: ipsec_alg_test_encrypt: "				    "%s %s speed=%d KB/s\n", 				    ixt_e->ixt_name,				    encrypt? "encrypt": "decrypt", speed);		}	}out:	if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);	if (buf) kfree(buf);	if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);	return ret;	#undef test_enc  	#undef test_dec  	#undef test_tmp  	#undef test_key_e	#undef test_iv   	#undef test_key  	#undef test_size }/* * 	Must be called from user context * 	used at module load type for testing algo implementation */static int ipsec_alg_test_auth(int auth_alg, int test) {	int ret;	caddr_t buf = NULL;	int blocksize, keysize, key_a_size;	struct ipsec_alg_auth *ixt_a;	#define BUFSZ	1024	#define MARGIN	0	#define test_auth  (buf+MARGIN)	#define test_key_a (test_auth+BUFSZ+MARGIN)	#define test_key   (test_key_a+key_a_size+MARGIN)	#define test_hash  (test_key+keysize+MARGIN)	#define test_size  (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)	ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);	if (ixt_a==NULL) {		KLIPS_PRINT(1, 			    "klips_debug: ipsec_alg_test_auth: "			    "encalg=%d object not found\n",			    auth_alg);		ret=-EINVAL;		goto out;	}	blocksize=ixt_a->ixt_blocksize;	key_a_size=ixt_a->ixt_a_ctx_size;	keysize=ixt_a->ixt_a_keylen;	KLIPS_PRINT(1, 		    "klips_debug: ipsec_alg_test_auth: "		    "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",		    auth_alg, blocksize, key_a_size, keysize);	if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {		ret= -ENOMEM;		goto out;	}	get_random_bytes(test_key, keysize);	ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);	if (ret < 0 )		goto out;	get_random_bytes(test_auth, BUFSZ);	ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);	printk(KERN_INFO		    "klips_info: ipsec_alg_test_auth: "		    "ret=%d\n", ret);	{		/*	Shamelessly taken from drivers/md sources  O:)  */		unsigned long now;		int i, count, max=0;		int speed;		for (i = 0; i < 5; i++) {			now = jiffies;			count = 0;			while (jiffies == now) {				mb();				ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);				mb();				count++;				mb();			}			if (count > max)				max = count;		}		speed = max * (HZ * BUFSZ / 1024);		printk(KERN_INFO				"klips_info: ipsec_alg_test_auth: "				"%s hash speed=%d KB/s\n", 				ixt_a->ixt_name,				speed);	}out:	if (buf) kfree(buf);	if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);	return ret;	#undef test_auth 	#undef test_key_a	#undef test_key  	#undef test_hash 	#undef test_size }int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {	switch(alg_type) {		case IPSEC_ALG_TYPE_ENCRYPT:			return ipsec_alg_test_encrypt(alg_id, test);			break;		case IPSEC_ALG_TYPE_AUTH:			return ipsec_alg_test_auth(alg_id, test);			break;	}	printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "			"alg_type=%d alg_id=%d\n",			alg_type, alg_id);	return -EINVAL;}int ipsec_alg_init(void) {	KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "			"KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",			IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),			SADB_EALG_MAX, SADB_AALG_MAX);	/*	Initialize tables */	write_lock_bh(&ipsec_alg_lock);	ipsec_alg_hash_init();	write_unlock_bh(&ipsec_alg_lock);	/*	Initialize static algos 	*/	KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "		"calling ipsec_alg_static_init()\n");	/* If we are suppose to use our AES, and don't have CryptoAPI enabled... */#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE) && !CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)	{		extern int ipsec_aes_init(void);		ipsec_aes_init();	}#endif	/* If we are doing CryptoAPI, then init */#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)	{                extern int ipsec_cryptoapi_init(void);                ipsec_cryptoapi_init();        }#endif	return 0;}/********************************************** * * 	INTERFACE for ipsec_sa init and wipe * **********************************************//*	 *	Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()	 */int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {	struct ipsec_alg_enc *ixt_e;	struct ipsec_alg_auth *ixt_a;	/*	Only ESP for now ... */	if (sa_p->ips_said.proto != IPPROTO_ESP)		return -EPROTONOSUPPORT;	KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"			"entering for encalg=%d, authalg=%d\n",			    sa_p->ips_encalg, sa_p->ips_authalg);	if ((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_sa_init() :"		    "found ipsec_alg (ixt_e=%p) for encalg=%d\n",		    ixt_e, sa_p->ips_encalg);		sa_p->ips_alg_enc=ixt_e;	}	if ((ixt_a=(struct ipsec_alg_auth *)		ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {		KLIPS_PRINT(debug_pfkey,		    "klips_debug: ipsec_alg_sa_init() :"		    "found ipsec_alg (ixt_a=%p) for auth=%d\n",		    ixt_a, sa_p->ips_authalg);		sa_p->ips_alg_auth=ixt_a;	}	return 0;}/*	 *	Called from pluto -> ipsec_sa.c:ipsec_sa_delchain() */int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {	struct ipsec_alg *ixt;	if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {		KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"				"unlinking for encalg=%d\n",				ixt->ixt_alg_id);		ipsec_alg_put(ixt);	}	if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {		KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"				"unlinking for authalg=%d\n",				ixt->ixt_alg_id);		ipsec_alg_put(ixt);	}	return 0;}IPSEC_PROCFS_DEBUG_NO_STATICintipsec_xform_get_info(char *buffer,		     char **start,		     off_t offset,		     int length     IPSEC_PROC_LAST_ARG){	int len = 0;	off_t begin = 0;	int i;	struct list_head *head;	struct ipsec_alg *ixt;	KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,		    "klips_debug:ipsec_tncfg_get_info: "		    "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",		    buffer,		    *start,		    (int)offset,		    length);	for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++)	{		struct list_head *p;		for (p=head->next; p!=head; p=p->next)		{			ixt = list_entry(p, struct ipsec_alg, ixt_list);			len += ipsec_snprintf(buffer+len, length-len,					      "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",					      ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id,					      ixt->ixt_name, ixt->ixt_refcnt);			len += ipsec_snprintf(buffer+len, length-len,					      "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",					      ixt->ixt_state, ixt->ixt_blocksize,					      ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);			len += ipsec_snprintf(buffer+len, length-len,					      "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",					      ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);			switch(ixt->ixt_alg_type)			{			case IPSEC_ALG_TYPE_AUTH:			{				struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;				len += ipsec_snprintf(buffer+len, length-len,						      "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",						      auth->ixt_a_keylen, auth->ixt_a_ctx_size,						      auth->ixt_a_authlen);				break;			}			case IPSEC_ALG_TYPE_ENCRYPT:			{				struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;				len += ipsec_snprintf(buffer+len, length-len,						      "KEYLEN=%d CTXSIZE=%d ",						      enc->ixt_e_keylen, enc->ixt_e_ctx_size);				break;			}			}			len += ipsec_snprintf(buffer+len, length-len, "\n");		}	} 	*start = buffer + (offset - begin);	/* Start of wanted data */	len -= (offset - begin);			/* Start slop */	if (len > length)		len = length;	return len;}/* * 	As the author of this module, I ONLY ALLOW using it from * 	GPL (or same LICENSE TERMS as kernel source) modules. * * 	In respect to hardware crypto engines this means: * 	* Closed-source device drivers ARE NOT ALLOWED to use  * 	  this interface. * 	* Closed-source VHDL/Verilog firmware running on  * 	  the crypto hardware device IS ALLOWED to use this interface * 	  via a GPL (or same LICENSE TERMS as kernel source) device driver. * 	--Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording) *//*	 *	These symbols can only be used from GPL modules	 *	for now, I'm disabling this because it creates false *	symbol problems for old modutils. */#ifndef NET_26#if 0#ifndef EXPORT_SYMBOL_GPL #undef EXPORT_SYMBOL_GPL#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL#endif #endifEXPORT_SYMBOL(register_ipsec_alg);EXPORT_SYMBOL(unregister_ipsec_alg);EXPORT_SYMBOL(ipsec_alg_test);#endif

⌨️ 快捷键说明

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