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

📄 ipsec_alg_cryptoapi.c

📁 This a good VPN source
💻 C
字号:
/* * ipsec_alg to linux cryptoapi GLUE * * Authors: CODE.ar TEAM * 	Harpo MAxx <harpo@linuxmendoza.org.ar> * 	JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> * 	Luciano Ruete <docemeses@softhome.net> *  * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp *  * 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. * * Example usage: *   modinfo -p ipsec_cryptoapi   (quite useful info, including supported algos) *   modprobe ipsec_cryptoapi *   modprobe ipsec_cryptoapi test=1 *   modprobe ipsec_cryptoapi excl=1                     (exclusive cipher/algo) *   modprobe ipsec_cryptoapi noauto=1  aes=1 twofish=1  (only these ciphers) *   modprobe ipsec_cryptoapi aes=128,128                (force these keylens) *   modprobe ipsec_cryptoapi des_ede3=0                 (everything but 3DES) */#include <linux/config.h>#include <linux/version.h>/*	 *	special case: ipsec core modular with this static algo inside: *	must avoid MODULE magic for this file */#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI#undef MODULE#endif#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h> /* printk() */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/string.h>/* Check if __exit is defined, if not null it */#ifndef __exit#define __exit#endif/* warn the innocent */#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"#define NO_CRYPTOAPI_SUPPORT#endif/*	Low freeswan header coupling	*/#include "freeswan/ipsec_alg.h"#include <linux/crypto.h>#ifdef CRYPTO_API_VERSION_CODE#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"#define NO_CRYPTOAPI_SUPPORT#endif#ifdef NO_CRYPTOAPI_SUPPORT#warning "Building an unusable module :P"/* Catch old CryptoAPI by not allowing module to load */IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ){	printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");	return -EINVAL;}#else#include <asm/scatterlist.h>#include <asm/pgtable.h>#include <linux/mm.h>#define CIPHERNAME_AES		"aes"#define CIPHERNAME_3DES		"des3_ede"#define CIPHERNAME_BLOWFISH	"blowfish"#define CIPHERNAME_CAST		"cast5"#define CIPHERNAME_SERPENT	"serpent"#define CIPHERNAME_TWOFISH	"twofish"#define ESP_3DES		3#define ESP_AES			12#define ESP_BLOWFISH		7	/* truely _constant_  :)  */#define ESP_CAST		6	/* quite constant :) */#define ESP_SERPENT		252	/* from ipsec drafts */#define ESP_TWOFISH		253	/* from ipsec drafts */#define AH_MD5			2#define AH_SHA			3#define DIGESTNAME_MD5		"md5"#define DIGESTNAME_SHA1		"sha1"MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");static int debug=0;MODULE_PARM(debug, "i");static int test=0;MODULE_PARM(test, "i");static int excl=0;MODULE_PARM(excl, "i");static int noauto = 0;MODULE_PARM(noauto,"i");MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");static int des_ede3[] = {-1, -1};static int aes[] = {-1, -1};static int blowfish[] = {-1, -1};static int cast[] = {-1, -1};static int serpent[] = {-1, -1};static int twofish[] = {-1, -1};MODULE_PARM(des_ede3,"1-2i");MODULE_PARM(aes,"1-2i");MODULE_PARM(blowfish,"1-2i");MODULE_PARM(cast,"1-2i");MODULE_PARM(serpent,"1-2i");MODULE_PARM(twofish,"1-2i");MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");struct ipsec_alg_capi_cipher {	const char *ciphername;	/* cryptoapi's ciphername */	unsigned blocksize;	unsigned short minbits;	unsigned short maxbits;	int *parm;		/* lkm param for this cipher */	struct ipsec_alg_enc alg;	/* note it's not a pointer */};static struct ipsec_alg_capi_cipher alg_capi_carray[] = {	{ CIPHERNAME_AES ,     16, 128, 256, aes    , { ixt_alg_id: ESP_AES, }},	{ CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},	{ CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},	{ CIPHERNAME_CAST ,     8, 128, 128, cast   , { ixt_alg_id: ESP_CAST, }},	{ CIPHERNAME_BLOWFISH , 8,  96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},	{ CIPHERNAME_3DES ,     8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},	{ NULL, 0, 0, 0, NULL, {} }};#ifdef NOT_YETstruct ipsec_alg_capi_digest {	const char *digestname;	/* cryptoapi's digestname */	struct digest_implementation *di;	struct ipsec_alg_auth alg;	/* note it's not a pointer */};static struct ipsec_alg_capi_cipher alg_capi_darray[] = {	{ DIGESTNAME_MD5,     NULL, { ixt_alg_id: AH_MD5, }},	{ DIGESTNAME_SHA1,    NULL, { ixt_alg_id: AH_SHA, }},	{ NULL, NULL, {} }};#endif/* * 	"generic" linux cryptoapi setup_cipher() function */int setup_cipher(const char *ciphername){	return crypto_alg_available(ciphername, 0);}/* * 	setups ipsec_alg_capi_cipher "hyper" struct components, calling * 	register_ipsec_alg for cointaned ipsec_alg object */static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);static intsetup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr){	int ret;	cptr->alg.ixt_version = IPSEC_ALG_VERSION;	cptr->alg.ixt_module = THIS_MODULE;	atomic_set (& cptr->alg.ixt_refcnt, 0);	strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));	cptr->alg.ixt_blocksize=cptr->blocksize;	cptr->alg.ixt_keyminbits=cptr->minbits;	cptr->alg.ixt_keymaxbits=cptr->maxbits;	cptr->alg.ixt_state = 0;	if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;	cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;	cptr->alg.ixt_e_ctx_size = 0;	cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;	cptr->alg.ixt_e_new_key = _capi_new_key;	cptr->alg.ixt_e_destroy_key = _capi_destroy_key;	cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;	cptr->alg.ixt_data = cptr;	ret=register_ipsec_alg_enc(&cptr->alg);	printk("setup_ipsec_alg_capi_cipher(): " 			"alg_type=%d alg_id=%d name=%s "			"keyminbits=%d keymaxbits=%d, ret=%d\n", 				cptr->alg.ixt_alg_type, 				cptr->alg.ixt_alg_id, 				cptr->alg.ixt_name, 				cptr->alg.ixt_keyminbits,				cptr->alg.ixt_keymaxbits,				ret);	return ret;}/* * 	called in ipsec_sa_wipe() time, will destroy key contexts * 	and do 1 unbind() */static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e){	struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;		if (debug > 0)		printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"				"name=%s key_e=%p \n",				alg->ixt_name, key_e);	if (!key_e) {		printk(KERN_ERR "klips_debug: _capi_destroy_key:"				"name=%s NULL key_e!\n",				alg->ixt_name);		return;	}	crypto_free_tfm(tfm);}	/* * 	create new key context, need alg->ixt_data to know which * 	(of many) cipher inside this module is the target */static __u8 *_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen){	struct ipsec_alg_capi_cipher *cptr;	struct crypto_tfm *tfm=NULL;	cptr = alg->ixt_data;	if (!cptr) {		printk(KERN_ERR "_capi_new_key(): "				"NULL ixt_data (?!) for \"%s\" algo\n" 				, alg->ixt_name);		goto err;	}	if (debug > 0)		printk(KERN_DEBUG "klips_debug:_capi_new_key:"				"name=%s cptr=%p key=%p keysize=%d\n",				alg->ixt_name, cptr, key, keylen);		/*		 *	alloc tfm	 */	tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);	if (!tfm) {		printk(KERN_ERR "_capi_new_key(): "				"NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" 			, alg->ixt_name, cptr->ciphername);		goto err;	}	if (crypto_cipher_setkey(tfm, key, keylen) < 0) {		printk(KERN_ERR "_capi_new_key(): "				"failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" 			, alg->ixt_name, keylen);		crypto_free_tfm(tfm);		tfm=NULL;	}err:	if (debug > 0)		printk(KERN_DEBUG "klips_debug:_capi_new_key:"				"name=%s key=%p keylen=%d tfm=%p\n",				alg->ixt_name, key, keylen, tfm);	return (__u8 *) tfm;}/* * 	core encryption function: will use cx->ci to call actual cipher's * 	cbc function */static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {	int error =0;	struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;	struct scatterlist sg = { 		.page = virt_to_page(in),		.offset = (unsigned long)(in) % PAGE_SIZE,		.length=ilen,	};	if (debug > 1)		printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"				"key_e=%p "				"in=%p out=%p ilen=%d iv=%p encrypt=%d\n"				, key_e				, in, in, ilen, iv, encrypt);	crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));	if (encrypt)		error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);	else		error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);	if (debug > 1)		printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"				"error=%d\n"				, error);	return (error<0)? error : ilen;}/* * 	main initialization loop: for each cipher in list, do * 	1) setup cryptoapi cipher else continue * 	2) register ipsec_alg object */static intsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) {	struct ipsec_alg_capi_cipher *cptr;	/* foreach cipher in list ... */	for (cptr=clist;cptr->ciphername;cptr++) {		/* 		 * see if cipher has been disabled (0) or		 * if noauto set and not enabled (1)		 */		if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {			if (debug>0)				printk(KERN_INFO "setup_cipher_list(): "					"ciphername=%s skipped at user request: "					"noauto=%d parm[0]=%d parm[1]=%d\n"					, cptr->ciphername					, noauto					, cptr->parm[0]					, cptr->parm[1]);			continue;		}		/* 		 * 	use a local ci to avoid touching cptr->ci,		 * 	if register ipsec_alg success then bind cipher		 */		if( setup_cipher(cptr->ciphername) ) {			if (debug > 0)				printk(KERN_DEBUG "klips_debug:"						"setup_cipher_list():"						"ciphername=%s found\n"				, cptr->ciphername);			if (setup_ipsec_alg_capi_cipher(cptr) == 0) {											} else {				printk(KERN_ERR "klips_debug:"						"setup_cipher_list():"						"ciphername=%s failed ipsec_alg_register\n"				, cptr->ciphername);			}		} else {			if (debug>0)				printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",				cptr->ciphername);		}	}	return 0;}/* * 	deregister ipsec_alg objects and unbind ciphers */static intunsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) {	struct ipsec_alg_capi_cipher *cptr;	/* foreach cipher in list ... */	for (cptr=clist;cptr->ciphername;cptr++) {		if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {			unregister_ipsec_alg_enc(&cptr->alg);		}	}	return 0;}/* * 	test loop for registered algos */static inttest_cipher_list (struct ipsec_alg_capi_cipher* clist) {	int test_ret;	struct ipsec_alg_capi_cipher *cptr;	/* foreach cipher in list ... */	for (cptr=clist;cptr->ciphername;cptr++) {		if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {			test_ret=ipsec_alg_test(					cptr->alg.ixt_alg_type,					cptr->alg.ixt_alg_id, 					test);			printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", 					cptr->alg.ixt_alg_type, 					cptr->alg.ixt_alg_id, 					test_ret);		}	}	return 0;}IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ){	int ret, test_ret;	if ((ret=setup_cipher_list(alg_capi_carray)) < 0)		return  -EPROTONOSUPPORT;	if (ret==0 && test) {		test_ret=test_cipher_list(alg_capi_carray);	}	return ret;}IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini ){	unsetup_cipher_list(alg_capi_carray);	return;}#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifEXPORT_NO_SYMBOLS;#endif /* NO_CRYPTOAPI_SUPPORT */

⌨️ 快捷键说明

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