📄 ipsec_sa.c
字号:
ips, ips->ips_ref, IPsecSAref2table(IPsecSA2SAref(ips)), ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))], IPsecSAref2entry(IPsecSA2SAref(ips))); } if(ips->ips_ref == IPSEC_SAREF_NULL) { KLIPS_PRINT(debug_xform, "klips_debug:ipsec_sa_wipe: " "why does this SA not have a valid SAref?.\n"); } ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL; ips->ips_ref = IPSEC_SAREF_NULL; ipsec_sa_put(ips);#endif /* IPSEC_SA_REF_CODE */ /* paranoid clean up */ if(ips->ips_addr_s != NULL) { memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size); kfree(ips->ips_addr_s); } ips->ips_addr_s = NULL; if(ips->ips_addr_d != NULL) { memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size); kfree(ips->ips_addr_d); } ips->ips_addr_d = NULL; if(ips->ips_addr_p != NULL) { memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size); kfree(ips->ips_addr_p); } ips->ips_addr_p = NULL;#ifdef CONFIG_IPSEC_NAT_TRAVERSAL if(ips->ips_natt_oa) { memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size); kfree(ips->ips_natt_oa); } ips->ips_natt_oa = NULL;#endif if(ips->ips_key_a != NULL) { memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size); kfree(ips->ips_key_a); } ips->ips_key_a = NULL; if(ips->ips_key_e != NULL) { if (ips->ips_alg_enc && ips->ips_alg_enc->ixt_e_destroy_key) { ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, ips->ips_key_e); } else { memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size); kfree(ips->ips_key_e); } } ips->ips_key_e = NULL; if(ips->ips_iv != NULL) { memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size); kfree(ips->ips_iv); } ips->ips_iv = NULL; if(ips->ips_ident_s.data != NULL) { memset((caddr_t)(ips->ips_ident_s.data), 0, ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); kfree(ips->ips_ident_s.data); } ips->ips_ident_s.data = NULL; if(ips->ips_ident_d.data != NULL) { memset((caddr_t)(ips->ips_ident_d.data), 0, ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); kfree(ips->ips_ident_d.data); } ips->ips_ident_d.data = NULL; if (ips->ips_alg_enc||ips->ips_alg_auth) { ipsec_alg_sa_wipe(ips); } memset((caddr_t)ips, 0, sizeof(*ips)); kfree(ips); ips = NULL; return 0;}extern int sysctl_ipsec_debug_verbose;int ipsec_sa_init(struct ipsec_sa *ipsp){ int i; int error = 0; char sa[SATOT_BUF]; size_t sa_len; char ipaddr_txt[ADDRTOA_BUF]; char ipaddr2_txt[ADDRTOA_BUF];#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1) unsigned char kb[AHMD596_BLKLEN];#endif struct ipsec_alg_enc *ixt_e = NULL; struct ipsec_alg_auth *ixt_a = NULL; if(ipsp == NULL) { KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "ipsp is NULL, fatal\n"); SENDERR(EINVAL); } sa_len = satot(&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: { addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt)); addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, 0, ipaddr2_txt, sizeof(ipaddr_txt)); KLIPS_PRINT(debug_pfkey, "ipsec_sa_init: " "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", ipaddr_txt, ipaddr2_txt); } break;#endif /* !CONFIG_KLIPS_IPIP */#ifdef CONFIG_KLIPS_AH case IPPROTO_AH: 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); } break;#endif /* CONFIG_KLIPS_AH */#ifdef CONFIG_KLIPS_ESP case IPPROTO_ESP: {#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1) unsigned char *akp; unsigned int aks;#endif ipsec_alg_sa_init(ipsp); ixt_e=ipsp->ips_alg_enc; if (ixt_e == NULL) { if(printk_ratelimit()) { printk(KERN_INFO "ipsec_sa_init: " "encalg=%d support not available in the kernel", ipsp->ips_encalg); } SENDERR(ENOENT); } ipsp->ips_iv_size = ixt_e->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; } if ((error=ipsec_alg_enc_key_create(ipsp)) < 0) SENDERR(-error); if ((ixt_a=ipsp->ips_alg_auth)) { if ((error=ipsec_alg_auth_key_create(ipsp)) < 0) SENDERR(-error); } else switch(ipsp->ips_authalg) {# 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)),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -