📄 ipsec_esp.c
字号:
} KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, " %02x", idat[irs->ilen - 2 - padlen + i - 1]); if(i != idat[irs->ilen - 2 - padlen + i - 1]) { badpad = 1; } if((i % 16) == 0) { KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, "\n"); } } if((i % 16) != 1) { KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, "\n"); } if(badpad) { KLIPS_PRINT(debug_rcv & DB_RX_IPAD, "klips_debug:ipsec_rcv: " "warning, decrypted packet from %s has bad padding\n", irs->ipsaddr_txt); KLIPS_PRINT(debug_rcv & DB_RX_IPAD, "klips_debug:ipsec_rcv: " "...may be bad decryption -- not dropped\n"); ipsp->ips_errs.ips_encpad_errs += 1; } KLIPS_PRINT(debug_rcv & DB_RX_IPAD, "klips_debug:ipsec_rcv: " "packet decrypted from %s: next_header = %d, padding = %d\n", irs->ipsaddr_txt, irs->next_header, pad - 2 - irs->authlen); irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad)); /* * move the IP header forward by the size of the ESP header, which * will remove the the ESP header from the packet. */ memmove((void *)(skb->data + esphlen), (void *)(skb->data), irs->iphlen); ipsec_rcv_dmp("esp postmove", skb->data, skb->len); /* skb_pull below, will move up by esphlen */ /* XXX not clear how this can happen, as the message indicates */ if(skb->len < esphlen) { printk(KERN_WARNING "klips_error:ipsec_rcv: " "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n", esphlen, (int)(skb->len)); return IPSEC_RCV_ESP_DECAPFAIL; } skb_pull(skb, esphlen); irs->ipp = (struct iphdr *)skb->data; ipsec_rcv_dmp("esp postpull", skb->data, skb->len); /* now, trip off the padding from the end */ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, "klips_debug:ipsec_rcv: " "trimming to %d.\n", irs->len - esphlen - pad); if(pad + esphlen <= irs->len) { skb_trim(skb, irs->len - esphlen - pad); } else { KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, "klips_debug:ipsec_rcv: " "bogus packet, size is zero or negative, dropping.\n"); return IPSEC_RCV_DECAPFAIL; } return IPSEC_RCV_OK;}enum ipsec_xmit_valueipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs){ __u32 iv[2]; struct esphdr *espp; int ilen = 0; int padlen = 0, i; unsigned char *dat; unsigned char *idat, *pad; __u8 hash[AH_AMAX]; union {#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5 MD5_CTX md5;#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1 SHA1_CTX sha1;#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */ } tctx; dat = (unsigned char *)ixs->iph; espp = (struct esphdr *)(dat + ixs->iphlen); espp->esp_spi = ixs->ipsp->ips_said.spi; espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); switch(ixs->ipsp->ips_encalg) {#if defined(CONFIG_KLIPS_ENC_3DES)#ifdef CONFIG_KLIPS_ENC_3DES case ESP_3DES:#endif /* CONFIG_KLIPS_ENC_3DES */ iv[0] = *((__u32*)&(espp->esp_iv) ) = ((__u32*)(ixs->ipsp->ips_iv))[0]; iv[1] = *((__u32*)&(espp->esp_iv) + 1) = ((__u32*)(ixs->ipsp->ips_iv))[1]; break;#endif /* defined(CONFIG_KLIPS_ENC_3DES) */ default: ixs->stats->tx_errors++; return IPSEC_XMIT_ESP_BADALG; } idat = dat + ixs->iphlen + sizeof(struct esphdr); ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen); /* Self-describing padding */ pad = &dat[ixs->skb->len - ixs->tailroom]; padlen = ixs->tailroom - 2 - ixs->authlen; for (i = 0; i < padlen; i++) { pad[i] = i + 1; } dat[ixs->skb->len - ixs->authlen - 2] = padlen; dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol; ixs->iph->protocol = IPPROTO_ESP; switch(ixs->ipsp->ips_encalg) {#ifdef CONFIG_KLIPS_ENC_3DES case ESP_3DES: des_ede3_cbc_encrypt((des_cblock *)idat, (des_cblock *)idat, ilen, ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks, ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks, ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks, (des_cblock *)iv, 1); break;#endif /* CONFIG_KLIPS_ENC_3DES */ default: ixs->stats->tx_errors++; return IPSEC_XMIT_ESP_BADALG; } switch(ixs->ipsp->ips_encalg) {#if defined(CONFIG_KLIPS_ENC_3DES)#ifdef CONFIG_KLIPS_ENC_3DES case ESP_3DES:#endif /* CONFIG_KLIPS_ENC_3DES */ /* XXX update IV with the last 8 octets of the encryption */#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK ((__u32*)(ixs->ipsp->ips_iv))[0] = ((__u32 *)(idat))[(ilen >> 2) - 2]; ((__u32*)(ixs->ipsp->ips_iv))[1] = ((__u32 *)(idat))[(ilen >> 2) - 1];#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ); #endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ break;#endif /* defined(CONFIG_KLIPS_ENC_3DES) */ default: ixs->stats->tx_errors++; return IPSEC_XMIT_ESP_BADALG; } switch(ixs->ipsp->ips_authalg) {#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5 case AH_MD5: ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); osMD5Final(hash, &tctx.md5); ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash)); tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); osMD5Update(&tctx.md5, hash, AHMD596_ALEN); ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); osMD5Final(hash, &tctx.md5); ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash)); memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); /* paranoid */ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); memset((caddr_t)hash, 0, sizeof(*hash)); break;#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1 case AH_SHA: tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); SHA1Final(hash, &tctx.sha1); tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); SHA1Final(hash, &tctx.sha1); memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); /* paranoid */ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); memset((caddr_t)hash, 0, sizeof(*hash)); break;#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */ case AH_NONE: break; default: ixs->stats->tx_errors++; return IPSEC_XMIT_AH_BADALG; }#ifdef NET_21 ixs->skb->h.raw = (unsigned char*)espp;#endif /* NET_21 */ return IPSEC_XMIT_OK;}struct xform_functions esp_xform_funcs[]={ { rcv_checks: ipsec_rcv_esp_checks, rcv_setup_auth: ipsec_rcv_esp_decrypt_setup, rcv_calc_auth: ipsec_rcv_esp_authcalc, rcv_decrypt: ipsec_rcv_esp_decrypt, xmit_setup: ipsec_xmit_esp_setup, xmit_headroom: sizeof(struct esphdr), xmit_needtailroom: 1, },};#ifdef NET_26struct inet_protocol esp_protocol = { .handler = ipsec_rcv, .no_policy = 1,};#elsestruct inet_protocol esp_protocol ={ ipsec_rcv, /* ESP handler */ NULL, /* TUNNEL error control */#ifdef NETDEV_25 1, /* no policy */#else 0, /* next */ IPPROTO_ESP, /* protocol ID */ 0, /* copy */ NULL, /* data */ "ESP" /* name */#endif};#endif /* NET_26 */#endif /* !CONFIG_KLIPS_ESP *//* * $Log: ipsec_esp.c,v $ * Revision 1.8 2004/09/14 00:22:57 mcr * adjustment of MD5* functions. * * Revision 1.7 2004/09/13 02:23:01 mcr * #define inet_protocol if necessary. * * Revision 1.6 2004/09/06 18:35:49 mcr * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility, * so adjust for that. * * Revision 1.5 2004/08/17 03:27:23 mcr * klips 2.6 edits. * * Revision 1.4 2004/08/04 15:57:07 mcr * moved des .h files to include/des/ * * included 2.6 protocol specific things * started at NAT-T support, but it will require a kernel patch. * * Revision 1.3 2004/07/10 19:11:18 mcr * CONFIG_IPSEC -> CONFIG_KLIPS. * * Revision 1.2 2004/04/06 02:49:25 mcr * pullup of algo code from alg-branch. * * * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -