Ejemplo n.º 1
0
/*	
 *	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:  %s() :"
			"entering for encalg=%d, authalg=%d\n",
			    __FUNCTION__, 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:  %s() :"
		    "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
		    __FUNCTION__, 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:  %s() :"
		    "found ipsec_alg (ixt_a=%p) for auth=%d\n",
		    __FUNCTION__, ixt_a, sa_p->ips_authalg);
		sa_p->ips_alg_auth=ixt_a;
	}
	return 0;
}
Ejemplo n.º 2
0
/*
 * 	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;
	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: %s: "
			    "encalg=%d object not found\n",
			    __FUNCTION__, 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: %s : "
		    "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
		    __FUNCTION__, 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);
	ixt_a->ixt_a_hmac_set_key(test_key_a, test_key, keysize);
	get_random_bytes(test_auth, BUFSZ);
	ret=ixt_a->ixt_a_hmac_hash(test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
	printk(KERN_INFO
		    "klips_info: %s: "
		    "ret=%d\n", __FUNCTION__, 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(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: %s: "
				"%s hash speed=%d KB/s\n", 
				__FUNCTION__, ixt_a->ixt_name,
				speed);
	}
	kfree(buf);
	ipsec_alg_put((struct ipsec_alg *)ixt_a);
out:
	return ret;
	#undef test_auth 
	#undef test_key_a
	#undef test_key  
	#undef test_hash 
	#undef test_size 
}
Ejemplo n.º 3
0
/*
 * 	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 = 0;
	int keyminbits, keymaxbits;
	caddr_t akp = NULL;
	struct ipsec_alg_auth *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_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;
	}

	/* will hold: 2 ctx and a blocksize buffer: kb */
	if ((akp = (caddr_t)kmalloc(ixt_a->ixt_a_ctx_size,
			GFP_ATOMIC)) == NULL) {
		ret = -ENOMEM;
		goto ixt_out;
	}

	KLIPS_PRINT(debug_pfkey,
		    "klips_debug:ipsec_alg_auth_key_create: about to call:"
		    "hmac_set_key(key_ctx=%p, key=%p, key_size=%d)\n",
		    akp, (caddr_t)sa_p->ips_key_a, sa_p->ips_key_bits_a/8);

	if (ixt_a->ixt_a_hmac_set_key) {
		ret = ixt_a->ixt_a_hmac_set_key(ixt_a, 
			akp, sa_p->ips_key_a, sa_p->ips_key_bits_a/8); /* XXX XXX */
		if (ret < 0) {
			kfree(akp);
			goto ixt_out;
		}
	} else {
		KLIPS_PRINT(debug_pfkey,
			    "klips_debug:ipsec_alg_auth_key_create: "
			    "no hmac_set_key function available!\n");

		ret = -EPROTO;
		goto ixt_out;
	}

	if (sa_p->ips_key_a) {
		memset(sa_p->ips_key_a, 0, sa_p->ips_key_bits_a/8);
		kfree(sa_p->ips_key_a);
	}

	sa_p->ips_key_a = akp;
	sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;

	sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */

	sa_p->ips_alg_auth = ixt_a;
	ixt_a = NULL;

ixt_out:
	if (ixt_a) {
		ipsec_alg_put((struct ipsec_alg *)ixt_a);
	}

	return ret;
}
Ejemplo n.º 4
0
/*
 * 	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;
	int iv_size, keysize, key_e_size;
	struct ipsec_alg_enc *ixt_e;
	#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: %s: "
			    "encalg=%d object not found\n",
			    __FUNCTION__, enc_alg);
		ret=-EINVAL;
		goto out;
	}
	iv_size=ixt_e->ixt_blocksize;
	key_e_size=ixt_e->ixt_e_ctx_size;
	keysize=ixt_e->ixt_e_keylen;
	KLIPS_PRINT(1, 
		    "klips_debug: %s: "
		    "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
		    __FUNCTION__, 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);
	ixt_e->ixt_e_set_key(test_key_e, test_key, keysize);
	get_random_bytes(test_enc, BUFSZ);
	memcpy(test_tmp, test_enc, BUFSZ);
	ret=ixt_e->ixt_e_cbc_encrypt(test_key_e, test_enc, test_enc, BUFSZ, test_iv, 1);
	printk(KERN_INFO
		    "klips_info: %s: "
		    "cbc_encrypt=1 ret=%d\n", 
		    	__FUNCTION__, ret);
	ret=memcmp(test_enc, test_tmp, BUFSZ);
	printk(KERN_INFO
		    "klips_info: %s: "
		    "memcmp(enc, tmp) ret=%d: %s\n", ret,
			__FUNCTION__,
			ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
	memcpy(test_dec, test_enc, BUFSZ);
	ret=ixt_e->ixt_e_cbc_encrypt(test_key_e, test_dec, test_dec, BUFSZ, test_iv, 0);
	printk(KERN_INFO
		    "klips_info: %s : "
		    "cbc_encrypt=0 ret=%d\n", __FUNCTION__, ret);
	ret=memcmp(test_dec, test_tmp, BUFSZ);
	printk(KERN_INFO
		    "klips_info: %s : "
		    "memcmp(dec,tmp) ret=%d: %s\n", __FUNCTION__, 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(test_key_e, test_tmp, test_tmp, BUFSZ, test_iv, encrypt);
					mb();
					count++;
					mb();
				}
				if (count > max)
					max = count;
			}
			speed = max * (HZ * BUFSZ / 1024);
			printk(KERN_INFO
				    "klips_info: %s: "
				    "%s %s speed=%d KB/s\n", 
				    __FUNCTION__, ixt_e->ixt_name,
				    encrypt? "encrypt": "decrypt", speed);
		}
	}
	kfree(buf);
	ipsec_alg_put((struct ipsec_alg *)ixt_e);
out:
	return ret;
	#undef test_enc  
	#undef test_dec  
	#undef test_tmp  
	#undef test_key_e
	#undef test_iv   
	#undef test_key  
	#undef test_size 
}
Ejemplo n.º 5
0
/*
 * 	encryption key context creation function
 * 	called from pfkey_v2_parser.c:pfkey_ips_init() 
 */
