Пример #1
0
const char *
init_pluto_vendorid(void)
{
    MD5_CTX hc;
    unsigned char hash[MD5_DIGEST_SIZE];
    const char *v = ipsec_version_string();
    int i;

    if(pluto_vendorid_built) {
	return pluto_vendorid;
    }

    osMD5Init(&hc);
    osMD5Update(&hc, (const unsigned char *)v, strlen(v));
    osMD5Update(&hc, (const unsigned char *)compile_time_interop_options
	, strlen(compile_time_interop_options));
    osMD5Final(hash, &hc);

    pluto_vendorid[0] = 'O';
    pluto_vendorid[1] = 'S';
    pluto_vendorid[2] = 'W';

#if PLUTO_VENDORID_SIZE - 3 <= MD5_DIGEST_SIZE
    /* truncate hash to fit our vendor ID */
    memcpy(pluto_vendorid + 3, hash, PLUTO_VENDORID_SIZE - 3);
#else
    /* pad to fill our vendor ID */
    memcpy(pluto_vendorid + 3, hash, MD5_DIGEST_SIZE);
    memset(pluto_vendorid + 3 + MD5_DIGEST_SIZE, '\0'
	, PLUTO_VENDORID_SIZE - 3 - MD5_DIGEST_SIZE);
#endif

    /* Make it printable!  Hahaha - MCR */
    for (i = 0; i < PLUTO_VENDORID_SIZE; i++)
    {
	/* Reset bit 7, force bit 6.  Puts it into 64-127 range */
	pluto_vendorid[i] &= 0x7f;
	pluto_vendorid[i] |= 0x40;
        if(pluto_vendorid[i]==127) pluto_vendorid[i]='_';  /* omit RUBOUT */
    }
    pluto_vendorid[PLUTO_VENDORID_SIZE] = '\0';
    pluto_vendorid_built = TRUE;

    return pluto_vendorid;
}
Пример #2
0
/*****************************************************************************************   
函数名称: init_vendorid
功能描述: 初始化_vid_tab中的vid结构,根据_vid_tab中的flag标记填充vid与vid_len
				以及descr,若vid->flags仅仅标识为VID_KEEP,
				表示在_vid_tab中已经填充好各个字段,不用再处理
				在进程开启时调用。
输入参数:无
输出参数:无   
返 回 值:无
-------------------------------------------------------------------------------------------    
最近一次修改记录 :  适配flag类型的删减
修改作者:刘东		
修改目的:   
修改日期: 2012年6月23日
********************************************************************************************/
void init_vendorid(void)
{
	struct vid_struct *vid;
	MD5_CTX ctx;
	

	for (vid = _vid_tab; vid->id; vid++) 
	{		
	    if (vid->flags & VID_STRING) 
		{
			/** VendorID is a string **/
			vid->vid = strdup(vid->data);
			vid->vid_len = strlen(vid->data);
	    }
	    else if (vid->flags & VID_MD5HASH) 
		{
			/** VendorID is a string to hash with MD5 **/
			unsigned char *vidm =  malloc(MD5_DIGEST_SIZE);
			vid->vid = (char *)vidm;
			if (vidm) 
			{
			    unsigned const char *d = (unsigned const char *)vid->data;
			    osMD5Init(&ctx);
			    osMD5Update(&ctx, d, strlen(vid->data));
			    osMD5Final(vidm, &ctx);
			    vid->vid_len = MD5_DIGEST_SIZE;
			}
	    }
    
	    if (vid->descr == NULL) 
		{
			/** Find something to display **/
			vid->descr = vid->data;
	    }
	}
}
Пример #3
0
int ipsec_sa_init(struct ipsec_sa *ipsp)
{
	int error = 0;
	char sa[SATOT_BUF];
	size_t sa_len;

#ifdef CONFIG_KLIPS_DEBUG
	char ipaddr_txt[ADDRTOA_BUF];
	char ipaddr2_txt[ADDRTOA_BUF];
#endif
#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || \
	defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
	unsigned char kb[AHMD596_BLKLEN];
	int i;
#endif

	if (ipsp == NULL) {
		KLIPS_PRINT(debug_pfkey,
			    "ipsec_sa_init: "
			    "ipsp is NULL, fatal\n");
		SENDERR(EINVAL);
	}

	sa_len = KLIPS_SATOT(debug_pfkey, &ipsp->ips_said, 0, sa, sizeof(sa));

	KLIPS_PRINT(debug_pfkey,
		    "ipsec_sa_init: "
		    "(pfkey defined) called for SA:%s\n",
		    sa_len ? sa : " (error)");

	KLIPS_PRINT(debug_pfkey,
		    "ipsec_sa_init: "
		    "calling init routine of %s%s%s\n",
		    IPS_XFORM_NAME(ipsp));

	switch (ipsp->ips_said.proto) {
#ifdef CONFIG_KLIPS_IPIP
	case IPPROTO_IPIP: {
		ipsp->ips_xformfuncs = ipip_xform_funcs;
#ifdef CONFIG_KLIPS_DEBUG
		sin_addrtot(ipsp->ips_addr_s, 0, ipaddr_txt,
			    sizeof(ipaddr_txt));
		sin_addrtot(ipsp->ips_addr_d, 0, ipaddr2_txt,
			    sizeof(ipaddr2_txt));
		KLIPS_PRINT(debug_pfkey,
			    "ipsec_sa_init: "
			    "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
			    ipaddr_txt,
			    ipaddr2_txt);
#endif
	}
	break;
#endif          /* !CONFIG_KLIPS_IPIP */

#ifdef CONFIG_KLIPS_AH
	case IPPROTO_AH:

		ipsp->ips_xformfuncs = ah_xform_funcs;

#ifdef CONFIG_KLIPS_OCF
		if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg, 0))
			break;
