1 #include <linux/config.h>
2 #include <linux/module.h>
5 #include <linux/crypto.h>
6 #include <linux/pfkeyv2.h>
8 #include <asm/scatterlist.h>
17 void (*digest
)(struct ah_data
*,
21 struct crypto_tfm
*tfm
;
25 /* Clear mutable options and find final destination to substitute
26 * into IP header for digest calculation. Options are already checked
27 * for validity, so paranoia is not required. */
29 int ip_clear_mutable_options(struct iphdr
*iph
, u32
*daddr
)
31 unsigned char * optptr
= (unsigned char*)(iph
+1);
32 int l
= iph
->ihl
*4 - 20;
45 if (optlen
<2 || optlen
>l
)
49 case 0x85: /* Some "Extended Security" crap. */
50 case 0x86: /* Another "Commercial Security" crap. */
52 case 0x80|21: /* RFC1770 */
58 memcpy(daddr
, optptr
+optlen
-4, 4);
61 memset(optptr
+2, 0, optlen
-2);
69 void skb_ah_walk(const struct sk_buff
*skb
, struct crypto_tfm
*tfm
)
73 int start
= skb
->len
- skb
->data_len
;
74 int i
, copy
= start
- offset
;
75 struct scatterlist sg
;
77 /* Checksum header. */
82 sg
.page
= virt_to_page(skb
->data
+ offset
);
83 sg
.offset
= (unsigned long)(skb
->data
+ offset
) % PAGE_SIZE
;
86 crypto_hmac_update(tfm
, &sg
, 1);
88 if ((len
-= copy
) == 0)
93 for (i
= 0; i
< skb_shinfo(skb
)->nr_frags
; i
++) {
96 BUG_TRAP(start
<= offset
+ len
);
98 end
= start
+ skb_shinfo(skb
)->frags
[i
].size
;
99 if ((copy
= end
- offset
) > 0) {
100 skb_frag_t
*frag
= &skb_shinfo(skb
)->frags
[i
];
105 sg
.page
= frag
->page
;
106 sg
.offset
= frag
->page_offset
+ offset
-start
;
109 crypto_hmac_update(tfm
, &sg
, 1);
118 if (skb_shinfo(skb
)->frag_list
) {
119 struct sk_buff
*list
= skb_shinfo(skb
)->frag_list
;
121 for (; list
; list
= list
->next
) {
124 BUG_TRAP(start
<= offset
+ len
);
126 end
= start
+ list
->len
;
127 if ((copy
= end
- offset
) > 0) {
130 skb_ah_walk(list
, tfm
);
131 if ((len
-= copy
) == 0)
143 ah_hmac_digest(struct ah_data
*ahp
, struct sk_buff
*skb
, u8
*auth_data
)
145 struct crypto_tfm
*tfm
= ahp
->tfm
;
147 memset(auth_data
, 0, ahp
->digest_len
);
148 crypto_hmac_init(tfm
, ahp
->key
, &ahp
->key_len
);
149 skb_ah_walk(skb
, tfm
);
150 crypto_hmac_final(tfm
, ahp
->key
, &ahp
->key_len
, ahp
->work_digest
);
151 memcpy(auth_data
, ahp
->work_digest
, ahp
->digest_len
);
154 int ah_output(struct sk_buff
*skb
)
157 struct dst_entry
*dst
= skb
->dst
;
158 struct xfrm_state
*x
= dst
->xfrm
;
159 struct iphdr
*iph
, *top_iph
;
160 struct ip_auth_hdr
*ah
;
167 if (skb
->ip_summed
== CHECKSUM_HW
&& skb_checksum_help(skb
) == NULL
)
170 spin_lock_bh(&x
->lock
);
171 if ((err
= xfrm_state_check_expire(x
)) != 0)
173 if ((err
= xfrm_state_check_space(x
, skb
)) != 0)
178 top_iph
= (struct iphdr
*)skb_push(skb
, x
->props
.header_len
);
180 top_iph
->version
= 4;
182 top_iph
->tot_len
= htons(skb
->len
);
183 top_iph
->frag_off
= 0;
184 if (!(iph
->frag_off
&htons(IP_DF
)))
185 __ip_select_ident(top_iph
, dst
, 0);
187 top_iph
->protocol
= IPPROTO_AH
;
189 top_iph
->saddr
= x
->props
.saddr
.xfrm4_addr
;
190 top_iph
->daddr
= x
->id
.daddr
.xfrm4_addr
;
191 ah
= (struct ip_auth_hdr
*)(top_iph
+1);
192 ah
->nexthdr
= IPPROTO_IPIP
;
194 memcpy(&tmp_iph
, skb
->data
, iph
->ihl
*4);
195 top_iph
= (struct iphdr
*)skb_push(skb
, x
->props
.header_len
);
196 memcpy(top_iph
, &tmp_iph
, iph
->ihl
*4);
199 top_iph
->tot_len
= htons(skb
->len
);
200 top_iph
->frag_off
= 0;
202 top_iph
->protocol
= IPPROTO_AH
;
204 if (top_iph
->ihl
!= 5) {
205 err
= ip_clear_mutable_options(top_iph
, &top_iph
->daddr
);
209 ah
= (struct ip_auth_hdr
*)((char*)top_iph
+iph
->ihl
*4);
210 ah
->nexthdr
= iph
->protocol
;
213 ah
->hdrlen
= (((ahp
->digest_len
+ 12 + 7)&~7)>>2)-2;
216 ah
->seq_no
= htonl(++x
->replay
.oseq
);
217 ahp
->digest(ahp
, skb
, ah
->auth_data
);
218 top_iph
->tos
= iph
->tos
;
219 top_iph
->ttl
= iph
->ttl
;
221 top_iph
->frag_off
= iph
->frag_off
&~htons(IP_MF
|IP_OFFSET
);
222 memset(&(IPCB(skb
)->opt
), 0, sizeof(struct ip_options
));
224 top_iph
->frag_off
= iph
->frag_off
;
225 top_iph
->daddr
= iph
->daddr
;
227 memcpy(top_iph
+1, iph
+1, iph
->ihl
*5 - 20);
229 ip_send_check(top_iph
);
231 skb
->nh
.raw
= skb
->data
;
233 x
->curlft
.bytes
+= skb
->len
;
235 spin_unlock_bh(&x
->lock
);
236 if ((skb
->dst
= dst_pop(dst
)) == NULL
)
238 return NET_XMIT_BYPASS
;
241 spin_unlock_bh(&x
->lock
);
246 int ah_input(struct xfrm_state
*x
, struct sk_buff
*skb
)
249 struct ip_auth_hdr
*ah
;
253 if (!pskb_may_pull(skb
, sizeof(struct ip_auth_hdr
)))
256 ah
= (struct ip_auth_hdr
*)skb
->data
;
260 if (((ah
->hdrlen
+2)<<2) != ((ahp
->digest_len
+ 12 + 7)&~7))
263 if (!pskb_may_pull(skb
, (ah
->hdrlen
+2)<<2))
266 /* We are going to _remove_ AH header to keep sockets happy,
267 * so... Later this can change. */
268 if (skb_cloned(skb
) &&
269 pskb_expand_head(skb
, 0, 0, GFP_ATOMIC
))
272 ah
= (struct ip_auth_hdr
*)skb
->data
;
275 memcpy(work_buf
, iph
, iph
->ihl
*4);
283 if (ip_clear_mutable_options(iph
, &dummy
))
287 u8 auth_data
[ahp
->digest_len
];
288 memcpy(auth_data
, ah
->auth_data
, ahp
->digest_len
);
289 skb_push(skb
, skb
->data
- skb
->nh
.raw
);
290 ahp
->digest(ahp
, skb
, ah
->auth_data
);
291 if (memcmp(ah
->auth_data
, auth_data
, ahp
->digest_len
)) {
292 x
->stats
.integrity_failed
++;
296 ((struct iphdr
*)work_buf
)->protocol
= ah
->nexthdr
;
297 skb
->nh
.raw
= skb_pull(skb
, (ah
->hdrlen
+2)<<2);
298 memcpy(skb
->nh
.raw
, work_buf
, iph
->ihl
*4);
299 skb
->nh
.iph
->tot_len
= htons(skb
->len
);
300 skb_pull(skb
, skb
->nh
.iph
->ihl
*4);
301 skb
->h
.raw
= skb
->data
;
309 void ah4_err(struct sk_buff
*skb
, u32 info
)
311 struct iphdr
*iph
= (struct iphdr
*)skb
->data
;
312 struct ip_auth_hdr
*ah
= (struct ip_auth_hdr
*)(skb
->data
+(iph
->ihl
<<2));
313 struct xfrm_state
*x
;
315 if (skb
->h
.icmph
->type
!= ICMP_DEST_UNREACH
||
316 skb
->h
.icmph
->code
!= ICMP_FRAG_NEEDED
)
319 x
= xfrm_state_lookup(iph
->daddr
, ah
->spi
, IPPROTO_AH
);
322 printk(KERN_DEBUG
"pmtu discvovery on SA AH/%08x/%08x\n",
323 ntohl(ah
->spi
), ntohl(iph
->daddr
));
327 int ah_init_state(struct xfrm_state
*x
, void *args
)
329 struct ah_data
*ahp
= NULL
;
331 if (x
->aalg
== NULL
|| x
->aalg
->alg_key_len
== 0 ||
332 x
->aalg
->alg_key_len
> 512)
335 ahp
= kmalloc(sizeof(*ahp
), GFP_KERNEL
);
339 memset(ahp
, 0, sizeof(*ahp
));
341 ahp
->key
= x
->aalg
->alg_key
;
342 ahp
->key_len
= (x
->aalg
->alg_key_len
+7)/8;
343 ahp
->tfm
= crypto_alloc_tfm(x
->aalg
->alg_name
, 0);
346 ahp
->digest
= ah_hmac_digest
;
347 ahp
->digest_len
= 12;
348 ahp
->work_digest
= kmalloc(crypto_tfm_alg_digestsize(ahp
->tfm
),
350 if (!ahp
->work_digest
)
352 x
->props
.header_len
= (12 + ahp
->digest_len
+ 7)&~7;
354 x
->props
.header_len
+= 20;
361 if (ahp
->work_digest
)
362 kfree(ahp
->work_digest
);
364 crypto_free_tfm(ahp
->tfm
);
370 void ah_destroy(struct xfrm_state
*x
)
372 struct ah_data
*ahp
= x
->data
;
374 if (ahp
->work_digest
) {
375 kfree(ahp
->work_digest
);
376 ahp
->work_digest
= NULL
;
379 crypto_free_tfm(ahp
->tfm
);
385 static struct xfrm_type ah_type
=
387 .description
= "AH4",
389 .init_state
= ah_init_state
,
390 .destructor
= ah_destroy
,
395 static struct inet_protocol ah4_protocol
= {
396 .handler
= xfrm4_rcv
,
397 .err_handler
= ah4_err
,
401 int __init
ah4_init(void)
403 SET_MODULE_OWNER(&ah_type
);
404 if (xfrm_register_type(&ah_type
) < 0) {
405 printk(KERN_INFO
"ip ah init: can't add xfrm type\n");
408 if (inet_add_protocol(&ah4_protocol
, IPPROTO_AH
) < 0) {
409 printk(KERN_INFO
"ip ah init: can't add protocol\n");
410 xfrm_unregister_type(&ah_type
);
416 static void __exit
ah4_fini(void)
418 if (inet_del_protocol(&ah4_protocol
, IPPROTO_AH
) < 0)
419 printk(KERN_INFO
"ip ah close: can't remove protocol\n");
420 if (xfrm_unregister_type(&ah_type
) < 0)
421 printk(KERN_INFO
"ip ah close: can't remove xfrm type\n");
424 module_init(ah4_init
);
425 module_exit(ah4_fini
);
426 MODULE_LICENSE("GPL");