Example #1
0
/* validation for registering (auth) module */
static int check_auth(struct ipsec_alg_auth *ixt) {
	int ret=-EINVAL;
	if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX)
		barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX);
	if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2)
		barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
	if (ixt->ixt_blocksize>AH_BLKLEN_MAX)
		barf_out(KERN_ERR "sorry blocksize=%d > %d. "
			"Please increase AH_BLKLEN_MAX and recompile\n", 
			ixt->ixt_blocksize,
			AH_BLKLEN_MAX);
	if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0)
		goto zero_key_ok;
	if (ixt->ixt_keyminbits==0)
		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
	if (ixt->ixt_keymaxbits==0)
		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
	if (ixt->ixt_keymaxbits!=ixt->ixt_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;
}
Example #2
0
/* 
 * 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 <*****@*****.**>
 			 */
			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[K_SADB_SATYPE_ESP]));

	if (ret==0) {
		ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
		/*	send register event to userspace	*/
		pfkey_register_reply(K_SADB_SATYPE_ESP, NULL);
	} else
		printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
				"Loading anyway.\n", ret);
	ret=0;
out:
	return ret;
}
Example #3
0
/* 
 * 	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[K_SADB_SATYPE_ESP]));

		/*	send register event to userspace	*/
		pfkey_register_reply(K_SADB_SATYPE_ESP, NULL);
	}

out:
	return ret;
}
Example #4
0
/*
 * 	inserts (in front) a new entry in hash table, 
 * 	called from ipsec_alg_register() when new algorithm is registered.
 */
static int ipsec_alg_insert(struct ipsec_alg *ixt) {
	int ret=-EINVAL;
	unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
	struct list_head *head= ipsec_alg_hash_table + hashval;
	struct ipsec_alg *ixt_cur;

	/* 	new element must be virgin ... */
	if (ixt->ixt_list.next != &ixt->ixt_list || 
		ixt->ixt_list.prev != &ixt->ixt_list) {
		printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
				"list head not initialized\n",
				ixt->ixt_name);
		return ret;
	}
	write_lock_bh(&ipsec_alg_lock);

	ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);

	/* if previous (current) ipsec_alg found check excl flag of _anyone_ */
	if (ixt_cur
	    && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
	  barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
		   "Not loaded (ret=%d).\n",
		   ixt->ixt_alg_type,
		   ixt->ixt_alg_id, ret=-EEXIST);
	}
	list_add(&ixt->ixt_list, head);
	ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
	ret=0;
out:
	write_unlock_bh(&ipsec_alg_lock);
	return ret;
}
Example #5
0
/* 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;
}
Example #6
0
/*
 * 	inserts (in front) a new entry in hash table, 
 * 	called from ipsec_alg_register() when new algorithm is registered.
 */
static int ipsec_alg_insert(struct ipsec_alg *ixt) {
	int ret=-EINVAL;
	unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
	struct list_head *head= ipsec_alg_hash_table + hashval;
	/* 	new element must be virgin ... */
	if (ixt->ixt_list.next != &ixt->ixt_list || 
		ixt->ixt_list.prev != &ixt->ixt_list) {
		printk(KERN_ERR "%s: ixt object \"%s\" "
				"list head not initialized\n",
				__FUNCTION__, ixt->ixt_name);
		return ret;
	}
	write_lock_bh(&ipsec_alg_lock);
	if (__ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head))
		barf_out(KERN_WARNING "ipsec_alg for alg_type=%d, alg_id=%d already exist."
				"Not loaded (ret=%d).\n",
				ixt->ixt_alg_type,
				ixt->ixt_alg_id, ret=-EEXIST);
	list_add(&ixt->ixt_list, head);
	ret=0;
out:
	write_unlock_bh(&ipsec_alg_lock);
	return ret;
}
Example #7
0
/* validation for registering (enc) module */
static int check_enc(struct ipsec_alg_enc *ixt) {
	int ret=-EINVAL;
	if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX)
		barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX);
	if (ixt->ixt_blocksize==0) /*  || ixt->ixt_blocksize%2) need for ESP_NULL */
		barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
	if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0)
		goto zero_key_ok;
	if (ixt->ixt_keyminbits==0)
		barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
	if (ixt->ixt_keymaxbits==0)
		barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_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)
		barf_out(KERN_ERR "invalid key_e_size=%d\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;
}