#endif

#ifdef CONFIG_KLIPS_ALG
		error = ipsec_alg_auth_key_create(ipsp);
		if ((error < 0) && (error != -EPROTO))
			SENDERR(-error);

		if (error == -EPROTO) {
			/* perform manual key generation,
			   ignore this particular error */
			error = 0;
#endif              /* CONFIG_KLIPS_ALG */

		switch (ipsp->ips_authalg) {
# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
		case AH_MD5: {
			unsigned char *akp;
			unsigned int aks;
			MD5_CTX *ictx;
			MD5_CTX *octx;

			if (ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
				KLIPS_PRINT(debug_pfkey,
					    "ipsec_sa_init: "
					    "incorrect key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/,
					    ipsp->ips_key_bits_a, AHMD596_KLEN *
					    8);
				SENDERR(EINVAL);
			}

#  if KLIPS_DIVULGE_HMAC_KEY
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 0)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 1)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 2)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 3)));
#  endif                        /* KLIPS_DIVULGE_HMAC_KEY */

			ipsp->ips_auth_bits = AHMD596_ALEN * 8;

			/* save the pointer to the key material */
			akp = ipsp->ips_key_a;
			aks = ipsp->ips_key_a_size;

			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "allocating %lu bytes for md5_ctx.\n",
				    (unsigned long) sizeof(struct md5_ctx));
			if ((ipsp->ips_key_a = (caddr_t)
					       kmalloc(sizeof(struct md5_ctx),
						       GFP_ATOMIC)) == NULL) {
				ipsp->ips_key_a = akp;
				SENDERR(ENOMEM);
			}
			ipsp->ips_key_a_size = sizeof(struct md5_ctx);

			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++)
				kb[i] = akp[i] ^ HMAC_IPAD;
			for (; i < AHMD596_BLKLEN; i++)
				kb[i] = HMAC_IPAD;

			ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
			osMD5Init(ictx);
			osMD5Update(ictx, kb, AHMD596_BLKLEN);

			for (i = 0; i < AHMD596_BLKLEN; i++)
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);

			octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
			osMD5Init(octx);
			osMD5Update(octx, kb, AHMD596_BLKLEN);

