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

📄 ipsec_alg.c

📁 ipsec vpn
💻 C
📖 第 1 页 / 共 3 页
字号:
			    GFP_ATOMIC)) == NULL) {			ret=-ENOMEM;			goto ixt_out;		}		/* zero-out key_e */		memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);		/* I cast here to allow more decoupling in alg module */		KLIPS_PRINT(debug_pfkey,			    "klips_debug:ipsec_alg_enc_key_create: about to call:"				    "set_key(key_e=%p, ekp=%p, key_size=%d)\n",				    (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);		ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);	}	/* paranoid */	memset(ekp, 0, sa_p->ips_key_bits_e/8);	kfree(ekp);ixt_out:	return ret;}/*************************************************************** * * 	INTERFACE for AUTH services: key creation, hash functions * ***************************************************************//* * 	auth key context creation function * 	called from pfkey_v2_parser.c:pfkey_ips_init()  */int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {	int ret=-EINVAL;	struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;	int keyminbits, keymaxbits;	unsigned char *akp;	unsigned int aks;	KLIPS_PRINT(debug_pfkey,		    "klips_debug:ipsec_alg_auth_key_create: "		    "entering with authalg=%d ixt_a=%p\n",		    sa_p->ips_authalg, ixt_a);	if (!ixt_a) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:ipsec_alg_auth_key_create: "			    "NULL ipsec_alg_auth object\n");		return -EPROTO;	}	keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;	keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;	if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:ipsec_alg_auth_key_create: incorrect auth"			    "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,			    sa_p->ips_key_bits_a, keyminbits, keymaxbits);		ret=-EINVAL;		goto ixt_out;	}	/* save auth key pointer */	sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */	akp = sa_p->ips_key_a;	aks = sa_p->ips_key_a_size;	/* will hold: 2 ctx and a blocksize buffer: kb */	sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;	if((sa_p->ips_key_a = 		(caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {		ret=-ENOMEM;		goto ixt_out;	}	ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */	ret=0;	memset(akp, 0, aks);	kfree(akp);			ixt_out:	return ret;}int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,			  int len, __u8 *hash, int hashlen){	struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;	if (!ixt_a) {		KLIPS_PRINT(debug_pfkey,			    "klips_debug:ipsec_sa_esp_hash: "			    "NULL ipsec_alg_auth object\n");		return -EPROTO;	}	KLIPS_PRINT(debug_tunnel|debug_rcv,			"klips_debug:ipsec_sa_esp_hash: "			"hashing %p (%d bytes) to %p (%d bytes)\n",			espp, len,			hash, hashlen);	ixt_a->ixt_a_hmac_hash(ixt_a,			sa_p->ips_key_a, 			espp, len,			hash, hashlen);	return 0;}/*************************************************************** * * 	INTERFACE for module loading,testing, and unloading * ***************************************************************//* validation for registering (enc) module */static int check_enc(struct ipsec_alg_enc *ixt){	int ret=-EINVAL;	if (ixt->ixt_common.ixt_blocksize==0) /*  || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */		barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);	if (ixt->ixt_common.ixt_support.ias_keyminbits==0	    && ixt->ixt_common.ixt_support.ias_keymaxbits==0	    && ixt->ixt_e_keylen==0)		goto zero_key_ok;		if (ixt->ixt_common.ixt_support.ias_keyminbits==0)		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);		if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);		if (ixt->ixt_e_keylen==0)		barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);	zero_key_ok:	if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)		barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);	if (ixt->ixt_e_cbc_encrypt==NULL)		barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");	ret=0;out:	return ret;}/* validation for registering (auth) module */static int check_auth(struct ipsec_alg_auth *ixt){	int ret=-EINVAL;	if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)		barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",			 ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);	if (ixt->ixt_common.ixt_blocksize==0	    || ixt->ixt_common.ixt_blocksize%2)		barf_out(KERN_ERR "invalid blocksize=%d\n",			 ixt->ixt_common.ixt_blocksize);	if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)		barf_out(KERN_ERR "sorry blocksize=%d > %d. "			"Please increase AH_BLKLEN_MAX and recompile\n", 			ixt->ixt_common.ixt_blocksize,			AH_BLKLEN_MAX);	if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)		goto zero_key_ok;	if (ixt->ixt_common.ixt_support.ias_keyminbits==0)		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);	if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);	if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)		barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");	if (ixt->ixt_a_keylen==0)		barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);zero_key_ok:	if (ixt->ixt_a_ctx_size==0)		barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);	if (ixt->ixt_a_hmac_set_key==NULL)		barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");	if (ixt->ixt_a_hmac_hash==NULL)		barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");	ret=0;out:	return ret;}/*  * Generic (enc, auth) registration entry point  */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_support.ias_ivlen == 0			    && ixt->ixt_blocksize > 1) {				ixt->ixt_support.ias_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_support.ias_id, ret);	ret = pfkey_list_insert_supported((struct ipsec_alg_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 ipsec_alg_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_common.ixt_support.ias_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) {

⌨️ 快捷键说明

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