int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
	int ret = 0;
	int keyminbits, keymaxbits;
	caddr_t ekp = NULL;
	struct ipsec_alg_enc *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_enc_key_create: "
		    "entering with encalg=%d ixt_e=%p\n",
		    sa_p->ips_encalg, ixt_e);
	if (!ixt_e) {
		KLIPS_ERROR(debug_pfkey,
			    "klips_debug:ipsec_alg_enc_key_create: "
			    "NULL ipsec_alg_enc object\n");
		return -EPROTO;
	}

	/* 
	 * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo 
	 */
	switch(ixt_e->ixt_common.ixt_support.ias_id) {
		case ESP_3DES:
			keyminbits=keymaxbits=192;break;
		case ESP_DES:
			keyminbits=keymaxbits=64;break;
		default:
			keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
			keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
	}
	if (sa_p->ips_key_bits_e<keyminbits ||
		sa_p->ips_key_bits_e>keymaxbits) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"incorrect encryption key size for id=%d: %d bits -- "
			"must be between %d,%d bits\n" /*octets (bytes)\n"*/,
			ixt_e->ixt_common.ixt_support.ias_id,
			sa_p->ips_key_bits_e, keyminbits, keymaxbits);
		ret=-EINVAL;
		goto ixt_out;
	}

	if (ixt_e->ixt_e_new_key) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"using ixt_e_new_key to generate key\n");

		if ((ekp = ixt_e->ixt_e_new_key(ixt_e,
			sa_p->ips_key_e,
			sa_p->ips_key_bits_e/8)) == NULL) {
			ret = -EINVAL;
			goto ixt_out;
		}
	} else if (ixt_e->ixt_e_set_key) {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"using ixt_e_set_key to generate key context\n");

		if ((ekp = (caddr_t)kmalloc(ixt_e->ixt_e_ctx_size,
			GFP_ATOMIC)) == NULL) {
			ret = -ENOMEM;
			goto ixt_out;
		}
		/* zero-out key_e */
		memset(ekp, 0, ixt_e->ixt_e_ctx_size);

		/* I cast here to allow more decoupling in alg module */
		KLIPS_PRINT(debug_pfkey,
			"set_key(key_ctx=%p, key=%p, key_size=%d)\n",
			ekp, (caddr_t)sa_p->ips_key_e, sa_p->ips_key_bits_e/8);

		ret = ixt_e->ixt_e_set_key(ixt_e,
			ekp, (caddr_t)sa_p->ips_key_e, sa_p->ips_key_bits_e/8);
		if (ret < 0) {
			kfree(ekp);
			goto ixt_out;
		}
	} else {
		KLIPS_PRINT(debug_pfkey,
			"klips_debug:ipsec_alg_enc_key_create: "
			"no function available to generate a key!\n");

		ret = -EPROTO;
		goto ixt_out;
	}

	if (sa_p->ips_key_e) {
		memset(sa_p->ips_key_e, 0, sa_p->ips_key_bits_e/8);
		kfree(sa_p->ips_key_e);
	}

	sa_p->ips_key_e = ekp;
	sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size;

	sa_p->ips_alg_enc = ixt_e;
	ixt_e = NULL;

ixt_out:
	if (ixt_e)
		ipsec_alg_put((struct ipsec_alg *)ixt_e);

	return ret;
}