#  if KLIPS_DIVULGE_HMAC_KEY
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
				    ((__u32*)ictx)[0],
				    ((__u32*)ictx)[1],
				    ((__u32*)ictx)[2],
				    ((__u32*)ictx)[3],
				    ((__u32*)octx)[0],
				    ((__u32*)octx)[1],
				    ((__u32*)octx)[2],
				    ((__u32*)octx)[3] );
#  endif                        /* KLIPS_DIVULGE_HMAC_KEY */

			/* zero key buffer -- paranoid */
			memset(akp, 0, aks);
			kfree(akp);
		}
		break;
# endif                 /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
		case AH_SHA: {
			unsigned char *akp;
			unsigned int aks;
			SHA1_CTX *ictx;
			SHA1_CTX *octx;

			if (ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
				KLIPS_PRINT(debug_pfkey,
					    "ipsec_sa_init: "
					    "incorrect key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/,
					    ipsp->ips_key_bits_a, AHSHA196_KLEN *
					    8);
				SENDERR(EINVAL);
			}

#  if KLIPS_DIVULGE_HMAC_KEY
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 0)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 1)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 2)),
				    ntohl(*(((__u32 *)ipsp->ips_key_a) + 3)));
#  endif                        /* KLIPS_DIVULGE_HMAC_KEY */

			ipsp->ips_auth_bits = AHSHA196_ALEN * 8;

			/* save the pointer to the key material */
			akp = ipsp->ips_key_a;
			aks = ipsp->ips_key_a_size;

			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "allocating %lu bytes for sha1_ctx.\n",
				    (unsigned long) sizeof(struct sha1_ctx));
			if ((ipsp->ips_key_a = (caddr_t)
					       kmalloc(sizeof(struct sha1_ctx),
						       GFP_ATOMIC)) == NULL) {
				ipsp->ips_key_a = akp;
				SENDERR(ENOMEM);
			}
			ipsp->ips_key_a_size = sizeof(struct sha1_ctx);

			for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++)
				kb[i] = akp[i] ^ HMAC_IPAD;
			for (; i < AHMD596_BLKLEN; i++)
				kb[i] = HMAC_IPAD;

			ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
			SHA1Init(ictx);
			SHA1Update(ictx, kb, AHSHA196_BLKLEN);

			for (i = 0; i < AHSHA196_BLKLEN; i++)
				kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);

			octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
			SHA1Init(octx);
			SHA1Update(octx, kb, AHSHA196_BLKLEN);

#  if KLIPS_DIVULGE_HMAC_KEY
			KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
				    "ipsec_sa_init: "
				    "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
				    ((__u32*)ictx)[0],
				    ((__u32*)ictx)[1],
				    ((__u32*)ictx)[2],
				    ((__u32*)ictx)[3],
				    ((__u32*)octx)[0],
				    ((__u32*)octx)[1],
				    ((__u32*)octx)[2],
				    ((__u32*)octx)[3] );
#  endif                        /* KLIPS_DIVULGE_HMAC_KEY */
			/* zero key buffer -- paranoid */
			memset(akp, 0, aks);
			kfree(akp);
		}
		break;
# endif                 /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
		default:
			KLIPS_PRINT(debug_pfkey,
				    "ipsec_sa_init: "
				    "authalg=%d support not available in the kernel",
				    ipsp->ips_authalg);
			SENDERR(EINVAL);
		}
#ifdef CONFIG_KLIPS_ALG
			/* closure of the -EPROTO condition above */
		}
#endif
		break;
#endif          /* CONFIG_KLIPS_AH */

#ifdef CONFIG_KLIPS_ESP
	case IPPROTO_ESP:
		ipsp->ips_xformfuncs = esp_xform_funcs;
		{
#ifdef CONFIG_KLIPS_OCF
			if (ipsec_ocf_sa_init(ipsp, ipsp->ips_authalg,
					      ipsp->ips_encalg))
				break;
#endif

#ifdef CONFIG_KLIPS_ALG
			error = ipsec_alg_enc_key_create(ipsp);
			if (error < 0)
				SENDERR(-error);

			error = ipsec_alg_auth_key_create(ipsp);
			if ((error < 0) && (error != -EPROTO))
				SENDERR(-error);

			if (error == -EPROTO) {
				/* perform manual key generation,
				   ignore this particular error */
				error = 0;
#endif                  /* CONFIG_KLIPS_ALG */

			switch (ipsp->ips_authalg) {
#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || \
				defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
				unsigned char *akp;
				unsigned int aks;
#endif
# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
			case AH_MD5: {
				MD5_CTX *ictx;
				MD5_CTX *octx;

				if (ipsp->ips_key_bits_a !=
				    (AHMD596_KLEN * 8)) {
					KLIPS_PRINT(debug_pfkey,
						    "ipsec_sa_init: "
						    "incorrect authorisation key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/,
						    ipsp->ips_key_bits_a,
						    AHMD596_KLEN * 8);
					SENDERR(EINVAL);
				}

#  if KLIPS_DIVULGE_HMAC_KEY
				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"hmac md5-96 key is 0x%08x %08x %08x %08x\n",
					ntohl(*(((__u32 *)(ipsp->ips_key_a)) +
						0)),
					ntohl(*(((__u32 *)(ipsp->ips_key_a)) +
						1)),
					ntohl(*(((__u32 *)(ipsp->ips_key_a)) +
						2)),
					ntohl(*(((__u32 *)(ipsp->ips_key_a)) +
						3)));
#  endif                                /* KLIPS_DIVULGE_HMAC_KEY */
				ipsp->ips_auth_bits = AHMD596_ALEN * 8;

				/* save the pointer to the key material */
				akp = ipsp->ips_key_a;
				aks = ipsp->ips_key_a_size;

				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"allocating %lu bytes for md5_ctx.\n",
					(unsigned long) sizeof(struct
							       md5_ctx));
				if ((ipsp->ips_key_a = (caddr_t)
					kmalloc(sizeof(struct md5_ctx),
						GFP_ATOMIC)) == NULL) {
					ipsp->ips_key_a = akp;
					SENDERR(ENOMEM);
				}
				ipsp->ips_key_a_size = sizeof(struct md5_ctx);

				for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8);
				     i++)
					kb[i] = akp[i] ^ HMAC_IPAD;
				for (; i < AHMD596_BLKLEN; i++)
					kb[i] = HMAC_IPAD;

				ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))
					  ->ictx);
				osMD5Init(ictx);
				osMD5Update(ictx, kb, AHMD596_BLKLEN);

				for (i = 0; i < AHMD596_BLKLEN; i++)
					kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);

				octx = &(((struct md5_ctx*)(ipsp->ips_key_a))
					  ->octx);
				osMD5Init(octx);
				osMD5Update(octx, kb, AHMD596_BLKLEN);

#  if KLIPS_DIVULGE_HMAC_KEY
				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
					((__u32*)ictx)[0],
					((__u32*)ictx)[1],
					((__u32*)ictx)[2],
					((__u32*)ictx)[3],
					((__u32*)octx)[0],
					((__u32*)octx)[1],
					((__u32*)octx)[2],
					((__u32*)octx)[3] );
#  endif                                /* KLIPS_DIVULGE_HMAC_KEY */
				/* paranoid */
				memset(akp, 0, aks);
				kfree(akp);
				break;
			}
# endif                         /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
			case AH_SHA: {
				SHA1_CTX *ictx;
				SHA1_CTX *octx;

				if (ipsp->ips_key_bits_a !=
				    (AHSHA196_KLEN * 8)) {
					KLIPS_PRINT(debug_pfkey,
						    "ipsec_sa_init: "
						    "incorrect authorisation key size: %d bits -- must be %d bits\n" /*octets (bytes)\n"*/,
						    ipsp->ips_key_bits_a,
						    AHSHA196_KLEN * 8);
					SENDERR(EINVAL);
				}

#  if KLIPS_DIVULGE_HMAC_KEY
				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
					ntohl(*(((__u32 *)ipsp->ips_key_a) +
						0)),
					ntohl(*(((__u32 *)ipsp->ips_key_a) +
						1)),
					ntohl(*(((__u32 *)ipsp->ips_key_a) +
						2)),
					ntohl(*(((__u32 *)ipsp->ips_key_a) +
						3)));
#  endif                                /* KLIPS_DIVULGE_HMAC_KEY */
				ipsp->ips_auth_bits = AHSHA196_ALEN * 8;

				/* save the pointer to the key material */
				akp = ipsp->ips_key_a;
				aks = ipsp->ips_key_a_size;

				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"allocating %lu bytes for sha1_ctx.\n",
					(unsigned long) sizeof(struct
							       sha1_ctx));
				if ((ipsp->ips_key_a = (caddr_t)
					kmalloc(sizeof(struct sha1_ctx),
						GFP_ATOMIC)) == NULL) {
					ipsp->ips_key_a = akp;
					SENDERR(ENOMEM);
				}
				ipsp->ips_key_a_size = sizeof(struct sha1_ctx);

				for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8);
				     i++)
					kb[i] = akp[i] ^ HMAC_IPAD;
				for (; i < AHMD596_BLKLEN; i++)
					kb[i] = HMAC_IPAD;

				ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))
					  ->ictx);
				SHA1Init(ictx);
				SHA1Update(ictx, kb, AHSHA196_BLKLEN);

				for (i = 0; i < AHSHA196_BLKLEN; i++)
					kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);

				octx = &((struct sha1_ctx*)(ipsp->ips_key_a))
					->octx;
				SHA1Init(octx);
				SHA1Update(octx, kb, AHSHA196_BLKLEN);

#  if KLIPS_DIVULGE_HMAC_KEY
				KLIPS_PRINT(
					debug_pfkey && sysctl_ipsec_debug_verbose,
					"ipsec_sa_init: "
					"SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
					((__u32*)ictx)[0],
					((__u32*)ictx)[1],
					((__u32*)ictx)[2],
					((__u32*)ictx)[3],
					((__u32*)octx)[0],
					((__u32*)octx)[1],
					((__u32*)octx)[2],
					((__u32*)octx)[3] );
#  endif                                /* KLIPS_DIVULGE_HMAC_KEY */
				memset(akp, 0, aks);
				kfree(akp);
				break;
			}
# endif                         /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
			case AH_NONE:
				break;
			default:
				KLIPS_PRINT(debug_pfkey,
					    "ipsec_sa_init: "
					    "authalg=%d support not available in the kernel.\n",
					    ipsp->ips_authalg);
				SENDERR(EINVAL);
			}
#ifdef CONFIG_KLIPS_ALG
			/* closure of the -EPROTO condition above */
		}
#endif

			ipsp->ips_iv_size =
				ipsp->ips_alg_enc->ixt_common.ixt_support.
				ias_ivlen / 8;

			/* Create IV */
			if (ipsp->ips_iv_size) {
				if ((ipsp->ips_iv = (caddr_t)
					kmalloc(ipsp->ips_iv_size,
						GFP_ATOMIC)) == NULL)
					SENDERR(ENOMEM);
				prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv,
					   ipsp->ips_iv_size);
				ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
			}
		}
		break;
#endif          /* !CONFIG_KLIPS_ESP */
#ifdef CONFIG_KLIPS_IPCOMP
	case IPPROTO_COMP:

		ipsp->ips_xformfuncs = ipcomp_xform_funcs;

		ipsp->ips_comp_adapt_tries = 0;
		ipsp->ips_comp_adapt_skip = 0;
		ipsp->ips_comp_ratio_cbytes = 0;
		ipsp->ips_comp_ratio_dbytes = 0;

#ifdef CONFIG_KLIPS_OCF
		if (ipsec_ocf_comp_sa_init(ipsp, ipsp->ips_encalg))
			break;
#endif

		ipsp->ips_comp_adapt_tries = 0;
		ipsp->ips_comp_adapt_skip = 0;
		ipsp->ips_comp_ratio_cbytes = 0;
		ipsp->ips_comp_ratio_dbytes = 0;
		break;
#endif          /* CONFIG_KLIPS_IPCOMP */
	default:
		printk(KERN_ERR "KLIPS sa initialization: "
		       "proto=%d unknown.\n",
		       ipsp->ips_said.proto);
		SENDERR(EINVAL);
	}

errlab:
	return error;
}
Пример #4
0
/*
 * Setup VendorID structs, and populate them
 * FIXME: This functions leaks a little bit, but these are one time leaks:
 * leak: 3 * vid->data, item size: 6
 * leak: self-vendor ID, item size: 37
 * leak: init_pluto_vendorid, item size: 13
 * leak: 2 * vid->data, item size: 13
 */
void init_vendorid(void)
{
	struct vid_struct *vid;

	for (vid = vid_tab; vid->id; vid++) {
		if (vid->flags & VID_SELF) {
			char *d;

			vid->vid = clone_str(
				ipsec_version_vendorid(), "init_pluto_vendorid");
			/* cut terminating NULL which won't go over the wire */
			vid->vid_len = strlen(vid->vid);
			d = alloc_bytes(strlen(vid->descr) + 256 +
					strlen(ipsec_version_vendorid()),
					"self-vendor ID");
			sprintf(d, "%s %s", vid->descr, ipsec_version_code());
			vid->descr = (const char *)d;
		} else if (vid->flags & VID_STRING) {
			/** VendorID is a string **/
			vid->vid = clone_str(vid->data, "vid->data");
			vid->vid_len = strlen(vid->data);
		} else if (vid->flags & VID_MD5HASH) {
			/** VendorID is a string to hash with MD5 **/
			unsigned char *vidm =  alloc_bytes(MD5_DIGEST_SIZE,
							   "VendorID MD5");
			vid->vid = (char *)vidm;
			if (vidm) {
				unsigned const char *d =
					(unsigned const char *)vid->data;
				MD5_CTX ctx;

				osMD5Init(&ctx);
				osMD5Update(&ctx, d, strlen(vid->data));
				osMD5Final(vidm, &ctx);
				vid->vid_len = MD5_DIGEST_SIZE;
			}
		} else if (vid->flags & VID_FSWAN_HASH) {
			/** FreeS/WAN 2.00+ specific hash **/
#define FSWAN_VID_SIZE 12
			unsigned char hash[MD5_DIGEST_SIZE];
			char *vidm =  alloc_bytes(FSWAN_VID_SIZE, "fswan VID");

			vid->vid = vidm;
			if (vidm) {
				MD5_CTX ctx;
				int i;

				osMD5Init(&ctx);
				osMD5Update(&ctx,
					    (const unsigned char *)vid->data, strlen(
						    vid->data));
				osMD5Final(hash, &ctx);
				vidm[0] = 'O';
				vidm[1] = 'E';
#if FSWAN_VID_SIZE <= 2 + MD5_DIGEST_SIZE
				memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);	/* truncate hash */
#else
				memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
				memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
				       FSWAN_VID_SIZE - (2 + MD5_DIGEST_SIZE));	/* pad hash */
#endif
				for (i = 2; i < FSWAN_VID_SIZE; i++) {
					vidm[i] &= 0x7f;
					vidm[i] |= 0x40;
				}
				vid->vid_len = FSWAN_VID_SIZE;
			}
#undef FSWAN_VID_SIZE
		}

		if (vid->descr == NULL) {
			/** Find something to display **/
			vid->descr = vid->data;
		}
#if 1
		DBG_log("init_vendorid: %d [%s]",
			vid->id,
			vid->descr ? vid->descr : ""
			);
		if (vid->vid)
			DBG_dump("VID:", vid->vid, vid->vid_len);
#endif
	}
	vid_struct_init = 1;
}